Esempio n. 1
0
    def predict_to_miller_set_with_shadow(self, expt, resolution):
        predicted = flex.reflection_table.from_predictions(expt, dmin=resolution)

        # transmogrify this to an ExperimentList from an Experiment
        experiments = ExperimentList()
        experiments.append(expt)
        predicted["id"] = flex.int(predicted.size(), 0)
        shadowed = filter_shadowed_reflections(
            experiments, predicted, experiment_goniometer=True
        )
        predicted = predicted.select(~shadowed)

        hkl = predicted["miller_index"]

        # now get a full set of all unique miller indices
        obs = miller.set(
            crystal_symmetry=crystal.symmetry(
                space_group=expt.crystal.get_space_group(),
                unit_cell=expt.crystal.get_unit_cell(),
            ),
            anomalous_flag=True,
            indices=hkl,
        ).unique_under_symmetry()

        return obs, shadowed
    def predict_to_miller_set_with_shadow(self, expt, resolution):
        from dials.array_family import flex
        from dials.algorithms.shadowing.filter import filter_shadowed_reflections
        predicted = flex.reflection_table.from_predictions(expt,
                                                           dmin=resolution)

        # transmogrify this to an ExperimentList from an Experiment
        from dxtbx.model import ExperimentList
        experiments = ExperimentList()
        experiments.append(expt)
        predicted['id'] = flex.int(predicted.size(), 0)
        shadowed = filter_shadowed_reflections(experiments,
                                               predicted,
                                               experiment_goniometer=True)
        predicted = predicted.select(~shadowed)

        hkl = predicted['miller_index']

        # now get a full set of all unique miller indices
        from cctbx import miller
        from cctbx import crystal

        obs = miller.set(crystal_symmetry=crystal.symmetry(
            space_group=expt.crystal.get_space_group(),
            unit_cell=expt.crystal.get_unit_cell()),
                         anomalous_flag=True,
                         indices=hkl).unique_under_symmetry()

        return obs, shadowed
Esempio n. 3
0
  def run(self):
    '''Execute the script.'''
    from dials.util.command_line import Command
    from dials.array_family import flex
    from dials.util.options import flatten_experiments

    # Parse the command line
    params, options = self.parser.parse_args(show_diff_phil=True)

    # Check the number of experiments
    experiments = flatten_experiments(params.input.experiments)
    if len(experiments) == 0:
      self.parser.print_help()
      return

    predicted_all = flex.reflection_table()

    for i_expt, expt in enumerate(experiments):
      if params.buffer_size > 0:
        # Hack to make the predicter predict reflections outside of the range
        # of the scan
        scan = expt.scan
        image_range = scan.get_image_range()
        oscillation = scan.get_oscillation()
        scan.set_image_range((image_range[0]-params.buffer_size,
                              image_range[1]+params.buffer_size))
        scan.set_oscillation((oscillation[0]-params.buffer_size*oscillation[1],
                              oscillation[1]))

      # Populate the reflection table with predictions
      predicted = flex.reflection_table.from_predictions(
        expt,
        force_static=params.force_static,
        dmin=params.d_min)
      predicted['id'] = flex.int(len(predicted), i_expt)
      predicted_all.extend(predicted)

    # if we are not ignoring shadows, look for reflections in the masked
    # region, see https://github.com/dials/dials/issues/349

    if not params.ignore_shadows:
      from dials.algorithms.shadowing.filter import filter_shadowed_reflections

      shadowed = filter_shadowed_reflections(experiments, predicted_all,
                                             experiment_goniometer=True)
      predicted_all = predicted_all.select(~shadowed)

    try:
      predicted_all.compute_bbox(experiments)
    except Exception:
      pass

    # Save the reflections to file
    Command.start('Saving {0} reflections to {1}'.format(
        len(predicted_all), params.output))
    predicted_all.as_pickle(params.output)
    Command.end('Saved {0} reflections to {1}'.format(
        len(predicted_all), params.output))
Esempio n. 4
0
    def run(self, args=None):
        """Execute the script."""
        # Parse the command line
        params, options = self.parser.parse_args(args, show_diff_phil=True)

        # Check the number of experiments
        experiments = flatten_experiments(params.input.experiments)
        if len(experiments) == 0:
            self.parser.print_help()
            return

        predicted_all = flex.reflection_table()

        for i_expt, expt in enumerate(experiments):
            if params.buffer_size > 0:
                # Hack to make the predicter predict reflections outside of the range
                # of the scan
                scan = expt.scan
                image_range = scan.get_image_range()
                oscillation = scan.get_oscillation()
                scan.set_image_range((
                    image_range[0] - params.buffer_size,
                    image_range[1] + params.buffer_size,
                ))
                scan.set_oscillation((
                    oscillation[0] - params.buffer_size * oscillation[1],
                    oscillation[1],
                ))

            # Populate the reflection table with predictions
            predicted = flex.reflection_table.from_predictions(
                expt, force_static=params.force_static, dmin=params.d_min)
            predicted["id"] = flex.int(len(predicted), i_expt)
            predicted_all.extend(predicted)

        # if we are not ignoring shadows, look for reflections in the masked
        # region, see https://github.com/dials/dials/issues/349

        if not params.ignore_shadows:
            shadowed = filter_shadowed_reflections(experiments,
                                                   predicted_all,
                                                   experiment_goniometer=True)
            predicted_all = predicted_all.select(~shadowed)

        try:
            predicted_all.compute_bbox(experiments)
        except Exception:
            pass

        # Save the reflections to file
        Command.start(
            f"Saving {len(predicted_all)} reflections to {params.output}")
        predicted_all.as_file(params.output)
        Command.end(
            f"Saved {len(predicted_all)} reflections to {params.output}")
Esempio n. 5
0
def test_filter_shadowed_reflections(dials_regression):
    experiments_json = os.path.join(
        dials_regression, "shadow_test_data/DLS_I04_SmarGon/experiments.json")
    predicted_pickle = os.path.join(
        dials_regression, "shadow_test_data/DLS_I04_SmarGon/predicted.pickle")

    experiments = load.experiment_list(experiments_json, check_format=True)
    predicted = flex.reflection_table.from_file(predicted_pickle)

    for experiment_goniometer in (True, False):
        shadowed = filter_shadowed_reflections(
            experiments,
            predicted,
            experiment_goniometer=experiment_goniometer)
        assert shadowed.count(True) == 17
        assert shadowed.count(False) == 674
Esempio n. 6
0
def test_filter_shadowed_reflections(dials_regression):
    experiments_json = os.path.join(
        dials_regression, "shadow_test_data/DLS_I04_SmarGon/experiments.json")

    predicted_pickle = os.path.join(
        dials_regression, "shadow_test_data/DLS_I04_SmarGon/predicted.pickle")

    from dxtbx.serialize import load
    experiments = load.experiment_list(experiments_json, check_format=True)

    from libtbx import easy_pickle
    predicted = easy_pickle.load(predicted_pickle)
    from dials.algorithms.shadowing.filter import filter_shadowed_reflections
    for experiment_goniometer in (True, False):
        shadowed = filter_shadowed_reflections(
            experiments,
            predicted,
            experiment_goniometer=experiment_goniometer)
        assert shadowed.count(True) == 17
        assert shadowed.count(False) == 674
Esempio n. 7
0
    def _integrate_finish(self):
        """Finish off the integration by running correct."""

        # first run the postrefinement etc with spacegroup P1
        # and the current unit cell - this will be used to
        # obtain a benchmark rmsd in pixels / phi and also
        # cell deviations (this is working towards spotting bad
        # indexing solutions) - only do this if we have no
        # reindex matrix... and no postrefined cell...

        p1_deviations = None

        # fix for bug # 3264 -
        # if we have not run integration with refined parameters, make it so...
        # erm? shouldn't this therefore return if this is the principle, or
        # set the flag after we have tested the lattice?

        if ("GXPARM.XDS" not in self._xds_data_files
                and PhilIndex.params.xds.integrate.reintegrate):
            logger.debug(
                "Resetting integrater, to ensure refined orientation is used")
            self.set_integrater_done(False)

        if (not self.get_integrater_reindex_matrix() and not self._intgr_cell
                and PhilIndex.params.xia2.settings.lattice_rejection
                and not self.get_integrater_sweep().get_user_lattice()):
            correct = self.Correct()

            correct.set_data_range(
                self._intgr_wedge[0] + self.get_frame_offset(),
                self._intgr_wedge[1] + self.get_frame_offset(),
            )

            if self.get_polarization() > 0.0:
                correct.set_polarization(self.get_polarization())

            # FIXME should this be using the correctly transformed
            # cell or are the results ok without it?!

            correct.set_spacegroup_number(1)
            correct.set_cell(self._intgr_refiner_cell)

            correct.run()

            cell = correct.get_result("cell")
            cell_esd = correct.get_result("cell_esd")

            logger.debug("Postrefinement in P1 results:")
            logger.debug("%7.3f %7.3f %7.3f %7.3f %7.3f %7.3f" % tuple(cell))
            logger.debug("%7.3f %7.3f %7.3f %7.3f %7.3f %7.3f" %
                         tuple(cell_esd))
            logger.debug("Deviations: %.2f pixels %.2f degrees" %
                         (correct.get_result("rmsd_pixel"),
                          correct.get_result("rmsd_phi")))

            p1_deviations = (
                correct.get_result("rmsd_pixel"),
                correct.get_result("rmsd_phi"),
            )

        # next run the postrefinement etc with the given
        # cell / lattice - this will be the assumed result...

        integrate_hkl = os.path.join(self.get_working_directory(),
                                     "INTEGRATE.HKL")

        if PhilIndex.params.xia2.settings.input.format.dynamic_shadowing:
            from dxtbx.serialize import load
            from dials.algorithms.shadowing.filter import filter_shadowed_reflections

            experiments_json = xparm_xds_to_experiments_json(
                os.path.join(self.get_working_directory(), "XPARM.XDS"),
                self.get_working_directory(),
            )
            experiments = load.experiment_list(experiments_json,
                                               check_format=True)
            imageset = experiments[0].imageset
            masker = (imageset.get_format_class().get_instance(
                imageset.paths()[0]).get_masker())
            if masker is not None:
                integrate_filename = integrate_hkl_to_reflection_file(
                    integrate_hkl, experiments_json,
                    self.get_working_directory())
                reflections = flex.reflection_table.from_file(
                    integrate_filename)

                t0 = time.time()
                sel = filter_shadowed_reflections(experiments, reflections)
                shadowed = reflections.select(sel)
                t1 = time.time()
                logger.debug("Filtered %i reflections in %.1f seconds" %
                             (sel.count(True), t1 - t0))

                filter_hkl = os.path.join(self.get_working_directory(),
                                          "FILTER.HKL")
                with open(filter_hkl, "wb") as f:
                    detector = experiments[0].detector
                    for ref in shadowed:
                        p = detector[ref["panel"]]
                        ox, oy = p.get_raw_image_offset()
                        h, k, l = ref["miller_index"]
                        x, y, z = ref["xyzcal.px"]
                        dx, dy, dz = (2, 2, 2)
                        print(
                            "%i %i %i %.1f %.1f %.1f %.1f %.1f %.1f" %
                            (h, k, l, x + ox, y + oy, z, dx, dy, dz),
                            file=f,
                        )
                t2 = time.time()
                logger.debug("Written FILTER.HKL in %.1f seconds" % (t2 - t1))

        correct = self.Correct()

        correct.set_data_range(
            self._intgr_wedge[0] + self.get_frame_offset(),
            self._intgr_wedge[1] + self.get_frame_offset(),
        )

        if self.get_polarization() > 0.0:
            correct.set_polarization(self.get_polarization())

        # BUG # 2695 probably comes from here - need to check...
        # if the pointless interface comes back with a different
        # crystal setting then the unit cell stored in self._intgr_cell
        # needs to be set to None...

        if self.get_integrater_spacegroup_number():
            correct.set_spacegroup_number(
                self.get_integrater_spacegroup_number())
            if not self._intgr_cell:
                raise RuntimeError("no unit cell to recycle")
            correct.set_cell(self._intgr_cell)

        # BUG # 3113 - new version of XDS will try and figure the
        # best spacegroup out from the intensities (and get it wrong!)
        # unless we set the spacegroup and cell explicitly

        if not self.get_integrater_spacegroup_number():
            cell = self._intgr_refiner_cell
            lattice = self._intgr_refiner.get_refiner_lattice()
            spacegroup_number = lattice_to_spacegroup_number(lattice)

            # this should not prevent the postrefinement from
            # working correctly, else what is above would not
            # work correctly (the postrefinement test)

            correct.set_spacegroup_number(spacegroup_number)
            correct.set_cell(cell)

            logger.debug("Setting spacegroup to: %d" % spacegroup_number)
            logger.debug("Setting cell to: %.2f %.2f %.2f %.2f %.2f %.2f" %
                         tuple(cell))

        if self.get_integrater_reindex_matrix():

            # bug! if the lattice is not primitive the values in this
            # reindex matrix need to be multiplied by a constant which
            # depends on the Bravais lattice centering.

            lattice = self._intgr_refiner.get_refiner_lattice()

            matrix = self.get_integrater_reindex_matrix()
            matrix = scitbx.matrix.sqr(matrix).transpose().elems
            matrix = r_to_rt(matrix)

            if lattice[1] == "P":
                mult = 1
            elif lattice[1] == "C" or lattice[1] == "I":
                mult = 2
            elif lattice[1] == "R":
                mult = 3
            elif lattice[1] == "F":
                mult = 4
            else:
                raise RuntimeError("unknown multiplier for lattice %s" %
                                   lattice)

            logger.debug("REIDX multiplier for lattice %s: %d" %
                         (lattice, mult))

            mult_matrix = [mult * m for m in matrix]

            logger.debug("REIDX set to %d %d %d %d %d %d %d %d %d %d %d %d" %
                         tuple(mult_matrix))
            correct.set_reindex_matrix(mult_matrix)

        correct.run()

        # record the log file -

        pname, xname, dname = self.get_integrater_project_info()
        sweep = self.get_integrater_sweep_name()
        FileHandler.record_log_file(
            f"{pname} {xname} {dname} {sweep} CORRECT",
            os.path.join(self.get_working_directory(), "CORRECT.LP"),
        )

        FileHandler.record_more_data_file(
            f"{pname} {xname} {dname} {sweep} CORRECT",
            os.path.join(self.get_working_directory(), "XDS_ASCII.HKL"),
        )

        # erm. just to be sure
        if self.get_integrater_reindex_matrix() and correct.get_reindex_used():
            raise RuntimeError("Reindex panic!")

        # get the reindex operation used, which may be useful if none was
        # set but XDS decided to apply one, e.g. #419.

        if not self.get_integrater_reindex_matrix(
        ) and correct.get_reindex_used():
            # convert this reindex operation to h, k, l form: n.b. this
            # will involve dividing through by the lattice centring multiplier

            matrix = rt_to_r(correct.get_reindex_used())

            matrix = scitbx.matrix.sqr(matrix).transpose().elems

            lattice = self._intgr_refiner.get_refiner_lattice()

            if lattice[1] == "P":
                mult = 1.0
            elif lattice[1] == "C" or lattice[1] == "I":
                mult = 2.0
            elif lattice[1] == "R":
                mult = 3.0
            elif lattice[1] == "F":
                mult = 4.0

            matrix = [m / mult for m in matrix]

            reindex_op = mat_to_symop(matrix)

            # assign this to self: will this reset?! make for a leaky
            # abstraction and just assign this...

            # self.set_integrater_reindex_operator(reindex)

            self._intgr_reindex_operator = reindex_op

        # record the log file -

        pname, xname, dname = self.get_integrater_project_info()
        sweep = self.get_integrater_sweep_name()
        FileHandler.record_log_file(
            f"{pname} {xname} {dname} {sweep} CORRECT",
            os.path.join(self.get_working_directory(), "CORRECT.LP"),
        )

        # should get some interesting stuff from the XDS correct file
        # here, for instance the resolution range to use in integration
        # (which should be fed back if not fast) and so on...

        self._intgr_corrected_hklout = os.path.join(
            self.get_working_directory(), "XDS_ASCII.HKL")

        # also record the batch range - needed for the analysis of the
        # radiation damage in chef...

        self._intgr_batches_out = (self._intgr_wedge[0], self._intgr_wedge[1])

        # FIXME perhaps I should also feedback the GXPARM file here??
        for file in ["GXPARM.XDS"]:
            self._xds_data_files[file] = correct.get_output_data_file(file)

        # record the postrefined cell parameters
        self._intgr_cell = correct.get_result("cell")
        self._intgr_n_ref = correct.get_result("n_ref")

        logger.debug('Postrefinement in "correct" spacegroup results:')
        logger.debug("%7.3f %7.3f %7.3f %7.3f %7.3f %7.3f" %
                     tuple(correct.get_result("cell")))
        logger.debug("%7.3f %7.3f %7.3f %7.3f %7.3f %7.3f" %
                     tuple(correct.get_result("cell_esd")))
        logger.debug(
            "Deviations: %.2f pixels %.2f degrees" %
            (correct.get_result("rmsd_pixel"), correct.get_result("rmsd_phi")))

        logger.debug("Error correction parameters: A=%.3f B=%.3f" %
                     correct.get_result("sdcorrection"))

        # compute misorientation of axes

        xparm_file = os.path.join(self.get_working_directory(), "GXPARM.XDS")

        handle = xparm.reader()
        handle.read_file(xparm_file)

        rotn = handle.rotation_axis
        beam = handle.beam_vector

        dot = sum(rotn[j] * beam[j] for j in range(3))
        r = math.sqrt(sum(rotn[j] * rotn[j] for j in range(3)))
        b = math.sqrt(sum(beam[j] * beam[j] for j in range(3)))

        rtod = 180.0 / math.pi

        angle = rtod * math.fabs(0.5 * math.pi - math.acos(dot / (r * b)))

        logger.debug("Axis misalignment %.2f degrees" % angle)

        correct_deviations = (
            correct.get_result("rmsd_pixel"),
            correct.get_result("rmsd_phi"),
        )

        if p1_deviations:
            # compare and reject if both > 50% higher - though adding a little
            # flexibility - 0.5 pixel / osc width slack.

            pixel = p1_deviations[0]
            phi = math.sqrt(0.05 * 0.05 + p1_deviations[1] * p1_deviations[1])

            threshold = PhilIndex.params.xia2.settings.lattice_rejection_threshold
            logger.debug("RMSD ratio: %.2f" % (correct_deviations[0] / pixel))
            logger.debug("RMSPhi ratio: %.2f" % (correct_deviations[1] / phi))

            if (correct_deviations[0] / pixel > threshold
                    and correct_deviations[1] / phi > threshold):

                logger.info(
                    "Eliminating this indexing solution as postrefinement")
                logger.info("deviations rather high relative to triclinic")
                raise BadLatticeError(
                    "high relative deviations in postrefinement")

        if (not PhilIndex.params.dials.fast_mode
                and not PhilIndex.params.xds.keep_outliers):
            # check for alien reflections and perhaps recycle - removing them
            correct_remove = correct.get_remove()
            if correct_remove:
                current_remove = set()
                final_remove = []

                # first ensure that there are no duplicate entries...
                if os.path.exists(
                        os.path.join(self.get_working_directory(),
                                     "REMOVE.HKL")):
                    with open(
                            os.path.join(self.get_working_directory(),
                                         "REMOVE.HKL")) as fh:
                        for line in fh.readlines():
                            h, k, l = list(map(int, line.split()[:3]))
                            z = float(line.split()[3])

                            if (h, k, l, z) not in current_remove:
                                current_remove.add((h, k, l, z))

                    for c in correct_remove:
                        if c in current_remove:
                            continue
                        final_remove.append(c)

                    logger.debug("%d alien reflections are already removed" %
                                 (len(correct_remove) - len(final_remove)))
                else:
                    # we want to remove all of the new dodgy reflections
                    final_remove = correct_remove

                z_min = PhilIndex.params.xds.z_min
                rejected = 0

                with open(
                        os.path.join(self.get_working_directory(),
                                     "REMOVE.HKL"), "w") as remove_hkl:

                    # write in the old reflections
                    for remove in current_remove:
                        z = remove[3]
                        if z >= z_min:
                            remove_hkl.write("%d %d %d %f\n" % remove)
                        else:
                            rejected += 1
                    logger.debug("Wrote %d old reflections to REMOVE.HKL" %
                                 (len(current_remove) - rejected))
                    logger.debug("Rejected %d as z < %f" % (rejected, z_min))

                    # and the new reflections
                    rejected = 0
                    used = 0
                    for remove in final_remove:
                        z = remove[3]
                        if z >= z_min:
                            used += 1
                            remove_hkl.write("%d %d %d %f\n" % remove)
                        else:
                            rejected += 1
                    logger.debug("Wrote %d new reflections to REMOVE.HKL" %
                                 (len(final_remove) - rejected))
                    logger.debug("Rejected %d as z < %f" % (rejected, z_min))

                # we want to rerun the finishing step so...
                # unless we have added no new reflections... or unless we
                # have not confirmed the point group (see SCI-398)

                if used and self.get_integrater_reindex_matrix():
                    self.set_integrater_finish_done(False)

        else:
            logger.debug(
                "Going quickly so not removing %d outlier reflections..." %
                len(correct.get_remove()))

        # Convert INTEGRATE.HKL to MTZ format and reapply any reindexing operations
        # spacegroup changes to allow use with CCP4 / Aimless for scaling

        hklout = os.path.splitext(integrate_hkl)[0] + ".mtz"
        self._factory.set_working_directory(self.get_working_directory())
        pointless = self._factory.Pointless()
        pointless.set_xdsin(integrate_hkl)
        pointless.set_hklout(hklout)
        pointless.xds_to_mtz()

        integrate_mtz = hklout

        if (self.get_integrater_reindex_operator()
                or self.get_integrater_spacegroup_number()):

            logger.debug("Reindexing things to MTZ")

            reindex = Reindex()
            reindex.set_working_directory(self.get_working_directory())
            auto_logfiler(reindex)

            if self.get_integrater_reindex_operator():
                reindex.set_operator(self.get_integrater_reindex_operator())

            if self.get_integrater_spacegroup_number():
                reindex.set_spacegroup(self.get_integrater_spacegroup_number())

            hklout = "%s_reindex.mtz" % os.path.splitext(integrate_mtz)[0]

            reindex.set_hklin(integrate_mtz)
            reindex.set_hklout(hklout)
            reindex.reindex()
            integrate_mtz = hklout

        experiments_json = xparm_xds_to_experiments_json(
            self._xds_data_files["GXPARM.XDS"], self.get_working_directory())
        pname, xname, dname = self.get_integrater_project_info()
        sweep = self.get_integrater_sweep_name()
        FileHandler.record_more_data_file(f"{pname} {xname} {dname} {sweep}",
                                          experiments_json)
        FileHandler.record_more_data_file(
            f"{pname} {xname} {dname} {sweep} INTEGRATE", integrate_mtz)

        self._intgr_experiments_filename = experiments_json

        return integrate_mtz
Esempio n. 8
0
def run(args):

    from dials.util.options import OptionParser
    from dials.util.options import flatten_experiments
    from dials.util.options import flatten_reflections
    import libtbx.load_env

    usage = "%s [options] datablock.json" % (libtbx.env.dispatcher_name)

    parser = OptionParser(usage=usage,
                          phil=phil_scope,
                          read_experiments=True,
                          read_reflections=True,
                          check_format=True,
                          epilog=help_message)

    params, options = parser.parse_args(show_diff_phil=True)
    experiments = flatten_experiments(params.input.experiments)
    reflections = flatten_reflections(params.input.reflections)

    if len(experiments) == 0 or len(reflections) == 0:
        parser.print_help()
        exit(0)

    from dials.algorithms.shadowing.filter import filter_shadowed_reflections

    imagesets = experiments.imagesets()
    reflections = reflections[0]
    shadowed = filter_shadowed_reflections(experiments, reflections)

    print "# shadowed reflections: %i/%i (%.2f%%)" % (shadowed.count(
        True), shadowed.size(), shadowed.count(True) / shadowed.size() * 100)

    expt = experiments[0]
    x, y, z = reflections['xyzcal.px'].parts()
    z_ = z * expt.scan.get_oscillation()[1]
    zmin, zmax = expt.scan.get_oscillation_range()

    hist_scan_angle = flex.histogram(z_.select(shadowed),
                                     n_slots=int(zmax - zmin))
    #hist_scan_angle.show()

    uc = experiments[0].crystal.get_unit_cell()
    d_spacings = uc.d(reflections['miller_index'])
    ds2 = uc.d_star_sq(reflections['miller_index'])

    hist_res = flex.histogram(
        ds2.select(shadowed),
        flex.min(ds2),
        flex.max(ds2),
        n_slots=20,
    )
    #hist_res.show()

    import matplotlib
    matplotlib.use('Agg')
    from matplotlib import pyplot as plt

    plt.hist2d(z_.select(shadowed).as_numpy_array(),
               ds2.select(shadowed).as_numpy_array(),
               bins=(40, 40),
               range=((flex.min(z_), flex.max(z_)), (flex.min(ds2),
                                                     flex.max(ds2))))
    yticks_dsq = flex.double(plt.yticks()[0])
    from cctbx import uctbx
    yticks_d = uctbx.d_star_sq_as_d(yticks_dsq)
    plt.axes().set_yticklabels(['%.2f' % y for y in yticks_d])
    plt.xlabel('Scan angle (degrees)')
    plt.ylabel('Resolution (A^-1)')
    cbar = plt.colorbar()
    cbar.set_label('# shadowed reflections')
    plt.savefig('n_shadowed_hist2d.png')
    plt.clf()

    plt.scatter(hist_scan_angle.slot_centers().as_numpy_array(),
                hist_scan_angle.slots().as_numpy_array())
    plt.xlabel('Scan angle (degrees)')
    plt.ylabel('# shadowed reflections')
    plt.savefig("n_shadowed_vs_scan_angle.png")
    plt.clf()

    plt.scatter(hist_res.slot_centers().as_numpy_array(),
                hist_res.slots().as_numpy_array())
    plt.xlabel('d_star_sq')
    plt.savefig("n_shadowed_vs_resolution.png")
    plt.clf()
Esempio n. 9
0
def run(args):

    usage = "%s [options] models.expt" % (libtbx.env.dispatcher_name)

    parser = OptionParser(
        usage=usage,
        phil=phil_scope,
        read_experiments=True,
        read_reflections=True,
        check_format=True,
        epilog=help_message,
    )

    params, options = parser.parse_args(show_diff_phil=True)
    experiments = flatten_experiments(params.input.experiments)
    reflections = flatten_reflections(params.input.reflections)

    if len(experiments) == 0 or len(reflections) == 0:
        parser.print_help()
        exit(0)

    reflections = reflections[0]
    shadowed = filter_shadowed_reflections(experiments, reflections)

    print("# shadowed reflections: %i/%i (%.2f%%)" % (
        shadowed.count(True),
        shadowed.size(),
        shadowed.count(True) / shadowed.size() * 100,
    ))

    expt = experiments[0]
    z = reflections["xyzcal.px"].parts()[-1]
    z_ = z * expt.scan.get_oscillation()[1]
    zmin, zmax = expt.scan.get_oscillation_range()

    hist_scan_angle = flex.histogram(z_.select(shadowed),
                                     n_slots=int(zmax - zmin))
    # hist_scan_angle.show()

    uc = experiments[0].crystal.get_unit_cell()
    ds2 = uc.d_star_sq(reflections["miller_index"])

    hist_res = flex.histogram(ds2.select(shadowed),
                              flex.min(ds2),
                              flex.max(ds2),
                              n_slots=20)
    # hist_res.show()

    import matplotlib

    matplotlib.use("Agg")
    from matplotlib import pyplot as plt

    plt.hist2d(
        z_.select(shadowed).as_numpy_array(),
        ds2.select(shadowed).as_numpy_array(),
        bins=(40, 40),
        range=((flex.min(z_), flex.max(z_)), (flex.min(ds2), flex.max(ds2))),
    )
    yticks_dsq = flex.double(plt.yticks()[0])

    yticks_d = uctbx.d_star_sq_as_d(yticks_dsq)
    plt.axes().set_yticklabels(["%.2f" % y for y in yticks_d])
    plt.xlabel("Scan angle (degrees)")
    plt.ylabel("Resolution (A^-1)")
    cbar = plt.colorbar()
    cbar.set_label("# shadowed reflections")
    plt.savefig("n_shadowed_hist2d.png")
    plt.clf()

    plt.scatter(
        hist_scan_angle.slot_centers().as_numpy_array(),
        hist_scan_angle.slots().as_numpy_array(),
    )
    plt.xlabel("Scan angle (degrees)")
    plt.ylabel("# shadowed reflections")
    plt.savefig("n_shadowed_vs_scan_angle.png")
    plt.clf()

    plt.scatter(hist_res.slot_centers().as_numpy_array(),
                hist_res.slots().as_numpy_array())
    plt.xlabel("d_star_sq")
    plt.savefig("n_shadowed_vs_resolution.png")
    plt.clf()