Content
Problem
In Run 18 planned on Aug 2019 the new single-piece 4M Jungfrau detector is going to be used with a couple of controllers. In daq and psana it will be seen as two independent detectors, i.e. MfxEndstation.0:Jungfrau.0 and 1. It seems natural to process data of these two detectors as a single piece. To make it feasible class AreaDetectorCompound was developed with functionality as explained in this note.
Details of implementation
Class AreaDetectorCompound constructor gets a list of detector names which need to be processed together. From this list it generates a list of AreaDetector objects, which is used to wrap all AreaDetector interface methods. Wrapping methods concatenates numpy arrays for the 3-rd to last index. This type of concatenation can be done for identical two last indeces, e.g. for jungfrau
(2, 512, 1024) (+) (1, 512, 1024) (=) (3, 512, 1024) (3, 2, 512, 1024) (+) (3, 1, 512, 1024) (=) (3, 3, 512, 1024)
Generalized methods from AreaDetector interface
methods returning concatinated arrays
raw, calib, pedestals, rms, gain, offset, bkgd, status, mask, photons,
coords_x, coords_y, coords_z,
indexes_x, indexes_y, indexes_z,
common_mode_correction, common_mode_apply,
mask_geo, mask_comb, mask_edges, mask_neighbors, mask_calib,
datast, status_as_mask, gain_mask, gain_mask_non_zero, areas
methods returning a couple of concatinated arrays
coords_xy, indexes_xy, indexes_xy_at_z
methods returning a list of per detector values
list_raw, list_calib, list_shape, list_size, list_ndim, list_common_mode, list_geometry
Code example
from Detector.AreaDetectorCompaund import AreaDetectorCompaund import psana from Detector.GlobalUtils import print_ndarr ds = psana.DataSource('exp=xpptut15:run=460') det = AreaDetectorCompaund(['MecTargetChamber.0:Cspad2x2.1',\ 'MecTargetChamber.0:Cspad2x2.2',\ 'MecTargetChamber.0:Cspad2x2.3']) env = ds.env() evt = ds.events().next() rnum = evt.run() if True : print 'rnum :', rnum print 'calibdir :', str(env.calibDir()) print 'size :', str(det.list_size(evt)) print 'shapes :', str(det.list_shape(evt)) print 'ndims :', str(det.list_ndim(evt)) raws = det.list_raw(evt) for nda in raws : print_ndarr(nda, name='-- per det list_raw', first=0, last=5) raw = det.raw(evt) print_ndarr(raw, name='raw as nda', first=0, last=5) calib = det.calib(evt) print_ndarr(calib, name='calib', first=0, last=5) xy0_offset = (1400,1400) img_raw = det.image(evt, nda_in=raw, xy0_off_pix=xy0_offset) #img_calib = det.image(evt, nda_in=calib, xy0_off_pix=xy0_offset) #img_at_z = det.image_at_z(evt, zplane=500000, nda_in=raw, xy0_off_pix=xy0_offset) if True : # True or False for to plot image or not from pyimgalgos.GlobalGraphics import plotImageLarge, show img = img_raw plotImageLarge(img, title='img as %s' % str(img.shape), amp_range=(0,5000)) show()
Methods for imaging
img = det.image(evt, nda_in=raw, xy0_off_pix=xy0_offset) img = det.image_at_z(evt, zplane=500000, nda_in=raw, xy0_off_pix=xy0_offset)
Compound detector image examples for three cspad2x1 from exp=xpptut15:run=460 and 1M and 512k Jungfrau from exp=mfxls4916:run=298
References
'raw', 'calib', 'shape', 'size', 'ndim', 'common_mode', 'geometry