Page History
Table of Contents |
---|
Introduction
...
In this note we describe the python
-based PyCSPadImage package which is intended to convert the CSPad raw data from HDF5 file to the geometry-corrected 2-D image array. Alternatively, this package evaluates and provide access to the pixel coordinate arrays. This package can be used in a stand-alone python
code.
Note |
---|
Please note, that LCLS main-stream data analysis framework is based on C++ package Psana. To work with CSPad images Psana has several modules which are collected in the CSPadPixCoords package. Two of these modules, CSPadImageProducer and CSPadInterpolImageProducer, are intended to produce the 2-D array with CSPad image from raw data (currently XTC, but HDF5 will be available soon). Precise CSPad geometry is accounted in Psana using the calibration parameters supplied by the PSCalib package. |
In this note we describe the PyCSPadImage package which converts the raw data in geometry-corrected 2-D array with CSPad image for HDF5 data in python
.
PyCSPadImage package
Package PyCSPadImage
Content
The python
-based PyCSPadImage package consists of modulesConsists of python modules (in alphabetic order):
CSPadConfigPars.py
- provides access to the CSPad configuration parametersCSPadImageProducer.py
- receives raw CSPad data 3-D (32, 185, 388) array, uses calibration parameters, produces the 2-D image arrayCalibPars.py
- provides access to the CSPad calibration parametersCalibParsDefault.py
- defines the default CSPad calibration parametersCalibParsEvaluated.py
- defines the evaluated CSPad parameters such as pixel coordinatesExamples.py
- contains examples of how to get the CSPad 2-D image array with corrected geometryAlignment.py
- similar to theExamples.py
, but is used for alignment purpose, its content is not guaranteedGlobalGraphics.py
- a set of useful global methods for interactive graphicGlobalMethods.py
- a set of misceleneous miscellaneous global modulesmethodsHDF5Methods.py
- a set of global methods to work with HDF5 filesCSPadPixCoordsWODB.py
- contains the most efficient way to get CSPad pixel x,y-coordinate arrays.
Update status
on 2013-06-24
PixCoords2x1.py
CSPAD2x2:
CSPAD2x2CalibParsDefault.py
CSPAD2x2CalibPars.py
CSPAD2x2PixCoords.py
CSPAD2x2Examples.py
CSPAD:
CSPadConfigPars.py
CalibParsDefault.py
CalibParsEvaluated.py
CalibPars.py
CSPADPixCoords.py
CSPadImageProducer.py
Examples.py
Utils:
GlobalGraphics.py
GlobalMethods.py
HDF5Methods.py
Functionality
The PyCSPadImage package is intended to convert the CSPad raw data from HDF5 file to the geometry-corrected 2-D image array. Methods of this package provide basic functionality as follows.
- Raw data 3-D (32, 185, 388) array can be be obtained from HDF5 file by its record name using methods from the module
HDF5Methods.py
. The CSPad dynamic configuration parameters are also uploaded using methods from the classCSPadConfigPars
.
- Access to the CSPad geometry calibration parameters are provided by the methods of the classes
CalibParsDefault
,CalibPars
, andCalibParsEvaluated
. It is assumed that the geometry calibration files, are available (see CSPAD Alignment) and located in the user-specified directory, otherwise default parameters will be used, which would not represent correctly the specific detector geometry.
- Methods of the class
CalibParsEvaluated
also evaluate pixel coordinates and provide access to the coordinate arrays of different shapes.
- Methods of the class
CSPadImageProducer
allows to get the geometry-corrected CSPad image or its part for specified 2x1 or quad.
- Methods of the class
CSPadPixCoordsWODB
provide the most efficient way to get CSPad pixel x,y-coordinate arrays. It works without data base access (WODB). User has to provide four 4,8 arrays for 2x1 sensor alignment: x,y-coordinate of the center, orientation, and tilt angle of each 2x1 in the "global" coordinate system of the detector. Test example inside theCSPadPixCoordsWODB.py
module also shows how to generate CSPad image from x,y-coordinate arrays usingnumpy.histogram2d(...)
method.
This class strongly rely onnumpy
, has no dependency from other classes in this package. For test purpose only it uses a couple of graphical methods fromGlobalGraphics.py
. The main methodmake_cspad_pix_coordinate_arrays()
consumes < 70ms on psexport02 (does not matter, because it should be done once per job...).
How to get this package
Below we assume that all standard environment variable settings are done (oservice otherwise see Analysis Workbook. Account Setup). In order to copy the PyCSPadImage package from SVN
repository and run a simple test one has to use commands:
Code Block |
---|
log loginin to psanaXXXXpsana<XXXX> kinit cd <your-favorite-directory> newrel ana-current <your-release-directory-name> cd <your-release-directory-name> sit_setup addpkg PyCSPadImage HEAD cd PyCSPadImage/src/ <==== All source-code files are located here python Examples.py |
External parameters
CSPAD geometry is varying for different detectors, experiments, or even runs. In order to keep track on all these variations LCLS offline has a simple calibration data base, which works as explained in CSPAD Alignment. In order to get correct CSPAD alignment parameters the pass to the calibration directory should be specified like this:
Code Block |
---|
path_calib = '/reg/d/psdm/CXI/cxi80410/calib/CsPad::CalibV1/CxiDs1.0:Cspad.0'
|
If the detector configuration was changed during the experiment, then more than one calibration file should be available for the run ranges with stable configuration.
In order to access correct calibration file the run number should be provided, for example
Code Block |
---|
runnum = 628
|
Data for CSPAD image and the detector configuration can be obtained from the HDF5 file, dataset name, and event number for example
Code Block |
---|
fname = '/reg/d/psdm/CXI/cxi80410/hdf5/cxi80410-r0628.h5'
dsname = '/Configure:0000/Run:0000/CalibCycle:0000/CsPad::ElementV2/CxiDs1.0:Cspad.0/data'
|
Example
event = 34
|
Note |
---|
|
In further description we assume that this set of external parameters is defined.
Import modules
In code snippets below we use definitions of modules and libraries as follows
Code Block |
---|
import numpy as np
import CalibPars as calp
import CalibParsEvaluated as cpe
import CSPadConfigPars as ccp
import CSPadImageProducer as cip
import GlobalGraphics as gg
import HDF5Methods as hm
|
Reconstruction of CSPAD image
Entire code example for image reconstruction is
Code Block |
---|
calp.calibpars.setCalibParsForPath ( run=runnum, path=path_calib )
ds1ev = hm.getOneCSPadEventForTest( fname, dsname, event )
cspadimg = cip.CSPadImageProducer(rotation=0, tiltIsOn=True, mirror=True)
arr = cspadimg.getCSPadImage( ds1ev )
|
First, one has to set the correct version of the calibration parameters
Code Block |
---|
calp.calibpars.setCalibParsForPath ( run=runnum, path=path_calib )
|
Then, one need in CSPAD dataset for event,
Code Block |
---|
ds1ev = hm.getOneCSPadEventForTest( fname, dsname, event )
|
this method returns the CSPAD data as a numpy array for one event, ds1ev.shape=(Nseg, 185, 388), where Nseg?32.
Note |
---|
It is recommended to use this method, which also loads correct configuration parameters from HDF5 file. |
Then, one has to initialize the object of the class CSPadImageProducer
Code Block |
---|
cspadimg = cip.CSPadImageProducer(rotation=0, tiltIsOn=True, mirror=True)
|
with optional parameters
rotation
integer from 0 to 3 parameters for CSPAD orientation as 90*rotation
degree.tiltIsOn
=True
orFalse
- to account or not the tiny tilt angle of 2x1 sections.mirror
=True
orFalse
- to mirror reflect or not the image.
Finally the method
Code Block |
---|
arr = cspadimg.getCSPadImage( ds1ev )
|
returns the 2-d numpy array with CSPAD image, which can be plotted using for example matplotlib
.
CSPAD pixel coordinate arrays
CSPAD pixel coordinate arrays can be evaluated/returned in two different shapes:
- for entire CSPAD with shape=(4,8,185,388)
- for data-driven shape=(Nseg,185,388), where Nseg?32 if some quads/segments are missing in data.
To get pixel coordinate arrays shaped for entire CSPAD use code:
Code Block |
---|
calp.calibpars.setCalibParsForPath ( run=runnum, path=path_calib )
cpe.cpeval.evaluateCSPadPixCoordinates (rotation=0, mirror=False)
xpix, ypix = cpe.cpeval.getCSPadPixCoordinates_pix()
|
where the parameters rotation
and mirror
have the same meaning as before,
xpix and ypix are the coordinate (in pixels) arrays with shape = (4,8,185,388).
Method xpix_um, ypix_um = cpe.cpeval.getCSPadPixCoordinates_um()
returns pixel coordinates in micrometer.
To get CSPAD pixel coordinate arrays shaped as in data use code:
Code Block |
---|
calp.calibpars.setCalibParsForPath ( run=runnum, path=path_calib )
cpe.cpeval.evaluateCSPadPixCoordinatesShapedAsData(fname,dsname,rotation=0,mirror=False)
xpix, ypix = cpe.cpeval.getCSPadPixCoordinatesShapedAsData_pix()
|
where xpix and ypix are the coordinate (in pixels) arrays with shape = (Nseg,185,388).
Note that the fname
and dsname
need to be specified in order to get configuration of the data array.
Method xpix_um, ypix_um = cpe.cpeval.getCSPadPixCoordinatesShapedAsData_um()
returns pixel coordinates in micrometer.
The coordinate arrays extracted for both shapes are tested in module Examples.py
by the methods
example_of_image_built_from_pix_coordinate_array_shaped_as_data()
and
example_of_image_built_from_pix_coordinate_array_for_entire_cspad()
,
where images are reconstructed through the pixel coordinate arrays in
cpe.cpeval.getTestImageShapedAsData(ds1ev)
and
cpe.cpeval.getTestImageForEntireArray(ds1ev)
, respectively.
Note |
---|
The last two methods use implicit loops over all pixels, that works pretty slow in Python. These modules are used for test only and are not recommended for real applications. |
Examples
Module Examples.py
contains a few examples of how to use the PyCSPadImage package.
Get and plot CSPAD image and spectrum
There are two equivalent examples defined by the methods main_example_xpp()
and main_example_cxi()
for XPP and CXI experimental data, respectively.
The essential part of these examples Module Examples.py
demonstrates of how to use the PyCSPadImage package. The essential part of the example can be presented as:
Code Block |
---|
import sys import os import CalibPars as calp import CSPadConfigPars as ccp import CSPadImageProducer as cip import GlobalGraphics as gg # For test purpose in main only import HDF5Methods as hm # For test purpose in main only #---------------------------------------------- def main_example_xpp() : print 'Start test in main_example_xpp()' path_calib = '/reg/d/psdm/xpp/xpp47712/calib/CsPad::CalibV1/XppGon.0:Cspad.0' fname, runnum = '/reg/d/psdm/xpp/xpp47712/hdf5/xpp47712-r0043.h5', 43 dsname = '/Configure:0000/Run:0000/CalibCycle:0000/CsPad::ElementV2/XppGon.0:Cspad.0/data' event = 0 print 'Load calibration parameters from', path_calib calp.calibpars.setCalibParsForPath ( run = 1runnum, path = path_calib ) print 'Get raw CSPad event %d from file %s \ndataset %s' % (event, fname, dsname) ds1ev = hm.getOneCSPadEventForTest( fname, dsname, event ) print 'ds1ev.shape = ',ds1ev.shape print 'Make the CSPad image from raw array' cspadimg = cip.CSPadImageProducer(rotation=0, tiltIsOn=True, mirror=False) arr = cspadimg.getImageArrayForCSPadElementgetCSPadImage( ds1ev ) print 'Plot CSPad image' gg.plotImage(arr,range=(0,2000),figsize=(11.6,10)) gg.move(200,100) gg.plotSpectrum(arr,range=(0,2000)) gg.move(50,50) print 'To EXIT the test click on "x" in the top-right corner of each plot window.' gg.show() #---------------------------------------------- |
Let us consider in detail what needs to be done in order to produce the CSPad image.
First, all necessary modules need to be imported:
if __name__ == "__main__" :
main_example_xpp()
sys.exit ( 'End of test.' )
|
This is working example, which can be copied, pasted in <file-name>.py file and executed.
Note |
---|
Appropriate permission is required to access particular experimental data. |
In addition to the description above, the statements
Code Block |
---|
gg.plotImage(arr,range=(0,2000),figsize=(11.6,10))
gg.move(200,100)
gg.plotSpectrum(arr,range=(0,2000))
gg.move(50,50)
gg.show()
|
allow to plot the CSPAD 2-d array as image and spectrum, move graphical windows to specified position and show all graphics.
Get CSPAD pixel coordinate arrays
Here we reproduce the test method
example_of_image_built_from_pix_coordinate_array_shaped_as_data()
from the module Examples.py
.
This example shows how to get the CSPAD pixel coordinate arrays. In addition, it uses the getTestImageShapedAsData(ds1ev)
(slow) method to produce image from the pixel coordinate arrays and data and plots this image.
Code Block |
---|
import sys
import CalibPars |
Code Block |
import CalibPars as calp import CSPadConfigPars as ccpcalp import CSPadImageProducerCalibParsEvaluated as cipcpe import GlobalGraphics as gg # For test purpose in main only import HDF5Methods as hm # For test purpose in main only |
Then, the path to the calibration data types, the HDF5 data file name, and the dataset name in HDF5 structure need to be defined:
Code Block |
---|
path_calib = '/reg/d/psdm/xpp/xpp47712/calib/CsPad::CalibV1/XppGon.0:Cspad.0' fname #---------------------------------------------- def example_of_image_built_from_pix_coordinate_array_shaped_as_data() : """Some CSPAD segments may be missing in the dataset """ fname, runnum = '/reg/d/psdm/xppCXI/xpp47712cxi80410/hdf5/xpp47712cxi80410-r0043r0628.h5', 628 dsname = '/Configure:0000/Run:0000/CalibCycle:0000/CsPad::ElementV2/XppGonCxiDs1.0:Cspad.0/data' |
Note |
---|
|
Then, calibration parameters need to be loaded:
Code Block |
---|
path_calib = '/reg/d/psdm/CXI/cxi80410/calib/CsPad::CalibV1/CxiDs1.0:Cspad.0' Range = (1000,3500) calp.calibpars.setCalibParsForPath ( run = 1runnum, path = path_calib) ) |
Note |
---|
|
Then, the raw CSPad dataset needs to be extracted:
Code Block |
---|
#cpe.cpeval.printCalibParsEvaluated('center_global') cpe.cpeval.evaluateCSPadPixCoordinatesShapedAsData(fname,dsname,rotation=0) # At this point pixel coordinates are available and can be extracted: xpix, ypix = cpe.cpeval.getCSPadPixCoordinatesShapedAsData_pix() print 'xpix =\n', xpix # Test image from pixel coordinate and data arrays can be produced and plotted: ds1ev = hm.getOneCSPadEventForTest( fname, dsname, event=0 ) # returns array with shape=(29, 185, 388) arr = cpe.cpeval.getTestImageShapedAsData(ds1ev) |
Note |
---|
It is recommended to use this method, which also loads correct configuration parameters from HDF5 file. |
Finally the 2-D image array can be obtained
Code Block |
---|
cspadimg = cip.CSPadImageProducer()
arr = cspadimg.getImageArrayForCSPadElement( ds1ev )
|
and used, for example for plotting
Code Block |
---|
gg.plotImage(arr,range=(0,2000),figsize=(11.6,10))
gg.plotSpectrum(arr,range=(0,2000))
gg.show()
|
References
gg.plotImage(arr,range=Range,figsize=(11.6,10))
gg.move(200,100)
gg.show()
#----------------------------------------------
if __name__ == "__main__" :
example_of_image_built_from_pix_coordinate_array_shaped_as_data()
sys.exit ( 'End of test.' )
|
Get CSPAD pixel coordinate arrays without data base.
Use class CSPadPixCoordsWODB.py
Essentialy user has to provide 4 arrays for 2x1 alignment. For example see
def main_test_cspad()
:
Code Block |
---|
xc_um = 109.92 * np.array(
[[ 473.38, 685.26, 155.01, 154.08, 266.81, 53.95, 583.04, 582.15],
[ 989.30, 987.12, 1096.93, 884.11, 1413.16, 1414.94, 1500.83, 1288.02],
[1142.59, 930.23, 1459.44, 1460.67, 1347.57, 1559.93, 1032.27, 1033.44],
[ 626.78, 627.42, 516.03, 729.15, 198.28, 198.01, 115.31, 327.66]])
yc_um = 109.92 * np.array(
[[1028.07, 1026.28, 1139.46, 926.91, 1456.78, 1457.35, 1539.71, 1327.89],
[1180.51, 967.36, 1497.74, 1498.54, 1385.08, 1598.19, 1069.65, 1069.93],
[ 664.89, 666.83, 553.60, 765.91, 237.53, 236.06, 152.17, 365.47],
[ 510.38, 722.95, 193.33, 193.41, 308.04, 95.25, 625.28, 624.14]])
orient_deg = np.array(
[[ 90., 90., 0., 0., 270., 270., 0., 0.],
[ 0., 0., 270., 270., 180., 180., 270., 270.],
[ 90., 90., 0., 0., 270., 270., 0., 0.],
[ 0., 0., 270., 270., 180., 180., 270., 270.]])
tilt_deg = np.array(
[[0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0.]])
|
Note |
---|
ALL arrays are shown here FOR TEST PURPOSE ONLY !!! and they are not consistent with any real detector. The |
These arrays of alignment parameters are used for initialization of the CSPadPixCoordsWODB
class object, which can be used to get X,Y-coordinate arrays as shown below:
Code Block |
---|
w = CSPadPixCoordsWODB(xc_um, yc_um, orient_deg, tilt_deg)
X,Y = w.get_cspad_pix_coordinate_arrays_pix ()
|
where X.shape = Y.shape = (4, 8, 185, 388) and obviously can be re-shaped to (32, 185, 388). Then, it is easy to produce image of coordinate arrays using numpy
2D histogramming method:
Code Block |
---|
xsize = X.max() + 1
ysize = Y.max() + 1
Img, Xedges, Yedges = np.histogram2d(X.flatten(), Y.flatten(), bins=[xsize,ysize], range=[[0,xsize],[0,ysize]], normed=False, weights=None)
|
In order to get an image of intensity the weights array needs to be provided.