def run(args): if ("--help" in args or "-h" in args) : print "Write a CBF header from a SLAC metrology file. Parameters:" master_phil.show(attributes_level=2) return user_phil = [] for arg in args: if (os.path.isfile(arg)) : user_phil.append(libtbx.phil.parse("""metrology_file=\"%s\"""" % arg)) else : try : user_phil.append(libtbx.phil.parse(arg)) except RuntimeError as e : raise Sorry("Unrecognized argument '%s' (error: %s)" % (arg, str(e))) params = master_phil.fetch(sources=user_phil).extract() if (params.metrology_file is None) : master_phil.show() raise Usage("metrology_file must be defined (either metrology_file=XXX, or the file path alone).") assert params.plot is not None assert params.out is not None print params.metrology_file metro = read_slac_metrology(params.metrology_file, plot=params.plot) write_cspad_cbf(None, metro, 'cbf', None, params.out, None, 0, header_only=True)
def v2calib2sections(filename): """The v2calib2sections() function reads calibration information stored in new style SLAC calibration file and returns a two-dimensional array of Section objects. The first index in the returned array identifies the quadrant, and the second index identifies the section within the quadrant. @param dirname Directory with calibration information @return Section objects """ from xfel.cftbx.detector.cspad_cbf_tbx import read_slac_metrology from scitbx.matrix import sqr from xfel.cxi.cspad_ana.cspad_tbx import pixel_size # metro is a dictionary where the keys are levels in the detector # hierarchy and the values are 'basis' objects metro = read_slac_metrology(filename) # 90 degree rotation to get into same frame reference_frame = sqr((0,-1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)) d = 0 d_basis = metro[(d,)] sections = [] for q in xrange(4): sections.append([]) q_basis = metro[(d,q)] for s in xrange(8): if not (d,q,s) in metro: continue s_basis = metro[(d,q,s)] # collapse the transformations from the detector center to the quadrant center # to the sensor center transform = reference_frame * \ d_basis.as_homogenous_transformation() * \ q_basis.as_homogenous_transformation() * \ s_basis.as_homogenous_transformation() # an homologous transformation is a 4x4 matrix, with a 3x3 rotation in the # upper left corner and the translation in the right-most column. The last # row is 0,0,0,1 ori = sqr((transform[0],transform[1],transform[2], transform[4],transform[5],transform[6], transform[8],transform[9],transform[10])) angle = ori.r3_rotation_matrix_as_x_y_z_angles(deg=True)[2] # move the reference of the sensor so its relative to the upper left of the # detector instead of the center of the detector center = (1765/2)+(transform[3]/pixel_size),(1765/2)+(transform[7]/pixel_size) sections[q].append(Section(angle, center)) return sections
def v2calib2sections(filename): """The v2calib2sections() function reads calibration information stored in new style SLAC calibration file and returns a two-dimensional array of Section objects. The first index in the returned array identifies the quadrant, and the second index identifies the section within the quadrant. @param dirname Directory with calibration information @return Section objects """ from xfel.cftbx.detector.cspad_cbf_tbx import read_slac_metrology from scitbx.matrix import sqr from xfel.cxi.cspad_ana.cspad_tbx import pixel_size # metro is a dictionary where the keys are levels in the detector # hierarchy and the values are 'basis' objects metro = read_slac_metrology(filename) # 90 degree rotation to get into same frame reference_frame = sqr((0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)) d = 0 d_basis = metro[(d, )] sections = [] for q in range(4): sections.append([]) q_basis = metro[(d, q)] for s in range(8): if not (d, q, s) in metro: continue s_basis = metro[(d, q, s)] # collapse the transformations from the detector center to the quadrant center # to the sensor center transform = reference_frame * \ d_basis.as_homogenous_transformation() * \ q_basis.as_homogenous_transformation() * \ s_basis.as_homogenous_transformation() # an homologous transformation is a 4x4 matrix, with a 3x3 rotation in the # upper left corner and the translation in the right-most column. The last # row is 0,0,0,1 ori = sqr((transform[0], transform[1], transform[2], transform[4], transform[5], transform[6], transform[8], transform[9], transform[10])) angle = ori.r3_rotation_matrix_as_x_y_z_angles(deg=True)[2] # move the reference of the sensor so its relative to the upper left of the # detector instead of the center of the detector center = (1765 / 2) + (transform[3] / pixel_size), (1765 / 2) + ( transform[7] / pixel_size) sections[q].append(Section(angle, center)) return sections
def _detector(self, index=None): if index is None: index = 0 run = self.get_run_from_index(index) det = self._get_psana_detector(run) geom = det.pyda.geoaccess(run.run()) cob = read_slac_metrology(geometry=geom, include_asic_offset=True) distance = env_distance( self.params.detector_address[0], run.env(), self.params.cspad.detz_offset ) d = Detector() pg0 = d.hierarchy() # first deal with D0 det_num = 0 origin = col((cob[(0,)] * col((0, 0, 0, 1)))[0:3]) fast = col((cob[(0,)] * col((1, 0, 0, 1)))[0:3]) - origin slow = col((cob[(0,)] * col((0, 1, 0, 1)))[0:3]) - origin origin += col((0.0, 0.0, -distance)) pg0.set_local_frame(fast.elems, slow.elems, origin.elems) pg0.set_name("D%d" % (det_num)) for quad_num in range(4): # Now deal with Qx pg1 = pg0.add_group() origin = col((cob[(0, quad_num)] * col((0, 0, 0, 1)))[0:3]) fast = col((cob[(0, quad_num)] * col((1, 0, 0, 1)))[0:3]) - origin slow = col((cob[(0, quad_num)] * col((0, 1, 0, 1)))[0:3]) - origin pg1.set_local_frame(fast.elems, slow.elems, origin.elems) pg1.set_name("D%dQ%d" % (det_num, quad_num)) for sensor_num in range(8): # Now deal with Sy pg2 = pg1.add_group() origin = col((cob[(0, quad_num, sensor_num)] * col((0, 0, 0, 1)))[0:3]) fast = ( col((cob[(0, quad_num, sensor_num)] * col((1, 0, 0, 1)))[0:3]) - origin ) slow = ( col((cob[(0, quad_num, sensor_num)] * col((0, 1, 0, 1)))[0:3]) - origin ) pg2.set_local_frame(fast.elems, slow.elems, origin.elems) pg2.set_name("D%dQ%dS%d" % (det_num, quad_num, sensor_num)) # Now deal with Az for asic_num in range(2): val = "ARRAY_D0Q%dS%dA%d" % (quad_num, sensor_num, asic_num) p = pg2.add_panel() origin = col( (cob[(0, quad_num, sensor_num, asic_num)] * col((0, 0, 0, 1)))[ 0:3 ] ) fast = ( col( ( cob[(0, quad_num, sensor_num, asic_num)] * col((1, 0, 0, 1)) )[0:3] ) - origin ) slow = ( col( ( cob[(0, quad_num, sensor_num, asic_num)] * col((0, 1, 0, 1)) )[0:3] ) - origin ) p.set_local_frame(fast.elems, slow.elems, origin.elems) p.set_pixel_size( (cspad_cbf_tbx.pixel_size, cspad_cbf_tbx.pixel_size) ) p.set_image_size(cspad_cbf_tbx.asic_dimension) p.set_trusted_range( ( cspad_tbx.cspad_min_trusted_value, cspad_tbx.cspad_saturated_value, ) ) p.set_name(val) try: beam = self._beam(index) except Exception: print( "No beam object initialized. Returning CSPAD detector without parallax corrections" ) return d # take into consideration here the thickness of the sensor also the # wavelength of the radiation (which we have in the same file...) wavelength = beam.get_wavelength() thickness = 0.5 # mm, see Hart et al. 2012 table = attenuation_coefficient.get_table("Si") # mu_at_angstrom returns cm^-1 mu = table.mu_at_angstrom(wavelength) / 10.0 # mu: mm^-1 t0 = thickness for panel in d: panel.set_px_mm_strategy(ParallaxCorrectedPxMmStrategy(mu, t0)) return d
def _detector(self, index=None): import psana from xfel.cftbx.detector.cspad_cbf_tbx import read_slac_metrology from dxtbx.model import Detector from scitbx.matrix import col from dxtbx.model import ParallaxCorrectedPxMmStrategy if index is None: index = 0 self._env = self._ds.env() self._det = psana.Detector(self._src, self._env) geom = self._det.pyda.geoaccess(self.events_list[index]) cob = read_slac_metrology(geometry=geom, include_asic_offset=True) d = Detector() pg0 = d.hierarchy() # first deal with D0 det_num = 0 origin = col((cob[(0, )] * col((0, 0, 0, 1)))[0:3]) fast = col((cob[(0, )] * col((1, 0, 0, 1)))[0:3]) - origin slow = col((cob[(0, )] * col((0, 1, 0, 1)))[0:3]) - origin origin += col((0., 0., -100.)) pg0.set_local_frame(fast.elems, slow.elems, origin.elems) pg0.set_name('D%d' % (det_num)) for quad_num in xrange(4): # Now deal with Qx pg1 = pg0.add_group() origin = col((cob[(0, quad_num)] * col((0, 0, 0, 1)))[0:3]) fast = col((cob[(0, quad_num)] * col((1, 0, 0, 1)))[0:3]) - origin slow = col((cob[(0, quad_num)] * col((0, 1, 0, 1)))[0:3]) - origin pg1.set_local_frame(fast.elems, slow.elems, origin.elems) pg1.set_name('D%dQ%d' % (det_num, quad_num)) for sensor_num in xrange(8): # Now deal with Sy pg2 = pg1.add_group() origin = col((cob[(0, quad_num, sensor_num)] * col( (0, 0, 0, 1)))[0:3]) fast = col((cob[(0, quad_num, sensor_num)] * col( (1, 0, 0, 1)))[0:3]) - origin slow = col((cob[(0, quad_num, sensor_num)] * col( (0, 1, 0, 1)))[0:3]) - origin pg2.set_local_frame(fast.elems, slow.elems, origin.elems) pg2.set_name('D%dQ%dS%d' % (det_num, quad_num, sensor_num)) # Now deal with Az for asic_num in xrange(2): val = 'ARRAY_D0Q%dS%dA%d' % (quad_num, sensor_num, asic_num) p = pg2.add_panel() origin = col( (cob[(0, quad_num, sensor_num, asic_num)] * col( (0, 0, 0, 1)))[0:3]) fast = col((cob[(0, quad_num, sensor_num, asic_num)] * col( (1, 0, 0, 1)))[0:3]) - origin slow = col((cob[(0, quad_num, sensor_num, asic_num)] * col( (0, 1, 0, 1)))[0:3]) - origin p.set_local_frame(fast.elems, slow.elems, origin.elems) p.set_pixel_size( (cspad_cbf_tbx.pixel_size, cspad_cbf_tbx.pixel_size)) p.set_image_size(cspad_cbf_tbx.asic_dimension) p.set_trusted_range((cspad_tbx.cspad_min_trusted_value, cspad_tbx.cspad_saturated_value)) p.set_name(val) try: beam = self._beam(index) except Exception: print 'No beam object initialized. Returning CSPAD detector without parallax corrections' return d # take into consideration here the thickness of the sensor also the # wavelength of the radiation (which we have in the same file...) wavelength = beam.get_wavelength() thickness = 0.5 # mm, see Hart et al. 2012 from cctbx.eltbx import attenuation_coefficient table = attenuation_coefficient.get_table("Si") # mu_at_angstrom returns cm^-1 mu = table.mu_at_angstrom(wavelength) / 10.0 # mu: mm^-1 t0 = thickness for panel in d: panel.set_px_mm_strategy(ParallaxCorrectedPxMmStrategy(mu, t0)) return d
if annulus: if params.resolution is None: print "Generating annular gain mask between %f and %f angstroms, assuming a distance %s mm and wavelength %s angstroms" % \ (params.annulus_inner, params.annulus_outer, params.distance, params.wavelength) else: print "Generating annular gain mask between %f and %f angstroms, assuming a distance %s mm and wavelength %s angstroms. Also, pixels higher than %f angstroms will be set to low gain." % \ (params.annulus_inner, params.annulus_outer, params.distance, params.wavelength, params.resolution) elif params.resolution is not None: print "Generating circular gain mask %s angstroms, assuming a distance %s mm and wavelength %s angstroms" % \ (params.resolution, params.distance, params.wavelength) from xfel.cftbx.detector.cspad_cbf_tbx import read_slac_metrology, get_cspad_cbf_handle from dxtbx.format.FormatCBFCspad import FormatCBFCspadInMemory from dxtbx.model import BeamFactory metro = read_slac_metrology(path = params.optical_metrology_path) cbf = get_cspad_cbf_handle(None, metro, 'cbf', None, "test", None, params.distance, verbose = True, header_only = True) img = FormatCBFCspadInMemory(cbf) beam = BeamFactory.simple(params.wavelength).get_s0() beam_center = (0,0) data = numpy.zeros((11840,194)) if annulus: inner = params.distance * math.tan(2*math.sinh(params.wavelength/(2*params.annulus_inner))) outer = params.distance * math.tan(2*math.sinh(params.wavelength/(2*params.annulus_outer))) print "Inner (mm):", inner print "Outer (mm):", outer if params.resolution is not None: radius = params.distance * math.tan(2*math.sinh(params.wavelength/(2*params.resolution))) print "Radius (mm):", radius
except RuntimeError, e: raise Sorry("Unrecognized argument '%s' (error: %s)" % (arg, str(e))) params = master_phil.fetch(sources=user_phil).extract() if (params.metrology_file is None): master_phil.show() raise Usage( "metrology_file must be defined (either metrology_file=XXX, or the file path alone)." ) assert params.plot is not None assert params.out is not None print params.metrology_file metro = read_slac_metrology(params.metrology_file, plot=params.plot) write_cspad_cbf(None, metro, 'cbf', None, params.out, None, 0, header_only=True) if (__name__ == "__main__"): args = sys.argv[1:] run(args)
print "Write a CBF header from a SLAC metrology file. Parameters:" master_phil.show(attributes_level=2) return user_phil = [] for arg in args: if (os.path.isfile(arg)) : user_phil.append(libtbx.phil.parse("""metrology_file=\"%s\"""" % arg)) else : try : user_phil.append(libtbx.phil.parse(arg)) except RuntimeError, e : raise Sorry("Unrecognized argument '%s' (error: %s)" % (arg, str(e))) params = master_phil.fetch(sources=user_phil).extract() if (params.metrology_file is None) : master_phil.show() raise Usage("metrology_file must be defined (either metrology_file=XXX, or the file path alone).") assert params.plot is not None assert params.out is not None print params.metrology_file metro = read_slac_metrology(params.metrology_file, plot=params.plot) write_cspad_cbf(None, metro, 'cbf', None, params.out, None, 0, header_only=True) if (__name__ == "__main__") : args = sys.argv[1:] run(args)
if annulus: if params.resolution is None: print "Generating annular gain mask between %f and %f angstroms, assuming a distance %s mm and wavelength %s angstroms" % \ (params.annulus_inner, params.annulus_outer, params.distance, params.wavelength) else: print "Generating annular gain mask between %f and %f angstroms, assuming a distance %s mm and wavelength %s angstroms. Also, pixels higher than %f angstroms will be set to low gain." % \ (params.annulus_inner, params.annulus_outer, params.distance, params.wavelength, params.resolution) elif params.resolution is not None: print "Generating circular gain mask %s angstroms, assuming a distance %s mm and wavelength %s angstroms" % \ (params.resolution, params.distance, params.wavelength) from xfel.cftbx.detector.cspad_cbf_tbx import read_slac_metrology, get_cspad_cbf_handle from dxtbx.format.FormatCBFCspad import FormatCBFCspadInMemory from dxtbx.model.beam import beam_factory metro = read_slac_metrology(path = params.optical_metrology_path) cbf = get_cspad_cbf_handle(None, metro, 'cbf', None, "test", None, params.distance, verbose = True, header_only = True) img = FormatCBFCspadInMemory(cbf) beam = beam_factory.simple(params.wavelength).get_s0() beam_center = (0,0) data = numpy.zeros((11840,194)) if annulus: inner = params.distance * math.tan(2*math.sinh(params.wavelength/(2*params.annulus_inner))) outer = params.distance * math.tan(2*math.sinh(params.wavelength/(2*params.annulus_outer))) print "Inner (mm):", inner print "Outer (mm):", outer if params.resolution is not None: radius = params.distance * math.tan(2*math.sinh(params.wavelength/(2*params.resolution))) print "Radius (mm):", radius