def OnRestoreMetrology(self, event): print("Not implemented") return dialog = wx.FileDialog( self, defaultDir="", message="Restore metrology file", style=wx.FD_OPEN, wildcard="Phil files (*.eff; *.def)|*.eff;*.def") if dialog.ShowModal() == wx.ID_OK: path = dialog.GetPath() if (path != ""): from xfel.cftbx.detector.metrology import \ master_phil, metrology_as_transformation_matrices from libtbx import phil frame = self.GetParent().GetParent() stream = open(path) metrology_phil = master_phil.fetch( sources=[phil.parse(stream.read())]) stream.close() # Merge restored metrology into the raw image from libtbx.phil import experimental experimental.merge_params_by_key( frame.pyslip.tiles.raw_image._metrology_params, metrology_phil.extract(), 'serial') img = frame.pyslip.tiles.raw_image img.apply_metrology_from_matrices( metrology_as_transformation_matrices( metrology_phil.extract())) # Update the view, trigger redraw. XXX Duplication # w.r.t. OnUpdateQuad(). tiles = frame.pyslip.tiles tiles.flex_image = frame.pyslip.tiles.raw_image.get_flex_image( brightness=tiles.current_brightness / 100) tiles.flex_image.adjust( color_scheme=tiles.current_color_scheme) tiles.reset_the_cache() tiles.tile_cache = tiles.cache[tiles.zoom_level] tiles.tile_list = tiles.lru[tiles.zoom_level] frame.pyslip.Update() # Update the controls, remember to reset the default values # for the spinners. for serial in range(4): fast, slow = img.get_panel_fast_slow(serial) name_quadrant = ["Q0", "Q1", "Q2", "Q3"][serial] spinner = getattr(self, "_" + name_quadrant + "_fast_ctrl") spinner.SetDefaultValue(fast) spinner.SetValue(fast) spinner = getattr(self, "_" + name_quadrant + "_slow_ctrl") spinner.SetDefaultValue(slow) spinner.SetValue(slow)
def OnRestoreMetrology(self, event): print "Not implemented" return dialog = wx.FileDialog( self, defaultDir="", message="Restore metrology file", style=wx.FD_OPEN, wildcard="Phil files (*.eff; *.def)|*.eff;*.def") if dialog.ShowModal() == wx.ID_OK: path = dialog.GetPath() if (path != "") : from xfel.cftbx.detector.metrology import \ master_phil, metrology_as_transformation_matrices from libtbx import phil frame = self.GetParent().GetParent() stream = open(path) metrology_phil = master_phil.fetch(sources=[phil.parse(stream.read())]) stream.close() # Merge restored metrology into the raw image from libtbx.phil import experimental experimental.merge_params_by_key( frame.pyslip.tiles.raw_image._metrology_params, metrology_phil.extract(), 'serial') img = frame.pyslip.tiles.raw_image img.apply_metrology_from_matrices(metrology_as_transformation_matrices( metrology_phil.extract())) # Update the view, trigger redraw. XXX Duplication # w.r.t. OnUpdateQuad(). tiles = frame.pyslip.tiles tiles.flex_image = frame.pyslip.tiles.raw_image.get_flex_image( brightness=tiles.current_brightness / 100) tiles.flex_image.adjust(color_scheme=tiles.current_color_scheme) tiles.reset_the_cache() tiles.tile_cache = tiles.cache[tiles.zoom_level] tiles.tile_list = tiles.lru[tiles.zoom_level] frame.pyslip.Update() # Update the controls, remember to reset the default values # for the spinners. for serial in xrange(4): fast, slow = img.get_panel_fast_slow(serial) name_quadrant = ["Q0", "Q1", "Q2", "Q3"][serial] spinner = getattr(self, "_" + name_quadrant + "_fast_ctrl") spinner.SetDefaultValue(fast) spinner.SetValue(fast) spinner = getattr(self, "_" + name_quadrant + "_slow_ctrl") spinner.SetDefaultValue(slow) spinner.SetValue(slow)
def transformation_matrices_as_metrology(self): """The transformation_matrices_as_metrology() function regularizes the the transformation matrices and converts them to a phil object. """ from libtbx import phil from xfel.cftbx.detector.metrology import \ master_phil, regularize_transformation_matrices # XXX Experimental! regularize_transformation_matrices(self._matrices) (Tf_d, Tb_d) = self._matrices[(0, )] metrology_str = "detector {\n" metrology_str += "serial = %d\n" % 0 metrology_str += self._matrix_as_string(Tb_d) for p in [ k[1] for k in self._matrices.keys() if (len(k) == 2 and k[0:1] == (0, )) ]: (Tf_p, Tb_p) = self._matrices[(0, p)] metrology_str += "panel {\n" metrology_str += "serial = %d\n" % p metrology_str += self._matrix_as_string(Tf_d * Tb_p) for s in [ k[2] for k in self._matrices.keys() if (len(k) == 3 and k[0:2] == (0, p)) ]: (Tf_s, Tb_s) = self._matrices[(0, p, s)] metrology_str += "sensor {\n" metrology_str += "serial = %d\n" % s metrology_str += self._matrix_as_string(Tf_p * Tb_s) for a in [ k[3] for k in self._matrices.keys() if (len(k) == 4 and k[0:3] == (0, p, s)) ]: (Tf_a, Tb_a) = self._matrices[(0, p, s, a)] metrology_str += "asic {\n" metrology_str += "serial = %d\n" % a metrology_str += self._matrix_as_string(Tf_s * Tb_a) metrology_str += "}\n" metrology_str += "}\n" metrology_str += "}\n" metrology_str += "}\n" return master_phil.fetch(sources=[phil.parse(metrology_str)])
def transformation_matrices_as_metrology(self): """The transformation_matrices_as_metrology() function regularizes the the transformation matrices and converts them to a phil object. """ from libtbx import phil from xfel.cftbx.detector.metrology import \ master_phil, regularize_transformation_matrices # XXX Experimental! regularize_transformation_matrices(self._matrices) (Tf_d, Tb_d) = self._matrices[(0,)] metrology_str = "detector {\n" metrology_str += "serial = %d\n" % 0 metrology_str += self._matrix_as_string(Tb_d) for p in [k[1] for k in self._matrices.keys() if (len(k) == 2 and k[0:1] == (0,))]: (Tf_p, Tb_p) = self._matrices[(0, p)] metrology_str += "panel {\n" metrology_str += "serial = %d\n" % p metrology_str += self._matrix_as_string(Tf_d * Tb_p) for s in[k[2] for k in self._matrices.keys() if (len(k) == 3 and k[0:2] == (0, p))]: (Tf_s, Tb_s) = self._matrices[(0, p, s)] metrology_str += "sensor {\n" metrology_str += "serial = %d\n" % s metrology_str += self._matrix_as_string(Tf_p * Tb_s) for a in [k[3] for k in self._matrices.keys() if (len(k) == 4 and k[0:3] == (0, p, s))]: (Tf_a, Tb_a) = self._matrices[(0, p, s, a)] metrology_str += "asic {\n" metrology_str += "serial = %d\n" % a metrology_str += self._matrix_as_string(Tf_s * Tb_a) metrology_str += "}\n" metrology_str += "}\n" metrology_str += "}\n" metrology_str += "}\n" return master_phil.fetch(sources=[phil.parse(metrology_str)])
def sections2phil(sections, verbose): from xfel.cftbx.detector.metrology import master_phil # Properties of CSPad pixels (Philipp et al., 2007). The counters # are 14 bits wide, and the pixels are square with a side length of # 110 um. Because cspad_tbx depends on pyana, it may fail to import # in which case a hardcoded fallback is provided. try: from xfel.cxi.cspad_ana.cspad_tbx import cspad_saturated_value as sv from xfel.cxi.cspad_ana.cspad_tbx import pixel_size as ps saturated_value = sv pixel_size = ps * 1e-3 except ImportError: saturated_value = 90000 pixel_size = 110e-6 # Build the Phil object. XXX Should have det-z? Probably not, # because then it aint't just metrology anymore. In fact, under # orthographic projection the whole translation/orientation thing # can be scrapped for the detector. XXX look up include, # include_scope for phil XXX Hardcoded address for now. address = "CxiDs1-0|Cspad-0" metrology_str = "detector { serial = %d\n" % 0 metrology_str += "label = %s\n" % address # The center of the detector is defined as the average of all the # sections it contains. The first coordinate of the matrix-oriented # coordinate system of the Section class maps to -y, the second to # x, and the third to z. While the detector still sits on the # origin (zero translation), the mapping from the origin in Section # coordinates is still needed. t_d = [0, 0, 0] nmemb = 0 for p in range(len(sections)): for s in range(len(sections[p])): t_d[0] += +sections[p][s].center[1] t_d[1] += -sections[p][s].center[0] t_d[2] += 0 nmemb += 1 if (nmemb > 0): for i in range(3): t_d[i] /= nmemb metrology_str += "translation = 0, 0, 0\n" o_d = matrix.col([0, 0, 1]).axis_and_angle_as_unit_quaternion( angle=0, deg=True) metrology_str += "orientation = %s, %s, %s, %s\n" % \ tuple(repr(c) for c in o_d) for p in range(len(sections)): # Loop over quadrants (panels). XXX Translation of panels is # wrongly set to to centre of sections in the quadrant # w.r.t. center of the detector. metrology_str += "panel { serial = %d\n" % p metrology_str += "translation = " t_p = [0, 0, 0] for s in range(len(sections[p])): t_p[0] += +sections[p][s].center[1] - t_d[0] t_p[1] += -sections[p][s].center[0] - t_d[1] t_p[2] += 0 - t_d[2] for i in range(3): t_p[i] /= len(sections[p]) metrology_str += "%s" % repr(t_p[i] * pixel_size) if (i < 2): metrology_str += ", " else: metrology_str += "\n" # XXX Orientation wrongly set to zero. o_p = matrix.col([0, 0, 1]).axis_and_angle_as_unit_quaternion( angle=0, deg=True) metrology_str += "orientation = %s, %s, %s, %s\n" % \ tuple(repr(c) for c in o_p) for s in range(len(sections[p])): # Loop over sensors (sections or two-by-one:s). Note that # sensors are rotated by -90 degrees in the SLAC metrology # convention w.r.t. their appearance in the XTC stream. s_t = [0, 0, 0] s_t[0] = +sections[p][s].center[1] - t_p[0] - t_d[0] s_t[1] = -sections[p][s].center[0] - t_p[1] - t_d[1] s_t[2] = 0 - t_p[2] - t_d[2] metrology_str += "sensor { serial = %d\n" % s metrology_str += "translation = " for i in range(3): metrology_str += "%s" % repr(s_t[i] * pixel_size) if (i < 2): metrology_str += ", " else: metrology_str += "\n" s_o = matrix.col([0, 0, 1]).axis_and_angle_as_unit_quaternion( angle=sections[p][s].angle - 90, deg=True) metrology_str += "orientation = %s, %s, %s, %s\n" % \ tuple(repr(c) for c in s_o) for a in range(2): # The ASIC:s of the CSPad are 185 rows by 194 columns. The # ASIC:s are horizontally aligned within a section, with a # three-column gap between them. metrology_str += "asic { serial = %d\n" % a if (a == 0): metrology_str += "translation = %s, %s, %s\n" % ( repr(-(194 + 3) / 2 * pixel_size), "0", "0") # XXX hardcoded! else: metrology_str += "translation = %s, %s, %s\n" % ( repr(+(194 + 3) / 2 * pixel_size), "0", "0") # XXX hardcoded! metrology_str += "orientation = 1, 0, 0, 0\n" metrology_str += "pixel_size = %s, %s\n" % ( repr(pixel_size), repr(pixel_size)) metrology_str += "dimension = %d, %d\n" % (194, 185) # XXX hardcoded! metrology_str += "saturation = %s\n" % repr(float(saturated_value)) metrology_str += "}\n" metrology_str += "}\n" metrology_str += "}\n" metrology_str += "}\n" metrology_phil = master_phil.fetch( sources=[phil.parse(metrology_str)]) return (metrology_phil)
def run(argv=None): if (argv is None): argv = sys.argv # XXX Could/should handle effective metrology the same way, except # it does not have a single scope. work_phil = phil.process_command_line(args=argv[1:], master_string=master_str + phil_str + additional_spotfinder_phil_defs) work_params = work_phil.work.extract() app = wx.App(0) wx.SystemOptions.SetOptionInt("osx.openfiledialog.always-show-types", 1) frame = XrayFrame(None, -1, "X-ray image display", size=(800, 720)) frame.Show() # show settings panel frame.OnShowSettings(None) frame.settings_frame.panel.center_ctrl.SetValue(work_params.beam_center) frame.settings_frame.panel.integ_ctrl.SetValue( work_params.show_integration_results) frame.settings_frame.panel.spots_ctrl.SetValue( work_params.show_spotfinder_results) frame.settings.show_effective_tiling = work_params.show_effective_tiling frame.settings_frame.panel.collect_values() if (work_params.effective_metrology is not None): from xfel.cftbx.detector.metrology import \ master_phil, metrology_as_transformation_matrices stream = open(work_params.effective_metrology) metrology_phil = master_phil.fetch(sources=[phil.parse(stream.read())]) stream.close() frame.metrology_matrices = metrology_as_transformation_matrices( metrology_phil.extract()) # Update initial settings with values from the command line. Needs # to be done before image is loaded (but after the frame is # instantiated). frame.params = work_params frame.init_pyslip() frame.pyslip.tiles.user_requests_antialiasing = work_params.anti_aliasing frame.pyslip.tiles.show_untrusted = frame.params.show_untrusted paths = work_phil.remaining_args if (len(paths) == 1 and os.path.basename(paths[0]) == "DISTL_pickle"): assert os.path.isfile(paths[0]) frame.load_distl_output(paths[0]) elif (len(paths) > 0): frame.CHOOSER_SIZE = 1500 # from dxtbx.imageset import ImageSetFactory # sets = ImageSetFactory.new(paths) from dxtbx.model.experiment_list import ExperimentListFactory from rstbx.slip_viewer.frame import chooser_wrapper experiments = ExperimentListFactory.from_filenames(paths) sets = experiments.imagesets() for imgset in sets: for idx in imgset.indices(): frame.add_file_name_or_data(chooser_wrapper(imgset, idx)) idx = sets[0].indices()[0] frame.load_image(chooser_wrapper(sets[0], idx)) app.MainLoop() return 0
def metrology2phil(calib_dir, verbose): """XXX Should really review the SLAC progress since last time around! XXX Note that this is all SLAC-specific (as is the whole thing, I guess). """ from xfel.cftbx.detector.metrology import master_phil # XXX Can this fail? How? sections = calib2sections(calib_dir) if (sections is None): return (None) # Properties of CSPad pixels (Philipp et al., 2007). The counters # are 14 bits wide, and the pixels are square with a side length of # 110 um. Because cspad_tbx depends on pyana, it may fail to import # in which case a hardcoded fallback is provided. try: from xfel.cxi.cspad_ana.cspad_tbx import cspad_saturated_value as sv from xfel.cxi.cspad_ana.cspad_tbx import pixel_size as ps saturated_value = sv pixel_size = ps * 1e-3 except ImportError: saturated_value = 90000 pixel_size = 110e-6 # Build the Phil object. XXX Should have det-z? Probably not, # because then it aint't just metrology anymore. In fact, under # orthographic projection the whole translation/orientation thing # can be scrapped for the detector. XXX look up include, # include_scope for phil XXX Hardcoded address for now. address = "CxiDs1-0|Cspad-0" metrology_str = "detector { serial = %d\n" % 0 metrology_str += "label = %s\n" % address # The center of the detector is defined as the average of all the # sections it contains. The first coordinate of the matrix-oriented # coordinate system of the Section class maps to -y, the second to # x, and the third to z. While the detector still sits on the # origin (zero translation), the mapping from the origin in Section # coordinates is still needed. t_d = [0, 0, 0] nmemb = 0 for p in xrange(len(sections)): for s in xrange(len(sections[p])): t_d[0] += +sections[p][s].center[1] t_d[1] += -sections[p][s].center[0] t_d[2] += 0 nmemb += 1 if (nmemb > 0): for i in xrange(3): t_d[i] /= nmemb metrology_str += "translation = 0, 0, 0\n" o_d = matrix.col([0, 0, 1]).axis_and_angle_as_unit_quaternion( angle=0, deg=True) metrology_str += "orientation = %s, %s, %s, %s\n" % \ tuple(repr(c) for c in o_d) for p in xrange(len(sections)): # Loop over quadrants (panels). XXX Translation of panels is # wrongly set to to centre of sections in the quadrant # w.r.t. center of the detector. metrology_str += "panel { serial = %d\n" % p metrology_str += "translation = " t_p = [0, 0, 0] for s in xrange(len(sections[p])): t_p[0] += +sections[p][s].center[1] - t_d[0] t_p[1] += -sections[p][s].center[0] - t_d[1] t_p[2] += 0 - t_d[2] for i in xrange(3): t_p[i] /= len(sections[p]) metrology_str += "%s" % repr(t_p[i] * pixel_size) if (i < 2): metrology_str += ", " else: metrology_str += "\n" # XXX Orientation wrongly set to zero. o_p = matrix.col([0, 0, 1]).axis_and_angle_as_unit_quaternion( angle=0, deg=True) metrology_str += "orientation = %s, %s, %s, %s\n" % \ tuple(repr(c) for c in o_p) for s in xrange(len(sections[p])): # Loop over sensors (sections or two-by-one:s). Note that # sensors are rotated by -90 degrees in the SLAC metrology # convention w.r.t. their appearance in the XTC stream. s_t = [0, 0, 0] s_t[0] = +sections[p][s].center[1] - t_p[0] - t_d[0] s_t[1] = -sections[p][s].center[0] - t_p[1] - t_d[1] s_t[2] = 0 - t_p[2] - t_d[2] metrology_str += "sensor { serial = %d\n" % s metrology_str += "translation = " for i in xrange(3): metrology_str += "%s" % repr(s_t[i] * pixel_size) if (i < 2): metrology_str += ", " else: metrology_str += "\n" s_o = matrix.col([0, 0, 1]).axis_and_angle_as_unit_quaternion( angle=sections[p][s].angle - 90, deg=True) metrology_str += "orientation = %s, %s, %s, %s\n" % \ tuple(repr(c) for c in s_o) for a in xrange(2): # The ASIC:s of the CSPad are 185 rows by 194 columns. The # ASIC:s are horizontally aligned within a section, with a # three-column gap between them. metrology_str += "asic { serial = %d\n" % a if (a == 0): metrology_str += "translation = %s, %s, %s\n" % ( repr(-(194 + 3) / 2 * pixel_size), "0", "0") # XXX hardcoded! else: metrology_str += "translation = %s, %s, %s\n" % ( repr(+(194 + 3) / 2 * pixel_size), "0", "0") # XXX hardcoded! metrology_str += "orientation = 1, 0, 0, 0\n" metrology_str += "pixel_size = %s, %s\n" % ( repr(pixel_size), repr(pixel_size)) metrology_str += "dimension = %d, %d\n" % (194, 185) # XXX hardcoded! metrology_str += "saturation = %s\n" % repr(float(saturated_value)) metrology_str += "}\n" metrology_str += "}\n" metrology_str += "}\n" metrology_str += "}\n" metrology_phil = master_phil.fetch( sources=[phil.parse(metrology_str)]) return (metrology_phil)
def run(argv=None): if (argv is None): argv = sys.argv # XXX Could/should handle effective metrology the same way, except # it does not have a single scope. work_phil = phil.process_command_line( args=argv[1:], master_string=master_str + phil_str + additional_spotfinder_phil_defs) work_params = work_phil.work.extract() app = wx.App(0) wx.SystemOptions.SetOptionInt("osx.openfiledialog.always-show-types", 1) frame = XrayFrame(None, -1, "X-ray image display", size=(800,720)) frame.Show() # show settings panel frame.OnShowSettings(None) frame.settings_frame.panel.center_ctrl.SetValue( work_params.beam_center) frame.settings_frame.panel.integ_ctrl.SetValue( work_params.show_integration_results) frame.settings_frame.panel.spots_ctrl.SetValue( work_params.show_spotfinder_results) frame.settings.show_effective_tiling = work_params.show_effective_tiling frame.settings_frame.panel.collect_values() if (work_params.effective_metrology is not None): from xfel.cftbx.detector.metrology import \ master_phil, metrology_as_transformation_matrices stream = open(work_params.effective_metrology) metrology_phil = master_phil.fetch(sources=[phil.parse(stream.read())]) stream.close() frame.metrology_matrices = metrology_as_transformation_matrices( metrology_phil.extract()) # Update initial settings with values from the command line. Needs # to be done before image is loaded (but after the frame is # instantiated). frame.params = work_params frame.init_pyslip() frame.pyslip.tiles.user_requests_antialiasing = work_params.anti_aliasing frame.pyslip.tiles.show_untrusted = frame.params.show_untrusted paths = work_phil.remaining_args if (len(paths) == 1 and os.path.basename(paths[0]) == "DISTL_pickle"): assert os.path.isfile(paths[0]) frame.load_distl_output(paths[0]) elif (len(paths) > 0): frame.CHOOSER_SIZE = 1500 from dxtbx.imageset import ImageSetFactory from rstbx.slip_viewer.frame import chooser_wrapper sets = ImageSetFactory.new(paths) for imgset in sets: for idx in imgset.indices(): frame.add_file_name_or_data(chooser_wrapper(imgset, idx)) idx = sets[0].indices()[0] frame.load_image(chooser_wrapper(sets[0],idx)) app.MainLoop() return 0