def write_integration_pickles(self, integrated, experiments, callback=None): """ This is streamlined vs. the code in stills_indexer, since the filename convention is set up upstream. """ # Construct frame from xfel.command_line.frame_extractor import ConstructFrame self.frame = ConstructFrame(integrated, experiments[0]).make_frame() self.frame["pixel_size"] = experiments[0].detector[0].get_pixel_size()[0] if self.write_pickle: from libtbx import easy_pickle easy_pickle.dump(self.params.output.integration_pickle, self.frame)
def write_integration_pickles(self, integrated, experiments, callback = None): """ Write a serialized python dictionary with integrated intensities and other information suitible for use by cxi.merge or prime.postrefine. @param integrated Reflection table with integrated intensities @param experiments Experiment list. One integration pickle for each experiment will be created. @param callback Deriving classes can use callback to make further modifications to the dictionary before it is serialized. Callback should be a function with this signature: def functionname(params, outfile, frame), where params is the phil scope, outfile is the path to the pickle that will be saved, and frame is the python dictionary to be serialized. """ try: picklefilename = self.params.output.integration_pickle except AttributeError: return if self.params.output.integration_pickle is not None: from libtbx import easy_pickle import os from xfel.command_line.frame_extractor import ConstructFrame from dials.array_family import flex # Split everything into separate experiments for pickling for e_number in xrange(len(experiments)): experiment = experiments[e_number] e_selection = integrated['id'] == e_number reflections = integrated.select(e_selection) frame = ConstructFrame(reflections, experiment).make_frame() frame["pixel_size"] = experiment.detector[0].get_pixel_size()[0] if not hasattr(self, 'tag') or self.tag is None: try: # if the data was a file on disc, get the path event_timestamp = os.path.splitext(experiments[0].imageset.paths()[0])[0] except NotImplementedError: # if the data is in memory only, check if the reader set a timestamp on the format object event_timestamp = experiment.imageset.reader().get_format(0).timestamp event_timestamp = os.path.basename(event_timestamp) if event_timestamp.find("shot-")==0: event_timestamp = os.path.splitext(event_timestamp)[0] # micromanage the file name else: event_timestamp = self.tag if hasattr(self.params.output, "output_dir"): outfile = os.path.join(self.params.output.output_dir, self.params.output.integration_pickle%(e_number,event_timestamp)) else: outfile = os.path.join(os.path.dirname(self.params.output.integration_pickle), self.params.output.integration_pickle%(e_number,event_timestamp)) if callback is not None: callback(self.params, outfile, frame) easy_pickle.dump(outfile, frame)
def write_integration_pickles(self): ''' This is streamlined vs. the code in stills_indexer, since the filename convention is set up upstream. ''' from libtbx import easy_pickle from xfel.command_line.frame_extractor import ConstructFrame self.frame = ConstructFrame(self.integrated, self.experiments[0]).make_frame() self.frame["pixel_size"] = self.experiments[0].detector[ 0].get_pixel_size()[0] easy_pickle.dump(self.phil.output.integration_pickle, self.frame)
class IOTAImageProcessor(Processor): """ Subclassed from dials.stills_process. Intended to only be used to process a single image; image import, pre-processing, triage, and process dispatching are handled by separate modules. Added features / overrides: - Streamlined writing of integration pickles. - Estimation of best-fit Bravais lattice and re-indexing """ def __init__(self, iparams, write_pickle=True, write_logs=True, last_stage='integrate'): ''' Constructor :param iparams: IOTA params :param write_pickle: Set to True to write out an integration pickle ''' self.iparams = iparams self.write_pickle = write_pickle self.write_logs = write_logs self.last_stage = last_stage self.dlog_bookmark = 0 # Get Processor PHIL and initialize Processor if self.iparams.cctbx_xfel.target: with open(self.iparams.cctbx_xfel.target, 'r') as tf: tphil_string = tf.read() tparams = phil_scope.fetch(source=parse(tphil_string)).extract() else: tparams = phil_scope.extract() Processor.__init__(self, params=tparams) # IOTA-specific settings from here # Turn off all peripheral output self.params.output.experiments_filename = None self.params.output.indexed_filename = None self.params.output.strong_filename = None self.params.output.refined_experiments_filename = None self.params.output.integrated_experiments_filename = None self.params.output.integrated_filename = None self.params.output.profile_filename = None # Set customized parameters beamX = self.iparams.image_import.beam_center.x beamY = self.iparams.image_import.beam_center.y if beamX != 0 or beamY != 0: self.params.geometry.detector.slow_fast_beam_centre = '{} {}'.format( beamY, beamX) if self.iparams.image_import.distance != 0: self.params.geometry.detector.distance = self.iparams.image_import.distance if self.iparams.image_import.mask is not None: self.params.spotfinder.lookup.mask = self.iparams.image_import.mask self.params.integration.lookup.mask = self.iparams.image_import.mask if self.iparams.cctbx_xfel.target_space_group is not None: sg = self.iparams.cctbx_xfel.target_space_group self.params.indexing.known_symmetry.space_group = sg if self.iparams.cctbx_xfel.target_unit_cell is not None: uc = self.iparams.cctbx_xfel.target_unit_cell self.params.indexing.known_symmetry.unit_cell = uc if not self.params.indexing.stills.method_list: self.params.indexing.stills.method_list = [ 'fft1d', 'real_space_grid_search' ] if self.iparams.cctbx_xfel.use_fft3d: self.params.indexing.stills.method_list.insert(2, 'fft3d') if self.iparams.cctbx_xfel.significance_filter.flag_on: sigma = self.iparams.cctbx_xfel.significance_filter.sigma sigma = sigma if sigma else 1 self.params.significance_filter.enable = True self.params.significance_filter.isigi_cutoff = sigma # Load reference geometry self.reference_detector = None if self.iparams.advanced.reference_geometry: from dxtbx.model.experiment_list import ExperimentListFactory try: ref_experiments = ExperimentListFactory.from_json_file( str(self.iparams.advanced.reference_geometry), check_format=False) except Exception as e: print('DEBUG: Could not make exp. list because: ', e) try: import dxtbx img = dxtbx.load( str(self.iparams.advanced.reference_geometry)) except Exception: print("DEBUG: Couldn't load geometry file {}" "".format(self.iparams.advanced.reference_geometry)) else: self.reference_detector = img.get_detector() else: assert len(ref_experiments.detectors()) == 1 self.reference_detector = ref_experiments.detectors()[0] def refine_bravais_settings(self, reflections, experiments): # configure DIALS logging if self.dials_log: log.config(verbosity=1, logfile=self.dials_log) proc_scope = phil_scope.format(python_object=self.params) sgparams = sg_scope.fetch(proc_scope).extract() sgparams.refinement.reflections.outlier.algorithm = 'tukey' crystal_P1 = copy.deepcopy(experiments[0].crystal) try: refined_settings = refined_settings_from_refined_triclinic( experiments=experiments, reflections=reflections, params=sgparams) possible_bravais_settings = { s["bravais"] for s in refined_settings } bravais_lattice_to_space_group_table(possible_bravais_settings) except Exception: for expt in experiments: expt.crystal = crystal_P1 return None # Generate Bravais settings # try: # Lfat = refined_settings_factory_from_refined_triclinic(sgparams, # experiments, # reflections, # lepage_max_delta=5) # except Exception as e: # # If refinement fails, reset to P1 (experiments remain modified by Lfat # # if there's a refinement failure, which causes issues down the line) # for expt in experiments: # expt.crystal = crystal_P1 # return None # # Lfat.labelit_printout() # # # Filter out not-recommended (i.e. too-high rmsd and too-high max angular # # difference) solutions # Lfat_recommended = [s for s in Lfat if s.recommended] # # # If none are recommended, return None (do not reindex) # if len(Lfat_recommended) == 0: # return None # # # Find the highest symmetry group # possible_bravais_settings = set(solution['bravais'] for solution in # Lfat_recommended) # bravais_lattice_to_space_group_table(possible_bravais_settings) lattice_to_sg_number = { 'aP': 1, 'mP': 3, 'mC': 5, 'oP': 16, 'oC': 20, 'oF': 22, 'oI': 23, 'tP': 75, 'tI': 79, 'hP': 143, 'hR': 146, 'cP': 195, 'cF': 196, 'cI': 197 } filtered_lattices = {} for key, value in lattice_to_sg_number.items(): if key in possible_bravais_settings: filtered_lattices[key] = value highest_sym_lattice = max(filtered_lattices, key=filtered_lattices.get) highest_sym_solutions = [ s for s in refined_settings if s['bravais'] == highest_sym_lattice ] if len(highest_sym_solutions) > 1: highest_sym_solution = sorted( highest_sym_solutions, key=lambda x: x['max_angular_difference'])[0] else: highest_sym_solution = highest_sym_solutions[0] return highest_sym_solution def reindex(self, reflections, experiments, solution): """ Reindex with newly-determined space group / unit cell """ # Update space group / unit cell experiment = experiments[0] print("Old crystal:") print(experiment.crystal, '\n') experiment.crystal.update(solution.refined_crystal) print("New crystal:") print(experiment.crystal, '\n') # Change basis cb_op = solution['cb_op_inp_best'].as_abc() change_of_basis_op = sgtbx.change_of_basis_op(cb_op) miller_indices = reflections['miller_index'] non_integral_indices = change_of_basis_op.apply_results_in_non_integral_indices( miller_indices) if non_integral_indices.size() > 0: print ("Removing {}/{} reflections (change of basis results in non-integral indices)" \ "".format(non_integral_indices.size(), miller_indices.size())) sel = flex.bool(miller_indices.size(), True) sel.set_selected(non_integral_indices, False) miller_indices_reindexed = change_of_basis_op.apply( miller_indices.select(sel)) reflections['miller_index'].set_selected(sel, miller_indices_reindexed) reflections['miller_index'].set_selected(~sel, (0, 0, 0)) return experiments, reflections def write_integration_pickles(self, integrated, experiments, callback=None): """ This is streamlined vs. the code in stills_indexer, since the filename convention is set up upstream. """ # Construct frame from xfel.command_line.frame_extractor import ConstructFrame self.frame = ConstructFrame(integrated, experiments[0]).make_frame() self.frame["pixel_size"] = experiments[0].detector[0].get_pixel_size( )[0] if self.write_pickle: from libtbx import easy_pickle easy_pickle.dump(self.params.output.integration_pickle, self.frame) def pg_and_reindex(self, indexed, experiments): ''' Find highest-symmetry Bravais lattice ''' solution = self.refine_bravais_settings(indexed, experiments) if solution is not None: experiments, indexed = self.reindex(indexed, experiments, solution) return experiments, indexed def error_handler(self, error, p_name, img_object, output=None): if not output: output = [] if hasattr(error, "classname"): # print(error.classname, "for {}:".format(img_object.img_path), ) error_message = "{}: {}".format(error.classname, error[0].replace('\n', ' ')[:50]) else: p_name = p_name.lower().capitalize() # print("{} error for {}:".format(p_name, img_object.img_path), ) error_message = "{}".format(str(error).replace('\n', ' ')[:50]) # print(error_message) img_object.fail = 'failed {}'.format(p_name.lower()) img_object.errors.append(error_message) # Generate log summary of integration results int_status = 'not integrated -- {}'.format(error) int_results = {'info': int_status} img_object.final['final'] = None img_object.final.update(int_results) log_entry = '\n{} - {}'.format(img_object.fail.upper(), error) img_object.log_info.append(log_entry) # Write log entry into log file output.append(error_message) if self.write_logs: self.write_int_log(path=img_object.int_log, output=output, log_entry=log_entry) return img_object def process(self, img_object): # write out DIALS info (tied to self.write_pickle) if self.write_pickle: self.params.output.indexed_filename = img_object.ridx_path self.params.output.strong_filename = img_object.rspf_path self.params.output.refined_experiments_filename = img_object.eref_path self.params.output.integrated_experiments_filename = img_object.eint_path self.params.output.integrated_filename = img_object.rint_path # Set up integration pickle path and logfile self.params.output.integration_pickle = img_object.int_file self.int_log = img_object.int_log # configure DIALS logging self.dials_log = getattr(img_object, 'dials_log', None) if self.dials_log: log.config(verbosity=1, logfile=self.dials_log) # Create output folder if one does not exist if self.write_pickle: if not os.path.isdir(img_object.int_path): os.makedirs(img_object.int_path) # Auto-set threshold and gain (not saved for target.phil) if self.iparams.cctbx_xfel.auto_threshold: center_int = img_object.center_int if img_object.center_int else 0 threshold = int(center_int) self.params.spotfinder.threshold.dispersion.global_threshold = threshold if self.iparams.image_import.estimate_gain: self.params.spotfinder.threshold.dispersion.gain = img_object.gain # Update geometry if reference geometry was applied from dials.command_line.dials_import import ManualGeometryUpdater update_geometry = ManualGeometryUpdater(self.params) try: imagesets = img_object.experiments.imagesets() update_geometry(imagesets[0]) experiment = img_object.experiments[0] experiment.beam = imagesets[0].get_beam() experiment.detector = imagesets[0].get_detector() except RuntimeError as e: print("DEBUG: Error updating geometry on {}, {}".format( img_object.img_path, e)) # Set detector if reference geometry was applied if self.reference_detector is not None: try: from dxtbx.model import Detector imageset = img_object.experiments[0].imageset imageset.set_detector( Detector.from_dict(self.reference_detector.to_dict())) img_object.experiments[0].detector = imageset.get_detector() except Exception as e: print('DEBUG: cannot set detector! ', e) # Write full params to file (DEBUG) if self.write_logs: param_string = phil_scope.format( python_object=self.params).as_str() full_param_dir = os.path.dirname(self.iparams.cctbx_xfel.target) full_param_fn = 'full_' + os.path.basename( self.iparams.cctbx_xfel.target) full_param_file = os.path.join(full_param_dir, full_param_fn) with open(full_param_file, 'w') as ftarg: ftarg.write(param_string) # **** SPOTFINDING **** # with util.Capturing() as output: try: print("{:-^100}\n".format(" SPOTFINDING: ")) print('<--->') observed = self.find_spots(img_object.experiments) img_object.final['spots'] = len(observed) except Exception as e: e_spf = str(e) observed = None else: if (self.iparams.data_selection.image_triage and len(observed) >= self.iparams.data_selection. image_triage.minimum_Bragg_peaks): msg = " FOUND {} SPOTS - IMAGE ACCEPTED!".format( len(observed)) print("{:-^100}\n\n".format(msg)) else: msg = " FOUND {} SPOTS - IMAGE REJECTED!".format( len(observed)) print("{:-^100}\n\n".format(msg)) e = 'Insufficient spots found ({})!'.format(len(observed)) return self.error_handler(e, 'triage', img_object, output) if not observed: return self.error_handler(e_spf, 'spotfinding', img_object, output) if self.write_logs: self.write_int_log(path=img_object.int_log, output=output, dials_log=self.dials_log) # Finish if spotfinding is the last processing stage if 'spotfind' in self.last_stage: try: detector = img_object.experiments.unique_detectors()[0] beam = img_object.experiments.unique_beams()[0] except AttributeError: detector = img_object.experiments.imagesets()[0].get_detector() beam = img_object.experiments.imagesets()[0].get_beam() s1 = flex.vec3_double() for i in range(len(observed)): s1.append(detector[observed['panel'][i]].get_pixel_lab_coord( observed['xyzobs.px.value'][i][0:2])) two_theta = s1.angle(beam.get_s0()) d = beam.get_wavelength() / (2 * flex.asin(two_theta / 2)) img_object.final['res'] = np.max(d) img_object.final['lres'] = np.min(d) return img_object # **** INDEXING **** # with util.Capturing() as output: try: print("{:-^100}\n".format(" INDEXING")) print('<--->') experiments, indexed = self.index(img_object.experiments, observed) except Exception as e: e_idx = str(e) indexed = None else: if indexed: img_object.final['indexed'] = len(indexed) print("{:-^100}\n\n".format(" USED {} INDEXED REFLECTIONS " "".format(len(indexed)))) else: e_idx = "Not indexed for unspecified reason(s)" img_object.fail = 'failed indexing' if indexed: if self.write_logs: self.write_int_log(path=img_object.int_log, output=output, dials_log=self.dials_log) else: return self.error_handler(e_idx, 'indexing', img_object, output) with util.Capturing() as output: # Bravais lattice and reindex if self.iparams.cctbx_xfel.determine_sg_and_reindex: try: print("{:-^100}\n".format(" DETERMINING SPACE GROUP")) print('<--->') experiments, indexed = self.pg_and_reindex( indexed, experiments) img_object.final['indexed'] = len(indexed) lat = experiments[0].crystal.get_space_group().info() sg = str(lat).replace(' ', '') if sg != 'P1': print("{:-^100}\n".format( " REINDEXED TO SPACE GROUP {} ".format(sg))) else: print("{:-^100}\n".format( " RETAINED TRICLINIC (P1) SYMMETRY ")) reindex_success = True except Exception as e: e_ridx = str(e) reindex_success = False if reindex_success: if self.write_logs: self.write_int_log(path=img_object.int_log, output=output, dials_log=self.dials_log) else: return self.error_handler(e_ridx, 'indexing', img_object, output) # **** REFINEMENT **** # with util.Capturing() as output: try: experiments, indexed = self.refine(experiments, indexed) refined = True except Exception as e: e_ref = str(e) refined = False if refined: if self.write_logs: self.write_int_log(path=img_object.int_log, output=output, dials_log=self.dials_log) else: return self.error_handler(e_ref, 'refinement', img_object, output) # **** INTEGRATION **** # with util.Capturing() as output: try: print("{:-^100}\n".format(" INTEGRATING ")) print('<--->') integrated = self.integrate(experiments, indexed) except Exception as e: e_int = str(e) integrated = None else: if integrated: img_object.final['integrated'] = len(integrated) print("{:-^100}\n\n".format( " FINAL {} INTEGRATED REFLECTIONS " "".format(len(integrated)))) if integrated: if self.write_logs: self.write_int_log(path=img_object.int_log, output=output, dials_log=self.dials_log) else: return self.error_handler(e_int, 'integration', img_object, output) # Filter if self.iparams.cctbx_xfel.filter.flag_on: self.selector = Selector( frame=self.frame, uc_tol=self.iparams.cctbx_xfel.filter.uc_tolerance, xsys=self.iparams.cctbx_xfel.filter.crystal_system, pg=self.iparams.cctbx_xfel.filter.pointgroup, uc=self.iparams.cctbx_xfel.filter.unit_cell, min_ref=self.iparams.cctbx_xfel.filter.min_reflections, min_res=self.iparams.cctbx_xfel.filter.min_resolution) fail, e = self.selector.result_filter() if fail: return self.error_handler(e, 'filter', img_object, output) int_results, log_entry = self.collect_information( img_object=img_object) # Update final entry with integration results img_object.final.update(int_results) # Update image log log_entry = "\n".join(log_entry) img_object.log_info.append(log_entry) if self.write_logs: self.write_int_log(path=img_object.int_log, log_entry=log_entry) return img_object def write_int_log(self, path, output=None, log_entry=None, dials_log=None): if output: output = [i for i in output if 'cxi_version' not in i] output_string = '\n'.join(output) else: output_string = '' # insert DIALS logging output if dials_log is not None: with open(dials_log, 'r') as dlog: dlog.seek(self.dlog_bookmark) dials_log_lines = [' {}'.format(l) for l in dlog.readlines()] dials_log_string = ''.join(dials_log_lines) self.dlog_bookmark = dlog.tell() output_string = output_string.replace('<--->', dials_log_string) # Add IOTA log entry if exists if log_entry: output_string += log_entry # Write log to file with open(path, 'a') as tf: tf.write(output_string) # for i in output: # if 'cxi_version' not in i: # tf.write('\n{}'.format(i)) # if log_entry: # tf.write('\n{}'.format(log_entry)) def collect_information(self, img_object): # Collect information obs = self.frame['observations'][0] Bravais_lattice = self.frame['pointgroup'] cell = obs.unit_cell().parameters() lres, hres = obs.d_max_min() # Calculate number of spots w/ high I / sigmaI Is = obs.data() sigmas = obs.sigmas() I_over_sigI = Is / sigmas strong_spots = len([ i for i in I_over_sigI if i >= self.iparams.data_selection.image_triage.strong_sigma ]) # Mosaicity parameters mosaicity = round((self.frame.get('ML_half_mosaicity_deg', [0])[0]), 6) ewald_proximal_volume = self.frame.get('ewald_proximal_volume', [0])[0] # Assemble output for log file and/or integration result file p_cell = "{:>6.2f}, {:>6.2f}, {:>6.2f}, {:>6.2f}, {:>6.2f}, {:>6.2f}"\ "".format(cell[0], cell[1], cell[2], cell[3], cell[4], cell[5]) int_status = 'RES: {:<4.2f} NSREF: {:<4} SG: {:<5} CELL: {}'\ ''.format(hres, strong_spots, Bravais_lattice, p_cell) int_results = { 'sg': Bravais_lattice, 'a': cell[0], 'b': cell[1], 'c': cell[2], 'alpha': cell[3], 'beta': cell[4], 'gamma': cell[5], 'wavelength': self.frame['wavelength'], 'distance': self.frame['distance'], 'beamX': self.frame['xbeam'], 'beamY': self.frame['ybeam'], 'observations': obs, 'strong': strong_spots, 'res': hres, 'lres': lres, 'mos': mosaicity, 'epv': ewald_proximal_volume, 'info': int_status, 'ok': True } # Generate log summary of integration results img_filename = os.path.basename(img_object.img_path) log_entry = ['\nCCTBX.XFEL integration:'] log_entry.append('{:<{width}} ---> {}'.format( img_filename, int_status, width=len(img_filename) + 2)) return int_results, log_entry def run(self, img_object): return self.process(img_object=img_object)
def make_pickle(self): if (self.experiments is None) or (self.reflections is None): self.dictionary = None else: contents = ConstructFrame(self.reflections, self.experiments) self.dictionary = contents.make_frame()
def process_image(self): if os.path.isfile(self.termfile): raise IOTATermination('IOTA_TRACKER: Termination signal received!') else: with Capturing() as junk_output: # if True: err = [] start = time.time() fail = False sg = None uc = None status = None score = 0 try: datablock = DataBlockFactory.from_filenames([self.img])[0] observed = self.processor.find_spots(datablock=datablock) status = 'spots found' except Exception, e: fail = True observed = [] err.append('SPOTFINDING ERROR: {}'.format(e)) pass # TODO: Indexing / lattice determination very slow (how to speed up?) if self.run_indexing: if not fail: try: experiments, indexed = self.processor.index( datablock=datablock, reflections=observed) score = len(indexed) except Exception, e: fail = True err.append('INDEXING ERROR: {}'.format(e)) pass if not fail: try: solution = self.processor.refine_bravais_settings( reflections=indexed, experiments=experiments) # Only reindex if higher-symmetry solution found if solution is not None: experiments, indexed = self.processor.reindex( reflections=indexed, experiments=experiments, solution=solution) obs = experiments lat = experiments[0].crystal.get_space_group( ).info() sg = str(lat).replace(' ', '') status = 'indexed' except Exception, e: fail = True err.append('LATTICE ERROR: {}'.format(e)) pass if not fail: unit_cell = experiments[0].crystal.get_unit_cell( ).parameters() uc = ' '.join(['{:.4f}'.format(i) for i in unit_cell]) if self.run_integration: if not fail: try: # Run refinement experiments, indexed = self.processor.refine( experiments=experiments, centroids=indexed) except Exception, e: fail = True err.append('REFINEMENT ERROR: {}'.format(e)) pass if not fail: try: print(experiments) print(indexed) integrated = self.processor.integrate( experiments=experiments, indexed=indexed) frame = ConstructFrame( integrated, experiments[0]).make_frame() status = 'integrated' except Exception, e: err.append('INTEGRATION ERROR: {}'.format(e)) pass
def __init__(self, refl=None, expt=None, id=None, **kwargs): from xfel.command_line.frame_extractor import ConstructFrame frame = ConstructFrame(refl, expt).make_frame() SingleFrame.__init__(self, dicti=frame, path=str(id), **kwargs) self.experiment = expt self.reflections = refl
def construct_frame(self, integrated, exeriments): # Construct frame from xfel.command_line.frame_extractor import ConstructFrame self.frame = ConstructFrame(integrated, experiments[0]).make_frame() self.frame["pixel_size"] = experiments[0].detector[0].get_pixel_size()[0]
def process_image(self): if os.path.isfile(self.termfile): raise IOTATermination('IOTA_TRACKER: Termination signal received!') else: with Capturing() as junk_output: # if True: err = [] start = time.time() fail = False sg = None uc = None status = None score = 0 try: datablock = DataBlockFactory.from_filenames([self.img])[0] observed = self.processor.find_spots(datablock=datablock) status = 'spots found' except Exception as e: fail = True observed = [] err.append('SPOTFINDING ERROR: {}'.format(e)) pass # TODO: Indexing / lattice determination very slow (how to speed up?) if self.run_indexing: if not fail: try: experiments, indexed = self.processor.index( datablock=datablock, reflections=observed) score = len(indexed) except Exception as e: fail = True err.append('INDEXING ERROR: {}'.format(e)) pass if not fail: try: solution = self.processor.refine_bravais_settings( reflections=indexed, experiments=experiments) # Only reindex if higher-symmetry solution found if solution is not None: experiments, indexed = self.processor.reindex( reflections=indexed, experiments=experiments, solution=solution) obs = experiments lat = experiments[0].crystal.get_space_group( ).info() sg = str(lat).replace(' ', '') status = 'indexed' except Exception as e: fail = True err.append('LATTICE ERROR: {}'.format(e)) pass if not fail: unit_cell = experiments[0].crystal.get_unit_cell( ).parameters() uc = ' '.join(['{:.4f}'.format(i) for i in unit_cell]) if self.run_integration: if not fail: try: # Run refinement experiments, indexed = self.processor.refine( experiments=experiments, centroids=indexed) except Exception as e: fail = True err.append('REFINEMENT ERROR: {}'.format(e)) pass if not fail: try: print experiments print indexed integrated = self.processor.integrate( experiments=experiments, indexed=indexed) frame = ConstructFrame( integrated, experiments[0]).make_frame() status = 'integrated' except Exception as e: err.append('INTEGRATION ERROR: {}'.format(e)) pass if status == 'integrated': res = frame['observations'][0].d_max_min() else: detector = datablock.unique_detectors()[0] beam = datablock.unique_beams()[0] s1 = flex.vec3_double() for i in xrange(len(observed)): s1.append( detector[observed['panel'][i]].get_pixel_lab_coord( observed['xyzobs.px.value'][i][0:2])) two_theta = s1.angle(beam.get_s0()) d = beam.get_wavelength() / (2 * flex.asin(two_theta / 2)) res = (np.max(d), np.min(d)) if len(observed) < self.min_bragg: res = (99, 99) elapsed = time.time() - start info = [self.index, len(observed), self.img, sg, uc] return status, info, res, score, elapsed, err
def make_pickle(self): if (self.experiments is None) or (self.reflections is None): self.dictionary = None else: contents = ConstructFrame(self.reflections, self.experiments) self.dictionary = contents.make_frame()
from libtbx import easy_pickle import os from xfel.command_line.frame_extractor import ConstructFrame from dials.array_family import flex from dxtbx.model.experiment_list import ExperimentListFactory import sys if __name__ == "__main__": experiments = ExperimentListFactory.from_json_file(sys.argv[1]) reflections = flex.reflection_table.from_file(sys.argv[2]) if len(sys.argv) == 4: outfile_template = sys.argv[3] else: outfile_template = "int-%03d.refl" # Split everything into separate experiments for pickling for e_number in range(len(experiments)): experiment = experiments[e_number] e_selection = reflections["id"] == e_number subset = reflections.select(e_selection) frame = ConstructFrame(subset, experiment).make_frame() frame["pixel_size"] = experiment.detector[0].get_pixel_size()[0] outfile = outfile_template % (e_number + 1) print("Writing %s" % outfile) easy_pickle.dump(outfile, frame)