Esempio n. 1
0
  def plot_cdf_manually(self, reflections, panel = None, ax = None, bounds = None):
    colors = ['blue', 'green']
    r = (reflections['xyzcal.mm']-reflections['xyzobs.mm.value']).norms()
    h = flex.histogram(r)
    sigma = h.slot_centers()[list(h.slots()).index(flex.max(h.slots()))] # mode

    x_extent = max(r)
    y_extent = len(r)
    xobs = [i/x_extent for i in sorted(r)]
    yobs = [i/y_extent for i in xrange(y_extent)]
    obs = [(x, y) for x, y in zip(xobs, yobs)]

    ncalc = 100
    xcalc = [i/ncalc for i in xrange(ncalc)]
    ycalc = [1-math.exp((-i**2)/(2*(sigma**2))) for i in xcalc]
    calc = [(x, y) for x, y in zip(xcalc, ycalc)]

    data = [flex.vec2_double(obs),
            flex.vec2_double(calc)]
    if bounds is None:
      ax.set_xlim((-1,1))
      ax.set_ylim((-1,1))
      ax.set_title("%s Outlier SP Manually"%self.params.tag)
    if bounds is not None:
      data = [self.get_bounded_data(d, bounds) for d in data]

    if ax is None:
      fig = plt.figure()
      ax = fig.add_subplot(111)

    for subset,c in zip(data, colors):
        ax.plot(subset.parts()[0], subset.parts()[1], '-', c=c)
Esempio n. 2
0
def calc_2D_rmsd_and_displacements(reflections):

  displacements = flex.vec2_double(reflections['xyzobs.px.value'].parts()[0], reflections['xyzobs.px.value'].parts()[1]) - \
                  flex.vec2_double(reflections['xyzcal.px'].parts()[0], reflections['xyzcal.px'].parts()[1])
  rmsd = math.sqrt(flex.mean(displacements.dot( displacements )))

  return rmsd,displacements
Esempio n. 3
0
 def _xyzcal_mm_to_px(self, experiments, reflections):
     # set xyzcal.px field in reflections
     reflections["xyzcal.px"] = flex.vec3_double(len(reflections))
     for i, expt in enumerate(experiments):
         imgset_sel = reflections["imageset_id"] == i
         refined_reflections = reflections.select(imgset_sel)
         panel_numbers = flex.size_t(refined_reflections["panel"])
         xyzcal_mm = refined_reflections["xyzcal.mm"]
         x_mm, y_mm, z_rad = xyzcal_mm.parts()
         xy_cal_mm = flex.vec2_double(x_mm, y_mm)
         xy_cal_px = flex.vec2_double(len(xy_cal_mm))
         for i_panel in range(len(expt.detector)):
             panel = expt.detector[i_panel]
             sel = panel_numbers == i_panel
             xy_cal_px.set_selected(
                 sel, panel.millimeter_to_pixel(xy_cal_mm.select(sel))
             )
         x_px, y_px = xy_cal_px.parts()
         if expt.scan is not None:
             z_px = expt.scan.get_array_index_from_angle(z_rad, deg=False)
         else:
             # must be a still image, z centroid not meaningful
             z_px = z_rad
         xyzcal_px = flex.vec3_double(x_px, y_px, z_px)
         reflections["xyzcal.px"].set_selected(imgset_sel, xyzcal_px)
Esempio n. 4
0
def calc_2D_rmsd_and_displacements(reflections):

    displacements = flex.vec2_double(reflections['xyzobs.px.value'].parts()[0], reflections['xyzobs.px.value'].parts()[1]) - \
                    flex.vec2_double(reflections['xyzcal.px'].parts()[0], reflections['xyzcal.px'].parts()[1])
    rmsd = math.sqrt(flex.mean(displacements.dot(displacements)))

    return rmsd, displacements
Esempio n. 5
0
  def plot_histograms(self, reflections, panel = None, ax = None, bounds = None):
    data = reflections['difference_vector_norms']
    colors = ['b-', 'g-', 'g--', 'r-', 'b-', 'b--']
    n_slots = 20
    if self.params.residuals.histogram_max is None:
      h = flex.histogram(data, n_slots=n_slots)
    else:
      h = flex.histogram(data.select(data <= self.params.residuals.histogram_max), n_slots=n_slots)

    n = len(reflections)
    rmsd_obs = math.sqrt((reflections['xyzcal.mm']-reflections['xyzobs.mm.value']).sum_sq()/n)
    sigma = mode = h.slot_centers()[list(h.slots()).index(flex.max(h.slots()))]
    mean_obs = flex.mean(data)
    median = flex.median(data)
    mean_rayleigh = math.sqrt(math.pi/2)*sigma
    rmsd_rayleigh = math.sqrt(2)*sigma

    data = flex.vec2_double([(i,j) for i, j in zip(h.slot_centers(), h.slots())])
    n = len(data)
    for i in [mean_obs, mean_rayleigh, mode, rmsd_obs, rmsd_rayleigh]:
      data.extend(flex.vec2_double([(i, 0), (i, flex.max(h.slots()))]))
    data = self.get_bounded_data(data, bounds)
    tmp = [data[:n]]
    for i in xrange(len(colors)):
      tmp.append(data[n+(i*2):n+((i+1)*2)])
    data = tmp

    for d, c in zip(data, colors):
      ax.plot(d.parts()[0], d.parts()[1], c)

    if ax.get_legend() is None:
      ax.legend([r"$\Delta$XY", "MeanObs", "MeanRayl", "Mode", "RMSDObs", "RMSDRayl"])
Esempio n. 6
0
def matcher(reference, moving, params):
    from annlib_ext import AnnAdaptor as ann_adaptor
    from dials.array_family import flex

    rxyz = reference['xyzobs.px.value'].parts()
    mxyz = moving['xyzobs.px.value'].parts()

    rxy = flex.vec2_double(rxyz[0], rxyz[1])
    mxy = flex.vec2_double(mxyz[0], mxyz[1])

    ann = ann_adaptor(rxy.as_double().as_1d(), 2)
    ann.query(mxy.as_double().as_1d())
    distances = flex.sqrt(ann.distances)

    matches = (distances < params.far) & (distances >= params.close)

    xyr = flex.vec2_double()
    xym = flex.vec2_double()

    for j in range(matches.size()):
        if not matches[j]:
            continue
        xym.append(mxy[j])
        xyr.append(rxy[ann.nn[j]])

    # filter outliers - use IQR etc.
    dxy = xym - xyr

    dx, dy = dxy.parts()

    iqx = IQR(dx.select(flex.sort_permutation(dx)))
    iqy = IQR(dy.select(flex.sort_permutation(dy)))

    keep_x = (dx > (iqx[0] - iqx[3])) & (dx < (iqx[2] + iqx[3]))
    keep_y = (dy > (iqy[0] - iqy[3])) & (dy < (iqy[2] + iqy[3]))
    keep = keep_x & keep_y
    xyr = xyr.select(keep)
    xym = xym.select(keep)

    # compute Rt

    R, t, d, n = Rt(xyr, xym)

    # verify matches in original image coordinate system

    from scitbx import matrix
    import math
    _R = matrix.sqr(R)
    rmsd = 0.0
    for j, _xym in enumerate(xym):
        _xymm = _R * _xym + matrix.col(t)
        rmsd += (matrix.col(xyr[j]) - _xymm).length()**2
    assert abs(math.sqrt(rmsd / xym.size()) - d) < 1e-6

    return R, t, d, n
Esempio n. 7
0
def compute_Rt(reference, moving):
    from dials.array_family import flex

    rxyz = reference['xyzobs.px.value'].parts()
    mxyz = moving['xyzobs.px.value'].parts()

    rxy = flex.vec2_double(rxyz[0], rxyz[1])
    mxy = flex.vec2_double(mxyz[0], mxyz[1])

    # compute Rt

    return Rt(rxy, mxy)
Esempio n. 8
0
def pair_up(reference, moving, params, R0, t0):
    from annlib_ext import AnnAdaptor as ann_adaptor
    from dials.array_family import flex

    rxyz = reference['xyzobs.px.value'].parts()
    mxyz = moving['xyzobs.px.value'].parts()

    # apply R0, t0 before performing matching - so should ideally be in almost
    # right position

    rxy = flex.vec2_double(rxyz[0], rxyz[1])
    _mxy = flex.vec2_double(mxyz[0], mxyz[1])
    mxy = flex.vec2_double()
    for __mxy in _mxy:
        mxy.append((R0 * __mxy + t0).elems)

    ann = ann_adaptor(rxy.as_double().as_1d(), 2)
    ann.query(mxy.as_double().as_1d())
    distances = flex.sqrt(ann.distances)

    matches = (distances < params.far)

    rsel = flex.size_t()
    msel = flex.size_t()

    xyr = flex.vec2_double()
    xym = flex.vec2_double()

    for j in range(matches.size()):
        if not matches[j]:
            continue
        msel.append(j)
        rsel.append(ann.nn[j])
        xym.append(mxy[j])
        xyr.append(rxy[ann.nn[j]])

    # filter outliers - use IQR etc.
    dxy = xym - xyr

    dx, dy = dxy.parts()

    iqx = IQR(dx.select(flex.sort_permutation(dx)))
    iqy = IQR(dy.select(flex.sort_permutation(dy)))

    keep_x = (dx > (iqx[0] - iqx[3])) & (dx < (iqx[2] + iqx[3]))
    keep_y = (dy > (iqy[0] - iqy[3])) & (dy < (iqy[2] + iqy[3]))
    keep = keep_x & keep_y

    return rsel.select(keep), msel.select(keep)
def get_pix_coords(wavelength, A, mill_arr, detector, delta_i=0.02):
    """ Code copied from sim.py courtesy of Aaron and Tara """
    s0=col((0,0,-1/wavelength))
    q=flex.vec3_double([A*col(idx) for idx in  mill_arr.indices().as_vec3_double()])
    s0_hat=flex.vec3_double([s0.normalize()]*len(q))
    q_hat=q.each_normalize()
    #q_hat.cross(flex.vec3_double([s0_hat]*len(q_hat)))
    e1_hat = q_hat.cross(s0_hat)
    c0_hat = s0_hat.cross(e1_hat)
    q_len_sq = flex.double([col(v).length_sq() for v in q])
    a_side=q_len_sq*wavelength/2
    b_side=flex.sqrt(q_len_sq)-a_side**2
    #flex.vec3_double([sqrt(q.length_sq()-a_side**2 for idx in mill_arr)])
    r_vec=flex.vec3_double(-a_side*s0_hat+b_side*c0_hat)
    s1=r_vec+s0

    EQ=q+s0
    len_EQ=flex.double([col(v).length() for v in EQ])
    ratio=len_EQ*wavelength

    indices = flex.miller_index()
    coords =flex.vec2_double()
    for i in range(len(s1)):
        if ratio[i] > 1 - delta_i and ratio[i] < 1 + delta_i:
            indices.append(mill_arr.indices()[i])
            pix = detector[0].get_ray_intersection_px(s1[i])
            if detector[0].is_coord_valid(pix):
                coords.append(pix)

    return coords, indices
Esempio n. 10
0
        def correction_and_within_spot_sigma(params_version,
                                             variance_within_spot=True):
            absorption = KaptonAbsorption(
                params_version[0],
                params_version[1],
                params_version[2],
                params_version[3],
                self.detector_dist_mm,
                self.pixel_size_mm,
                self.wavelength_ang,
                *map(float, self.panel_size_px),
            )
            detector = self.expt.detector
            # y_max = int(detector[0].millimeter_to_pixel(detector[0].get_image_size())[1])

            absorption_corrections = flex.double()
            absorption_sigmas = (
                flex.double()
            )  # std dev of corrections for pixels within a spot, default sigma

            if variance_within_spot:
                mask_code = MaskCode.Foreground | MaskCode.Valid
                for iref in range(len(self.reflections_sele)):
                    kapton_correction_vector = flex.double()
                    # foreground: integration mask
                    shoebox = self.reflections_sele[iref]["shoebox"]
                    foreground = ((shoebox.mask.as_1d()
                                   & mask_code) == mask_code).iselection()
                    width = shoebox.xsize()
                    fast_coords = (foreground % width).as_int()  # within spot
                    slow_coords = (foreground / width).as_int()  # within spot
                    f_absolute = fast_coords + shoebox.bbox[
                        0]  # relative to detector
                    s_absolute = slow_coords + shoebox.bbox[
                        2]  # relative to detector
                    lab_coords = detector[0].get_lab_coord(
                        detector[0].pixel_to_millimeter(
                            flex.vec2_double(f_absolute.as_double(),
                                             s_absolute.as_double())))
                    s1 = lab_coords.each_normalize()
                    kapton_correction_vector.extend(
                        absorption.abs_correction_flex(s1))
                    average_kapton_correction = flex.mean(
                        kapton_correction_vector)
                    absorption_corrections.append(average_kapton_correction)
                    try:
                        spot_px_stddev = flex.mean_and_variance(
                            kapton_correction_vector
                        ).unweighted_sample_standard_deviation()
                    except Exception:
                        assert (len(kapton_correction_vector) == 1
                                ), "stddev could not be calculated"
                        spot_px_stddev = 0
                    absorption_sigmas.append(spot_px_stddev)
                return absorption_corrections, absorption_sigmas
            else:
                s1_flex = self.reflections_sele["s1"].each_normalize()
                absorption_corrections = absorption.abs_correction_flex(
                    s1_flex)
                return absorption_corrections, None
Esempio n. 11
0
def get_pix_coords(wavelength, A, mill_arr, detector, delta_i=0.02):
    """ Code copied from sim.py courtesy of Aaron and Tara """
    s0 = col((0, 0, -1 / wavelength))
    q = flex.vec3_double(
        [A * col(idx) for idx in mill_arr.indices().as_vec3_double()])
    s0_hat = flex.vec3_double([s0.normalize()] * len(q))
    q_hat = q.each_normalize()
    #q_hat.cross(flex.vec3_double([s0_hat]*len(q_hat)))
    e1_hat = q_hat.cross(s0_hat)
    c0_hat = s0_hat.cross(e1_hat)
    q_len_sq = flex.double([col(v).length_sq() for v in q])
    a_side = q_len_sq * wavelength / 2
    b_side = flex.sqrt(q_len_sq) - a_side**2
    #flex.vec3_double([sqrt(q.length_sq()-a_side**2 for idx in mill_arr)])
    r_vec = flex.vec3_double(-a_side * s0_hat + b_side * c0_hat)
    s1 = r_vec + s0

    EQ = q + s0
    len_EQ = flex.double([col(v).length() for v in EQ])
    ratio = len_EQ * wavelength

    indices = flex.miller_index()
    coords = flex.vec2_double()
    for i in range(len(s1)):
        if ratio[i] > 1 - delta_i and ratio[i] < 1 + delta_i:
            indices.append(mill_arr.indices()[i])
            pix = detector[0].get_ray_intersection_px(s1[i])
            if detector[0].is_coord_valid(pix):
                coords.append(pix)

    return coords, indices
Esempio n. 12
0
 def populate_pixel_positions(self):
     assert 'xyzcal.px' in self.reflections, "no calculated spot positions"
     self.frame['mapped_predictions'][0] = flex.vec2_double()
     for i in range(len(self.reflections['xyzcal.px'])):
         self.frame['mapped_predictions'][0].append(
             tuple(self.reflections['xyzcal.px'][i][1::-1])
         )  # 1::-1 reverses the order taking only the first two elements first.
def test_calc_lookup_index():
    pi = 3.141
    theta_phi = flex.vec2_double([(0.001, -pi), (pi, pi), (0.001, pi), (pi, -pi)])
    indices = calc_lookup_index(theta_phi, 1)
    assert list(indices) == [0, 64799, 359, 64440]
    indices = calc_lookup_index(theta_phi, 2)
    assert list(indices) == [0, 259199, 719, 258480]
Esempio n. 14
0
  def plot_difference_vector_norms_histograms(self, reflections, panel = None, ax = None, bounds = None):
    r = reflections['difference_vector_norms']*1000
    h = flex.histogram(r, n_slots=50, data_min=0, data_max=100)

    x_extent = max(r)
    y_extent = len(r)
    xobs = [i/x_extent for i in sorted(r)]
    yobs = [i/y_extent for i in xrange(y_extent)]
    obs = [(x, y) for x, y in zip(xobs, yobs)]

    if bounds is None:
      #ax.set_xlim((-1,1))
      #ax.set_ylim((-1,1))
      x = h.slot_centers().as_numpy_array()
      y = h.slots().as_numpy_array()
      ax.set_title("%s Residual norms histogram"%self.params.tag)
    if bounds is not None:
      d = flex.vec2_double(h.slot_centers(), h.slots().as_double())
      data = self.get_bounded_data(d, bounds)
      x, y = data.parts()

    if ax is None:
      fig = plt.figure()
      ax = fig.add_subplot(111)
    ax.plot(x, y, '-', c='blue')
Esempio n. 15
0
def xy_to_q(x, y, detector, beam, oldmethod=False, panel_id=0):
    """
    convert pixel coords to q-vectors

    :param x,y:  pixel coordinates of spots as separate lists/arrays
                x should be the fast-scan coord
    :param detector: dxtbx detector model
    :param beam:  dxtbx beam model
    :param method1: whether to use method 1 below..
    :return: the Q-vectors corresponding to the spots
    """
    panel = detector[panel_id]
    if oldmethod:
        pixsizeFS, pixsizeSS = panel.get_pixel_size()[0]
        orig = np.array(panel.get_origin())
        ss = np.array(panel.get_slow_axis())
        fs = np.array(panel.get_fast_axis())
        s0 = np.array(beam.get_s0())  # this is already scaled by 1/wavelength
        pix_mm = np.vstack([
            orig + fs * i * pixsizeFS + ss * j * pixsizeSS
            for i, j in zip(x, y)
        ])
        s1 = pix_mm / np.linalg.norm(pix_mm,
                                     axis=1)[:, None] / beam.get_wavelength()
        q_vecs = (s1 - s0)
    else:
        pix_mm = panel.pixel_to_millimeter(flex.vec2_double(zip(x, y)))
        coords = panel.get_lab_coord(pix_mm)
        coords = coords / coords.norms()
        q_vecs = coords * (1. / beam.get_wavelength()) - beam.get_s0()

        # I like to return as numpy array...
        q_vecs = q_vecs.as_double().as_numpy_array().reshape((len(q_vecs), 3))

    return q_vecs
Esempio n. 16
0
def test_sort():
    table = flex.reflection_table()
    table["a"] = flex.int([2, 4, 3, 1, 5, 6])
    table["b"] = flex.vec2_double([(3, 2), (3, 1), (1, 3), (4, 5), (4, 3),
                                   (2, 0)])
    table["c"] = flex.miller_index([(3, 2, 1), (3, 1, 1), (2, 4, 2), (2, 1, 1),
                                    (1, 1, 1), (1, 1, 2)])

    table.sort("a")
    assert list(table["a"]) == [1, 2, 3, 4, 5, 6]

    table.sort("b")
    assert list(table["b"]) == [(1, 3), (2, 0), (3, 1), (3, 2), (4, 3), (4, 5)]

    table.sort("c")
    assert list(table["c"]) == [
        (1, 1, 1),
        (1, 1, 2),
        (2, 1, 1),
        (2, 4, 2),
        (3, 1, 1),
        (3, 2, 1),
    ]

    table.sort("c", order=(1, 2, 0))
    assert list(table["c"]) == [
        (1, 1, 1),
        (2, 1, 1),
        (3, 1, 1),
        (1, 1, 2),
        (3, 2, 1),
        (2, 4, 2),
    ]
Esempio n. 17
0
  def get_bounded_data(self, data, bounds):
    assert len(bounds) == 4
    x = [b[0] for b in bounds]
    y = [b[1] for b in bounds]
    left = sorted(x)[1]
    right = sorted(x)[2]
    top = sorted(y)[2]
    bottom = sorted(y)[1]
    origin = col((left, bottom))
    scale_x = right-left
    scale_y = top-bottom
    scale = min(scale_x, scale_y)

    data_max_x = flex.max(data.parts()[0])
    data_min_x = flex.min(data.parts()[0])
    data_max_y = flex.max(data.parts()[1])
    data_min_y = flex.min(data.parts()[1])
    data_scale_x = data_max_x - data_min_x
    data_scale_y = data_max_y - data_min_y

    if data_scale_x == 0 or data_scale_y == 0:
      print "WARNING bad scale"
      return data

    return flex.vec2_double(data.parts()[0] * (scale/abs(data_scale_x)),
                            data.parts()[1] * (scale/abs(data_scale_y))) + origin
Esempio n. 18
0
def random_positions(n, amount):
    from scitbx.random import variate, normal_distribution
    from dials.array_family import flex
    g = variate(normal_distribution(mean=0, sigma=amount))
    xy = flex.vec2_double(n)
    for j in range(n):
        xy[j] = (next(g), next(g))
    return xy
Esempio n. 19
0
def exercise_polygon():
    from dials.algorithms.polygon import polygon

    x = 1
    y = 1
    vertices = [(0, 0), (2, 0), (2, 2), (0, 2)]
    poly = polygon(vertices)
    assert poly.is_inside(x, y)

    poly = polygon([(3, 5), (40, 90), (80, 70), (50, 50), (70, 20)])
    for p in [(42, 40), (16, 25), (64, 67), (16, 30), (48, 45), (21, 30)]:
        assert poly.is_inside(p[0], p[1])
    for p in [(59, 4), (70, 15), (57, 14), (21, 78), (37, 100), (88, 89)]:
        assert not poly.is_inside(p[0], p[1])

    if 0:
        # for visual confirmation of algorithm
        from scitbx.array_family import flex

        inside_points = flex.vec2_double()
        outside_points = flex.vec2_double()
        import random

        x_max = 100
        y_max = 100
        for i in range(1000):
            x = random.randint(0, x_max)
            y = random.randint(0, y_max)
            is_inside = poly.is_inside(x, y)
            if is_inside:
                inside_points.append((x, y))
            else:
                outside_points.append((x, y))
        from matplotlib import pyplot
        from matplotlib.patches import Polygon

        v = poly.vertices + poly.vertices[:1]
        fig = pyplot.figure()
        ax = fig.add_subplot(111)
        ax.add_patch(Polygon(poly.vertices, closed=True, fill=False))
        inside_x, inside_y = inside_points.parts()
        outside_x, outside_y = outside_points.parts()
        ax.scatter(inside_x, inside_y, marker="+", c="r")
        ax.scatter(outside_x, outside_y, marker="+", c="b")
        pyplot.show()
Esempio n. 20
0
  def plot_obs_colored_by_data(self, data, reflections, panel = None, ax = None, bounds = None):
    assert panel is not None and ax is not None and bounds is not None
    norm, cmap, color_vals, sm = self.get_normalized_colors(data)
    mm_panel_coords = flex.vec2_double(reflections['xyzobs.mm.value'].parts()[0], reflections['xyzobs.mm.value'].parts()[1])
    lab_coords = panel.get_lab_coord(mm_panel_coords)

    ax.scatter(lab_coords.parts()[0], lab_coords.parts()[1], c = data, norm=norm, cmap = cmap, linewidths=0, s=self.params.dot_size)

    return sm, color_vals
Esempio n. 21
0
        def correction_and_within_spot_sigma(params_version, variance_within_spot=True):
            # instantiate Kapton absorption class here
            absorption = KaptonTape_2019(
                params_version[0],
                params_version[1],
                params_version[2],
                params_version[3],
                self.wavelength_ang,
            )
            # *map(float, self.panel_size_px)) #
            detector = self.expt.detector

            absorption_corrections = flex.double()
            absorption_sigmas = (
                flex.double()
            )  # std dev of corrections for pixels within a spot, default sigma

            if variance_within_spot:
                mask_code = MaskCode.Foreground | MaskCode.Valid
                for iref in range(len(self.reflections_sele)):
                    kapton_correction_vector = flex.double()
                    # foreground: integration mask
                    shoebox = self.reflections_sele[iref]["shoebox"]
                    foreground = (
                        (shoebox.mask.as_1d() & mask_code) == mask_code
                    ).iselection()
                    f_absolute, s_absolute, z_absolute = (
                        shoebox.coords().select(foreground).parts()
                    )
                    panel_number = self.reflections_sele[iref]["panel"]
                    lab_coords = detector[panel_number].get_lab_coord(
                        detector[panel_number].pixel_to_millimeter(
                            flex.vec2_double(f_absolute, s_absolute)
                        )
                    )
                    s1 = lab_coords.each_normalize()
                    # Real step right here
                    kapton_correction_vector.extend(absorption.abs_correction_flex(s1))
                    #
                    average_kapton_correction = flex.mean(kapton_correction_vector)
                    absorption_corrections.append(average_kapton_correction)
                    try:
                        spot_px_stddev = flex.mean_and_variance(
                            kapton_correction_vector
                        ).unweighted_sample_standard_deviation()
                    except Exception:
                        assert (
                            len(kapton_correction_vector) == 1
                        ), "stddev could not be calculated"
                        spot_px_stddev = 0
                    absorption_sigmas.append(spot_px_stddev)
                return absorption_corrections, absorption_sigmas
            else:
                s1_flex = self.reflections_sele["s1"].each_normalize()
                absorption_corrections = absorption.abs_correction_flex(s1_flex)
                return absorption_corrections, None
Esempio n. 22
0
def exercise_polygon():
  from dials.algorithms.polygon import polygon

  x = 1
  y = 1
  vertices = [(0,0), (2,0), (2,2), (0,2)]
  poly = polygon(vertices)
  assert poly.is_inside(x,y)

  poly = polygon([(3,5), (40,90), (80,70), (50,50), (70,20)])
  for p in [(42,40), (16,25), (64,67), (16,30), (48, 45), (21,30)]:
    assert poly.is_inside(p[0], p[1])
  for p in [(59,4), (70,15), (57,14), (21,78), (37,100), (88,89)]:
    assert not poly.is_inside(p[0], p[1])

  if 0:
    # for visual confirmation of algorithm
    from scitbx.array_family import flex
    inside_points = flex.vec2_double()
    outside_points = flex.vec2_double()
    import random
    x_max = 100
    y_max = 100
    for i in range(1000):
      x = random.randint(0,x_max)
      y = random.randint(0,y_max)
      is_inside = poly.is_inside(x, y)
      if is_inside:
        inside_points.append((x,y))
      else:
        outside_points.append((x,y))
    from matplotlib import pyplot
    from matplotlib.patches import Polygon
    v = poly.vertices + poly.vertices[:1]
    fig = pyplot.figure()
    ax = fig.add_subplot(111)
    ax.add_patch(Polygon(poly.vertices, closed=True, fill=False))
    inside_x, inside_y = inside_points.parts()
    outside_x, outside_y = outside_points.parts()
    ax.scatter(inside_x, inside_y, marker='+', c='r')
    ax.scatter(outside_x, outside_y, marker='+', c='b')
    pyplot.show()
Esempio n. 23
0
    def sim_rois(self,
                 rois=None,
                 reset=True,
                 cuda=False,
                 omp=False,
                 add_water=False,
                 boost=1,
                 add_spots=True,
                 show_params=False):
        if show_params:
            self.SIM2.show_params()
            #if self.crystal_size_mm is not None:
            print("  Mosaic domain size mm = %.3g" %
                  np.power(self.mosaic_domain_volume, 1 / 3.))
            print("  Spot scale = %.3g" % self.SIM2.spot_scale)

        if rois is None:
            rois = [self.FULL_ROI]
        if add_spots:
            for roi in rois:
                self.SIM2.region_of_interest = roi
                if cuda:
                    self.SIM2.add_nanoBragg_spots_cuda()
                elif omp:
                    from boost.python import streambuf  # will deposit printout into dummy StringIO as side effect
                    from six.moves import StringIO
                    self.SIM2.add_nanoBragg_spots_nks(streambuf(StringIO()))
                else:
                    self.SIM2.add_nanoBragg_spots()

            self.SIM2.raw_pixels = self.SIM2.raw_pixels * boost

        if add_water:  # add water for full panel, ignoring ROI
            water_scatter = flex.vec2_double([(0, 2.57), (0.0365, 2.58),
                                              (0.07, 2.8), (0.12, 5),
                                              (0.162, 8), (0.2, 6.75),
                                              (0.18, 7.32), (0.216, 6.75),
                                              (0.236, 6.5), (0.28, 4.5),
                                              (0.3, 4.3), (0.345, 4.36),
                                              (0.436, 3.77), (0.5, 3.17)])
            self.SIM2.Fbg_vs_stol = water_scatter
            self.SIM2.amorphous_density_gcm3 = 1
            self.SIM2.amorphous_molecular_weight_Da = 18
            self.SIM2.amorphous_sample_thick_mm = self.amorphous_sample_thick_mm
            self.SIM2.region_of_interest = self.FULL_ROI
            self.SIM2.add_background()

        img = self.SIM2.raw_pixels.as_numpy_array()

        if reset:
            self.SIM2.raw_pixels *= 0
            self.SIM2.region_of_interest = self.FULL_ROI

        return img
Esempio n. 24
0
 def __init__(self, strong_spots, experiment=None):
     self.strong = strong_spots
     assert 'bbox' in self.strong and 'shoebox' in self.strong, \
       "Spotfinder shoeboxes are required for spot length calculations."
     assert experiment, \
       "Supply one experiment object."
     self.det = experiment.detector
     self.beam = experiment.beam
     self.s0 = matrix.col(self.beam.get_unit_s0())
     self.panel_s0_intersections = flex.vec2_double([
         self.det[i].get_ray_intersection_px(self.s0)
         for i in range(len(self.det))
     ])
Esempio n. 25
0
    def sim_rois(self,
                 rois,
                 reset=True,
                 cuda=False,
                 omp=False,
                 add_water=False,
                 add_noise=False,
                 water_par=None,
                 noise_par=None,
                 boost=1,
                 add_spots=True):
        if add_spots:
            for roi in rois:
                self.SIM2.region_of_interest = roi
                if cuda:
                    self.SIM2.add_nanoBragg_spots_cuda()
                elif omp:
                    from boost.python import streambuf  # will deposit printout into dummy StringIO as side effect
                    from six.moves import StringIO
                    self.SIM2.add_nanoBragg_spots_nks(streambuf(StringIO()))
                else:
                    self.SIM2.add_nanoBragg_spots()

            self.SIM2.raw_pixels = self.SIM2.raw_pixels * boost

        if add_water:
            water_scatter = flex.vec2_double([(0, 2.57), (0.0365, 2.58),
                                              (0.07, 2.8), (0.12, 5),
                                              (0.162, 8), (0.2, 6.75),
                                              (0.18, 7.32), (0.216, 6.75),
                                              (0.236, 6.5), (0.28, 4.5),
                                              (0.3, 4.3), (0.345, 4.36),
                                              (0.436, 3.77), (0.5, 3.17)])
            self.SIM2.Fbg_vs_stol = water_scatter
            self.SIM2.amorphous_sample_thick_mm = 0.004  # typical GDVN
            self.SIM2.amorphous_density_gcm3 = 1
            self.SIM2.amorphous_molecular_weight_Da = 18
            self.SIM2.exposure_s = 1.0  # multiplies flux x exposure
            self.SIM2.region_of_interest = self.FULL_ROI
            self.SIM2.add_background()

        if add_noise:
            self.SIM2.add_noise()

        img = self.SIM2.raw_pixels.as_numpy_array()

        if reset:
            self.SIM2.raw_pixels *= 0
            self.SIM2.region_of_interest = self.FULL_ROI

        return img
Esempio n. 26
0
    def set_general_variables(self):

        self.frame = load(self.raw)
        self.detector = self.frame.get_detector()
        self.beam = self.frame.get_beam()
        self.s0 = self.beam.get_s0()
        self.gonio = self.frame.get_goniometer()
        self.scan = self.frame.get_scan()

        self.lab_coordinates = flex.vec3_double()
        for panel in self.detector:
            self.beam_center_mm_x, self.beam_center_mm_y = col(panel.get_beam_centre(self.s0))
            pixels = flex.vec2_double(panel.get_image_size())
            mms = panel.pixel_to_millimeter(pixels)
            self.lab_coordinates.extend(panel.get_lab_coord(mms))
            self.Isizex, self.Isizey = panel.get_image_size()
            self.beam_center_x, self.beam_center_y = col(panel.get_beam_centre_px(self.s0))
            self.detector_distance = panel.get_distance()
            thrshim_min, thrshim_max = panel.get_trusted_range()
            self.pixel_size = panel.get_pixel_size()[0]

        self.raw_data = self.frame.get_raw_data()

        if thrshim_min < 0 :
            self.thrshim_min = int(0)
        else:
            self.thrshim_min = thrshim_min

        if thrshim_max > 32767:
            self.thrshim_max = int(32767)
        else:
            self.thrshim_max = int(thrshim_max)

        self.polarization_fraction = self.beam.get_polarization_fraction()
        self.polarization_offset = 0.0
        self.cassette_x = 0.0
        self.cassette_y = 0.0
        self.windim_xmax     = int(self.Isizex)-100          # right border for processed image (pixels)
        self.windim_xmin     = 100          # left border for processed image (pixels)
        self.windim_ymax     = int(self.Isizey)-100     # top border for processed image (pixels)
        self.windim_ymin     = 100          # bottom border for processed image (pixels)
        ### beamstop borders
        self.punchim_xmax    = int(self.Isizex)          # right border of beam stop shadow (pixels)
        self.punchim_xmin    = int(self.beam_center_x)-80          # left border of beam stop shadow (pixels)
        self.punchim_ymax    = int(self.beam_center_y)+100          # top border of beam stop shadow (pixels)
        self.punchim_ymin    = int(self.beam_center_y)-40          # bottom border of beam stop shadow (pixels)
        self.mode_filter_footprint = int(20)

        return
Esempio n. 27
0
def del_op(A):
    from dials.array_family import flex

    del_A = flex.vec2_double(A.accessor())

    for j in range(A.all()[0]):
        for i in range(A.all()[1]):
            del_x = 0
            del_y = 0
            if i > 0:
                del_x = A[j, i] - A[j, i - 1]
            if j > 0:
                del_y = A[j, i] - A[j - 1, i]
            del_A[j, i] = (del_y, del_x)

    return del_A
Esempio n. 28
0
  def plot_obs_colored_by_deltapsi(self, reflections, panel = None, ax = None, bounds = None):
    assert panel is not None and ax is not None and bounds is not None
    data = reflections['delpsical.rad'] * (180/math.pi)
    norm, cmap, color_vals, sm = self.get_normalized_colors(data, vmin=-0.1, vmax=0.1)
    deltas = (reflections['xyzcal.mm']-reflections['xyzobs.mm.value'])*self.delta_scalar

    x, y = panel.get_image_size_mm()
    offset = col((x, y, 0))/2
    deltas += offset
    mm_panel_coords = flex.vec2_double(deltas.parts()[0], deltas.parts()[1])

    lab_coords = panel.get_lab_coord(mm_panel_coords)

    ax.scatter(lab_coords.parts()[0], lab_coords.parts()[1], c = data, norm=norm, cmap = cmap, linewidths=0, s=self.params.dot_size)

    return sm, color_vals
Esempio n. 29
0
def del_op(A):
  from dials.array_family import flex

  del_A = flex.vec2_double(A.accessor())

  for j in range(A.all()[0]):
    for i in range(A.all()[1]):
      del_x = 0
      del_y = 0
      if i > 0:
        del_x = A[j,i] - A[j,i-1]
      if j < 0:
        del_y = A[j,i] - A[j-1,i]
      del_A[j,i] = (del_y, del_x)

  return del_A
Esempio n. 30
0
  def plot_radial_displacements_vs_deltapsi(self, reflections, panel = None, ax = None, bounds = None):
    assert panel is not None and ax is not None and bounds is not None
    data = reflections['difference_vector_norms']
    norm, cmap, color_vals, sm = self.get_normalized_colors(data)

    a = reflections['delpsical.rad']*180/math.pi
    b = reflections['radial_displacements']

    fake_coords = flex.vec2_double(a, b) * self.delta_scalar

    x, y = panel.get_image_size_mm()
    offset = col((x, y))/2

    lab_coords = fake_coords + panel.get_lab_coord(offset)[0:2]

    ax.scatter(lab_coords.parts()[0], lab_coords.parts()[1], c = data, norm=norm, cmap = cmap, linewidths=0, s=self.params.dot_size)

    return sm, color_vals
Esempio n. 31
0
def test_sort():
  from dials.array_family import flex
  table = flex.reflection_table()
  table['a'] = flex.int([2, 4, 3, 1, 5])
  table['b'] = flex.vec2_double([(3, 2), (3, 1), (1, 3), (4, 5), (4, 3)])
  table['c'] = flex.miller_index([(3,2,1), (3,1,1), (2,4,2), (2,1,1), (1,1,1)])

  table.sort("a")
  assert list(table['a']) == [1, 2, 3, 4, 5]

  table.sort("b")
  assert list(table['b']) == [(1,3), (3,1), (3,2), (4,3), (4,5)]

  table.sort("c")
  assert list(table['c']) == [(1,1,1),(2,1,1),(2,4,2),(3,1,1),(3,2,1)]

  table.sort("c", order=(1,2,0))
  assert list(table['c']) == [(1, 1, 1), (2, 1, 1), (3, 1, 1), (3, 2, 1), (2, 4, 2)]
Esempio n. 32
0
 def __init__(self, strong_spots, experiment=None, datablock=None):
     self.strong = strong_spots
     assert 'bbox' in self.strong and 'shoebox' in self.strong, \
       "Spotfinder shoeboxes are required for spot length calculations."
     assert experiment or datablock, \
       "Supply one experiment or datablock object."
     if datablock:
         imgset = datablock._imagesets[0]
         self.det = imgset.get_detector()
         self.beam = imgset.get_beam()
     else:
         self.det = experiment.detector
         self.beam = experiment.beam
     self.s0 = matrix.col(self.beam.get_unit_s0())
     self.panel_s0_intersections = flex.vec2_double([
         self.det[i].get_ray_intersection_px(self.s0)
         for i in xrange(len(self.det))
     ])
Esempio n. 33
0
def extract_spot_data(reflections, experiments, max_two_theta):
    """
    From the spot positions, extract reciprocal space X, Y and angle positions
    for each reflection up to the scattering angle max_two_theta
    """
    # Map reflections to reciprocal space
    reflections.centroid_px_to_mm(experiments)

    # Calculate scattering vectors
    reflections["s1"] = flex.vec3_double(len(reflections))
    reflections["2theta"] = flex.double(len(reflections))
    panel_numbers = flex.size_t(reflections["panel"])
    for i, expt in enumerate(experiments):
        if "imageset_id" in reflections:
            sel_expt = reflections["imageset_id"] == i
        else:
            sel_expt = reflections["id"] == i

        for i_panel in range(len(expt.detector)):
            sel = sel_expt & (panel_numbers == i_panel)
            x, y, _ = reflections["xyzobs.mm.value"].select(sel).parts()
            s1 = expt.detector[i_panel].get_lab_coord(flex.vec2_double(x, y))
            s1 = s1 / s1.norms() * (1 / expt.beam.get_wavelength())
            tt = s1.angle(expt.beam.get_s0(), deg=True)
            reflections["s1"].set_selected(sel, s1)
            reflections["2theta"].set_selected(sel, tt)

    # Filter reflections
    full_len = len(reflections)
    reflections = reflections.select(reflections["2theta"] <= max_two_theta)
    if len(reflections) < full_len:
        logger.info(
            f"{len(reflections)} reflections with 2θ ≤ {max_two_theta}° selected from {full_len} total"
        )

    x, y, _ = reflections["s1"].parts()
    _, _, angle = reflections["xyzobs.mm.value"].parts()
    arr = flumpy.to_numpy(x)
    arr = np.c_[x, flumpy.to_numpy(
        -y
    )]  # Y is inverted to match calculation in edtools.find_rotation_axis
    arr = np.c_[arr, flumpy.to_numpy(angle)]
    return arr
Esempio n. 34
0
def get_experiment_xvectors(experiments):

    beam = experiments[0].beam
    detector = experiments[0].detector

    x = []

    for panel in detector:
        lab_coordinates = flex.vec3_double()
        pixels = flex.vec2_double(panel.get_image_size())
        mms = panel.pixel_to_millimeter(pixels)
        lab_coordinates.extend(panel.get_lab_coord(mms))

        # generate s1 vectors
        s1 = lab_coordinates.each_normalize() * (1 / beam.get_wavelength())
        # Generate x vectors
        x.append((s1 - beam.get_s0()).as_double())

    return (x)
Esempio n. 35
0
def calc_2theta(reflections, experiments):
  """Calculate and return 2theta angles in radians"""

  twotheta = flex.double(len(reflections), 0.)
  for iexp, exp in enumerate(experiments):
    isel = (reflections['id'] == iexp).iselection()
    sub_ref = reflections.select(isel)
    s0 = matrix.col(exp.beam.get_s0())
    for ipanel in range(len(exp.detector)):
      sel = (sub_ref['panel'] == ipanel)
      panel_ref = sub_ref.select(sel)
      x, y, phi = panel_ref['xyzobs.mm.value'].parts()
      s1 = exp.detector[ipanel].get_lab_coord(flex.vec2_double(x,y))
      s1 = s1/s1.norms() * s0.length()

      sub_isel = isel.select(sel)
      twotheta.set_selected(sub_isel, s1.angle(s0))

  return twotheta
Esempio n. 36
0
def calc_2theta(reflections, experiments):
    """Calculate and return 2theta angles in radians"""

    twotheta = flex.double(len(reflections), 0.0)
    for iexp, exp in enumerate(experiments):
        isel = (reflections["id"] == iexp).iselection()
        sub_ref = reflections.select(isel)
        s0 = matrix.col(exp.beam.get_s0())
        for ipanel in range(len(exp.detector)):
            sel = sub_ref["panel"] == ipanel
            panel_ref = sub_ref.select(sel)
            x, y, phi = panel_ref["xyzobs.mm.value"].parts()
            s1 = exp.detector[ipanel].get_lab_coord(flex.vec2_double(x, y))
            s1 = s1 / s1.norms() * s0.length()

            sub_isel = isel.select(sel)
            twotheta.set_selected(sub_isel, s1.angle(s0))

    return twotheta
Esempio n. 37
0
  def tst_sort(self):

    from dials.array_family import flex
    table = flex.reflection_table()
    table['a'] = flex.int([2, 4, 3, 1, 5])
    table['b'] = flex.vec2_double([(3, 2), (3, 1), (1, 3), (4, 5), (4, 3)])
    table['c'] = flex.miller_index([(3,2,1), (3,1,1), (2,4,2), (2,1,1), (1,1,1)])

    table.sort("a")
    assert list(table['a']) == [1, 2, 3, 4, 5]

    table.sort("b")
    assert list(table['b']) == [(1,3), (3,1), (3,2), (4,3), (4,5)]

    table.sort("c")
    assert list(table['c']) == [(1,1,1),(2,1,1),(2,4,2),(3,1,1),(3,2,1)]

    table.sort("c", order=(1,2,0))
    assert list(table['c']) == [(1, 1, 1), (2, 1, 1), (3, 1, 1), (3, 2, 1), (2, 4, 2)]

    print "OK"
Esempio n. 38
0
def test_to_from_msgpack(tmpdir):
    from dials.model.data import Shoebox

    def gen_shoebox():
        shoebox = Shoebox(0, (0, 4, 0, 3, 0, 1))
        shoebox.allocate()
        for k in range(1):
            for j in range(3):
                for i in range(4):
                    shoebox.data[k, j, i] = i + j + k + 0.1
                    shoebox.mask[k, j, i] = i % 2
                    shoebox.background[k, j, i] = i * j + 0.2
        return shoebox

    def compare(a, b):
        assert a.is_consistent()
        assert b.is_consistent()
        assert a.panel == b.panel
        assert a.bbox == b.bbox
        for aa, bb in zip(a.data, b.data):
            if abs(aa - bb) > 1e-9:
                return False
        for aa, bb in zip(a.background, b.background):
            if abs(aa - bb) > 1e-9:
                return False
        for aa, bb in zip(a.mask, b.mask):
            if aa != bb:
                return False
        return True

    # The columns as lists
    c1 = list(range(10))
    c2 = list(range(10))
    c3 = ["a", "b", "c", "d", "e", "f", "g", "i", "j", "k"]
    c4 = [True, False, True, False, True] * 2
    c5 = list(range(10))
    c6 = [(i + 1, i + 2) for i in range(10)]
    c7 = [(i + 1, i + 2, i + 3) for i in range(10)]
    c8 = [tuple(i + j for j in range(9)) for i in range(10)]
    c9 = [tuple(i + j for j in range(6)) for i in range(10)]
    c10 = [(i + 1, i + 2, i + 3) for i in range(10)]
    c11 = [gen_shoebox() for i in range(10)]

    # Create a table with some elements
    table = flex.reflection_table()
    table["col1"] = flex.int(c1)
    table["col2"] = flex.double(c2)
    table["col3"] = flex.std_string(c3)
    table["col4"] = flex.bool(c4)
    table["col5"] = flex.size_t(c5)
    table["col6"] = flex.vec2_double(c6)
    table["col7"] = flex.vec3_double(c7)
    table["col8"] = flex.mat3_double(c8)
    table["col9"] = flex.int6(c9)
    table["col10"] = flex.miller_index(c10)
    table["col11"] = flex.shoebox(c11)

    obj = table.as_msgpack()
    new_table = flex.reflection_table.from_msgpack(obj)
    assert new_table.is_consistent()
    assert new_table.nrows() == 10
    assert new_table.ncols() == 11
    assert all(tuple(a == b for a, b in zip(new_table["col1"], c1)))
    assert all(tuple(a == b for a, b in zip(new_table["col2"], c2)))
    assert all(tuple(a == b for a, b in zip(new_table["col3"], c3)))
    assert all(tuple(a == b for a, b in zip(new_table["col4"], c4)))
    assert all(tuple(a == b for a, b in zip(new_table["col5"], c5)))
    assert all(tuple(a == b for a, b in zip(new_table["col6"], c6)))
    assert all(tuple(a == b for a, b in zip(new_table["col7"], c7)))
    assert all(tuple(a == b for a, b in zip(new_table["col8"], c8)))
    assert all(tuple(a == b for a, b in zip(new_table["col9"], c9)))
    assert all(tuple(a == b for a, b in zip(new_table["col10"], c10)))
    assert all(tuple(compare(a, b) for a, b in zip(new_table["col11"], c11)))

    table.as_msgpack_file(tmpdir.join("reflections.mpack").strpath)
    new_table = flex.reflection_table.from_msgpack_file(
        tmpdir.join("reflections.mpack").strpath)
    assert new_table.is_consistent()
    assert new_table.nrows() == 10
    assert new_table.ncols() == 11
    assert all(tuple(a == b for a, b in zip(new_table["col1"], c1)))
    assert all(tuple(a == b for a, b in zip(new_table["col2"], c2)))
    assert all(tuple(a == b for a, b in zip(new_table["col3"], c3)))
    assert all(tuple(a == b for a, b in zip(new_table["col4"], c4)))
    assert all(tuple(a == b for a, b in zip(new_table["col5"], c5)))
    assert all(tuple(a == b for a, b in zip(new_table["col6"], c6)))
    assert all(tuple(a == b for a, b in zip(new_table["col7"], c7)))
    assert all(tuple(a == b for a, b in zip(new_table["col8"], c8)))
    assert all(tuple(a == b for a, b in zip(new_table["col9"], c9)))
    assert all(tuple(a == b for a, b in zip(new_table["col10"], c10)))
    assert all(tuple(compare(a, b) for a, b in zip(new_table["col11"], c11)))
Esempio n. 39
0
    print(len(selection), len(reflections))

    from matplotlib import pylab

    pylab.hist(I_obs, bins=50)
    pylab.show()

    # from matplotlib import pylab
    # s0 = matrix.col(experiments[0].beam.get_s0())
    # D = [matrix.col(s2).length()/s0.length() for s2 in s2_obs]
    # pylab.hist(D, bins=50)
    # pylab.show()

    angles = []
    for s1, s2 in zip(s1_obs, s2_obs):
        a = matrix.col(s1).angle(matrix.col(s2), deg=True)
        angles.append(a)
    print("Mean angle between s1 and s2 %f degrees " %
          (sum(angles) / len(angles)))

    # Do the ray intersection
    reflections["intensity.sum.value"] = I_obs
    reflections["s1_obs"] = s1_obs
    reflections["s1"] = s2_obs
    reflections["xyzobs.px"] = flex.vec2_double([
        experiments[0].detector[0].get_ray_intersection_px(s1) for s1 in s1_obs
    ])

    # Do the refinement
    refiner = ProfileRefiner(experiments[0], reflections)
Esempio n. 40
0
    def index(self):
        # most of this is the same as dials.algorithms.indexing.indexer.indexer_base.index(), with some stills
        # specific modifications (don't re-index after choose best orientation matrix, but use the indexing from
        # choose best orientation matrix, also don't use macrocycles) of refinement after indexing.
        # 2017 update: do accept multiple lattices per shot
        if self.params.refinement_protocol.n_macro_cycles > 1:
            raise Sorry(
                "For stills, please set refinement_protocol.n_macro_cycles = 1"
            )

        experiments = ExperimentList()

        had_refinement_error = False
        have_similar_crystal_models = False

        while True:
            self.d_min = self.params.refinement_protocol.d_min_start
            if had_refinement_error or have_similar_crystal_models:
                break
            max_lattices = self.params.multiple_lattice_search.max_lattices
            if max_lattices is not None and len(experiments) >= max_lattices:
                break
            if len(experiments) > 0:
                cutoff_fraction = \
                  self.params.multiple_lattice_search.recycle_unindexed_reflections_cutoff
                d_spacings = 1 / self.reflections['rlp'].norms()
                d_min_indexed = flex.min(
                    d_spacings.select(self.indexed_reflections))
                min_reflections_for_indexing = \
                  cutoff_fraction * len(self.reflections.select(d_spacings > d_min_indexed))
                crystal_ids = self.reflections.select(
                    d_spacings > d_min_indexed)['id']
                if (crystal_ids
                        == -1).count(True) < min_reflections_for_indexing:
                    logger.info(
                        "Finish searching for more lattices: %i unindexed reflections remaining."
                        % (min_reflections_for_indexing))
                    break

            n_lattices_previous_cycle = len(experiments)

            # index multiple lattices per shot
            if len(experiments) == 0:
                experiments.extend(self.find_lattices())
                if len(experiments) == 0:
                    raise Sorry("No suitable lattice could be found.")
            else:
                try:
                    new = self.find_lattices()
                    experiments.extend(new)
                except Exception as e:
                    logger.info("Indexing remaining reflections failed")
                    logger.debug(
                        "Indexing remaining reflections failed, exception:\n" +
                        str(e))

            # reset reflection lattice flags
            # the lattice a given reflection belongs to: a value of -1 indicates
            # that a reflection doesn't belong to any lattice so far
            self.reflections['id'] = flex.int(len(self.reflections), -1)

            self.index_reflections(experiments, self.reflections)

            if len(experiments) == n_lattices_previous_cycle:
                # no more lattices found
                break

            if not self.params.stills.refine_candidates_with_known_symmetry and self.params.known_symmetry.space_group is not None:
                # now apply the space group symmetry only after the first indexing
                # need to make sure that the symmetrized orientation is similar to the P1 model
                target_space_group = self.target_symmetry_primitive.space_group(
                )
                for i_cryst, cryst in enumerate(experiments.crystals()):
                    if i_cryst >= n_lattices_previous_cycle:
                        new_cryst, cb_op_to_primitive = self.apply_symmetry(
                            cryst, target_space_group)
                        if self.cb_op_primitive_inp is not None:
                            new_cryst = new_cryst.change_basis(
                                self.cb_op_primitive_inp)
                            logger.info(new_cryst.get_space_group().info())
                        cryst.update(new_cryst)
                        cryst.set_space_group(
                            self.params.known_symmetry.space_group.group())
                        for i_expt, expt in enumerate(experiments):
                            if expt.crystal is not cryst:
                                continue
                            if not cb_op_to_primitive.is_identity_op():
                                miller_indices = self.reflections[
                                    'miller_index'].select(
                                        self.reflections['id'] == i_expt)
                                miller_indices = cb_op_to_primitive.apply(
                                    miller_indices)
                                self.reflections['miller_index'].set_selected(
                                    self.reflections['id'] == i_expt,
                                    miller_indices)
                            if self.cb_op_primitive_inp is not None:
                                miller_indices = self.reflections[
                                    'miller_index'].select(
                                        self.reflections['id'] == i_expt)
                                miller_indices = self.cb_op_primitive_inp.apply(
                                    miller_indices)
                                self.reflections['miller_index'].set_selected(
                                    self.reflections['id'] == i_expt,
                                    miller_indices)

            # discard nearly overlapping lattices on the same shot
            if len(experiments) > 1:
                from dials.algorithms.indexing.compare_orientation_matrices \
                     import difference_rotation_matrix_axis_angle
                cryst_b = experiments.crystals()[-1]
                have_similar_crystal_models = False
                for i_a, cryst_a in enumerate(experiments.crystals()[:-1]):
                    R_ab, axis, angle, cb_op_ab = \
                      difference_rotation_matrix_axis_angle(cryst_a, cryst_b)
                    min_angle = self.params.multiple_lattice_search.minimum_angular_separation
                    if abs(angle) < min_angle:  # degrees
                        logger.info(
                            "Crystal models too similar, rejecting crystal %i:"
                            % (len(experiments)))
                        logger.info(
                            "Rotation matrix to transform crystal %i to crystal %i"
                            % (i_a + 1, len(experiments)))
                        logger.info(R_ab)
                        logger.info("Rotation of %.3f degrees" % angle +
                                    " about axis (%.3f, %.3f, %.3f)" % axis)
                        #show_rotation_matrix_differences([cryst_a, cryst_b])
                        have_similar_crystal_models = True
                        del experiments[-1]
                        break
                if have_similar_crystal_models:
                    break

            self.indexed_reflections = (self.reflections['id'] > -1)
            if self.d_min is None:
                sel = self.reflections['id'] <= -1
            else:
                sel = flex.bool(len(self.reflections), False)
                lengths = 1 / self.reflections['rlp'].norms()
                isel = (lengths >= self.d_min).iselection()
                sel.set_selected(isel, True)
                sel.set_selected(self.reflections['id'] > -1, False)
            self.unindexed_reflections = self.reflections.select(sel)

            reflections_for_refinement = self.reflections.select(
                self.indexed_reflections)

            if len(self.params.stills.isoforms) > 0:
                logger.info("")
                logger.info("#" * 80)
                logger.info("Starting refinement")
                logger.info("#" * 80)
                logger.info("")

                import copy
                isoform_experiments = ExperimentList()
                isoform_reflections = flex.reflection_table()
                # Note, changes to params after initial indexing. Cannot use tie to target when fixing the unit cell.
                self.all_params.refinement.reflections.outlier.algorithm = "null"
                self.all_params.refinement.parameterisation.crystal.fix = "cell"
                self.all_params.refinement.parameterisation.crystal.unit_cell.restraints.tie_to_target = []

                for expt_id, experiment in enumerate(experiments):
                    reflections = reflections_for_refinement.select(
                        reflections_for_refinement['id'] == expt_id)
                    reflections['id'] = flex.int(len(reflections), 0)
                    refiners = []
                    for isoform in self.params.stills.isoforms:
                        iso_experiment = copy.deepcopy(experiment)
                        crystal = iso_experiment.crystal
                        if isoform.lookup_symbol != crystal.get_space_group(
                        ).type().lookup_symbol():
                            logger.info(
                                "Crystal isoform lookup_symbol %s does not match isoform %s lookup_symbol %s"
                                % (crystal.get_space_group().type(
                                ).lookup_symbol(), isoform.name,
                                   isoform.lookup_symbol))
                            continue
                        crystal.set_B(isoform.cell.fractionalization_matrix())

                        logger.info("Refining isoform %s" % isoform.name)
                        refiners.append(
                            e_refine(params=self.all_params,
                                     experiments=ExperimentList(
                                         [iso_experiment]),
                                     reflections=reflections,
                                     graph_verbose=False))

                    if len(refiners) == 0:
                        raise Sorry(
                            "No isoforms had a lookup symbol that matched")
                    positional_rmsds = [
                        math.sqrt(P.rmsds()[0]**2 + P.rmsds()[1]**2)
                        for P in refiners
                    ]
                    logger.info("Positional rmsds for all isoforms:" +
                                str(positional_rmsds))
                    minrmsd_mm = min(positional_rmsds)
                    minindex = positional_rmsds.index(minrmsd_mm)
                    logger.info(
                        "The smallest rmsd is %5.1f um from isoform %s" %
                        (1000. * minrmsd_mm,
                         self.params.stills.isoforms[minindex].name))
                    if self.params.stills.isoforms[
                            minindex].rmsd_target_mm is not None:
                        logger.info("Asserting %f < %f" %
                                    (minrmsd_mm, self.params.stills.
                                     isoforms[minindex].rmsd_target_mm))
                        assert minrmsd_mm < self.params.stills.isoforms[
                            minindex].rmsd_target_mm
                    logger.info("Acceptable rmsd for isoform %s." %
                                (self.params.stills.isoforms[minindex].name))
                    if len(self.params.stills.isoforms) == 2:
                        logger.info(
                            "Rmsd gain over the other isoform %5.1f um." %
                            (1000. *
                             abs(positional_rmsds[0] - positional_rmsds[1])))
                    R = refiners[minindex]
                    # Now one last check to see if direct beam is out of bounds
                    if self.params.stills.isoforms[
                            minindex].beam_restraint is not None:
                        from scitbx import matrix
                        refined_beam = matrix.col(
                            R.get_experiments()
                            [0].detector[0].get_beam_centre_lab(
                                experiments[0].beam.get_s0())[0:2])
                        known_beam = matrix.col(
                            self.params.stills.isoforms[minindex].
                            beam_restraint)
                        logger.info(
                            "Asserting difference in refined beam center and expected beam center %f < %f"
                            %
                            ((refined_beam - known_beam).length(), self.params.
                             stills.isoforms[minindex].rmsd_target_mm))
                        assert (refined_beam - known_beam
                                ).length() < self.params.stills.isoforms[
                                    minindex].rmsd_target_mm
                        # future--circle of confusion could be given as a separate length in mm instead of reusing rmsd_target

                    experiment = R.get_experiments()[0]
                    experiment.crystal.identified_isoform = self.params.stills.isoforms[
                        minindex].name

                    isoform_experiments.append(experiment)
                    reflections['id'] = flex.int(len(reflections), expt_id)
                    isoform_reflections.extend(reflections)
                experiments = isoform_experiments
                reflections_for_refinement = isoform_reflections

            try:
                refined_experiments, refined_reflections = self.refine(
                    experiments, reflections_for_refinement)
            except Exception as e:
                s = str(e)
                if len(experiments) == 1:
                    raise Sorry(e)
                had_refinement_error = True
                logger.info("Refinement failed:")
                logger.info(s)
                del experiments[-1]
                break

            # sanity check for unrealistic unit cell volume increase during refinement
            # usually this indicates too many parameters are being refined given the
            # number of observations provided.
            if not self.params.refinement_protocol.disable_unit_cell_volume_sanity_check:
                for orig_expt, refined_expt in zip(experiments,
                                                   refined_experiments):
                    uc1 = orig_expt.crystal.get_unit_cell()
                    uc2 = refined_expt.crystal.get_unit_cell()
                    volume_change = abs(uc1.volume() -
                                        uc2.volume()) / uc1.volume()
                    cutoff = 0.5
                    if volume_change > cutoff:
                        msg = "\n".join((
                            "Unrealistic unit cell volume increase during refinement of %.1f%%.",
                            "Please try refining fewer parameters, either by enforcing symmetry",
                            "constraints (space_group=) and/or disabling experimental geometry",
                            "refinement (detector.fix=all and beam.fix=all). To disable this",
                            "sanity check set disable_unit_cell_volume_sanity_check=True."
                        )) % (100 * volume_change)
                        raise Sorry(msg)

            self.refined_reflections = refined_reflections.select(
                refined_reflections['id'] > -1)

            for i, imageset in enumerate(self.imagesets):
                ref_sel = self.refined_reflections.select(
                    self.refined_reflections['imageset_id'] == i)
                ref_sel = ref_sel.select(ref_sel['id'] >= 0)
                for i_expt in set(ref_sel['id']):
                    expt = refined_experiments[i_expt]
                    imageset.set_detector(expt.detector)
                    imageset.set_beam(expt.beam)
                    imageset.set_goniometer(expt.goniometer)
                    imageset.set_scan(expt.scan)
                    expt.imageset = imageset

            if not (self.all_params.refinement.parameterisation.beam.fix
                    == 'all' and
                    self.all_params.refinement.parameterisation.detector.fix
                    == 'all'):
                # Experimental geometry may have changed - re-map centroids to
                # reciprocal space

                spots_mm = self.reflections
                self.reflections = flex.reflection_table()
                for i, imageset in enumerate(self.imagesets):
                    spots_sel = spots_mm.select(spots_mm['imageset_id'] == i)
                    self.map_centroids_to_reciprocal_space(
                        spots_sel, imageset.get_detector(),
                        imageset.get_beam(), imageset.get_goniometer())
                    self.reflections.extend(spots_sel)

            # update for next cycle
            experiments = refined_experiments
            self.refined_experiments = refined_experiments

        if not 'refined_experiments' in locals():
            raise Sorry("None of the experiments could refine.")

        # discard experiments with zero reflections after refinement
        id_set = set(self.refined_reflections['id'])
        if len(id_set) < len(self.refined_experiments):
            filtered_refined_reflections = flex.reflection_table()
            for i in xrange(len(self.refined_experiments)):
                if i not in id_set:
                    del self.refined_experiments[i]
            for old, new in zip(sorted(id_set), range(len(id_set))):
                subset = self.refined_reflections.select(
                    self.refined_reflections['id'] == old)
                subset['id'] = flex.int(len(subset), new)
                filtered_refined_reflections.extend(subset)
            self.refined_reflections = filtered_refined_reflections

        if len(self.refined_experiments) > 1:
            from dials.algorithms.indexing.compare_orientation_matrices \
                 import show_rotation_matrix_differences
            show_rotation_matrix_differences(
                self.refined_experiments.crystals(), out=info_handle)

        logger.info("Final refined crystal models:")
        for i, crystal_model in enumerate(self.refined_experiments.crystals()):
            n_indexed = 0
            for i_expt in experiments.where(crystal=crystal_model):
                n_indexed += (self.reflections['id'] == i).count(True)
            logger.info("model %i (%i reflections):" % (i + 1, n_indexed))
            logger.info(crystal_model)

        if 'xyzcal.mm' in self.refined_reflections:  # won't be there if refine_all_candidates = False and no isoforms
            self.refined_reflections['xyzcal.px'] = flex.vec3_double(
                len(self.refined_reflections))
            for i, imageset in enumerate(self.imagesets):
                imgset_sel = self.refined_reflections['imageset_id'] == i
                # set xyzcal.px field in self.refined_reflections
                refined_reflections = self.refined_reflections.select(
                    imgset_sel)
                panel_numbers = flex.size_t(refined_reflections['panel'])
                xyzcal_mm = refined_reflections['xyzcal.mm']
                x_mm, y_mm, z_rad = xyzcal_mm.parts()
                xy_cal_mm = flex.vec2_double(x_mm, y_mm)
                xy_cal_px = flex.vec2_double(len(xy_cal_mm))
                for i_panel in range(len(imageset.get_detector())):
                    panel = imageset.get_detector()[i_panel]
                    sel = (panel_numbers == i_panel)
                    isel = sel.iselection()
                    ref_panel = refined_reflections.select(
                        panel_numbers == i_panel)
                    xy_cal_px.set_selected(
                        sel, panel.millimeter_to_pixel(xy_cal_mm.select(sel)))
                x_px, y_px = xy_cal_px.parts()
                scan = imageset.get_scan()
                if scan is not None:
                    z_px = scan.get_array_index_from_angle(z_rad, deg=False)
                else:
                    # must be a still image, z centroid not meaningful
                    z_px = z_rad
                xyzcal_px = flex.vec3_double(x_px, y_px, z_px)
                self.refined_reflections['xyzcal.px'].set_selected(
                    imgset_sel, xyzcal_px)
Esempio n. 41
0
  def run(self):
    ''' Parse the options. '''
    from dials.util.options import flatten_experiments, flatten_reflections
    # Parse the command line arguments
    params, options = self.parser.parse_args(show_diff_phil=True)
    self.params = params
    experiments = flatten_experiments(params.input.experiments)

    # Find all detector objects
    detectors = experiments.detectors()

    # Verify inputs
    if len(params.input.reflections) == len(detectors) and len(detectors) > 1:
      # case for passing in multiple images on the command line
      assert len(params.input.reflections) == len(detectors)
      reflections = flex.reflection_table()
      for expt_id in xrange(len(detectors)):
        subset = params.input.reflections[expt_id].data
        subset['id'] = flex.int(len(subset), expt_id)
        reflections.extend(subset)
    else:
      # case for passing in combined experiments and reflections
      reflections = flatten_reflections(params.input.reflections)[0]

    detector = detectors[0]

    #from dials.algorithms.refinement.prediction import ExperimentsPredictor
    #ref_predictor = ExperimentsPredictor(experiments, force_stills=experiments.all_stills())

    print "N reflections total:", len(reflections)
    if params.residuals.exclude_outliers:
      reflections = reflections.select(reflections.get_flags(reflections.flags.used_in_refinement))
      print "N reflections used in refinement:", len(reflections)
      print "Reporting only on those reflections used in refinement"

    if self.params.residuals.i_sigi_cutoff is not None:
      sel = (reflections['intensity.sum.value']/flex.sqrt(reflections['intensity.sum.variance'])) >= self.params.residuals.i_sigi_cutoff
      reflections = reflections.select(sel)
      print "After filtering by I/sigi cutoff of %f, there are %d reflections left"%(self.params.residuals.i_sigi_cutoff,len(reflections))

    reflections['difference_vector_norms'] = (reflections['xyzcal.mm']-reflections['xyzobs.mm.value']).norms()

    n = len(reflections)
    rmsd = self.get_weighted_rmsd(reflections)
    print "Dataset RMSD (microns)", rmsd * 1000

    if params.tag is None:
      tag = ''
    else:
      tag = '%s '%params.tag

    # set up delta-psi ratio heatmap
    p = flex.int() # positive
    n = flex.int() # negative
    for i in set(reflections['id']):
      exprefls = reflections.select(reflections['id']==i)
      p.append(len(exprefls.select(exprefls['delpsical.rad']>0)))
      n.append(len(exprefls.select(exprefls['delpsical.rad']<0)))
    plt.hist2d(p, n, bins=30)
    cb = plt.colorbar()
    cb.set_label("N images")
    plt.title(r"%s2D histogram of pos vs. neg $\Delta\Psi$ per image"%tag)
    plt.xlabel(r"N reflections with $\Delta\Psi$ > 0")
    plt.ylabel(r"N reflections with $\Delta\Psi$ < 0")

    self.delta_scalar = 50

    # Iterate through the detectors, computing detector statistics at the per-panel level (IE one statistic per panel)
    # Per panel dictionaries
    rmsds = {}
    refl_counts = {}
    transverse_rmsds = {}
    radial_rmsds = {}
    ttdpcorr = {}
    pg_bc_dists = {}
    mean_delta_two_theta = {}
    # per panelgroup flex arrays
    pg_rmsds = flex.double()
    pg_r_rmsds = flex.double()
    pg_t_rmsds = flex.double()
    pg_refls_count = flex.int()
    pg_refls_count_d = {}
    table_header = ["PG id", "RMSD","Radial", "Transverse", "N refls"]
    table_header2 = ["","(um)","RMSD (um)","RMSD (um)",""]
    table_data = []
    table_data.append(table_header)
    table_data.append(table_header2)

    # Compute a set of radial and transverse displacements for each reflection
    print "Setting up stats..."
    tmp = flex.reflection_table()
    # Need to construct a variety of vectors
    for panel_id, panel in enumerate(detector):
      panel_refls = reflections.select(reflections['panel'] == panel_id)
      bcl = flex.vec3_double()
      tto = flex.double()
      ttc = flex.double()
      # Compute the beam center in lab space (a vector pointing from the origin to where the beam would intersect
      # the panel, if it did intersect the panel)
      for expt_id in set(panel_refls['id']):
        beam = experiments[expt_id].beam
        s0 = beam.get_s0()
        expt_refls = panel_refls.select(panel_refls['id'] == expt_id)
        beam_centre = panel.get_beam_centre_lab(s0)
        bcl.extend(flex.vec3_double(len(expt_refls), beam_centre))
        obs_x, obs_y, _ = expt_refls['xyzobs.px.value'].parts()
        cal_x, cal_y, _ = expt_refls['xyzcal.px'].parts()
        tto.extend(flex.double([panel.get_two_theta_at_pixel(s0, (obs_x[i], obs_y[i])) for i in xrange(len(expt_refls))]))
        ttc.extend(flex.double([panel.get_two_theta_at_pixel(s0, (cal_x[i], cal_y[i])) for i in xrange(len(expt_refls))]))
      panel_refls['beam_centre_lab'] = bcl
      panel_refls['two_theta_obs'] = tto * (180/math.pi)
      panel_refls['two_theta_cal'] = ttc * (180/math.pi) #+ (0.5*panel_refls['delpsical.rad']*panel_refls['two_theta_obs'])
      # Compute obs in lab space
      x, y, _ = panel_refls['xyzobs.mm.value'].parts()
      c = flex.vec2_double(x, y)
      panel_refls['obs_lab_coords'] = panel.get_lab_coord(c)
      # Compute deltaXY in panel space. This vector is relative to the panel origin
      x, y, _ = (panel_refls['xyzcal.mm'] - panel_refls['xyzobs.mm.value']).parts()
      # Convert deltaXY to lab space, subtracting off of the panel origin
      panel_refls['delta_lab_coords'] = panel.get_lab_coord(flex.vec2_double(x,y)) - panel.get_origin()
      tmp.extend(panel_refls)
    reflections = tmp
    # The radial vector points from the center of the reflection to the beam center
    radial_vectors = (reflections['obs_lab_coords'] - reflections['beam_centre_lab']).each_normalize()
    # The transverse vector is orthogonal to the radial vector and the beam vector
    transverse_vectors = radial_vectors.cross(reflections['beam_centre_lab']).each_normalize()
    # Compute the raidal and transverse components of each deltaXY
    reflections['radial_displacements']     = reflections['delta_lab_coords'].dot(radial_vectors)
    reflections['transverse_displacements'] = reflections['delta_lab_coords'].dot(transverse_vectors)

    # Iterate through the detector at the specified hierarchy level
    for pg_id, pg in enumerate(iterate_detector_at_level(detector.hierarchy(), 0, params.hierarchy_level)):
      pg_msd_sum = 0
      pg_r_msd_sum = 0
      pg_t_msd_sum = 0
      pg_refls = 0
      pg_delpsi = flex.double()
      pg_deltwotheta = flex.double()
      for p in iterate_panels(pg):
        panel_id = id_from_name(detector, p.get_name())
        panel_refls = reflections.select(reflections['panel'] == panel_id)
        n = len(panel_refls)
        pg_refls += n

        delta_x = panel_refls['xyzcal.mm'].parts()[0] - panel_refls['xyzobs.mm.value'].parts()[0]
        delta_y = panel_refls['xyzcal.mm'].parts()[1] - panel_refls['xyzobs.mm.value'].parts()[1]

        tmp = flex.sum((delta_x**2)+(delta_y**2))
        pg_msd_sum += tmp

        r = panel_refls['radial_displacements']
        t = panel_refls['transverse_displacements']
        pg_r_msd_sum += flex.sum_sq(r)
        pg_t_msd_sum += flex.sum_sq(t)

        pg_delpsi.extend(panel_refls['delpsical.rad']*180/math.pi)
        pg_deltwotheta.extend(panel_refls['two_theta_obs'] - panel_refls['two_theta_cal'])

      bc = col(pg.get_beam_centre_lab(s0))
      ori = get_center(pg)
      pg_bc_dists[pg.get_name()] = (ori-bc).length()
      if len(pg_deltwotheta) > 0:
        mean_delta_two_theta[pg.get_name()] = flex.mean(pg_deltwotheta)
      else:
        mean_delta_two_theta[pg.get_name()] = 0

      if pg_refls == 0:
        pg_rmsd = pg_r_rmsd = pg_t_rmsd = 0
      else:
        pg_rmsd = math.sqrt(pg_msd_sum/pg_refls) * 1000
        pg_r_rmsd = math.sqrt(pg_r_msd_sum/pg_refls) * 1000
        pg_t_rmsd = math.sqrt(pg_t_msd_sum/pg_refls) * 1000
      pg_rmsds.append(pg_rmsd)
      pg_r_rmsds.append(pg_r_rmsd)
      pg_t_rmsds.append(pg_t_rmsd)
      pg_refls_count.append(pg_refls)
      pg_refls_count_d[pg.get_name()] = pg_refls
      table_data.append(["%d"%pg_id, "%.1f"%pg_rmsd, "%.1f"%pg_r_rmsd, "%.1f"%pg_t_rmsd, "%6d"%pg_refls])

      refl_counts[pg.get_name()] = pg_refls
      if pg_refls == 0:
        rmsds[p.get_name()] = -1
        radial_rmsds[p.get_name()] = -1
        transverse_rmsds[p.get_name()] = -1
        ttdpcorr[pg.get_name()] = -1
      else:
        rmsds[pg.get_name()] = pg_rmsd
        radial_rmsds[pg.get_name()]     = pg_r_rmsd
        transverse_rmsds[pg.get_name()] = pg_t_rmsd

        lc = flex.linear_correlation(pg_delpsi, pg_deltwotheta)
        ttdpcorr[pg.get_name()] = lc.coefficient()


    r1 = ["Weighted mean"]
    r2 = ["Weighted stddev"]
    if len(pg_rmsds) > 1:
      stats = flex.mean_and_variance(pg_rmsds, pg_refls_count.as_double())
      r1.append("%.1f"%stats.mean())
      r2.append("%.1f"%stats.gsl_stats_wsd())
      stats = flex.mean_and_variance(pg_r_rmsds, pg_refls_count.as_double())
      r1.append("%.1f"%stats.mean())
      r2.append("%.1f"%stats.gsl_stats_wsd())
      stats = flex.mean_and_variance(pg_t_rmsds, pg_refls_count.as_double())
      r1.append("%.1f"%stats.mean())
      r2.append("%.1f"%stats.gsl_stats_wsd())
    else:
      r1.extend([""]*3)
      r2.extend([""]*3)
    r1.append("")
    r2.append("")
    table_data.append(r1)
    table_data.append(r2)
    table_data.append(["Mean", "", "", "", "%8.1f"%flex.mean(pg_refls_count.as_double())])

    from libtbx import table_utils
    print "Detector statistics.  Angles in degrees, RMSDs in microns"
    print table_utils.format(table_data,has_header=2,justify='center',delim=" ")

    self.histogram(reflections, '%sDifference vector norms (mm)'%tag)

    if params.show_plots:
      if self.params.tag is None:
        t = ""
      else:
        t = "%s "%self.params.tag
      self.image_rmsd_histogram(reflections, tag)

      # Plots! these are plots with callbacks to draw on individual panels
      self.detector_plot_refls(detector, reflections, '%sOverall positional displacements (mm)'%tag, show=False, plot_callback=self.plot_obs_colored_by_deltas)
      self.detector_plot_refls(detector, reflections, '%sRadial positional displacements (mm)'%tag, show=False, plot_callback=self.plot_obs_colored_by_radial_deltas)
      self.detector_plot_refls(detector, reflections, '%sTransverse positional displacements (mm)'%tag, show=False, plot_callback=self.plot_obs_colored_by_transverse_deltas)
      self.detector_plot_refls(detector, reflections, r'%s$\Delta\Psi$'%tag, show=False, plot_callback=self.plot_obs_colored_by_deltapsi, colorbar_units=r"$\circ$")
      self.detector_plot_refls(detector, reflections, r'%s$\Delta$XY*%s'%(tag, self.delta_scalar), show=False, plot_callback=self.plot_deltas)
      self.detector_plot_refls(detector, reflections, '%sSP Manual CDF'%tag, show=False, plot_callback=self.plot_cdf_manually)
      self.detector_plot_refls(detector, reflections, r'%s$\Delta$XY Histograms'%tag, show=False, plot_callback=self.plot_histograms)
      self.detector_plot_refls(detector, reflections, r'%sRadial displacements vs. $\Delta\Psi$, colored by $\Delta$XY'%tag, show=False, plot_callback=self.plot_radial_displacements_vs_deltapsi)
      self.detector_plot_refls(detector, reflections, r'%sDistance vector norms'%tag, show=False, plot_callback=self.plot_difference_vector_norms_histograms)

      # Plot intensity vs. radial_displacement
      fig = plt.figure()
      panel_id = 15
      panel_refls = reflections.select(reflections['panel'] == panel_id)
      a = panel_refls['radial_displacements']
      b = panel_refls['intensity.sum.value']
      sel = (a > -0.2) & (a < 0.2) & (b < 50000)
      plt.hist2d(a.select(sel), b.select(sel), bins=100)
      plt.title("%s2D histogram of intensity vs. radial displacement for panel %d"%(tag, panel_id))
      plt.xlabel("Radial displacement (mm)")
      plt.ylabel("Intensity")
      ax = plt.colorbar()
      ax.set_label("Counts")

      # Plot delta 2theta vs. deltapsi
      n_bins = 10
      bin_size = len(reflections)//n_bins
      bin_low = []
      bin_high = []
      data = flex.sorted(reflections['two_theta_obs'])
      for i in xrange(n_bins):
        bin_low = data[i*bin_size]
        if (i+1)*bin_size >= len(reflections):
          bin_high = data[-1]
        else:
          bin_high = data[(i+1)*bin_size]
        refls = reflections.select((reflections['two_theta_obs'] >= bin_low) &
                                   (reflections['two_theta_obs'] <= bin_high))
        a = refls['delpsical.rad']*180/math.pi
        b = refls['two_theta_obs'] - refls['two_theta_cal']
        fig = plt.figure()
        sel = (a > -0.2) & (a < 0.2) & (b > -0.05) & (b < 0.05)
        plt.hist2d(a.select(sel), b.select(sel), bins=50, range = [[-0.2, 0.2], [-0.05, 0.05]])
        cb = plt.colorbar()
        cb.set_label("N reflections")
        plt.title(r'%sBin %d (%.02f, %.02f 2$\Theta$) $\Delta2\Theta$ vs. $\Delta\Psi$. Showing %d of %d refls'%(tag,i,bin_low,bin_high,len(a.select(sel)),len(a)))
        plt.xlabel(r'$\Delta\Psi \circ$')
        plt.ylabel(r'$\Delta2\Theta \circ$')

      # Plot delta 2theta vs. 2theta
      a = reflections['two_theta_obs']#[:71610]
      b = reflections['two_theta_obs'] - reflections['two_theta_cal']
      fig = plt.figure()
      limits = -0.05, 0.05
      sel = (b > limits[0]) & (b < limits[1])
      plt.hist2d(a.select(sel), b.select(sel), bins=100, range=((0,50), limits))
      plt.clim((0,100))
      cb = plt.colorbar()
      cb.set_label("N reflections")
      plt.title(r'%s$\Delta2\Theta$ vs. 2$\Theta$. Showing %d of %d refls'%(tag,len(a.select(sel)),len(a)))
      plt.xlabel(r'2$\Theta \circ$')
      plt.ylabel(r'$\Delta2\Theta \circ$')

      # calc the trendline
      z = np.polyfit(a.select(sel), b.select(sel), 1)
      print 'y=%.7fx+(%.7f)'%(z[0],z[1])

      # Plots with single values per panel
      self.detector_plot_dict(detector, refl_counts, u"%s N reflections"%t, u"%6d", show=False)
      self.detector_plot_dict(detector, rmsds, "%s Positional RMSDs (microns)"%t, u"%4.1f", show=False)
      self.detector_plot_dict(detector, radial_rmsds, "%s Radial RMSDs (microns)"%t, u"%4.1f", show=False)
      self.detector_plot_dict(detector, transverse_rmsds, "%s Transverse RMSDs (microns)"%t, u"%4.1f", show=False)
      self.detector_plot_dict(detector, ttdpcorr, r"%s $\Delta2\Theta$ vs. $\Delta\Psi$ CC"%t, u"%5.3f", show=False)

      self.plot_unitcells(experiments)
      self.plot_data_by_two_theta(reflections, tag)

      # Plot data by panel group
      sorted_values = sorted(pg_bc_dists.values())
      vdict = {}
      for k in pg_bc_dists:
        vdict[pg_bc_dists[k]] = k
      sorted_keys = [vdict[v] for v in sorted_values if vdict[v] in rmsds]
      x = [sorted_values[i] for i in xrange(len(sorted_values)) if pg_bc_dists.keys()[i] in rmsds]

      self.plot_multi_data(x,
                           [[pg_refls_count_d[k] for k in sorted_keys],
                            ([rmsds[k] for k in sorted_keys],
                             [radial_rmsds[k] for k in sorted_keys],
                             [transverse_rmsds[k] for k in sorted_keys]),
                            [radial_rmsds[k]/transverse_rmsds[k] for k in sorted_keys],
                            [mean_delta_two_theta[k] for k in sorted_keys]],
                           "Panel group distance from beam center (mm)",
                           ["N reflections",
                            ("Overall RMSD",
                             "Radial RMSD",
                             "Transverse RMSD"),
                            "R/T RMSD ratio",
                            "Delta two theta"],
                           ["N reflections",
                            "RMSD (microns)",
                            "R/T RMSD ratio",
                            "Delta two theta (degrees)"],
                           "%sData by panelgroup"%tag)

      if self.params.save_pdf:
        pp = PdfPages('residuals_%s.pdf'%(tag.strip()))
        for i in plt.get_fignums():
          pp.savefig(plt.figure(i))
        pp.close()
      else:
        plt.show()
Esempio n. 42
0
def generate_mask(imageset: ImageSet,
                  params: libtbx.phil.scope_extract) -> Tuple[flex.bool]:
    """Generate a mask based on the input parameters.

    Args:
      imageset (ImageSet): The imageset for which to generate a mask
      params (libtbx.phil.scope_extract): The phil parameters for mask generation. This
        should be an extract of `dials.util.masking.phil_scope`
    """
    # Get the detector and beam
    detector = imageset.get_detector()
    beam = imageset.get_beam()

    # Create the mask for each panel
    masks = []
    for index, panel in enumerate(detector):

        mask = flex.bool(flex.grid(reversed(panel.get_image_size())), True)

        # Add a border around the image
        if params.border > 0:
            logger.debug(f"Generating border mask:\n border = {params.border}")
            border = params.border
            height, width = mask.all()
            borderx = flex.bool(flex.grid(border, width), False)
            bordery = flex.bool(flex.grid(height, border), False)
            mask[0:border, :] = borderx
            mask[-border:, :] = borderx
            mask[:, 0:border] = bordery
            mask[:, -border:] = bordery

        # Apply the untrusted regions
        for region in params.untrusted:
            if region.panel is None:
                region.panel = 0
            if region.panel == index:
                if not any([
                        region.circle, region.rectangle, region.polygon,
                        region.pixel
                ]):
                    mask[:, :] = flex.bool(flex.grid(mask.focus()), False)
                    continue

                if region.circle is not None:
                    xc, yc, radius = region.circle
                    logger.debug("Generating circle mask:\n" +
                                 f" panel = {region.panel}\n" +
                                 f" xc = {xc}\n" + f" yc = {yc}\n" +
                                 f" radius = {radius}")
                    mask_untrusted_circle(mask, xc, yc, radius)
                if region.rectangle is not None:
                    x0, x1, y0, y1 = region.rectangle
                    logger.debug("Generating rectangle mask:\n" +
                                 f" panel = {region.panel}\n" +
                                 f" x0 = {x0}\n" + f" y0 = {y0}\n" +
                                 f" x1 = {x1}\n" + f" y1 = {y1}")
                    mask_untrusted_rectangle(mask, x0, x1, y0, y1)
                if region.polygon is not None:
                    assert (len(region.polygon) %
                            2 == 0), "Polygon must contain 2D coords"
                    vertices = []
                    for i in range(int(len(region.polygon) / 2)):
                        x = region.polygon[2 * i]
                        y = region.polygon[2 * i + 1]
                        vertices.append((x, y))
                    polygon = flex.vec2_double(vertices)
                    logger.debug(
                        f"Generating polygon mask:\n panel = {region.panel}\n"
                        + "\n".join(f" coord = {vertex}"
                                    for vertex in vertices))
                    mask_untrusted_polygon(mask, polygon)
                if region.pixel is not None:
                    mask[region.pixel] = False

        # Generate high and low resolution masks
        if params.d_min is not None:
            logger.debug(
                f"Generating high resolution mask:\n d_min = {params.d_min}")
            _apply_resolution_mask(mask, beam, panel, 0, params.d_min)
        if params.d_max is not None:
            logger.debug(
                f"Generating low resolution mask:\n d_max = {params.d_max}")
            d_max = params.d_max
            d_inf = max(d_max + 1, 1e9)
            _apply_resolution_mask(mask, beam, panel, d_max, d_inf)

        try:
            # Mask out the resolution range
            for drange in params.resolution_range:
                d_min = min(drange)
                d_max = max(drange)
                assert d_min < d_max, "d_min must be < d_max"
                logger.debug("Generating resolution range mask:\n" +
                             f" d_min = {d_min}\n" + f" d_max = {d_max}")
                _apply_resolution_mask(mask, beam, panel, d_min, d_max)
        except TypeError:
            # Catch the default value None of params.resolution_range
            if any(params.resolution_range):
                raise

        # Mask out the resolution ranges for the ice rings
        for drange in generate_ice_ring_resolution_ranges(
                beam, panel, params.ice_rings):
            d_min = min(drange)
            d_max = max(drange)
            assert d_min < d_max, "d_min must be < d_max"
            logger.debug("Generating ice ring mask:\n" +
                         f" d_min = {d_min:.4f}\n" + f" d_max = {d_max:.4f}")
            _apply_resolution_mask(mask, beam, panel, d_min, d_max)

        # Add to the list
        masks.append(mask)

    # Return the mask
    return tuple(masks)
Esempio n. 43
0
def tv_alg(image, mask, tolerance=1e-3, max_iter=10):
  from dials.array_family import flex
  from scitbx import matrix

  # Set lambda
  L = flex.double(image.accessor(), 0)
  for j in range(image.all()[0]):
    for i in range(image.all()[1]):
      if mask[j,i]:
        L[j,i] = 100
      else:
        L[j,i] = 0

  gamma = 1
  F = image
  UPREV = flex.double(image.accessor(), 0)
  D = flex.vec2_double(image.accessor(), (0,0))
  B = flex.vec2_double(image.accessor(), (0,0))
  for num_iter in range(max_iter):

    U = UPREV

    del_U = del_op(U)

    # Solve D subproblem
    for j in range(image.all()[0]):
      for i in range(image.all()[1]):
        d = matrix.col(del_U[j,i]) + matrix.col(B[j,i])
        dn = d.length()
        if dn == 0:
          D[j,i] = (0,0)
        else:
          D[j,i] = (d / dn) * max([dn-1.0/gamma, 0])

    # Solve U subproblem
    div_db = div_op(D - B)
    delta_U = delta_op(U)

    UCURR = flex.double(image.accessor(), 0)
    for j in range(image.all()[0]):
      for i in range(image.all()[1]):
        if L[j,i] == 0:
          UCURR[j,i] = 0
        else:
          const = gamma / L[j,i]
          UCURR[j,i] = F[j,i] - const*div_db[j,i]+ const*delta_U[j,i]

    # Do the update
    B = B + del_U - D

    # Break if reached convergence
    from math import sqrt
    l2norm = sqrt(sum([u**2 for u in (UCURR - UPREV)]))
    print l2norm
    if l2norm < tolerance:
      break

    UPREV = UCURR
    from matplotlib import pylab
    #pylab.imshow(UCURR.as_numpy_array())
    #pylab.show()

  return UCURR
Esempio n. 44
0
from __future__ import absolute_import, division, print_function
from simtbx.nanoBragg import nanoBragg, nanoBragg_beam
from dials.array_family import flex
import numpy as np
"""Purpose of the test:  compare nanoBragg background two ways:
1) single channel
2) multiple channels
Overall photon fluence is the same in both simulations.
Results will be nearly identical if the multiple channel bandpass is small,
and if the spectrum is even (tophat), not irregular (random).
"""

water = flex.vec2_double([(0, 2.57), (0.0365, 2.58), (0.07, 2.8), (0.12, 5),
                          (0.162, 8), (0.18, 7.32), (0.2, 6.75), (0.216, 6.75),
                          (0.236, 6.5), (0.28, 4.5), (0.3, 4.3), (0.345, 4.36),
                          (0.436, 3.77), (0.5, 3.17)])


def gaussian(x, mu, sig):
    return np.exp(-np.power(x - mu, 2.) / (2 * np.power(sig, 2.)))


class run_background_simulation:
    def __init__(self):
        self.SIM = nanoBragg()
        self.SIM.progress_meter = False
        self.SIM.Fbg_vs_stol = water
        self.SIM.amorphous_sample_thick_mm = 0.1
        self.SIM.amorphous_density_gcm3 = 1
        self.SIM.amorphous_molecular_weight_Da = 18
        self.total_flux = self.SIM.flux = 1e12
Esempio n. 45
0
      n_indexed = 0
      for i_expt in experiments.where(crystal=crystal_model):
        n_indexed += (self.reflections['id'] == i).count(True)
      info("model %i (%i reflections):" %(i+1, n_indexed))
      info(crystal_model)

    self.refined_reflections['xyzcal.px'] = flex.vec3_double(
      len(self.refined_reflections))
    for i, imageset in enumerate(self.imagesets):
      imgset_sel = self.refined_reflections['imageset_id'] == i
      # set xyzcal.px field in self.refined_reflections
      refined_reflections = self.refined_reflections.select(imgset_sel)
      panel_numbers = flex.size_t(refined_reflections['panel'])
      xyzcal_mm = refined_reflections['xyzcal.mm']
      x_mm, y_mm, z_rad = xyzcal_mm.parts()
      xy_cal_mm = flex.vec2_double(x_mm, y_mm)
      xy_cal_px = flex.vec2_double(len(xy_cal_mm))
      for i_panel in range(len(imageset.get_detector())):
        panel = imageset.get_detector()[i_panel]
        sel = (panel_numbers == i_panel)
        isel = sel.iselection()
        ref_panel = refined_reflections.select(panel_numbers == i_panel)
        xy_cal_px.set_selected(
          sel, panel.millimeter_to_pixel(xy_cal_mm.select(sel)))
      x_px, y_px = xy_cal_px.parts()
      scan = imageset.get_scan()
      if scan is not None:
        z_px = scan.get_array_index_from_angle(z_rad, deg=False)
      else:
        # must be a still image, z centroid not meaningful
        z_px = z_rad
Esempio n. 46
0
#    raise ValueError,"Output datasze file must be specified."
  else:
    datasize = args.pop(datasizeidx).split("=")[1]

  import copy, os

  import dxtbx
  from dxtbx.model.experiment_list import ExperimentListFactory
  from dials.array_family import flex
   
  experiments = ExperimentListFactory.from_json_file(json, check_format=False)
  beam = experiments[0].beam
  detector = experiments[0].detector
 
  lab_coordinates = flex.vec3_double()
  for panel in detector: 
    pixels = flex.vec2_double(panel.get_image_size())
    mms = panel.pixel_to_millimeter(pixels)
    lab_coordinates.extend(panel.get_lab_coord(mms))

    # generate s1 vectors
  s1 = lab_coordinates.each_normalize() * (1/beam.get_wavelength())
    # Generate x vectors
  x = np.asarray(s1 - beam.get_s0())
    
#  DATAsize = np.asarray(detector[0].get_image_size())

#  np.save(xvectors,x)
#  np.save(datasize,DATAsize)
  x.astype('float32').tofile(xvectors)
Esempio n. 47
0
 def populate_pixel_positions(self):
   assert self.reflections.has_key('xyzcal.px'), "no calculated spot positions"
   self.frame['mapped_predictions'][0] = flex.vec2_double()
   for i in xrange(len(self.reflections['xyzcal.px'])):
     self.frame['mapped_predictions'][0].append(tuple(self.reflections['xyzcal.px'][i][1::-1])) # 1::-1 reverses the order taking only the first two elements first.
Esempio n. 48
0
def model_reflection_rt0(reflection, experiment, params):
  import math
  import random
  from scitbx import matrix
  from dials.array_family import flex
  still = (experiment.goniometer is None) or (experiment.scan is None)

  d2r = math.pi / 180.0

  hkl = reflection['miller_index']
  xyz = reflection['xyzcal.px']
  xyz_mm = reflection['xyzcal.mm']
  panel = reflection['panel']
  p = experiment.detector[panel]
  s0 = matrix.col(experiment.beam.get_s0())

  if params.debug:
    print 'hkl = %d %d %d' % hkl
    print 'xyz px = %f %f %f' % xyz
    print 'xyz mm = %f %f %f' % xyz_mm
    if reflection['entering']:
      print 'entering'
    else:
      print 'exiting'

    resolution = p.get_resolution_at_pixel(s0, reflection['xyzobs.px.value'][0:2])
    print "Resolution = %.2f"% resolution

  if still:
    Amat = matrix.sqr(experiment.crystal.get_A())
    p0_star = Amat * hkl
    angle, s1 = predict_still_delpsi_and_s1(p0_star, experiment)
    assert angle

    if params.debug:
      print 'delpsi angle = %f' % angle
  else:
    Amat = matrix.sqr(experiment.crystal.get_A_at_scan_point(int(xyz[2])))
    p0_star = Amat * hkl
    angles = predict_angles(p0_star, experiment)

    assert(angles)

    if params.debug:
      print 'angles = %f %f' % angles

    angle = angles[0] if (abs(angles[0] - xyz_mm[2]) <
                          abs(angles[1] - xyz_mm[2])) else angles[1]

  # FIX DQE for this example *** NOT PORTABLE ***
  n = matrix.col(p.get_normal())
  s1 = matrix.col(reflection['s1'])
  t = p.get_thickness() / math.cos(s1.angle(n))
  if params.debug and 'dqe' in reflection:
    print 'old dqe = %f' % reflection['dqe']
  reflection['dqe'] = (1.0 - math.exp(-p.get_mu() * t * 0.1))
  if params.debug:
    print 'dqe = %f' % reflection['dqe']

  if params.physics:
    i0 = reflection['intensity.sum.value'] / reflection['dqe']
  else:
    i0 = reflection['intensity.sum.value']

  if params.min_isum:
    if i0 < params.min_isum:
      return

  s1 = reflection['s1']
  if not still:
    a = matrix.col(experiment.goniometer.get_rotation_axis())

  if params.debug:
    print 's1 = %f %f %f' % s1

  pixels = reflection['shoebox']
  pixels.flatten()
  data = pixels.data
  dz, dy, dx = data.focus()

  # since now 2D data
  data.reshape(flex.grid(dy, dx))

  if params.show:
    print 'Observed reflection (flattened in Z):'
    print
    for j in range(dy):
      for i in range(dx):
        print '%5d' % data[(j, i)],
      print

  if params.sigma_m is None:
    sigma_m = 0
  elif params.sigma_m > 0:
    sigma_m = params.sigma_m * d2r
  else:
    sigma_m = experiment.profile.sigma_m() * d2r

  if params.sigma_b is None:
    sigma_b = 0
  elif params.sigma_b > 0:
    sigma_b = params.sigma_b * d2r
  elif experiment.profile is not None:
    sigma_b = experiment.profile.sigma_b() * d2r

  r0 = xyz_mm[2]

  detector = experiment.detector

  if params.whole_panel:
    whole_panel = flex.double(flex.grid(p.get_image_size()[1], p.get_image_size()[0]))
  all_pix = flex.vec2_double()
  all_iw = flex.double()

  patch = flex.double(dy * dx, 0)
  patch.reshape(flex.grid(dy, dx))

  bbox = reflection['bbox']

  if params.interference_weighting.enable:
    # Kroon-Batenburg 2015 equation 7
    uc = experiment.crystal.get_unit_cell()
    lmbda = experiment.beam.get_wavelength()

    if params.interference_weighting.ncell:
      if params.interference_weighting.domain_size_angstroms:
        raise RuntimeError, "Only specify ncell or domain_size_angstroms, not both"
      ncell = params.interference_weighting.ncell
    else:
      if params.interference_weighting.domain_size_angstroms:
        diameter = params.interference_weighting.domain_size_angstroms
      elif hasattr(experiment.crystal, "_ML_domain_size_ang"):
        diameter = experiment.crystal._ML_domain_size_ang
      else:
        diameter = None
      if diameter is None:
        ncell = 25
      else:
        # assume spherical crystallite
        volume = (math.pi*4/3)*((diameter/2)**3)
        ncell = volume / uc.volume()

    if params.debug:
      print "ncell: %.1f"%ncell

    d = uc.d(hkl)
    theta = uc.two_theta(hkl, lmbda)/2
    iw_s = ncell * (abs(hkl[0]) + abs(hkl[1]) + abs(hkl[2]))
    iw_B = 2*math.pi*d*math.cos(theta)/lmbda
    iw_term1 = (1/(2*(math.sin(theta)**2))) * (1/iw_s)

  scale = params.scale
  if params.nrays is None:
    nrays = int(round(i0 * scale))
  else:
    nrays = params.nrays
  if params.show:
    print '%d rays' % (nrays)
  for i in range(nrays):
    if params.real_space_beam_simulation.enable:
      # all values in mm
      if params.real_space_beam_simulation.source_shape == 'square':
        source_length = params.real_space_beam_simulation.source_dimension
        sx = (random.random() * source_length) - (source_length / 2)
        sy = (random.random() * source_length) - (source_length / 2)
      elif params.real_space_beam_simulation.source_shape == 'circle':
        source_radius = params.real_space_beam_simulation.source_dimension
        v = matrix.col((random.random() * source_radius, 0, 0))
        v = v.rotate(matrix.col((0,0,1)), random.random() * 2.0 * math.pi)
        sx = v[0]
        sy = v[1]
      else:
        raise RuntimeError, "Invalid choice for source_shape"

      if params.real_space_beam_simulation.illuminated_crystal_volume.shape == 'sphere':
        crystal_radius = params.real_space_beam_simulation.illuminated_crystal_volume.sphere.radius
        v = get_random_axis() * crystal_radius * random.random()

      elif params.real_space_beam_simulation.illuminated_crystal_volume.shape == 'rectangular_parallelepiped':
        width = params.real_space_beam_simulation.illuminated_crystal_volume.rectangular_parallelepiped.width
        depth = params.real_space_beam_simulation.illuminated_crystal_volume.rectangular_parallelepiped.depth

        cx = (random.random() * width) - (width / 2)
        cy = (random.random() * width) - (width / 2)
        cz = (random.random() * depth) - (depth / 2)
        v = matrix.col((cx, cy, cz))
      else:
        raise RuntimeError, "Invalid choice for illuminated_crystal_volume.shape"

      # construct a vector from a random point on the source to a random point in the crystal (note the minus sign!)
      source_to_crystal = -params.real_space_beam_simulation.source_to_crystal
      real_space_beam_vector = matrix.col((sx, sy, source_to_crystal)) + v

      # construct the randomized reciprocal space beam vector
      b = real_space_beam_vector.normalize() * (1/experiment.beam.get_wavelength())
      if params.sigma_l:
        l_scale = random.gauss(1, params.sigma_l)
        b *= l_scale
    else:
      if params.sigma_l:
        l_scale = random.gauss(1, params.sigma_l)
        b = random_vector_cone(s0 * l_scale, sigma_b)
      else:
        b = random_vector_cone(s0, sigma_b)
    if params.sigma_m_rotates_relp:
      if params.sigma_cell:
        cell_scale = random.gauss(1, params.sigma_cell)
        p0 = random_vector_cone(cell_scale * Amat * hkl, sigma_m)
      else:
        p0 = random_vector_cone(Amat * hkl, sigma_m)
    else:
      axis = get_random_axis()
      rotation = random.gauss(0, sigma_m)
      R = axis.axis_and_angle_as_r3_rotation_matrix(rotation)
      if params.sigma_cell:
        cell_scale = random.gauss(1, params.sigma_cell)
        p0 = cell_scale * R * Amat * hkl
      else:
        p0 = R * Amat * hkl
    if params.rs_node_size > 0:
      ns = params.rs_node_size
      import random
      dp0 = matrix.col((random.gauss(0, ns),
                        random.gauss(0, ns),
                        random.gauss(0, ns)))
      p0 += dp0
    if still:
      result = predict_still_delpsi_and_s1(p0, experiment, b, s1_rotated = not params.interference_weighting.enable)
      if result is None:
        # scattered ray ended up in blind region
        continue
      epsilon, s1 = result
    else:
      angles = predict_angles(p0, experiment, b)
      if angles is None:
        # scattered ray ended up in blind region
        continue
      r = angles[0] if reflection['entering'] else angles[1]
      p = p0.rotate(a, r)
      s1 = p + b

    if params.interference_weighting.enable:
      # Rest of Kroon-Batenburg eqn 7
      iw = iw_term1 * (math.sin(iw_s*iw_B*epsilon)**2) / ((iw_B*epsilon)**2)
    else:
      iw = 1

    if params.physics:
      model_path_through_sensor(detector, reflection, s1, patch, scale)

    else:
      try:
        xy = p.get_ray_intersection(s1)
      except RuntimeError, e:
        # Not on the detector
        continue

      all_pix.append(xy)
      all_iw.append(iw)

      # FIXME DO NOT USE THIS FUNCTION EVENTUALLY...
      x, y = detector[panel].millimeter_to_pixel(xy)
      x = int(round(x))
      y = int(round(y))
      if params.whole_panel:
        if x < 0 or x >= whole_panel.focus()[1]:
          continue
        if y < 0 or y >= whole_panel.focus()[0]:
          continue
        whole_panel[(y, x)] += 1.0 * iw / scale
      if x < bbox[0] or x >= bbox[1]:
        continue
      if y < bbox[2] or y >= bbox[3]:
        continue
      x -= bbox[0]
      y -= bbox[2]
      # FIXME in here try to work out probability distribution along path
      # length through the detector sensitive surface i.e. deposit fractional
      # counts along pixels (and allow for DQE i.e. photon passing right through
      # the detector)
      patch[(y, x)] += 1.0 * iw / scale
Esempio n. 49
0
    #  import dxtbx
    t0 = time()
    #  img = FormatSMVADSCNoDateStamp(imgname)
    img = dxtbx.load(imgname)
    detector = img.get_detector()
    beam = img.get_beam()
    scan = img.get_scan()
    gonio = img.get_goniometer()

    print "transform pixel numbers to mm positions and rotational degrees"

    print "Creating pixel map..."
    t0 = time()
    lab_coordinates = flex.vec3_double()
    for panel in detector:
        pixels = flex.vec2_double(panel.get_image_size())
        mms = panel.pixel_to_millimeter(pixels)
        lab_coordinates.extend(panel.get_lab_coord(mms))

        # generate s1 vectors
    s1_vectors = lab_coordinates.each_normalize() * (1 / beam.get_wavelength())
    # Generate x vectors
    x_vectors = np.asarray(s1_vectors - beam.get_s0())

    #  print "there are ",x_vectors.size()," elements in x_vectors"
    tel = time() - t0
    print "done creating pixel map (", tel, " sec)"

    workdir = "tmpdir_common"
    #  if (os.path.isdir(workdir)):
    #    command = 'rm -r {0}'.format(workdir)
Esempio n. 50
0
    def generate(self, imageset):
        """Generate the mask."""
        # Get the detector and beam
        detector = imageset.get_detector()
        beam = imageset.get_beam()

        # Get the first image
        image = imageset.get_raw_data(0)
        assert len(detector) == len(image)

        # Create the mask for each panel
        masks = []
        for index, (im, panel) in enumerate(zip(image, detector)):

            # Build a trusted mask by looking for pixels that are always outside
            # the trusted range. This identifies bad pixels, but does not include
            # pixels that are overloaded on some images.
            if self.params.use_trusted_range:
                warnings.warn(
                    "Checking for hot pixels using the trusted_range is"
                    " deprecated. https://github.com/dials/dials/issues/1156",
                    FutureWarning,
                )
                trusted_mask = None
                low, high = panel.get_trusted_range()

                # Take 10 evenly-spaced images from the imageset. Pixels outside
                # the trusted mask on all of these images are considered bad and
                # masked. https://github.com/dials/dials/issues/1061
                stride = max(int(len(imageset) / 10), 1)
                image_indices = range(0, len(imageset), stride)

                for image_index in image_indices:
                    image_data = imageset.get_raw_data(
                        image_index)[index].as_double()
                    frame_mask = (image_data > low) & (image_data < high)
                    if trusted_mask is None:
                        trusted_mask = frame_mask
                    else:
                        trusted_mask = trusted_mask | frame_mask

                    if trusted_mask.count(False) == 0:
                        break
                mask = trusted_mask
            else:
                mask = flex.bool(flex.grid(im.all()), True)

            # Add a border around the image
            if self.params.border > 0:
                logger.info("Generating border mask:")
                logger.info(" border = %d" % self.params.border)
                border = self.params.border
                height, width = mask.all()
                borderx = flex.bool(flex.grid(border, width), False)
                bordery = flex.bool(flex.grid(height, border), False)
                mask[0:border, :] = borderx
                mask[-border:, :] = borderx
                mask[:, 0:border] = bordery
                mask[:, -border:] = bordery

            # Apply the untrusted regions
            for region in self.params.untrusted:
                if region.panel is None:
                    region.panel = 0
                if region.panel == index:
                    if not any([
                            region.circle, region.rectangle, region.polygon,
                            region.pixel
                    ]):
                        mask[:, :] = flex.bool(flex.grid(mask.focus()), False)
                        continue

                    if region.circle is not None:
                        xc, yc, radius = region.circle
                        logger.info("Generating circle mask:")
                        logger.info(" panel = %d" % region.panel)
                        logger.info(" xc = %d" % xc)
                        logger.info(" yc = %d" % yc)
                        logger.info(" radius = %d" % radius)
                        mask_untrusted_circle(mask, xc, yc, radius)
                    if region.rectangle is not None:
                        x0, x1, y0, y1 = region.rectangle
                        logger.info("Generating rectangle mask:")
                        logger.info(" panel = %d" % region.panel)
                        logger.info(" x0 = %d" % x0)
                        logger.info(" y0 = %d" % y0)
                        logger.info(" x1 = %d" % x1)
                        logger.info(" y1 = %d" % y1)
                        mask_untrusted_rectangle(mask, x0, x1, y0, y1)
                    if region.polygon is not None:
                        assert (len(region.polygon) %
                                2 == 0), "Polygon must contain 2D coords"
                        vertices = []
                        for i in range(int(len(region.polygon) / 2)):
                            x = region.polygon[2 * i]
                            y = region.polygon[2 * i + 1]
                            vertices.append((x, y))
                        polygon = flex.vec2_double(vertices)
                        logger.info("Generating polygon mask:")
                        logger.info(" panel = %d" % region.panel)
                        for vertex in vertices:
                            logger.info(" coord = (%d, %d)" % (vertex))
                        mask_untrusted_polygon(mask, polygon)
                    if region.pixel is not None:
                        mask[region.pixel] = False

            # Generate high and low resolution masks
            if self.params.d_min is not None:
                logger.info("Generating high resolution mask:")
                logger.info(" d_min = %f" % self.params.d_min)
                _apply_resolution_mask(mask, beam, panel, 0, self.params.d_min)
            if self.params.d_max is not None:
                logger.info("Generating low resolution mask:")
                logger.info(" d_max = %f" % self.params.d_max)
                d_max = self.params.d_max
                d_inf = max(d_max + 1, 1e9)
                _apply_resolution_mask(mask, beam, panel, d_max, d_inf)

            try:
                # Mask out the resolution range
                for drange in self.params.resolution_range:
                    d_min = min(drange)
                    d_max = max(drange)
                    assert d_min < d_max, "d_min must be < d_max"
                    logger.info("Generating resolution range mask:")
                    logger.info(" d_min = %f" % d_min)
                    logger.info(" d_max = %f" % d_max)
                    _apply_resolution_mask(mask, beam, panel, d_min, d_max)
            except TypeError:
                # Catch the default value None of self.params.resolution_range
                if any(self.params.resolution_range):
                    raise

            # Mask out the resolution ranges for the ice rings
            for drange in generate_ice_ring_resolution_ranges(
                    beam, panel, self.params.ice_rings):
                d_min = min(drange)
                d_max = max(drange)
                assert d_min < d_max, "d_min must be < d_max"
                logger.info("Generating ice ring mask:")
                logger.info(" d_min = %f" % d_min)
                logger.info(" d_max = %f" % d_max)
                _apply_resolution_mask(mask, beam, panel, d_min, d_max)

            # Add to the list
            masks.append(mask)

        # Return the mask
        return tuple(masks)
Esempio n. 51
0
  def generate(self, imageset):
    ''' Generate the mask. '''
    from dials.util import ResolutionMaskGenerator
    from dials.util import mask_untrusted_rectangle
    from dials.util import mask_untrusted_circle
    from dials.util import mask_untrusted_polygon
    from dials.util import mask_untrusted_resolution_range
    from dials.array_family import flex
    from math import floor, ceil
    from logging import info

    # Get the detector and beam
    detector = imageset.get_detector()
    beam = imageset.get_beam()

    # Get the first image
    image = imageset.get_raw_data(0)
    assert(len(detector) == len(image))

    # Create the mask for each image
    masks = []
    for index, (im, panel) in enumerate(zip(image, detector)):

      # The image width height
      height, width = im.all()

      # Create the basic mask from the trusted range
      if self.params.use_trusted_range:
        low, high = panel.get_trusted_range()
        imd = im.as_double()
        mask = (imd > low) & (imd < high)
      else:
        mask = flex.bool(flex.grid(im.all()), True)

      # Add a border around the image
      if self.params.border > 0:
        info("Generating border mask:")
        info(" border = %d" % self.params.border)
        border = self.params.border
        height, width = mask.all()
        borderx = flex.bool(flex.grid(border, width), False)
        bordery = flex.bool(flex.grid(height, border), False)
        mask[0:border,:] = borderx
        mask[-border:,:] = borderx
        mask[:,0:border] = bordery
        mask[:,-border:] = bordery

      # Apply the untrusted regions
      for region in self.params.untrusted:
        if region.panel == index:
          if region.circle is not None:
            xc, yc, radius = region.circle
            info("Generating circle mask:")
            info(" panel = %d" % region.panel)
            info(" xc = %d" % xc)
            info(" yc = %d" % yc)
            info(" radius = %d" % radius)
            mask_untrusted_circle(mask, xc, yc, radius)
          if region.rectangle is not None:
            x0, x1, y0, y1 = region.rectangle
            info("Generating rectangle mask:")
            info(" panel = %d" % region.panel)
            info(" x0 = %d" % x0)
            info(" y0 = %d" % y0)
            info(" x1 = %d" % x1)
            info(" y1 = %d" % y1)
            mask_untrusted_rectangle(mask, x0, x1, y0, y1)
          if region.polygon is not None:
            assert len(region.polygon) % 2 == 0, "Polygon must contain 2D coords"
            vertices = []
            for i in range(int(len(region.polygon)/2)):
              x = region.polygon[2*i]
              y = region.polygon[2*i+1]
              vertices.append((x,y))
            polygon = flex.vec2_double(vertices)
            info("Generating polygon mask:")
            info(" panel = %d" % region.panel)
            for vertex in vertices:
              info(" coord = (%d, %d)" % (vertex))
            mask_untrusted_polygon(mask, polygon)

      # Create the resolution mask generator
      class ResolutionMaskGeneratorGetter(object):
        def __init__(self, beam, panel):
          self.beam = beam
          self.panel = panel
          self.result = None
        def __call__(self):
          if self.result is None:
            self.result = ResolutionMaskGenerator(beam, panel)
          return self.result
      get_resolution_mask_generator = ResolutionMaskGeneratorGetter(beam, panel)

      # Generate high and low resolution masks
      if self.params.d_min is not None:
        info("Generating high resolution mask:")
        info(" d_min = %f" % self.params.d_min)
        get_resolution_mask_generator().apply(mask, 0, self.params.d_min)
      if self.params.d_max is not None:
        info("Generating low resolution mask:")
        info(" d_max = %f" % self.params.d_max)
        d_min = self.params.d_max
        d_max = max(d_min + 1, 1e9)
        get_resolution_mask_generator().apply(mask, d_min, d_max)

      # Mask out the resolution range
      for drange in self.params.resolution_range:
        d_min=min(drange)
        d_max=max(drange)
        assert d_min < d_max, "d_min must be < d_max"
        info("Generating resolution range mask:")
        info(" d_min = %f" % d_min)
        info(" d_max = %f" % d_max)
        get_resolution_mask_generator().apply(mask, d_min, d_max)

      # Mask out the resolution ranges for the ice rings
      for drange in generate_ice_ring_resolution_ranges(
          beam, panel, self.params.ice_rings):
        d_min=min(drange)
        d_max=max(drange)
        assert d_min < d_max, "d_min must be < d_max"
        info("Generating ice ring mask:")
        info(" d_min = %f" % d_min)
        info(" d_max = %f" % d_max)
        get_resolution_mask_generator().apply(mask, d_min, d_max)

      # Add to the list
      masks.append(mask)

    # Return the mask
    return tuple(masks)