Ejemplo n.º 1
0
    def _report(self, experiments, reflections):
        # type: (ExperimentList, flex.reflection_table) -> None
        """
        Run `dials.report` on an experiment list and reflection table.

        Args:
            experiments:  An experiment list.
            reflections:  The corresponding reflection table.
        """
        info("\nCreating report...")
        command = ["dials.report", experiments, reflections]
        result = procrunner.run(command,
                                print_stdout=False,
                                debug=procrunner_debug)
        debug("result = %s", screen19.prettyprint_dictionary(result))
        if result["exitcode"] == 0:
            info("Successfully completed (%.1f sec)", result["runtime"])
        #     if sys.stdout.isatty():
        #       info("Trying to start browser")
        #       try:
        #         import subprocess
        #         d = dict(os.environ)
        #         d["LD_LIBRARY_PATH"] = ""
        #         subprocess.Popen(["xdg-open", "dials-report.html"], env=d)
        #       except Exception as e:
        #         debug("Could not open browser\n%s", str(e))
        else:
            warning("Failed with exit code %d", result["exitcode"])
            sys.exit(1)
Ejemplo n.º 2
0
        def _refine_bravais(self, experiments, reflections):
            # type: (ExperimentList, flex.reflection_table) -> None
            """
            Run `dials.refine_bravais_settings` on an experiments and reflections.

            Args:
                experiments:  An experiment list..
                reflections:  The corresponding reflection table.
            """
            info("\nRefining Bravais settings...")
            command = [
                "dials.refine_bravais_settings", experiments, reflections
            ]
            result = procrunner.run(command,
                                    print_stdout=False,
                                    debug=procrunner_debug)
            debug("result = %s", screen19.prettyprint_dictionary(result))
            if result["exitcode"] == 0:
                m = re.search(
                    r"[-+]{3,}\n[^\n]*\n[-+|]{3,}\n(.*\n)*[-+]{3,}",
                    result["stdout"].decode("utf-8"),
                )
                if m:
                    info(m.group(0))
                else:
                    info(
                        "Could not interpret dials.refine_bravais_settings output, "
                        "please check dials.refine_bravais_settings.log")
                info("Successfully completed (%.1f sec)", result["runtime"])
            else:
                warning("Failed with exit code %d", result["exitcode"])
                sys.exit(1)
Ejemplo n.º 3
0
    def _create_profile_model(self):  # type: () -> bool
        """
        Run `dials.create_profile_model` on indexed reflections.

        The indexed experiment list will be overwritten with a copy that includes
        the profile model but is otherwise identical.

        Returns:
            Boolean value indicating whether it was possible to determine a profile
            model from the data.
        """
        info("\nCreating profile model...")
        command = [
            "dials.create_profile_model",
            self.params.dials_index.output.experiments,
            self.params.dials_index.output.reflections,
            "output = %s" % self.params.dials_index.output.experiments,
        ]
        result = procrunner.run(command,
                                print_stdout=False,
                                debug=procrunner_debug)
        debug("result = %s", screen19.prettyprint_dictionary(result))
        self._sigma_m = None
        if result["exitcode"] == 0:
            db = ExperimentList.from_file(
                self.params.dials_index.output.experiments)[0]
            self._oscillation = db.imageset.get_scan().get_oscillation()[1]
            self._sigma_m = db.profile.sigma_m()
            info(
                u"%d images, %s° oscillation, σ_m=%.3f°",
                db.imageset.get_scan().get_num_images(),
                str(self._oscillation),
                self._sigma_m,
            )
            info("Successfully completed (%.1f sec)", result["runtime"])
            return True
        warning("Failed with exit code %d", result["exitcode"])
        return False
Ejemplo n.º 4
0
    def _check_intensities(self,
                           mosaicity_correction=True):  # type: (bool) -> None
        """
        Run xia2.overload and plot a histogram of pixel intensities.

        If `mosaicity_correction` is true, the pixel intensities are approximately
        adjusted to take account of a systematic defect in the detector count rate
        correction.  See https://github.com/xia2/screen19/wiki#mosaicity-correction

        Args:
            mosaicity_correction (optional):  default is `True`.
        """
        info("\nTesting pixel intensities...")
        command = ["xia2.overload", "nproc=%s" % self.nproc, "indexed.expt"]
        debug("running %s", command)
        result = procrunner.run(command,
                                print_stdout=False,
                                debug=procrunner_debug)
        debug("result = %s", screen19.prettyprint_dictionary(result))
        info("Successfully completed (%.1f sec)", result["runtime"])

        if result["exitcode"] != 0:
            warning("Failed with exit code %d", result["exitcode"])
            sys.exit(1)

        with open("overload.json") as fh:
            overload_data = json.load(fh)

        info("Pixel intensity distribution:")
        count_sum = 0
        hist = {}
        if "bins" in overload_data:
            for b in range(overload_data["bin_count"]):
                if overload_data["bins"][b] > 0:
                    hist[b] = overload_data["bins"][b]
                    count_sum += b * overload_data["bins"][b]
        else:
            hist = {
                int(k): v
                for k, v in overload_data["counts"].items() if int(k) > 0
            }
            count_sum = sum([k * v for k, v in hist.items()])

        average_to_peak = 1
        if mosaicity_correction:
            # Adjust for the detector count rate correction
            if self._sigma_m:
                delta_z = self._oscillation / self._sigma_m / math.sqrt(2)
                average_to_peak = (
                    math.sqrt(math.pi) * delta_z * math.erf(delta_z) +
                    math.exp(-(delta_z**2)) - 1) / delta_z**2
                info("Average-to-peak intensity ratio: %f", average_to_peak)

        scale = 100 * overload_data["scale_factor"] / average_to_peak
        info("Determined scale factor for intensities as %f", scale)

        debug(
            "intensity histogram: { %s }",
            ", ".join(["%d:%d" % (k, hist[k]) for k in sorted(hist)]),
        )
        max_count = max(hist.keys())
        hist_max = max_count * scale
        hist_granularity, hist_format = 1, "%.0f"
        if hist_max < 50:
            hist_granularity, hist_format = 2, "%.1f"
        if hist_max < 15:
            hist_granularity, hist_format = 10, "%.1f"
        rescaled_hist = {}
        for x in hist.keys():
            rescaled = round(x * scale * hist_granularity)
            if rescaled > 0:
                rescaled_hist[rescaled] = hist[x] + rescaled_hist.get(
                    rescaled, 0)
        hist = rescaled_hist
        debug(
            "rescaled histogram: { %s }",
            ", ".join([(hist_format + ":%d") % (k / hist_granularity, hist[k])
                       for k in sorted(hist)]),
        )

        screen19.plot_intensities(hist,
                                  1 / hist_granularity,
                                  procrunner_debug=procrunner_debug)

        linear_response_limit = 100 * self.params.maximum_flux.trusted_range_correction
        marginal_limit = max(70, linear_response_limit)

        text = "".join((
            "Strongest pixel (%d counts) " % max_count,
            "reaches %.1f%% " % hist_max,
            "of the detector count rate limit",
        ))
        if hist_max > 100:
            warning("Warning: %s!", text)
        else:
            info(text)
        if ("overload_limit" in overload_data
                and max_count >= overload_data["overload_limit"]):
            warning(
                "Warning: THE DATA CONTAIN REGULAR OVERLOADS!\n"
                "         The photon incidence rate is outside the specified "
                "limits of the detector.\n"
                "         The built-in detector count rate correction cannot "
                "adjust for this.\n"
                "         You should aim for count rates below {:.0%} of the "
                "detector limit.".format(
                    self.params.maximum_flux.trusted_range_correction))
        elif hist_max > marginal_limit:
            warning(
                "Warning: The photon incidence rate is well outside the "
                "linear response region of the detector (<{:.0%}).\n"
                "    The built-in detector count rate correction may not be "
                "able to adjust for this.".format(
                    self.params.maximum_flux.trusted_range_correction))
        elif hist_max > linear_response_limit:
            info("The photon incidence rate is outside the linear response "
                 "region of the detector (<{:.0%}).\n"
                 "    The built-in detector count rate correction may be able "
                 "to adjust for this.".format(
                     self.params.maximum_flux.trusted_range_correction))
        if not mosaicity_correction:
            warning(
                "Warning: Not enough data for proper profile estimation."
                "    The spot intensities are not corrected for mosaicity.\n"
                "    The true photon incidence rate will be higher than the "
                "given estimate.")

        info("Total sum of counts in dataset: %d", count_sum)