def get_symop_correlation_coefficients(miller_array, use_binning=False):
    corr_coeffs = flex.double()
    n_refs = flex.int()
    space_group = miller_array.space_group()
    for smx in space_group.smx():
        reindexed_array = miller_array.change_basis(sgtbx.change_of_basis_op(smx))
        intensity, intensity_rdx = reindexed_array.common_sets(miller_array)
        if use_binning:
            intensity.use_binning_of(miller_array)
            intensity_rdx.use_binning_of(miller_array)
            cc = intensity.correlation(intensity_rdx, use_binning=use_binning)
            corr_coeffs.append(
                flex.mean_weighted(
                    flex.double(i for i in cc.data if i is not None),
                    flex.double(
                        j for i, j in zip(cc.data, cc.binner.counts()) if i is not None
                    ),
                )
            )
        else:
            corr_coeffs.append(
                intensity.correlation(
                    intensity_rdx, use_binning=use_binning
                ).coefficient()
            )
        n_refs.append(intensity.size())
    return corr_coeffs, n_refs
예제 #2
0
  maxy = flex.max(all_pix.parts()[1])
  minx = flex.min(all_pix.parts()[0])
  miny = flex.min(all_pix.parts()[1])
  dx = (maxx-minx)/2
  dy = (maxy-miny)/2
  medx = minx + (dx)
  medy = miny + (dy)
  if maxx-minx > maxy-miny:
    miny = medy-dx
    maxy = medy+dx
  else:
    minx = medx-dy
    maxx = medx+dy
  limits = [[minx, maxx], [miny, maxy]]

  reflection['xyzsim.mm'] = (flex.mean_weighted(all_pix.parts()[0], all_iw),
                             flex.mean_weighted(all_pix.parts()[1], all_iw), 0.0)

  pred = p.get_ray_intersection((matrix.col(experiment.beam.get_s0()) + (Amat*hkl)).normalize() * s0.length())
  reflection['xyzpred.mm'] = (pred[0], pred[1], 0.0)

  if params.debug:
    print "obs:", reflection['xyzobs.mm.value']
    print "cal:", reflection['xyzcal.mm']
    print "sim:", reflection['xyzsim.mm']
    print "delta Obs - cal", (matrix.col(reflection['xyzobs.mm.value']) - matrix.col(reflection['xyzcal.mm'])).length() * 1000
    print "delta Obs - sim", (matrix.col(reflection['xyzobs.mm.value']) - matrix.col(reflection['xyzsim.mm'])).length() * 1000
    print "delta Cal - sim", (matrix.col(reflection['xyzcal.mm']) - matrix.col(reflection['xyzsim.mm'])).length() * 1000

  if params.plots:
    from matplotlib import pyplot as plt
예제 #3
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)], end=" ")
            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 as 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

    cc = profile_correlation(data, patch)
    if params.show:
        print("Simulated reflection (flattened in Z):")
        print()
        for j in range(dy):
            for i in range(dx):
                print("%5d" % int(patch[(j, i)]), end=" ")
            print()
        print("Correlation coefficient: %.3f isum: %.1f " % (cc, i0))

    import numpy as np

    maxx = flex.max(all_pix.parts()[0])
    maxy = flex.max(all_pix.parts()[1])
    minx = flex.min(all_pix.parts()[0])
    miny = flex.min(all_pix.parts()[1])
    dx = (maxx - minx) / 2
    dy = (maxy - miny) / 2
    medx = minx + (dx)
    medy = miny + (dy)
    if maxx - minx > maxy - miny:
        miny = medy - dx
        maxy = medy + dx
    else:
        minx = medx - dy
        maxx = medx + dy
    limits = [[minx, maxx], [miny, maxy]]

    reflection["xyzsim.mm"] = (
        flex.mean_weighted(all_pix.parts()[0], all_iw),
        flex.mean_weighted(all_pix.parts()[1], all_iw),
        0.0,
    )

    pred = p.get_ray_intersection((matrix.col(experiment.beam.get_s0()) +
                                   (Amat * hkl)).normalize() * s0.length())
    reflection["xyzpred.mm"] = (pred[0], pred[1], 0.0)

    if params.debug:
        print("obs:", reflection["xyzobs.mm.value"])
        print("cal:", reflection["xyzcal.mm"])
        print("sim:", reflection["xyzsim.mm"])
        print(
            "delta Obs - cal",
            (matrix.col(reflection["xyzobs.mm.value"]) -
             matrix.col(reflection["xyzcal.mm"])).length() * 1000,
        )
        print(
            "delta Obs - sim",
            (matrix.col(reflection["xyzobs.mm.value"]) -
             matrix.col(reflection["xyzsim.mm"])).length() * 1000,
        )
        print(
            "delta Cal - sim",
            (matrix.col(reflection["xyzcal.mm"]) -
             matrix.col(reflection["xyzsim.mm"])).length() * 1000,
        )

    if params.plots:
        from matplotlib import pyplot as plt
        from matplotlib import patches as patches
        import numpy as np

        if params.whole_panel:
            fig = plt.figure()
            ax = fig.add_subplot(111)
            plt.imshow(whole_panel.as_numpy_array(), interpolation="none")
            plt.colorbar()
            ax.add_patch(
                patches.Rectangle((bbox[0], bbox[2]),
                                  bbox[1] - bbox[0],
                                  bbox[3] - bbox[2],
                                  fill=False))
            plt.scatter(
                [reflection["xyzobs.px.value"][0]],
                [reflection["xyzobs.px.value"][1]],
                c="green",
            )
            plt.scatter([reflection["xyzcal.px"][0]],
                        [reflection["xyzcal.px"][1]],
                        c="red")
            plt.scatter([p.get_beam_centre_px(s0)[0]],
                        [p.get_beam_centre_px(s0)[1]],
                        c="gold")

            arr = whole_panel.as_numpy_array()
            centroid_x = np.average(range(arr.shape[1]), weights=arr.sum(0))
            centroid_y = np.average(range(arr.shape[0]), weights=arr.sum(1))
            plt.scatter([centroid_x], [centroid_y], c="purple")

            plt.legend(["", "Obs", "Cal", "BC", "Sim"])

        fig = plt.figure()
        ax = fig.add_subplot(111)
        results = plt.hist2d(
            all_pix.parts()[0],
            all_pix.parts()[1],
            weights=all_iw,
            bins=100,
            range=limits,
        )
        plt.colorbar()
        plt.scatter(
            [reflection["xyzobs.mm.value"][0]],
            [reflection["xyzobs.mm.value"][1]],
            c="green",
        )
        plt.scatter([reflection["xyzcal.mm"][0]], [reflection["xyzcal.mm"][1]],
                    c="red")
        plt.scatter([reflection["xyzpred.mm"][0]],
                    [reflection["xyzcal.mm"][1]],
                    c="white")
        plt.scatter([p.get_beam_centre(s0)[0]], [p.get_beam_centre(s0)[1]],
                    c="gold")

        plt.scatter([reflection["xyzsim.mm"][0]], [reflection["xyzsim.mm"][1]],
                    c="purple")

        plt.legend(["Obs", "Cal", "Pred", "BC", "Sim"])

        plt.plot(
            [reflection["xyzsim.mm"][0],
             p.get_beam_centre(s0)[0]],
            [reflection["xyzsim.mm"][1],
             p.get_beam_centre(s0)[1]],
            "k-",
            lw=2,
        )

        plt.show()

    return cc, reflection