CalibManager/src/OpticAlignmentCspadV2.py

Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 
00003 #--------------------------------------------------------------------------
00004 # File and Version Information:
00005 #  $Id: OpticAlignmentCspadV2.py 12520 2016-08-23 17:12:08Z dubrovin@SLAC.STANFORD.EDU $
00006 #
00007 # Description:
00008 #------------------------------------------------------------------------
00009 """ Processing of optical measurements for XPP-CSPAD (fixed geometry)
00010 
00011 @see OpticAlignmentCspadMethods.py
00012 
00013 @version $Id: OpticAlignmentCspadV2.py 12520 2016-08-23 17:12:08Z dubrovin@SLAC.STANFORD.EDU $
00014 
00015 @author Mikhail S. Dubrovin
00016 """
00017 
00018 #------------------------------
00019 __version__ = "$Revision: 12520 $"
00020 # $Source$
00021 #----------------------------------
00022 #import os
00023 #import sys
00024 #import numpy
00025 #import numpy as np
00026 #import math
00027 #from time import localtime, gmtime, strftime, clock, time, sleep
00028 
00029 #import matplotlib.pyplot as plt
00030 #import matplotlib.lines  as lines
00031 
00032 from CalibManager.OpticAlignmentCspadMethods import *
00033 #from OpticAlignmentCspadMethods import *
00034 
00035 #----------------------------------
00036 #  Numeration of quads in the metrology file should be consistent with numeration in DAQ.
00037 #  Orientation of CSPAD for
00038 #
00039 #  n90=0,          n90=1, etc.
00040 #  ^               ^           
00041 #  | Q0  Q1        | Q1  Q2    
00042 #  |               |           
00043 #  | Q3  Q2        | Q0  Q3    
00044 #  +-------->      +-------->  
00045 #
00046 #----------------------------------
00047 
00048 class OpticAlignmentCspadV2 (OpticAlignmentCspadMethods) :
00049     """OpticAlignmentCspadV2"""
00050 
00051     # Numeration of 2x1 corners in XPP-CSPAD optical measurements depending on quad orientation
00052     quad_r090 = [0,  32,29,30,31,  28,25,26,27,      4,1,2,3,      8,5,6,7,  16,13,14,15,   12,9,10,11,  20,17,18,19,  24,21,22,23]
00053     quad_r000 = [0,      1,2,3,4,      5,6,7,8,   9,10,11,12,  13,14,15,16,  17,18,19,20,  21,22,23,24,  25,26,27,28,  29,30,31,32]
00054     quad_r270 = [0,   10,11,12,9,  14,15,16,13,  22,23,24,21,  18,19,20,17,  26,27,28,25,  30,31,32,29,      6,7,8,5,      2,3,4,1]
00055     quad_r180 = [0,  23,24,21,22,  19,20,17,18,  31,32,29,30,  27,28,25,26,      7,8,5,6,      3,4,1,2,  15,16,13,14,   11,12,9,10]
00056 
00057 
00058     quad_n90_in_det = [1,0,3,2]
00059 
00060     def __init__(self, fname=None, path='calib-tmp', save_calib_files=True, print_bits=07777, plot_bits=0377, exp='Any', det='CSPAD-XPP', n90=0):
00061         """Constructor."""
00062 
00063         if print_bits &  1 : print 'Start OpticAlignmentCspadV2'
00064 
00065         if fname is not None : self.fname = fname
00066         else                 : self.fname = '/reg/neh/home1/dubrovin/LCLS/CSPadMetrologyProc/metrology_standard.txt'
00067 
00068         if not os.path.lexists(self.fname) : 
00069             if print_bits &  1 : print 'Non-available input file: ' + self.fname
00070             return
00071 
00072         self.path             = path
00073         self.save_calib_files = save_calib_files
00074         self.print_bits       = print_bits
00075         self.plot_bits        = plot_bits
00076         self.exp              = exp
00077         self.det              = det
00078 
00079         self.fname_center_um  = os.path.join(self.path, 'center_global_um-0-end.data')
00080         self.fname_center     = os.path.join(self.path, 'center_global-0-end.data')
00081         self.fname_tilt       = os.path.join(self.path, 'tilt-0-end.data')
00082         self.fname_geometry   = os.path.join(self.path, 'geometry-0-end.data')
00083 
00084         self.fname_plot_det   = os.path.join(self.path, 'metrology_standard_det.png')
00085 
00086         self.readOpticalAlignmentFile()
00087         self.changeNumerationToQuadsV1(n90)
00088         self.evaluate_deviation_from_flatness()
00089         self.evaluate_center_coordinates()
00090         self.evaluate_length_width_angle(n90)
00091 
00092         self.present_results()
00093 
00094 
00095 #----------------------------------
00096 
00097     def present_results(self): 
00098 
00099         if self.print_bits & 2 : print '\n' + self.txt_deviation_from_flatness()
00100         if self.print_bits & 4 : print '\nQuality check in XY plane:\n', self.txt_qc_table_xy() 
00101         if self.print_bits & 8 : print '\nQuality check in Z:\n', self.txt_qc_table_z()
00102 
00103         center_txt_um  = self.txt_center_um_formatted_array (format='%6i  ')
00104         center_txt_pix = self.txt_center_pix_formatted_array(format='%7.2f  ')
00105         tilt_txt       = self.txt_tilt_formatted_array(format='%8.5f  ')
00106         geometry_txt   = self.txt_geometry()
00107 
00108         if self.print_bits &  16 : print 'X, Y, and Z coordinates of the 2x1 center_global (um):\n' + center_txt_um
00109         if self.print_bits &  32 : print '\nCalibration type "center_global" in pixels:\n' + center_txt_pix
00110         if self.print_bits &  64 : print '\nCalibration type "tilt" - degree:\n' + tilt_txt
00111         if self.print_bits & 128 : print '\nCalibration type "geometry"\n%s' % geometry_txt
00112 
00113         if self.save_calib_files :
00114             self.create_directory(self.path)
00115             self.save_text_file(self.fname_center_um, center_txt_um)
00116             self.save_text_file(self.fname_center, center_txt_pix)
00117             self.save_text_file(self.fname_tilt, tilt_txt)
00118             self.save_text_file(self.fname_geometry, geometry_txt)
00119 
00120         if self.plot_bits & 1 :
00121             self.arr = self.arr_opt
00122             print 'Draw array from metrology file'
00123             self.drawOpticalAlignmentFile()
00124 
00125         if self.plot_bits & 2 :
00126             self.arr = self.arr_renum
00127             print 'Draw array with re-numerated points for quads'
00128             self.drawOpticalAlignmentFile()
00129 
00130 #----------------------------------
00131 
00132     def readOpticalAlignmentFile(self): 
00133         """Reads the metrology.txt file with original optical measurements.
00134            The numereation of points is changed since 2012-02-26.
00135         """
00136         if self.print_bits & 1 : print 'readOpticalAlignmentFile()'
00137 
00138                                  # quad 0:3
00139                                    # point 1:32
00140                                       # record: point, X, Y, Z 0:3
00141         self.arr_opt = numpy.zeros( (self.nquads, self.npoints+1, 4), dtype=numpy.int32 )
00142 
00143         #infile = './2012-01-12-Run5-DSD-Metrology-corrected.txt'
00144         file = open(self.fname, 'r')
00145         # Print out 7th entry in each line.
00146         for linef in file:
00147 
00148             line = linef.strip('\n')
00149 
00150             #if len(line) == 1 : continue # ignore empty lines
00151             #print len(line),  ' Line: ', line
00152             if not line : continue   # discard empty strings
00153 
00154             list_of_fields = line.split()
00155 
00156             if list_of_fields[0] == 'Quad' : # Treat quad header lines
00157                 self.quad = int(list_of_fields[1])
00158                 if self.print_bits & 256 : print 'Stuff for quad', self.quad  
00159                 continue
00160 
00161             if list_of_fields[0] in ('Sensor', 'Point') : # Treat the title lines
00162                 if self.print_bits & 256 : print 'Comment line:', line  
00163                 continue
00164             
00165             if len(list_of_fields) != 4 : # Ignore lines with non-expected number of fields
00166                 if self.print_bits & 256 : print 'len(list_of_fields) =', len(list_of_fields),
00167                 if self.print_bits & 256 : print 'RECORD IS IGNORED due to unexpected format of the line:',line
00168                 continue              
00169 
00170             point, X, Y, Z = [int(v) for v in list_of_fields]
00171             
00172             #record = [point, X, Y, Z, Title]
00173             if self.print_bits & 256 : print 'ACCEPT RECORD:', point, X, Y, Z #, Title
00174 
00175             self.arr_opt[self.quad,point,:] = [point, X, Y, Z]
00176 
00177         file.close()
00178 
00179         if self.print_bits & 256 : print 'Array of alignment info:\n', self.arr_opt
00180 
00181 
00182 #----------------------------------
00183 
00184     def arrNumTransformationForN90(self, n90=0): 
00185         
00186         if   n90 == 0 : return np.array([self.quad_r090, self.quad_r000, self.quad_r270, self.quad_r180])
00187         elif n90 == 1 : return np.array([self.quad_r000, self.quad_r270, self.quad_r180, self.quad_r090])
00188         elif n90 == 2 : return np.array([self.quad_r270, self.quad_r180, self.quad_r090, self.quad_r000]) 
00189         elif n90 == 3 : return np.array([self.quad_r180, self.quad_r090, self.quad_r000, self.quad_r270])
00190         else        :
00191             print 'arrNumTransformationForN90: WRONG n90=%d, use n90 = 0, 1, 2, or 3' % n90
00192             sys.exit('Exit on warning')
00193 
00194 
00195 #----------------------------------
00196 
00197     def changeNumerationToQuadsV1(self, n90=0): 
00198         """The numereation of points is changed since 2012-02-26.
00199            Bring the numeration of points to old-standard.
00200         """
00201         if self.print_bits & 256 : print 'changeNumerationToQuadsV1()'
00202 
00203                                        # quad 0:3
00204                                          # point 1:32
00205                                             # record: point, X, Y, Z 0:3
00206         self.arr_renum = numpy.zeros( (self.nquads, self.npoints+1, 4), dtype=numpy.int32 )
00207 
00208         # Table of new in positions of old-standard
00209         num_conv = self.arrNumTransformationForN90(n90)
00210 
00211         for quad in range(self.nquads) :
00212             for point in range(1,self.npoints+1,1) :
00213                 #print 'quad, point=', quad, point
00214                 point_optical = num_conv[quad][point] # INDEXES for a python list
00215                 self.arr_renum[quad,point,...] = self.arr_opt[quad,point_optical,...]
00216                 self.arr_renum[quad,point,0]   = point # change the point number from optical to standard
00217 
00218         if self.print_bits & 256 : print 'Array with standard (per quad) numeration of points:\n', self.arr_renum
00219 
00220         self.arr = self.arr_renum
00221 
00222 
00223 #----------------------------------
00224 
00225     def txt_geometry_segments(self) :
00226         txt = ''        
00227         name_segm   = 'SENS2X1:V1'
00228         segm_index  = -1
00229         name_parent = 'CSPAD:V2'
00230         name_index  = 0
00231         rotXZ, rotYZ = 0,0
00232         for quad in range(self.nquads) :
00233             for segm in range(self.nsegms) :
00234                 segm_index += 1 
00235                 txt += self.str_fmt() % \
00236                        (name_parent.ljust(12), name_index, name_segm.ljust(12), segm_index, \
00237                        self.arrXmu[quad][segm], \
00238                        self.arrYmu[quad][segm], \
00239                        self.arrZmu[quad][segm], \
00240                        self.rotXYDegree[quad][segm], \
00241                        rotXZ, \
00242                        rotYZ, \
00243                        self.tiltXYDegree[quad][segm], \
00244                        self.tiltXZDegree[quad][segm], \
00245                        self.tiltYZDegree[quad][segm])
00246             txt += '\n' 
00247         return txt
00248 
00249 #----------------------------------
00250  
00251     def txt_geometry_det_ip(self) :
00252         txt = ''
00253         name_object = 'CSPAD:V2'
00254         name_parent = 'IP'
00255         num_parent, num_object, x0, y0, z0, rotXY, rotXZ, rotYZ, tiltXY, tiltXZ, tiltYZ = 0,0,0,0,1e6,0,0,0,0,0,0
00256         txt += self.str_fmt() % \
00257             (name_parent.ljust(12), num_parent, name_object.ljust(12), num_object, \
00258             x0, y0, z0, rotXY, rotXZ, rotYZ, tiltXY, tiltXZ, tiltYZ)
00259 
00260         return txt + '\n' 
00261 
00262 
00263 #----------------------------------
00264  
00265     def txt_geometry(self) :
00266         return self.txt_geometry_header() + \
00267                self.txt_geometry_segments() + \
00268                self.txt_geometry_det_ip()
00269 
00270 #----------------------------------
00271 #----------------------------------
00272 #----------------------------------
00273 #----------------------------------
00274 
00275 def main():
00276 
00277     #fname = '2012-02-26-CSPAD-XPP-Metrology.txt'
00278     #fname = '2013-01-24-CSPAD-XPP-Metrology.txt'
00279     #fname = '2013-01-29-CSPAD-XPP-Metrology.txt'      wrong numeration of quads
00280     #fname = '2013-01-29-CSPAD-XPP-Metrology-corr.txt' wrong numeration of quads
00281     fname = '2013-10-09-CSPAD-XPP-Metrology.txt'
00282 
00283     base_dir = '/reg/neh/home1/dubrovin/LCLS/CSPadMetrologyProc/'
00284 
00285     (opts, args) = input_option_parser(base_dir, fname)
00286     path_metrol = os.path.join(opts.dir, opts.fname)
00287 
00288     OpticAlignmentCspadV2(path_metrol, print_bits=opts.pbits, plot_bits=opts.gbits, n90=0)
00289     sys.exit()
00290 
00291 if __name__ == '__main__':
00292     main()
00293 
00294 #----------------------------------

Generated on 19 Dec 2016 for PSDMSoftware by  doxygen 1.4.7