def tst_consistent(self):

    from dxtbx.imageset import ImageSetFactory
    from glob import glob
    from os.path import join
    from dxtbx.model import Scan

    # Create a sweep
    sweep_filenames = join(self.path, 'centroid_test_data', 'centroid*.cbf')
    sweep = ImageSetFactory.new(sorted(glob(sweep_filenames)))[0]

    # Create experiment with sweep and good scan
    e = Experiment(imageset=sweep, scan=sweep.get_scan())
    assert(e.is_consistent())

    # Create experiment with sweep and defective scan
    scan = sweep.get_scan()
    scan.set_image_range((1, 1))
    e = Experiment(imageset=sweep, scan=scan)
    #assert(not e.is_consistent()) # FIXME

    ## Create experiment with imageset and good scan
    #assert(e.is_consistent())

    ## Create experiment with imageset and non-still scan
    #assert(not e.is_consistent())

    ## Create experiment with imageset and scan with more than 1 image
    #assert(not e.is_consistent())

    ## Create experiment with imageset and defective scan
    #assert(not e.is_consistent())

    # Test passed
    print 'OK'
Beispiel #2
0
def generate_spots(crystal_model, detector, beam, goniometer=None, scan=None,
                   sel_fraction=1.0):
  import math

  experiment = Experiment(beam=beam,
                          detector=detector,
                          goniometer=goniometer,
                          scan=scan,
                          crystal=crystal_model)

  # if we don't set the imageset then from_predictions uses the StillsReflectionPredictor :-(
  from dxtbx.imageset import NullReader, ImageSweep
  imageset = ImageSweep(NullReader, indices=range(len(scan.get_epochs())), beam=beam, goniometer=goniometer,
                        detector=detector, scan=scan)
  experiment.imageset = imageset

  predicted = flex.reflection_table.from_predictions(experiment)

  sel = flex.random_selection(len(predicted),
                              int(math.floor(sel_fraction*len(predicted))))
  predicted = predicted.select(sel)
  predicted['imageset_id'] = flex.size_t(len(predicted), 0)
  predicted['xyzobs.px.value'] = predicted['xyzcal.px']
  predicted['xyzobs.px.variance'] = flex.vec3_double(
    len(predicted), (0.5,0.5,0.5))
  return predicted
  def tst_consistent(self):

    from dxtbx.imageset import ImageSetFactory
    from glob import glob
    from os.path import join
    from dxtbx.model import Scan

    # Create a sweep
    sweep_filenames = join(self.path, 'centroid_test_data', 'centroid*.cbf')
    sweep = ImageSetFactory.new(sorted(glob(sweep_filenames)))[0]

    # Create experiment with sweep and good scan
    e = Experiment(imageset=sweep, scan=sweep.get_scan())
    assert(e.is_consistent())

    # Create experiment with sweep and defective scan
    scan = sweep.get_scan()
    scan.set_image_range((1, 1))
    e = Experiment(imageset=sweep, scan=scan)
    #assert(not e.is_consistent()) # FIXME

    ## Create experiment with imageset and good scan
    #assert(e.is_consistent())

    ## Create experiment with imageset and non-still scan
    #assert(not e.is_consistent())

    ## Create experiment with imageset and scan with more than 1 image
    #assert(not e.is_consistent())

    ## Create experiment with imageset and defective scan
    #assert(not e.is_consistent())

    # Test passed
    print 'OK'
Beispiel #4
0
def generate_spots(crystal_model,
                   detector,
                   beam,
                   goniometer=None,
                   scan=None,
                   sel_fraction=1.0):
    import math

    experiment = Experiment(beam=beam,
                            detector=detector,
                            goniometer=goniometer,
                            scan=scan,
                            crystal=crystal_model)

    # if we don't set the imageset then from_predictions uses the StillsReflectionPredictor :-(
    from dxtbx.imageset import NullReader, ImageSweep
    imageset = ImageSweep(NullReader,
                          indices=range(len(scan.get_epochs())),
                          beam=beam,
                          goniometer=goniometer,
                          detector=detector,
                          scan=scan)
    experiment.imageset = imageset

    predicted = flex.reflection_table.from_predictions(experiment)

    sel = flex.random_selection(len(predicted),
                                int(math.floor(sel_fraction * len(predicted))))
    predicted = predicted.select(sel)
    predicted['imageset_id'] = flex.size_t(len(predicted), 0)
    predicted['xyzobs.px.value'] = predicted['xyzcal.px']
    predicted['xyzobs.px.variance'] = flex.vec3_double(len(predicted),
                                                       (0.5, 0.5, 0.5))
    return predicted
Beispiel #5
0
    def predict_reflections(self):
        from dials.algorithms import shoebox
        from dials.array_family import flex
        from dxtbx.model.experiment.experiment_list import ExperimentList
        from dxtbx.model.experiment.experiment_list import Experiment
        from dials.algorithms.profile_model.gaussian_rs import Model

        # Get models from the sweep
        self.beam = self.sweep.get_beam()
        self.detector = self.sweep.get_detector()
        self.gonio = self.sweep.get_goniometer()
        self.scan = self.sweep.get_scan()

        sigma_b = self.beam.get_sigma_divergence(deg=True)
        sigma_m = self.crystal.get_mosaicity(deg=True)

        exlist = ExperimentList()
        exlist.append(
            Experiment(imageset=self.sweep,
                       beam=self.beam,
                       detector=self.detector,
                       goniometer=self.gonio,
                       scan=self.scan,
                       crystal=self.crystal,
                       profile=Model(None, 3, sigma_b, sigma_m, deg=True)))

        predicted = flex.reflection_table.from_predictions(exlist[0])
        predicted['id'] = flex.int(len(predicted), 0)
        predicted.compute_bbox(exlist)

        # Find overlapping reflections
        overlaps = shoebox.find_overlapping(predicted['bbox'])

        # Return the reflections and overlaps
        return predicted, overlaps
    def predict_once(args):
        from dxtbx.model.experiment.experiment_list import Experiment

        U = args[0]
        A = U * B
        direct_matrix = A.inverse()
        cryst_model = crystal_model(
            direct_matrix[0:3],
            direct_matrix[3:6],
            direct_matrix[6:9],
            space_group=space_group,
        )
        experiment = Experiment(
            imageset=sweep,
            beam=sweep.get_beam(),
            detector=sweep.get_detector(),
            goniometer=sweep.get_goniometer(),
            scan=sweep.get_scan(),
            crystal=cryst_model,
        )
        predicted_reflections = flex.reflection_table.from_predictions(experiment)
        miller_indices = predicted_reflections["miller_index"]
        miller_set = miller.set(crystal_symmetry, miller_indices, anomalous_flag=True)
        if params.d_min is not None:
            resolution_sel = miller_set.d_spacings().data() > params.d_min
            predicted_reflections = predicted_reflections.select(resolution_sel)
        return len(predicted_reflections)
Beispiel #7
0
    def __init__(self,
                 reflections,
                 crystal,
                 beam,
                 detector,
                 goniometer,
                 scan,
                 min_zeta=0.05):
        ''' Calculate the profile model. '''
        from dxtbx.model.experiment.experiment_list import Experiment
        from dials.array_family import flex
        from math import pi

        # Check input has what we want
        assert (reflections is not None)
        assert ("miller_index" in reflections)
        assert ("s1" in reflections)
        assert ("shoebox" in reflections)
        assert ("xyzobs.px.value" in reflections)
        assert ("xyzcal.mm" in reflections)

        # Calculate the E.S.D of the beam divergence
        logger.info('Calculating E.S.D Beam Divergence.')
        beam_divergence = ComputeEsdBeamDivergence(detector, reflections)

        # Set the sigma b
        self._sigma_b = beam_divergence.sigma()

        # FIXME Calculate properly
        if goniometer is None or scan is None or scan.get_oscillation(
        )[1] == 0:
            self._sigma_m = 0.0
        else:

            # Select by zeta
            zeta = reflections.compute_zeta(
                Experiment(crystal=crystal,
                           beam=beam,
                           detector=detector,
                           goniometer=goniometer,
                           scan=scan))
            mask = flex.abs(zeta) >= min_zeta
            reflections = reflections.select(mask)

            # Calculate the E.S.D of the reflecting range
            logger.info('Calculating E.S.D Reflecting Range.')
            reflecting_range = ComputeEsdReflectingRange(
                crystal, beam, detector, goniometer, scan, reflections)

            # Set the sigmas
            self._sigma_m = reflecting_range.sigma()

        # Print the output
        logger.info(' sigma b: %f degrees' % (self._sigma_b * 180 / pi))
        logger.info(' sigma m: %f degrees' % (self._sigma_m * 180 / pi))
Beispiel #8
0
 def experiment_list_for_crystal(self, crystal):
     experiments = ExperimentList()
     for imageset in self.imagesets:
         experiments.append(
             Experiment(imageset=imageset,
                        beam=imageset.get_beam(),
                        detector=imageset.get_detector(),
                        goniometer=imageset.get_goniometer(),
                        scan=imageset.get_scan(),
                        crystal=crystal))
     return experiments
  def tst_equality(self):

    from dxtbx.model import Beam, Detector, Goniometer, Scan
    from dxtbx.model.crystal import crystal_model

    # Create a load of models
    b1 = Beam()
    d1 = Detector()
    g1 = Goniometer()
    s1 = Scan()
    c1 = crystal_model((1, 0, 0), (0, 1, 0), (0, 0, 1), 0)

    # Create a load of models that look the same but aren't
    b2 = Beam()
    d2 = Detector()
    g2 = Goniometer()
    s2 = Scan()
    c2 = crystal_model((1, 0, 0), (0, 1, 0), (0, 0, 1), 0)

    # Create an experiment
    e1 = Experiment(
      beam=b1, detector=d1, goniometer=g1,
      scan=s1, crystal=c1, imageset=None)

    # Create an experiment
    e2 = Experiment(
      beam=b1, detector=d1, goniometer=g1,
      scan=s1, crystal=c1, imageset=None)

    # Create an experiment
    e3 = Experiment(
      beam=b2, detector=d2, goniometer=g2,
      scan=s2, crystal=c2, imageset=None)

    # Check e1 equals e2 but not e3
    assert(e1 == e2)
    assert(e1 != e3)
    assert(e2 != e3)

    # Test passed
    print 'OK'
Beispiel #10
0
class Test(object):
    def __init__(self):
        import os
        import libtbx.load_env
        from dxtbx.serialize.load import crystal as load_crystal
        from dials.model.serialize import load
        from dials.algorithms.profile_model.gaussian_rs import Model
        from dials.algorithms.profile_model.gaussian_rs import MaskCalculator3D
        from dxtbx.model.experiment.experiment_list import Experiment, ExperimentList

        try:
            dials_regression = libtbx.env.dist_path('dials_regression')
        except KeyError, e:
            print 'FAIL: dials_regression not configured'
            exit(0)

        # Set the sweep filename and load the sweep
        sweep_filename = os.path.join(dials_regression, 'centroid_test_data',
                                      'sweep.json')
        crystal_filename = os.path.join(dials_regression, 'centroid_test_data',
                                        'crystal.json')

        # Load the sweep
        self.sweep = load.sweep(sweep_filename)
        self.crystal = load_crystal(crystal_filename)
        self.beam = self.sweep.get_beam()
        self.detector = self.sweep.get_detector()
        self.goniometer = self.sweep.get_goniometer()
        self.scan = self.sweep.get_scan()
        self.delta_d = 3 * self.beam.get_sigma_divergence(deg=False)
        self.delta_m = 3 * self.crystal.get_mosaicity(deg=False)
        self.nsigma = 3
        self.profile_model = Model(None, self.nsigma,
                                   self.beam.get_sigma_divergence(deg=False),
                                   self.crystal.get_mosaicity(deg=False))
        self.experiment = ExperimentList()
        self.experiment.append(
            Experiment(imageset=self.sweep,
                       beam=self.beam,
                       detector=self.detector,
                       goniometer=self.goniometer,
                       scan=self.scan,
                       crystal=self.crystal,
                       profile=self.profile_model))

        assert (len(self.detector) == 1)

        # Get the function object to mask the foreground
        self.mask_foreground = MaskCalculator3D(self.beam, self.detector,
                                                self.goniometer, self.scan,
                                                self.delta_d, self.delta_m)
Beispiel #11
0
  def __init__(self, test_nave_model = False):

    # Set up experimental models with regular geometry
    from dxtbx.model.experiment import beam_factory
    from dxtbx.model.experiment import goniometer_factory
    from dxtbx.model.experiment import detector_factory

    from dxtbx.model.crystal import crystal_model

    # Beam along the Z axis
    self.beam = beam_factory.make_beam(unit_s0 = matrix.col((0, 0, 1)),
                                       wavelength = 1.0)

    # Goniometer (used only for index generation) along X axis
    self.goniometer = goniometer_factory.known_axis(matrix.col((1, 0, 0)))

    # Detector fast, slow along X, -Y; beam in the centre, 200 mm distance
    dir1 = matrix.col((1, 0, 0))
    dir2 = matrix.col((0, -1, 0))
    n = matrix.col((0, 0, 1))
    centre = matrix.col((0, 0, 200))
    npx_fast = npx_slow = 1000
    pix_size = 0.2
    origin = centre - (0.5 * npx_fast * pix_size * dir1 +
                       0.5 * npx_slow * pix_size * dir2)
    self.detector = detector_factory.make_detector("PAD",
                        dir1, dir2, origin,
                        (pix_size, pix_size),
                        (npx_fast, npx_slow),
                        (0, 1.e6))

    # Cubic 100 A^3 crystal
    a = matrix.col((100, 0, 0))
    b = matrix.col((0, 100, 0))
    c = matrix.col((0, 0, 100))
    self.crystal = crystal_model(a, b, c, space_group_symbol = "P 1")

    if test_nave_model:
      self.crystal._ML_half_mosaicity_deg = 500
      self.crystal._ML_domain_size_ang = 0.2

    # Collect these models in an Experiment (ignoring the goniometer)
    from dxtbx.model.experiment.experiment_list import Experiment
    self.experiment = Experiment(beam=self.beam, detector=self.detector,
      goniometer=None, scan=None, crystal=self.crystal, imageset=None)

    # Generate some reflections
    self.reflections = self.generate_reflections()

    return
Beispiel #12
0
 def find_lattices(self):
     self.real_space_grid_search()
     crystal_models = self.candidate_crystal_models
     experiments = ExperimentList()
     for cm in crystal_models:
         for imageset in self.imagesets:
             experiments.append(
                 Experiment(imageset=imageset,
                            beam=imageset.get_beam(),
                            detector=imageset.get_detector(),
                            goniometer=imageset.get_goniometer(),
                            scan=imageset.get_scan(),
                            crystal=cm))
     return experiments
Beispiel #13
0
    def combine_crystals(experiments):
        '''Replace all crystals in the experiments list with the first crystal'''

        from dxtbx.model.experiment.experiment_list import Experiment, ExperimentList
        new_experiments = ExperimentList()
        ref_crystal = experiments[0].crystal
        for exp in experiments:
            new_experiments.append(
                Experiment(beam=exp.beam,
                           detector=exp.detector,
                           scan=exp.scan,
                           goniometer=exp.goniometer,
                           crystal=ref_crystal,
                           imageset=exp.imageset))
        return new_experiments
Beispiel #14
0
 def find_lattices(self):
     experiments = ExperimentList()
     for cm in self.known_orientations:
         # indexer expects crystals to be in primitive setting
         space_group = cm.get_space_group()
         cb_op_to_primitive \
           = space_group.info().change_of_basis_op_to_primitive_setting()
         cm = cm.change_basis(cb_op_to_primitive)
         for imageset in self.imagesets:
             experiments.append(
                 Experiment(imageset=imageset,
                            beam=imageset.get_beam(),
                            detector=imageset.get_detector(),
                            goniometer=imageset.get_goniometer(),
                            scan=imageset.get_scan(),
                            crystal=cm))
     return experiments
  def tst_index(self):

    # Check the indices of exisiting experiments
    assert(self.el.index(self.el[0]) is 0)
    assert(self.el.index(self.el[1]) is 1)
    assert(self.el.index(self.el[2]) is 2)
    assert(self.el.index(self.el[3]) is 1)
    assert(self.el.index(self.el[4]) is 0)

    # Check index of non exisiting experiment
    try:
      self.el.index(Experiment())
      assert(False)
    except ValueError:
      pass

    # Test passed
    print 'OK'
  def create_models(self, cmdline_overrides=None):

    if cmdline_overrides is None:
      cmdline_overrides = []
    overrides = """geometry.parameters.crystal.a.length.range = 10 50
geometry.parameters.crystal.b.length.range = 10 50
geometry.parameters.crystal.c.length.range = 10 50"""

    master_phil = parse("""
    include scope dials.test.algorithms.refinement.geometry_phil
    """, process_includes=True)

    # Extract models
    models = Extract(master_phil, overrides, cmdline_args = cmdline_overrides)
    self.detector = models.detector
    self.goniometer = models.goniometer
    self.crystal = models.crystal
    self.beam = models.beam

    # Make a scan of 1-360 * 0.5 deg images
    sf = scan_factory()
    self.scan = sf.make_scan((1,360), 0.5, (0, 0.5), range(360))

    # Generate an ExperimentList
    self.experiments = ExperimentList()
    self.experiments.append(Experiment(
          beam=self.beam, detector=self.detector, goniometer=self.goniometer,
          scan=self.scan, crystal=self.crystal, imageset=None))

    # Create a reflection predictor for the experiments
    self.ref_predictor = ExperimentsPredictor(self.experiments)

    # Create scan-varying parameterisations of these models, with 5 samples
    self.det_param = ScanVaryingDetectorParameterisationSinglePanel(
            self.detector, self.scan.get_array_range(), 5)
    self.s0_param = ScanVaryingBeamParameterisation(
            self.beam, self.scan.get_array_range(), 5, self.goniometer)
    self.xlo_param = ScanVaryingCrystalOrientationParameterisation(
            self.crystal, self.scan.get_array_range(), 5)
    self.xluc_param = ScanVaryingCrystalUnitCellParameterisation(
            self.crystal, self.scan.get_array_range(), 5)
    return
  def generate(self):
    from dxtbx.model import Beam, Detector, Goniometer, Scan

    # Initialise a list of experiments
    experiments = ExperimentList()

    # Create a few beams
    b1 = Beam()
    b2 = Beam()
    b3 = Beam()

    # Create a few detectors
    d1 = Detector()
    d2 = Detector()
    d3 = Detector()

    # Create a few goniometers
    g1 = Goniometer()
    g2 = Goniometer()
    g3 = Goniometer()

    # Create a few scans
    s1 = Scan()
    s2 = Scan()
    s3 = Scan()

    # Create a list of models
    b = [b1, b2, b3, b2, b1]
    d = [d1, d2, d3, d2, d1]
    g = [g1, g2, g3, g2, g1]
    s = [s1, s2, s3, s2, s1]

    # Populate with various experiments
    for i in range(5):
      experiments.append(Experiment(
        beam=b[i],
        detector=d[i],
        goniometer=g[i],
        scan=s[i]))

    # Return the list of experiments
    return experiments
  def tst_contains(self):
    from dxtbx.model import Beam, Detector, Goniometer, Scan
    from dxtbx.model.crystal import crystal_model

    # Create a load of models
    b1 = Beam()
    d1 = Detector()
    g1 = Goniometer()
    s1 = Scan()
    c1 = crystal_model((1, 0, 0), (0, 1, 0), (0, 0, 1), 0)

    # Create an experiment
    e = Experiment(
      beam=b1, detector=d1, goniometer=g1,
      scan=s1, crystal=c1, imageset=None)

    # Check experiment contains model
    assert(b1 in e)
    assert(d1 in e)
    assert(g1 in e)
    assert(s1 in e)
    assert(c1 in e)

    # Create a load of models that look the same but aren't
    b2 = Beam()
    d2 = Detector()
    g2 = Goniometer()
    s2 = Scan()
    c2 = crystal_model((1, 0, 0), (0, 1, 0), (0, 0, 1), 0)

    # Check experiment doesn't contain model
    assert(b2 not in e)
    assert(d2 not in e)
    assert(g2 not in e)
    assert(s2 not in e)
    assert(c2 not in e)

    # Test passed
    print 'OK'
  def prepare_dxtbx_models(self,setting_specific_ai,sg,isoform=None):

    from dxtbx.model.beam import beam_factory
    beam = beam_factory.simple(wavelength = self.inputai.wavelength)

    from dxtbx.model.detector import detector_factory
    detector = detector_factory.simple(
      sensor = detector_factory.sensor("PAD"),
      distance = setting_specific_ai.distance(),
      beam_centre = [setting_specific_ai.xbeam(), setting_specific_ai.ybeam()],
      fast_direction = "+x",
      slow_direction = "+y",
      pixel_size = [self.pixel_size,self.pixel_size],
      image_size = [self.inputpd['size1'],self.inputpd['size1']],
      )

    direct = matrix.sqr(setting_specific_ai.getOrientation().direct_matrix())
    from dxtbx.model.crystal import crystal_model
    crystal = crystal_model(
      real_space_a = matrix.row(direct[0:3]),
      real_space_b = matrix.row(direct[3:6]),
      real_space_c = matrix.row(direct[6:9]),
      space_group_symbol = sg,
      mosaicity = setting_specific_ai.getMosaicity()
    )
    if isoform is not None:
      newB = matrix.sqr(isoform.fractionalization_matrix()).transpose()
      crystal.set_B(newB)

    from dxtbx.model.experiment.experiment_list import Experiment, ExperimentList
    experiments = ExperimentList()
    experiments.append(Experiment(beam=beam,
                                  detector=detector,
                                  crystal=crystal))

    print beam
    print detector
    print crystal
    return experiments
def setup_models(args):
    """setup the experimental models"""

    # Setup experimental models
    master_phil = parse("""
      include scope dials.test.algorithms.refinement.geometry_phil
      """,
                        process_includes=True)

    models = setup_geometry.Extract(master_phil, cmdline_args=args)

    detector = models.detector
    goniometer = models.goniometer
    crystal = models.crystal
    beam = models.beam

    # Build a mock scan for a 180 degree sweep
    sf = scan_factory()
    scan = sf.make_scan(image_range=(1, 180),
                        exposure_times=0.1,
                        oscillation=(0, 1.0),
                        epochs=range(180),
                        deg=True)
    sweep_range = scan.get_oscillation_range(deg=False)
    im_width = scan.get_oscillation(deg=False)[1]
    assert sweep_range == (0., pi)
    assert approx_equal(im_width, 1.0 * pi / 180.)

    experiments = ExperimentList()
    experiments.append(
        Experiment(beam=beam,
                   detector=detector,
                   goniometer=goniometer,
                   scan=scan,
                   crystal=crystal,
                   imageset=None))

    return experiments
Beispiel #21
0
    def generate_reflections(self):

        # Build a mock scan for a 3 degree sweep
        from dxtbx.model.scan import scan_factory
        sf = scan_factory()
        self.scan = sf.make_scan(image_range=(1, 1),
                                 exposure_times=0.1,
                                 oscillation=(0, 3.0),
                                 epochs=range(1),
                                 deg=True)
        sweep_range = self.scan.get_oscillation_range(deg=False)

        # Create a scans ExperimentList, only for generating reflections
        experiments = ExperimentList()
        experiments.append(
            Experiment(beam=self.beam,
                       detector=self.detector,
                       goniometer=self.gonio,
                       scan=self.scan,
                       crystal=self.crystal,
                       imageset=None))

        # Create a ScansRayPredictor
        ray_predictor = ScansRayPredictor(experiments, sweep_range)

        # Generate rays - only to work out which hkls are predicted
        resolution = 2.0
        index_generator = IndexGenerator(
            self.crystal.get_unit_cell(),
            space_group(space_group_symbols(1).hall()).type(), resolution)
        indices = index_generator.to_array()
        rays = ray_predictor(indices)

        # Make a standard reflection_table and copy in the ray data
        self.reflections = flex.reflection_table.empty_standard(len(rays))
        self.reflections.update(rays)

        return
Beispiel #22
0
    def find_lattices(self):
        self.d_min = self.params.refinement_protocol.d_min_start

        from rstbx.phil.phil_preferences import indexing_api_defs
        import iotbx.phil
        hardcoded_phil = iotbx.phil.parse(
            input_string=indexing_api_defs).extract()

        sel = (self.reflections['id'] == -1)
        if self.d_min is not None:
            sel &= (1 / self.reflections['rlp'].norms() > self.d_min)
        reflections = self.reflections.select(sel)
        solutions = candidate_basis_vectors_fft1d(
            reflections['rlp'], hardcoded_phil, max_cell=self.params.max_cell)
        self.candidate_basis_vectors = solutions[0]
        self.debug_show_candidate_basis_vectors()
        if self.params.debug_plots:
            self.debug_plot_candidate_basis_vectors()
        self.candidate_crystal_models = self.find_candidate_orientation_matrices(
            self.candidate_basis_vectors,
            max_combinations=self.params.basis_vector_combinations.max_try)
        crystal_model, n_indexed = self.choose_best_orientation_matrix(
            self.candidate_crystal_models)
        if crystal_model is not None:
            crystal_models = [crystal_model]
        else:
            crystal_models = []
        experiments = ExperimentList()
        for cm in crystal_models:
            for imageset in self.imagesets:
                experiments.append(
                    Experiment(imageset=imageset,
                               beam=imageset.get_beam(),
                               detector=imageset.get_detector(),
                               goniometer=imageset.get_goniometer(),
                               scan=imageset.get_scan(),
                               crystal=cm))
        return experiments
Beispiel #23
0
def get_random_predictions():
    """Return a DIALS reflection table representing predictions using the given models.
    Assumes a Ewald proximity model for mosaicity"""
    # The U matrix to calculate A*
    rot = flex.random_double_r3_rotation_matrix()
    A = sqr(rot) * sqr(uc.reciprocal().orthogonalization_matrix())
    A_inv = A.inverse()

    # Use the matrix to create a crystal model
    a = col(A_inv[:3])
    b = col(A_inv[3:6])
    c = col(A_inv[6:])
    cm = crystal_model(a, b, c, space_group=spgrp)

    # This DIALS object has no gonio or scan which will identify it as a still
    expt = Experiment(beam=beam,
                      detector=detector,
                      goniometer=None,
                      scan=None,
                      crystal=cm)

    # Predict the reflections
    return flex.reflection_table.from_predictions(expt)
Beispiel #24
0
    def create_models(self):

        # build models, with a larger crystal than default in order to get plenty of
        # reflections on the 'still' image
        overrides = """
    geometry.parameters.crystal.a.length.range=40 50;
    geometry.parameters.crystal.b.length.range=40 50;
    geometry.parameters.crystal.c.length.range=40 50;
    geometry.parameters.random_seed = 42"""

        master_phil = parse("""
        include scope dials.test.algorithms.refinement.geometry_phil
        """,
                            process_includes=True)

        models = Extract(master_phil, overrides)

        # keep track of the models
        self.detector = models.detector
        self.gonio = models.goniometer
        self.crystal = models.crystal
        self.beam = models.beam

        # Create a stills ExperimentList
        self.stills_experiments = ExperimentList()
        self.stills_experiments.append(
            Experiment(beam=self.beam,
                       detector=self.detector,
                       crystal=self.crystal,
                       imageset=None))

        # keep track of the parameterisation of the models
        self.det_param = DetectorParameterisationSinglePanel(self.detector)
        self.s0_param = BeamParameterisation(self.beam, self.gonio)
        self.xlo_param = CrystalOrientationParameterisation(self.crystal)
        self.xluc_param = CrystalUnitCellParameterisation(self.crystal)
Beispiel #25
0
    def predict_reflections(self,
                            imageset,
                            crystal,
                            beam,
                            detector,
                            goniometer=None,
                            scan=None,
                            dmin=None,
                            dmax=None,
                            margin=1,
                            force_static=False,
                            **kwargs):
        '''
    Given an experiment, predict the reflections.

    :param crystal: The crystal model
    :param beam: The beam model
    :param detector: The detector model
    :param goniometer: The goniometer model
    :param scan: The scan model

    '''
        from dxtbx.model.experiment.experiment_list import Experiment
        from dials.algorithms.spot_prediction.reflection_predictor \
          import ReflectionPredictor
        predict = ReflectionPredictor(Experiment(imageset=imageset,
                                                 crystal=crystal,
                                                 beam=beam,
                                                 detector=detector,
                                                 goniometer=goniometer,
                                                 scan=scan),
                                      dmin=dmin,
                                      dmax=dmax,
                                      margin=margin,
                                      force_static=force_static)
        return predict()
Beispiel #26
0
    def split_for_scan_range(self, experiments, reference, scan_range):
        """ Update experiments when scan range is set. """
        from dxtbx.model.experiment.experiment_list import ExperimentList
        from dxtbx.model.experiment.experiment_list import Experiment
        from logging import info
        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
            info("Modified experiment list to integrate over requested scan range")
            for frame00, frame01 in scan_range:
                info(" scan_range = %d -> %d" % (frame00, frame01))
            info("")

        # Return the experiments
        return experiments, reference
Beispiel #27
0
    def __call__(self, crystal):

        return Experiment(beam=self.reference_beam,
                          detector=self.reference_detector,
                          crystal=crystal)
def test1():

    dials_regression = libtbx.env.find_in_repositories(
        relative_path="dials_regression", test=os.path.isdir)

    # use a datablock that contains a CS-PAD detector description
    data_dir = os.path.join(dials_regression, "refinement_test_data",
                            "hierarchy_test")
    datablock_path = os.path.join(data_dir, "datablock.json")
    assert os.path.exists(datablock_path)

    # load models
    from dxtbx.datablock import DataBlockFactory
    datablock = DataBlockFactory.from_serialized_format(datablock_path,
                                                        check_format=False)
    im_set = datablock[0].extract_imagesets()[0]
    from copy import deepcopy
    detector = deepcopy(im_set.get_detector())
    beam = im_set.get_beam()

    # we'll invent a crystal, goniometer and scan for this test
    from dxtbx.model.crystal import crystal_model
    crystal = crystal_model((40., 0., 0.), (0., 40., 0.), (0., 0., 40.),
                            space_group_symbol="P1")

    from dxtbx.model.experiment import goniometer_factory
    goniometer = goniometer_factory.known_axis((1., 0., 0.))

    # Build a mock scan for a 180 degree sweep
    from dxtbx.model.scan import scan_factory
    sf = scan_factory()
    scan = sf.make_scan(image_range=(1, 1800),
                        exposure_times=0.1,
                        oscillation=(0, 0.1),
                        epochs=range(1800),
                        deg=True)
    sweep_range = scan.get_oscillation_range(deg=False)
    im_width = scan.get_oscillation(deg=False)[1]
    assert sweep_range == (0., pi)
    assert approx_equal(im_width, 0.1 * pi / 180.)

    from dxtbx.model.experiment.experiment_list import ExperimentList, Experiment

    # Build an experiment list
    experiments = ExperimentList()
    experiments.append(
        Experiment(beam=beam,
                   detector=detector,
                   goniometer=goniometer,
                   scan=scan,
                   crystal=crystal,
                   imageset=None))

    # simulate some reflections
    refs, ref_predictor = generate_reflections(experiments)

    # move the detector quadrants apart by 2mm both horizontally and vertically
    from dials.algorithms.refinement.parameterisation \
      import DetectorParameterisationHierarchical
    det_param = DetectorParameterisationHierarchical(detector, level=1)
    det_p_vals = det_param.get_param_vals()
    p_vals = list(det_p_vals)
    p_vals[1] += 2
    p_vals[2] -= 2
    p_vals[7] += 2
    p_vals[8] += 2
    p_vals[13] -= 2
    p_vals[14] += 2
    p_vals[19] -= 2
    p_vals[20] -= 2
    det_param.set_param_vals(p_vals)

    # reparameterise the detector at the new perturbed geometry
    det_param = DetectorParameterisationHierarchical(detector, level=1)

    # parameterise other models
    from dials.algorithms.refinement.parameterisation.beam_parameters import \
        BeamParameterisation
    from dials.algorithms.refinement.parameterisation.crystal_parameters import \
        CrystalOrientationParameterisation, CrystalUnitCellParameterisation
    beam_param = BeamParameterisation(beam, goniometer)
    xlo_param = CrystalOrientationParameterisation(crystal)
    xluc_param = CrystalUnitCellParameterisation(crystal)

    # fix beam
    beam_param.set_fixed([True] * 3)

    # fix crystal
    xluc_param.set_fixed([True] * 6)
    xlo_param.set_fixed([True] * 3)

    # parameterisation of the prediction equation
    from dials.algorithms.refinement.parameterisation.prediction_parameters import \
        XYPhiPredictionParameterisation
    from dials.algorithms.refinement.parameterisation.parameter_report import \
        ParameterReporter
    pred_param = XYPhiPredictionParameterisation(experiments, [det_param],
                                                 [beam_param], [xlo_param],
                                                 [xluc_param])
    param_reporter = ParameterReporter([det_param], [beam_param], [xlo_param],
                                       [xluc_param])

    # reflection manager and target function
    from dials.algorithms.refinement.target import \
      LeastSquaresPositionalResidualWithRmsdCutoff
    from dials.algorithms.refinement.reflection_manager import ReflectionManager
    refman = ReflectionManager(refs, experiments, nref_per_degree=20)

    # set a very tight rmsd target of 1/10000 of a pixel
    target = LeastSquaresPositionalResidualWithRmsdCutoff(
        experiments,
        ref_predictor,
        refman,
        pred_param,
        restraints_parameterisation=None,
        frac_binsize_cutoff=0.0001)

    # minimisation engine
    from dials.algorithms.refinement.engine \
      import LevenbergMarquardtIterations as Refinery
    refinery = Refinery(target=target,
                        prediction_parameterisation=pred_param,
                        log=None,
                        verbosity=0,
                        track_step=False,
                        track_gradient=False,
                        track_parameter_correlation=False,
                        max_iterations=20)

    # Refiner
    from dials.algorithms.refinement.refiner import Refiner
    refiner = Refiner(reflections=refs,
                      experiments=experiments,
                      pred_param=pred_param,
                      param_reporter=param_reporter,
                      refman=refman,
                      target=target,
                      refinery=refinery,
                      verbosity=0)

    history = refiner.run()
    assert history.reason_for_termination == "RMSD target achieved"

    #compare detector with original detector
    orig_det = im_set.get_detector()
    refined_det = refiner.get_experiments()[0].detector

    from scitbx import matrix
    import math
    for op, rp in zip(orig_det, refined_det):
        # compare the origin vectors by...
        o1 = matrix.col(op.get_origin())
        o2 = matrix.col(rp.get_origin())
        # ...their relative lengths
        assert approx_equal(math.fabs(o1.length() - o2.length()) / o1.length(),
                            0,
                            eps=1e-5)
        # ...the angle between them
        assert approx_equal(o1.accute_angle(o2), 0, eps=1e-5)

    print "OK"
    return
  sf = scan_factory()
  myscan = sf.make_scan(image_range = (1,1800),
                        exposure_times = 0.1,
                        oscillation = (0, 0.1),
                        epochs = range(1800),
                        deg = True)
  sweep_range = myscan.get_oscillation_range(deg=False)
  im_width = myscan.get_oscillation(deg=False)[1]
  assert sweep_range == (0., pi)
  assert approx_equal(im_width, 0.1 * pi / 180.)

  # Build ExperimentLists
  experiments_single_panel = ExperimentList()
  experiments_multi_panel = ExperimentList()
  experiments_single_panel.append(Experiment(
        beam=mybeam, detector=single_panel_detector, goniometer=mygonio,
        scan=myscan, crystal=mycrystal, imageset=None))
  experiments_multi_panel.append(Experiment(
        beam=mybeam, detector=multi_panel_detector, goniometer=mygonio,
        scan=myscan, crystal=mycrystal, imageset=None))

  ###########################
  # Parameterise the models #
  ###########################

  det_param = DetectorParameterisationSinglePanel(single_panel_detector)
  s0_param = BeamParameterisation(mybeam, mygonio)
  xlo_param = CrystalOrientationParameterisation(mycrystal)
  xluc_param = CrystalUnitCellParameterisation(mycrystal)

  multi_det_param = DetectorParameterisationMultiPanel(multi_panel_detector, mybeam)
Beispiel #30
0
            (-float(fs_x.rstrip('x')), float(fs_y.rstrip('y')), 0.0))
        slow = matrix.col(
            (-float(ss_x.rstrip('x')), float(ss_y.rstrip('y')), 0.0))

        origin = matrix.col(
            (-float(geom[key]['corner_x']) * params.pixel_size,
             float(geom[key]['corner_y']) * params.pixel_size, 0.0))

        # OBS! you need to set the panel to a root before set local frame...
        p = root.add_panel()
        p.set_name('panel-%s' % key)
        p.set_image_size((512, 1024))
        p.set_trusted_range((-1, 1000000))
        p.set_pixel_size((params.pixel_size, params.pixel_size))
        p.set_local_frame(fast.elems, slow.elems, origin.elems)

    from dxtbx.model.beam import beam_factory
    wavelength = params.wavelength
    beam = beam_factory.simple(wavelength)

    from dxtbx.model.experiment.experiment_list import Experiment, ExperimentList, ExperimentListDumper
    experiments = ExperimentList()
    experiment = Experiment(detector=detector, beam=beam)
    experiments.append(experiment)
    dump = ExperimentListDumper(experiments)
    dump.as_json("geometry.json")


if __name__ == "__main__":
    run(sys.argv[1:])
Beispiel #31
0
def run(space_group_info):
  datablock_json = os.path.join(
    dials_regression, "indexing_test_data",
    "i04_weak_data", "datablock_orig.json")

  datablock = load.datablock(datablock_json, check_format=False)[0]
  sweep = datablock.extract_imagesets()[0]

  sweep._indices = sweep._indices[:20]
  sweep.set_scan(sweep.get_scan()[:20])

  import random
  space_group = space_group_info.group()
  unit_cell = space_group_info.any_compatible_unit_cell(volume=random.uniform(1e4,1e6))

  crystal_symmetry = crystal.symmetry(unit_cell=unit_cell,
                                      space_group=space_group)
  crystal_symmetry.show_summary()

  # the reciprocal matrix
  B = matrix.sqr(unit_cell.fractionalization_matrix()).transpose()
  U = random_rotation()
  A = U * B

  direct_matrix = A.inverse()
  cryst_model = crystal_model(direct_matrix[0:3],
                              direct_matrix[3:6],
                              direct_matrix[6:9],
                              space_group=space_group)
  experiment = Experiment(imageset=sweep,
                          beam=sweep.get_beam(),
                          detector=sweep.get_detector(),
                          goniometer=sweep.get_goniometer(),
                          scan=sweep.get_scan(),
                          crystal=cryst_model)
  predicted_reflections = flex.reflection_table.from_predictions(
    experiment)
  use_fraction = 0.3
  use_sel = flex.random_selection(
    len(predicted_reflections), int(use_fraction*len(predicted_reflections)))
  predicted_reflections = predicted_reflections.select(use_sel)
  miller_indices = predicted_reflections['miller_index']
  miller_set = miller.set(
    crystal_symmetry, miller_indices, anomalous_flag=True)
  predicted_reflections['xyzobs.mm.value'] = predicted_reflections['xyzcal.mm']
  predicted_reflections['id'] = flex.int(len(predicted_reflections), 0)
  from dials.algorithms.indexing.indexer import indexer_base
  indexer_base.map_centroids_to_reciprocal_space(
    predicted_reflections, sweep.get_detector(), sweep.get_beam(),
    sweep.get_goniometer())


  # check that local and global indexing worked equally well in absence of errors
  result = compare_global_local(experiment, predicted_reflections,
                                miller_indices)
  assert result.misindexed_local == 0
  assert result.misindexed_global == 0

  a, b, c = cryst_model.get_real_space_vectors()
  relative_error = 0.02
  a *= (1+relative_error)
  b *= (1+relative_error)
  c *= (1+relative_error)

  cryst_model2 = crystal_model(a, b, c, space_group=space_group)
  experiment.crystal = cryst_model2

  result = compare_global_local(experiment, predicted_reflections,
                                miller_indices)

  # check that the local indexing did a better job given the errors in the basis vectors
  #assert result.misindexed_local < result.misindexed_global
  assert result.misindexed_local == 0
  assert result.correct_local > result.correct_global
  # usually the number misindexed is much smaller than this
  assert result.misindexed_local < (0.001 * len(result.reflections_local))

  # the reciprocal matrix
  A = cryst_model.get_A()
  A = random_rotation(angle_max=0.03) * A

  direct_matrix = A.inverse()
  cryst_model2 = crystal_model(direct_matrix[0:3],
                               direct_matrix[3:6],
                               direct_matrix[6:9],
                               space_group=space_group)
  experiment.crystal = cryst_model2

  result = compare_global_local(experiment, predicted_reflections,
                                miller_indices)

  # check that the local indexing did a better job given the errors in the basis vectors
  assert result.misindexed_local <= result.misindexed_global, (
    result.misindexed_local, result.misindexed_global)
  assert result.misindexed_local < 0.01 * result.correct_local
  assert result.correct_local > result.correct_global
  # usually the number misindexed is much smaller than this
  assert result.misindexed_local < (0.001 * len(result.reflections_local))
    def __init__(self, params):
        import cPickle as pickle
        from dxtbx.model.beam import beam_factory
        from dxtbx.model.detector import detector_factory
        from dxtbx.model.crystal import crystal_model
        from cctbx.crystal_orientation import crystal_orientation, basis_type
        from dxtbx.model.experiment.experiment_list import Experiment, ExperimentList
        from scitbx import matrix
        self.experiments = ExperimentList()
        self.unique_file_names = []

        self.params = params
        data = pickle.load(
            open(self.params.output.prefix + "_frame.pickle", "rb"))
        frames_text = data.split("\n")

        for item in frames_text:
            tokens = item.split(' ')
            wavelength = float(tokens[order_dict["wavelength"]])

            beam = beam_factory.simple(wavelength=wavelength)

            detector = detector_factory.simple(
                sensor=detector_factory.sensor(
                    "PAD"),  # XXX shouldn't hard code for XFEL
                distance=float(tokens[order_dict["distance"]]),
                beam_centre=[
                    float(tokens[order_dict["beam_x"]]),
                    float(tokens[order_dict["beam_y"]])
                ],
                fast_direction="+x",
                slow_direction="+y",
                pixel_size=[self.params.pixel_size, self.params.pixel_size],
                image_size=[1795,
                            1795],  # XXX obviously need to figure this out
            )

            reciprocal_matrix = matrix.sqr([
                float(tokens[order_dict[k]]) for k in [
                    'res_ori_1', 'res_ori_2', 'res_ori_3', 'res_ori_4',
                    'res_ori_5', 'res_ori_6', 'res_ori_7', 'res_ori_8',
                    'res_ori_9'
                ]
            ])
            ORI = crystal_orientation(reciprocal_matrix, basis_type.reciprocal)
            direct = matrix.sqr(ORI.direct_matrix())
            crystal = crystal_model(
                real_space_a=matrix.row(direct[0:3]),
                real_space_b=matrix.row(direct[3:6]),
                real_space_c=matrix.row(direct[6:9]),
                space_group_symbol=self.params.target_space_group.type().
                lookup_symbol(),
                mosaicity=float(tokens[order_dict["half_mosaicity_deg"]]),
            )
            crystal.domain_size = float(tokens[order_dict["domain_size_ang"]])
            #if isoform is not None:
            #  newB = matrix.sqr(isoform.fractionalization_matrix()).transpose()
            #  crystal.set_B(newB)

            self.experiments.append(
                Experiment(
                    beam=beam,
                    detector=None,  #dummy for now
                    crystal=crystal))
            self.unique_file_names.append(
                tokens[order_dict["unique_file_name"]])

        self.show_summary()
########################################################################

# Build a mock scan for a 180 degree sweep
sf = scan_factory()
myscan = sf.make_scan(image_range=(1, 1800),
                      exposure_times=0.1,
                      oscillation=(0, 0.1),
                      epochs=range(1800),
                      deg=True)

# Build an ExperimentList
experiments = ExperimentList()
experiments.append(
    Experiment(beam=mybeam,
               detector=mydetector,
               goniometer=mygonio,
               scan=myscan,
               crystal=mycrystal,
               imageset=None))

# Create the PredictionParameterisation
pred_param = XYPhiPredictionParameterisation(experiments, [det_param],
                                             [s0_param], [xlo_param],
                                             [xluc_param])

################################
# Apply known parameter shifts #
################################

# shift detector by 1.0 mm each translation and 4 mrad each rotation
det_p_vals = det_param.get_param_vals()
p_vals = [a + b for a, b in zip(det_p_vals, [1.0, 1.0, 1.0, 4., 4., 4.])]
Beispiel #34
0
def load(entry, exp_index):
  from dxtbx.model.experiment.experiment_list import ExperimentList
  from dxtbx.model.experiment.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