00001
00002
00003
00004
00005
00006
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
00087
00088 __version__ = "$Revision: 12411 $"
00089
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
00105 _cols = 768
00106 _pixs = 50
00107 _pixw = 175
00108 _pixd = 400.00
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
00119
00120 SegGeometry.__init__(sp)
00121
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
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
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
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
00363 mask[0, :] = zero_row
00364 mask[-1,:] = zero_row
00365 mask[:, 0] = zero_col
00366 mask[:,-1] = zero_col
00367
00368 if mbits & 2 :
00369
00370 mask[:,sp._colsh-1] = zero_col
00371 mask[:,sp._colsh] = zero_col
00372 mask[sp._rowsh-1] = zero_row
00373 mask[sp._rowsh] = zero_row
00374
00375 return mask
00376
00377
00378
00379
00380
00381 epix2x2_one = SegGeometryEpix100V1(use_wide_pix_center=False)
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391 if __name__ == "__main__" :
00392 import pyimgalgos.GlobalGraphics as gg
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
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
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
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
00446
00447
00448
00449
00450
00451
00452
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