Versions Compared

Key

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

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.

Package PyCSPadImage

Content

The python-based PyCSPadImage package consists of modules:

  • CSPadConfigPars.py - provides access to the CSPad configuration parameters
  • CSPadImageProducer.py - receives raw CSPad data 3-D (32, 185, 388) array, uses calibration parameters, produces the 2-D image array
  • CalibPars.py - provides access to the CSPad calibration parameters
  • CalibParsDefault.py - defines the default CSPad calibration parameters
  • CalibParsEvaluated.py - defines the evaluated CSPad parameters such as pixel coordinates
  • Examples.py - contains examples of how to get the CSPad 2-D image array with corrected geometry
  • Alignment.py - similar to the Examples.py, but is used for alignment purpose, its content is not guaranteed
  • GlobalGraphics.py - a set of useful global methods for interactive graphic
  • GlobalMethods.py - a set of miscellaneous global methods
  • HDF5Methods.py - a set of global methods to work with HDF5 files
  • CSPadPixCoordsWODB.py - contains the most efficient way to get CSPad pixel x,y-coordinate arrays.

Update status

on 2013-06-24
(tick) PixCoords2x1.py

CSPAD2x2:
(tick) CSPAD2x2CalibParsDefault.py
(tick) CSPAD2x2CalibPars.py
(tick) CSPAD2x2PixCoords.py
(tick) CSPAD2x2Examples.py

CSPAD:
(tick) CSPadConfigPars.py
(tick) CalibParsDefault.py
(plus) CalibParsEvaluated.py
(plus) CalibPars.py
(tick) CSPADPixCoords.py
(plus) CSPadImageProducer.py
(plus) Examples.py

Utils:
(tick) GlobalGraphics.py
(tick) GlobalMethods.py
(tick) 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.

...

  • Access to the CSPad geometry calibration parameters are provided by the methods of the classes CalibParsDefault, CalibPars, and CalibParsEvaluated. It is assumed that the geometry calibration files, are available (see CSPad 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 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 the CSPadPixCoordsWODB.py module also shows how to generate CSPad image from x,y-coordinate arrays using numpy.histogram2d(...) method.
    This class strongly rely on numpy, has no dependency from other classes in this package. For test purpose only it uses a couple of graphical methods from GlobalGraphics.py. The main method make_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 (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 in to psana<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 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'
    event  = 34

...

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 )

...

Then, one has to initialize the object of the class CSPadImageProducer

Code Block

    cspadimg = cip.CSPadImageProducer(rotation=0, tiltIsOn=True, mirror=True)

...

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:

...

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()

...

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()

...

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 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=runnum, 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.getCSPadImage( 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()
#----------------------------------------------
if __name__ == "__main__" :
    main_example_xpp()
    sys.exit ( 'End of test.' )

...

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          as calp
import CalibParsEvaluated as cpe
import GlobalGraphics     as gg # For test purpose in main only
import HDF5Methods        as hm # For test purpose in main only
#----------------------------------------------
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/CXI/cxi80410/hdf5/cxi80410-r0628.h5',  628
    dsname        = '/Configure:0000/Run:0000/CalibCycle:0000/CsPad::ElementV2/CxiDs1.0:Cspad.0/data'
    path_calib    = '/reg/d/psdm/CXI/cxi80410/calib/CsPad::CalibV1/CxiDs1.0:Cspad.0'
    Range         = (1000,3500)
 
    calp.calibpars.setCalibParsForPath (run=runnum, path=path_calib)
    #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)
    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.]])

...

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.

References