Versions Compared

Key

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

...

Code Block
languagepy
(ps-4.5.26) drp-srcf-eb009:lcls2$ python junk4.py
nstep/nevent/nnorm/ndir 0 32399 200 3
nstep/nevent/nnorm/ndir 1 32283 200 3
nstep/nevent/nnorm/ndir 2 32399 200 3
nstep/nevent/nnorm/ndir 3 32284 200 3
nstep/nevent/nnorm/ndir 4 32298 200 4

(ps-4.5.26) drp-srcf-eb009:lcls2$ more junk4.py
from psana import DataSource
import datetime as dt
import numpy as np
import sys

ds = DataSource(exp='rixx1003821',run=55,dir='/cds/data/psdm/prj/public01/xtc')
myrun = next(ds.runs())
andor_norm = myrun.Detector('andor_norm')
andor_dir = myrun.Detector('andor_dir')

for nstep,step in enumerate(myrun.steps()):
    nnorm = 0
    ndir = 0
    for nevent,evt in enumerate(step.events()):
        norm_value = andor_norm.raw.value(evt)
        dir_value = andor_dir.raw.value(evt)
        if norm_value is not None: nnorm+=1
        if dir_value is not None: ndir+=1
    print('nstep/nevent/nnorm/ndir',nstep,nevent,nnorm,ndir)
(ps-4.5.26) drp-srcf-eb009:lcls2$  

Andor Normalization With Realtime Plotting

Run with "mpirun -n 5 python andor.py" with "psplot ANDOR" on the same node.

Code Block
languagepy
from psana import DataSource
from psmon import publish
from psmon.plots import Image,XYPlot
import os
from mpi4py import MPI
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()

os.environ['PS_SRV_NODES']='1'

if rank==4: # hack for now to eliminate use of publish.local below
    publish.init()

# we will remove this for batch processing and use "psplot" instead
# publish.local = True

def my_smalldata(data_dict):
    if 'unaligned_andor_norm' in data_dict:
        andor_norm = data_dict['unaligned_andor_norm'][0]
        myplot = XYPlot(0,"Andor (normalized)",range(len(andor_norm)),andor_norm)
        publish.send('ANDOR',myplot)

ds = DataSource(exp='rixx1003821',run=46,dir='/cds/data/psdm/prj/public01/xtc',intg_det='andor_vls',batch_size=1)
for myrun in ds.runs():
    andor = myrun.Detector('andor_vls')
    timing = myrun.Detector('timing')
    smd = ds.smalldata(filename='mysmallh5.h5',batch_size=1000, callbacks=[my_smalldata])
    norm = 0
    ndrop_inhibit = 0
    for nstep,step in enumerate(myrun.steps()):
        print('step:',nstep)
        for nevt,evt in enumerate(step.events()):
            andor_img = andor.raw.value(evt)
            # also need to check for events missing due to damage
            # (or compare against expected number of events)
            ndrop_inhibit += timing.raw.inhibitCounts(evt)
            smd.event(evt, mydata=nevt) # high rate data saved to h5
            # need to check Matt's new timing-system data on every
            # event to make sure we haven't missed normalization
            # data due to deadtime
            norm+=nevt # fake normalization
            if andor_img is not None:
                print('andor data on evt:',nevt,'ndrop_inhibit:',ndrop_inhibit)
                # check that the high-read readout group (2) didn't
                # miss any events due to deadtime
                if ndrop_inhibit[2]!=0: print('*** data lost due to deadtime')
                # need to prefix the name with "unaligned_" so
                # the low-rate andor dataset doesn't get padded
                # to align with the high rate datasets
                smd.event(evt, mydata=nevt,
                          unaligned_andor_norm=(andor_img/norm))
                norm=0
                ndrop_inhibit=0

Practice Session Nov. 8, 2023

Executive summary of starting plan: we will run continuous sequences for all running (free running and scans).  At the start all the andors will run at the same rate at either 1,10,100Hz in some appropriate combination of FVB,crop,full-frame mode.

To calculate readout time: Take difference of "accumulate period" and "exposure time" reported by the IOC (we don't understand difference between accumulate period and acquire period, but they have always been the same historically).

to do:

  • rix specifies ~3 modes for both andors running at same rate (1,10,100Hz) for  the 3 andor modes.  kristjan will send that matt.
  • how do we say all-laser-on or all laser off in rixgeneratory.py?
  • longer term: there will be an additional ~7 patterns for the three andors running at two different rates
  • how do we detect mps problems? (will kill some shots).  But Matt thinks it doesn't break the machine's TPG sequencing pattern
  • need to fix pva gateway: see timeouts for seqprogram
  • work on psplot_live robustness (e.g. not leaving dangling processes)

andors dir/norm will always have the same rate/exposure
third vls andor is what may cause us to want 2 different rates

archon will be treated like an andor for rate/exposure

longer term epixm will be different has timing gap of 200us (exposure 20us min, readout 150us).  may not have to shutter the camera because the signal is so low?

4 potential andor modes:
- crop mode
- full vertical binning
- full frame
- don't use partial vertical binning for now

rixgeneratory assumes the first one is the slow camera.  times are in seconds.  bunch_period in buckets.  laser_onoff is counted in terms of the slow camera images (the first on in the list).  This shows generating one event code, but lists can be given to generating different andor trigger rates:

(ps-4.6.1) rix-daq:scripts> python ~rixopr/git/lcls2_102323/psdaq/psdaq/seq/rixgeneratory.py  --periods 0.1 --readout_time 0.005 --bunch_period 28 --laser_onoff 2 2
Generating one repeating bunch train for one camera
d {'period': 3250, 'readout': 163}
** Wrote beam.py **
factors of 3250 : [3250]
** Wrote laser.py **
# period 91000  args.period [91000]
** Wrote codes.py **
(ps-4.6.1) rix-daq:scripts> 

beam.py is simulation of accelerator
laser.py triggers laser

To view event code patterns in an interactive plot: seqplot --seq 1:beam.py 2:codes.py 3:laser.py --time 1.0

Program the sequences like this.  Normally the laser.py eventcodes would be programmed in XPM:0 and the beam.py eventcodes would be programmed by ACR into their TPG (timing pattern generator):

seqprogram --seq 1:beam.py 2:codes.py 3:laser.py --pv DAQ:NEH:XPM:3 --start

took rixc00121 run 49 with 31kHz piranha/timing and 10Hz dir/norm andor.
run 50 is a scan with same 

To view status of the 4 sequence engines (4 eventcodes per engine) execute "xpmpva DAQ:NEH:XPM:3" and select the "Groups/Eventcodes" tab.  The "Master" column is important: it says which XPM controls which event code (in units of an "engine": 4 event codes).  The "Ena" and "Dis" buttons (for the appropriate XPM!) can be used to change which XPM controls a particular engine.

Image Added

Kristjan's tables of andor rates/readout times:

View file
nameAndor_burst_modes_8Nov23.pdf
height250

Practice Session April 3, 2024

Commands for 66Hz Andor running with 8kHz beam:

Code Block
8kHz beam + one camera (66Hz): rixgenerator --bunch_period 112 --periods 0.015385 --readout_time 0.005
8kHz beam + two cameras(1Hz + 66Hz): rixgenerator --bunch_period 112 --periods 1 0.015385