Measurement Scripts

Note

Please see Examples for more a comprehensive set of examples

Functions

class pychron.pyscripts.measurement_pyscript.MeasurementPyScript(*args: Any, **kwargs: Any)[source]

MeasurementPyScripts are used to collect isotopic data

activate_detectors(*dets, **kw)[source]

set the active detectors

Parameters

dets – list

coincidence()[source]

Do a coincidence scan. Peak center all active detectors simulatenously. calculate required deflection corrections to bring all detectors into coincidence

property eqtime

Property. Equilibration time. Get value from AutomatedRun.

Returns

float, int

equilibrate(eqtime=20, inlet=None, outlet=None, do_post_equilibration=True, close_inlet=True, delay=3)[source]

equilibrate the extraction line with the mass spectrometer

inlet or outlet can be a single valve name or a list of valve names.

'A', ('A','B'), ['A','B'], 'A,B'
Parameters
  • eqtime – int, equilibration duration in seconds

  • inlet – str, tuple or list, inlet valve

  • outlet – str, tuple or list, ion pump valve

  • do_post_equilibration – bool

  • close_inlet – bool

  • delay – int, delay in seconds between close of outlet and open of inlet

generate_ic_mftable(detectors, refiso='Ar40', peak_center_config='', n=1, calc_time=False)[source]

Generate an IC MFTable. Use this when doing a Detector Intercalibration. peak centers the refiso on a list of detectors. MFTable saved as ic_mftable

cancel script if generating mftable fails

Parameters
  • detectors (list) – list of detectors to peak center

  • refiso (str) – isotope to peak center

peak_center(detector='', isotope='', integration_time=1.04, save=True, calc_time=False, directions='Increase', config_name='default')[source]

Calculate the peak center for isotope on detector.

Parameters
  • detector – str

  • isotope – str

  • integration_time – float

  • save – bool

position_magnet(pos, detector='AX', use_dac=False, for_collection=True)[source]
Parameters
  • pos (str) – location to set magnetic field

  • detector – detector to position pos

  • use_dac (bool) – is the pos a DAC voltage

examples:

position_magnet(4.54312, use_dac=True) # detector is not relevant
position_magnet(39.962, detector='AX')
position_magnet('Ar40', detector='AX') #Ar40 will be converted to 39.962 use mole weight dict
post_equilibration(block=False)[source]

Run the post equilibration script.

reset(arun)[source]

Reset the script with a new automated run

Parameters

arun (AutomatedRun) – A new AutomatedRun

set_baseline_fits(*fits)[source]

set baseline fits for detectors

Parameters

fits

set_fits(*fits)[source]

set time vs intensity regression fits for isotopes

Parameters

fits – str, list, or tuple

set_integration_time(v)[source]

Set the integration time

Parameters

v (float) – integration time in seconds

set_time_zero(offset=0)[source]

set the time_zero value. add offset to time_zero

T_o= ion pump closes
offset seconds after T_o. define time_zero

T_eq= inlet closes
property time_zero_offset

Property. Substract time_zero_offset from time value for all data points

Returns

float, int

property truncated

Property. True if run was truncated otherwise False

Returns

bool

property use_cdd_warming

Property. Use CDD Warming. Get value from AutomatedRunSpec

Returns

bool

whiff(ncounts=0, conditionals=None)[source]

Do a whiff measurement.

Whiff’s are quick measurements with conditionals. use them to take action at the beginning of a measurement. For example do a whiff to determine if intensity to great.

Parameters
  • ncounts – int

  • conditionals – list of dicts

Variables

truncated

eqtime

use_cdd_warming

Multicollect

#!Measurement

#counts
MULTICOLLECT_COUNTS= 4

#baselines
BASELINE_COUNTS= 2
BASELINE_DETECTOR= 'H1'
BASELINE_MASS= 39.5
BASELINE_BEFORE= False
BASELINE_AFTER= True

#peak center
PEAK_CENTER_BEFORE= False
PEAK_CENTER_AFTER= False
PEAK_CENTER_DETECTOR= 'H1'
PEAK_CENTER_ISOTOPE= 'Ar40'

#equilibration
EQ_TIME= 2
INLET= 'R'
OUTLET= 'S'
DELAY= 3.0
TIME_ZERO_OFFSET=5

ACTIVE_DETECTORS=('H1','AX')
FITS=[
      ((0,5),('linear', 'linear')),
      ((5,None),('linear', 'parabolic'))
      ]
USE_FIT_BLOCKS=True

ACTIONS= [(False,('age','<',10.6,20,10,'',False)),
         ]

TRUNCATIONS = [(False, ('age','<',10.6,20,10,)),
              ]

TERMINATIONS= [(False, ('age','<',10.6,20,10))
              ]

def main():
    #this is a comment
    '''
        this is a multiline
        comment aka docstring
    '''
    #display information with info(msg)
    info('unknown measurement script')

    #set the spectrometer parameters
    #provide a value
    set_source_parameters(YSymmetry=10)

    #or leave blank and values are loaded from a config file (setupfiles/spectrometer/config.cfg)
    set_source_optics()

    #set the cdd operating voltage
    set_cdd_operating_voltage(100)

    if PEAK_CENTER_BEFORE:
        peak_center(detector=PEAK_CENTER_DETECTOR,isotope=PEAK_CENTER_ISOTOPE)

    #open a plot panel for this detectors
    activate_detectors(*ACTIVE_DETECTORS)

    if BASELINE_BEFORE:
        baselines(ncounts=BASELINE_COUNTS,mass=BASELINE_MASS, detector=BASELINE_DETECTOR)
    #set default regression
    regress(*FITS)

    #position mass spectrometer
    position_magnet('Ar40', detector='H1')

    #gas is staged behind inlet

    #post equilibration script triggered after eqtime elapsed
    #equilibrate is non blocking
    #so use either a sniff of sleep as a placeholder until eq finished
    equilibrate(eqtime=EQ_TIME, inlet=INLET, outlet=OUTLET)

    for use,args in ACTIONS:
        if use:
            add_action(*args)

    for use,args in TRUNCATIONS:
        if use:
            add_truncation(*args)

    for use, args in TERMINATIONS:
        if use:
            add_termination(*args)

    #equilibrate returns immediately after the inlet opens
    set_time_zero(offset=TIME_ZERO_OFFSET)

    sniff(EQ_TIME)

    #multicollect on active detectors
    multicollect(ncounts=MULTICOLLECT_COUNTS, integration_time=1)

    clear_conditionals()

    if BASELINE_AFTER:
        baselines(ncounts=BASELINE_COUNTS,mass=BASELINE_MASS, detector=BASELINE_DETECTOR)
    if PEAK_CENTER_AFTER:
        peak_center(detector=PEAK_CENTER_DETECTOR,isotope=PEAK_CENTER_ISOTOPE)


    #WARM CDD
    warm_cdd()

    info('finished measure script')

def warm_cdd():
    '''
        1. blank beam
        2. move to desired position
        3. unblank beam
    '''
    if not is_last_run():
        set_deflection('CDD',2000)

        position_magnet(28.04, detector='H1')
        #or
        #position_magnet(5.00, dac=True)

        #return to config.cfg deflection value
        set_deflection('CDD')

#========================EOF==============================================================

Peak Hop

For a detailed description of a Peak Hop sequence see hops. Instead of defining the peak hop sequence directly within the measurement script it is cleaner to load the sequence from a separate file using load_hops

#!Measurement

#===============================================================================
# parameter definitions
#===============================================================================
#multicollect
MULTICOLLECT_COUNTS      = 1003
MULTICOLLECT_ISOTOPE     = 'Ar40'
MULTICOLLECT_DETECTOR    = 'H1'

#baselines
BASELINE_COUNTS          = 10
BASELINE_DETECTOR        = 'H1'
BASELINE_MASS            = 39.5
BASELINE_BEFORE          = False
BASELINE_AFTER           = True

#peak center
PEAK_CENTER_BEFORE       = False
PEAK_CENTER_AFTER        = False
PEAK_CENTER_DETECTOR     = 'H1'
PEAK_CENTER_ISOTOPE      = 'Ar40'

#equilibration
EQ_TIME                  = 1.0
EQ_INLET                 = 'S'
EQ_OUTLET                = 'O'
EQ_DELAY                 = 3.0

#PEAK HOP
USE_PEAK_HOP             = True
NCYCLES                  = 3
BASELINE_NCYCLES         = 3


"""
    HOPS definition

    HOPS is a list of peak hops.
    a peak hop is a list of iso:detector pairs plus the number of counts to measure
    for this hop. The first iso:detector pair is used for positioning.

    added rev 1665
        specify a deflection for the iso:det pair
        Ar40:H1:30
        if no value is specified and the deflection value had been changed by a previous cycle
        then set the deflection to the config. value


    ('Ar40:H1,     Ar39:AX,     Ar36:CDD',      10)
    ('Ar40:L2,     Ar39:CDD',                   20),
    means position Ar40 on detector H1 and
    record 10 H1,AX,and CDD measurements. After 10 measurements
    position Ar40 on detector L2, record 20 measurements.

    repeat this sequence NCYCLES times

"""

HOPS=[('Ar40:H1:10,     Ar39:AX,     Ar36:CDD',      5, 1),
      #('Ar40:L2,     Ar39:CDD',                   5, 1),
      #('Ar38:CDD',                                5, 1),
      ('Ar37:CDD',                                5, 1),
      ]

#Detectors
ACTIVE_DETECTORS         = ('H2','H1','AX','L1','L2','CDD')
FITS                     = ('average','parabolic','parabolic','parabolic','parabolic','linear')
#===============================================================================
#
#===============================================================================


def main():
    #this is a comment
    '''
        this is a multiline
        comment aka docstring
    '''
    #display information with info(msg)
    info('unknown measurement script')

    #set the spectrometer parameters
    #provide a value
    #set_source_parameters(YSymmetry=10)

    #or leave blank and values are loaded from a config file (setupfiles/spectrometer/config.cfg)
    #set_source_optics()

    #set the cdd operating voltage
    #set_cdd_operating_voltage(100)

    if PEAK_CENTER_BEFORE:
        peak_center(detector=PEAK_CENTER_DETECTOR,isotope=PEAK_CENTER_ISOTOPE)

    activate_detectors(*ACTIVE_DETECTORS)

    if BASELINE_BEFORE:
        baselines(ncounts=BASELINE_COUNTS,mass=BASELINE_MASS, detector=BASELINE_DETECTOR)
    #set default regression
    regress(*FITS)

    #position mass spectrometer even though this is a peak hop so an accurate sniff/eq is measured
    position_magnet(MULTICOLLECT_ISOTOPE, detector=MULTICOLLECT_DETECTOR)

    #gas is staged behind inlet

    #post equilibration script triggered after eqtime elapsed
    #equilibrate is non blocking
    #so use either a sniff of sleep as a placeholder until eq finished
    equilibrate(eqtime=EQ_TIME, inlet=EQ_INLET, outlet=EQ_OUTLET)

    #equilibrate returns immediately after the inlet opens
    set_time_zero()

    sniff(EQ_TIME)

    if USE_PEAK_HOP:
        hops=load_hops('hops/hop.txt')
        info(hops)

        peak_hop(ncycles=NCYCLES, hops=HOPS)
    else:
        #multicollect on active detectors
        multicollect(ncounts=MULTICOLLECT_COUNTS, integration_time=1)

    if BASELINE_AFTER:
        if USE_PEAK_HOP:
            peak_hop(ncycles=BASELINE_NCYCLES, hops=BASELINE_HOPS, baseline=True)
        else:
            baselines(ncounts=BASELINE_COUNTS,mass=BASELINE_MASS,
                      detector=BASELINE_DETECTOR)
    if PEAK_CENTER_AFTER:
        peak_center(detector=PEAK_CENTER_DETECTOR,isotope=PEAK_CENTER_ISOTOPE)

    info('finished measure script')


    #=============================EOF=======================================================

Annotated Multicollect

#!Measurement

def main():
    '''
    display a message in the Experiment Executor and add to log
    '''
    info('example measurement script')

    '''
    define which detectors to collect with
    '''
    activate_detectors('H1','AX','L1','L2','CDD')

    '''
    set the fit types
    if a single value is supplied it's applied to all active detectors
    '''
    regress('parabolic')

    #or a list of fits the same len as active detectors is required
    regress('parabolic','parabolic','linear','linear','parabolic')

    '''
    position the magnet

    position_magnet(4.54312, dac=True) # detector is not relevant
    position_magnet(39.962, detector='AX')
    position_magnet('Ar40', detector='AX') #Ar40 will be converted to 39.962 use mole weight dict
    '''

    #position isotope Ar40 on detector H1
    position_magnet('Ar40', detector='H1')

    '''
    sniff and split

        1. isolate sniffer volumne
        2. equilibrate
        3. sniff gas
        4. test condition

    gas is staged behind inlet
    isolate sniffer volume
    '''
    close('S')
    sleep(1)

    '''
    equilibrate with mass spec
    set outlet to make a static measurement

    set do_post_equilibration to False so that the gas in the microbone
    is not pumped away
    '''
    equilibrate(eqtime=20, inlet='R', do_post_equilibration=False)
    set_time_zero()

    #display pressure wave
    sniff(20)

    #define sniff/split threshold
    sniff_threshold=100

    #test condition
    if get_intensity('H1')>sniff_threshold:
        extraction_gosub('splits:jan_split')
        '''
        extraction_gosub is same as
        gosub('splits:jan_split', klass='ExtractionLinePyScript')
        '''

    '''
    gas has been split down and staged behind the inlet
    post equilibration script triggered after eqtime elapsed
    equilibrate is non-blocking so use a sniff or sleep as a placeholder
    e.g sniff(<equilibration_time>) or sleep(<equilibration_time>)
    '''
    equilibrate(eqtime=5,inlet='R', outlet='V')
    set_time_zero()

    #sniff the gas during equilibration
    sniff(5)
    sleep(1)

    '''
    Set conditionals

    order added defines conditional precedence.
    conditionals after the first true conditional are NOT evaluated

    terminate if age < 10000 ma after 5 counts, check every 2 counts
    terminate means do not finish measurement script and immediately execute
    the post measurement script
    '''
    add_termination('age','<',10000, start_count=5, frequency=2)

    '''
    truncate means finish the measurement block immediately and continue to next
    command in the script
    '''
    add_truncation('age','>',10.6, start_count=20, frequency=10)

    '''
    use add_action to specify an action to take for a given conditional

    action can be a code snippet 'sleep(10)', 'gosub("example_gosub")' or
    a callable such as a function or lambda

    the resume keyword (default=False) continues measurement after executing
    the action
    '''
    add_action('age','>',10.6, start_count=20, frequency=10,
                action='sleep(10)')
    add_action('age','<',10000, start_count=5, frequency=2,
                  action=func)
    add_action('age','<',10000, start_count=5, frequency=2,
                  action='sleep(7)',
                  resume=True
                  )
    add_action('age','<',10000, start_count=5, frequency=2,
                  action='gosub("snippet")')

    #measure active detectors for ncounts
    multicollect(ncounts=50, integration_time=1)

    '''
    clear the conditionals when measuring baseline
    also have oppurtunity to add new conditionals
    '''
    clear_conditionals()

    #multicollect baselines for ncounts
    baselines(ncounts=5,mass=39.5)

    info('finished measure script')

def func():
    info('action performed')

#=============================EOF=======================================================