Ejemplo n.º 1
0
def work_all(host,
             port,
             filenames,
             params,
             plot=False,
             table=False,
             json_file=None,
             grid=None,
             nproc=None):
    import json
    from multiprocessing.pool import ThreadPool as thread_pool
    if nproc is None:
        nproc = _nproc()
    pool = thread_pool(processes=nproc)
    threads = {}
    for filename in filenames:
        threads[filename] = pool.apply_async(work,
                                             (host, port, filename, params))
    results = []
    for filename in filenames:
        response = threads[filename].get()
        d = json.loads(response)
        results.append(d)
        print response_to_xml(d)

    if json_file is not None:
        'Writing results to %s' % json_file
        with open(json_file, 'wb') as f:
            json.dump(results, f)

    if plot or table:

        from scitbx.array_family import flex
        from libtbx import group_args
        from dials.algorithms.spot_finding.per_image_analysis \
             import plot_stats, print_table

        estimated_d_min = flex.double()
        d_min_distl_method_1 = flex.double()
        d_min_distl_method_2 = flex.double()
        n_spots_total = flex.int()
        n_spots_no_ice = flex.int()
        total_intensity = flex.double()

        for d in results:
            estimated_d_min.append(d['estimated_d_min'])
            d_min_distl_method_1.append(d['d_min_distl_method_1'])
            d_min_distl_method_2.append(d['d_min_distl_method_2'])
            n_spots_total.append(d['n_spots_total'])
            n_spots_no_ice.append(d['n_spots_no_ice'])
            total_intensity.append(d['total_intensity'])

        stats = group_args(n_spots_total=n_spots_total,
                           n_spots_no_ice=n_spots_no_ice,
                           n_spots_4A=None,
                           total_intensity=total_intensity,
                           estimated_d_min=estimated_d_min,
                           d_min_distl_method_1=d_min_distl_method_1,
                           d_min_distl_method_2=d_min_distl_method_2,
                           noisiness_method_1=None,
                           noisiness_method_2=None)

        if plot:
            plot_stats(stats)
        if table:
            print_table(stats)

        if grid is not None:
            from matplotlib import pyplot
            n_spots_no_ice.reshape(flex.grid(grid))
            print n_spots_no_ice.size()
            from matplotlib import pyplot
            fig = pyplot.figure()
            pyplot.pcolormesh(n_spots_no_ice.as_numpy_array(),
                              cmap=pyplot.cm.Reds)
            pyplot.savefig("spot_count.png")

    return
Ejemplo n.º 2
0
def run(args):
    from dials.util.options import OptionParser
    import libtbx.load_env

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

    parser = OptionParser(usage=usage, phil=phil_scope, epilog=help_message)

    params, options, args = parser.parse_args(
        show_diff_phil=True, return_unhandled=True
    )

    positions = None
    if params.positions is not None:
        with open(params.positions, "rb") as f:
            positions = flex.vec2_double()
            for line in f.readlines():
                line = (
                    line.replace("(", " ")
                    .replace(")", "")
                    .replace(",", " ")
                    .strip()
                    .split()
                )
                assert len(line) == 3
                i, x, y = [float(l) for l in line]
                positions.append((x, y))

    assert len(args) == 1
    json_file = args[0]
    import json

    with open(json_file, "rb") as f:
        results = json.load(f)

    n_indexed = flex.double()
    fraction_indexed = flex.double()
    n_spots = flex.double()
    n_lattices = flex.double()
    crystals = []
    image_names = flex.std_string()

    for r in results:
        n_spots.append(r["n_spots_total"])
        image_names.append(str(r["image"]))
        if "n_indexed" in r:
            n_indexed.append(r["n_indexed"])
            n_lattices.append(len(r["lattices"]))
            for d in r["lattices"]:
                from dxtbx.model.crystal import CrystalFactory

                crystals.append(CrystalFactory.from_dict(d["crystal"]))
        else:
            n_indexed.append(0)
            n_lattices.append(0)

    if n_indexed.size():
        sel = n_spots > 0
        fraction_indexed = flex.double(n_indexed.size(), 0)
        fraction_indexed.set_selected(sel, n_indexed.select(sel) / n_spots.select(sel))

    import matplotlib

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

    red = "#e74c3c"

    plot = True
    table = True
    grid = params.grid

    from libtbx import group_args
    from dials.algorithms.spot_finding.per_image_analysis import plot_stats, print_table

    estimated_d_min = flex.double()
    d_min_distl_method_1 = flex.double()
    d_min_distl_method_2 = flex.double()
    n_spots_total = flex.int()
    n_spots_no_ice = flex.int()
    total_intensity = flex.double()

    for d in results:
        estimated_d_min.append(d["estimated_d_min"])
        d_min_distl_method_1.append(d["d_min_distl_method_1"])
        d_min_distl_method_2.append(d["d_min_distl_method_2"])
        n_spots_total.append(d["n_spots_total"])
        n_spots_no_ice.append(d["n_spots_no_ice"])
        total_intensity.append(d["total_intensity"])

    stats = group_args(
        image=image_names,
        n_spots_total=n_spots_total,
        n_spots_no_ice=n_spots_no_ice,
        n_spots_4A=None,
        n_indexed=n_indexed,
        fraction_indexed=fraction_indexed,
        total_intensity=total_intensity,
        estimated_d_min=estimated_d_min,
        d_min_distl_method_1=d_min_distl_method_1,
        d_min_distl_method_2=d_min_distl_method_2,
        noisiness_method_1=None,
        noisiness_method_2=None,
    )

    if plot:
        plot_stats(stats)
        pyplot.clf()
    if table:
        print_table(stats)

    n_rows = 10
    n_rows = min(n_rows, len(n_spots_total))
    perm_n_spots_total = flex.sort_permutation(n_spots_total, reverse=True)
    print("Top %i images sorted by number of spots:" % n_rows)
    print_table(stats, perm=perm_n_spots_total, n_rows=n_rows)
    if flex.max(n_indexed) > 0:
        perm_n_indexed = flex.sort_permutation(n_indexed, reverse=True)
        print("Top %i images sorted by number of indexed reflections:" % n_rows)
        print_table(stats, perm=perm_n_indexed, n_rows=n_rows)

    print("Number of indexed lattices: ", (n_indexed > 0).count(True))

    print(
        "Number with valid d_min but failed indexing: ",
        (
            (d_min_distl_method_1 > 0)
            & (d_min_distl_method_2 > 0)
            & (estimated_d_min > 0)
            & (n_indexed == 0)
        ).count(True),
    )

    n_bins = 20
    spot_count_histogram(
        n_spots_total, n_bins=n_bins, filename="hist_n_spots_total.png", log=True
    )
    spot_count_histogram(
        n_spots_no_ice, n_bins=n_bins, filename="hist_n_spots_no_ice.png", log=True
    )
    spot_count_histogram(
        n_indexed.select(n_indexed > 0),
        n_bins=n_bins,
        filename="hist_n_indexed.png",
        log=False,
    )

    if len(crystals):
        plot_unit_cell_histograms(crystals)

    if params.stereographic_projections and len(crystals):
        from dxtbx.model.experiment_list import ExperimentListFactory

        experiments = ExperimentListFactory.from_filenames(
            [image_names[0]], verbose=False
        )
        assert len(experiments) == 1
        imageset = experiments.imagesets()[0]
        s0 = imageset.get_beam().get_s0()
        # XXX what if no goniometer?
        rotation_axis = imageset.get_goniometer().get_rotation_axis()

        indices = ((1, 0, 0), (0, 1, 0), (0, 0, 1))
        for i, index in enumerate(indices):

            from cctbx import crystal, miller
            from scitbx import matrix

            miller_indices = flex.miller_index([index])
            symmetry = crystal.symmetry(
                unit_cell=crystals[0].get_unit_cell(),
                space_group=crystals[0].get_space_group(),
            )
            miller_set = miller.set(symmetry, miller_indices)
            d_spacings = miller_set.d_spacings()
            d_spacings = d_spacings.as_non_anomalous_array().expand_to_p1()
            d_spacings = d_spacings.generate_bijvoet_mates()
            miller_indices = d_spacings.indices()

            # plane normal
            d0 = matrix.col(s0).normalize()
            d1 = d0.cross(matrix.col(rotation_axis)).normalize()
            d2 = d1.cross(d0).normalize()
            reference_poles = (d0, d1, d2)

            from dials.command_line.stereographic_projection import (
                stereographic_projection,
            )

            projections = []

            for cryst in crystals:
                reciprocal_space_points = (
                    list(cryst.get_U() * cryst.get_B())
                    * miller_indices.as_vec3_double()
                )
                projections.append(
                    stereographic_projection(reciprocal_space_points, reference_poles)
                )

                # from dials.algorithms.indexing.compare_orientation_matrices import \
                #  difference_rotation_matrix_and_euler_angles
                # R_ij, euler_angles, cb_op = difference_rotation_matrix_and_euler_angles(
                #  crystals[0], cryst)
                # print max(euler_angles)

            from dials.command_line.stereographic_projection import plot_projections

            plot_projections(projections, filename="projections_%s.png" % ("hkl"[i]))
            pyplot.clf()

    def plot_grid(
        values,
        grid,
        file_name,
        cmap=pyplot.cm.Reds,
        vmin=None,
        vmax=None,
        invalid="white",
    ):
        values = values.as_double()
        # At DLS, fast direction appears to be largest direction
        if grid[0] > grid[1]:
            values.reshape(flex.grid(reversed(grid)))
            values = values.matrix_transpose()
        else:
            values.reshape(flex.grid(grid))

        f, ax1 = pyplot.subplots(1)

        mesh1 = ax1.pcolormesh(values.as_numpy_array(), cmap=cmap, vmin=vmin, vmax=vmax)
        mesh1.cmap.set_under(color=invalid, alpha=None)
        mesh1.cmap.set_over(color=invalid, alpha=None)
        ax1.set_aspect("equal")
        ax1.invert_yaxis()
        pyplot.colorbar(mesh1, ax=ax1)
        pyplot.savefig(file_name, dpi=600)
        pyplot.clf()

    def plot_positions(
        values,
        positions,
        file_name,
        cmap=pyplot.cm.Reds,
        vmin=None,
        vmax=None,
        invalid="white",
    ):
        values = values.as_double()
        assert positions.size() >= values.size()
        positions = positions[: values.size()]

        if vmin is None:
            vmin = flex.min(values)
        if vmax is None:
            vmax = flex.max(values)

        x, y = positions.parts()
        dx = flex.abs(x[1:] - x[:-1])
        dy = flex.abs(y[1:] - y[:-1])
        dx = dx.select(dx > 0)
        dy = dy.select(dy > 0)

        scale = 1 / flex.min(dx)
        # print scale
        x = (x * scale).iround()
        y = (y * scale).iround()

        from libtbx.math_utils import iceil

        z = flex.double(flex.grid(iceil(flex.max(y)) + 1, iceil(flex.max(x)) + 1), -2)
        # print z.all()
        for x_, y_, z_ in zip(x, y, values):
            z[y_, x_] = z_

        plot_grid(
            z.as_1d(),
            z.all(),
            file_name,
            cmap=cmap,
            vmin=vmin,
            vmax=vmax,
            invalid=invalid,
        )
        return

    if grid is not None or positions is not None:
        if grid is not None:
            positions = tuple(reversed(grid))
            plotter = plot_grid
        else:
            plotter = plot_positions

        cmap = pyplot.get_cmap(params.cmap)
        plotter(
            n_spots_total,
            positions,
            "grid_spot_count_total.png",
            cmap=cmap,
            invalid=params.invalid,
        )
        plotter(
            n_spots_no_ice,
            positions,
            "grid_spot_count_no_ice.png",
            cmap=cmap,
            invalid=params.invalid,
        )
        plotter(
            total_intensity,
            positions,
            "grid_total_intensity.png",
            cmap=cmap,
            invalid=params.invalid,
        )
        if flex.max(n_indexed) > 0:
            plotter(
                n_indexed,
                positions,
                "grid_n_indexed.png",
                cmap=cmap,
                invalid=params.invalid,
            )
            plotter(
                fraction_indexed,
                positions,
                "grid_fraction_indexed.png",
                cmap=cmap,
                vmin=0,
                vmax=1,
                invalid=params.invalid,
            )

        for i, d_min in enumerate(
            (estimated_d_min, d_min_distl_method_1, d_min_distl_method_2)
        ):
            vmin = flex.min(d_min.select(d_min > 0))
            vmax = flex.max(d_min)
            cmap = pyplot.get_cmap("%s_r" % params.cmap)
            d_min.set_selected(d_min <= 0, vmax)

            if i == 0:
                plotter(
                    d_min,
                    positions,
                    "grid_d_min.png",
                    cmap=cmap,
                    vmin=vmin,
                    vmax=vmax,
                    invalid=params.invalid,
                )
            else:
                plotter(
                    d_min,
                    positions,
                    "grid_d_min_method_%i.png" % i,
                    cmap=cmap,
                    vmin=vmin,
                    vmax=vmax,
                    invalid=params.invalid,
                )

    if flex.max(n_indexed) > 0:
        pyplot.hexbin(n_spots, n_indexed, bins="log", cmap=pyplot.cm.jet, gridsize=50)
        pyplot.colorbar()
        xlim = pyplot.xlim()
        ylim = pyplot.ylim()
        pyplot.plot([0, max(n_spots)], [0, max(n_spots)], c=red)
        pyplot.xlim(0, xlim[1])
        pyplot.ylim(0, ylim[1])
        pyplot.xlabel("# spots")
        pyplot.ylabel("# indexed")
        pyplot.savefig("n_spots_vs_n_indexed.png")
        pyplot.clf()

        pyplot.hexbin(
            n_spots, fraction_indexed, bins="log", cmap=pyplot.cm.jet, gridsize=50
        )
        pyplot.colorbar()
        pyplot.xlim(0, pyplot.xlim()[1])
        pyplot.ylim(0, pyplot.ylim()[1])
        pyplot.xlabel("# spots")
        pyplot.ylabel("Fraction indexed")
        pyplot.savefig("n_spots_vs_fraction_indexed.png")
        pyplot.clf()

        pyplot.hexbin(
            n_indexed, fraction_indexed, bins="log", cmap=pyplot.cm.jet, gridsize=50
        )
        pyplot.colorbar()
        pyplot.xlim(0, pyplot.xlim()[1])
        pyplot.ylim(0, pyplot.ylim()[1])
        pyplot.xlabel("# indexed")
        pyplot.ylabel("Fraction indexed")
        pyplot.savefig("n_indexed_vs_fraction_indexed.png")
        pyplot.clf()

        pyplot.hexbin(n_spots, n_lattices, bins="log", cmap=pyplot.cm.jet, gridsize=50)
        pyplot.colorbar()
        pyplot.xlim(0, pyplot.xlim()[1])
        pyplot.ylim(0, pyplot.ylim()[1])
        pyplot.xlabel("# spots")
        pyplot.ylabel("# lattices")
        pyplot.savefig("n_spots_vs_n_lattices.png")
        pyplot.clf()

    pyplot.hexbin(
        estimated_d_min,
        d_min_distl_method_1,
        bins="log",
        cmap=pyplot.cm.jet,
        gridsize=50,
    )
    pyplot.colorbar()
    # pyplot.gca().set_aspect('equal')
    xlim = pyplot.xlim()
    ylim = pyplot.ylim()
    m = max(max(estimated_d_min), max(d_min_distl_method_1))
    pyplot.plot([0, m], [0, m], c=red)
    pyplot.xlim(0, xlim[1])
    pyplot.ylim(0, ylim[1])
    pyplot.xlabel("estimated_d_min")
    pyplot.ylabel("d_min_distl_method_1")
    pyplot.savefig("d_min_vs_distl_method_1.png")
    pyplot.clf()

    pyplot.hexbin(
        estimated_d_min,
        d_min_distl_method_2,
        bins="log",
        cmap=pyplot.cm.jet,
        gridsize=50,
    )
    pyplot.colorbar()
    # pyplot.gca().set_aspect('equal')
    xlim = pyplot.xlim()
    ylim = pyplot.ylim()
    m = max(max(estimated_d_min), max(d_min_distl_method_2))
    pyplot.plot([0, m], [0, m], c=red)
    pyplot.xlim(0, xlim[1])
    pyplot.ylim(0, ylim[1])
    pyplot.xlabel("estimated_d_min")
    pyplot.ylabel("d_min_distl_method_2")
    pyplot.savefig("d_min_vs_distl_method_2.png")
    pyplot.clf()

    pyplot.hexbin(
        d_min_distl_method_1,
        d_min_distl_method_2,
        bins="log",
        cmap=pyplot.cm.jet,
        gridsize=50,
    )
    pyplot.colorbar()
    # pyplot.gca().set_aspect('equal')
    xlim = pyplot.xlim()
    ylim = pyplot.ylim()
    m = max(max(d_min_distl_method_1), max(d_min_distl_method_2))
    pyplot.plot([0, m], [0, m], c=red)
    pyplot.xlim(0, xlim[1])
    pyplot.ylim(0, ylim[1])
    pyplot.xlabel("d_min_distl_method_1")
    pyplot.ylabel("d_min_distl_method_2")
    pyplot.savefig("distl_method_1_vs_distl_method_2.png")
    pyplot.clf()

    pyplot.hexbin(n_spots, estimated_d_min, bins="log", cmap=pyplot.cm.jet, gridsize=50)
    pyplot.colorbar()
    pyplot.xlim(0, pyplot.xlim()[1])
    pyplot.ylim(0, pyplot.ylim()[1])
    pyplot.xlabel("# spots")
    pyplot.ylabel("estimated_d_min")
    pyplot.savefig("n_spots_vs_d_min.png")
    pyplot.clf()

    pyplot.hexbin(
        n_spots, d_min_distl_method_1, bins="log", cmap=pyplot.cm.jet, gridsize=50
    )
    pyplot.colorbar()
    pyplot.xlim(0, pyplot.xlim()[1])
    pyplot.ylim(0, pyplot.ylim()[1])
    pyplot.xlabel("# spots")
    pyplot.ylabel("d_min_distl_method_1")
    pyplot.savefig("n_spots_vs_distl_method_1.png")
    pyplot.clf()

    pyplot.hexbin(
        n_spots, d_min_distl_method_2, bins="log", cmap=pyplot.cm.jet, gridsize=50
    )
    pyplot.colorbar()
    pyplot.xlim(0, pyplot.xlim()[1])
    pyplot.ylim(0, pyplot.ylim()[1])
    pyplot.xlabel("# spots")
    pyplot.ylabel("d_min_distl_method_2")
    pyplot.savefig("n_spots_vs_distl_method_2.png")
    pyplot.clf()
Ejemplo n.º 3
0
    def run(self, args=None):
        """Execute the script."""
        from dials.array_family import flex
        from dials.util.options import flatten_experiments
        from time import time
        from dials.util import log

        start_time = time()

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

        if __name__ == "__main__":
            # Configure the logging
            log.config(verbosity=options.verbose, logfile=params.output.log)

        from dials.util.version import dials_version

        logger.info(dials_version())

        # Log the diff phil
        diff_phil = self.parser.diff_phil.as_str()
        if diff_phil != "":
            logger.info("The following parameters have been modified:\n")
            logger.info(diff_phil)

        # Ensure we have a data block
        experiments = flatten_experiments(params.input.experiments)
        if len(experiments) == 0:
            self.parser.print_help()
            return

        # Loop through all the imagesets and find the strong spots
        reflections = flex.reflection_table.from_observations(
            experiments, params)

        # Add n_signal column - before deleting shoeboxes
        from dials.algorithms.shoebox import MaskCode

        good = MaskCode.Foreground | MaskCode.Valid
        reflections["n_signal"] = reflections["shoebox"].count_mask_values(
            good)

        # Delete the shoeboxes
        if not params.output.shoeboxes:
            del reflections["shoebox"]

        # ascii spot count per image plot
        from dials.util.ascii_art import spot_counts_per_image_plot

        for i, experiment in enumerate(experiments):
            ascii_plot = spot_counts_per_image_plot(
                reflections.select(reflections["id"] == i))
            if len(ascii_plot):
                logger.info(
                    "\nHistogram of per-image spot count for imageset %i:" % i)
                logger.info(ascii_plot)

        # Save the reflections to file
        logger.info("\n" + "-" * 80)
        reflections.as_file(params.output.reflections)
        logger.info("Saved {} reflections to {}".format(
            len(reflections), params.output.reflections))

        # Save the experiments
        if params.output.experiments:
            logger.info("Saving experiments to {}".format(
                params.output.experiments))
            experiments.as_file(params.output.experiments)

        # Print some per image statistics
        if params.per_image_statistics:
            from dials.algorithms.spot_finding import per_image_analysis
            from six.moves import cStringIO as StringIO

            s = StringIO()
            for i, experiment in enumerate(experiments):
                print("Number of centroids per image for imageset %i:" % i,
                      file=s)
                imageset = experiment.imageset
                stats = per_image_analysis.stats_imageset(
                    imageset,
                    reflections.select(reflections["id"] == i),
                    resolution_analysis=False,
                )
                per_image_analysis.print_table(stats, out=s)
            logger.info(s.getvalue())

        # Print the time
        logger.info("Time Taken: %f" % (time() - start_time))

        if params.output.experiments:
            return experiments, reflections
        else:
            return reflections
Ejemplo n.º 4
0
    def run(self):
        '''Execute the script.'''
        from dials.array_family import flex
        from dials.util.options import flatten_datablocks
        from time import time
        from dials.util import log
        from libtbx.utils import Sorry
        start_time = time()

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

        # Configure the logging
        log.config(params.verbosity,
                   info=params.output.log,
                   debug=params.output.debug_log)

        from dials.util.version import dials_version
        logger.info(dials_version())

        # Log the diff phil
        diff_phil = self.parser.diff_phil.as_str()
        if diff_phil is not '':
            logger.info('The following parameters have been modified:\n')
            logger.info(diff_phil)

        # Ensure we have a data block
        datablocks = flatten_datablocks(params.input.datablock)
        if len(datablocks) == 0:
            self.parser.print_help()
            return
        elif len(datablocks) != 1:
            raise Sorry('only 1 datablock can be processed at a time')

        # Loop through all the imagesets and find the strong spots
        reflections = flex.reflection_table.from_observations(
            datablocks[0], params)

        # Delete the shoeboxes
        if not params.output.shoeboxes:
            del reflections['shoebox']

        # ascii spot count per image plot
        from dials.util.ascii_art import spot_counts_per_image_plot

        for i, imageset in enumerate(datablocks[0].extract_imagesets()):
            ascii_plot = spot_counts_per_image_plot(
                reflections.select(reflections['id'] == i))
            if len(ascii_plot):
                logger.info(
                    '\nHistogram of per-image spot count for imageset %i:' % i)
                logger.info(ascii_plot)

        # Save the reflections to file
        logger.info('\n' + '-' * 80)
        reflections.as_pickle(params.output.reflections)
        logger.info('Saved {0} reflections to {1}'.format(
            len(reflections), params.output.reflections))

        # Save the datablock
        if params.output.datablock:
            from dxtbx.datablock import DataBlockDumper
            logger.info('Saving datablocks to {0}'.format(
                params.output.datablock))
            dump = DataBlockDumper(datablocks)
            dump.as_file(params.output.datablock)

        # Print some per image statistics
        if params.per_image_statistics:
            from dials.algorithms.spot_finding import per_image_analysis
            from cStringIO import StringIO
            s = StringIO()
            for i, imageset in enumerate(datablocks[0].extract_imagesets()):
                print >> s, "Number of centroids per image for imageset %i:" % i
                stats = per_image_analysis.stats_imageset(
                    imageset,
                    reflections.select(reflections['id'] == i),
                    resolution_analysis=False)
                per_image_analysis.print_table(stats, out=s)
            logger.info(s.getvalue())

        # Print the time
        logger.info("Time Taken: %f" % (time() - start_time))
def run(args):
    usage = "dials.spot_counts_per_image [options] imported.expt strong.refl"

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

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

    if not any([reflections, experiments]):
        parser.print_help()
        return

    # FIXME may want to change this to allow many to be passed i.e.
    # from parallel runs
    if len(reflections) != 1:
        sys.exit("Only one reflection list may be passed")
    reflections = reflections[0]
    expts = set(reflections["id"])
    if max(expts) >= len(experiments.imagesets()):
        sys.exit("Unknown experiments in reflection list")

    if params.id is not None:
        reflections = reflections.select(reflections["id"] == params.id)

    all_stats = []
    for j, imageset in enumerate(experiments.imagesets()):
        refl = reflections.select(reflections["id"] == j)
        stats = per_image_analysis.stats_imageset(
            imageset,
            refl,
            resolution_analysis=params.resolution_analysis,
            plot=params.individual_plots,
        )
        all_stats.append(stats)

    # transpose stats
    class empty(object):
        pass

    e = empty()
    for s in all_stats:
        for k in dir(s):
            if k.startswith("_") or k in ["merge", "next"]:
                continue
            if not hasattr(e, k):
                setattr(e, k, [])
            getattr(e, k).extend(getattr(s, k))

    per_image_analysis.print_table(e)
    from libtbx import table_utils

    # FIXME this is now probably nonsense...
    overall_stats = per_image_analysis.stats_single_image(
        imageset, reflections, resolution_analysis=params.resolution_analysis
    )
    rows = [
        ("Overall statistics", ""),
        ("#spots", "%i" % overall_stats.n_spots_total),
        ("#spots_no_ice", "%i" % overall_stats.n_spots_no_ice),
        ("d_min", "%.2f" % overall_stats.estimated_d_min),
        (
            "d_min (distl method 1)",
            "%.2f (%.2f)"
            % (overall_stats.d_min_distl_method_1, overall_stats.noisiness_method_1),
        ),
        (
            "d_min (distl method 2)",
            "%.2f (%.2f)"
            % (overall_stats.d_min_distl_method_1, overall_stats.noisiness_method_1),
        ),
    ]
    print(table_utils.format(rows, has_header=True, prefix="| ", postfix=" |"))

    if params.json:
        import json

        if params.split_json:
            for k in stats.__dict__:
                start, end = params.json.split(".")
                with open("%s_%s.%s" % (start, k, end), "wb") as fp:
                    json.dump(stats.__dict__[k], fp)
        if params.joint_json:
            with open(params.json, "wb") as fp:
                json.dump(stats.__dict__, fp)
    if params.plot:
        import matplotlib

        matplotlib.use("Agg")
        per_image_analysis.plot_stats(stats, filename=params.plot)
Ejemplo n.º 6
0
def work_all(host, port, filenames, params, plot=False, table=False,
             json_file=None, grid=None, nproc=None):
  import json
  from multiprocessing.pool import ThreadPool as thread_pool
  if nproc is None:
    nproc=_nproc()
  pool = thread_pool(processes=nproc)
  threads = { }
  for filename in filenames:
    threads[filename] = pool.apply_async(work, (host, port, filename, params))
  results = []
  for filename in filenames:
    response = threads[filename].get()
    d = json.loads(response)
    results.append(d)
    print response_to_xml(d)

  if json_file is not None:
    'Writing results to %s' %json_file
    with open(json_file, 'wb') as f:
      json.dump(results, f)

  if plot or table:

    from scitbx.array_family import flex
    from libtbx import group_args
    from dials.algorithms.spot_finding.per_image_analysis \
         import plot_stats, print_table

    estimated_d_min = flex.double()
    d_min_distl_method_1 = flex.double()
    d_min_distl_method_2 = flex.double()
    n_spots_total = flex.int()
    n_spots_no_ice = flex.int()
    total_intensity = flex.double()

    for d in results:
      estimated_d_min.append(d['estimated_d_min'])
      d_min_distl_method_1.append(d['d_min_distl_method_1'])
      d_min_distl_method_2.append(d['d_min_distl_method_2'])
      n_spots_total.append(d['n_spots_total'])
      n_spots_no_ice.append(d['n_spots_no_ice'])
      total_intensity.append(d['total_intensity'])

    stats = group_args(n_spots_total=n_spots_total,
                       n_spots_no_ice=n_spots_no_ice,
                       n_spots_4A=None,
                       total_intensity=total_intensity,
                       estimated_d_min=estimated_d_min,
                       d_min_distl_method_1=d_min_distl_method_1,
                       d_min_distl_method_2=d_min_distl_method_2,
                       noisiness_method_1=None,
                       noisiness_method_2=None)

    if plot:
      plot_stats(stats)
    if table:
      print_table(stats)

    if grid is not None:
      from matplotlib import pyplot
      n_spots_no_ice.reshape(flex.grid(grid))
      print n_spots_no_ice.size()
      from matplotlib import pyplot
      fig = pyplot.figure()
      pyplot.pcolormesh(n_spots_no_ice.as_numpy_array(), cmap=pyplot.cm.Reds)
      pyplot.savefig("spot_count.png")

  return
Ejemplo n.º 7
0
  def run(self):
    '''Execute the script.'''
    from dials.array_family import flex
    from dials.util.options import flatten_datablocks
    from time import time
    from dials.util import log
    from libtbx.utils import Sorry
    start_time = time()

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

    # Configure the logging
    log.config(
      params.verbosity,
      info=params.output.log,
      debug=params.output.debug_log)

    from dials.util.version import dials_version
    logger.info(dials_version())

    # Log the diff phil
    diff_phil = self.parser.diff_phil.as_str()
    if diff_phil is not '':
      logger.info('The following parameters have been modified:\n')
      logger.info(diff_phil)

    # Ensure we have a data block
    datablocks = flatten_datablocks(params.input.datablock)
    if len(datablocks) == 0:
      self.parser.print_help()
      return
    elif len(datablocks) != 1:
      raise Sorry('only 1 datablock can be processed at a time')

    # Loop through all the imagesets and find the strong spots
    reflections = flex.reflection_table.from_observations(
      datablocks[0], params)

    # Delete the shoeboxes
    if not params.output.shoeboxes:
      del reflections['shoebox']

    # ascii spot count per image plot
    from dials.util.ascii_art import spot_counts_per_image_plot

    for i, imageset in enumerate(datablocks[0].extract_imagesets()):
      ascii_plot = spot_counts_per_image_plot(
        reflections.select(reflections['id'] == i))
      if len(ascii_plot):
        logger.info('\nHistogram of per-image spot count for imageset %i:' %i)
        logger.info(ascii_plot)

    # Save the reflections to file
    logger.info('\n' + '-' * 80)
    reflections.as_pickle(params.output.reflections)
    logger.info('Saved {0} reflections to {1}'.format(
        len(reflections), params.output.reflections))

    # Save the datablock
    if params.output.datablock:
      from dxtbx.datablock import DataBlockDumper
      logger.info('Saving datablocks to {0}'.format(
        params.output.datablock))
      dump = DataBlockDumper(datablocks)
      dump.as_file(params.output.datablock)

    # Print some per image statistics
    if params.per_image_statistics:
      from dials.algorithms.spot_finding import per_image_analysis
      from cStringIO import StringIO
      s = StringIO()
      for i, imageset in enumerate(datablocks[0].extract_imagesets()):
        print >> s, "Number of centroids per image for imageset %i:" %i
        stats = per_image_analysis.stats_imageset(
          imageset, reflections.select(reflections['id'] == i),
          resolution_analysis=False)
        per_image_analysis.print_table(stats, out=s)
      logger.info(s.getvalue())

    # Print the time
    logger.info("Time Taken: %f" % (time() - start_time))
Ejemplo n.º 8
0
def run(args):
    import libtbx.load_env
    usage = "%s [options] datablock.json strong.pickle" % libtbx.env.dispatcher_name

    parser = OptionParser(usage=usage,
                          read_reflections=True,
                          read_datablocks=True,
                          read_experiments=True,
                          phil=phil_scope,
                          check_format=False,
                          epilog=help_message)
    from libtbx.utils import Sorry

    params, options = parser.parse_args(show_diff_phil=False)
    reflections = flatten_reflections(params.input.reflections)
    datablocks = flatten_datablocks(params.input.datablock)
    experiments = flatten_experiments(params.input.experiments)

    if not any([reflections, experiments, datablocks]):
        parser.print_help()
        return

    if len(reflections) != 1:
        raise Sorry('exactly 1 reflection table must be specified')
    if len(datablocks) != 1:
        if experiments:
            if len(experiments.imagesets()) != 1:
                raise Sorry('exactly 1 datablock must be specified')
            imageset = experiments.imagesets()[0]
        else:
            raise Sorry('exactly 1 datablock must be specified')
    else:
        imageset = datablocks[0].extract_imagesets()[0]

    reflections = reflections[0]

    if params.id is not None:
        reflections = reflections.select(reflections['id'] == params.id)

    stats = per_image_analysis.stats_imageset(
        imageset,
        reflections,
        resolution_analysis=params.resolution_analysis,
        plot=params.individual_plots)
    per_image_analysis.print_table(stats)

    from libtbx import table_utils
    overall_stats = per_image_analysis.stats_single_image(
        imageset, reflections, resolution_analysis=params.resolution_analysis)
    rows = [
        ("Overall statistics", ""),
        ("#spots", "%i" % overall_stats.n_spots_total),
        ("#spots_no_ice", "%i" % overall_stats.n_spots_no_ice),
        #("total_intensity", "%.0f" %overall_stats.total_intensity),
        ("d_min", "%.2f" % overall_stats.estimated_d_min),
        ("d_min (distl method 1)",
         "%.2f (%.2f)" % (overall_stats.d_min_distl_method_1,
                          overall_stats.noisiness_method_1)),
        ("d_min (distl method 2)",
         "%.2f (%.2f)" % (overall_stats.d_min_distl_method_1,
                          overall_stats.noisiness_method_1)),
    ]
    print table_utils.format(rows, has_header=True, prefix="| ", postfix=" |")

    if params.json is not None:
        import json
        with open(params.json, 'wb') as fp:
            json.dump(stats.__dict__, fp)
    if params.plot is not None:
        per_image_analysis.plot_stats(stats, filename=params.plot)
Ejemplo n.º 9
0
    def run(self):
        """Execute the script."""
        from dials.util import log
        from time import time
        from libtbx import easy_mp
        import copy

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

        # Check we have some filenames
        if not all_paths:
            self.parser.print_help()
            return

        # Mask validation
        for mask_path in params.spotfinder.lookup.mask, params.integration.lookup.mask:
            if mask_path is not None and not os.path.isfile(mask_path):
                raise Sorry("Mask %s not found" % mask_path)

        # Save the options
        self.options = options
        self.params = params

        st = time()

        # Configure logging
        #log.config(
        #    params.verbosity, info="exafel_spotfinding.process.log", debug="exafel.spot_finding.debug.log"
        #)

        bad_phils = [f for f in all_paths if os.path.splitext(f)[1] == ".phil"]
        if len(bad_phils) > 0:
            self.parser.print_help()
            logger.error(
                "Error: the following phil files were not understood: %s" %
                (", ".join(bad_phils)))
            return

        # Log the diff phil
        diff_phil = self.parser.diff_phil.as_str()
        if diff_phil is not "":
            logger.info("The following parameters have been modified:\n")
            logger.info(diff_phil)

        for abs_params in self.params.integration.absorption_correction:
            if abs_params.apply:
                if not (self.params.integration.debug.output
                        and not self.params.integration.debug.separate_files):
                    raise Sorry(
                        "Shoeboxes must be saved to integration intermediates to apply an absorption correction. "
                        +
                        "Set integration.debug.output=True, integration.debug.separate_files=False and "
                        +
                        "integration.debug.delete_shoeboxes=True to temporarily store shoeboxes."
                    )

        self.load_reference_geometry()
        from dials.command_line.dials_import import ManualGeometryUpdater

        update_geometry = ManualGeometryUpdater(params)

        # Import stuff
        logger.info("Loading files...")
        pre_import = params.dispatch.pre_import or len(all_paths) == 1
        if True:  #pre_import:
            # Handle still imagesets by breaking them apart into multiple experiments
            # Further handle single file still imagesets (like HDF5) by tagging each
            # frame using its index
            experiments = ExperimentList()
            for path in all_paths:
                experiments.extend(do_import(path, load_models=False))

            indices = []
            basenames = []
            split_experiments = []
            for i, imageset in enumerate(experiments.imagesets()):
                assert len(imageset) == 1
                paths = imageset.paths()
                indices.append(i)
                basenames.append(
                    os.path.splitext(os.path.basename(paths[0]))[0])
                split_experiments.append(experiments[i:i + 1])
            tags = []
            for i, basename in zip(indices, basenames):
                if basenames.count(basename) > 1:
                    tags.append("%s_%05d" % (basename, i))
                else:
                    tags.append(basename)

            # Wrapper function
            def do_work(i, item_list):
                processor = SpotFinding_Processor(copy.deepcopy(params),
                                                  composite_tag="%04d" % i,
                                                  rank=i)
                if params.LS49.dump_CBF:
                    print('READING IN TIMESTAMPS TO DUMP')
                    # Read in file with timestamps information
                    processor.timestamps_to_dump = []
                    for fin in glob.glob(
                            os.path.join(
                                self.params.LS49.
                                path_to_rayonix_crystal_models,
                                'idx-fee_data*')):
                        #for fin in glob.glob(os.path.join(self.params.LS49.path_to_rayonix_crystal_models, 'int-0-*')):
                        int_file = os.path.basename(fin)
                        ts = int_file[13:30]
                        processor.timestamps_to_dump.append(ts)
                    #with open(os.path.join(self.params.output.output_dir,'../timestamps_to_dump.dat'), 'r') as fin:
                    #    for line in fin:
                    #        if line !='\n':
                    #            ts = line.split()[0].strip()
                    #            processor.timestamps_to_dump.append(ts)

                from dials.array_family import flex
                all_spots_from_rank = flex.reflection_table()
                for item in item_list:
                    try:
                        assert len(item[1]) == 1
                        experiment = item[1][0]
                        experiment.load_models()
                        imageset = experiment.imageset
                        update_geometry(imageset)
                        experiment.beam = imageset.get_beam()
                        experiment.detector = imageset.get_detector()
                    except RuntimeError as e:
                        logger.warning(
                            "Error updating geometry on item %s, %s" %
                            (str(item[0]), str(e)))
                        continue

                    if self.reference_detector is not None:
                        from dxtbx.model import Detector
                        experiment = item[1][0]
                        imageset = experiment.imageset
                        imageset.set_detector(
                            Detector.from_dict(
                                self.reference_detector.to_dict()))
                        experiment.detector = imageset.get_detector()

                    refl_table = processor.process_experiments(
                        item[0], item[1], item[2])
                    if refl_table is not None:
                        all_spots_from_rank.extend(refl_table)
                processor.finalize()
                return all_spots_from_rank

            iterable = zip(tags, split_experiments, indices)

        # Process the data
        if params.mp.method == 'mpi':
            from mpi4py import MPI
            comm = MPI.COMM_WORLD
            rank = comm.Get_rank(
            )  # each process in MPI has a unique id, 0-indexed
            size = comm.Get_size(
            )  # size: number of processes running in this job

            # Configure the logging
            if params.output.logging_dir is None:
                info_path = ''
                debug_path = ''
            else:
                import sys
                log_path = os.path.join(params.output.logging_dir,
                                        "log_rank%04d.out" % rank)
                error_path = os.path.join(params.output.logging_dir,
                                          "error_rank%04d.out" % rank)
                print("Redirecting stdout to %s" % log_path)
                print("Redirecting stderr to %s" % error_path)
                sys.stdout = open(log_path, 'a', buffering=0)
                sys.stderr = open(error_path, 'a', buffering=0)
                print("Should be redirected now")

                info_path = os.path.join(params.output.logging_dir,
                                         "info_rank%04d.out" % rank)
                debug_path = os.path.join(params.output.logging_dir,
                                          "debug_rank%04d.out" % rank)

            from dials.util import log
            print('IOTA_ALL_SPOTS_RANKS_0')
            #log.config(params.verbosity, info=info_path, debug=debug_path)
            subset = [
                item for i, item in enumerate(iterable)
                if (i + rank) % size == 0
            ]
            all_spots_from_rank = do_work(rank, subset)
            all_spots_rank0 = comm.gather(all_spots_from_rank, root=0)
            print('IOTA_ALL_SPOTS_RANKS_1')
            exit()
            if rank == 0:
                from dials.array_family import flex
                all_spots = flex.reflection_table()
                for ii, refl_table in enumerate(all_spots_rank0):
                    if refl_table is not None:
                        all_spots.extend(refl_table)
                from libtbx.easy_pickle import dump
                #dump('all_spots.pickle', all_spots_rank0)
                #dump('all_experiments.pickle', experiments)
                #print ('IOTA_ALL_SPOTS_RANKS_2')
                #print ('IOTA_ALL_SPOTS_RANKS_3')
                from dials.algorithms.spot_finding import per_image_analysis
                from six.moves import cStringIO as StringIO
                s = StringIO()
                # Assuming one datablock. Might be dangerous
                # FIXME
                from dxtbx.format.cbf_writer import FullCBFWriter
                for i, imageset in enumerate(experiments.imagesets()):
                    print("Number of centroids per image for imageset %i:" % i,
                          file=s)
                    #from IPython import embed; embed(); exit()
                    print('IOTA_ALL_SPOTS_RANKS_4')
                    stats = custom_stats_imageset(
                        imageset, all_spots.select(all_spots['img_id'] == i))
                    n_spots_total = flex.int(stats.n_spots_total)
                    max_number_of_spots = max(stats.n_spots_total)
                    for num_spots in range(1, max_number_of_spots + 1):
                        print("IOTA_NUMBER_OF_SPOTS %d %d" %
                              (num_spots,
                               len(
                                   n_spots_total.select(
                                       n_spots_total == num_spots))))
                    if max_number_of_spots > 0:
                        # assuming one imageset per experiment here : applicable for stills
                        ts = imageset.get_image_identifier(0)
                        xfel_ts = ts[0:4] + ts[5:7] + ts[8:10] + ts[
                            11:13] + ts[14:16] + ts[17:19] + ts[20:23]
                        cbf_path = os.path.join(params.output.logging_dir,
                                                'jungfrau_%s.cbf' % xfel_ts)
                        cbf_writer = FullCBFWriter(imageset=imageset)
                        cbf_writer.write_cbf(cbf_path)
                    per_image_analysis.print_table(stats)
                    logger.info(s.getvalue())
            comm.barrier()
        else:
            do_work(0, iterable)
Ejemplo n.º 10
0
def run(args):
  import libtbx.load_env
  usage = "%s [options] datablock.json strong.pickle" %libtbx.env.dispatcher_name

  parser = OptionParser(
    usage=usage,
    read_reflections=True,
    read_datablocks=True,
    read_experiments=True,
    phil=phil_scope,
    check_format=False,
    epilog=help_message)
  from libtbx.utils import Sorry

  params, options = parser.parse_args(show_diff_phil=False)
  reflections = flatten_reflections(params.input.reflections)
  datablocks = flatten_datablocks(params.input.datablock)
  experiments = flatten_experiments(params.input.experiments)

  if not any([reflections, experiments, datablocks]):
    parser.print_help()
    return

  if len(reflections) != 1:
    raise Sorry('exactly 1 reflection table must be specified')
  if len(datablocks) != 1:
    if experiments:
      if len(experiments.imagesets()) != 1:
        raise Sorry('exactly 1 datablock must be specified')
      imageset = experiments.imagesets()[0]
    else:
      raise Sorry('exactly 1 datablock must be specified')
  else:
    imageset = datablocks[0].extract_imagesets()[0]

  reflections = reflections[0]

  if params.id is not None:
    reflections = reflections.select(reflections['id'] == params.id)

  stats = per_image_analysis.stats_imageset(
    imageset, reflections, resolution_analysis=params.resolution_analysis,
    plot=params.individual_plots)
  per_image_analysis.print_table(stats)

  from libtbx import table_utils
  overall_stats = per_image_analysis.stats_single_image(
    imageset, reflections, resolution_analysis=params.resolution_analysis)
  rows = [
    ("Overall statistics", ""),
    ("#spots", "%i" %overall_stats.n_spots_total),
    ("#spots_no_ice", "%i" %overall_stats.n_spots_no_ice),
    #("total_intensity", "%.0f" %overall_stats.total_intensity),
    ("d_min", "%.2f" %overall_stats.estimated_d_min),
    ("d_min (distl method 1)", "%.2f (%.2f)" %(
      overall_stats.d_min_distl_method_1, overall_stats.noisiness_method_1)),
    ("d_min (distl method 2)", "%.2f (%.2f)" %(
      overall_stats.d_min_distl_method_1, overall_stats.noisiness_method_1)),
    ]
  print table_utils.format(rows, has_header=True, prefix="| ", postfix=" |")

  if params.json is not None:
    import json
    with open(params.json, 'wb') as fp:
      json.dump(stats.__dict__, fp)
  if params.plot is not None:
    per_image_analysis.plot_stats(stats, filename=params.plot)
Ejemplo n.º 11
0
def run(args):
    from dials.util.options import OptionParser
    import libtbx.load_env

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

    parser = OptionParser(usage=usage, phil=phil_scope, epilog=help_message)

    params, options, args = parser.parse_args(show_diff_phil=True,
                                              return_unhandled=True)

    positions = None
    if params.positions is not None:
        with open(params.positions, 'rb') as f:
            positions = flex.vec2_double()
            for line in f.readlines():
                line = line.replace('(', ' ').replace(')', '').replace(
                    ',', ' ').strip().split()
                assert len(line) == 3
                i, x, y = [float(l) for l in line]
                positions.append((x, y))

    assert len(args) == 1
    json_file = args[0]
    import json

    with open(json_file, 'rb') as f:
        results = json.load(f)

    n_indexed = flex.double()
    fraction_indexed = flex.double()
    n_spots = flex.double()
    n_lattices = flex.double()
    crystals = []
    image_names = flex.std_string()

    for r in results:
        n_spots.append(r['n_spots_total'])
        image_names.append(str(r['image']))
        if 'n_indexed' in r:
            n_indexed.append(r['n_indexed'])
            n_lattices.append(len(r['lattices']))
            for d in r['lattices']:
                from dxtbx.serialize.crystal import from_dict
                crystals.append(from_dict(d['crystal']))
        else:
            n_indexed.append(0)
            n_lattices.append(0)

    if n_indexed.size():
        sel = n_spots > 0
        fraction_indexed = flex.double(n_indexed.size(), 0)
        fraction_indexed.set_selected(
            sel,
            n_indexed.select(sel) / n_spots.select(sel))

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

    blue = '#3498db'
    red = '#e74c3c'

    marker = 'o'
    alpha = 0.5
    lw = 0

    plot = True
    table = True
    grid = params.grid

    from libtbx import group_args
    from dials.algorithms.spot_finding.per_image_analysis \
         import plot_stats, print_table

    estimated_d_min = flex.double()
    d_min_distl_method_1 = flex.double()
    d_min_distl_method_2 = flex.double()
    n_spots_total = flex.int()
    n_spots_no_ice = flex.int()
    total_intensity = flex.double()

    for d in results:
        estimated_d_min.append(d['estimated_d_min'])
        d_min_distl_method_1.append(d['d_min_distl_method_1'])
        d_min_distl_method_2.append(d['d_min_distl_method_2'])
        n_spots_total.append(d['n_spots_total'])
        n_spots_no_ice.append(d['n_spots_no_ice'])
        total_intensity.append(d['total_intensity'])

    stats = group_args(image=image_names,
                       n_spots_total=n_spots_total,
                       n_spots_no_ice=n_spots_no_ice,
                       n_spots_4A=None,
                       n_indexed=n_indexed,
                       fraction_indexed=fraction_indexed,
                       total_intensity=total_intensity,
                       estimated_d_min=estimated_d_min,
                       d_min_distl_method_1=d_min_distl_method_1,
                       d_min_distl_method_2=d_min_distl_method_2,
                       noisiness_method_1=None,
                       noisiness_method_2=None)

    if plot:
        plot_stats(stats)
        pyplot.clf()
    if table:
        print_table(stats)

    n_rows = 10
    n_rows = min(n_rows, len(n_spots_total))
    perm_n_spots_total = flex.sort_permutation(n_spots_total, reverse=True)
    print 'Top %i images sorted by number of spots:' % n_rows
    print_table(stats, perm=perm_n_spots_total, n_rows=n_rows)
    if flex.max(n_indexed) > 0:
        perm_n_indexed = flex.sort_permutation(n_indexed, reverse=True)
        print 'Top %i images sorted by number of indexed reflections:' % n_rows
        print_table(stats, perm=perm_n_indexed, n_rows=n_rows)

    print "Number of indexed lattices: ", (n_indexed > 0).count(True)

    print "Number with valid d_min but failed indexing: ", (
        (d_min_distl_method_1 > 0) & (d_min_distl_method_2 > 0) &
        (estimated_d_min > 0) & (n_indexed == 0)).count(True)

    n_bins = 20
    spot_count_histogram(n_spots_total,
                         n_bins=n_bins,
                         filename='hist_n_spots_total.png',
                         log=True)
    spot_count_histogram(n_spots_no_ice,
                         n_bins=n_bins,
                         filename='hist_n_spots_no_ice.png',
                         log=True)
    spot_count_histogram(n_indexed.select(n_indexed > 0),
                         n_bins=n_bins,
                         filename='hist_n_indexed.png',
                         log=False)

    if len(crystals):
        plot_unit_cell_histograms(crystals)

    if params.stereographic_projections and len(crystals):
        from dxtbx.datablock import DataBlockFactory
        datablocks = DataBlockFactory.from_filenames([image_names[0]],
                                                     verbose=False)
        assert len(datablocks) == 1
        imageset = datablocks[0].extract_imagesets()[0]
        s0 = imageset.get_beam().get_s0()
        # XXX what if no goniometer?
        rotation_axis = imageset.get_goniometer().get_rotation_axis()

        indices = ((1, 0, 0), (0, 1, 0), (0, 0, 1))
        for i, index in enumerate(indices):

            from cctbx import crystal, miller
            from scitbx import matrix
            miller_indices = flex.miller_index([index])
            symmetry = crystal.symmetry(
                unit_cell=crystals[0].get_unit_cell(),
                space_group=crystals[0].get_space_group())
            miller_set = miller.set(symmetry, miller_indices)
            d_spacings = miller_set.d_spacings()
            d_spacings = d_spacings.as_non_anomalous_array().expand_to_p1()
            d_spacings = d_spacings.generate_bijvoet_mates()
            miller_indices = d_spacings.indices()

            # plane normal
            d0 = matrix.col(s0).normalize()
            d1 = d0.cross(matrix.col(rotation_axis)).normalize()
            d2 = d1.cross(d0).normalize()
            reference_poles = (d0, d1, d2)

            from dials.command_line.stereographic_projection import stereographic_projection
            projections = []

            for cryst in crystals:
                reciprocal_space_points = list(
                    cryst.get_U() *
                    cryst.get_B()) * miller_indices.as_vec3_double()
                projections.append(
                    stereographic_projection(reciprocal_space_points,
                                             reference_poles))

                #from dials.algorithms.indexing.compare_orientation_matrices import \
                #  difference_rotation_matrix_and_euler_angles
                #R_ij, euler_angles, cb_op = difference_rotation_matrix_and_euler_angles(
                #  crystals[0], cryst)
                #print max(euler_angles)

            from dials.command_line.stereographic_projection import plot_projections
            plot_projections(projections,
                             filename='projections_%s.png' % ('hkl'[i]))
            pyplot.clf()

    def plot_grid(values,
                  grid,
                  file_name,
                  cmap=pyplot.cm.Reds,
                  vmin=None,
                  vmax=None,
                  invalid='white'):
        values = values.as_double()
        # At DLS, fast direction appears to be largest direction
        if grid[0] > grid[1]:
            values.reshape(flex.grid(reversed(grid)))
            values = values.matrix_transpose()
        else:
            values.reshape(flex.grid(grid))

        Z = values.as_numpy_array()

        #f, (ax1, ax2) = pyplot.subplots(2)
        f, ax1 = pyplot.subplots(1)

        mesh1 = ax1.pcolormesh(values.as_numpy_array(),
                               cmap=cmap,
                               vmin=vmin,
                               vmax=vmax)
        mesh1.cmap.set_under(color=invalid, alpha=None)
        mesh1.cmap.set_over(color=invalid, alpha=None)
        #mesh2 = ax2.contour(Z, cmap=cmap, vmin=vmin, vmax=vmax)
        #mesh2 = ax2.contourf(Z, cmap=cmap, vmin=vmin, vmax=vmax)
        ax1.set_aspect('equal')
        ax1.invert_yaxis()
        #ax2.set_aspect('equal')
        #ax2.invert_yaxis()
        pyplot.colorbar(mesh1, ax=ax1)
        #pyplot.colorbar(mesh2, ax=ax2)
        pyplot.savefig(file_name, dpi=600)
        pyplot.clf()

    def plot_positions(values,
                       positions,
                       file_name,
                       cmap=pyplot.cm.Reds,
                       vmin=None,
                       vmax=None,
                       invalid='white'):
        values = values.as_double()
        assert positions.size() >= values.size()
        positions = positions[:values.size()]

        if vmin is None:
            vmin = flex.min(values)
        if vmax is None:
            vmax = flex.max(values)

        x, y = positions.parts()
        dx = flex.abs(x[1:] - x[:-1])
        dy = flex.abs(y[1:] - y[:-1])
        dx = dx.select(dx > 0)
        dy = dy.select(dy > 0)

        scale = 1 / flex.min(dx)
        #print scale
        x = (x * scale).iround()
        y = (y * scale).iround()

        from libtbx.math_utils import iceil
        z = flex.double(
            flex.grid(iceil(flex.max(y)) + 1,
                      iceil(flex.max(x)) + 1), -2)
        #print z.all()
        for x_, y_, z_ in zip(x, y, values):
            z[y_, x_] = z_

        plot_grid(z.as_1d(),
                  z.all(),
                  file_name,
                  cmap=cmap,
                  vmin=vmin,
                  vmax=vmax,
                  invalid=invalid)
        return

    if grid is not None or positions is not None:
        if grid is not None:
            positions = tuple(reversed(grid))
            plotter = plot_grid
        else:
            plotter = plot_positions

        cmap = pyplot.get_cmap(params.cmap)
        plotter(n_spots_total,
                positions,
                'grid_spot_count_total.png',
                cmap=cmap,
                invalid=params.invalid)
        plotter(n_spots_no_ice,
                positions,
                'grid_spot_count_no_ice.png',
                cmap=cmap,
                invalid=params.invalid)
        plotter(total_intensity,
                positions,
                'grid_total_intensity.png',
                cmap=cmap,
                invalid=params.invalid)
        if flex.max(n_indexed) > 0:
            plotter(n_indexed,
                    positions,
                    'grid_n_indexed.png',
                    cmap=cmap,
                    invalid=params.invalid)
            plotter(fraction_indexed,
                    positions,
                    'grid_fraction_indexed.png',
                    cmap=cmap,
                    vmin=0,
                    vmax=1,
                    invalid=params.invalid)

        for i, d_min in enumerate(
            (estimated_d_min, d_min_distl_method_1, d_min_distl_method_2)):
            from cctbx import uctbx
            d_star_sq = uctbx.d_as_d_star_sq(d_min)
            d_star_sq.set_selected(d_star_sq == 1, 0)
            vmin = flex.min(d_star_sq.select(d_star_sq > 0))
            vmax = flex.max(d_star_sq)

            vmin = flex.min(d_min.select(d_min > 0))
            vmax = flex.max(d_min)
            cmap = pyplot.get_cmap('%s_r' % params.cmap)
            d_min.set_selected(d_min <= 0, vmax)

            if i == 0:
                plotter(d_min,
                        positions,
                        'grid_d_min.png',
                        cmap=cmap,
                        vmin=vmin,
                        vmax=vmax,
                        invalid=params.invalid)
            else:
                plotter(d_min,
                        positions,
                        'grid_d_min_method_%i.png' % i,
                        cmap=cmap,
                        vmin=vmin,
                        vmax=vmax,
                        invalid=params.invalid)

    if flex.max(n_indexed) > 0:
        pyplot.hexbin(n_spots,
                      n_indexed,
                      bins='log',
                      cmap=pyplot.cm.jet,
                      gridsize=50)
        pyplot.colorbar()
        #pyplot.scatter(n_spots, n_indexed, marker=marker, alpha=alpha, c=blue, lw=lw)
        xlim = pyplot.xlim()
        ylim = pyplot.ylim()
        pyplot.plot([0, max(n_spots)], [0, max(n_spots)], c=red)
        pyplot.xlim(0, xlim[1])
        pyplot.ylim(0, ylim[1])
        pyplot.xlabel('# spots')
        pyplot.ylabel('# indexed')
        pyplot.savefig('n_spots_vs_n_indexed.png')
        pyplot.clf()

        pyplot.hexbin(n_spots,
                      fraction_indexed,
                      bins='log',
                      cmap=pyplot.cm.jet,
                      gridsize=50)
        pyplot.colorbar()
        #pyplot.scatter(
        #n_spots, fraction_indexed, marker=marker, alpha=alpha, c=blue, lw=lw)
        pyplot.xlim(0, pyplot.xlim()[1])
        pyplot.ylim(0, pyplot.ylim()[1])
        pyplot.xlabel('# spots')
        pyplot.ylabel('Fraction indexed')
        pyplot.savefig('n_spots_vs_fraction_indexed.png')
        pyplot.clf()

        pyplot.hexbin(n_indexed,
                      fraction_indexed,
                      bins='log',
                      cmap=pyplot.cm.jet,
                      gridsize=50)
        pyplot.colorbar()
        #pyplot.scatter(
        #n_indexed, fraction_indexed, marker=marker, alpha=alpha, c=blue, lw=lw)
        pyplot.xlim(0, pyplot.xlim()[1])
        pyplot.ylim(0, pyplot.ylim()[1])
        pyplot.xlabel('# indexed')
        pyplot.ylabel('Fraction indexed')
        pyplot.savefig('n_indexed_vs_fraction_indexed.png')
        pyplot.clf()

        pyplot.hexbin(n_spots,
                      n_lattices,
                      bins='log',
                      cmap=pyplot.cm.jet,
                      gridsize=50)
        pyplot.colorbar()
        #pyplot.scatter(
        #n_spots, n_lattices, marker=marker, alpha=alpha, c=blue, lw=lw)
        pyplot.xlim(0, pyplot.xlim()[1])
        pyplot.ylim(0, pyplot.ylim()[1])
        pyplot.xlabel('# spots')
        pyplot.ylabel('# lattices')
        pyplot.savefig('n_spots_vs_n_lattices.png')
        pyplot.clf()

    #pyplot.scatter(
    #  estimated_d_min, d_min_distl_method_1, marker=marker, alpha=alpha, c=blue, lw=lw)
    pyplot.hexbin(estimated_d_min,
                  d_min_distl_method_1,
                  bins='log',
                  cmap=pyplot.cm.jet,
                  gridsize=50)
    pyplot.colorbar()
    #pyplot.gca().set_aspect('equal')
    xlim = pyplot.xlim()
    ylim = pyplot.ylim()
    m = max(max(estimated_d_min), max(d_min_distl_method_1))
    pyplot.plot([0, m], [0, m], c=red)
    pyplot.xlim(0, xlim[1])
    pyplot.ylim(0, ylim[1])
    pyplot.xlabel('estimated_d_min')
    pyplot.ylabel('d_min_distl_method_1')
    pyplot.savefig('d_min_vs_distl_method_1.png')
    pyplot.clf()

    #pyplot.scatter(
    #  estimated_d_min, d_min_distl_method_2, marker=marker, alpha=alpha, c=blue, lw=lw)
    pyplot.hexbin(estimated_d_min,
                  d_min_distl_method_2,
                  bins='log',
                  cmap=pyplot.cm.jet,
                  gridsize=50)
    pyplot.colorbar()
    #pyplot.gca().set_aspect('equal')
    xlim = pyplot.xlim()
    ylim = pyplot.ylim()
    m = max(max(estimated_d_min), max(d_min_distl_method_2))
    pyplot.plot([0, m], [0, m], c=red)
    pyplot.xlim(0, xlim[1])
    pyplot.ylim(0, ylim[1])
    pyplot.xlabel('estimated_d_min')
    pyplot.ylabel('d_min_distl_method_2')
    pyplot.savefig('d_min_vs_distl_method_2.png')
    pyplot.clf()

    #pyplot.scatter(
    #  d_min_distl_method_1, d_min_distl_method_2, marker=marker, alpha=alpha, c=blue, lw=lw)
    pyplot.hexbin(d_min_distl_method_1,
                  d_min_distl_method_2,
                  bins='log',
                  cmap=pyplot.cm.jet,
                  gridsize=50)
    pyplot.colorbar()
    #pyplot.gca().set_aspect('equal')
    xlim = pyplot.xlim()
    ylim = pyplot.ylim()
    m = max(max(d_min_distl_method_1), max(d_min_distl_method_2))
    pyplot.plot([0, m], [0, m], c=red)
    pyplot.xlim(0, xlim[1])
    pyplot.ylim(0, ylim[1])
    pyplot.xlabel('d_min_distl_method_1')
    pyplot.ylabel('d_min_distl_method_2')
    pyplot.savefig('distl_method_1_vs_distl_method_2.png')
    pyplot.clf()

    pyplot.hexbin(n_spots,
                  estimated_d_min,
                  bins='log',
                  cmap=pyplot.cm.jet,
                  gridsize=50)
    pyplot.colorbar()
    #pyplot.scatter(
    #n_spots, estimated_d_min, marker=marker, alpha=alpha, c=blue, lw=lw)
    pyplot.xlim(0, pyplot.xlim()[1])
    pyplot.ylim(0, pyplot.ylim()[1])
    pyplot.xlabel('# spots')
    pyplot.ylabel('estimated_d_min')
    pyplot.savefig('n_spots_vs_d_min.png')
    pyplot.clf()

    pyplot.hexbin(n_spots,
                  d_min_distl_method_1,
                  bins='log',
                  cmap=pyplot.cm.jet,
                  gridsize=50)
    pyplot.colorbar()
    #pyplot.scatter(
    #n_spots, d_min_distl_method_1, marker=marker, alpha=alpha, c=blue, lw=lw)
    pyplot.xlim(0, pyplot.xlim()[1])
    pyplot.ylim(0, pyplot.ylim()[1])
    pyplot.xlabel('# spots')
    pyplot.ylabel('d_min_distl_method_1')
    pyplot.savefig('n_spots_vs_distl_method_1.png')
    pyplot.clf()

    pyplot.hexbin(n_spots,
                  d_min_distl_method_2,
                  bins='log',
                  cmap=pyplot.cm.jet,
                  gridsize=50)
    pyplot.colorbar()
    #pyplot.scatter(
    #n_spots, d_min_distl_method_2, marker=marker, alpha=alpha, c=blue, lw=lw)
    pyplot.xlim(0, pyplot.xlim()[1])
    pyplot.ylim(0, pyplot.ylim()[1])
    pyplot.xlabel('# spots')
    pyplot.ylabel('d_min_distl_method_2')
    pyplot.savefig('n_spots_vs_distl_method_2.png')
    pyplot.clf()