PSCalib/src/SegGeometryEpix100V1.py

Go to the documentation of this file.
00001 #--------------------------------------------------------------------------
00002 # File and Version Information:
00003 #  $Id: SegGeometryEpix100V1.py 12411 2016-08-05 17:46:52Z dubrovin@SLAC.STANFORD.EDU $
00004 #
00005 # Description:
00006 #  Module SegGeometryEpix100V1...
00007 #------------------------------------------------------------------------
00008 
00009 """Class :py:class:`PSCalib.SegGeometryEpix100V1` describes the Epix100 V1 sensor geometry.
00010 
00011 In this class we use natural matrix notations like in data array
00012 \n We assume that
00013 \n * 2x2 ASICs has 704 rows and 768 columns,
00014 \n * Epix100 has a pixel size 50x50um, wide pixel size 50x175um
00015 \n * Epix10k has a pixel size 100x100um, 
00016 \n * X-Y coordinate system origin is in the sensor center,
00017 \n * pixel (r,c)=(0,0) is in the top left corner of the matrix, has coordinates (xmin,ymax), as shown below
00018 \n ::
00019 
00020    (Xmin,Ymax)      ^ Y          (Xmax,Ymax)
00021    (0,0)            |            (0,768)
00022       ------------------------------
00023       |             |              |
00024       |             |              |
00025       |             |              |
00026       |             |              |
00027       |             |              |
00028       |             |              |
00029       |             |              |
00030     --|-------------+--------------|----> X
00031       |             |              |
00032       |             |              |
00033       |             |              |
00034       |             |              |
00035       |             |              |
00036       |             |              |
00037       |             |              |
00038       ------------------------------
00039    (704,0)          |           (704,768)
00040    (Xmin,Ymin)                  (Xmax,Ymin)
00041 
00042 
00043 Usage of interface methods::
00044 
00045     from SegGeometryEpix100V1 import epix2x2_one as sg
00046 
00047     sg.print_seg_info(0377)
00048 
00049     size_arr = sg.size()
00050     rows     = sg.rows()
00051     cols     = sg.cols()
00052     shape    = sg.shape()
00053     pix_size = pixel_scale_size()
00054 
00055     area     = sg.pixel_area_array()
00056     mask     = sg.pixel_mask_array(mbits=0377)
00057     # where mbits = +1-edges, +2-wide pixels
00058 
00059     sizeX = sg.pixel_size_array('X')
00060     sizeX, sizeY, sizeZ = sg.pixel_size_array()
00061 
00062     X     = sg.pixel_coord_array('X')
00063     X,Y,Z = sg.pixel_coord_array()
00064     print 'X.shape =', X.shape
00065 
00066     xmin, ymin, zmin = sg.pixel_coord_min()
00067     xmax, ymax, zmax = sg.pixel_coord_max()
00068     xmin = sg.pixel_coord_min('X')
00069     ymax = sg.pixel_coord_max('Y')
00070 
00071     # global method for rotation of numpy arrays:
00072     Xrot, Yrot = rotation(X, Y, C, S)
00073     ...
00074 
00075 This software was developed for the SIT project.  If you use all or 
00076 part of it, please give an appropriate acknowledgment.
00077 
00078 @see :py:class:`PSCalib.SegGeometry`
00079 
00080 @version $Id: 2013-03-08$
00081 
00082 @author Mikhail S. Dubrovin
00083 """
00084 
00085 #--------------------------------
00086 #  Module's version from CVS --
00087 #--------------------------------
00088 __version__ = "$Revision: 12411 $"
00089 # $Source$
00090 #--------------------------------
00091 
00092 import sys
00093 import math
00094 import numpy as np
00095 from time import time
00096 
00097 from PSCalib.SegGeometry import *
00098 
00099 #------------------------------
00100 
00101 class SegGeometryEpix100V1(SegGeometry) :
00102     """Self-sufficient class for generation of Epix100 2x2 sensor pixel coordinate array"""
00103 
00104     _rows  = 704     # Number of rows in 2x2
00105     _cols  = 768     # Number of cols in 2x2
00106     _pixs  =  50     # Pixel size in um (micrometer)
00107     _pixw  = 175     # Wide pixel size in um (micrometer)
00108     _pixd  = 400.00  # Pixel depth in um (micrometer)
00109 
00110     _colsh = _cols/2
00111     _rowsh = _rows/2
00112     _pixsh = _pixs/2
00113     _pixwh = _pixw/2
00114 
00115 #------------------------------
00116 
00117     def __init__(sp, use_wide_pix_center=True) :
00118         #print 'SegGeometryEpix100V1.__init__()'
00119 
00120         SegGeometry.__init__(sp)
00121         #super(SegGeometry, self).__init__()
00122 
00123         sp.use_wide_pix_center = use_wide_pix_center
00124 
00125         sp.x_pix_arr_um_offset  = None
00126         sp.pix_area_arr = None
00127 
00128         sp.make_pixel_coord_arrs()
00129 
00130 #------------------------------
00131 
00132     def make_pixel_coord_arrs(sp) :
00133         """Makes [704,768] maps of x, y, and z 2x2 pixel coordinates
00134         with origin in the center of 2x2
00135         """        
00136         x_rhs = np.arange(sp._colsh)*sp._pixs + sp._pixw - sp._pixsh
00137         if sp.use_wide_pix_center : x_rhs[0] = sp._pixwh # set x-coordinate of the wide pixel in its geometry center
00138         sp.x_arr_um = np.hstack([-x_rhs[::-1], x_rhs])
00139 
00140         y_rhs = np.arange(sp._rowsh)*sp._pixs + sp._pixw - sp._pixsh
00141         if sp.use_wide_pix_center : y_rhs[0] = sp._pixwh # set y-coordinate of the wide pixel in its geometry center
00142         sp.y_arr_um = np.hstack([-y_rhs[::-1], y_rhs])
00143 
00144         sp.x_pix_arr_um, sp.y_pix_arr_um  = np.meshgrid(sp.x_arr_um, sp.y_arr_um)
00145         sp.z_pix_arr_um = np.zeros((sp._rows,sp._cols))
00146         
00147 #------------------------------
00148 
00149     def make_pixel_size_arrs(sp) :
00150         """Makes [704,768] maps of x, y, and z 2x2 pixel size 
00151         """        
00152         if sp.pix_area_arr is not None : return
00153 
00154         x_rhs_size_um = np.ones(sp._colsh)*sp._pixs
00155         x_rhs_size_um[0] = sp._pixw
00156         x_arr_size_um = np.hstack([x_rhs_size_um[::-1],x_rhs_size_um])
00157 
00158         y_rhs_size_um = np.ones(sp._rowsh)*sp._pixs
00159         y_rhs_size_um[0] = sp._pixw
00160         y_arr_size_um = np.hstack([y_rhs_size_um[::-1],y_rhs_size_um])
00161 
00162         sp.x_pix_size_um, sp.y_pix_size_um = np.meshgrid(x_arr_size_um, y_arr_size_um)
00163         sp.z_pix_size_um = np.ones((sp._rows,sp._cols)) * sp._pixd
00164         
00165         factor = 1./(sp._pixs*sp._pixs)
00166         sp.pix_area_arr = sp.x_pix_size_um * sp.y_pix_size_um * factor
00167 
00168 #------------------------------
00169 
00170     def print_member_data(sp) :
00171         print 'SegGeometryEpix100V1.print_member_data()'
00172         print '    _rows : %d'     % sp._rows
00173         print '    _cols : %d'     % sp._cols
00174         print '    _pixs  : %7.2f' % sp._pixs 
00175         print '    _pixw  : %7.2f' % sp._pixw 
00176         print '    _pixd  : %7.2f' % sp._pixd 
00177         print '    _colsh : %d'    % sp._colsh
00178         print '    _pixsh : %7.2f' % sp._pixsh
00179         print '    _pixwh : %7.2f' % sp._pixwh
00180 
00181 #------------------------------
00182 
00183     def print_pixel_size_arrs(sp) :
00184         print 'SegGeometryEpix100V1.print_pixel_size_arrs()'
00185         sp.make_pixel_size_arrs()
00186         print 'sp.x_pix_size_um[348:358,378:388]:\n', sp.x_pix_size_um[348:358,378:388]
00187         print 'sp.x_pix_size_um.shape = ',            sp.x_pix_size_um.shape
00188         print 'sp.y_pix_size_um:\n',                  sp.y_pix_size_um
00189         print 'sp.y_pix_size_um.shape = ',            sp.y_pix_size_um.shape
00190         print 'sp.z_pix_size_um:\n',                  sp.z_pix_size_um
00191         print 'sp.z_pix_size_um.shape = ',            sp.z_pix_size_um.shape
00192         print 'sp.pix_area_arr[348:358,378:388]:\n',  sp.pix_area_arr[348:358,378:388]
00193         print 'sp.pix_area_arr.shape  = ',            sp.pix_area_arr.shape
00194 
00195 #------------------------------
00196 
00197     def print_maps_seg_um(sp) :
00198         print 'SegGeometryEpix100V1.print_maps_seg_um()'
00199         print 'x_pix_arr_um =\n',      sp.x_pix_arr_um
00200         print 'x_pix_arr_um.shape = ', sp.x_pix_arr_um.shape
00201         print 'y_pix_arr_um =\n',      sp.y_pix_arr_um
00202         print 'y_pix_arr_um.shape = ', sp.y_pix_arr_um.shape
00203         print 'z_pix_arr_um =\n',      sp.z_pix_arr_um
00204         print 'z_pix_arr_um.shape = ', sp.z_pix_arr_um.shape
00205 
00206 #------------------------------
00207 
00208     def print_xy_1darr_um(sp) :
00209         print 'SegGeometryEpix100V1.print_xy_1darr_um()'
00210         print 'x_arr_um:\n',       sp.x_arr_um
00211         print 'x_arr_um.shape = ', sp.x_arr_um.shape
00212         print 'y_arr_um:\n',       sp.y_arr_um
00213         print 'y_arr_um.shape = ', sp.y_arr_um.shape
00214 
00215 #------------------------------
00216 
00217     def print_xyz_min_max_um(sp) :
00218         print 'SegGeometryEpix100V1.print_xyz_min_max_um()'
00219         xmin, ymin, zmin = sp.get_xyz_min_um()
00220         xmax, ymax, zmax = sp.get_xyz_max_um()
00221         print 'In [um] xmin:%9.2f, xmax:%9.2f, ymin:%9.2f, ymax:%9.2f, zmin:%9.2f, zmax:%9.2f' \
00222               % (xmin, xmax, ymin, ymax, zmin, zmax)
00223 
00224 #------------------------------
00225 
00226     def get_xyz_min_um(sp) : 
00227         return sp.x_arr_um[0], sp.y_arr_um[-1], 0
00228 
00229     def get_xyz_max_um(sp) : 
00230         return sp.x_arr_um[-1], sp.y_arr_um[0], 0
00231 
00232     def get_seg_xy_maps_um(sp) : 
00233         return sp.x_pix_arr_um, sp.y_pix_arr_um
00234 
00235     def get_seg_xyz_maps_um(sp) : 
00236         return sp.x_pix_arr_um, sp.y_pix_arr_um, sp.z_pix_arr_um
00237 
00238     def get_seg_xy_maps_um_with_offset(sp) : 
00239         if  sp.x_pix_arr_um_offset is None :
00240             x_min_um, y_min_um, z_min_um = sp.get_xyz_min_um()
00241             sp.x_pix_arr_um_offset = sp.x_pix_arr_um - x_min_um
00242             sp.y_pix_arr_um_offset = sp.y_pix_arr_um - y_min_um
00243         return sp.x_pix_arr_um_offset, sp.y_pix_arr_um_offset
00244 
00245     def get_seg_xyz_maps_um_with_offset(sp) : 
00246         if  sp.x_pix_arr_um_offset is None :
00247             x_min_um, y_min_um, z_min_um = sp.get_xyz_min_um()
00248             sp.x_pix_arr_um_offset = sp.x_pix_arr_um - x_min_um
00249             sp.y_pix_arr_um_offset = sp.y_pix_arr_um - y_min_um
00250             sp.z_pix_arr_um_offset = sp.z_pix_arr_um - z_min_um
00251         return sp.x_pix_arr_um_offset, sp.y_pix_arr_um_offset, sp.z_pix_arr_um_offset
00252 
00253     def get_pix_size_um(sp) : 
00254         return sp._pixs
00255 
00256     def get_pixel_size_arrs_um(sp) :
00257         sp.make_pixel_size_arrs()
00258         return sp.x_pix_size_um, sp.y_pix_size_um, sp.z_pix_size_um
00259 
00260     def get_pixel_area_arr(sp) :
00261         sp.make_pixel_size_arrs()
00262         return sp.pix_area_arr
00263 
00264     def get_seg_xy_maps_pix(sp) :
00265         sp.x_pix_arr_pix = sp.x_pix_arr_um/sp._pixs
00266         sp.y_pix_arr_pix = sp.y_pix_arr_um/sp._pixs
00267         return sp.x_pix_arr_pix, sp.y_pix_arr_pix
00268 
00269     def get_seg_xy_maps_pix_with_offset(sp) :
00270         X, Y = sp.get_seg_xy_maps_pix()
00271         xmin, ymin = X.min(), Y.min()
00272         return X-xmin, Y-ymin
00273 
00274 #------------------------------
00275 # INTERFACE METHODS
00276 #------------------------------
00277 
00278     def print_seg_info(sp, pbits=0) :
00279         """ Prints segment info for selected bits
00280             pbits = 0 - nothing
00281                    +1 - member data
00282                    +2 - coordinate maps in um
00283                    +4 - min, max coordinates in um
00284                    +8 - x, y 1-d pixel coordinate arrays in um
00285         """
00286         if pbits & 1 : sp.print_member_data()
00287         if pbits & 2 : sp.print_maps_seg_um()
00288         if pbits & 4 : sp.print_xyz_min_max_um()
00289         if pbits & 8 : sp.print_xy_1darr_um()
00290 
00291 
00292     def size(sp) :
00293         """ Returns number of pixels in segment
00294         """
00295         return sp._rows*sp._cols
00296 
00297 
00298     def rows(sp) :
00299         """ Returns number of rows in segment
00300         """
00301         return sp._rows
00302 
00303 
00304     def cols(sp) :
00305         """ Returns number of cols in segment
00306         """
00307         return sp._cols
00308 
00309 
00310     def shape(sp) :
00311         """ Returns shape of the segment (rows, cols)
00312         """
00313         return (sp._rows, sp._cols)
00314 
00315 
00316     def pixel_scale_size(sp) :
00317         """ Returns pixel size in um for indexing
00318         """
00319         return sp._pixs
00320 
00321 
00322     def pixel_area_array(sp) :
00323         """ Returns pixel area array of shape=(rows, cols)
00324         """
00325         return sp.get_pixel_area_arr()
00326 
00327 
00328     def pixel_size_array(sp, axis=None) :
00329         """ Returns numpy array of pixel sizes in um for AXIS
00330         """
00331         return sp.return_switch(sp.get_pixel_size_arrs_um, axis)
00332 
00333 
00334     def pixel_coord_array(sp, axis=None) :
00335         """ Returns numpy array of segment pixel coordinates in um for AXIS
00336         """
00337         return sp.return_switch(sp.get_seg_xyz_maps_um, axis)
00338 
00339 
00340     def pixel_coord_min(sp, axis=None) :
00341         """ Returns minimal value in the array of segment pixel coordinates in um for AXIS
00342         """
00343         return sp.return_switch(sp.get_xyz_min_um, axis)
00344 
00345 
00346     def pixel_coord_max(sp, axis=None) :
00347         """ Returns maximal value in the array of segment pixel coordinates in um for AXIS
00348         """
00349         return sp.return_switch(sp.get_xyz_max_um, axis)
00350 
00351 
00352     def pixel_mask_array(sp, mbits=0377) :
00353         """ Returns numpy array of pixel mask: 1/0 = ok/masked,
00354             mbits: +1 - mask edges
00355                    +2 - mask two central columns 
00356         """
00357         zero_col = np.zeros(sp._rows,dtype=np.uint8)
00358         zero_row = np.zeros(sp._cols,dtype=np.uint8)
00359         mask     = np.ones((sp._rows,sp._cols),dtype=np.uint8)
00360 
00361         if mbits & 1 : 
00362         # mask edges
00363             mask[0, :] = zero_row # mask top    edge
00364             mask[-1,:] = zero_row # mask bottom edge
00365             mask[:, 0] = zero_col # mask left   edge
00366             mask[:,-1] = zero_col # mask right  edge
00367 
00368         if mbits & 2 : 
00369         # mask two central columns
00370             mask[:,sp._colsh-1] = zero_col # mask central-left  column
00371             mask[:,sp._colsh]   = zero_col # mask central-right column
00372             mask[sp._rowsh-1]   = zero_row # mask central-low   row
00373             mask[sp._rowsh]     = zero_row # mask central-high  row
00374 
00375         return mask
00376 
00377   
00378 #------------------------------
00379 #------------------------------
00380 
00381 epix2x2_one = SegGeometryEpix100V1(use_wide_pix_center=False)
00382 
00383 #------------------------------
00384 #------------------------------
00385 #------------------------------
00386 #----------- TEST -------------
00387 #------------------------------
00388 #------------------------------
00389 #------------------------------
00390 
00391 if __name__ == "__main__" :
00392     import pyimgalgos.GlobalGraphics as gg # For test purpose in main only
00393 
00394 
00395 def test_xyz_min_max() :
00396     w = SegGeometryEpix100V1()
00397     w.print_xyz_min_max_um() 
00398     print 'Ymin = ', w.pixel_coord_min('Y')
00399     print 'Ymax = ', w.pixel_coord_max('Y')
00400 
00401 #------------------------------
00402 
00403 def test_xyz_maps() :
00404 
00405     w = SegGeometryEpix100V1()
00406     w.print_maps_seg_um()
00407 
00408     titles = ['X map','Y map']
00409     #for i,arr2d in enumerate([w.x_pix_arr,w.y_pix_arr]) :
00410     for i,arr2d in enumerate( w.get_seg_xy_maps_pix() ) :
00411         amp_range = (arr2d.min(), arr2d.max())
00412         gg.plotImageLarge(arr2d, amp_range=amp_range, figsize=(10,5), title=titles[i])
00413         gg.move(200*i,100*i)
00414 
00415     gg.show()
00416 
00417 #------------------------------
00418 
00419 def test_2x2_img() :
00420 
00421     t0_sec = time()
00422     w = SegGeometryEpix100V1(use_wide_pix_center=False)
00423     #w = SegGeometryEpix100V1(use_wide_pix_center=True)
00424     print 'Consumed time for coordinate arrays (sec) =', time()-t0_sec
00425 
00426     X,Y = w.get_seg_xy_maps_pix()
00427 
00428     w.print_seg_info(0377)
00429 
00430     #print 'X(pix) :\n', X
00431     print 'X.shape =', X.shape
00432 
00433     xmin, ymin, zmin = w.get_xyz_min_um()
00434     xmax, ymax, zmax = w.get_xyz_max_um()
00435     xmin /= w.pixel_scale_size()
00436     xmax /= w.pixel_scale_size()
00437     ymin /= w.pixel_scale_size()
00438     ymax /= w.pixel_scale_size()
00439 
00440     xsize = xmax - xmin + 1
00441     ysize = ymax - ymin + 1
00442     print 'xsize =', xsize
00443     print 'ysize =', ysize
00444 
00445 #    H, Xedges, Yedges = np.histogram2d(X.flatten(), Y.flatten(), bins=[xsize,ysize], range=[[xmin, xmax], [ymin, ymax]], normed=False, weights=X.flatten()+Y.flatten()) 
00446 
00447 #    print 'Xedges:', Xedges
00448 #    print 'Yedges:', Yedges
00449 #    print 'H.shape:', H.shape
00450 
00451 #    gg.plotImageLarge(H, amp_range=(-800, 800), figsize=(8,10)) # range=(-1, 2), 
00452 #    gg.show()
00453 
00454 #------------------------------
00455 
00456 def test_2x2_img_easy() :
00457     pc2x2 = SegGeometryEpix100V1(use_wide_pix_center=False)
00458     X,Y = pc2x2.get_seg_xy_maps_pix_with_offset()
00459     iX, iY = (X+0.25).astype(int), (Y+0.25).astype(int)
00460     img = gg.getImageFromIndexArrays(iX,iY,iX+iY)
00461     gg.plotImageLarge(img, amp_range=(0, 1500), figsize=(8,10))
00462     gg.show()
00463 
00464 #------------------------------
00465 
00466 def test_pix_sizes() :
00467     w = SegGeometryEpix100V1()
00468     w.print_pixel_size_arrs()
00469     size_arrX = w.pixel_size_array('X')
00470     size_arrY = w.pixel_size_array('Y')
00471     area_arr  = w.pixel_area_array()
00472     print 'area_arr[348:358,378:388]:\n',   area_arr[348:358,378:388]
00473     print 'area_arr.shape :',               area_arr.shape
00474     print 'size_arrX[348:358,378:388]:\n',  size_arrX[348:358,378:388]
00475     print 'size_arrX.shape :',              size_arrX.shape
00476     print 'size_arrY[348:358,378:388]:\n',  size_arrY[348:358,378:388]
00477     print 'size_arrY.shape :',              size_arrY.shape
00478 
00479 #------------------------------
00480 
00481 def test_2x2_mask(mbits=0377) :
00482     pc2x2 = SegGeometryEpix100V1(use_wide_pix_center=False)
00483     X, Y = pc2x2.get_seg_xy_maps_pix_with_offset()
00484     mask = pc2x2.pixel_mask_array(mbits)
00485     mask[mask==0]=3
00486     iX, iY = (X+0.25).astype(int), (Y+0.25).astype(int)
00487     img = gg.getImageFromIndexArrays(iX,iY,mask)
00488     gg.plotImageLarge(img, amp_range=(-1, 2), figsize=(8,10))
00489     gg.show()
00490 
00491 #------------------------------
00492  
00493 if __name__ == "__main__" :
00494 
00495     if len(sys.argv)==1   : print 'For test(s) use command: python', sys.argv[0], '<test-number=0-5>'
00496     elif sys.argv[1]=='0' : test_xyz_min_max()
00497     elif sys.argv[1]=='1' : test_xyz_maps()
00498     elif sys.argv[1]=='2' : test_2x2_img()
00499     elif sys.argv[1]=='3' : test_2x2_img_easy()
00500     elif sys.argv[1]=='4' : test_pix_sizes()
00501     elif sys.argv[1]=='5' : test_2x2_mask(mbits=1+2)
00502     else : print 'Non-expected arguments: sys.argv=', sys.argv
00503 
00504     sys.exit( 'End of test.' )
00505 
00506 #------------------------------

Generated on 19 Dec 2016 for PSANAmodules by  doxygen 1.4.7