Exemple #1
0
def calc_crystal_frame_vectors(reflection_table, experiment):
    """Calculate the diffraction vectors in the crystal frame."""

    gonio = experiment.goniometer
    fixed_rotation = np.array(gonio.get_fixed_rotation()).reshape(3, 3)
    setting_rotation = np.array(gonio.get_setting_rotation()).reshape(3, 3)
    rotation_axis = np.array(gonio.get_rotation_axis_datum())

    s0c = np.zeros((len(reflection_table), 3))
    s1c = np.zeros((len(reflection_table), 3))
    s0 = np.array(experiment.beam.get_sample_to_source_direction())
    s1 = flumpy.to_numpy(reflection_table["s1"])
    phi = flumpy.to_numpy(
        experiment.scan.get_angle_from_array_index(
            reflection_table["xyzobs.px.value"].parts()[2], deg=False))
    # exclude any data that has a bad s1.
    lengths = np.linalg.norm(s1, axis=1)
    non_zero = np.where(lengths > 0.0)
    sel_s1 = s1[non_zero]
    s1n = sel_s1 / lengths[non_zero][:, np.newaxis]
    rotation_matrix = Rotation.from_rotvec(phi[non_zero][:, np.newaxis] *
                                           rotation_axis).as_matrix()
    R = setting_rotation @ rotation_matrix @ fixed_rotation
    R_inv = np.transpose(R, axes=(0, 2, 1))
    s0c[non_zero] = R_inv @ s0
    # Pairwise matrix multiplication of the arrays of R_inv matrices and s1n vectors
    s1c[non_zero] = np.einsum("ijk,ik->ij", R_inv, s1n)

    reflection_table["s0c"] = flumpy.vec_from_numpy(s0c)
    reflection_table["s1c"] = flumpy.vec_from_numpy(s1c)
    return reflection_table
Exemple #2
0
 def calculate_gradients(self, apm):
     "calculate the gradient vector"
     a = self.error_model.components["a"].parameters[0]
     b = apm.x[0]
     Ih_table = self.error_model.binner.Ih_table
     I_hl = Ih_table.intensities
     g_hl = Ih_table.inverse_scale_factors
     weights = self.error_model.binner.weights
     bin_vars = self.error_model.binner.bin_variances
     sum_matrix = self.error_model.binner.summation_matrix
     bin_counts = self.error_model.binner.binning_info["refl_per_bin"]
     dsig_dc = (b * np.square(I_hl) * (a**2) /
                (self.error_model.binner.sigmaprime * np.square(g_hl)))
     ddelta_dsigma = (-1.0 * self.error_model.binner.delta_hl /
                      self.error_model.binner.sigmaprime)
     deriv = ddelta_dsigma * dsig_dc
     dphi_by_dvar = -2.0 * (np.full(bin_vars.size, 0.5) - bin_vars +
                            (1.0 / (2.0 * np.square(bin_vars))))
     term1 = flumpy.to_numpy(
         flumpy.from_numpy(2.0 * self.error_model.binner.delta_hl * deriv) *
         sum_matrix)
     term2a = flumpy.to_numpy(
         flumpy.from_numpy(self.error_model.binner.delta_hl) * sum_matrix)
     term2b = flumpy.to_numpy(flumpy.from_numpy(deriv) * sum_matrix)
     grad = dphi_by_dvar * ((term1 / bin_counts) -
                            (2.0 * term2a * term2b / np.square(bin_counts)))
     gradients = flex.double([np.sum(grad * weights) / np.sum(weights)])
     return gradients
Exemple #3
0
def test_flex_loop_nesting():
    fo = flex.int(10)
    npo = flumpy.to_numpy(fo)
    assert fo is flumpy.from_numpy(npo)

    # Now try vec
    fo = flex.complex_double(5)
    npo = flumpy.to_numpy(fo)
    assert flumpy.from_numpy(npo) is fo
Exemple #4
0
 def calculate_bin_variances(self) -> np.array:
     """Calculate the variance of each bin."""
     sum_deltasq = flumpy.to_numpy(
         flumpy.from_numpy(np.square(self.delta_hl)) *
         self.summation_matrix)
     sum_delta_sq = np.square(
         flumpy.to_numpy(
             flumpy.from_numpy(self.delta_hl) * self.summation_matrix))
     bin_vars = (sum_deltasq / self.binning_info["refl_per_bin"]) - (
         sum_delta_sq / np.square(self.binning_info["refl_per_bin"]))
     self.binning_info["bin_variances"] = bin_vars
     return bin_vars
Exemple #5
0
 def __init__(self, Ih_table, zmax):
     super().__init__(Ih_table, zmax)
     self.weights = flumpy.to_numpy(
         limit_outlier_weights(
             copy.deepcopy(self._Ih_table_block.weights),
             self._Ih_table_block.h_index_matrix,
         ))
Exemple #6
0
    def _beam_direction_variance_list(self,
                                      detector,
                                      reflections,
                                      centroid_definition="s1"):
        """Calculate the variance in beam direction for each spot.

        Params:
            detector The detector model
            reflections The list of reflections
            centroid_definition ENUM com or s1

        Returns:
            The list of variances
        """
        # Get the reflection columns
        shoebox = reflections["shoebox"]
        xyz = reflections["xyzobs.px.value"]

        # Loop through all the reflections
        variance = np.array([], dtype=np.float64)

        if centroid_definition == "com":
            # Calculate the beam vector at the centroid
            s1_centroid = []
            for r in range(len(reflections)):
                panel = shoebox[r].panel
                s1_centroid.append(detector[panel].get_pixel_lab_coord(
                    xyz[r][0:2]))
        else:
            s1_centroid = reflections["s1"]

        for r in range(len(reflections)):
            # Get the coordinates and values of valid shoebox pixels
            # FIXME maybe I note in Kabsch (2010) s3.1 step (v) is
            # background subtraction, appears to be missing here.
            mask = shoebox[r].mask != 0
            values = flumpy.to_numpy(shoebox[r].values(mask))
            s1 = shoebox[r].beam_vectors(detector, mask)

            angles = flumpy.to_numpy(s1.angle(s1_centroid[r], deg=False))

            if np.sum(values) > 1:
                var = np.sum(values * np.square(angles)) / (np.sum(values) - 1)
                variance = np.append(variance, var)

        # Return a list of variances
        return variance
Exemple #7
0
def test_bool():
    fo = flex.bool(flex.grid([5, 5, 5, 5, 5]))
    for indices in itertools.product(*([range(5)] * 5)):
        fo[indices] = sum(indices) % 3 == 0 or sum(indices) % 5 == 0
    as_np = flumpy.to_numpy(fo)
    for indices in itertools.product(*([range(5)] * 5)):
        assert fo[indices] == as_np[indices]
    assert fo.count(True) == as_np.sum()
Exemple #8
0
def test_flex_looping_vecs():
    # We want to try and avoid recursive nesting, but don't want to
    # return the original object if attempting to miscast vec<->numeric
    # however.... this means lots of conditions to check, so ignore now
    fo = flex.vec3_double(5)
    npo = flumpy.to_numpy(fo)
    assert flumpy.vec_from_numpy(npo) is fo

    # Don't be dumb when casting
    flex_nonvec = flex.double((9, 3))
    assert not flumpy.vec_from_numpy(
        flumpy.to_numpy(flex_nonvec)) is flex_nonvec

    # mat3
    fo = flex.mat3_double(5)
    npo = flumpy.to_numpy(fo)
    assert flumpy.mat3_from_numpy(npo) is fo
Exemple #9
0
def test_numeric_1d(flex_numeric):
    # 1d basics
    f1d = flex_numeric(range(10))
    as_np = flumpy.to_numpy(f1d)
    assert (f1d == as_np).all()
    # Change and make sure reflected in both
    as_np[2] = 42
    assert (f1d == as_np).all()
    assert as_np.dtype.char != "?"
Exemple #10
0
def test_vec2(flex_vec):
    basic_vector = [(i, i * 2) for i in range(10)]
    fo = flex_vec(basic_vector)
    as_np = flumpy.to_numpy(fo)
    assert (as_np == fo).all()
    as_np[0] = (0, 4)
    as_np[1, 1] = 42
    assert fo[0] == (0, 4)
    assert (as_np == fo).all()
Exemple #11
0
def test_nonowning():
    f_a = flex.double([0, 1, 2, 3, 4])
    n_b = flumpy.to_numpy(f_a)
    f_c = flumpy.from_numpy(n_b[1:])
    assert f_c[0] == 1
    f_c[1] = 9
    assert f_a[2] == 9
    assert n_b[2] == 9
    assert f_c[1] == 9
Exemple #12
0
def test_numeric_4d(flex_numeric):
    #  Check that we can think fourth-dimnesionally
    grid = flex.grid(1, 9, 8, 5)
    fo = flex_numeric(grid)
    assert fo.nd() == 4
    as_np = flumpy.to_numpy(fo)
    for indices in itertools.product(range(1), range(9), range(8), range(5)):
        fo[indices] = sum(indices)
        assert fo[indices] == as_np[indices]
Exemple #13
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
Exemple #14
0
def test_numeric_2d(flex_numeric):
    grid = flex.grid(10, 10)
    fo = flex_numeric(grid)
    as_np = flumpy.to_numpy(fo)

    for i in range(10):
        for j in range(10):
            as_np[j, i] = i + j
            assert fo[j, i] == as_np[j, i]
            fo[j, i] = max(i, j) - min(i, j)
            assert fo[j, i] == as_np[j, i]
Exemple #15
0
def determine_Esq_outlier_index_arrays(Ih_table, experiment, emax=10.0):
    # first calculate normalised intensities and set in the Ih_table.
    intensities = Ih_table.as_miller_array(experiment.crystal.get_unit_cell())
    normalised_intensities = quasi_normalisation(intensities)

    sel = normalised_intensities.data() > (emax**2)
    n_e2_outliers = sel.count(True)
    if n_e2_outliers:
        logger.info(
            f"{n_e2_outliers} outliers identified from normalised intensity analysis (E\xb2 > {(emax ** 2)})"
        )
    outlier_indices = (Ih_table.Ih_table_blocks[0].Ih_table["loc_indices"].
                       iloc[flumpy.to_numpy(sel)].to_numpy())
    if Ih_table.n_datasets == 1:
        return [outlier_indices]
    datasets = (Ih_table.Ih_table_blocks[0].Ih_table["dataset_id"].iloc[
        flumpy.to_numpy(sel)].to_numpy())
    final_outlier_arrays = []
    for i in range(Ih_table.n_datasets):
        final_outlier_arrays.append(outlier_indices[datasets == i])
    return final_outlier_arrays
Exemple #16
0
 def _add_dataset_to_blocks(
     self,
     dataset_id: int,
     reflections: flex.reflection_table,
     indices_array: Optional[flex.size_t] = None,
     additional_cols: Optional[List[str]] = None,
 ) -> None:
     sorted_asu_indices, perm = get_sorted_asu_indices(
         reflections["asu_miller_index"], self.space_group, self.anomalous)
     hkl = reflections["asu_miller_index"]
     df = pd.DataFrame()
     df["intensity"] = flumpy.to_numpy(reflections["intensity"])
     df["variance"] = flumpy.to_numpy(reflections["variance"])
     df["inverse_scale_factor"] = flumpy.to_numpy(
         reflections["inverse_scale_factor"])
     if isinstance(additional_cols, list):
         for col in additional_cols:
             if col in reflections:
                 df[col] = flumpy.to_numpy(reflections[col])
     if indices_array:
         df["loc_indices"] = flumpy.to_numpy(indices_array)
     else:
         df["loc_indices"] = np.arange(df.shape[0], dtype=np.uint64)
     df = df.iloc[flumpy.to_numpy(perm)]
     hkl = hkl.select(perm)
     df["dataset_id"] = np.full(df.shape[0], dataset_id, dtype=np.uint64)
     # if data are sorted by asu_index, then up until boundary, should be in same
     # block (still need to read group_id though)
     # sort data, get group ids and block_ids
     group_ids = np.zeros(sorted_asu_indices.size(), dtype=np.uint64)
     boundary = self.properties_dict["miller_index_boundaries"][0]
     boundary_id = 0
     boundaries_for_this_datset = [0]  # use to slice
     # make this a c++ method for speed?
     prev = (0, 0, 0)
     group_id = -1
     for i, index in enumerate(sorted_asu_indices):
         if index != prev:
             while index >= boundary:
                 boundaries_for_this_datset.append(i)
                 boundary_id += 1
                 boundary = self.properties_dict["miller_index_boundaries"][
                     boundary_id]
             group_id = self._asu_index_dict[tuple(index)]
             prev = index
         group_ids[i] = group_id
     while len(boundaries_for_this_datset) < self.n_work_blocks + 1:
         # catch case where last boundaries aren't reached
         boundaries_for_this_datset.append(len(sorted_asu_indices))
     # so now have group ids as well for individual dataset
     if self.n_work_blocks == 1:
         self.Ih_table_blocks[0].add_data(dataset_id, group_ids, df, hkl)
     else:
         for i, val in enumerate(boundaries_for_this_datset[:-1]):
             start = val
             end = boundaries_for_this_datset[i + 1]
             self.Ih_table_blocks[i].add_data(dataset_id,
                                              group_ids[start:end],
                                              df[start:end], hkl[start:end])
Exemple #17
0
    def match_Ih_values_to_target(self, target_Ih_table: IhTable) -> None:
        """
        Use an Ih_table as a target to set Ih values in this table.

        Given an Ih table as a target, the common reflections across the tables
        are determined and the Ih_values are set to those of the target. If no
        matching reflection is found, then the values are removed from the table.
        """
        assert target_Ih_table.n_work_blocks == 1
        target_asu_Ih_dict = dict(
            zip(
                target_Ih_table.blocked_data_list[0].asu_miller_index,
                target_Ih_table.blocked_data_list[0].Ih_values,
            ))
        new_Ih_values = np.zeros(self.size, dtype=float)
        location_in_unscaled_array = 0
        sorted_asu_indices, permuted = get_sorted_asu_indices(
            self.asu_miller_index,
            target_Ih_table.space_group,
            anomalous=target_Ih_table.anomalous,
        )
        for j, miller_idx in enumerate(OrderedSet(sorted_asu_indices)):
            n_in_group = self._csc_h_index_matrix.getcol(j).count_nonzero()
            if miller_idx in target_asu_Ih_dict:
                i = location_in_unscaled_array
                new_Ih_values[np.arange(i, i + n_in_group,
                                        dtype=np.uint64)] = np.full(
                                            n_in_group,
                                            target_asu_Ih_dict[miller_idx])
            location_in_unscaled_array += n_in_group
        self.Ih_table.loc[flumpy.to_numpy(permuted),
                          "Ih_values"] = new_Ih_values
        sel = self.Ih_values != 0.0
        new_table = self.select(sel)
        # now set attributes to update object
        self.Ih_table = new_table.Ih_table
        self.h_index_matrix = new_table.h_index_matrix
        self.h_expand_matrix = new_table.h_expand_matrix
        self.block_selections = new_table.block_selections
        self._csc_h_expand_matrix = new_table._csc_h_expand_matrix
        self._csc_h_index_matrix = new_table._csc_h_index_matrix
Exemple #18
0
    def update_data_in_blocks(self,
                              data: flex.double,
                              dataset_id: int,
                              column: str = "intensity") -> None:
        """
        Update a given column across all blocks for a given dataset.

        Given an array of data (of the same size as the input reflection
        table) and the name of the column, use the internal data to split
        this up and set in individual blocks.
        """
        assert column in ["intensity", "variance", "inverse_scale_factor"]
        assert dataset_id in range(self.n_datasets)
        # split up data for blocks
        data = flumpy.to_numpy(data)
        for block in self.blocked_data_list:
            data_for_block = data[block.block_selections[dataset_id]]
            start = block.dataset_info[dataset_id]["start_index"]
            end = block.dataset_info[dataset_id]["end_index"]
            block.Ih_table.loc[np.arange(start=start, stop=end),
                               column] = data_for_block
Exemple #19
0
def select_connected_reflections_across_datasets(Ih_table,
                                                 experiment,
                                                 Isigma_cutoff=2.0,
                                                 min_total=40000,
                                                 n_resolution_bins=20):
    """Select highly connected reflections across datasets."""
    assert Ih_table.n_work_blocks == 1
    Ih_table = Ih_table.Ih_table_blocks[0]
    sel_Ih_table = _select_groups_on_Isigma_cutoff(Ih_table, Isigma_cutoff)

    # now split into resolution bins
    sel_Ih_table.setup_binner(
        experiment.crystal.get_unit_cell(),
        experiment.crystal.get_space_group(),
        n_resolution_bins,
    )
    binner = sel_Ih_table.binner

    # prepare parameters for selection algorithm.
    n_datasets = len(set(sel_Ih_table.Ih_table["dataset_id"].to_numpy()))
    min_per_class = min_total / (n_datasets * 4.0)
    max_total = min_total * 1.2
    logger.info(
        """
Using quasi-random reflection selection. Selecting from %s symmetry groups
with <I/sI> > %s (%s reflections)). Selection target of %.2f reflections
from each dataset, with a total number between %.2f and %.2f.
""",
        sel_Ih_table.n_groups,
        Isigma_cutoff,
        sel_Ih_table.size,
        min_per_class,
        min_total,
        max_total,
    )
    # split across resolution bins
    mpc = int(min_per_class / n_resolution_bins)
    mint = int(min_total / n_resolution_bins)
    maxt = int(max_total / n_resolution_bins)

    header = ["d-range", "n_groups", "n_refl"
              ] + [str(i) for i in range(n_datasets)]
    rows = []
    if n_datasets >= 15:
        summary_rows = []
        summary_header = ["d-range", "n_groups", "n_refl"]

    indices = flex.size_t()
    dataset_ids = flex.size_t()
    total_groups_used = 0
    n_cols_used = 0

    for ibin in binner.range_all():
        sel = binner.selection(ibin)
        res_Ih_table = sel_Ih_table.select(flumpy.to_numpy(sel))
        if not res_Ih_table.Ih_table.size:
            continue

        (
            indices_this_res,
            dataset_ids_this_res,
            n_groups_used,
            total_per_dataset,
        ) = _perform_quasi_random_selection(res_Ih_table, n_datasets, mpc,
                                            mint, maxt)

        indices.extend(indices_this_res)
        dataset_ids.extend(dataset_ids_this_res)
        total_groups_used += n_groups_used
        d0, d1 = binner.bin_d_range(ibin)
        drange = str(round(d0, 3)) + " - " + str(round(d1, 3))
        n_refl = str(int(indices_this_res.size()))
        rows.append([drange, str(n_groups_used), n_refl] +
                    [str(int(i)) for i in total_per_dataset])
        if n_datasets >= 15:
            summary_rows.append([drange, str(n_groups_used), n_refl])
        n_cols_used += n_groups_used

    logger.info(
        "Summary of cross-dataset reflection groups chosen (%s groups, %s reflections):",
        n_cols_used,
        indices.size(),
    )
    if n_datasets < 15:
        logger.info(tabulate(rows, header))
    else:
        logger.info(tabulate(summary_rows, summary_header))
        logger.debug(tabulate(rows, header))

    return indices, dataset_ids
Exemple #20
0
def test_numpy_loop_nesting():
    no = np.array([0, 1, 2])
    fo = flumpy.from_numpy(no)
    no_2 = flumpy.to_numpy(fo)
    assert no_2 is no
Exemple #21
0
    def _round_of_outlier_rejection(self):
        """
        Calculate normal deviations from the data in the Ih_table.
        """
        Ih_table = self._Ih_table_block
        intensity = Ih_table.intensities
        g = Ih_table.inverse_scale_factors
        w = self.weights
        wgIsum = Ih_table.sum_in_groups(w * g * intensity, output="per_refl")
        wg2sum = Ih_table.sum_in_groups(w * g * g, output="per_refl")
        wgIsum_others = wgIsum - (w * g * intensity)
        wg2sum_others = wg2sum - (w * g * g)
        # Now do the rejection analysis if n_in_group > 2
        nh = Ih_table.calc_nh()
        sel = nh > 2
        wg2sum_others_sel = wg2sum_others[sel]
        wgIsum_others_sel = wgIsum_others[sel]

        # guard against zero division errors - can happen due to rounding errors
        # or bad data giving g values are very small
        zero_sel = wg2sum_others_sel == 0.0
        # set as one for now, then mark as outlier below. This will only affect if
        # g is near zero, if w is zero then throw an assertionerror.
        wg2sum_others_sel[zero_sel] = 1.0
        g_sel = g[sel]
        I_sel = intensity[sel]
        w_sel = w[sel]

        assert np.all(w_sel > 0)  # guard against division by zero
        norm_dev = (I_sel -
                    (g_sel * wgIsum_others_sel / wg2sum_others_sel)) / (
                        np.sqrt((1.0 / w_sel) +
                                (np.square(g_sel) / wg2sum_others_sel)))
        norm_dev[zero_sel] = 1000  # to trigger rejection
        z_score = np.abs(norm_dev)
        # Want an array same size as Ih table.
        all_z_scores = np.zeros(Ih_table.size)
        # all_z_scores.set_selected(sel.iselection(), z_score)
        all_z_scores[sel] = z_score
        outlier_indices, other_potential_outliers = determine_outlier_indices(
            Ih_table.h_index_matrix, flumpy.from_numpy(all_z_scores),
            self._zmax)
        sel = np.full(Ih_table.size, False, dtype=bool)
        outlier_indices = flumpy.to_numpy(outlier_indices)
        sel[outlier_indices] = True
        lsel = self._Ih_table_block.Ih_table["loc_indices"].iloc[sel].to_numpy(
        )
        dsel = self._Ih_table_block.Ih_table["dataset_id"].iloc[sel].to_numpy()
        self._outlier_indices = np.concatenate([
            self._outlier_indices,
            lsel,
        ])
        self._datasets = np.concatenate([
            self._datasets,
            dsel,
        ])

        sel = np.full(Ih_table.size, False, dtype=bool)
        sel[flumpy.to_numpy(other_potential_outliers)] = True
        self._Ih_table_block = self._Ih_table_block.select(sel)
        self.weights = self.weights[sel]
Exemple #22
0
def test_already_numpy():
    no = np.zeros(10, dtype="B")
    assert flumpy.to_numpy(no) is no
Exemple #23
0
def test_complex():
    fo = flex.complex_double(10)
    as_np = flumpy.to_numpy(fo)
    fo[1] = 3j
    fo[4] = 1.3 + 3j
    assert (as_np == fo).all()
Exemple #24
0
def test_mat3():
    fo = flex.mat3_double(10)
    as_np = flumpy.to_numpy(fo)
    for i in range(10):
        fo[i] = [1, i, 0, 0, 1, 0, i, 0, 1]
    assert (as_np.reshape(10, 9) == fo).all()
Exemple #25
0
 def collect_after_integration(self, experiment, reflection_table):
     super().collect_after_integration(experiment, reflection_table)
     p = flumpy.to_numpy(reflection_table["partiality"])
     bins = np.linspace(0, 1, 11)
     hist = np.histogram(p, bins)
     self.data["partiality"] = hist[0]
Exemple #26
0
    def del_anom_normal_plot(intensities, strong_cutoff=0.0):
        """Make a normal probability plot of the normalised anomalous differences."""
        diff_array = intensities.anomalous_differences()
        if not diff_array.data().size():
            return {}
        delta = diff_array.data() / diff_array.sigmas()

        n = delta.size()
        y = np.sort(flumpy.to_numpy(delta))
        d = 0.5 / n
        v = np.linspace(start=d, stop=1.0 - d, endpoint=True, num=n)
        x = norm.ppf(v)

        H, xedges, yedges = np.histogram2d(x, y, bins=(200, 200))
        nonzeros = np.nonzero(H)
        z = np.empty(H.shape)
        z[:] = np.NAN
        z[nonzeros] = H[nonzeros]

        # also make a histogram
        histy = flex.histogram(flumpy.from_numpy(y), n_slots=100)
        # make a gaussian for reference also
        n = y.size
        width = histy.slot_centers()[1] - histy.slot_centers()[0]
        gaussian = []
        from math import exp, pi

        for x in histy.slot_centers():
            gaussian.append(n * width * exp(-(x**2) / 2.0) / ((2.0 * pi) ** 0.5))

        title = "Normal probability plot of anomalous differences"
        plotname = "normal_distribution_plot"
        if strong_cutoff > 0.0:
            title += f" (d > {strong_cutoff:.2f})"
            plotname += "_lowres"
        else:
            title += " (all data)"
            plotname += "_highres"
        return {
            plotname: {
                "data": [
                    {
                        "x": xedges.tolist(),
                        "y": yedges.tolist(),
                        "z": z.transpose().tolist(),
                        "type": "heatmap",
                        "name": "normalised deviations",
                        "colorbar": {
                            "title": "Number of reflections",
                            "titleside": "right",
                        },
                        "colorscale": "Viridis",
                    },
                    {
                        "x": [-5, 5],
                        "y": [-5, 5],
                        "type": "scatter",
                        "mode": "lines",
                        "name": "z = m",
                        "color": "rgb(0,0,0)",
                    },
                ],
                "layout": {
                    "title": title,
                    "xaxis": {
                        "anchor": "y",
                        "title": "expected delta",
                        "range": [-4, 4],
                    },
                    "yaxis": {
                        "anchor": "x",
                        "title": "observed delta",
                        "range": [-5, 5],
                    },
                },
                "help": """\
    This plot shows the normalised anomalous differences, sorted in order and
    plotted against the expected order based on a normal distribution model.
    A true normal distribution of deviations would give the straight line indicated.

    [1] P. L. Howell and G. D. Smith, J. Appl. Cryst. (1992). 25, 81-86
    https://doi.org/10.1107/S0021889891010385
    [2] P. Evans, Acta Cryst. (2006). D62, 72-82
    https://doi.org/10.1107/S0907444905036693
    """,
            }
        }
Exemple #27
0
def refl_table_to_df(table):
    df = pd.DataFrame()
    for col in table.keys():
        if col != "asu_miller_index" and col != "miller_index":
            df[col] = flumpy.to_numpy(table[col])
    return df