Versions Compared

Key

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

Content

Table of Contents

Introduction

In this note we describe the python-based PyCSPadImage package which is intended to
evaluate and provide access to the pixel coordinate arrays. In addition, it
converts the CSPAD raw data from HDF5 file to the geometry-corrected 2-D image array.
This package can be used in a stand-alone python code.

...

Package PyCSPadImage

Content

...

The python-based PyCSPadImage package consists of modules:

Status

Module

For

Description

(tick)

PixCoords2x1.py

2x1

defines the 2x1 section pixel coordinates

...

(tick)

CSPAD2x2CalibParsDefault.py

CSPAD2x2

defines default CSPAD2x2 calibration parameters

(tick)

CSPAD2x2CalibPars.py

CSPAD2x2

provides access to the CSPAD2x2 calibration parameters

(tick)

CSPAD2x2PixCoords.py

CSPAD2x2

evaluates the CSPAD2x2 pixel coordinates

(tick)

CSPAD2x2Examples.py

CSPAD2x2

CSPAD2x2 examples

...

(tick)

CSPadConfigPars.py

CSPAD

defines CSPAD configuration parameters

(tick)

CalibParsDefault.py

CSPAD

defines default CSPAD calibration parameters

(tick)

CSPADCalibParsEvaluated.py

CSPAD

evaluates the center_global from other quad parametes

(tick)

CalibPars.py

CSPAD

provides access to the CSPAD calibration parameters

(tick)

CSPADPixCoords.py

CSPAD

evaluates the CSPAD pixel coordinates

(tick)

Examples.py

CSPAD

CSPAD examples

(plus)

CSPadImageProducer.py

CSPAD

Depricated

...

(tick)

GlobalGraphics.py

Utils 

Graphical utils

(tick)

GlobalMethods.py

Utils 

Global methods

(tick)

HDF5Methods.py

 

Utils

Common methods for operations with HDF5 files

(plus)

Alignment.py

Internal

It is used for alignment purpose

How to 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

cdpython PyCSPadImage/src/Examples.py 1

Import modules

Code Block
import sys
import os
import numpy as np
import PyCSPadImage.CalibPars    <==== All source-code files are located hereas calp
pythonimport Examples.py 1

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

PyCSPadImage.CSPadConfigPars    as ccp
import PyCSPadImage.CSPadImageProducer as cip
import PyCSPadImage.CSPADPixCoords     as pixcoor
import PyCSPadImage.PixCoords2x1       as pixcoor2x1
import PyCSPadImage.GlobalGraphics     as gg
import PyCSPadImage.GlobalMethods      as gm
import PyCSPadImage.HDF5Methods        as hm

External parameters

HDF5 data file:

Code Block
   fname = '/reg/d/psdm/xpp/xpptut13/hdf5/xpptut13-r0150.h5' # to test XPP data
   fname
Code Block

    fname  = '/reg/d/psdm/CXIcxi/cxi80410cxitut13/hdf5/cxi80410cxitut13-r0628r1150.h5'
 # to test dsname = '/Configure:0000/Run:0000/CalibCycle:0000CXI data

Path to the directory with calibration types:

Code Block
   path_calib = '/reg/d/psdm/CXI/cxi80410/calib/CsPad::ElementV2CalibV1/CxiDs1.0:Cspad.0/data'
    event  = 34
Note
  • In principal, the path to the calibration data types can be defined automatically, but there is a chance that user would want to keep calibration files in non-standard place.
  • The CSPad dataset can be also found automatically, but there might be more than one CSPad detector in experiment.

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.
Default version of the configuration parameters can be wrong, if not all 2x1 are in use.

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 or False - to account or not the tiny tilt angle of 2x1 sections.
  • mirror = True or False - 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:

  1. for entire CSPAD with shape=(4,8,185,388)
  2. 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.

Image RemovedImage Removed

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.' )

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

path_calib = '/reg/d/psdm/xpp/xpptut13/calib/CsPad::CalibV1/XppGon.0:Cspad.0/'

HDF5 dataset names for known CSPADs:

Code Block
  
   dsname = '/Configure:0000/Run:0000/CalibCycle:0000/CsPad::ElementV2/CxiDs1.0:Cspad.0/data'
   dsname = '/Configure:0000/Run:0000/CalibCycle:0000/CsPad::ElementV2/CxiDsd.0:Cspad.0/data'
   dsname = '/Configure:0000/Run:0000/CalibCycle:0000/CsPad::ElementV2/XppGon.0:Cspad.0/data'
   dsname = '/Configure:0000/Run:0000/CalibCycle:0000/CsPad::ElementV2/XcsEndstation.0:Cspad.0/data'

Interface to CalibPars.py

This class provides access to the CSPAD calibration parameters.

Code Block
       Regular instantiation:
           ALL parameters are OPTIONAL NAMED parameters;
           path  = '/reg/d/psdm/xpp/xpptut13/calib/CsPad::CalibV1/XppGon.0:Cspad.0/' 
           run   = 123
           calib = CalibPars(path, list_of_clib_types=['center', 'tilt', 'pedestals'])
           arr_pedestals = calib.getCalibPars('pedestals', run)
 
       Other option for instantiation:
           calib    = CalibPars()
           run      = 123  - is an optional, named
           calibdir = '/reg/d/psdm/CXI/cxi35711/calib'
           group    = 'CsPad::CalibV1'
           source   = 'CxiDs1.0:Cspad.0'
           calib.setCalibPars (run, calibdir, group, source)

       Get array of calibration parameters for specified type and run number:
           type = 'center'
           arr  = calib.getCalibPars (type[,run])

Interface to CSPadConfigPars.py

This class provides access to the CSPAD configuration parameters.

Code Block
    1. Sets a bunch of default configuration parameters,
       loads current coniguration parameters from hdf5 file or from external parameters.
    2. Provides access to current coniguration parameters
    3. Contains conversion methods for arrays between raw data and entire cspad.
    
    Interface
    =========
    1.  Instatiation
    1.1 Default constructor sets default parameters for indPairsInQuads & quadNumsInEvent:

        config = CSPadConfigPars()

    1.2 Initialization of configuration parameters using hdf5 file, for example:
        fname  = '/reg/d/psdm/xpp/xpp66213/hdf5/xpp66213-r0150.h5'
        dsname = '/Configure:0000/Run:0000/CalibCycle:0000/CsPad::ElementV2/XppGon.0:Cspad.0/data'

        config.setCSPadConfiguration( fname, dsname, event=0 ):

    1.3 Initialization of configuration parameters using external arrays, for example:        
        indPairs = np.arange(32)
        indPairs.shape = (4,8)
        quadNums = np.arange(4)

        config.setCSPadConfigArrays( indPairsInQuads=indPairs, quadNumsInEvent=quadNums )

   2.  Access methods:

    2.1 Access to indPairsInQuads and quadNumsInEvent:
        quadNums = config.getQuadNumsInEvent()
        indPairs = config.getIndPairsInQuads()
        config.printCSPadConfigPars()

    2.2 Access to static class parameters:    
        import CSPadConfigPars as ccp
        my_wid2x1 = ccp.CSPadConfigPars().wid2x1
        etc...

    3.  Conversions between entire (4,8,185,388) and shaped as data (N<32,185,388) cspad pixel array shapes:

    3.1 Conversion of the entire cspad pixel array arr_entire_cspad with shape (4,8,185,388)
        in to the arr_raw_data, shaped as data (N<32,185,388):
        arr_raw_data = config.getCSPadPixArrayShapedAsData(arr_entire_cspad)

    3.2 Conversion of the cspad pixel array arr_raw_data shaped as data (N<32,185,388)
        in to the entire cspad pixel array arr_entire_cspad with shape (4,8,185,388):
        arr_entire_cspad = getCSPadPixArrayFromArrayShapedAsData(arr_raw_data)

    4.  Tests
        To test CSPadConfigPars from release directory use command:
        python PyCSPadImage/src/CSPadConfigPars.py <test-number>
        where <test-number> stands for  0, 1, 2, or 3

Interface to CSPADPixCoords.py

Class for generation of CSPad pixel coordinate array with and without data base

Code Block
    Interface
    =========
       1.0 Instantiation with default parameters taken from optical measurement for XPP on 2013-01-29:
           coord = CSPADPixCoords()

       1.1 Instantiation with external geometry parameters:
 
           All parameters optional. Default values will be used if parameters are not specified.
           xc    - np.array(...), shape=(3, 4, 8)) [um]
 
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.],  
          yc    - np.array(...), shape=(3, 4, 8)) [um]
  [0.,  0.,  0.,  0.,  0., tilt 0.,  0.,  0.],  - np.array(...), shape=(4, 8)) [deg]
           coord = CSPADPixCoords(xc_um=xc,    yc_um=yc, tilt_deg=tilt)


    [0.,   01.,2 Instantiation 0.,with regular 0.,  0.,  0.,  0.,  0.],  
     calibration parameters:

           path  = '/reg/neh/home1/dubrovin/LCLS/CSPadAlignment-v01/calib-xpp-2013-01-29'
           run   = 123
 [0.,  0.,  0.,  0.,  0.,  0.,calib = 0.CalibPars(path,  0.]])
Note

ALL arrays are shown here FOR TEST PURPOSE ONLY !!! and they are not consistent with any real detector. The orient_deg is not consistent with real orientation as well...

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)
run)
           coord = CSPADPixCoords(calib)

       1.2 Access methods:
           Get arrays of pixel coordinates in mu with shape: [2,185,388]
            X, Y = wcoord.get_cspad_pix_coordinate_arrays_pixum  ()

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)

Image RemovedImage Removed

config=None)
           or in integer pixels:
           iX,iY = coord.get_cspad_pix_coordinate_arrays_pix (config=None)

       1.3 Get image  
           img = coord.get_cspad_image(data,config)     

Examples

Module Examples.py contains a few examples of how to use the PyCSPadImage packageIn order to get an image of intensity the weights array needs to be provided.

References