Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

XTC Explorer - GUI interface that builds pyana modules for you.

Panel
titleTry:
Code Block
none
none

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.

...

Extracting the data with pyana, some examples

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 
  1. 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.

...

'Det-ID|Dev-ID'

...

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

...


        @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

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 Block
    none
    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
    none
    none
    
            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 the evt 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 filtering
    Code 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 signal
    Code 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 histograms
    Code 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 )
    

...