def refine_bravais_settings(self, reflections, experiments): # configure DIALS logging if self.dials_log: log.config(verbosity=0, 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) # 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 Lfat 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 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 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