Page History
...
XTC Explorer - GUI interface that builds pyana modules for you.
Panel | ||
---|---|---|
| ||
Code Block | ||||
---|---|---|---|---|
| ||||
xtcexplorer /reg/d/psdm/xpp/xppi0310/xtc/e81-r0098-s0* {none} Then hit the "Scan File(s)" button (can you find it?!?) What do you see? Compare the GUI that pops up, with the output in the terminal window. h2. Extracting the data with pyana, some examples |
...
h3. Outline of a pyana module |
...
Like the other frameworks, pyana is an executable that loops through the XTC file and calls all |
...
requested user modules at certain transitions. All the analysts need to do is to fill in the |
...
relevant functions in their user analysis module: |
Code Block |
---|
- useful
...
- imports
...
import
...
- numpy
...
- as
...
- np
...
import
...
- matplotlib.pyplot
...
- as
...
- plt
...
from
...
- pypdsdata.xtc
...
- import
...
- TypeId
...
class
...
mymodule
...
(object)
...
:
...
"""Class
...
whose
...
instance
...
will
...
be
...
used
...
as
...
a
...
user
...
analysis
...
module.
...
"""
...
def _init
...
_
...
(
...
self,
source = ""
threshold = "" ):
"""Class
...
constructor.
...
The parameters to the constructor are passed from pyana configuration file.
If parameters do not have default values here then the must be defined in
pyana.cfg. All parameters are passed as strings, convert to correct type before use.
@param source name of device, format 'Det-ID|Dev-
...
Point detector delay scan
...
ID'
@param threshold threshold value (remember to convert from string)
"""
self.source = source
self.threshold = float(threshold)
def beginjob( self, evt, env ) :
"""This method is called once at the beginning of the job. It should
do a one-time initialization possible extracting values from event
data (which is a Configure object) or environment.
@param evt event data object
@param env environment object
"""
pass
def beginrun( self, evt, env ) :
"""This optional method is called if present at the beginning of the new run.
@param evt event data object
@param env environment object
"""
pass
def begincalibcycle( self, evt, env ) :
"""This optional method is called if present at the beginning
of the new calibration cycle.
@param evt event data object
@param env environment object
"""
pass
def event( self, evt, env ) :
"""This method is called for every L1Accept transition.
@param evt event data object
@param env environment object
"""
pass
def endcalibcycle( self, env ) :
"""This optional method is called if present at the end of the
calibration cycle.
@param env environment object
"""
pass
def endrun( self, env ) :
"""This optional method is called if present at the end of the run.
@param env environment object
"""
pass
def endjob( self, env ) :
"""This method is called at the end of the job. It should do
final cleanup, e.g. close all open files.
@param env environment object
"""
pass
Code Block |
---|
h3. Point detector delay scan
* *Fetching the ControlPV information:*
ControlPV is available from the {{env}} object, and since it only changes at the beginning
of each calibration cycle, the {{begincalibcycle}} function is the appropriate place to get it:
\\
{code:none} |
...
def begincalibcycle( self, evt, env ) :
|
The ControlConfig object may contain several pvControl and pvMonitor objects. In this case
there's only one, but make sure the name matches anyway:
Code Block | ||||
---|---|---|---|---|
| ||||
ctrl_config = env.getConfig(TypeId.Type.Id_ControlConfig)
for ic in range (0, ctrl_config.npvControls() ):
cpv = ctrl_config.pvControl(ic)
if cpv.name()=="fs2:ramp_angsft_target":
# store the value in a class variable (visible in every class method)
self.current_pv_value = cpv.value() )
|
- Fetching the IPIMB and PhaseCavity information:
All the other information that we need, is available through theevt
object, and
event
member function is the place to get it:Code Block none none def event( self, evt, env ) :
Use "XppSb3Ipm-1|Ipimb-0" (a.k.a. IPM3) sum of all channels for normalization and filteringCode Block none none ipmN_raw = evt.get(TypeId.Type.Id_IpimbData, "XppSb3Ipm-1|Ipimb-0") ipmN_fex = evt.get(TypeId.Type.Id_IpmFex, "XppSb3Ipm-1|Ipimb-0") ipmN_norm = ipmN_fex.sum
Use "XppSb3Pim-1|Ipimb-0" (a.k.a. PIM3) channel 1 as signalCode Block none none ipmS_raw = evt.get(TypeId.Type.Id_IpimbData, "XppSb3Pim-1|Ipimb-0" ) ipmS_fex = evt.get(TypeId.Type.Id_IpmFex, "XppSb3Pim-1|Ipimb-0" ) ipm_sig = ipmS_fex.channel[1]
Get the phase cavity:Code Block none none pc = evt.getPhaseCavity() phasecav1 = pc.fFitTime1 phasecav2 = pc.fFitTime2 charge1 = pc.fCharge1 charge2 = pc.fCharge2
Compute delay time and fill histogramsCode Block none none delaytime = self.current_pv_value + phasecav1*1e3 # The "histograms" are nothing but python lists. Append to them, and turn them into arrays at the end. self.h_ipm_rsig.append( ipm_sig ) self.h_ipm_nsig.append( ipm_sig/ipm_norm ) self.h_delaytime.append( delaytime )
...