Пример #1
0
def load(entry, exp_index):
    from dxtbx.model.experiment_list import Experiment, ExperimentList

    print("Loading NXmx")

    # Check file contains the feature
    assert "features" in entry
    assert 6 in entry["features"][()]

    experiment_list = ExperimentList()

    # Find all the experiments
    entries = find_nx_mx_entries(entry, ".")
    if len(entries) > 1:
        entries = sorted(entries, key=lambda x: x["dials/index"][()])

    assert len(entries) == len(exp_index)
    for nxmx, name in zip(entries, exp_index):
        assert np.string_(nxmx.name) == name, (nxmx.name, name)

    index = []
    rotations = []
    for name in exp_index:

        # Get the entry
        nxmx = entry.file[name]

        # Get the definition
        definition = nxmx["definition"]
        assert definition[()] == "NXmx"
        assert definition.attrs["version"] == 1

        # Get dials specific stuff
        nx_dials = get_nx_dials(nxmx, "dials")

        # Set index
        b = nx_dials["index"].attrs["source"]
        d = nx_dials["index"].attrs["detector"]
        if "goniometer" in nx_dials["index"].attrs:
            g = nx_dials["index"].attrs["goniometer"]
        else:
            g = None
        if "scan" in nx_dials["index"].attrs:
            s = nx_dials["index"].attrs["scan"]
        else:
            s = None
        c = nx_dials["index"].attrs["sample"]
        index.append((b, d, g, s, c))

        # Get the original orientation (dials specific)
        transformations = get_nx_transformations(nx_dials, "transformations")
        angle = transformations["angle"][()]
        assert transformations["angle"].attrs[
            "transformation_type"] == "rotation"
        axis = transformations["angle"].attrs["vector"]
        assert tuple(transformations["angle"].attrs["offset"]) == (0, 0, 0)
        assert transformations["angle"].attrs["offset_units"] == "mm"
        assert transformations["angle"].attrs["depends_on"] == "."
        rotations.append((axis, angle))

        # Get the imageset
        try:
            image_range = nx_dials["template"].attrs["range"]
        except Exception:
            image_range = None

        # Create the experiment
        experiment = Experiment()

        # Read the models
        experiment.beam = load_beam(nxmx)
        experiment.detector = load_detector(nxmx)
        experiment.goniometer = load_goniometer(nxmx)
        experiment.scan = load_scan(nxmx)
        experiment.crystal = load_crystal(nxmx)

        # Set the image range
        if image_range is not None and experiment.scan is not None:
            num = image_range[1] - image_range[0] + 1
            assert num == len(experiment.scan)
            experiment.scan.set_image_range([int(x) for x in image_range])

        # Return the experiment list
        experiment_list.append(experiment)

    # Convert from nexus beam direction
    experiment_list = convert_from_nexus_beam_direction(
        experiment_list, rotations)

    beam = collections.defaultdict(list)
    detector = collections.defaultdict(list)
    goniometer = collections.defaultdict(list)
    scan = collections.defaultdict(list)
    crystal = collections.defaultdict(list)
    for i, ind in enumerate(index):
        beam[ind[0]].append(i)
        detector[ind[1]].append(i)
        goniometer[ind[2]].append(i)
        scan[ind[3]].append(i)
        crystal[ind[4]].append(i)

    # Set all the shared beams
    for value in beam.values():
        b1 = experiment_list[value[0]].beam
        assert all(experiment_list[v].beam == b1 for v in value[1:])
        for v in value[1:]:
            experiment_list[v].beam = b1
    # Set all the shared detectors
    for value in detector.values():
        d1 = experiment_list[value[0]].detector
        assert all(experiment_list[v].detector == d1 for v in value[1:])
        for v in value[1:]:
            experiment_list[v].detector = d1
    # Set all the shared goniometer
    for value in goniometer.values():
        g1 = experiment_list[value[0]].goniometer
        assert all(experiment_list[v].goniometer == g1 for v in value[1:])
        for v in value[1:]:
            experiment_list[v].goniometer = g1
    # Set all the shared scans
    for value in scan.values():
        s1 = experiment_list[value[0]].scan
        assert all(experiment_list[v].scan == s1 for v in value[1:])
        for v in value[1:]:
            experiment_list[v].scan = s1
    # Set all the shared crystals
    for value in crystal.values():
        c1 = experiment_list[value[0]].crystal
        assert all(experiment_list[v].crystal == c1 for v in value[1:])
        for v in value[1:]:
            experiment_list[v].crystal = c1

    return experiment_list
Пример #2
0
    def split_for_scan_range(self, experiments, reference, scan_range):
        ''' Update experiments when scan range is set. '''
        from dxtbx.model.experiment_list import ExperimentList
        from dxtbx.model.experiment_list import Experiment
        from dials.array_family import flex

        # Only do anything is the scan range is set
        if scan_range is not None and len(scan_range) > 0:

            # Ensure that all experiments have the same imageset and scan
            iset = [e.imageset for e in experiments]
            scan = [e.scan for e in experiments]
            assert (all(x == iset[0] for x in iset))
            assert (all(x == scan[0] for x in scan))

            # Get the imageset and scan
            iset = experiments[0].imageset
            scan = experiments[0].scan

            # Get the array range
            if scan is not None:
                frame10, frame11 = scan.get_array_range()
                assert (scan.get_num_images() == len(iset))
            else:
                frame10, frame11 = (0, len(iset))

            # Create the new lists
            new_experiments = ExperimentList()
            new_reference_all = reference.split_by_experiment_id()
            new_reference = flex.reflection_table()
            for i in range(len(new_reference_all) - len(experiments)):
                new_reference_all.append(flex.reflection_table())
            assert (len(new_reference_all) == len(experiments))

            # Loop through all the scan ranges and create a new experiment list with
            # the requested scan ranges.
            for frame00, frame01 in scan_range:
                assert (frame01 > frame00)
                assert (frame00 >= frame10)
                assert (frame01 <= frame11)
                index0 = frame00 - frame10
                index1 = index0 + (frame01 - frame00)
                assert (index0 < index1)
                assert (index0 >= 0)
                assert (index1 <= len(iset))
                new_iset = iset[index0:index1]
                if scan is None:
                    new_scan = None
                else:
                    new_scan = scan[index0:index1]
                for i, e1 in enumerate(experiments):
                    e2 = Experiment()
                    e2.beam = e1.beam
                    e2.detector = e1.detector
                    e2.goniometer = e1.goniometer
                    e2.crystal = e1.crystal
                    e2.imageset = new_iset
                    e2.scan = new_scan
                    new_reference_all[i]['id'] = flex.int(
                        len(new_reference_all[i]), len(new_experiments))
                    new_reference.extend(new_reference_all[i])
                    new_experiments.append(e2)
            experiments = new_experiments
            reference = new_reference

            # Print some information
            logger.info(
                'Modified experiment list to integrate over requested scan range'
            )
            for frame00, frame01 in scan_range:
                logger.info(' scan_range = %d -> %d' % (frame00, frame01))
            logger.info('')

        # Return the experiments
        return experiments, reference
Пример #3
0
    def split_for_scan_range(self, experiments, reference, scan_range):
        """ Update experiments when scan range is set. """
        from dxtbx.model.experiment_list import ExperimentList
        from dxtbx.model.experiment_list import Experiment

        # Only do anything is the scan range is set
        if scan_range is not None and len(scan_range) > 0:

            # Ensure that all experiments have the same imageset and scan
            iset = [e.imageset for e in experiments]
            scan = [e.scan for e in experiments]
            assert all(x == iset[0] for x in iset)
            assert all(x == scan[0] for x in scan)

            # Get the imageset and scan
            iset = experiments[0].imageset
            scan = experiments[0].scan

            # Get the array range
            if scan is not None:
                frames_start, frames_end = scan.get_array_range()
                assert scan.get_num_images() == len(iset)
            else:
                frames_start, frames_end = (0, len(iset))

            # Create the new lists
            new_experiments = ExperimentList()
            new_reference_all = reference.split_by_experiment_id()
            new_reference = flex.reflection_table()
            for i in range(len(new_reference_all) - len(experiments)):
                new_reference_all.append(flex.reflection_table())
            assert len(new_reference_all) == len(experiments)

            # Loop through all the scan ranges and create a new experiment list with
            # the requested scan ranges.
            for scan_start, scan_end in scan_range:
                # Validate the requested scan range
                if scan_end == scan_start:
                    raise Sorry(
                        "Scan range end must be higher than start; pass {},{} for single image"
                        .format(scan_start, scan_start + 1))
                if scan_end < scan_start:
                    raise Sorry("Scan range must be in ascending order")
                elif scan_start < frames_start or scan_end > frames_end:
                    raise Sorry(
                        "Scan range must be within image range {}..{}".format(
                            frames_start, frames_end))

                assert scan_end > scan_start
                assert scan_start >= frames_start
                assert scan_end <= frames_end

                index_start = scan_start - frames_start
                index_end = index_start + (scan_end - scan_start)
                assert index_start < index_end
                assert index_start >= 0
                assert index_end <= len(iset)
                new_iset = iset[index_start:index_end]
                if scan is None:
                    new_scan = None
                else:
                    new_scan = scan[index_start:index_end]
                for i, e1 in enumerate(experiments):
                    e2 = Experiment()
                    e2.beam = e1.beam
                    e2.detector = e1.detector
                    e2.goniometer = e1.goniometer
                    e2.crystal = e1.crystal
                    e2.profile = e1.profile
                    e2.imageset = new_iset
                    e2.scan = new_scan
                    new_reference_all[i]["id"] = flex.int(
                        len(new_reference_all[i]), len(new_experiments))
                    new_reference.extend(new_reference_all[i])
                    new_experiments.append(e2)
            experiments = new_experiments
            reference = new_reference

            # Print some information
            logger.info(
                "Modified experiment list to integrate over requested scan range"
            )
            for scan_start, scan_end in scan_range:
                logger.info(" scan_range = %d -> %d" % (scan_start, scan_end))
            logger.info("")

        # Return the experiments
        return experiments, reference
Пример #4
0
def load(entry, exp_index):
    from dxtbx.model.experiment_list import ExperimentList
    from dxtbx.model.experiment_list import Experiment

    print "Loading NXmx"

    # Check file contains the feature
    assert ("features" in entry)
    assert (6 in entry['features'].value)

    experiment_list = ExperimentList()

    # Find all the experiments
    entries = find_nx_mx_entries(entry, ".")
    if len(entries) > 1:
        entries = sorted(entries, key=lambda x: x['dials/index'].value)

    assert (len(entries) == len(exp_index))
    for nxmx, name in zip(entries, exp_index):
        assert (nxmx.name == name)

    index = []
    rotations = []
    for name in exp_index:

        # Get the entry
        nxmx = entry.file[name]

        # Get the definition
        definition = nxmx['definition']
        assert (definition.value == 'NXmx')
        assert (definition.attrs['version'] == 1)

        # Get dials specific stuff
        nx_dials = get_nx_dials(nxmx, "dials")

        # Set index
        b = nx_dials['index'].attrs['source']
        d = nx_dials['index'].attrs['detector']
        if "goniometer" in nx_dials['index'].attrs:
            g = nx_dials['index'].attrs['goniometer']
        else:
            g = None
        if "scan" in nx_dials['index'].attrs:
            s = nx_dials['index'].attrs['scan']
        else:
            s = None
        c = nx_dials['index'].attrs['sample']
        index.append((b, d, g, s, c))

        # Get the original orientation (dials specific)
        transformations = get_nx_transformations(nx_dials, "transformations")
        angle = transformations['angle'].value
        assert (transformations['angle'].attrs['transformation_type'] ==
                'rotation')
        axis = transformations['angle'].attrs['vector']
        assert (tuple(transformations['angle'].attrs['offset']) == (0, 0, 0))
        assert (transformations['angle'].attrs['offset_units'] == 'mm')
        assert (transformations['angle'].attrs['depends_on'] == '.')
        rotations.append((axis, angle))

        # Get the tmeplate and imageset
        try:
            template = list(nx_dials['template'])
            image_range = None
        except Exception:
            template = nx_dials['template'].value
            if template == "":
                template = None
            if "range" in nx_dials['template'].attrs:
                image_range = nx_dials['template'].attrs['range']
            else:
                image_range = None

        # Create the experiment
        experiment = Experiment()

        # Read the models
        experiment.beam = load_beam(nxmx)
        experiment.detector = load_detector(nxmx)
        experiment.goniometer = load_goniometer(nxmx)
        experiment.scan = load_scan(nxmx)
        experiment.crystal = load_crystal(nxmx)

        # Set the image range
        if image_range is not None and experiment.scan is not None:
            num = image_range[1] - image_range[0] + 1
            assert (num == len(experiment.scan))
            experiment.scan.set_image_range(image_range)

        # Return the experiment list
        experiment_list.append(experiment)

    # Convert from nexus beam direction
    experiment_list = convert_from_nexus_beam_direction(
        experiment_list, rotations)

    from collections import defaultdict
    beam = defaultdict(list)
    detector = defaultdict(list)
    goniometer = defaultdict(list)
    scan = defaultdict(list)
    crystal = defaultdict(list)
    for i, ind in enumerate(index):
        beam[ind[0]].append(i)
        detector[ind[1]].append(i)
        goniometer[ind[2]].append(i)
        scan[ind[3]].append(i)
        crystal[ind[4]].append(i)

    # Set all the shared beams
    for key, value in beam.iteritems():
        b1 = experiment_list[value[0]].beam
        assert (all(experiment_list[v].beam == b1 for v in value[1:]))
        for v in value[1:]:
            experiment_list[v].beam = b1
    # Set all the shared detectors
    for key, value in detector.iteritems():
        d1 = experiment_list[value[0]].detector
        assert (all(experiment_list[v].detector == d1 for v in value[1:]))
        for v in value[1:]:
            experiment_list[v].detector = d1
    # Set all the shared goniometer
    for key, value in goniometer.iteritems():
        g1 = experiment_list[value[0]].goniometer
        assert (all(experiment_list[v].goniometer == g1 for v in value[1:]))
        for v in value[1:]:
            experiment_list[v].goniometer = g1
    # Set all the shared scans
    for key, value in scan.iteritems():
        s1 = experiment_list[value[0]].scan
        assert (all(experiment_list[v].scan == s1 for v in value[1:]))
        for v in value[1:]:
            experiment_list[v].scan = s1
    # Set all the shared crystals
    for key, value in crystal.iteritems():
        c1 = experiment_list[value[0]].crystal
        assert (all(experiment_list[v].crystal == c1 for v in value[1:]))
        for v in value[1:]:
            experiment_list[v].crystal = c1

    return experiment_list