예제 #1
0
def test_slice_reflections():
    r = flex.reflection_table()
    r["id"] = flex.int([0, 0, 0, 1, 1, 1, 2, 2, 2])
    image_number = [0, 1, 2, 0, 1, 2, 0, 1, 2]
    r["xyzobs.px.value"] = flex.vec3_double(
        zip([0] * len(r), [0] * len(r), image_number))
    sliced_r = slice_reflections(r, [(1, 2), (1, 1), (2, 3)])
    assert list(sliced_r["id"]) == [0, 0, 1, 2, 2]
    assert list(
        sliced_r["xyzobs.px.value"].parts()[2]) == [0.0, 1.0, 0.0, 1.0, 2.0]
예제 #2
0
def run(args):
    usage = "dials.search_beam_position [options] imported.expt strong.refl"

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

    params, options = parser.parse_args(args, show_diff_phil=False)
    reflections, experiments = reflections_and_experiments_from_files(
        params.input.reflections, params.input.experiments)

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

    # Configure the logging
    log.config(logfile=params.output.log)

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

    if params.seed is not None:
        flex.set_random_seed(params.seed)
        random.seed(params.seed)

    if params.nproc is libtbx.Auto:
        params.nproc = libtbx.introspection.number_of_processors()

    imagesets = experiments.imagesets()
    # Split all the refln tables by ID, corresponding to the respective imagesets
    reflections = [
        refl_unique_id for refl in reflections
        for refl_unique_id in refl.split_by_experiment_id()
    ]

    assert len(imagesets) > 0
    assert len(reflections) == len(imagesets)

    if params.image_range is not None and len(params.image_range) > 0:
        reflections = [
            slice_reflections(refl, params.image_range) for refl in reflections
        ]

    for i in range(params.n_macro_cycles):
        if params.n_macro_cycles > 1:
            logger.info("Starting macro cycle %i" % (i + 1))
        experiments = discover_better_experimental_model(
            experiments,
            reflections,
            params,
            nproc=params.nproc,
            d_min=params.d_min,
            mm_search_scope=params.mm_search_scope,
            wide_search_binning=params.wide_search_binning,
            plot_search_scope=params.plot_search_scope,
        )
        logger.info("")

    logger.info("Saving optimised experiments to %s" %
                params.output.experiments)
    experiments.as_file(params.output.experiments)
예제 #3
0
def index(experiments, reflections, params):
    """
    Index the input experiments and reflections.

    Args:
        experiments: The experiments to index
        reflections (list): A list of reflection tables containing strong spots
        params: An instance of the indexing phil scope

    Returns:
        (tuple): tuple containing:
            experiments: The indexed experiment list
            reflections (dials.array_family.flex.reflection_table):
                The indexed reflections

    """
    if experiments.crystals()[0] is not None:
        known_crystal_models = experiments.crystals()
    else:
        known_crystal_models = None

    if len(reflections) == 0:
        raise ValueError("No reflection lists found in input")
    elif len(reflections) == 1:
        reflections[0]["imageset_id"] = reflections[0]["id"]
    elif len(reflections) > 1:
        assert len(reflections) == len(experiments)
        for i in range(len(reflections)):
            reflections[i]["imageset_id"] = flex.int(len(reflections[i]), i)
            if i > 0:
                reflections[0].extend(reflections[i])
    reflections = reflections[0]

    # If there are scan and goniometer objects present but the oscillation angle is zero
    # then expt.scan and expt.goniometer to None, as the behaviour of some downstream
    # algorithms depend on the presence/absence of these objects
    for expt in experiments:
        if (expt.goniometer is not None and expt.scan is not None
                and expt.scan.is_still()):
            expt.imageset = ImageSetFactory.imageset_from_anyset(expt.imageset)
            expt.goniometer = None
            expt.scan = None

    if params.indexing.image_range:
        reflections = slice_reflections(reflections,
                                        params.indexing.image_range)

    if len(experiments) == 1 or params.indexing.joint_indexing:
        indexed_experiments, indexed_reflections = _index_experiments(
            experiments,
            reflections,
            copy.deepcopy(params),
            known_crystal_models=known_crystal_models,
        )
    else:
        indexed_experiments = ExperimentList()
        indexed_reflections = flex.reflection_table()

        with concurrent.futures.ProcessPoolExecutor(
                max_workers=params.indexing.nproc) as pool:
            futures = []
            for i_expt, expt in enumerate(experiments):
                refl = reflections.select(reflections["imageset_id"] == i_expt)
                refl["imageset_id"] = flex.size_t(len(refl), 0)
                futures.append(
                    pool.submit(
                        _index_experiments,
                        ExperimentList([expt]),
                        refl,
                        copy.deepcopy(params),
                        known_crystal_models=known_crystal_models,
                    ))

            for future in concurrent.futures.as_completed(futures):
                try:
                    idx_expts, idx_refl = future.result()
                except Exception as e:
                    print(e)
                else:
                    if idx_expts is None:
                        continue
                    for j_expt, _ in enumerate(idx_expts):
                        sel = idx_refl["id"] == j_expt
                        idx_refl["id"].set_selected(
                            sel,
                            len(indexed_experiments) + j_expt)
                    idx_refl["imageset_id"] = flex.size_t(
                        len(idx_refl), i_expt)
                    indexed_reflections.extend(idx_refl)
                    indexed_experiments.extend(idx_expts)
    return indexed_experiments, indexed_reflections
예제 #4
0
def test_trim_scans_to_observations(dials_data):

    # Use 4 scan data for this test
    data_dir = dials_data("l_cysteine_dials_output")
    experiments = ExperimentListFactory.from_json_file(
        (data_dir / "indexed.expt").strpath, check_format=False)
    reflections = flex.reflection_table.from_file(
        (data_dir / "indexed.refl").strpath)

    # Check the image and oscillation range are what we expect
    image_ranges = [e.scan.get_image_range() for e in experiments]
    osc_ranges = [e.scan.get_oscillation_range() for e in experiments]
    for a, b in zip(image_ranges, [(1, 1700), (1, 1700), (1, 1700),
                                   (1, 1800)]):
        assert a == b
    for a, b in zip(osc_ranges, [(-145.0, 25.0), (-145.0, 25.0),
                                 (-145.0, 25.0), (0.0, 180.0)]):
        assert a == pytest.approx(b)

    # If image range unchanged, nothing should happen
    trim_expt = _trim_scans_to_observations(deepcopy(experiments), reflections)
    new_im_ranges = [e.scan.get_image_range() for e in trim_expt]
    for a, b in zip(image_ranges, new_im_ranges):
        assert a == b

    # Slice 20 images off head and tail
    sliced_ranges = [(r[0] + 20, r[1] - 20) for r in image_ranges]
    sliced = slice_reflections(reflections, sliced_ranges)

    # Now trimmed scans should have array ranges equal to their min, max
    # shoebox z coords
    trim_expt = _trim_scans_to_observations(deepcopy(experiments), sliced)
    new_array_ranges = [e.scan.get_array_range() for e in trim_expt]

    for i, e in enumerate(trim_expt):
        refs = sliced.select(sliced["id"] == i)
        bb = refs["shoebox"].bounding_boxes()
        z_min, z_max = bb.parts()[4:]
        assert new_array_ranges[i] == (min(z_min), max(z_max))

    # Oscillation ranges should be trimmed so that the associated angle is the
    # same in the original and trimmed scans
    new_osc_ranges = [e.scan.get_oscillation_range() for e in trim_expt]
    for exp, r1, r2 in zip(experiments, new_array_ranges, new_osc_ranges):
        assert exp.scan.get_angle_from_array_index(r1[0]) == pytest.approx(
            r2[0])
        assert exp.scan.get_angle_from_array_index(r1[1]) == pytest.approx(
            r2[1])

    # Now delete shoebox data. Trimmed scans will be wider than the observed
    # range by >0.5 deg at each end
    del sliced["shoebox"]
    trim_expt = _trim_scans_to_observations(deepcopy(experiments), sliced)
    new_array_ranges = [e.scan.get_array_range() for e in trim_expt]

    for i, e in enumerate(trim_expt):
        refs = sliced.select(sliced["id"] == i)
        z = refs["xyzobs.px.value"].parts()[2]
        im_width = e.scan.get_oscillation()[1]
        assert ((min(z) - new_array_ranges[i][0]) / im_width) > 0.5
        assert ((new_array_ranges[i][1] - max(z)) / im_width) > 0.5

    # Oscillation ranges should be trimmed so that the associated angle is the
    # same in the original and trimmed scans
    new_osc_ranges = [e.scan.get_oscillation_range() for e in trim_expt]
    for exp, r1, r2 in zip(experiments, new_array_ranges, new_osc_ranges):
        assert exp.scan.get_angle_from_array_index(r1[0]) == pytest.approx(
            r2[0])
        assert exp.scan.get_angle_from_array_index(r1[1]) == pytest.approx(
            r2[1])
예제 #5
0
    def run(self):
        """Execute the script."""

        from dials.util.options import reflections_and_experiments_from_files

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

        # Try to load the models and data
        slice_exps = len(experiments) > 0
        slice_refs = len(reflections) > 0

        # Catch case of nothing to do
        if not slice_exps and not slice_refs:
            print("No suitable input provided")
            self.parser.print_help()
            return

        if reflections:
            if len(reflections) > 1:
                raise Sorry(
                    "Only one reflections list can be imported at present")
            reflections = reflections[0]

            # calculate frame numbers if needed
            if experiments:
                reflections = calculate_frame_numbers(reflections, experiments)

            # if we still don't have the right column give up
            if "xyzobs.px.value" not in reflections:
                raise Sorry(
                    "These reflections do not have frame numbers set, and "
                    "there are no experiments provided to calculate these.")

        # set trivial case where no scan range is provided at all
        if not params.image_range:
            params.image_range = [None]

        # check if slicing into blocks
        if params.block_size is not None:
            if slice_exps:
                if len(experiments) > 1:
                    raise Sorry(
                        "For slicing into blocks please provide a single "
                        "scan only")
                scan = experiments[0].scan

            # Having extracted the scan, calculate the blocks
            params.image_range = calculate_block_ranges(
                scan, params.block_size)

            # Do the slicing then recombine
            if slice_exps:
                sliced = [
                    slice_experiments(experiments, [sr])[0]
                    for sr in params.image_range
                ]
                sliced_experiments = ExperimentList()
                for exp in sliced:
                    sliced_experiments.append(exp)

            # slice reflections if present
            if slice_refs:
                sliced = [
                    slice_reflections(reflections, [sr])
                    for sr in params.image_range
                ]
                sliced_reflections = sliced[0]
                for i, rt in enumerate(sliced[1:]):
                    rt["id"] += i + 1  # set id
                    sliced_reflections.extend(rt)

        else:
            # slice each dataset into the requested subset
            if slice_exps:
                sliced_experiments = slice_experiments(experiments,
                                                       params.image_range)
            if slice_refs:
                sliced_reflections = slice_reflections(reflections,
                                                       params.image_range)

        # Save sliced experiments
        if slice_exps:
            output_experiments_filename = params.output.experiments_filename
            if output_experiments_filename is None:
                # take first filename as template
                bname = basename(params.input.experiments[0].filename)
                bname = splitext(bname)[0]
                if not bname:
                    bname = "experiments"
                if len(params.image_range
                       ) == 1 and params.image_range[0] is not None:
                    ext = "_{0}_{1}.expt".format(*params.image_range[0])
                else:
                    ext = "_sliced.expt"
                output_experiments_filename = bname + ext
            print("Saving sliced experiments to {}".format(
                output_experiments_filename))

            sliced_experiments.as_file(output_experiments_filename)

        # Save sliced reflections
        if slice_refs:
            output_reflections_filename = params.output.reflections_filename
            if output_reflections_filename is None:
                # take first filename as template
                bname = basename(params.input.reflections[0].filename)
                bname = splitext(bname)[0]
                if not bname:
                    bname = "reflections"
                if len(params.image_range
                       ) == 1 and params.image_range[0] is not None:
                    ext = "_{0}_{1}.refl".format(*params.image_range[0])
                else:
                    ext = "_sliced.refl"
                output_reflections_filename = bname + ext

            print("Saving sliced reflections to {0}".format(
                output_reflections_filename))
            sliced_reflections.as_file(output_reflections_filename)

        return
예제 #6
0
def index(experiments, reflections, params):
    """
    Index the input experiments and reflections.

    Args:
        experiments: The experiments to index
        reflections (list): A list of reflection tables containing strong spots
        params: An instance of the indexing phil scope

    Returns:
        (tuple): tuple containing:
            experiments: The indexed experiment list
            reflections (dials.array_family.flex.reflection_table):
                The indexed reflections

    Raises:
        ValueError: `reflections` is an empty list or `experiments` contains a
                    combination of sequence and stills data.
        dials.algorithms.indexing.DialsIndexError: Indexing failed.
    """
    if experiments.crystals()[0] is not None:
        known_crystal_models = experiments.crystals()
    else:
        known_crystal_models = None

    if len(reflections) == 0:
        raise ValueError("No reflection lists found in input")
    elif len(reflections) == 1:
        if "imageset_id" not in reflections[0]:
            reflections[0]["imageset_id"] = reflections[0]["id"]
    elif len(reflections) > 1:
        assert len(reflections) == len(experiments)
        for i in range(len(reflections)):
            reflections[i]["imageset_id"] = flex.int(len(reflections[i]), i)
            if i > 0:
                reflections[0].extend(reflections[i])
    reflections = reflections[0]

    if params.indexing.image_range:
        reflections = slice_reflections(reflections, params.indexing.image_range)

    if len(experiments) == 1 or params.indexing.joint_indexing:
        indexed_experiments, indexed_reflections = _index_experiments(
            experiments,
            reflections,
            copy.deepcopy(params),
            known_crystal_models=known_crystal_models,
        )
    else:
        indexed_experiments = ExperimentList()
        indexed_reflections = flex.reflection_table()

        with concurrent.futures.ProcessPoolExecutor(
            max_workers=params.indexing.nproc
        ) as pool:
            futures = []
            for i_expt, expt in enumerate(experiments):
                refl = reflections.select(reflections["imageset_id"] == i_expt)
                refl["imageset_id"] = flex.size_t(len(refl), 0)
                futures.append(
                    pool.submit(
                        _index_experiments,
                        ExperimentList([expt]),
                        refl,
                        copy.deepcopy(params),
                        known_crystal_models=known_crystal_models,
                    )
                )
            tables_list = []
            for future in concurrent.futures.as_completed(futures):
                try:
                    idx_expts, idx_refl = future.result()
                except Exception as e:
                    print(e)
                else:
                    if idx_expts is None:
                        continue
                    # Update the experiment ids by incrementing by the number of indexed
                    # experiments already in the list
                    ##FIXME below, is i_expt correct - or should it be the
                    # index of the 'future'?
                    idx_refl["imageset_id"] = flex.size_t(idx_refl.size(), i_expt)
                    tables_list.append(idx_refl)
                    indexed_experiments.extend(idx_expts)
            tables_list = renumber_table_id_columns(tables_list)
            for table in tables_list:
                indexed_reflections.extend(table)
    return indexed_experiments, indexed_reflections
def run(args):
    usage = "dials.search_beam_position [options] imported.expt strong.refl"

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

    params, options = parser.parse_args(show_diff_phil=False)
    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)

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

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

    if params.seed is not None:
        flex.set_random_seed(params.seed)
        random.seed(params.seed)

    imagesets = experiments.imagesets()
    # Split all the refln tables by ID, corresponding to the respective imagesets
    reflections = [
        refl_unique_id for refl in reflections
        for refl_unique_id in refl.split_by_experiment_id()
    ]

    assert len(imagesets) > 0
    assert len(reflections) == len(imagesets)

    if params.image_range is not None and len(params.image_range) > 0:
        reflections = [
            slice_reflections(refl, params.image_range) for refl in reflections
        ]

    dps_params = dps_phil_scope.extract()
    # for development, we want an exhaustive plot of beam probability map:
    dps_params.indexing.plot_search_scope = params.plot_search_scope
    dps_params.indexing.mm_search_scope = params.mm_search_scope

    for i in range(params.n_macro_cycles):
        if params.n_macro_cycles > 1:
            logger.info("Starting macro cycle %i" % (i + 1))
        new_detector, new_beam = discover_better_experimental_model(
            imagesets,
            reflections,
            params,
            dps_params,
            nproc=params.nproc,
            wide_search_binning=params.wide_search_binning,
        )
        for experiment in experiments:
            experiment.beam = new_beam
            experiment.detector = new_detector
        logger.info("")

    logger.info("Saving optimized experiments to %s" %
                params.output.experiments)
    dump.experiment_list(experiments, params.output.experiments)
예제 #8
0
    def __init__(self, experiments, reflections, params):

        self._params = params

        if experiments.crystals()[0] is not None:
            known_crystal_models = experiments.crystals()
        else:
            known_crystal_models = None

        if len(reflections) == 0:
            raise Sorry("No reflection lists found in input")
        elif len(reflections) == 1:
            reflections[0]["imageset_id"] = reflections[0]["id"]
        elif len(reflections) > 1:
            assert len(reflections) == len(experiments)
            for i in range(len(reflections)):
                reflections[i]["imageset_id"] = flex.int(
                    len(reflections[i]), i)
                if i > 0:
                    reflections[0].extend(reflections[i])
        reflections = reflections[0]

        for expt in experiments:
            if (expt.goniometer is not None and expt.scan is not None
                    and expt.scan.get_oscillation()[1] == 0):
                expt.goniometer = None
                expt.scan = None

        if self._params.indexing.image_range:
            reflections = slice_reflections(reflections,
                                            self._params.indexing.image_range)

        if len(experiments) == 1 or self._params.indexing.joint_indexing:
            try:
                self._indexed_experiments, self._indexed_reflections = index_experiments(
                    experiments,
                    reflections,
                    copy.deepcopy(params),
                    known_crystal_models=known_crystal_models,
                )
            except DialsIndexError as e:
                raise Sorry(e.message)
        else:
            self._indexed_experiments = ExperimentList()
            self._indexed_reflections = flex.reflection_table()

            import concurrent.futures

            with concurrent.futures.ProcessPoolExecutor(
                    max_workers=params.indexing.nproc) as pool:
                futures = []
                for i_expt, expt in enumerate(experiments):
                    refl = reflections.select(
                        reflections["imageset_id"] == i_expt)
                    refl["imageset_id"] = flex.size_t(len(refl), 0)
                    futures.append(
                        pool.submit(
                            index_experiments,
                            ExperimentList([expt]),
                            refl,
                            copy.deepcopy(params),
                            known_crystal_models=known_crystal_models,
                        ))

                for future in concurrent.futures.as_completed(futures):
                    try:
                        idx_expts, idx_refl = future.result()
                    except Exception as e:
                        print(e)
                    else:
                        if idx_expts is None:
                            continue
                        for j_expt, _ in enumerate(idx_expts):
                            sel = idx_refl["id"] == j_expt
                            idx_refl["id"].set_selected(
                                sel,
                                len(self._indexed_experiments) + j_expt)
                        idx_refl["imageset_id"] = flex.size_t(
                            len(idx_refl), i_expt)
                        self._indexed_reflections.extend(idx_refl)
                        self._indexed_experiments.extend(idx_expts)