def test_mask_argument(self): # simple smoke test to make sure we can interpolate with a mask q_value = np.array([1.0, 2.0]) num_phi = 360 mask = np.random.binomial(1, 0.1, size=self.i.shape) s = xray.Shotset(self.i, self.d, mask=mask) s.interpolate_to_polar()
def test_interpolation_consistency(self): # TJL warning: these methods are working, but this test is *weak* # I am not sure why turning up the tol causes fails :( q_values = np.array([2.0, 4.0]) de = xray.Detector.generic(spacing=0.4, force_explicit=True) s1 = xray.Shotset(self.i, self.d) s2 = xray.Shotset(self.i, de) p1, m1 = s1.interpolate_to_polar(q_values=q_values) p2, m2 = s2.interpolate_to_polar(q_values=q_values) p1 /= p1.max() p2 /= p2.max() assert_allclose(p1[0, 0, 1:].flatten(), p2[0, 0, 1:].flatten(), err_msg='interp intensities dont match', rtol=1.0, atol=0.5)
def setup(self): self.q_values = np.array([1.0, 2.0]) self.num_phi = 360 self.l = 50.0 self.d = xray.Detector.generic(spacing=0.4, l=self.l) self.i = np.abs(np.random.randn(self.d.num_pixels)) self.t = trajectory.load(ref_file('ala2.pdb')) self.shot = xray.Shotset(self.i, self.d)
def test_interpolation_consistency(self): q_values = np.array([2.0, 4.0]) de = xray.Detector.generic(spacing=0.4, force_explicit=True) s1 = xray.Shotset(self.i, self.d) s2 = xray.Shotset(self.i, de) p1, m1 = s1.interpolate_to_polar(q_values, self.num_phi) p2, m2 = s2.interpolate_to_polar(q_values, self.num_phi) p1 /= p1.max() p2 /= p2.max() # import matplotlib.pyplot as plt # plt.figure() # plt.plot(p1[0,0,1:].flatten()) # plt.plot(p2[0,0,1:].flatten()) # plt.show() assert_allclose(p1[0, 0, 1:].flatten(), p2[0, 0, 1:].flatten(), err_msg='interp intensities dont match', rtol=1.0, atol=0.5)
def __init__(self, filename): # EEEK raise NotImplementedError('CXI parser not complete, sorry') self.filename = filename self._get_root() self.shots = [] for entry_group in self._get_groups('entry'): self.shots.append(self._generate_shot_from_entry(entry_group)) self.shotset = xray.Shotset(self.shots)
def test_multi_panel_interp(self): # regression test ensuring detectors w/multiple basisgrid panels # are handled correctly t = structure.load_coor(ref_file('gold1k.coor')) q_values = np.array([2.66]) multi_d = xray.Detector.load(ref_file('lcls_test.dtc')) num_phi = 1080 num_molecules = 1 xyzlist = t.xyz[0, :, :] * 10.0 # convert nm -> ang. / first snapshot atomic_numbers = np.array( [a.element.atomic_number for a in t.topology.atoms]) # generate a set of random numbers that we can use to make sure the # two simulations have the same molecular orientation (and therefore) # output rfloats = np.random.rand(num_molecules, 3) # --- first, scatter onto a perfect ring q_grid = xray.xray._q_grid_as_xyz(q_values, num_phi, multi_d.k) ring_i = _cpuscatter.simulate(num_molecules, q_grid, xyzlist, atomic_numbers, rfloats=rfloats) perf = xray.Rings(q_values, ring_i[None, None, :], multi_d.k) # --- next, to the full detector q_grid2 = multi_d.reciprocal real_i = _cpuscatter.simulate(num_molecules, q_grid2, xyzlist, atomic_numbers, rfloats=rfloats) # interpolate ss = xray.Shotset(real_i, multi_d) real = ss.to_rings(q_values, num_phi) # count the number of points that differ significantly between the two diff = ( np.abs((perf.polar_intensities[0,0,:] - real.polar_intensities[0,0,:]) \ / (real.polar_intensities[0,0,:] + 1e-300) ) > 1e-3) print np.sum(diff) assert np.sum(diff) < 300
def setup(self): self.q_values = np.array([1.0, 2.0]) self.num_phi = 360 self.l = 50.0 self.d = xray.Detector.generic(spacing=0.4, l=self.l) self.t = trajectory.load(ref_file('ala2.pdb')) self.num_shots = 2 intensities = np.abs(np.random.randn(self.num_shots, self.d.num_pixels)) io.saveh('tmp_tables.h5', data=intensities) self.tables_file = tables.File('tmp_tables.h5') self.i = self.tables_file.root.data self.shot = xray.Shotset(self.i, self.d) return
def convert(self, image_filter=None, max_shot_limit=None): """ Perform the conversion from LCLS h5 files to an odin shotset. Optional Parameters ------------------- image_filter : odin.xray.ImageFilter An image filter that will get applied to each shot. max_shot_limit : int If provided, will truncate the conversion after this many shots. Returns ------- shotset : odin.xray.ShotSet A shotset containing all the shots described in the original yaml file. """ self.shot_list = [] if image_filter: self.filter = image_filter else: self.filter = None if max_shot_limit: logger.info('Discarding all but the last %d shots' % max_shot_limit) n = max_shot_limit else: n = self.num_descriptors # convert the shots using the appropriate method for i in range(n): if self.mode == 'raw': s = self._convert_raw_shot(self.descriptors[i]) elif self.mode == 'asm': s = self._convert_asm_shot(self.descriptors[i]) self.shot_list.append(s) return xray.Shotset(self.shot_list)
def test_polar_mask_conversion(self): # make a real mask that is a circle, and then it should be easy to check # that the polar mask is correct q_cutoff_index = 5 q_values = np.arange(3.5, 4.5, 0.1) q_cutoff = q_values[q_cutoff_index] rm = np.ones(self.d.num_pixels, dtype=np.bool) rm[self.d.recpolar[:, 0] < q_cutoff] = np.bool(False) shot = xray.Shotset(self.i, self.d, mask=rm) r = shot.to_rings(q_values) ref_pm = np.ones((len(q_values), r.num_phi), dtype=np.bool) ref_pm[:q_cutoff_index + 1, :] = np.bool(False) print "num px masked", ref_pm.sum(), r.polar_mask.sum() assert ref_pm.sum() == r.polar_mask.sum() # same num px masked assert_array_equal(ref_pm, r.polar_mask)
def as_shotset(self): """ Convert the CBF file to an ODIN shotset representation. Returns ------- cbf : odin.xray.Shotset The CBF file as an ODIN shotset. """ p = np.array(list(self.corner) + [self.path_length]) f = np.array([self.pixel_size[0], 0.0, 0.0]) # fast is x s = np.array([0.0, self.pixel_size[1], 0.0]) # slow is y bg = xray.BasisGrid() bg.add_grid(p, s, f, self.intensities_shape) # todo better value for photons b = xray.Beam(1e4, wavelength=self.wavelength) d = xray.Detector(bg, b.k) s = xray.Shotset(self.intensities.flatten().astype(np.float64), d, self.mask) return s
def files_to_shotset(cls, list_of_cbf_files, shotset_filename=None, autocenter=True): """ Convert a bunch of CBF files to a single ODIN shotset instance. If you write the shotset immediately to disk, does this in a smart "lazy" way so as to preseve memory. Parameters ---------- list_of_cbf_files : list of str A list of paths to CBF files to convert. Optional Parameters ------------------- shotset_filename : str The filename of the shotset to write to disk. autocenter : bool Whether or not to automatically determine the center of the detector. Returns ------- ss : odin.xray.Shotset If `shotset_filename` is None, then returns the shotset object """ # convert one CBF, and use it to get the detector, etc info seed_shot = cls(list_of_cbf_files[0], autocenter=autocenter).as_shotset() if shotset_filename: logger.info('writing CBF files straight to disk at: %s' % shotset_filename) seed_shot.save(shotset_filename) # now open a handle to that h5 file and add to it for i, fn in enumerate(list_of_cbf_files[1:]): # i+1 b/c we already saved one shot d = { ('shot%d' % (i + 1, )): cls(fn, autocenter=False).intensities.flatten() } io.saveh(shotset_filename, **d) io.saveh(shotset_filename, num_shots=np.array([len(list_of_cbf_files)])) logger.info('Combined CBF data into: %s' % shotset_filename) return else: shot_i = np.zeros( (len(list_of_cbf_files), seed_shot.intensities.shape[1])) shot_i[0, :] = seed_shot.intensities.flatten() for i, fn in enumerate(list_of_cbf_files[1:]): x = cls(fn, autocenter=False).intensities.flatten() if not len(x) == shot_i.shape[1]: raise ValueError('Variable number of pixels in shots!') shot_i[i + 1, :] = x ss = xray.Shotset(shot_i, seed_shot.detector, seed_shot.mask) return ss