Exemple #1
0
def make_images(data, tag):
    pixel_size = 0.1  # mm/pixel
    detector = DetectorFactory.simple(
        'PAD', 100,
        (pixel_size * data.focus()[1] / 2, pixel_size * data.focus()[2] / 2),
        '+x', '-y', (pixel_size, pixel_size),
        (data.focus()[2], data.focus()[1]), (-1, 1e6 - 1), [], None)
    beam = BeamFactory.simple(1.0)
    sf = ScanFactory()
    scan = sf.make_scan(image_range=(1, 180),
                        exposure_times=0.1,
                        oscillation=(0, 1.0),
                        epochs=range(180),
                        deg=True)

    # write images in each of three directions
    for slice_id in [0, 1, 2]:
        for idx in xrange(data.focus()[slice_id]):
            if slice_id == 0:  # slow
                data_slice = data[idx:idx + 1, :, :]
                data_slice.reshape(flex.grid(data.focus()[1], data.focus()[2]))
                filename = "fft_frame_%s_mf_%04d.cbf" % (tag, idx)
            elif slice_id == 1:  # med
                data_slice = data[:, idx:idx + 1, :]
                data_slice.reshape(flex.grid(data.focus()[0], data.focus()[2]))
                filename = "fft_frame_%s_sf_%04d.cbf" % (tag, idx)
            elif slice_id == 2:  # fast
                data_slice = data[:, :, idx:idx + 1]
                data_slice.reshape(flex.grid(data.focus()[0], data.focus()[1]))
                filename = "fft_frame_%s_sm_%04d.cbf" % (tag, idx)
            print['slow', 'med', 'fast'][slice_id], idx
            FormatCBFMini.as_file(detector, beam, None, scan, data_slice,
                                  filename)
Exemple #2
0
    def __call__(self, imageset):
        """
        Override the parameters
        """
        from dxtbx.imageset import ImageSequence, ImageSetFactory
        from dxtbx.model import BeamFactory
        from dxtbx.model import DetectorFactory
        from dxtbx.model import GoniometerFactory
        from dxtbx.model import ScanFactory
        from copy import deepcopy

        if self.params.geometry.convert_sequences_to_stills:
            imageset = ImageSetFactory.imageset_from_anyset(imageset)
            for j in imageset.indices():
                imageset.set_scan(None, j)
                imageset.set_goniometer(None, j)
        if not isinstance(imageset, ImageSequence):
            if self.params.geometry.convert_stills_to_sequences:
                imageset = self.convert_stills_to_sequence(imageset)
        if isinstance(imageset, ImageSequence):
            beam = BeamFactory.from_phil(self.params.geometry, imageset.get_beam())
            detector = DetectorFactory.from_phil(
                self.params.geometry, imageset.get_detector(), beam
            )
            goniometer = GoniometerFactory.from_phil(
                self.params.geometry, imageset.get_goniometer()
            )
            scan = ScanFactory.from_phil(
                self.params.geometry, deepcopy(imageset.get_scan())
            )
            i0, i1 = scan.get_array_range()
            j0, j1 = imageset.get_scan().get_array_range()
            if i0 < j0 or i1 > j1:
                imageset = self.extrapolate_imageset(
                    imageset=imageset,
                    beam=beam,
                    detector=detector,
                    goniometer=goniometer,
                    scan=scan,
                )
            else:
                imageset.set_beam(beam)
                imageset.set_detector(detector)
                imageset.set_goniometer(goniometer)
                imageset.set_scan(scan)
        else:
            for i in range(len(imageset)):
                beam = BeamFactory.from_phil(self.params.geometry, imageset.get_beam(i))
                detector = DetectorFactory.from_phil(
                    self.params.geometry, imageset.get_detector(i), beam
                )
                goniometer = GoniometerFactory.from_phil(
                    self.params.geometry, imageset.get_goniometer(i)
                )
                scan = ScanFactory.from_phil(self.params.geometry, imageset.get_scan(i))
                imageset.set_beam(beam, i)
                imageset.set_detector(detector, i)
                imageset.set_goniometer(goniometer, i)
                imageset.set_scan(scan, i)
        return imageset
Exemple #3
0
    def generate_reflections(self):
        # Build a mock scan for a 3 degree sweep
        from dxtbx.model import ScanFactory
        sf = ScanFactory()
        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)
    def tst_scan(self):
        from dxtbx.model import Scan, ScanFactory
        from scitbx.array_family import flex
        s1 = Scan((1, 3), (1.0, 0.2), flex.double([0.1, 0.1, 0.1]),
                  flex.double([0.1, 0.2, 0.3]))
        d = s1.to_dict()
        s2 = ScanFactory.from_dict(d)
        assert (d['image_range'] == (1, 3))
        assert (d['oscillation'] == (1.0, 0.2))
        assert (d['exposure_time'] == [0.1, 0.1, 0.1])
        assert (d['epochs'] == [0.1, 0.2, 0.3])
        assert (s1 == s2)

        # Test with a template and partial dictionary
        d2 = {'exposure_time': [0.2, 0.2, 0.2]}
        s3 = ScanFactory.from_dict(d2, d)
        assert (s3.get_image_range() == (1, 3))
        assert (s3.get_oscillation() == (1.0, 0.2))
        assert (list(s3.get_exposure_times()) == [0.2, 0.2, 0.2])
        assert (list(s3.get_epochs()) == [0.1, 0.2, 0.3])
        assert (s2 != s3)

        # Test with a partial epoch
        d3 = {'image_range': (1, 10), 'epochs': [0.1, 0.2]}
        s4 = ScanFactory.from_dict(d3, d)
        assert (abs(s4.get_epochs()[2] - 0.3) < 1e-7)
        assert (abs(s4.get_epochs()[9] - 1.0) < 1e-7)

        print 'OK'
Exemple #5
0
    def __init__(self, override_fdp=None):

        # Set up detector
        distance = 100
        pixel_size = 0.1
        image_size = (1000, 1000)
        beam_centre_mm = (
            pixel_size * image_size[0] / 2,
            pixel_size * image_size[1] / 2,
        )
        self.detector = DetectorFactory().simple(
            "CCD",
            distance,
            beam_centre_mm,
            "+x",
            "-y",
            (pixel_size, pixel_size),
            image_size,
        )

        # Set up beam
        self.beam = BeamFactory().simple(wavelength=1)

        # Set up scan
        sequence_width = 90.0
        osc_start = 0.0
        image_width = 0.2
        oscillation = (osc_start, image_width)

        nframes = int(math.ceil(sequence_width / image_width))
        image_range = (1, nframes)
        exposure_times = 0.0
        epochs = [0] * nframes
        self.scan = ScanFactory().make_scan(image_range,
                                            exposure_times,
                                            oscillation,
                                            epochs,
                                            deg=True)

        # Set up goniometer
        self.goniometer = GoniometerFactory.known_axis(
            self.detector[0].get_fast_axis())

        # Set up simulated structure factors
        self.sfall = self.fcalc_from_pdb(resolution=1.6,
                                         algorithm="direct",
                                         override_fdp=override_fdp)

        # Set up crystal
        self.crystal = Crystal(
            real_space_a=(50, 0, 0),
            real_space_b=(0, 60, 0),
            real_space_c=(0, 0, 70),
            space_group_symbol="P1",
        )
        axis = matrix.col(elems=(-0.14480368275412925, -0.6202131724405818,
                                 -0.7709523423610766))
        self.crystal.set_U(
            axis.axis_and_angle_as_r3_rotation_matrix(angle=0.625126343998969))
Exemple #6
0
    def create_models(self, cmdline_overrides=None):
        from dxtbx.model import ScanFactory
        from libtbx.phil import parse

        from dials.test.algorithms.refinement.setup_geometry import Extract

        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-20 * 0.5 deg images
        sf = ScanFactory()
        self.scan = sf.make_scan((1, 20), 0.5, (0, 0.5), list(range(20)))

        # 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 = ScansExperimentsPredictor(self.experiments)

        # Create scan-varying parameterisations of these models, with 3 samples
        self.det_param = ScanVaryingDetectorParameterisationSinglePanel(
            self.detector, self.scan.get_array_range(), 3)
        self.s0_param = ScanVaryingBeamParameterisation(
            self.beam, self.scan.get_array_range(), 3, self.goniometer)
        self.xlo_param = ScanVaryingCrystalOrientationParameterisation(
            self.crystal, self.scan.get_array_range(), 3)
        self.xluc_param = ScanVaryingCrystalUnitCellParameterisation(
            self.crystal, self.scan.get_array_range(), 3)
        self.gon_param = ScanVaryingGoniometerParameterisation(
            self.goniometer, self.scan.get_array_range(), 3, self.beam)
Exemple #7
0
  def __call__(self, imageset):
    '''
    Override the parameters

    '''
    from dxtbx.imageset import ImageSet
    from dxtbx.imageset import ImageSweep
    from dxtbx.model import BeamFactory
    from dxtbx.model import DetectorFactory
    from dxtbx.model import GoniometerFactory
    from dxtbx.model import ScanFactory
    from copy import deepcopy
    if self.params.geometry.convert_sweeps_to_stills:
      imageset = ImageSet(reader=imageset.reader())
    if not isinstance(imageset, ImageSweep):
      if self.params.geometry.convert_stills_to_sweeps:
        imageset = self.convert_stills_to_sweep(imageset)
    if isinstance(imageset, ImageSweep):
      beam = BeamFactory.from_phil(
        self.params.geometry,
        imageset.get_beam())
      detector = DetectorFactory.from_phil(
        self.params.geometry,
        imageset.get_detector(),
        beam)
      goniometer = GoniometerFactory.from_phil(
        self.params.geometry,
        imageset.get_goniometer())
      scan = ScanFactory.from_phil(
        self.params.geometry,
        deepcopy(imageset.get_scan()))
      i0, i1 = scan.get_array_range()
      j0, j1 = imageset.get_scan().get_array_range()
      imageset.set_beam(beam)
      imageset.set_detector(detector)
      imageset.set_goniometer(goniometer)
      imageset.set_scan(scan)
    else:
      for i in range(len(imageset)):
        beam = BeamFactory.from_phil(
          self.params.geometry,
          imageset.get_beam(i))
        detector = DetectorFactory.from_phil(
          self.params.geometry,
          imageset.get_detector(i),
          beam)
        goniometer = GoniometerFactory.from_phil(
          self.params.geometry,
          imageset.get_goniometer(i))
        scan = ScanFactory.from_phil(
          self.params.geometry,
          imageset.get_scan(i))
        imageset.set_beam(beam, i)
        imageset.set_detector(detector, i)
        imageset.set_goniometer(goniometer, i)
        imageset.set_scan(scan, i)
    return imageset
Exemple #8
0
def create_experiments(image_start=1):

    # Create models
    from libtbx.phil import parse

    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,
    )
    from dials.test.algorithms.refinement.setup_geometry import Extract

    models = Extract(master_phil, overrides)

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

    # Build a mock scan for a 72 degree sequence
    from dxtbx.model import ScanFactory

    sf = ScanFactory()
    scan = sf.make_scan(
        image_range=(image_start, image_start + 720 - 1),
        exposure_times=0.1,
        oscillation=(0, 0.1),
        epochs=list(range(720)),
        deg=True,
    )

    # No matter what image_start is, scan should start at 0.0 and end at 72.0 deg
    assert scan.get_oscillation_range(deg=True) == (0.0, 72.0)

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

    return experiments
Exemple #9
0
def imagesweep_from_dict(d, check_format=True, directory=None):
    """Construct and image sweep from the dictionary."""
    # Get the template (required)
    template = load_path(str(d["template"]), directory=directory)

    # If the scan isn't set, find all available files
    scan_dict = d.get("scan")
    if scan_dict is None:
        image_range = None
    else:
        image_range = scan_dict.get("image_range")

    # Set the models with the exisiting models as templates
    beam = BeamFactory.from_dict(d.get("beam"))
    goniometer = GoniometerFactory.from_dict(d.get("goniometer"))
    detector = DetectorFactory.from_dict(d.get("detector"))
    scan = ScanFactory.from_dict(d.get("scan"))

    # Construct the sweep
    try:
        sweep = ImageSetFactory.from_template(
            template,
            image_range,
            beam=beam,
            detector=detector,
            goniometer=goniometer,
            scan=scan,
            check_format=check_format,
        )[0]
    except Exception:
        indices = range(image_range[0], image_range[1] + 1)
        sweep = ImageSetFactory.make_sweep(
            template,
            indices,
            beam=beam,
            detector=detector,
            goniometer=goniometer,
            scan=scan,
            check_format=check_format,
        )

    # Set some external lookups
    if "mask" in d and d["mask"] is not None and d["mask"] is not "":
        path = load_path(d["mask"], directory=directory)
        with open(path) as infile:
            sweep.external_lookup.mask.filename = path
            sweep.external_lookup.mask.data = ImageBool(pickle.load(infile))
    if "gain" in d and d["gain"] is not None and d["gain"] is not "":
        path = load_path(d["gain"], directory=directory)
        with open(path) as infile:
            sweep.external_lookup.gain.filename = path
            sweep.external_lookup.gain.data = ImageDouble(pickle.load(infile))
    if "pedestal" in d and d["pedestal"] is not None and d["pedestal"] is not "":
        path = load_path(d["pedestal"], directory=directory)
        with open(path) as infile:
            sweep.external_lookup.pedestal.filename = path
            sweep.external_lookup.pedestal.data = ImageDouble(pickle.load(infile))

    # Return the sweep
    return sweep
def experiment():
    beam = BeamFactory.make_beam(wavelength=0.97625, sample_to_source=(0, 0, 1))

    detector = DetectorFactory.simple(
        sensor="PAD",
        distance=265.27,
        beam_centre=(210.7602, 205.27684),
        fast_direction="+x",
        slow_direction="-y",
        pixel_size=(0.172, 0.172),
        image_size=(2463, 2527),
        trusted_range=(-1, 1e8),
    )

    goniometer = GoniometerFactory.single_axis()

    scan = ScanFactory.make_scan(
        image_range=(1, 20),
        exposure_times=0.067,
        oscillation=(82, 0.15),
        epochs=[0] * 20,
    )

    isetdata = ImageSetData(
        reader=Format.Reader(None, ["path"] * len(scan)), masker=None
    )
    iset = ImageSequence(
        isetdata, beam=beam, detector=detector, goniometer=goniometer, scan=scan
    )

    return Experiment(
        imageset=iset, beam=beam, detector=detector, goniometer=goniometer, scan=scan
    )
Exemple #11
0
def imagesweep_from_dict(d, check_format=True):
    '''Construct and image sweep from the dictionary.'''
    from dxtbx.imageset import ImageSetFactory
    from dxtbx.model import BeamFactory, DetectorFactory, GoniometerFactory, ScanFactory
    from dxtbx.serialize.filename import load_path

    # Get the template (required)
    template = load_path(str(d['template']))

    # If the scan isn't set, find all available files
    scan_dict = d.get('scan')
    if scan_dict is None:
        image_range = None
    else:
        image_range = scan_dict.get('image_range')

    # Set the models with the exisiting models as templates
    beam = BeamFactory.from_dict(d.get('beam'))
    goniometer = GoniometerFactory.from_dict(d.get('goniometer'))
    detector = DetectorFactory.from_dict(d.get('detector'))
    scan = ScanFactory.from_dict(d.get('scan'))

    # Construct the sweep
    try:
        sweep = ImageSetFactory.from_template(template,
                                              image_range,
                                              beam=beam,
                                              detector=detector,
                                              goniometer=goniometer,
                                              scan=scan,
                                              check_format=check_format)[0]
    except Exception:
        indices = range(image_range[0], image_range[1] + 1)
        sweep = ImageSetFactory.make_sweep(template,
                                           indices,
                                           beam=beam,
                                           detector=detector,
                                           goniometer=goniometer,
                                           scan=scan,
                                           check_format=check_format)

    # Set some external lookups
    if 'mask' in d and d['mask'] is not None and d['mask'] is not "":
        with open(d['mask']) as infile:
            sweep.external_lookup.mask.filename = d['mask']
            sweep.external_lookup.mask.data = ImageBool(pickle.load(infile))
    if 'gain' in d and d['gain'] is not None and d['gain'] is not "":
        with open(d['gain']) as infile:
            sweep.external_lookup.gain.filename = d['gain']
            sweep.external_lookup.gain.data = ImageDouble(pickle.load(infile))
    if 'pedestal' in d and d['pedestal'] is not None and d[
            'pedestal'] is not "":
        with open(d['pedestal']) as infile:
            sweep.external_lookup.pedestal.filename = d['pedestal']
            sweep.external_lookup.pedestal.data = ImageDouble(
                pickle.load(infile))

    # Return the sweep
    return sweep
Exemple #12
0
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 sequence
    sf = ScanFactory()
    scan = sf.make_scan(
        image_range=(1, 180),
        exposure_times=0.1,
        oscillation=(0, 1.0),
        epochs=list(range(180)),
        deg=True,
    )
    sequence_range = scan.get_oscillation_range(deg=False)
    im_width = scan.get_oscillation(deg=False)[1]
    assert sequence_range == (0.0, math.pi)
    assert approx_equal(im_width, 1.0 * math.pi / 180.0)

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

    return experiments
Exemple #13
0
    def generate_reflections(self):
        # Build a mock scan for a 3 degree sequence
        sf = ScanFactory()
        self.scan = sf.make_scan(
            image_range=(1, 1),
            exposure_times=0.1,
            oscillation=(0, 3.0),
            epochs=list(range(1)),
            deg=True,
        )
        sequence_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, sequence_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)

        # Set dummy observed variances to allow statistical weights to be set
        self.reflections["xyzobs.mm.variance"] += (1e-3, 1e-3, 1e-6)
Exemple #14
0
    def _scan(self):
        """Dummy scan for this image"""

        alpha = self._header_dictionary.get('alphaTilt', 0.0)
        dalpha = 1.0
        exposure = self._header_dictionary.get('integrationTime', 0.0)
        fname = os.path.split(self._image_file)[-1]
        # assume final number before the extension is the image number
        s = fname.split("_")[-1].split(".")[0]
        index = int(re.match('.*?([0-9]+)$', s).group(1))
        return ScanFactory.make_scan((index, index), exposure, (alpha, dalpha),
                                     {index: 0})
Exemple #15
0
def test_extract_experiment_data():
    """Test basic operation of the extract_experiment_data function. Does not
    test extraction of data from scan-varying models"""

    # Set up an Experiment with idealised geometry
    from dxtbx.model import BeamFactory
    from dxtbx.model import GoniometerFactory
    from dxtbx.model import Crystal
    from dxtbx.model import ScanFactory
    from dxtbx.model.experiment_list import Experiment

    beam = BeamFactory.make_beam(unit_s0=(0, 0, -1), wavelength=1.0)
    goniometer = GoniometerFactory.known_axis((1, 0, 0))
    a = (100, 0, 0)
    b = (0, 90, 0)
    c = (0, 0, 80)
    crystal = Crystal(a, b, c, space_group_symbol="P1")
    scan = ScanFactory.make_scan(
        image_range=(1, 91),
        exposure_times=0.1,
        oscillation=(0, 1.0),
        epochs=list(range(91)),
        deg=True,
    )

    exp = Experiment(beam=beam,
                     goniometer=goniometer,
                     scan=scan,
                     crystal=crystal)

    # Extract experiment data
    dat = extract_experiment_data(exp, scale=100)

    # Check results are as expected
    za = dat["zone_axes"]

    # At the first image the c axis is aligned antiparallel with the beam vector,
    # while the a and b axes are orthogonal. The zone axis calculation is scaled
    # by 100 (i.e. the max cell dimension, which is the default), therefore we
    # expect the zone axis [uvw] = [0 0 -100/80]
    assert za[0].elems == pytest.approx((0, 0, -100 / 80))

    # At the start of the 91st image the crystal has rotated by 90 degrees, so
    # now c is orthogonal to the beam while b is anti-parallel to it. The zone
    # axis is now expected to be [uvw] = [0 -100/90 0]
    assert za[-1].elems == pytest.approx((0, -100 / 90, 0))

    rsa = dat["real_space_axes"]
    a, b, c = rsa[0]
    assert a.elems == pytest.approx(crystal.get_real_space_vectors()[0])
    assert b.elems == pytest.approx(crystal.get_real_space_vectors()[1])
    assert c.elems == pytest.approx(crystal.get_real_space_vectors()[2])
def test_experimentlist_imagesequence_decode(mocker):
    # These models are shared between experiments
    beam = Beam(s0=(0, 0, -1))
    detector = Detector()
    gonio = Goniometer()

    # Construct the experiment list
    experiments = ExperimentList()
    for i in range(3):
        experiments.append(
            Experiment(
                beam=beam,
                detector=detector,
                scan=ScanFactory.make_scan(
                    image_range=(i + 1, i + 1),
                    exposure_times=[1],
                    oscillation=(0, 0),
                    epochs=[0],
                ),
                goniometer=gonio,
            ))

    # Convert experiment list to dict and manually insert a shared imageset
    d = experiments.to_dict()
    d["imageset"].append({
        "__id__": "ImageSequence",
        "template": "Puck3_10_1_####.cbf.gz"
    })
    for e in d["experiment"]:
        e["imageset"] = 0

    # Monkeypatch this function as we don't actually have an imageset
    make_sequence = mocker.patch.object(ExperimentListDict, "_make_sequence")
    # Ensure that if make_sequence is called more than once it returns a different
    # value each time
    make_sequence.side_effect = lambda *args, **kwargs: mocker.MagicMock()

    # Decode the dict to get a new experiment list
    experiments2 = ExperimentListDict(d).decode()

    # This function should only be called once per imageset
    make_sequence.assert_called_once()

    # Verify that this experiment is as we expect
    assert len(experiments2) == 3
    assert len(experiments2.imagesets()) == 1
    assert len(experiments2.goniometers()) == 1
    assert len(experiments2.detectors()) == 1
    assert len(experiments2.beams()) == 1
    assert len(experiments2.scans()) == 3
    for expt in experiments2:
        assert expt.imageset is experiments2.imagesets()[0]
Exemple #17
0
def import_geometry(xds_inp=None, dials_json=None):
    assert (xds_inp, dials_json).count(None) == 1

    geom_kwds = set([
        "DIRECTION_OF_DETECTOR_X-AXIS",
        "DIRECTION_OF_DETECTOR_Y-AXIS",
        "DETECTOR_DISTANCE",
        "ORGX",
        "ORGY",
        "ROTATION_AXIS",  # "X-RAY_WAVELENGTH",
        "INCIDENT_BEAM_DIRECTION",
        "SEGMENT",
        "DIRECTION_OF_SEGMENT_X-AXIS",
        "DIRECTION_OF_SEGMENT_Y-AXIS",
        "SEGMENT_DISTANCE",
        "SEGMENT_ORGX",
        "SEGMENT_ORGY"
    ])

    # FIXME in case of multi-segment detector..

    if xds_inp:
        inp = get_xdsinp_keyword(xds_inp)
        inp = filter(lambda x: x[0] in geom_kwds, inp)
        return map(lambda x: "%s= %s" % x, inp)
    elif dials_json:
        import dxtbx.imageset
        from dxtbx.serialize.load import _decode_dict
        from dxtbx.model import BeamFactory
        from dxtbx.model import DetectorFactory
        from dxtbx.model import GoniometerFactory
        from dxtbx.model import ScanFactory
        from dxtbx.serialize.xds import to_xds
        j = json.loads(open(dials_json).read(), object_hook=_decode_dict)
        # dummy
        sweep = dxtbx.imageset.ImageSetFactory.from_template(
            "####", image_range=[1, 1], check_format=False)[0]
        sweep.set_detector(DetectorFactory.from_dict(j["detector"][0]))
        sweep.set_beam(BeamFactory.from_dict(j["beam"][0]))
        sweep.set_goniometer(GoniometerFactory.from_dict(j["goniometer"][0]))
        sweep.set_scan(
            ScanFactory.make_scan(image_range=[1, 1],
                                  exposure_times=[1],
                                  oscillation=[1, 2],
                                  epochs=[0]))  # dummy
        sio = cStringIO.StringIO()
        to_xds(sweep).XDS_INP(sio)
        inp = get_xdsinp_keyword(inp_str=sio.getvalue())
        inp = filter(lambda x: x[0] in geom_kwds, inp)
        return map(lambda x: "%s= %s" % x, inp)

    return []
def test_scan():
    from dxtbx.model import Scan, ScanFactory
    from scitbx.array_family import flex
    s1 = Scan((1, 3), (1.0, 0.2), flex.double([0.1, 0.1, 0.1]),
              flex.double([0.1, 0.2, 0.3]), 0)
    d = s1.to_dict()
    s2 = ScanFactory.from_dict(d)
    assert d['image_range'] == (1, 3)
    assert d['oscillation'] == (1.0, 0.2)
    assert d['exposure_time'] == [0.1, 0.1, 0.1]
    assert d['epochs'] == [0.1, 0.2, 0.3]
    assert d['batch_offset'] == 0
    assert s1 == s2

    # Test with a template and partial dictionary
    d2 = {'exposure_time': [0.2, 0.2, 0.2]}
    s3 = ScanFactory.from_dict(d2, d)
    assert s3.get_image_range() == (1, 3)
    assert s3.get_oscillation() == (1.0, 0.2)
    assert list(s3.get_exposure_times()) == [0.2, 0.2, 0.2]
    assert list(s3.get_epochs()) == [0.1, 0.2, 0.3]
    assert s2 != s3

    # Test with a partial epoch
    d3 = {
        'image_range': (1, 10),
        'epochs': [0.1, 0.2],
    }
    s4 = ScanFactory.from_dict(d3, d)
    assert s4.get_epochs()[2] == pytest.approx(0.3)
    assert s4.get_epochs()[9] == pytest.approx(1.0)

    d4 = {'batch_offset': 100}
    s5 = ScanFactory.from_dict(d4, d)
    assert s5.get_batch_offset() == 100
    assert s5.get_batch_range() == (101, 103)
Exemple #19
0
def test_scan():
    s1 = Scan(
        (1, 3),
        (1.0, 0.2),
        flex.double([0.1, 0.1, 0.1]),
        flex.double([0.1, 0.2, 0.3]),
        0,
    )
    d = s1.to_dict()
    s2 = ScanFactory.from_dict(d)
    assert d["image_range"] == (1, 3)
    assert d["oscillation"] == (1.0, 0.2)
    assert d["exposure_time"] == [0.1, 0.1, 0.1]
    assert d["epochs"] == [0.1, 0.2, 0.3]
    assert d["batch_offset"] == 0
    assert s1 == s2

    # Test with a template and partial dictionary
    d2 = {"exposure_time": [0.2, 0.2, 0.2]}
    s3 = ScanFactory.from_dict(d2, d)
    assert s3.get_image_range() == (1, 3)
    assert s3.get_oscillation() == (1.0, 0.2)
    assert list(s3.get_exposure_times()) == [0.2, 0.2, 0.2]
    assert list(s3.get_epochs()) == [0.1, 0.2, 0.3]
    assert s2 != s3

    # Test with a partial epoch
    d3 = {"image_range": (1, 10), "epochs": [0.1, 0.2]}
    s4 = ScanFactory.from_dict(d3, d)
    assert s4.get_epochs()[2] == pytest.approx(0.3)
    assert s4.get_epochs()[9] == pytest.approx(1.0)

    d4 = {"batch_offset": 100}
    s5 = ScanFactory.from_dict(d4, d)
    assert s5.get_batch_offset() == 100
    assert s5.get_batch_range() == (101, 103)
    def _scan(self):
        """Dummy scan for this image"""

        format = self._scan_factory.format("CBF")

        exposure_time = float(
            self._cif_header_dictionary["Exposure_period"].split()[0])

        fname = os.path.split(self._image_file)[-1]
        index = int(fname.split("_")[-1].split(".")[0])

        return ScanFactory.make_scan(
            image_range=(index, index),
            exposure_times=exposure_time,
            oscillation=(0, 1),
            epochs={index: 0},
        )
Exemple #21
0
    def _scan(self):
        """Scan model for this image, filling out any unavailable items with
        dummy values"""

        alpha = self._header_dictionary.get("alphaTilt", 0.0)
        dalpha = self._header_dictionary.get("tiltPerImage", 1.0)
        exposure = self._header_dictionary.get("integrationTime", 0.0)
        oscillation = (alpha, dalpha)
        fname = os.path.split(self._image_file)[-1]
        # assume that the final number before the extension is the image number
        s = fname.split("_")[-1].split(".")[0]
        try:
            index = int(re.match(".*?([0-9]+)$", s).group(1))
        except AttributeError:
            index = 1
        return ScanFactory.make_scan((index, index), exposure, oscillation,
                                     {index: 0})
Exemple #22
0
 def load_models(obj):
   try:
     beam = BeamFactory.from_dict(blist[obj['beam']])
   except Exception:
     beam = None
   try:
     dobj = dlist[obj['detector']]
     detector = DetectorFactory.from_dict(dobj)
   except Exception:
     detector = None
   try:
     gonio = GoniometerFactory.from_dict(glist[obj['goniometer']])
   except Exception:
     gonio = None
   try:
     scan = ScanFactory.from_dict(slist[obj['scan']])
   except Exception:
     scan = None
   return beam, detector, gonio, scan
Exemple #23
0
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"""
models = setup_geometry.Extract(master_phil,
                                cmdline_args=args,
                                local_overrides=param)

crystal = models.crystal
mydetector = models.detector
mygonio = models.goniometer
mybeam = models.beam

# Build a mock scan for a 1.5 degree wedge. Only used for generating indices near
# the Ewald sphere
sf = ScanFactory()
myscan = sf.make_scan(image_range=(1, 1),
                      exposure_times=0.1,
                      oscillation=(0, 1.5),
                      epochs=range(1),
                      deg=True)
sweep_range = myscan.get_oscillation_range(deg=False)
im_width = myscan.get_oscillation(deg=False)[1]
assert approx_equal(im_width, 1.5 * pi / 180.)

# Build experiment lists
stills_experiments = ExperimentList()
stills_experiments.append(
    Experiment(beam=mybeam,
               detector=mydetector,
               crystal=crystal,
Exemple #24
0
def test_fd_derivatives():
    """Test derivatives of the prediction equation"""

    from libtbx.phil import parse

    # Import model builder
    from dials.test.algorithms.refinement.setup_geometry import Extract

    # Create models
    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,
    )
    models = Extract(master_phil, overrides)

    mydetector = models.detector
    mygonio = models.goniometer
    mycrystal = models.crystal
    mybeam = models.beam

    # Build a mock scan for a 72 degree sequence
    from dxtbx.model import ScanFactory

    sf = ScanFactory()
    myscan = sf.make_scan(
        image_range=(1, 720),
        exposure_times=0.1,
        oscillation=(0, 0.1),
        epochs=list(range(720)),
        deg=True,
    )

    # Create a parameterisation of the crystal unit cell
    from dials.algorithms.refinement.parameterisation.crystal_parameters import (
        CrystalUnitCellParameterisation, )

    xluc_param = CrystalUnitCellParameterisation(mycrystal)

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

    # Build a prediction parameterisation for two theta prediction
    pred_param = TwoThetaPredictionParameterisation(
        experiments,
        detector_parameterisations=None,
        beam_parameterisations=None,
        xl_orientation_parameterisations=None,
        xl_unit_cell_parameterisations=[xluc_param],
    )

    # Generate some reflections
    obs_refs, ref_predictor = generate_reflections(experiments)

    # Build a ReflectionManager with overloads for handling 2theta residuals
    refman = TwoThetaReflectionManager(obs_refs,
                                       experiments,
                                       outlier_detector=None)

    # Build a TwoThetaExperimentsPredictor
    ref_predictor = TwoThetaExperimentsPredictor(experiments)

    # Make a target for the least squares 2theta residual
    target = TwoThetaTarget(experiments, ref_predictor, refman, pred_param)

    # Keep only reflections that pass inclusion criteria and have predictions
    reflections = refman.get_matches()

    # Get analytical gradients
    an_grads = pred_param.get_gradients(reflections)

    # Get finite difference gradients
    p_vals = pred_param.get_param_vals()
    deltas = [1.0e-7] * len(p_vals)

    for i in range(len(deltas)):

        val = p_vals[i]

        p_vals[i] -= deltas[i] / 2.0
        pred_param.set_param_vals(p_vals)

        target.predict()
        reflections = refman.get_matches()

        rev_state = reflections["2theta_resid"].deep_copy()

        p_vals[i] += deltas[i]
        pred_param.set_param_vals(p_vals)

        target.predict()
        reflections = refman.get_matches()

        fwd_state = reflections["2theta_resid"].deep_copy()
        p_vals[i] = val

        fd = fwd_state - rev_state
        fd /= deltas[i]

        # compare with analytical calculation
        assert approx_equal(fd, an_grads[i]["d2theta_dp"], eps=1.0e-6)

    # return to the initial state
    pred_param.set_param_vals(p_vals)
Exemple #25
0
def test_refinement(dials_regression):
    """Test a refinement run"""

    # Get a beam and detector from a experiments. This one has a CS-PAD, but that
    # is irrelevant
    data_dir = os.path.join(dials_regression, "refinement_test_data",
                            "hierarchy_test")
    experiments_path = os.path.join(data_dir, "datablock.json")
    assert os.path.exists(experiments_path)

    # load models
    from dxtbx.model.experiment_list import ExperimentListFactory

    experiments = ExperimentListFactory.from_serialized_format(
        experiments_path, check_format=False)
    im_set = experiments.imagesets()[0]
    detector = deepcopy(im_set.get_detector())
    beam = im_set.get_beam()

    # Invent a crystal, goniometer and scan for this test
    from dxtbx.model import Crystal

    crystal = Crystal((40.0, 0.0, 0.0), (0.0, 40.0, 0.0), (0.0, 0.0, 40.0),
                      space_group_symbol="P1")
    orig_xl = deepcopy(crystal)

    from dxtbx.model import GoniometerFactory

    goniometer = GoniometerFactory.known_axis((1.0, 0.0, 0.0))

    # Build a mock scan for a 180 degree sequence
    from dxtbx.model import ScanFactory

    sf = ScanFactory()
    scan = sf.make_scan(
        image_range=(1, 1800),
        exposure_times=0.1,
        oscillation=(0, 0.1),
        epochs=list(range(1800)),
        deg=True,
    )
    sequence_range = scan.get_oscillation_range(deg=False)
    im_width = scan.get_oscillation(deg=False)[1]
    assert sequence_range == (0.0, pi)
    assert approx_equal(im_width, 0.1 * pi / 180.0)

    # 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, _ = generate_reflections(experiments)

    # change unit cell a bit (=0.1 Angstrom length upsets, 0.1 degree of
    # alpha and beta angles)
    from dials.algorithms.refinement.parameterisation.crystal_parameters import (
        CrystalUnitCellParameterisation, )

    xluc_param = CrystalUnitCellParameterisation(crystal)
    cell_params = crystal.get_unit_cell().parameters()
    cell_params = [
        a + b for a, b in zip(cell_params, [0.1, -0.1, 0.1, 0.1, -0.1, 0.0])
    ]
    from cctbx.uctbx import unit_cell
    from rstbx.symmetry.constraints.parameter_reduction import symmetrize_reduce_enlarge
    from scitbx import matrix

    new_uc = unit_cell(cell_params)
    newB = matrix.sqr(new_uc.fractionalization_matrix()).transpose()
    S = symmetrize_reduce_enlarge(crystal.get_space_group())
    S.set_orientation(orientation=newB)
    X = tuple([e * 1.0e5 for e in S.forward_independent_parameters()])
    xluc_param.set_param_vals(X)

    # reparameterise the crystal at the perturbed geometry
    xluc_param = CrystalUnitCellParameterisation(crystal)

    # Dummy parameterisations for other models
    beam_param = None
    xlo_param = None
    det_param = None

    # parameterisation of the prediction equation
    from dials.algorithms.refinement.parameterisation.parameter_report import (
        ParameterReporter, )

    pred_param = TwoThetaPredictionParameterisation(experiments, det_param,
                                                    beam_param, xlo_param,
                                                    [xluc_param])
    param_reporter = ParameterReporter(det_param, beam_param, xlo_param,
                                       [xluc_param])

    # reflection manager
    refman = TwoThetaReflectionManager(refs, experiments, nref_per_degree=20)

    # reflection predictor
    ref_predictor = TwoThetaExperimentsPredictor(experiments)

    # target function
    target = TwoThetaTarget(experiments, ref_predictor, refman, pred_param)

    # minimisation engine
    from dials.algorithms.refinement.engine import (
        LevenbergMarquardtIterations as Refinery, )

    refinery = Refinery(
        target=target,
        prediction_parameterisation=pred_param,
        log=None,
        max_iterations=20,
    )

    # Refiner
    from dials.algorithms.refinement.refiner import Refiner

    refiner = Refiner(
        experiments=experiments,
        pred_param=pred_param,
        param_reporter=param_reporter,
        refman=refman,
        target=target,
        refinery=refinery,
    )
    refiner.run()

    # compare crystal with original crystal
    refined_xl = refiner.get_experiments()[0].crystal

    # print refined_xl
    assert refined_xl.is_similar_to(orig_xl,
                                    uc_rel_length_tolerance=0.001,
                                    uc_abs_angle_tolerance=0.01)
def test():
    # 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)

    mydetector = models.detector
    mygonio = models.goniometer
    mycrystal = models.crystal
    mybeam = models.beam

    # Build a mock scan for a 3 degree sweep
    from dxtbx.model import ScanFactory

    sf = ScanFactory()
    myscan = sf.make_scan(
        image_range=(1, 1),
        exposure_times=0.1,
        oscillation=(0, 3.0),
        epochs=list(range(1)),
        deg=True,
    )
    sweep_range = myscan.get_oscillation_range(deg=False)

    # Create parameterisations of these models
    det_param = DetectorParameterisationSinglePanel(mydetector)
    s0_param = BeamParameterisation(mybeam, mygonio)
    xlo_param = CrystalOrientationParameterisation(mycrystal)
    xluc_param = CrystalUnitCellParameterisation(mycrystal)

    # Create a scans ExperimentList, only for generating reflections
    experiments = ExperimentList()
    experiments.append(
        Experiment(
            beam=mybeam,
            detector=mydetector,
            goniometer=mygonio,
            scan=myscan,
            crystal=mycrystal,
            imageset=None,
        ))

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

    # Generate rays - only to work out which hkls are predicted
    ray_predictor = ScansRayPredictor(experiments, sweep_range)
    resolution = 2.0
    index_generator = IndexGenerator(
        mycrystal.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
    reflections = flex.reflection_table.empty_standard(len(rays))
    reflections.update(rays)

    # Build a standard prediction parameterisation for the stills experiment to do
    # FD calculation (not used for its analytical gradients)
    pred_param = StillsPredictionParameterisation(
        stills_experiments,
        detector_parameterisations=[det_param],
        beam_parameterisations=[s0_param],
        xl_orientation_parameterisations=[xlo_param],
        xl_unit_cell_parameterisations=[xluc_param],
    )

    # Make a managed SphericalRelpStillsReflectionPredictor reflection predictor
    # for the first (only) experiment
    ref_predictor = Predictor(stills_experiments)

    # Predict these reflections in place. Must do this ahead of calculating
    # the analytical gradients so quantities like s1 are correct
    ref_predictor.update()
    ref_predictor.predict(reflections)

    # calculate analytical gradients
    ag = AnalyticalGradients(
        stills_experiments,
        detector_parameterisation=det_param,
        beam_parameterisation=s0_param,
        xl_orientation_parameterisation=xlo_param,
        xl_unit_cell_parameterisation=xluc_param,
    )
    an_grads = ag.get_beam_gradients(reflections)
    an_grads.update(ag.get_crystal_orientation_gradients(reflections))
    an_grads.update(ag.get_crystal_unit_cell_gradients(reflections))

    # get finite difference gradients
    p_vals = pred_param.get_param_vals()
    deltas = [1.0e-7] * len(p_vals)

    fd_grads = []
    p_names = pred_param.get_param_names()
    for i, delta in enumerate(deltas):

        # save parameter value
        val = p_vals[i]

        # calc reverse state
        p_vals[i] -= delta / 2.0
        pred_param.set_param_vals(p_vals)

        ref_predictor.update()
        ref_predictor.predict(reflections)

        x, y, _ = reflections["xyzcal.mm"].deep_copy().parts()
        s1 = reflections["s1"].deep_copy()
        rev_state = s1

        # calc forward state
        p_vals[i] += delta
        pred_param.set_param_vals(p_vals)

        ref_predictor.update()
        ref_predictor.predict(reflections)

        x, y, _ = reflections["xyzcal.mm"].deep_copy().parts()
        s1 = reflections["s1"].deep_copy()
        fwd_state = s1

        # reset parameter to saved value
        p_vals[i] = val

        # finite difference - currently for s1 only
        fd = fwd_state - rev_state
        inv_delta = 1.0 / delta
        s1_grads = fd * inv_delta

        # store gradients
        fd_grads.append({"name": p_names[i], "ds1": s1_grads})

    # return to the initial state
    pred_param.set_param_vals(p_vals)

    for i, fd_grad in enumerate(fd_grads):

        ## compare FD with analytical calculations
        print("\n\nParameter {0}: {1}".format(i, fd_grad["name"]))

        print("d[s1]/dp for the first reflection")
        print("finite diff", fd_grad["ds1"][0])
        try:
            an_grad = an_grads[fd_grad["name"]]
        except KeyError:
            continue

        print("checking analytical vs finite difference gradients for s1")
        for a, b in zip(fd_grad["ds1"], an_grad["ds1"]):
            assert a == pytest.approx(b, abs=1e-7)
Exemple #27
0
class Simulation(object):
    def __init__(self, override_fdp=None):

        # Set up detector
        distance = 100
        pixel_size = 0.1
        image_size = (1000, 1000)
        beam_centre_mm = (
            pixel_size * image_size[0] / 2,
            pixel_size * image_size[1] / 2,
        )
        self.detector = DetectorFactory().simple(
            "CCD",
            distance,
            beam_centre_mm,
            "+x",
            "-y",
            (pixel_size, pixel_size),
            image_size,
        )

        # Set up beam
        self.beam = BeamFactory().simple(wavelength=1)

        # Set up scan
        sequence_width = 90.0
        osc_start = 0.0
        image_width = 0.2
        oscillation = (osc_start, image_width)

        nframes = int(math.ceil(sequence_width / image_width))
        image_range = (1, nframes)
        exposure_times = 0.0
        epochs = [0] * nframes
        self.scan = ScanFactory().make_scan(
            image_range, exposure_times, oscillation, epochs, deg=True
        )

        # Set up goniometer
        self.goniometer = GoniometerFactory.known_axis(self.detector[0].get_fast_axis())

        # Set up simulated structure factors
        self.sfall = self.fcalc_from_pdb(
            resolution=1.6, algorithm="direct", override_fdp=override_fdp
        )

        # Set up crystal
        self.crystal = Crystal(
            real_space_a=(50, 0, 0),
            real_space_b=(0, 60, 0),
            real_space_c=(0, 0, 70),
            space_group_symbol="P1",
        )
        axis = matrix.col(
            elems=(-0.14480368275412925, -0.6202131724405818, -0.7709523423610766)
        )
        self.crystal.set_U(
            axis.axis_and_angle_as_r3_rotation_matrix(angle=0.625126343998969)
        )

    def fcalc_from_pdb(self, resolution, algorithm=None, override_fdp=None):
        pdb_inp = pdb.input(source_info=None, lines=_pdb_lines)
        xray_structure = pdb_inp.xray_structure_simple()
        wavelength = self.beam.get_wavelength()
        #
        # take a detour to calculate anomalous contribution of every atom
        scatterers = xray_structure.scatterers()
        for sc in scatterers:
            expected_henke = henke.table(sc.element_symbol()).at_angstrom(wavelength)
            sc.fp = expected_henke.fp()
            sc.fdp = override_fdp if override_fdp is not None else expected_henke.fdp()

        # how do we do bulk solvent?
        primitive_xray_structure = xray_structure.primitive_setting()
        P1_primitive_xray_structure = primitive_xray_structure.expand_to_p1()
        fcalc = P1_primitive_xray_structure.structure_factors(
            d_min=resolution, anomalous_flag=True, algorithm=algorithm
        ).f_calc()
        return fcalc.amplitudes()

    def set_varying_beam(self, along="fast", npixels_drift=5):
        assert along in ["fast", "slow", "both"]
        num_scan_points = self.scan.get_num_images() + 1
        s0 = matrix.col(self.beam.get_s0())
        beam_centre_px = self.detector[0].get_beam_centre_px(s0)
        if along == "fast":
            start_beam_centre = (
                beam_centre_px[0] - npixels_drift / 2,
                beam_centre_px[1],
            )
            end_beam_centre = (beam_centre_px[0] + npixels_drift / 2, beam_centre_px[1])
        elif along == "slow":
            start_beam_centre = (
                beam_centre_px[0],
                beam_centre_px[1] - npixels_drift / 2,
            )
            end_beam_centre = (beam_centre_px[0], beam_centre_px[1] + npixels_drift / 2)
        elif along == "both":
            offset = math.sqrt(2.0) * npixels_drift / 4.0
            start_beam_centre = (beam_centre_px[0] - offset, beam_centre_px[1] - offset)
            end_beam_centre = (beam_centre_px[0] + offset, beam_centre_px[1] + offset)

        start_lab = matrix.col(self.detector[0].get_pixel_lab_coord(start_beam_centre))
        end_lab = matrix.col(self.detector[0].get_pixel_lab_coord(end_beam_centre))
        axis = start_lab.cross(end_lab).normalize()
        full_angle = start_lab.angle(end_lab)
        angle_step = full_angle / self.scan.get_num_images()
        angles = [e * angle_step for e in range(num_scan_points)]

        start_s0 = start_lab.normalize() * s0.length()
        s0_list = [start_s0.rotate_around_origin(axis=axis, angle=e) for e in angles]

        self.beam.set_s0_at_scan_points(s0_list)
def test2():
    """Test on simulated data"""

    # Get models for reflection prediction
    import dials.test.algorithms.refinement.setup_geometry as setup_geometry

    from libtbx.phil import parse

    overrides = """geometry.parameters.crystal.a.length.value = 77
  geometry.parameters.crystal.b.length.value = 77
  geometry.parameters.crystal.c.length.value = 37"""

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

    from dxtbx.model import Crystal

    models = setup_geometry.Extract(master_phil)
    crystal = Crystal(
        real_space_a=(2.62783398111729, -63.387215823567125,
                      -45.751375737456975),
        real_space_b=(15.246640559660356, -44.48254330406616,
                      62.50501032727026),
        real_space_c=(-76.67246874451074, -11.01804131886244,
                      10.861322446352226),
        space_group_symbol="I 2 3",
    )
    detector = models.detector
    goniometer = models.goniometer
    beam = models.beam

    # Build a mock scan for a 180 degree sweep
    from dxtbx.model import ScanFactory

    sf = ScanFactory()
    scan = sf.make_scan(
        image_range=(1, 1800),
        exposure_times=0.1,
        oscillation=(0, 0.1),
        epochs=range(1800),
        deg=True,
    )

    # Build an experiment list
    from dxtbx.model.experiment_list import ExperimentList, Experiment

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

    # Generate all indices in a 1.5 Angstrom sphere
    from dials.algorithms.spot_prediction import IndexGenerator
    from cctbx.sgtbx import space_group, space_group_symbols

    resolution = 1.5
    index_generator = IndexGenerator(
        crystal.get_unit_cell(),
        space_group(space_group_symbols(1).hall()).type(),
        resolution,
    )
    indices = index_generator.to_array()

    # Predict rays within the sweep range
    from dials.algorithms.refinement.prediction import ScansRayPredictor

    sweep_range = scan.get_oscillation_range(deg=False)
    ray_predictor = ScansRayPredictor(experiments, sweep_range)
    obs_refs = ray_predictor(indices)

    # Take only those rays that intersect the detector
    from dials.algorithms.spot_prediction import ray_intersection

    intersects = ray_intersection(detector, obs_refs)
    obs_refs = obs_refs.select(intersects)

    # Make a reflection predictor and re-predict for all these reflections. The
    # result is the same, but we gain also the flags and xyzcal.px columns
    from dials.algorithms.refinement.prediction import ExperimentsPredictor

    ref_predictor = ExperimentsPredictor(experiments)
    obs_refs["id"] = flex.int(len(obs_refs), 0)
    obs_refs = ref_predictor(obs_refs)

    # Copy 'observed' centroids from the predicted ones, applying sinusoidal
    # offsets
    obs_x, obs_y, obs_z = obs_refs["xyzcal.mm"].parts()

    # obs_z is in range (0, pi). Calculate offsets for phi at twice that
    # frequency
    im_width = scan.get_oscillation(deg=False)[1]
    z_off = flex.sin(2 * obs_z) * im_width
    obs_z += z_off

    # Calculate offsets for x
    pixel_size = detector[0].get_pixel_size()
    x_off = flex.sin(20 * obs_z) * pixel_size[0]

    # Calculate offsets for y with a phase-shifted sine wave
    from math import pi

    y_off = flex.sin(4 * obs_z + pi / 6) * pixel_size[1]

    # Incorporate the offsets into the 'observed' centroids
    obs_z += z_off
    obs_x += x_off
    obs_y += y_off
    obs_refs["xyzobs.mm.value"] = flex.vec3_double(obs_x, obs_y, obs_z)

    # Now do centroid analysis of the residuals
    results = CentroidAnalyser(obs_refs, debug=True)()

    # FIXME this test shows that the suggested interval width heuristic is not
    # yet robust. This simulation function seems a useful direction to proceed
    # in though
    raise RuntimeError("test2 failed")

    print("OK")
    return
def test():
    from cctbx.sgtbx import space_group, space_group_symbols

    # We will set up a mock scan
    from dxtbx.model import ScanFactory
    from dxtbx.model.experiment_list import Experiment, ExperimentList
    from libtbx.phil import parse
    from scitbx import matrix
    from scitbx.array_family import flex

    from dials.algorithms.refinement.prediction.managed_predictors import (
        ScansExperimentsPredictor,
        ScansRayPredictor,
    )

    # Reflection prediction
    from dials.algorithms.spot_prediction import IndexGenerator

    # Building experimental models
    from dials.test.algorithms.refinement.setup_geometry import Extract

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

    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"""

    models = Extract(master_phil, local_overrides=overrides)

    mydetector = models.detector
    mygonio = models.goniometer
    mycrystal = models.crystal
    mybeam = models.beam

    #############################
    # Generate some reflections #
    #############################

    # All indices in a 2.0 Angstrom sphere
    resolution = 2.0
    index_generator = IndexGenerator(
        mycrystal.get_unit_cell(),
        space_group(space_group_symbols(1).hall()).type(),
        resolution,
    )
    indices = index_generator.to_array()

    # Build a mock scan for a 30 degree sequence
    sf = ScanFactory()
    myscan = sf.make_scan(
        image_range=(1, 300),
        exposure_times=0.1,
        oscillation=(0, 0.1),
        epochs=list(range(300)),
        deg=True,
    )
    sequence_range = myscan.get_oscillation_range(deg=False)
    assert sequence_range == pytest.approx((0.0, math.pi / 6.0))
    im_width = myscan.get_oscillation(deg=False)[1]
    assert im_width == pytest.approx(0.1 * math.pi / 180.0)

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

    # Select those that are excited in a 30 degree sequence and get angles
    ray_predictor = ScansRayPredictor(experiments, sequence_range)
    obs_refs = ray_predictor(indices)

    # Set the experiment number
    obs_refs["id"] = flex.int(len(obs_refs), 0)

    # Calculate intersections
    ref_predictor = ScansExperimentsPredictor(experiments)
    obs_refs = ref_predictor(obs_refs)

    print("Total number of observations made", len(obs_refs))

    s0 = matrix.col(mybeam.get_s0())
    spindle = matrix.col(mygonio.get_rotation_axis())

    for ref in obs_refs.rows():
        # get the s1 vector of this reflection
        s1 = matrix.col(ref["s1"])

        r = s1 - s0
        r_orig = r.rotate_around_origin(spindle, -1.0, deg=True)

        # is it outside the Ewald sphere (i.e. entering)?
        test = (s0 + r_orig).length() > s0.length()
        assert ref["entering"] == test
 def _scan_from_dict(obj):
     ''' Get the scan from a dictionary. '''
     from dxtbx.model import ScanFactory
     return ScanFactory.from_dict(obj)