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
示例#2
0
    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
示例#3
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