Esempio n. 1
0
def crystal_model_from_mosflm_mat(mosflm_mat_lines, unit_cell, space_group):
    from scitbx import matrix
    from cctbx import uctbx
    if not isinstance(unit_cell, uctbx.unit_cell):
        unit_cell = uctbx.unit_cell(unit_cell)
    from dxtbx.model import CrystalFactory
    mosflm_matrix = matrix.sqr(
        [float(i) for line in mosflm_mat_lines[:3] for i in line.split()][:9])
    crystal_model = CrystalFactory.from_mosflm_matrix(mosflm_matrix,
                                                      unit_cell=unit_cell,
                                                      space_group=space_group)
    return crystal_model
Esempio n. 2
0
def test_crystal_model_from_mosflm_matrix():
    mosflm_matrix = map(
        float, ''' -0.00495480 -0.01491776  0.00238445
  0.01505572 -0.00661190 -0.00149401
  0.00585043  0.00438127  0.00586415
       0.000       0.000       0.000
  -0.2932645  -0.8829514   0.3665960
   0.8911171  -0.3913446  -0.2296951
   0.3462750   0.2593185   0.9015806
     57.7822     57.7822    150.0931     90.0000     90.0000     90.0000
       0.000       0.000       0.000'''.split())
    A = mosflm_matrix[:9]
    unit_cell = uctbx.unit_cell(mosflm_matrix[21:27])
    cm = CrystalFactory.from_mosflm_matrix(A, unit_cell=unit_cell)
    assert approx_equal(cm.get_unit_cell().parameters(),
                        unit_cell.parameters(),
                        eps=1.0e-2)
Esempio n. 3
0
    def _index(self):
        '''Actually index the diffraction pattern. Note well that
    this is not going to compute the matrix...'''

        # acknowledge this program

        Citations.cite('labelit')
        Citations.cite('distl')

        #self.reset()

        _images = []
        for i in self._indxr_images:
            for j in i:
                if not j in _images:
                    _images.append(j)

        _images.sort()

        images_str = '%d' % _images[0]
        for i in _images[1:]:
            images_str += ', %d' % i

        cell_str = None
        if self._indxr_input_cell:
            cell_str = '%.2f %.2f %.2f %.2f %.2f %.2f' % \
                        self._indxr_input_cell

        if self._indxr_sweep_name:

            # then this is a proper autoindexing run - describe this
            # to the journal entry

            #if len(self._fp_directory) <= 50:
            #dirname = self._fp_directory
            #else:
            #dirname = '...%s' % self._fp_directory[-46:]
            dirname = os.path.dirname(self.get_imageset().get_template())

            Journal.block(
                'autoindexing', self._indxr_sweep_name, 'labelit', {
                    'images': images_str,
                    'target cell': cell_str,
                    'target lattice': self._indxr_input_lattice,
                    'template': self.get_imageset().get_template(),
                    'directory': dirname
                })

        if len(_images) > 4:
            raise RuntimeError('cannot use more than 4 images')

        from xia2.Wrappers.Labelit.LabelitIndex import LabelitIndex
        index = LabelitIndex()
        index.set_working_directory(self.get_working_directory())
        auto_logfiler(index)

        #task = 'Autoindex from images:'

        #for i in _images:
        #task += ' %s' % self.get_image_name(i)

        #self.set_task(task)

        Debug.write('Indexing from images:')
        for i in _images:
            index.add_image(self.get_image_name(i))
            Debug.write('%s' % self.get_image_name(i))

        xsweep = self.get_indexer_sweep()
        if xsweep is not None:
            if xsweep.get_distance() is not None:
                index.set_distance(xsweep.get_distance())
            #if self.get_wavelength_prov() == 'user':
            #index.set_wavelength(self.get_wavelength())
            if xsweep.get_beam_centre() is not None:
                index.set_beam_centre(xsweep.get_beam_centre())

        if self._refine_beam is False:
            index.set_refine_beam(False)
        else:
            index.set_refine_beam(True)
            index.set_beam_search_scope(self._beam_search_scope)

        if ((math.fabs(self.get_wavelength() - 1.54) < 0.01)
                or (math.fabs(self.get_wavelength() - 2.29) < 0.01)):
            index.set_Cu_KA_or_Cr_KA(True)

        #sweep = self.get_indexer_sweep_name()
        #FileHandler.record_log_file(
        #'%s INDEX' % (sweep), self.get_log_file())

        try:
            index.run()
        except RuntimeError as e:

            if self._refine_beam is False:
                raise e

            # can we improve the situation?

            if self._beam_search_scope < 4.0:
                self._beam_search_scope += 4.0

                # try repeating the indexing!

                self.set_indexer_done(False)
                return 'failed'

            # otherwise this is beyond redemption

            raise e

        self._solutions = index.get_solutions()

        # FIXME this needs to check the smilie status e.g.
        # ":)" or ";(" or "  ".

        # FIXME need to check the value of the RMSD and raise an
        # exception if the P1 solution has an RMSD > 1.0...

        # Change 27/FEB/08 to support user assigned spacegroups
        # (euugh!) have to "ignore" solutions with higher symmetry
        # otherwise the rest of xia will override us. Bummer.

        for i, solution in self._solutions.iteritems():
            if self._indxr_user_input_lattice:
                if (lattice_to_spacegroup(solution['lattice']) >
                        lattice_to_spacegroup(self._indxr_input_lattice)):
                    Debug.write('Ignoring solution: %s' % solution['lattice'])
                    del self._solutions[i]

        # check the RMSD from the triclinic unit cell
        if self._solutions[1]['rmsd'] > 1.0 and False:
            # don't know when this is useful - but I know when it is not!
            raise RuntimeError('high RMSD for triclinic solution')

        # configure the "right" solution
        self._solution = self.get_solution()

        # now store also all of the other solutions... keyed by the
        # lattice - however these should only be added if they
        # have a smiley in the appropriate record, perhaps?

        for solution in self._solutions.keys():
            lattice = self._solutions[solution]['lattice']
            if lattice in self._indxr_other_lattice_cell:
                if self._indxr_other_lattice_cell[lattice]['goodness'] < \
                   self._solutions[solution]['metric']:
                    continue

            self._indxr_other_lattice_cell[lattice] = {
                'goodness': self._solutions[solution]['metric'],
                'cell': self._solutions[solution]['cell']
            }

        self._indxr_lattice = self._solution['lattice']
        self._indxr_cell = tuple(self._solution['cell'])
        self._indxr_mosaic = self._solution['mosaic']

        lms = LabelitMosflmScript()
        lms.set_working_directory(self.get_working_directory())
        lms.set_solution(self._solution['number'])
        self._indxr_payload['mosflm_orientation_matrix'] = lms.calculate()

        # get the beam centre from the mosflm script - mosflm
        # may have inverted the beam centre and labelit will know
        # this!

        mosflm_beam_centre = lms.get_mosflm_beam()

        if mosflm_beam_centre:
            self._indxr_payload['mosflm_beam_centre'] = tuple(
                mosflm_beam_centre)

        import copy
        detector = copy.deepcopy(self.get_detector())
        beam = copy.deepcopy(self.get_beam())
        from dxtbx.model.detector_helpers import set_mosflm_beam_centre
        set_mosflm_beam_centre(detector, beam, mosflm_beam_centre)

        from xia2.Experts.SymmetryExpert import lattice_to_spacegroup_number
        from scitbx import matrix
        from cctbx import sgtbx, uctbx
        from dxtbx.model import CrystalFactory
        mosflm_matrix = matrix.sqr([
            float(i) for line in lms.calculate()
            for i in line.replace("-", " -").split()
        ][:9])

        space_group = sgtbx.space_group_info(
            lattice_to_spacegroup_number(self._solution['lattice'])).group()
        crystal_model = CrystalFactory.from_mosflm_matrix(
            mosflm_matrix,
            unit_cell=uctbx.unit_cell(tuple(self._solution['cell'])),
            space_group=space_group)

        from dxtbx.model import Experiment, ExperimentList
        experiment = Experiment(
            beam=beam,
            detector=detector,
            goniometer=self.get_goniometer(),
            scan=self.get_scan(),
            crystal=crystal_model,
        )

        experiment_list = ExperimentList([experiment])
        self.set_indexer_experiment_list(experiment_list)

        # also get an estimate of the resolution limit from the
        # labelit.stats_distl output... FIXME the name is wrong!

        lsd = LabelitStats_distl()
        lsd.set_working_directory(self.get_working_directory())
        lsd.stats_distl()

        resolution = 1.0e6
        for i in _images:
            stats = lsd.get_statistics(self.get_image_name(i))

            resol = 0.5 * (stats['resol_one'] + stats['resol_two'])

            if resol < resolution:
                resolution = resol

        self._indxr_resolution_estimate = resolution

        return 'ok'
    def _index(self):
        """Actually index the diffraction pattern. Note well that
        this is not going to compute the matrix..."""

        # acknowledge this program

        if not self._indxr_images:
            raise RuntimeError("No good spots found on any images")

        Citations.cite("labelit")
        Citations.cite("distl")

        _images = []
        for i in self._indxr_images:
            for j in i:
                if not j in _images:
                    _images.append(j)

        _images.sort()

        images_str = "%d" % _images[0]
        for i in _images[1:]:
            images_str += ", %d" % i

        cell_str = None
        if self._indxr_input_cell:
            cell_str = "%.2f %.2f %.2f %.2f %.2f %.2f" % self._indxr_input_cell

        if self._indxr_sweep_name:

            # then this is a proper autoindexing run - describe this
            # to the journal entry

            if len(self._fp_directory) <= 50:
                dirname = self._fp_directory
            else:
                dirname = "...%s" % self._fp_directory[-46:]

            Journal.block(
                "autoindexing",
                self._indxr_sweep_name,
                "labelit",
                {
                    "images": images_str,
                    "target cell": cell_str,
                    "target lattice": self._indxr_input_lattice,
                    "template": self._fp_template,
                    "directory": dirname,
                },
            )

        # auto_logfiler(self)

        from xia2.Wrappers.Labelit.LabelitIndex import LabelitIndex

        index = LabelitIndex()
        index.set_working_directory(self.get_working_directory())
        auto_logfiler(index)

        # task = 'Autoindex from images:'

        # for i in _images:
        # task += ' %s' % self.get_image_name(i)

        # self.set_task(task)

        # self.add_command_line('--index_only')

        Debug.write("Indexing from images:")
        for i in _images:
            index.add_image(self.get_image_name(i))
            Debug.write("%s" % self.get_image_name(i))

        if self._primitive_unit_cell:
            index.set_primitive_unit_cell(self._primitive_unit_cell)

        if self._indxr_input_cell:
            index.set_max_cell(1.25 * max(self._indxr_input_cell[:3]))

        xsweep = self.get_indexer_sweep()
        if xsweep is not None:
            if xsweep.get_distance() is not None:
                index.set_distance(xsweep.get_distance())
            # if self.get_wavelength_prov() == 'user':
            # index.set_wavelength(self.get_wavelength())
            if xsweep.get_beam_centre() is not None:
                index.set_beam_centre(xsweep.get_beam_centre())

        if self._refine_beam is False:
            index.set_refine_beam(False)
        else:
            index.set_refine_beam(True)
            index.set_beam_search_scope(self._beam_search_scope)

        if (math.fabs(self.get_wavelength() - 1.54) <
                0.01) or (math.fabs(self.get_wavelength() - 2.29) < 0.01):
            index.set_Cu_KA_or_Cr_KA(True)

        try:
            index.run()
        except RuntimeError as e:

            if self._refine_beam is False:
                raise e

            # can we improve the situation?

            if self._beam_search_scope < 4.0:
                self._beam_search_scope += 4.0

                # try repeating the indexing!

                self.set_indexer_done(False)
                return "failed"

            # otherwise this is beyond redemption

            raise e

        self._solutions = index.get_solutions()

        # FIXME this needs to check the smilie status e.g.
        # ":)" or ";(" or "  ".

        # FIXME need to check the value of the RMSD and raise an
        # exception if the P1 solution has an RMSD > 1.0...

        # Change 27/FEB/08 to support user assigned spacegroups
        # (euugh!) have to "ignore" solutions with higher symmetry
        # otherwise the rest of xia will override us. Bummer.

        for i, solution in self._solutions.iteritems():
            if self._indxr_user_input_lattice:
                if lattice_to_spacegroup(
                        solution["lattice"]) > lattice_to_spacegroup(
                            self._indxr_input_lattice):
                    Debug.write("Ignoring solution: %s" % solution["lattice"])
                    del self._solutions[i]

        # configure the "right" solution
        self._solution = self.get_solution()

        # now store also all of the other solutions... keyed by the
        # lattice - however these should only be added if they
        # have a smiley in the appropriate record, perhaps?

        for solution in self._solutions.keys():
            lattice = self._solutions[solution]["lattice"]
            if lattice in self._indxr_other_lattice_cell:
                if (self._indxr_other_lattice_cell[lattice]["goodness"] <
                        self._solutions[solution]["metric"]):
                    continue

            self._indxr_other_lattice_cell[lattice] = {
                "goodness": self._solutions[solution]["metric"],
                "cell": self._solutions[solution]["cell"],
            }

        self._indxr_lattice = self._solution["lattice"]
        self._indxr_cell = tuple(self._solution["cell"])
        self._indxr_mosaic = self._solution["mosaic"]

        lms = LabelitMosflmMatrix()
        lms.set_working_directory(self.get_working_directory())
        lms.set_solution(self._solution["number"])
        self._indxr_payload["mosflm_orientation_matrix"] = lms.calculate()

        # get the beam centre from the mosflm script - mosflm
        # may have inverted the beam centre and labelit will know
        # this!

        mosflm_beam_centre = lms.get_mosflm_beam()

        if mosflm_beam_centre:
            self._indxr_payload["mosflm_beam_centre"] = tuple(
                mosflm_beam_centre)

        detector = copy.deepcopy(self.get_detector())
        beam = copy.deepcopy(self.get_beam())
        from dxtbx.model.detector_helpers import set_mosflm_beam_centre

        set_mosflm_beam_centre(detector, beam, mosflm_beam_centre)

        from xia2.Experts.SymmetryExpert import lattice_to_spacegroup_number
        from scitbx import matrix
        from cctbx import sgtbx, uctbx
        from dxtbx.model import CrystalFactory

        mosflm_matrix = matrix.sqr([
            float(i) for line in lms.calculate()
            for i in line.replace("-", " -").split()
        ][:9])

        space_group = sgtbx.space_group_info(
            lattice_to_spacegroup_number(self._solution["lattice"])).group()
        crystal_model = CrystalFactory.from_mosflm_matrix(
            mosflm_matrix,
            unit_cell=uctbx.unit_cell(tuple(self._solution["cell"])),
            space_group=space_group,
        )

        from dxtbx.model import Experiment, ExperimentList

        experiment = Experiment(
            beam=beam,
            detector=detector,
            goniometer=self.get_goniometer(),
            scan=self.get_scan(),
            crystal=crystal_model,
        )

        experiment_list = ExperimentList([experiment])
        self.set_indexer_experiment_list(experiment_list)

        # also get an estimate of the resolution limit from the
        # labelit.stats_distl output... FIXME the name is wrong!

        lsd = LabelitStats_distl()
        lsd.set_working_directory(self.get_working_directory())
        lsd.stats_distl()

        resolution = 1.0e6
        for i in _images:
            stats = lsd.get_statistics(self.get_image_name(i))

            resol = 0.5 * (stats["resol_one"] + stats["resol_two"])

            if resol < resolution:
                resolution = resol

        self._indxr_resolution_estimate = resolution

        return "ok"