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
def test_beam_parameters(): from scitbx import matrix from dxtbx.model import BeamFactory from dials.algorithms.refinement.parameterisation.beam_parameters import ( BeamParameterisation, ) from dials.algorithms.refinement.refinement_helpers import ( get_fd_gradients, random_param_shift, ) # make a random beam vector and parameterise it bf = BeamFactory() s0 = bf.make_beam(matrix.col.random(3, 0.5, 1.5), wavelength=1.2) s0p = BeamParameterisation(s0) # Let's do some basic tests. First, can we change parameter values and # update the modelled vector s0? s0_old = matrix.col(s0.get_s0()) s0p.set_param_vals([1000 * 0.1, 1000 * 0.1, 0.8]) assert matrix.col(s0.get_s0()).angle(s0_old) == pytest.approx(0.1413033, abs=1e-6) assert matrix.col(s0.get_s0()).length() == pytest.approx(0.8, abs=1e-6) # random initial orientations and wavelengths with a random parameter shifts attempts = 1000 failures = 0 for i in range(attempts): # make a random beam vector and parameterise it s0 = bf.make_beam( matrix.col.random(3, 0.5, 1.5), wavelength=random.uniform(0.8, 1.5) ) s0p = BeamParameterisation(s0) # apply a random parameter shift p_vals = s0p.get_param_vals() p_vals = random_param_shift(p_vals, [1000 * pi / 9, 1000 * pi / 9, 0.01]) s0p.set_param_vals(p_vals) # compare analytical and finite difference derivatives an_ds_dp = s0p.get_ds_dp() fd_ds_dp = get_fd_gradients(s0p, [1.0e-5 * pi / 180, 1.0e-5 * pi / 180, 1.0e-6]) for j in range(3): try: assert list(fd_ds_dp[j] - an_ds_dp[j]) == pytest.approx( (0, 0, 0), abs=1e-6 ) except Exception: print("for try", i) print("failure for parameter number", j) print("with fd_ds_dp = ") print(fd_ds_dp[j]) print("and an_ds_dp = ") print(an_ds_dp[j]) print("so that difference fd_ds_dp - an_ds_dp =") print(fd_ds_dp[j] - an_ds_dp[j]) raise
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 __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
def basic_imageset_from_dict(d, directory=None): """ Construct an ImageSet class from the dictionary.""" # Get the filename list and create the imageset filenames = map( lambda p: load_path(p, directory=directory), map(str, d["filenames"]) ) imageset = ImageSetFactory.new(filenames)[0] # 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: imageset.external_lookup.mask.filename = path imageset.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: imageset.external_lookup.gain.filename = path imageset.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: imageset.external_lookup.pedestal.filename = path imageset.external_lookup.pedestal.data = ImageDouble(pickle.load(infile)) # Get the existing models as dictionaries beam_dict = imageset.get_beam(0).to_dict() detector_dict = imageset.get_detector(0).to_dict() # Set models imageset.set_beam(BeamFactory.from_dict(d.get("beam"), beam_dict)) imageset.set_detector(DetectorFactory.from_dict(d.get("detector"), detector_dict)) # Return the imageset return imageset
def basic_imageset_from_dict(d): ''' Construct an ImageSet class from the dictionary.''' from dxtbx.model import BeamFactory, DetectorFactory from dxtbx.imageset import ImageSetFactory from dxtbx.serialize.filename import load_path # Get the filename list and create the imageset filenames = map(lambda p: load_path(p), map(str, d['filenames'])) imageset = ImageSetFactory.new(filenames)[0] # Set some external lookups if 'mask' in d and d['mask'] is not None: with open(d['mask']) as infile: imageset.external_lookup.mask.filename = d['mask'] imageset.external_lookup.mask.data = pickle.load(infile) if 'gain' in d and d['gain'] is not None: with open(d['gain']) as infile: imageset.external_lookup.gain.filename = d['gain'] imageset.external_lookup.gain.data = pickle.load(infile) if 'pedestal' in d and d['pedestal'] is not None: with open(d['pedestal']) as infile: imageset.external_lookup.pedestal.filename = d['pedestal'] imageset.external_lookup.pedestal.data = pickle.load(infile) # Get the existing models as dictionaries beam_dict = imageset.get_beam().to_dict() detector_dict = imageset.get_detector().to_dict() # Set models imageset.set_beam(BeamFactory.from_dict(d.get('beam'), beam_dict)) imageset.set_detector( DetectorFactory.from_dict(d.get('detector'), detector_dict)) # Return the imageset return imageset
def build_beam(self): if self._params.beam.wavelength.random: wavelength = random.uniform(*self._params.beam.wavelength.range) else: wavelength = self._params.beam.wavelength.value assert self._params.beam.direction.method in [ 'inclination', 'close_to', 'exactly' ] if self._params.beam.direction.method == 'inclination': if self._params.beam.direction.inclination.random: inclination = random.gauss( 0., self._params.beam.direction.inclination.angle) else: inclination = \ self._params.beam.direction.inclination.angle beam_dir = matrix.col((0, 0, 1)).rotate(matrix.col((0, 1, 0)), inclination, deg=True) elif self._params.beam.direction.method == 'close_to': temp = self._params.beam.direction.close_to.direction beam_dir = random_vector_close_to( temp, sd=self._params.beam.direction.close_to.sd) elif self._params.beam.direction.method == 'exactly': beam_dir = matrix.col(self._params.beam.direction.exactly) self.beam = BeamFactory.make_beam(unit_s0=beam_dir, wavelength=wavelength)
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 )
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 __init__(self, test_nave_model=False): # Set up experimental models with regular geometry from dxtbx.model import BeamFactory, DetectorFactory, GoniometerFactory # Beam along the Z axis self.beam = BeamFactory.make_beam(unit_s0=matrix.col((0, 0, 1)), wavelength=1.0) # Goniometer (used only for index generation) along X axis self.goniometer = GoniometerFactory.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)) 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 = DetectorFactory.make_detector( "PAD", dir1, dir2, origin, (pix_size, pix_size), (npx_fast, npx_slow), (0, 1.0e6), ) # Cubic 100 A^3 crystal a = matrix.col((100, 0, 0)) b = matrix.col((0, 100, 0)) c = matrix.col((0, 0, 100)) if test_nave_model: from dxtbx.model import MosaicCrystalSauter2014 self.crystal = MosaicCrystalSauter2014(a, b, c, space_group_symbol="P 1") self.crystal.set_half_mosaicity_deg(500) self.crystal.set_domain_size_ang(0.2) else: from dxtbx.model import Crystal self.crystal = Crystal(a, b, c, space_group_symbol="P 1") # Collect these models in an Experiment (ignoring the goniometer) from dxtbx.model.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()
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
def test_beam(): b1 = Beam((1, 0, 0), 2, 0.1, 0.1) d = b1.to_dict() b2 = BeamFactory.from_dict(d) assert d["direction"] == (1, 0, 0) assert d["wavelength"] == 2 assert d["divergence"] == pytest.approx(0.1) assert d["sigma_divergence"] == pytest.approx(0.1) assert b1 == b2 assert "s0_at_scan_points" not in d # Test with a template and partial dictionary d2 = {"direction": (0, 1, 0), "divergence": 0.2} b3 = BeamFactory.from_dict(d2, d) assert b3.get_sample_to_source_direction() == (0, 1, 0) assert b3.get_wavelength() == 2 assert b3.get_divergence() == pytest.approx(0.2) assert b3.get_sigma_divergence() == pytest.approx(0.1) assert b2 != b3
def test_beam(): from dxtbx.model import Beam, BeamFactory b1 = Beam((1, 0, 0), 2, 0.1, 0.1) d = b1.to_dict() b2 = BeamFactory.from_dict(d) assert d['direction'] == (1, 0, 0) assert d['wavelength'] == 2 assert d['divergence'] == pytest.approx(0.1) assert d['sigma_divergence'] == pytest.approx(0.1) assert b1 == b2 assert 's0_at_scan_points' not in d # Test with a template and partial dictionary d2 = {'direction': (0, 1, 0), 'divergence': 0.2} b3 = BeamFactory.from_dict(d2, d) assert b3.get_direction() == (0, 1, 0) assert b3.get_wavelength() == 2 assert b3.get_divergence() == pytest.approx(0.2) assert b3.get_sigma_divergence() == pytest.approx(0.1) assert b2 != b3
def tst_beam(self): from dxtbx.model import Beam, BeamFactory b1 = Beam((1, 0, 0), 2, 0.1, 0.1) d = b1.to_dict() b2 = BeamFactory.from_dict(d) assert (d['direction'] == (1, 0, 0)) assert (d['wavelength'] == 2) assert (abs(d['divergence'] - 0.1) <= 1e-7) assert (abs(d['sigma_divergence'] - 0.1) <= 1e-7) assert (b1 == b2) # Test with a template and partial dictionary d2 = {'direction': (0, 1, 0), 'divergence': 0.2} b3 = BeamFactory.from_dict(d2, d) assert (b3.get_direction() == (0, 1, 0)) assert (b3.get_wavelength() == 2) assert (abs(b3.get_divergence() - 0.2) <= 1e-7) assert (abs(b3.get_sigma_divergence() - 0.1) <= 1e-7) assert (b2 != b3) print 'OK'
def beam(self): # Does this handle the conventions ? Im always confused about where the beam is pointing, whats s0 and whats beam_vector beam_dict = {'direction': self.beam_vector, 'divergence': 0.0, # TODO 'flux': self.flux, 'polarization_fraction': self.polarization, #TODO 'polarization_normal': col(self.polar_vector).cross(col(self.beam_vector)), 'sigma_divergence': 0.0, # TODO 'transmission': 1.0, #TODO ? 'wavelength': self.wavelength_A} beam = BeamFactory.from_dict(beam_dict) return beam
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_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_beam_with_scan_points(): b1 = Beam((1, 0, 0), 2, 0.1, 0.1) s0_static = matrix.col(b1.get_s0()) b1.set_s0_at_scan_points([s0_static] * 5) d = b1.to_dict() b2 = BeamFactory.from_dict(d) for s0comp in d["s0_at_scan_points"]: assert matrix.col(s0comp) == s0_static for s0comp in b2.get_s0_at_scan_points(): assert matrix.col(s0comp) == s0_static assert b1 == b2
def trumpet_wrapper(result, postx, file_name, params, out): from scitbx import matrix from dxtbx.model import BeamFactory beam = BeamFactory.make_beam(s0=(0, 0, -1. / result["wavelength"])) from dxtbx.model import Experiment from dxtbx.model import crystal obs_to_plot = postx.observations_original_index_pair1_selected # XXX uses a private interface HKL = obs_to_plot.indices() i_sigi = obs_to_plot.data() / obs_to_plot.sigmas() direct_matrix = result["current_orientation"][0].direct_matrix() real_a = direct_matrix[0:3] real_b = direct_matrix[3:6] real_c = direct_matrix[6:9] SG = obs_to_plot.space_group() crystal = crystal.crystal_model(real_a, real_b, real_c, space_group=SG) q = Experiment(beam=beam, crystal=crystal) TPL = trumpet_plot() from xfel.cxi.data_utils import reduction RED = reduction(filename=file_name, experiment=q, HKL=HKL, i_sigi=i_sigi, measurements=obs_to_plot, params=params) TPL.set_reduction(RED) # first plot: before postrefinement TPL.reduction.experiment.crystal.set_A( matrix.sqr(result["current_orientation"][0].reciprocal_matrix())) TPL.set_refined( dict(half_mosaic_rotation_deg=result["ML_half_mosaicity_deg"][0], mosaic_domain_size_ang=result["ML_domain_size_ang"][0])) TPL.plot_one_model(nrow=0, out=out) # second plot after postrefinement values = postx.get_parameter_values() TPL.reduction.experiment.crystal.set_A( postx.refined_mini.refinery.get_eff_Astar(values)) TPL.refined["red_curve_domain_size_ang"] = 1 / values.RS TPL.refined[ "partiality_array"] = postx.refined_mini.refinery.get_partiality_array( values) TPL.plot_one_model(nrow=1, out=out) TPL.show()
def test_beam_with_scan_points(): from dxtbx.model import Beam, BeamFactory b1 = Beam((1, 0, 0), 2, 0.1, 0.1) from scitbx import matrix s0_static = matrix.col(b1.get_s0()) b1.set_s0_at_scan_points([s0_static] * 5) d = b1.to_dict() b2 = BeamFactory.from_dict(d) for s0comp in d['s0_at_scan_points']: assert matrix.col(s0comp) == s0_static for s0comp in b2.get_s0_at_scan_points(): assert matrix.col(s0comp) == s0_static assert b1 == b2
def get_xray_beams(spectrum, beam_originator): """ :param spectrum: list of tuples where one tuple is (wavelength_Angstrom, flux) :param beam_originator: beam where we derive the s0 vector and polarization and divergence :return: flex_Beam array to be set as a nanoBragg property """ xray_beams = flex_Beam() for wavelen, flux in spectrum: beam = BeamFactory.simple(wavelen*1e-10) beam.set_flux(flux) beam.set_unit_s0(beam_originator.get_unit_s0()) beam.set_polarization_fraction(beam_originator.get_polarization_fraction()) beam.set_divergence(beam_originator.get_divergence()) xray_beams.append(beam) return xray_beams
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
def prepare_dxtbx_models(self, setting_specific_ai, sg, isoform=None): from dxtbx.model import BeamFactory beam = BeamFactory.simple(wavelength=self.inputai.wavelength) from dxtbx.model import DetectorFactory detector = DetectorFactory.simple( sensor=DetectorFactory.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 import Crystal crystal = Crystal( 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, ) crystal.set_mosaicity(setting_specific_ai.getMosaicity()) if isoform is not None: newB = matrix.sqr(isoform.fractionalization_matrix()).transpose() crystal.set_B(newB) from dxtbx.model import Experiment, ExperimentList experiments = ExperimentList() experiments.append( Experiment(beam=beam, detector=detector, crystal=crystal)) print beam print detector print crystal return experiments
def build_beam(self): if self._params.beam.wavelength.random: wavelength = random.uniform(*self._params.beam.wavelength.range) else: wavelength = self._params.beam.wavelength.value assert self._params.beam.direction.method in [ "inclination", "close_to", "exactly", ] if self._params.beam.direction.method == "inclination": if self._params.beam.direction.inclination.random: inclination = random.gauss( 0.0, self._params.beam.direction.inclination.angle) else: inclination = self._params.beam.direction.inclination.angle beam_dir = matrix.col((0, 0, 1)).rotate_around_origin(matrix.col( (0, 1, 0)), inclination, deg=True) elif self._params.beam.direction.method == "close_to": temp = self._params.beam.direction.close_to.direction beam_dir = random_vector_close_to( temp, sd=self._params.beam.direction.close_to.sd) elif self._params.beam.direction.method == "exactly": beam_dir = matrix.col(self._params.beam.direction.exactly) self.beam = BeamFactory.make_beam(unit_s0=beam_dir, wavelength=wavelength)
def expt_beam_maker(self): """Construct the beam object for the experiments file.""" self.beam = BeamFactory.simple(self.wavelength)
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 test(): # set the random seed to make the test reproducible random.seed(1337) # set up a simple detector frame with directions aligned with # principal axes and sensor origin located on the z-axis at -110 d1 = matrix.col((1, 0, 0)) d2 = matrix.col((0, -1, 0)) # lim = (0,50) npx_fast = 1475 npx_slow = 1679 pix_size_f = pix_size_s = 0.172 detector = DetectorFactory.make_detector( "PAD", d1, d2, matrix.col((0, 0, -110)), (pix_size_f, pix_size_s), (npx_fast, npx_slow), (0, 2e20), ) dp = DetectorParameterisationSinglePanel(detector) beam = BeamFactory().make_beam( sample_to_source=-1 * (matrix.col((0, 0, -110)) + 10 * d1 + 10 * d2), wavelength=1.0, ) # Test change of parameters # ========================= # 1. shift detector plane so that the z-axis intercepts its centre # at a distance of 100 along the initial normal direction. As the # initial normal is along -z, we expect the frame to intercept the # z-axis at -100. p_vals = dp.get_param_vals() p_vals[0:3] = [100.0, 0.0, 0.0] dp.set_param_vals(p_vals) detector = dp._model assert len(detector) == 1 panel = detector[0] v1 = matrix.col(panel.get_origin()) v2 = matrix.col((0.0, 0.0, 1.0)) assert approx_equal(v1.dot(v2), -100.0) # 2. rotate frame around its initial normal by +90 degrees. Only d1 # and d2 should change. As we rotate clockwise around the initial # normal (-z direction) then d1 should rotate onto the original # direction d2, and d2 should rotate to negative of the original # direction d1 p_vals[3] = 1000.0 * pi / 2 # set tau1 value dp.set_param_vals(p_vals) detector = dp._model assert len(detector) == 1 panel = detector[0] assert approx_equal( matrix.col(panel.get_fast_axis()).dot(dp._initial_state["d1"]), 0.0) assert approx_equal( matrix.col(panel.get_slow_axis()).dot(dp._initial_state["d2"]), 0.0) assert approx_equal( matrix.col(panel.get_normal()).dot(dp._initial_state["dn"]), 1.0) # 3. no rotation around initial normal, +10 degrees around initial # d1 direction and +10 degrees around initial d2. Check d1 and d2 # match paper calculation p_vals[3] = 0.0 # tau1 p_vals[4] = 1000.0 * pi / 18 # tau2 p_vals[5] = 1000.0 * pi / 18 # tau3 dp.set_param_vals(p_vals) # paper calculation values v1 = matrix.col((cos(pi / 18), 0, sin(pi / 18))) v2 = matrix.col(( sin(pi / 18)**2, -cos(pi / 18), sqrt((2 * sin(pi / 36) * sin(pi / 18))**2 - sin(pi / 18)**4) - sin(pi / 18), )) detector = dp._model assert len(detector) == 1 panel = detector[0] assert approx_equal(matrix.col(panel.get_fast_axis()).dot(v1), 1.0) assert approx_equal(matrix.col(panel.get_slow_axis()).dot(v2), 1.0) # 4. Test fixing and unfixing of parameters p_vals = [ 100.0, 0.0, 0.0, 1000.0 * pi / 18, 1000.0 * pi / 18, 1000.0 * pi / 18 ] dp.set_param_vals(p_vals) f = dp.get_fixed() f[0:3] = [True] * 3 dp.set_fixed(f) p_vals2 = [0.0, 0.0, 0.0] dp.set_param_vals(p_vals2) assert dp.get_param_vals(only_free=False) == [ 100.0, 0.0, 0.0, 0.0, 0.0, 0.0 ] an_ds_dp = dp.get_ds_dp() assert len(an_ds_dp) == 3 f[0:3] = [False] * 3 dp.set_fixed(f) p_vals = dp.get_param_vals() p_vals2 = [a + b for a, b in zip(p_vals, [-10.0, 1.0, 1.0, 0.0, 0.0, 0.0])] dp.set_param_vals(p_vals2) assert dp.get_param_vals() == [90.0, 1.0, 1.0, 0.0, 0.0, 0.0] # 5. Tests of the calculation of derivatives # Now using parameterisation in mrad # random initial orientations with a random parameter shift at each attempts = 100 for i in range(attempts): # create random initial position det = Detector(random_panel()) dp = DetectorParameterisationSinglePanel(det) # apply a random parameter shift p_vals = dp.get_param_vals() p_vals = random_param_shift( p_vals, [10, 10, 10, 1000.0 * pi / 18, 1000.0 * pi / 18, 1000.0 * pi / 18]) dp.set_param_vals(p_vals) # compare analytical and finite difference derivatives. an_ds_dp = dp.get_ds_dp(multi_state_elt=0) fd_ds_dp = get_fd_gradients(dp, [1.0e-6] * 3 + [1.0e-4 * pi / 180] * 3) for j in range(6): assert approx_equal( (fd_ds_dp[j] - an_ds_dp[j]), matrix.sqr((0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)), eps=1.0e-6, ), textwrap.dedent("""\ Failure comparing analytical with finite difference derivatives. Failure in try {i} failure for parameter number {j} of the orientation parameterisation with fd_ds_dp = {fd} and an_ds_dp = {an} so that difference fd_ds_dp - an_ds_dp = {diff} """).format(i=i, j=j, fd=fd_ds_dp[j], an=an_ds_dp[j], diff=fd_ds_dp[j] - an_ds_dp[j]) # 5. Test a multi-panel detector with non-coplanar panels. # place a beam at the centre of the single panel detector (need a # beam to initialise the multi-panel detector parameterisation) lim = det[0].get_image_size_mm() shift1 = lim[0] / 2.0 shift2 = lim[1] / 2.0 beam_centre = (matrix.col(det[0].get_origin()) + shift1 * matrix.col(det[0].get_fast_axis()) + shift2 * matrix.col(det[0].get_slow_axis())) beam = BeamFactory().make_beam(sample_to_source=-1.0 * beam_centre, wavelength=1.0) multi_panel_detector = make_multi_panel(det) # parameterise this detector dp = DetectorParameterisationMultiPanel(multi_panel_detector, beam) # ensure the beam still intersects the central panel intersection = multi_panel_detector.get_ray_intersection(beam.get_s0()) assert intersection[0] == 4 # record the offsets and dir1s, dir2s offsets_before_shift = dp._offsets dir1s_before_shift = dp._dir1s dir2s_before_shift = dp._dir2s # apply a random parameter shift (~10 mm distances, ~50 mrad angles) p_vals = dp.get_param_vals() p_vals = random_param_shift(p_vals, [10, 10, 10, 50, 50, 50]) # reparameterise the detector dp = DetectorParameterisationMultiPanel(multi_panel_detector, beam) # record the offsets and dir1s, dir2s offsets_after_shift = dp._offsets dir1s_after_shift = dp._dir1s dir2s_after_shift = dp._dir2s # ensure the offsets, dir1s and dir2s are the same. This means that # each panel in the detector moved with the others as a rigid body for a, b in zip(offsets_before_shift, offsets_after_shift): assert approx_equal(a, b, eps=1.0e-10) for a, b in zip(dir1s_before_shift, dir1s_after_shift): assert approx_equal(a, b, eps=1.0e-10) for a, b in zip(dir2s_before_shift, dir2s_after_shift): assert approx_equal(a, b, eps=1.0e-10) attempts = 5 for i in range(attempts): multi_panel_detector = make_multi_panel(det) # parameterise this detector dp = DetectorParameterisationMultiPanel(multi_panel_detector, beam) p_vals = dp.get_param_vals() # apply a random parameter shift p_vals = random_param_shift( p_vals, [10, 10, 10, 1000.0 * pi / 18, 1000.0 * pi / 18, 1000.0 * pi / 18]) dp.set_param_vals(p_vals) # compare analytical and finite difference derivatives # get_fd_gradients will implicitly only get gradients for the # 1st panel in the detector, so explicitly get the same for the # analytical gradients for j in range(9): an_ds_dp = dp.get_ds_dp(multi_state_elt=j) fd_ds_dp = get_fd_gradients(dp, [1.0e-7] * dp.num_free(), multi_state_elt=j) for k in range(6): assert approx_equal( (fd_ds_dp[k] - matrix.sqr(an_ds_dp[k])), matrix.sqr((0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)), eps=1.0e-5, out=None, ), textwrap.dedent("""\ Failure comparing analytical with finite difference derivatives. Failure in try {i} for panel number {j] failure for parameter number {k} of the orientation parameterisation with fd_ds_dp = {fd} and an_ds_dp = {an} so that difference fd_ds_dp - an_ds_dp = {diff} """).format( i=i, j=j, k=k, fd=fd_ds_dp[k], an=an_ds_dp[k], diff=fd_ds_dp[k] - matrix.sqr(an_ds_dp[k]), )
def run(args): if '-h' in args or '--help' in args or '-c' in args: print(help_str) phil_scope.show(attributes_level=2) return user_phil = [] for arg in args: if os.path.isfile(arg): user_phil.append(parse("geom_path=%s" % arg)) else: try: user_phil.append(parse(arg)) except Exception as e: raise Sorry("Unrecognized argument: %s" % arg) params = phil_scope.fetch(sources=user_phil).extract() if params.distance is None: raise Usage("Please specify detector distance") geom = {} for line in open(params.geom_path): if len(line.split("=")) != 2: continue if "rigid_group" in line and not "collection" in line: geom[line.split("=")[1].strip()] = {} else: for key in geom: if line.startswith("%s/" % key): geom[key][line.split("=")[0].split("/") [1].strip()] = line.split("=")[-1].strip() detector = Detector() root = detector.hierarchy() root.set_frame((1, 0, 0), (0, 1, 0), (0, 0, -params.distance)) for i, key in enumerate(sorted(geom)): fs_x, fs_y = geom[key]['fs'].split(" ") ss_x, ss_y = geom[key]['ss'].split(" ") fast = matrix.col( (-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 import BeamFactory wavelength = params.wavelength beam = BeamFactory.simple(wavelength) from dxtbx.model import Experiment, ExperimentList from dxtbx.model.experiment_list import ExperimentListDumper experiments = ExperimentList() experiment = Experiment(detector=detector, beam=beam) experiments.append(experiment) dump = ExperimentListDumper(experiments) dump.as_json("geometry.json")
def _beam_from_dict(obj): ''' Get a beam from a dictionary. ''' from dxtbx.model import BeamFactory return BeamFactory.from_dict(obj)
def __init__(self, params): import cPickle as pickle from dxtbx.model import BeamFactory from dxtbx.model import DetectorFactory from dxtbx.model.crystal import crystal_model from cctbx.crystal_orientation import crystal_orientation, basis_type from dxtbx.model 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 = BeamFactory.simple(wavelength=wavelength) detector = DetectorFactory.simple( sensor=DetectorFactory.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()