def __init__(SMG, goniometer): from scitbx.array_family import flex import math SMG.goniometer = goniometer coords = flex.vec3_double() axis = flex.size_t() # FACE A: Sample holder # Defined as semi-circle of radius r(A) = 10 mm (centred on PHI axis) # with rectangle of size a(A) = 12.8 mm (x 20 mm) offsetA = 33.0 # semi-circle for phi=-90 ... +90 radiusA = 10.0 phi = flex.double_range(-90, 100, step=10) * math.pi / 180 x = flex.double(phi.size(), -offsetA) y = radiusA * flex.cos(phi) z = radiusA * flex.sin(phi) # corners of square sqdA = 12.8 # square depth nsteps = 10 for i in range(nsteps + 1): for sign in (+1, -1): x.append(-offsetA) y.append(i * -sqdA / nsteps) z.append(sign * radiusA) x.append(-offsetA) y.append(-sqdA) z.append(0) SMG.faceA = flex.vec3_double(x, y, z) # FACE B: Lower arm sx = -28.50 sy = -4.90 sz = 8.50 mx = -13.80 my = -26.00 nx = -27.50 ny = -29.50 px = -65.50 py = -29.50 SMG.faceB = flex.vec3_double( ((sx, sy, sz), (mx, my, 0), (nx, ny, 0), (px, py, 0))) # FACE E: Rim of sample holder # Defined as circle of radius r(E) = 6 mm (centred on PHI axis) at an # offset o(E) = 19 mm offsetE = 19.0 radiusE = 6.0 phi = flex.double_range(0, 360, step=15) * math.pi / 180 x = flex.double(phi.size(), -offsetE) y = radiusE * flex.cos(phi) z = radiusE * flex.sin(phi) SMG.faceE = flex.vec3_double(x, y, z)
def __init__(self, goniometer): # FACE A: Sample holder # Defined as semi-circle of radius r(A) = 10 mm (centred on PHI axis) # with rectangle of size a(A) = 12.8 mm (x 20 mm) offsetA = 33.0 # semi-circle for phi=-90 ... +90 radiusA = 10.0 phi = flex.double_range(-90, 100, step=10) * math.pi / 180 x = flex.double(phi.size(), -offsetA) y = radiusA * flex.cos(phi) z = radiusA * flex.sin(phi) # corners of square sqdA = 12.8 # square depth nsteps = 10 for i in range(nsteps + 1): for sign in (+1, -1): x.append(-offsetA) y.append(i * -sqdA / nsteps) z.append(sign * radiusA) x.append(-offsetA) y.append(-sqdA) z.append(0) self.faceA = flex.vec3_double(-x, -y, z) # FACE B: Lower arm sx = -28.50 sy = -4.90 sz = 8.50 mx = -13.80 my = -26.00 nx = -27.50 ny = -29.50 px = -65.50 py = -29.50 self.faceB = flex.vec3_double( ((-sx, -sy, sz), (-mx, -my, 0), (-nx, -ny, 0), (-px, -py, 0)) ) # FACE E: Rim of sample holder # Defined as circle of radius r(E) = 6 mm (centred on PHI axis) at an # offset o(E) = 19 mm offsetE = 19.0 radiusE = 6.0 phi = flex.double_range(0, 360, step=15) * math.pi / 180 x = flex.double(phi.size(), -offsetE) y = radiusE * flex.cos(phi) z = radiusE * flex.sin(phi) self.faceE = flex.vec3_double(-x, -y, z) extrema_at_datum = self.faceA.deep_copy() extrema_at_datum.extend(self.faceE) super().__init__( goniometer, extrema_at_datum, flex.size_t(extrema_at_datum.size(), 1) )
def __init__(self, goniometer): from scitbx.array_family import flex import math self.goniometer = goniometer coords = flex.vec3_double() axis = flex.size_t() # FACE A: Sample holder # Defined as semi-circle of radius r(A) = 10 mm (centred on PHI axis) # with rectangle of size a(A) = 12.8 mm (x 20 mm) offsetA = 33.0 radiusA = 10.0 sqdA = 12.8 # square depth phi = flex.double_range(-90, 100, step=10) * math.pi / 180 x = flex.double(phi.size(), -offsetA) y = radiusA * flex.cos(phi) z = radiusA * flex.sin(phi) x.extend(flex.double(5, -offsetA)) y.extend(flex.double((-sqdA / 2, -sqdA, -sqdA, -sqdA, -sqdA / 2))) z.extend(flex.double((radiusA, radiusA, 0, -radiusA, -radiusA))) self.faceA = flex.vec3_double(x, y, z) # FACE B: Lower arm sx = -28.50 sy = -4.90 sz = 8.50 mx = -13.80 my = -26.00 nx = -27.50 ny = -29.50 px = -65.50 py = -29.50 self.faceB = flex.vec3_double( ((sx, sy, sz), (mx, my, 0), (nx, ny, 0), (px, py, 0))) # FACE E: Rim of sample holder # Defined as circle of radius r(E) = 6 mm (centred on PHI axis) at an # offset o(E) = 19 mm offsetE = 19.0 radiusE = 6.0 phi = flex.double_range(0, 360, step=15) * math.pi / 180 x = flex.double(phi.size(), -offsetE) y = radiusE * flex.cos(phi) z = radiusE * flex.sin(phi) self.faceE = flex.vec3_double(x, y, z)
def __init__(self, goniometer): from scitbx.array_family import flex import math self.goniometer = goniometer coords = flex.vec3_double() axis = flex.size_t() # FACE A: Sample holder # Defined as semi-circle of radius r(A) = 10 mm (centred on PHI axis) # with rectangle of size a(A) = 12.8 mm (x 20 mm) offsetA = 33.0 radiusA = 10.0 sqdA = 12.8 # square depth phi = flex.double_range(-90, 100, step=10) * math.pi/180 x = flex.double(phi.size(), -offsetA) y = radiusA * flex.cos(phi) z = radiusA * flex.sin(phi) x.extend(flex.double(5, -offsetA)) y.extend(flex.double((-sqdA/2, -sqdA, -sqdA, -sqdA, -sqdA/2))) z.extend(flex.double((radiusA, radiusA, 0, -radiusA, -radiusA))) self.faceA = flex.vec3_double(x, y, z) # FACE B: Lower arm sx = -28.50 sy = -4.90 sz = 8.50 mx = -13.80 my = -26.00 nx = -27.50 ny = -29.50 px = -65.50 py = -29.50 self.faceB = flex.vec3_double(((sx,sy,sz),(mx,my,0),(nx,ny,0),(px,py,0))) # FACE E: Rim of sample holder # Defined as circle of radius r(E) = 6 mm (centred on PHI axis) at an # offset o(E) = 19 mm offsetE = 19.0 radiusE = 6.0 phi = flex.double_range(0, 360, step=15) * math.pi/180 x = flex.double(phi.size(), -offsetE) y = radiusE * flex.cos(phi) z = radiusE * flex.sin(phi) self.faceE = flex.vec3_double(x, y, z)
def _plot(self): fig = plt.figure() ax = fig.add_subplot(111) minor_loc = MultipleLocator(10) ax.yaxis.set_minor_locator(minor_loc) ax.xaxis.set_minor_locator(minor_loc) ax.grid(True, which="minor") ax.set_axisbelow(True) ax.set_aspect("equal") ax.set_xlabel(r"$F_c$") ax.set_ylabel(r"$F_o$") ax.scatter(self.fc, self.fobs, s=1, c="indianred") if self.params.max_Fc: ax.set_xlim((0, self.params.max_Fc)) ax.set_ylim((0, self.params.max_Fc)) if self.params.show_y_eq_x: ax.plot(ax.get_xlim(), ax.get_ylim(), ls="--", c="0.0", linewidth=0.8) if self.model_fit: x = flex.double_range(0, int(ax.get_xlim()[1])) y = self.model_fit(x) ax.plot(x, y, c="0.0", linewidth=0.8) print("Saving plot to {0}".format(self.params.plot_filename)) plt.savefig(self.params.plot_filename)
def __init__(self, normalised, **kwds): super(klass, self).__init__(n_parameters=3, normalised=normalised) libtbx.adopt_optional_init_args(self, kwds) self.t = t = flex.double_range(self.n_data) / self.n_data noise = self.noise * flex.double([(-1)**i for i in xrange(self.n_data)]) self.yo = 2. * t**2. * (1 - t) + noise self.one = flex.double(self.n_data, 1) self.t2 = t**2 self.t3 = t**3 self.restart()
def __init__(self, normalised, **kwds): super(polynomial_fit, self).__init__(n_parameters=3, normalised=normalised) libtbx.adopt_optional_init_args(self, kwds) self.t = t = flex.double_range(self.n_data)/self.n_data noise = self.noise*flex.double([ (-1)**i for i in xrange(self.n_data) ]) self.yo = 2.*t**2.*(1-t) + noise self.one = flex.double(self.n_data, 1) self.t2 = t**2 self.t3 = t**3 self.restart()
def find_delta(rho_map, tol): """ Find delta as hinted on fig. 1 of ref. [1] in module charge_flipping """ rho = rho_map.real_map_unpadded().as_1d() max_rho = flex.max(rho) rho /= max_rho sorting = flex.sort_permutation(rho) sorted_rho = rho.select(sorting) n = len(sorted_rho) p,q = n//4, 3*n//4 indexes = flex.double_range(p,q) values = sorted_rho[p:q] c = flex.linear_correlation(indexes, values) assert c.is_well_defined() and c.coefficient() > 0.99 r = flex.linear_regression(indexes, values) a,b = r.y_intercept(), r.slope() deviation = flex.abs(a + b*flex.double_range(n) - sorted_rho) non_linear_sel = deviation > tol low = flex.first_index(non_linear_sel, False) high = flex.last_index(non_linear_sel, False) assert non_linear_sel[low:high].count(False)/(high-low+1) > 0.99 assert sorted_rho[low] < 0 and sorted_rho[high] > 0 return min(sorted_rho[high], -sorted_rho[low]), max_rho
def __init__(self): super(exponential_fit, self).__init__(n_parameters=4) self.t = 0.02 * flex.double_range(1, self.n_data + 1) self.y = flex.double( (0.090542, 0.124569, 0.179367, 0.195654, 0.269707, 0.286027, 0.289892, 0.317475, 0.308191, 0.336995, 0.348371, 0.321337, 0.299423, 0.338972, 0.304763, 0.288903, 0.300820, 0.303974, 0.283987, 0.262078, 0.281593, 0.267531, 0.218926, 0.225572, 0.200594, 0.197375, 0.182440, 0.183892, 0.152285, 0.174028, 0.150874, 0.126220, 0.126266, 0.106384, 0.118923, 0.091868, 0.128926, 0.119273, 0.115997, 0.105831, 0.075261, 0.068387, 0.090823, 0.085205, 0.067203)) assert len(self.y) == len(self.t) self.restart()
def __init__(self): super(exponential_fit, self).__init__(n_parameters=4) self.t = 0.02*flex.double_range(1, self.n_data + 1) self.y = flex.double(( 0.090542, 0.124569, 0.179367, 0.195654, 0.269707, 0.286027, 0.289892, 0.317475, 0.308191, 0.336995, 0.348371, 0.321337, 0.299423, 0.338972, 0.304763, 0.288903, 0.300820, 0.303974, 0.283987, 0.262078, 0.281593, 0.267531, 0.218926, 0.225572, 0.200594, 0.197375, 0.182440, 0.183892, 0.152285, 0.174028, 0.150874, 0.126220, 0.126266, 0.106384, 0.118923, 0.091868, 0.128926, 0.119273, 0.115997, 0.105831, 0.075261, 0.068387, 0.090823, 0.085205, 0.067203 )) assert len(self.y) == len(self.t) self.restart()
def exercise_a_tr_diag_a_and_a_diag_a_tr(): from scitbx.random import variate, uniform_distribution for m, n in [(5, 5), (3, 5), (5, 3)]: random_matrices = variate( sparse.matrix_distribution(m, n, density=0.6, elements=uniform_distribution(min=-3, max=10))) w = flex.double_range(0, m) ww = flex.double(m * m) ww.resize(flex.grid(m, m)) ww.matrix_diagonal_set_in_place(diagonal=w) for n_test in range(50): a = next(random_matrices) b = a.self_transpose_times_diagonal_times_self(w) aa = a.as_dense_matrix() bb = b.as_dense_matrix() assert approx_equal( bb, aa.matrix_transpose().matrix_multiply(ww).matrix_multiply(aa)) c = a.transpose().self_times_diagonal_times_self_transpose(w) cc = c.as_dense_matrix() assert approx_equal(cc, bb)
def get_goniometer_shadow_masker(self, goniometer=None): from dials.util.masking import GoniometerShadowMaskGenerator from scitbx.array_family import flex import math coords = flex.vec3_double(((0, 0, 0), )) alpha = flex.double_range(0, 190, step=10) * math.pi / 180 r = flex.double(alpha.size(), 40) x = flex.double(r.size(), 107.61) y = -r * flex.sin(alpha) z = -r * flex.cos(alpha) coords.extend(flex.vec3_double(x, y, z)) coords.extend( flex.vec3_double(( # fixed (107.49, 7.84, 39.49), (107.39, 15.69, 38.97), (107.27, 23.53, 38.46), (107.16, 31.37, 37.94), (101.76, 33.99, 36.25), (96.37, 36.63, 34.56), (90.98, 39.25, 33.00), (85.58, 41.88, 31.18), (80.89, 47.06, 31.00), (76.55, 51.51, 31.03), (72.90, 55.04, 31.18), (66.86, 60.46, 31.67), (62.10, 64.41, 32.25), ))) alpha = flex.double_range(180, 370, step=10) * math.pi / 180 r = flex.double(alpha.size(), 33) x = (flex.sqrt(flex.pow2(r * flex.sin(alpha)) + 89.02**2) * flex.cos((50 * math.pi / 180) - flex.atan(r / 89.02 * flex.sin(alpha)))) y = (flex.sqrt(flex.pow2(r * flex.sin(alpha)) + 89.02**2) * flex.sin((50 * math.pi / 180) - flex.atan(r / 89.02 * flex.sin(alpha)))) z = -r * flex.cos(alpha) coords.extend(flex.vec3_double(x, y, z)) coords.extend( flex.vec3_double(( # fixed (62.10, 64.41, -32.25), (66.86, 60.46, -31.67), (72.90, 55.04, -31.18), (76.55, 51.51, -31.03), (80.89, 47.06, -31.00), (85.58, 41.88, -31.18), (90.98, 39.25, -33.00), (96.37, 36.63, -34.56), (101.76, 33.99, -36.25), (107.16, 31.37, -37.94), (107.27, 23.53, -38.46), (107.39, 15.69, -38.97), (107.49, 7.84, -39.49), (107.61, 0.00, -40.00)))) # I23 end station coordinate system: # X-axis: positive direction is facing away from the storage ring (from # sample towards goniometer) # Y-axis: positive direction is vertically up # Z-axis: positive direction is in the direction of the beam (from # sample towards detector) # K-axis (kappa): at an angle of +50 degrees from the X-axis # K & phi rotation axes: clockwise rotation is positive (right hand # thumb rule) # Omega-axis: along the X-axis; clockwise rotation is positive # End station x-axis is parallel to ImgCIF x-axis # End station z-axis points in opposite direction to ImgCIF definition # (ImgCIF: The Z-axis is derived from the source axis which goes from # the sample to the source) # Consequently end station y-axis (to complete set following right hand # rule) points in opposite direction to ImgCIF y-axis. # Kappa arm aligned with -y in ImgCIF convention from rstbx.cftbx.coordinate_frame_helpers import align_reference_frame from scitbx import matrix R = align_reference_frame(matrix.col((1, 0, 0)), matrix.col((1, 0, 0)), matrix.col((0, 1, 0)), matrix.col( (0, -1, 0))) coords = R.elems * coords if goniometer is None: goniometer = self.get_goniometer() return GoniometerShadowMaskGenerator(goniometer, coords, flex.size_t(len(coords), 1))
def render(self, canvas): from scitbx.array_family import flex from libtbx.utils import frange import math size = self.GetSize() border = 10 i_rows = flex.double_range(border, size[1] - border) scene = self.scene if self.scene.settings.scale_colors_multiplicity: data = self.scene.multiplicities.data() else: data = self.scene.data if self.settings.sqrt_scale_colors: data = flex.sqrt(data) min_data = flex.min(data) max_data = flex.max(data) data_for_colors = flex.double( frange(max_data, min_data, -(max_data - min_data) / len(i_rows))) tick_step = int(math.ceil((max_data - min_data) / 10)) i_row_ticks = [] tick_text = [] start_tick = math.floor(max_data) i_tick = 0 for i in range(len(data_for_colors) - 1): tick_d = start_tick - tick_step * i_tick if abs(data_for_colors[i] - tick_d) < abs(data_for_colors[i + 1] - tick_d): i_row_ticks.append(i_rows[i]) tick_text.append(str(int(tick_d))) i_tick += 1 tick_d = start_tick - tick_step * i_tick if tick_d == min_data: i_row_ticks.append(i_rows[-1]) tick_text.append(str(int(tick_d))) from scitbx import graphics_utils if (self.settings.color_scheme in ["rainbow", "heatmap", "redblue"]): colors = graphics_utils.color_by_property( properties=data_for_colors, selection=flex.bool(data_for_colors.size(), True), color_all=False, gradient_type=self.settings.color_scheme) elif (self.settings.color_scheme == "grayscale"): colors = graphics_utils.grayscale_by_property( properties=data_for_colors, selection=flex.bool(data_for_colors.size(), True), shade_all=False, invert=self.settings.black_background) else: if (self.settings.black_background): base_color = (1.0, 1.0, 1.0) else: base_color = (0.0, 0.0, 0.0) colors = flex.vec3_double(data_for_colors.size(), base_color) l_padding = border r_padding = 4 * border for i_row, color in zip(i_rows, colors): self.draw_line(canvas, l_padding, i_row, size[0] - r_padding, i_row, color=color) for i_row, text in zip(i_row_ticks, tick_text): self.draw_text(canvas, text, size[0] - 0.8 * r_padding, i_row - 5) self.draw_line(canvas, size[0] - r_padding - 10, i_row, size[0] - r_padding, i_row)
def generate_image(self, image_no=1): expr_no = image_no - self.start crystal = self.experiments[int(expr_no)].crystal # Set the beam for this image beam = self.beam print("Generating image {0}".format(image_no)) print("DIALS beam centre will be", self.detector[0].get_beam_centre(beam.get_s0())) # Construct simulation. Ugh, it prints a load of stuff from C++ that is not # easy to suppress. print("Ignore the following output from simtbx") print("#######################################") SIM = nanoBragg(self.detector, beam, verbose=1) print("#######################################") # Set Ncells to give approx 200nm cube a, b, c, aa, bb, cc = self._unit_cell.parameters() Na = int(round(2000 / a)) Nb = int(round(2000 / b)) Nc = int(round(2000 / c)) print("setting Ncells:", (Na, Nb, Nc)) SIM.Ncells_abc = (Na, Nb, Nc) # set different random number seed for noise generation for each image SIM.seed = image_no SIM.oversample = 1 SIM.progress_meter = False # only really useful for long runs # SIM.default_F=100 # this will become F000, marking the beam center # use crystal structure to initialize Fhkl array SIM.Fhkl = self.sfall # This does not 'stick': "ERROR: cannot initialize without a cell" # SIM.Amatrix = self.crystal.get_A() # WORKAROUND: Instead, use nanoBragg to set the A matrix by missets, then # update the dxtbx crystal to keep track SIM.missets_deg = (uniform(0, 360), uniform(0, 360), uniform(0, 360)) # Apparently this needs the transpose crystal.set_A(matrix.sqr(SIM.Amatrix).transpose()) SIM.xtal_shape = shapetype.Gauss # fastest option, least realistic SIM.flux = 1e12 # photons/s SIM.beamsize_mm = 0.01 # assumes round beam SIM.exposure_s = 0.1 SIM.divergence_hv_mrad = 0.07, 0.07 SIM.divsteps_hv = 6, 6 # Set mosaic spread _before_ setting the number of domains. If the # mosaicity is zero, the domain count is always reset to 1. SIM.mosaic_spread_deg = 0.1 SIM.mosaic_domains = 10 # Set detector noise and offset parameters to zero SIM.adc_offset_adu = 0 SIM.readout_noise_adu = 0 SIM.detector_calibration_noise_pct = 0 # Now actually burn up some CPU SIM.add_nanoBragg_spots() # Amplify spot signal SIM.raw_pixels *= 100 # Write out the noise-free image with a pedestal matching that reported in # the header SIM.raw_pixels += SIM.adc_offset_adu fileout = "intimage_{0:05d}.img".format(image_no) SIM.to_smv_format(fileout=fileout, intfile_scale=1) SIM.raw_pixels -= SIM.adc_offset_adu # Add background scatter: interpolation points for sin(theta/lambda) # vs structure factor. Model ED images approximately using an # exponential fall off stol = flex.double_range(0, 51, 2) / 100 scatt = 70 * flex.exp(-7 * stol) bg = flex.vec2_double(stol, scatt) SIM.Fbg_vs_stol = bg SIM.amorphous_sample_thick_mm = 0.3 SIM.amorphous_density_gcm3 = 1 SIM.amorphous_molecular_weight_Da = 18 SIM.add_background() # Add scatter from rough approximation to air # bg = flex.vec2_double([(0,14.1),(0.045,13.5),(0.174,8.35),(0.35,4.78), # (0.5,4.22)]) # SIM.Fbg_vs_stol = bg # SIM.amorphous_sample_thick_mm = 35 # between beamstop and collimator # SIM.amorphous_density_gcm3 = 1.2e-3 # SIM.amorphous_sample_molecular_weight_Da = 28 # nitrogen = N2 # SIM.add_background() # detector PSF params for apply_psf(), called within add_noise() SIM.detector_psf_kernel_radius_pixels = 0 SIM.detector_psf_fwhm_mm = 0.05 SIM.detector_psf_type = shapetype.Gauss # Add the various noise sources SIM.add_noise() # Write out image with noise fileout = "noiseimage_{0:05d}.img".format(image_no) SIM.to_smv_format(fileout=fileout, intfile_scale=1) SIM.free_all() # Set an imageset in the experiment list using the noiseimage self.set_imageset(fileout, expr_no) self.experiments[expr_no:expr_no + 1].as_file("experiments_%03d.json" % image_no)
def exercise_vector(): v = sparse.vector(5) assert v.size == 5 assert v.is_structurally_zero() v[1] = 2 v[2] = 0 v[3] = 6 assert list(v) == [(1,2.), (2,0.), (3,6.)] assert list(v.compact()) == [(1,2.), (2,0.), (3,6.)] assert [ v[i] for i in xrange(5) ] == [0, 2, 0, 6, 0] p = flex.size_t([1,2,3,4,0]) assert list(v.permute(p)) == [(2,2.), (3,0.), (4,6.)] assert v.non_zeroes == 3 v = sparse.vector(10) v[7] = -5 v[1] = -1 v[4] = 0 v[1] = 2 v[9] = 9. v[7] = 6 v[4] = 1 v[1] = 3 v[4] = 0 assert list(v.compact()) == [(1,3.), (4,0.), (7,6.), (9,9.)] assert ([ v.is_structural_zero(i) for i in xrange(10) ] == [ True, False, True, True, False, True, True, False, True, False ]) v = sparse.vector(10) v[4] += 1 v[5] += 2 v[4] += 2 v[5] = 1 v[3] = 2 v[5] += 3 assert list(v.compact()) == [ (3,2.), (4,3.), (5,4.) ] assert v.non_zeroes == 3 v = sparse.vector(6) v[3] = 1 v[2] = 1 v[5] = 1 assert v.size == 6 v[7] = 1 assert v[7] == 0 assert v.size == 6 u = flex.double((1, -1, 2, 0, -2)) v = sparse.vector(5) v[0] = 10 v[3] = 4 v[4] = 5 assert u*v == 0 u = sparse.vector(10, {1:1, 3:3, 7:7}) v = sparse.vector(10, {0:-1, 1:2, 7:-1, 8:2}) assert u*v == -5 assert sparse.weighted_dot(u, flex.double_range(10), v) == -47 a = flex.double() for i in xrange(10): for j in xrange(i,10): a.append(1/(i+j+1)) assert approx_equal(sparse.quadratic_form(u, a, v), 4003/1980, eps=1e-15) assert approx_equal(sparse.quadratic_form(a, u), sparse.quadratic_form(u, a, u), eps=1e-15) sparse_approx_equal = sparse.approx_equal(tolerance=0.1) u = sparse.vector(4) u[0] = 1.01 v = sparse.vector(4) v[0] = 1.02 v[3] = 0.001 assert sparse_approx_equal(u,v) u = sparse.vector(4) v = sparse.vector(4) v[3] = 0.001 assert sparse_approx_equal(u,v) u = sparse.vector(5, {3: 0.3, 1: 0.1}) assert list(u.as_dense_vector()) == [ 0, 0.1, 0, 0.3, 0 ] try: sparse.vector(4, [1, 2, 3, 4]) raise Exception_expected except Exception, e: assert e.__class__.__module__ == 'Boost.Python' assert e.__class__.__name__ == 'ArgumentError'
# Problem 18 from Nielsen's collection def model(x, t, only_value): exp_x0_t = math.exp(x[0] * t) exp_x1_t = math.exp(x[1] * t) value = x[2] * exp_x0_t + x[3] * exp_x1_t if not only_value: derivatives = (t * x[2] * exp_x0_t, t * x[3] * exp_x1_t, exp_x0_t, exp_x1_t) return (value, derivatives) else: return value # t: independent variable (like hkl in intro) # = [0.02, 0.04, 0.06, ..., 0.9] t = 0.02 * flex.double_range(1, n + 1) #noise = flex.double(n) # zeroes noise = 1e-5 * (2 * flex.random_double(n) - 1) # between -1 and 1 # Generate data x_star = (-4, -5, 4, -4) yo = flex.double(n) for i in xrange(n): yo[i] = model(x_star, t[i], only_value=True) + noise[i] print "Data" for ind, dep in zip(t, yo): print ind, dep print x_0 = (-1, -2, 1, -1) # starting point
def exercise_vector(): v = sparse.vector(5) assert v.size == 5 assert v.is_structurally_zero() v[1] = 2 v[2] = 0 v[3] = 6 assert list(v) == [(1, 2.), (2, 0.), (3, 6.)] assert list(v.compact()) == [(1, 2.), (2, 0.), (3, 6.)] assert [v[i] for i in range(5)] == [0, 2, 0, 6, 0] p = flex.size_t([1, 2, 3, 4, 0]) assert list(v.permute(p)) == [(2, 2.), (3, 0.), (4, 6.)] assert v.non_zeroes == 3 v = sparse.vector(10) v[7] = -5 v[1] = -1 v[4] = 0 v[1] = 2 v[9] = 9. v[7] = 6 v[4] = 1 v[1] = 3 v[4] = 0 assert list(v.compact()) == [(1, 3.), (4, 0.), (7, 6.), (9, 9.)] assert ([v.is_structural_zero(i) for i in range(10)] == [ True, False, True, True, False, True, True, False, True, False ]) v = sparse.vector(10) v[4] += 1 v[5] += 2 v[4] += 2 v[5] = 1 v[3] = 2 v[5] += 3 assert list(v.compact()) == [(3, 2.), (4, 3.), (5, 4.)] assert v.non_zeroes == 3 v = sparse.vector(6) v[3] = 1 v[2] = 1 v[5] = 1 assert v.size == 6 v[7] = 1 assert v[7] == 0 assert v.size == 6 u = flex.double((1, -1, 2, 0, -2)) v = sparse.vector(5) v[0] = 10 v[3] = 4 v[4] = 5 assert u * v == 0 u = sparse.vector(10, {1: 1, 3: 3, 7: 7}) v = sparse.vector(10, {0: -1, 1: 2, 7: -1, 8: 2}) assert u * v == -5 assert sparse.weighted_dot(u, flex.double_range(10), v) == -47 a = flex.double() for i in range(10): for j in range(i, 10): a.append(1 / (i + j + 1)) assert approx_equal(sparse.quadratic_form(u, a, v), 4003 / 1980, eps=1e-15) assert approx_equal(sparse.quadratic_form(a, u), sparse.quadratic_form(u, a, u), eps=1e-15) sparse_approx_equal = sparse.approx_equal(tolerance=0.1) u = sparse.vector(4) u[0] = 1.01 v = sparse.vector(4) v[0] = 1.02 v[3] = 0.001 assert sparse_approx_equal(u, v) u = sparse.vector(4) v = sparse.vector(4) v[3] = 0.001 assert sparse_approx_equal(u, v) u = sparse.vector(5, {3: 0.3, 1: 0.1}) assert list(u.as_dense_vector()) == [0, 0.1, 0, 0.3, 0] try: sparse.vector(4, [1, 2, 3, 4]) raise Exception_expected except Exception as e: assert e.__class__.__module__ == 'Boost.Python' assert e.__class__.__name__ == 'ArgumentError' u = sparse.vector(4, {1: 1, 3: 3}) v = flex.double([1, 2, 3, 4]) assert u * v == 14 u = sparse.vector(5) s = flex.bool((True, False, False, True, True)) v = flex.double((1, 2, 3, 4, 5)) u.set_selected(s, v) assert u == sparse.vector(5, {0: 1, 3: 4, 4: 5}) u = sparse.vector(7) i = flex.size_t((2, 4, 5)) v = flex.double((-2.0, -4.0, -5.0)) u.set_selected(i, v) assert u == sparse.vector(7, {2: -2.0, 4: -4.0, 5: -5.0}) sparse_approx_equal = sparse.approx_equal(tolerance=1e-15) def linear_combination_trial_vectors(): u = sparse.vector(8, {1: 1.1, 3: 1.3}) v = sparse.vector(8, {0: 2.0, 2: 2.2, 3: 2.3, 4: 2.4}) w = list(-2 * u.as_dense_vector() + 3 * v.as_dense_vector()) yield u, v, w random_vectors = scitbx.random.variate( sparse.vector_distribution( 8, density=0.4, elements=scitbx.random.uniform_distribution(min=-2, max=2))) u = next(random_vectors) v = next(random_vectors) w = list(-2 * u.as_dense_vector() + 3 * v.as_dense_vector()) yield u, v, w for u, v, w in itertools.islice(linear_combination_trial_vectors(), 50): w1 = -2 * u + 3 * v w2 = 3 * v - 2 * u assert sparse_approx_equal(w1, w2) assert approx_equal(list(w1.as_dense_vector()), w, eps=1e-15) w1 += 2 * u w1 /= 3 assert sparse_approx_equal(w1, v) w2 -= 3 * v w2 /= -2 assert sparse_approx_equal(w2, u) u = sparse.vector(3, {1: 2}) v = u / 2 assert v == sparse.vector(3, {1: 1})
def exercise_vector(): v = sparse.vector(5) assert v.size == 5 assert v.is_structurally_zero() v[1] = 2 v[2] = 0 v[3] = 6 assert list(v) == [(1, 2.), (2, 0.), (3, 6.)] assert list(v.compact()) == [(1, 2.), (2, 0.), (3, 6.)] assert [v[i] for i in xrange(5)] == [0, 2, 0, 6, 0] p = flex.size_t([1, 2, 3, 4, 0]) assert list(v.permute(p)) == [(2, 2.), (3, 0.), (4, 6.)] assert v.non_zeroes == 3 v = sparse.vector(10) v[7] = -5 v[1] = -1 v[4] = 0 v[1] = 2 v[9] = 9. v[7] = 6 v[4] = 1 v[1] = 3 v[4] = 0 assert list(v.compact()) == [(1, 3.), (4, 0.), (7, 6.), (9, 9.)] assert ([v.is_structural_zero(i) for i in xrange(10)] == [ True, False, True, True, False, True, True, False, True, False ]) v = sparse.vector(10) v[4] += 1 v[5] += 2 v[4] += 2 v[5] = 1 v[3] = 2 v[5] += 3 assert list(v.compact()) == [(3, 2.), (4, 3.), (5, 4.)] assert v.non_zeroes == 3 v = sparse.vector(6) v[3] = 1 v[2] = 1 v[5] = 1 assert v.size == 6 v[7] = 1 assert v[7] == 0 assert v.size == 6 u = flex.double((1, -1, 2, 0, -2)) v = sparse.vector(5) v[0] = 10 v[3] = 4 v[4] = 5 assert u * v == 0 u = sparse.vector(10, {1: 1, 3: 3, 7: 7}) v = sparse.vector(10, {0: -1, 1: 2, 7: -1, 8: 2}) assert u * v == -5 assert sparse.weighted_dot(u, flex.double_range(10), v) == -47 a = flex.double() for i in xrange(10): for j in xrange(i, 10): a.append(1 / (i + j + 1)) assert approx_equal(sparse.quadratic_form(u, a, v), 4003 / 1980, eps=1e-15) assert approx_equal(sparse.quadratic_form(a, u), sparse.quadratic_form(u, a, u), eps=1e-15) sparse_approx_equal = sparse.approx_equal(tolerance=0.1) u = sparse.vector(4) u[0] = 1.01 v = sparse.vector(4) v[0] = 1.02 v[3] = 0.001 assert sparse_approx_equal(u, v) u = sparse.vector(4) v = sparse.vector(4) v[3] = 0.001 assert sparse_approx_equal(u, v) u = sparse.vector(5, {3: 0.3, 1: 0.1}) assert list(u.as_dense_vector()) == [0, 0.1, 0, 0.3, 0] try: sparse.vector(4, [1, 2, 3, 4]) raise Exception_expected except Exception, e: assert e.__class__.__module__ == 'Boost.Python' assert e.__class__.__name__ == 'ArgumentError'
def project_extrema(self, detector, scan_angle): coords = self.extrema_at_scan_angle(scan_angle) shadow_boundary = [] for p_id, p in enumerate(detector): # project coordinates onto panel plane a = p.get_D_matrix() * coords x, y, z = a.parts() valid = z > 0 x.set_selected(valid, x.select(valid) / z.select(valid)) y.set_selected(valid, y.select(valid) / z.select(valid)) if valid.count(True) < 3: # no shadow projected onto this panel shadow_boundary.append(flex.vec2_double()) continue # Compute convex hull of shadow points points = flex.vec2_double(x.select(valid), y.select(valid)) shadow = flex.vec2_double(_convex_hull(points)) shadow *= 1 / p.get_pixel_size()[0] shadow_orig = shadow.deep_copy() for i in (0, p.get_image_size()[0]): points = flex.vec2_double( flex.double(p.get_image_size()[1], i), flex.double_range(0, p.get_image_size()[1]), ) inside = is_inside_polygon(shadow_orig, points) # only add those points needed to define vertices of shadow inside_isel = inside.iselection() outside_isel = (~inside).iselection() while inside_isel.size(): j = inside_isel[0] shadow.append(points[j]) outside_isel = outside_isel.select(outside_isel > j) if outside_isel.size() == 0: shadow.append(points[inside_isel[-1]]) break sel = inside_isel >= outside_isel[0] if sel.count(True) == 0: shadow.append(points[inside_isel[-1]]) break inside_isel = inside_isel.select(sel) for i in (0, p.get_image_size()[1]): points = flex.vec2_double( flex.double_range(0, p.get_image_size()[0]), flex.double(p.get_image_size()[0], i), ) inside = is_inside_polygon(shadow_orig, points) # only add those points needed to define vertices of shadow inside_isel = inside.iselection() outside_isel = (~inside).iselection() while inside_isel.size(): j = inside_isel[0] shadow.append(points[j]) outside_isel = outside_isel.select(outside_isel > j) if outside_isel.size() == 0: shadow.append(points[inside_isel[-1]]) break sel = inside_isel >= outside_isel[0] if sel.count(True) == 0: shadow.append(points[inside_isel[-1]]) break inside_isel = inside_isel.select(sel) # Select only those vertices that are within the panel dimensions n_px = p.get_image_size() x, y = shadow.parts() valid = (x >= 0) & (x <= n_px[0]) & (y >= 0) & (y <= n_px[1]) shadow = shadow.select(valid) # sort vertices clockwise from centre of mass com = principal_axes_of_inertia_2d(shadow).center_of_mass() sx, sy = shadow.parts() shadow = shadow.select( flex.sort_permutation(flex.atan2(sy - com[1], sx - com[0])) ) shadow_boundary.append(shadow) return shadow_boundary
def get_goniometer_shadow_masker(self, goniometer=None): from dials.util.masking import GoniometerShadowMaskGenerator from scitbx.array_family import flex import math coords = flex.vec3_double(( (0,0,0), )) alpha = flex.double_range(0, 190, step=10) * math.pi / 180 r = flex.double(alpha.size(), 40) x = flex.double(r.size(), 107.61) y = -r*flex.sin(alpha) z = -r*flex.cos(alpha) coords.extend(flex.vec3_double(x, y, z)) coords.extend(flex.vec3_double(( # fixed (107.49, 7.84, 39.49), (107.39, 15.69, 38.97), (107.27, 23.53, 38.46), (107.16, 31.37, 37.94), (101.76, 33.99, 36.25), (96.37, 36.63, 34.56), (90.98, 39.25, 33.00), (85.58, 41.88, 31.18), (80.89, 47.06, 31.00), (76.55, 51.51, 31.03), (72.90, 55.04, 31.18), (66.86, 60.46, 31.67), (62.10, 64.41, 32.25), ))) alpha = flex.double_range(180, 370, step=10) * math.pi / 180 r = flex.double(alpha.size(), 33) x = (flex.sqrt(flex.pow2(r * flex.sin(alpha)) + 89.02**2) * flex.cos((50 * math.pi/180) - flex.atan(r/89.02 * flex.sin(alpha)))) y = (flex.sqrt(flex.pow2(r * flex.sin(alpha)) + 89.02**2) * flex.sin((50 * math.pi/180) - flex.atan(r/89.02 * flex.sin(alpha)))) z = -r*flex.cos(alpha) coords.extend(flex.vec3_double(x, y, z)) coords.extend(flex.vec3_double(( # fixed (62.10, 64.41, -32.25), (66.86, 60.46, -31.67), (72.90, 55.04, -31.18), (76.55, 51.51, -31.03), (80.89, 47.06, -31.00), (85.58, 41.88, -31.18), (90.98, 39.25, -33.00), (96.37, 36.63, -34.56), (101.76, 33.99, -36.25), (107.16, 31.37, -37.94), (107.27, 23.53, -38.46), (107.39, 15.69, -38.97), (107.49, 7.84, -39.49), (107.61, 0.00, -40.00) ))) # I23 end station coordinate system: # X-axis: positive direction is facing away from the storage ring (from # sample towards goniometer) # Y-axis: positive direction is vertically up # Z-axis: positive direction is in the direction of the beam (from # sample towards detector) # K-axis (kappa): at an angle of +50 degrees from the X-axis # K & phi rotation axes: clockwise rotation is positive (right hand # thumb rule) # Omega-axis: along the X-axis; clockwise rotation is positive # End station x-axis is parallel to ImgCIF x-axis # End station z-axis points in opposite direction to ImgCIF definition # (ImgCIF: The Z-axis is derived from the source axis which goes from # the sample to the source) # Consequently end station y-axis (to complete set following right hand # rule) points in opposite direction to ImgCIF y-axis. # Kappa arm aligned with -y in ImgCIF convention from rstbx.cftbx.coordinate_frame_helpers import align_reference_frame from scitbx import matrix R = align_reference_frame(matrix.col((1,0,0)), matrix.col((1,0,0)), matrix.col((0,1,0)), matrix.col((0,-1,0))) coords = R.elems * coords if goniometer is None: goniometer = self.get_goniometer() return GoniometerShadowMaskGenerator( goniometer, coords, flex.size_t(len(coords), 1))
def project_extrema(self, detector, scan_angle): from dials.util import is_inside_polygon coords = self.extrema_at_scan_angle(scan_angle) shadow_boundary = [] for p_id, p in enumerate(detector): # project coordinates onto panel plane a = p.get_D_matrix() * coords x, y, z = a.parts() valid = z > 0 x.set_selected(valid, x.select(valid)/z.select(valid)) y.set_selected(valid, y.select(valid)/z.select(valid)) if valid.count(True) < 3: # no shadow projected onto this panel shadow_boundary.append(flex.vec2_double()) continue # Compute convex hull of shadow points points = flex.vec2_double(x.select(valid), y.select(valid)) shadow = flex.vec2_double(convex_hull(points)) shadow *= 1/p.get_pixel_size()[0] shadow_orig = shadow.deep_copy() for i in (0, p.get_image_size()[0]): points = flex.vec2_double(flex.double(p.get_image_size()[1], i), flex.double_range(0, p.get_image_size()[1])) inside = is_inside_polygon(shadow_orig, points) # only add those points needed to define vertices of shadow inside_isel = inside.iselection() outside_isel = (~inside).iselection() while inside_isel.size(): j = inside_isel[0] shadow.append(points[j]) outside_isel = outside_isel.select(outside_isel > j) if outside_isel.size() == 0: shadow.append(points[inside_isel[-1]]) break sel = inside_isel >= outside_isel[0] if sel.count(True) == 0: shadow.append(points[inside_isel[-1]]) break inside_isel = inside_isel.select(sel) for i in (0, p.get_image_size()[1]): points = flex.vec2_double(flex.double_range(0, p.get_image_size()[0]), flex.double(p.get_image_size()[0], i)) inside = is_inside_polygon(shadow_orig, points) # only add those points needed to define vertices of shadow inside_isel = inside.iselection() outside_isel = (~inside).iselection() while inside_isel.size(): j = inside_isel[0] shadow.append(points[j]) outside_isel = outside_isel.select(outside_isel > j) if outside_isel.size() == 0: shadow.append(points[inside_isel[-1]]) break sel = inside_isel >= outside_isel[0] if sel.count(True) == 0: shadow.append(points[inside_isel[-1]]) break inside_isel = inside_isel.select(sel) # Select only those vertices that are within the panel dimensions n_px = p.get_image_size() x, y = shadow.parts() valid = (x >= 0) & (x <= n_px[0]) & (y >= 0) & (y <= n_px[1]) shadow = shadow.select(valid) # sort vertices clockwise from centre of mass from scitbx.math import principal_axes_of_inertia_2d com = principal_axes_of_inertia_2d(shadow).center_of_mass() sx, sy = shadow.parts() shadow = shadow.select( flex.sort_permutation(flex.atan2(sy-com[1],sx-com[0]))) shadow_boundary.append(shadow) return shadow_boundary