Пример #1
0
def cross_validate_to_determine_number_of_terms(
    x_obs, y_obs, w_obs=None, min_terms=10, max_terms=25, n_free=100, n_goes=5
):
    if n_goes == None:
        if min_terms < 2:
            min_terms = 2

        free_residuals = []

        free_flags = flex.bool(x_obs.size(), True)
        free_permut = flex.random_permutation(x_obs.size())
        for ii in range(n_free):
            free_flags[free_permut[ii]] = False

        for count in range(min_terms, max_terms):
            fit = chebyshev_lsq_fit(count, x_obs, y_obs, w_obs, free_flags)
            free_residuals.append(fit.free_f)
        return flex.double(free_residuals)

    else:
        if w_obs is None:
            w_obs = flex.double(x_obs.size(), 1)
        free_resid = flex.double(max_terms - min_terms, 0)
        for jj in range(n_goes):
            free_resid += cross_validate_to_determine_number_of_terms(
                x_obs, y_obs, w_obs, min_terms=min_terms, max_terms=max_terms, n_free=n_free, n_goes=None
            )
        return min_terms + flex.min_index(free_resid)
Пример #2
0
  def split_into_groups(self, sample, ngroups):
    """Split each vector in the data sample into groups of approximately equal
    size."""

    # number of obs in the sample
    sample_size = len(sample[0])

    # random permutation
    p = flex.random_permutation(sample_size)
    permuted = [col.select(p) for col in sample]

    # determine groups
    blocksize = int(sample_size / ngroups)
    rem = sample_size % ngroups
    blocksizes = [blocksize] * (ngroups - rem) + [blocksize + 1] * rem

    starts = [0]
    ends = [blocksizes[0]]
    for b in blocksizes[1:]:
      starts.append(ends[-1])
      ends.append(ends[-1] + b)
    blocks = zip(starts, ends)

    # split into groups
    groups = []
    for s,e in blocks:
      groups.append([col[s:e] for col in permuted])

    return groups
Пример #3
0
def exercise_densely_distributed_singular_values(show_progress, full_coverage,
                                                 klass):
    n = 40
    m = 2 * n
    n_runs = 20
    tol = 10 * scitbx.math.double_numeric_limits.epsilon
    gen = scitbx.linalg.random_normal_matrix_generator(m, n)
    sigmas = []
    sigmas.append(flex.double([10**(-i / n) for i in range(n)]))
    sigmas.append(sigmas[0].select(flex.random_permutation(n)))
    sigmas.append(sigmas[0].reversed())
    print("Densely distributed singular values:", end=' ')
    n_tests = 0
    for i in range(n_runs):
        if not full_coverage and random.random() < 0.8: continue
        n_tests += 1
        for i_case, sigma in enumerate(sigmas):
            a = gen.matrix_with_singular_values(sigma)
            svd = klass(a, accumulate_u=False, accumulate_v=False)
            if i_case > 0:
                sigma = sigma.select(flex.sort_permutation(sigma,
                                                           reverse=True))
            delta = (svd.sigma - sigma) / sigma / tol
            assert delta.all_lt(5)
    print("%i done." % n_tests)
Пример #4
0
    def split_into_groups(self, sample, ngroups):
        """Split each vector in the data sample into groups of approximately equal
        size."""

        # number of obs in the sample
        sample_size = len(sample[0])

        # random permutation
        p = flex.random_permutation(sample_size)
        permuted = [col.select(p) for col in sample]

        # determine groups
        blocksize = int(sample_size / ngroups)
        rem = sample_size % ngroups
        blocksizes = [blocksize] * (ngroups - rem) + [blocksize + 1] * rem

        starts = [0]
        ends = [blocksizes[0]]
        for b in blocksizes[1:]:
            starts.append(ends[-1])
            ends.append(ends[-1] + b)
        blocks = zip(starts, ends)

        # split into groups
        groups = [[col[start:end] for col in permuted] for start, end in blocks]

        return groups
Пример #5
0
  def estimate_cc_sig_fac(self):

    # A1.1. Estimation of sigma(CC) as a function of sample size.

    binner = self.intensities.setup_binner_counting_sorted(reflections_per_bin=200)

    a = flex.double()
    b = flex.double()
    for i in range(binner.n_bins_all()):
      count = binner.counts()[i]
      if count == 0:
        continue
      bin_isel = binner.array_indices(i)
      p = flex.random_permutation(count)
      p = p[:2 * (count // 2)] # ensure even count
      a.extend(self.intensities.data().select(bin_isel.select(p[:count//2])))
      b.extend(self.intensities.data().select(bin_isel.select(p[count//2:])))

    perm = flex.random_selection(a.size(), min(20000, a.size()))
    a = a.select(perm)
    b = b.select(perm)

    self.corr_unrelated = CorrelationCoefficientAccumulator(a, b)

    n_pairs = a.size()
    min_num_groups = 10 # minimum number of groups
    max_n_group = int(min(n_pairs/min_num_groups, 200)) # maximum number in group
    min_n_group = int(min(5, max_n_group)) # minimum number in group

    mean_ccs = flex.double()
    rms_ccs = flex.double()
    ns = flex.double()
    for n in range(min_n_group, max_n_group):
      ns.append(n)
      ccs = flex.double()
      for i in range(200):
        isel = flex.random_selection(a.size(), n)
        corr = CorrelationCoefficientAccumulator(a.select(isel), b.select(isel))
        ccs.append(corr.coefficient())

      mean_ccs.append(flex.mean(ccs))
      rms_ccs.append(flex.mean(flex.pow2(ccs))**0.5)

    x = 1/flex.pow(ns, 0.5)
    y = rms_ccs
    fit = flex.linear_regression(x, y)

    assert fit.is_well_defined()
    self.cc_sig_fac = fit.slope()

    if 0:
      from matplotlib import pyplot as plt
      plt.plot(x, y)
      plt.plot(
        plt.xlim(), [fit.slope() * x_ + fit.y_intercept() for x_ in plt.xlim()])
      plt.show()
Пример #6
0
def test_median_and_iqr():

    # Even number of values, one bin
    vals1 = flex.double((1, 2, 3, 4))
    bins = flex.size_t([0] * len(vals1))
    binned_statistics = BinnedStatistics(vals1, bins, 1)
    assert binned_statistics.get_medians().all_eq(flex.double((2.5,)))
    assert binned_statistics.get_iqrs().all_eq(flex.double((1.5,)))
    # NB this differs from the calculation performed via
    # _,q1,_,q3,_=five_number_summary(vals1);q3-q1
    # which gives 2.0. However, it matches the result of R's IQR function

    # Odd number of values, one bin, and robustness test
    vals2 = flex.double((1, 2, 3, 100, 1000))
    bins = flex.size_t([0] * len(vals2))
    binned_statistics = BinnedStatistics(vals2, bins, 1)
    assert binned_statistics.get_medians().all_eq(flex.double((3.0,)))
    assert binned_statistics.get_iqrs().all_eq(flex.double((98,)))
    # NB this is the same as the calculation performed via
    # _,q1,_,q3,_=five_number_summary(vals2);q3-q1, and matches R's IQR function

    # Now combine the data and randomise order
    vals3 = vals1.concatenate(vals2)
    bins = flex.size_t([0] * len(vals1) + [1] * len(vals2))
    perm = flex.random_permutation(len(bins))
    vals3 = vals3.select(perm)
    bins = bins.select(perm)
    binned_statistics = BinnedStatistics(vals3, bins, 2)
    assert binned_statistics.get_medians().all_eq(
        flex.double(
            (
                2.5,
                3.0,
            )
        )
    )
    assert binned_statistics.get_iqrs().all_eq(
        flex.double(
            (
                1.5,
                98,
            )
        )
    )
Пример #7
0
  def form_initial_subset(self, h, data):
    """Method 2 of subsection 3.1 of R&vD"""

    # permutation of input data for sampling
    p = flex.random_permutation(len(data[0]))
    permuted = [col.select(p) for col in data]

    # draw random p+1 subset J (or larger if required)
    detS0 = 0.0
    i = 0
    while not detS0 > 0.0:
      subset_size = self._p + 1 + i
      J = [e[0:subset_size] for e in permuted]
      i += 1
      T0, S0 = self.means_and_covariance(J)
      detS0 = S0.matrix_determinant_via_lu()

    H1 = self.concentration_step(h, data, T0, S0)
    return H1
Пример #8
0
def block(data_size, n_repeats):
    data = flex.random_double(size=data_size)
    permutation = flex.random_permutation(data.size())
    for use_pointers, use_iterators_range in [(False, 2), (True, 3)]:
        print "  use_pointers =", use_pointers
        for use_iterators in range(use_iterators_range):
            t0 = time.time()
            result = flex.integer_offsets_vs_pointers(data, permutation, 0,
                                                      use_pointers,
                                                      use_iterators)
            t_overhead = time.time() - t0
            t0 = time.time()
            result = flex.integer_offsets_vs_pointers(data, permutation,
                                                      n_repeats, use_pointers,
                                                      use_iterators)
            print "    use_iterators =", use_iterators, \
                  "time = %.2f s" % (time.time() - t0 - t_overhead), \
                  "overhead = %.2f s" % t_overhead, \
                  "(%-7s %.6g)" % result
Пример #9
0
    def form_initial_subset(self, h, data):
        """Method 2 of subsection 3.1 of R&vD"""

        # permutation of input data for sampling
        p = flex.random_permutation(len(data[0]))
        permuted = [col.select(p) for col in data]

        # draw random p+1 subset J (or larger if required)
        detS0 = 0.0
        i = 0
        while not detS0 > 0.0:
            subset_size = self._p + 1 + i
            J = [e[0:subset_size] for e in permuted]
            i += 1
            T0, S0 = self.means_and_covariance(J)
            detS0 = S0.matrix_determinant_via_lu()

        H1 = self.concentration_step(h, data, T0, S0)
        return H1
def block(data_size, n_repeats):
  data = flex.random_double(size=data_size)
  permutation = flex.random_permutation(data.size())
  for use_pointers, use_iterators_range in [(False, 2), (True, 3)]:
    print "  use_pointers =", use_pointers
    for use_iterators in range(use_iterators_range):
      t0 = time.time()
      result = flex.integer_offsets_vs_pointers(
        data, permutation, 0, use_pointers, use_iterators)
      t_overhead = time.time() - t0
      t0 = time.time()
      result = flex.integer_offsets_vs_pointers(
        data,
        permutation,
        n_repeats,
        use_pointers,
        use_iterators)
      print "    use_iterators =", use_iterators, \
            "time = %.2f s" % (time.time() - t0 - t_overhead), \
            "overhead = %.2f s" % t_overhead, \
            "(%-7s %.6g)" % result
Пример #11
0
def exercise_densely_distributed_singular_values(show_progress, full_coverage):
  n = 40
  m = 2*n
  n_runs = 20
  tol = 10*scitbx.math.double_numeric_limits.epsilon
  gen = scitbx.linalg.random_normal_matrix_generator(m, n)
  sigmas = []
  sigmas.append( flex.double([ 10**(-i/n) for i in xrange(n) ]) )
  sigmas.append( sigmas[0].select(flex.random_permutation(n))   )
  sigmas.append( sigmas[0].reversed()                           )
  print "Densely distributed singular values:",
  n_tests = 0
  for i in xrange(n_runs):
    if not full_coverage and random.random() < 0.8: continue
    n_tests += 1
    for i_case, sigma in enumerate(sigmas):
      a = gen.matrix_with_singular_values(sigma)
      svd = scitbx.linalg.svd.real(a, accumulate_u=False, accumulate_v=False)
      if i_case > 0: sigma = sigma.select(
        flex.sort_permutation(sigma, reverse=True))
      delta = (svd.sigma - sigma)/sigma/tol
      assert delta.all_lt(5)
  print "%i done." % n_tests
Пример #12
0
def cross_validate_to_determine_number_of_terms(x_obs,
                                                y_obs,
                                                w_obs=None,
                                                min_terms=10,
                                                max_terms=25,
                                                n_free=100,
                                                n_goes=5):
    if (n_goes == None):
        if (min_terms < 2):
            min_terms = 2

        free_residuals = []

        free_flags = flex.bool(x_obs.size(), True)
        free_permut = flex.random_permutation(x_obs.size())
        for ii in range(n_free):
            free_flags[free_permut[ii]] = False

        for count in range(min_terms, max_terms):
            fit = chebyshev_lsq_fit(count, x_obs, y_obs, w_obs, free_flags)
            free_residuals.append(fit.free_f)
        return (flex.double(free_residuals))

    else:
        if w_obs is None:
            w_obs = flex.double(x_obs.size(), 1)
        free_resid = flex.double(max_terms - min_terms, 0)
        for jj in range(n_goes):
            free_resid += cross_validate_to_determine_number_of_terms(
                x_obs,
                y_obs,
                w_obs,
                min_terms=min_terms,
                max_terms=max_terms,
                n_free=n_free,
                n_goes=None)
        return (min_terms + flex.min_index(free_resid))
Пример #13
0
    def _estimate_cc_sig_fac(self):
        """Estimation of sigma(CC) as a function of sample size.

        Estimate the error in the correlation coefficient, sigma(CC) by using
        pairs of reflections at similar resolutions that are not related by
        potential symmetry. Using pairs of unrelated reflections at similar
        resolutions, calculate sigma(CC) == rms(CC) for groups of size N = 3..200.
        The constant CCsigFac is obtained from a linear fit of
        sigma(CC) to 1/N^(1/2), i.e.:
            sigma(CC) = CCsigFac/N^(1/2)
        """

        max_bins = 500
        reflections_per_bin = max(
            200, int(math.ceil(self.intensities.size() / max_bins)))
        binner = self.intensities.setup_binner_counting_sorted(
            reflections_per_bin=reflections_per_bin)

        a = flex.double()
        b = flex.double()
        ma_tmp = self.intensities.customized_copy(
            crystal_symmetry=crystal.symmetry(
                space_group=self.lattice_group,
                unit_cell=self.intensities.unit_cell(),
                assert_is_compatible_unit_cell=False,
            )).map_to_asu()
        for i in range(binner.n_bins_all()):
            count = binner.counts()[i]
            if count == 0:
                continue
            bin_isel = binner.array_indices(i)
            p = flex.random_permutation(count)
            p = p[:2 * (count // 2)]  # ensure even count
            ma_a = ma_tmp.select(bin_isel.select(p[:count // 2]))
            ma_b = ma_tmp.select(bin_isel.select(p[count // 2:]))
            # only choose pairs of reflections that don't have the same indices
            # in the asu of the lattice group
            sel = ma_a.indices() != ma_b.indices()
            a.extend(ma_a.data().select(sel))
            b.extend(ma_b.data().select(sel))

        perm = flex.random_selection(a.size(), min(20000, a.size()))
        a = a.select(perm)
        b = b.select(perm)

        self.corr_unrelated = CorrelationCoefficientAccumulator(a, b)

        n_pairs = a.size()
        min_num_groups = 10  # minimum number of groups
        max_n_group = int(min(n_pairs / min_num_groups,
                              200))  # maximum number in group
        min_n_group = int(min(5, max_n_group))  # minimum number in group

        if (max_n_group - min_n_group) < 4:
            self.cc_sig_fac = 0
            return

        mean_ccs = flex.double()
        rms_ccs = flex.double()
        ns = flex.double()
        for n in range(min_n_group, max_n_group + 1):
            ns.append(n)
            ccs = flex.double()
            for i in range(200):
                isel = flex.random_selection(a.size(), n)
                corr = CorrelationCoefficientAccumulator(
                    a.select(isel), b.select(isel))
                ccs.append(corr.coefficient())

            mean_ccs.append(flex.mean(ccs))
            rms_ccs.append(flex.mean(flex.pow2(ccs))**0.5)

        x = 1 / flex.pow(ns, 0.5)
        y = rms_ccs
        fit = flex.linear_regression(x, y)

        if fit.is_well_defined():
            self.cc_sig_fac = fit.slope()
        else:
            self.cc_sig_fac = 0
Пример #14
0
 def update_minimum_covering_sphere(self):
     n_points = min(1000, self.points.size())
     isel = flex.random_permutation(self.points.size())[:n_points]
     self.minimum_covering_sphere = minimum_covering_sphere(
         self.points.select(isel))
Пример #15
0
def discover_better_experimental_model(
    experiments,
    reflections,
    params,
    nproc=1,
    d_min=None,
    mm_search_scope=4.0,
    wide_search_binning=1,
    plot_search_scope=False,
):
    assert len(experiments) == len(reflections)
    assert len(experiments) > 0

    refl_lists = []
    max_cell_list = []

    # The detector/beam of the first experiment is used to define the basis for the
    # optimisation, so assert that the beam intersects with the detector
    detector = experiments[0].detector
    beam = experiments[0].beam
    beam_panel = detector.get_panel_intersection(beam.get_s0())
    if beam_panel == -1:
        raise Sorry("input beam does not intersect detector")

    for expt, refl in zip(experiments, reflections):
        refl = copy.deepcopy(refl)
        refl["imageset_id"] = flex.int(len(refl), 0)
        refl.centroid_px_to_mm([expt])
        refl.map_centroids_to_reciprocal_space([expt])

        if d_min is not None:
            d_spacings = 1 / refl["rlp"].norms()
            sel = d_spacings > d_min
            refl = refl.select(sel)

        # derive a max_cell from mm spots
        if params.max_cell is None:
            max_cell = find_max_cell(refl,
                                     max_cell_multiplier=1.3,
                                     step_size=45).max_cell
            max_cell_list.append(max_cell)

        if params.max_reflections is not None and refl.size(
        ) > params.max_reflections:
            logger.info("Selecting subset of %i reflections for analysis" %
                        params.max_reflections)
            perm = flex.random_permutation(refl.size())
            sel = perm[:params.max_reflections]
            refl = refl.select(sel)

        refl_lists.append(refl)

    if params.max_cell is None:
        max_cell = flex.median(flex.double(max_cell_list))
    else:
        max_cell = params.max_cell

    with concurrent.futures.ProcessPoolExecutor(max_workers=nproc) as pool:
        solution_lists = []
        amax_list = []
        for result in pool.map(run_dps, experiments, refl_lists,
                               itertools.repeat(max_cell)):
            if result.get("solutions"):
                solution_lists.append(result["solutions"])
                amax_list.append(result["amax"])

    if not solution_lists:
        raise Sorry("No solutions found")

    new_experiments = optimize_origin_offset_local_scope(
        experiments,
        refl_lists,
        solution_lists,
        amax_list,
        mm_search_scope=mm_search_scope,
        wide_search_binning=wide_search_binning,
        plot_search_scope=plot_search_scope,
    )
    new_detector = new_experiments[0].detector
    old_panel, old_beam_centre = detector.get_ray_intersection(beam.get_s0())
    new_panel, new_beam_centre = new_detector.get_ray_intersection(
        beam.get_s0())

    old_beam_centre_px = detector[old_panel].millimeter_to_pixel(
        old_beam_centre)
    new_beam_centre_px = new_detector[new_panel].millimeter_to_pixel(
        new_beam_centre)

    logger.info("Old beam centre: %.2f, %.2f mm" % old_beam_centre +
                " (%.1f, %.1f px)" % old_beam_centre_px)
    logger.info("New beam centre: %.2f, %.2f mm" % new_beam_centre +
                " (%.1f, %.1f px)" % new_beam_centre_px)
    logger.info(
        "Shift: %.2f, %.2f mm" %
        (matrix.col(old_beam_centre) - matrix.col(new_beam_centre)).elems +
        " (%.1f, %.1f px)" %
        (matrix.col(old_beam_centre_px) - matrix.col(new_beam_centre_px)).elems
    )
    return new_experiments
Пример #16
0
def random_permutation(s):
  from scitbx.array_family import flex
  return flex.select(s, flex.random_permutation(size=len(s)))
Пример #17
0
def get_optimisation_test_set(
    n_grp,
    n_dst,
    n_atm,
    atomic_amplitude=1.0,
    random_dataset_order=False,
):
    """Generate a test set of random uijs for optimisation"""

    assert n_grp > 0
    assert n_grp <= len(TLS_MATRICES)
    assert n_dst > 0
    assert n_atm > 3

    target_uijs = numpy.zeros((n_dst, n_atm, 6))

    # Default to equal weights
    target_weights = flex.double(flex.grid((n_dst, n_atm)), 1.0)

    # Create atomic base
    atomic_values_numpy = rran(n_atm * 6).reshape((n_atm, 6))
    real_atomic_amps = atomic_amplitude * rran(n_atm)
    atomic_base = flex.sym_mat3_double(atomic_values_numpy)

    # Create atomic total and add to target
    atomic_uijs = real_atomic_amps.reshape((n_atm, 1)) * atomic_values_numpy
    for i_dst in range(n_dst):
        target_uijs[i_dst] = atomic_uijs

    # Generate a random set of amplitudes
    real_group_amps = rran(n_grp * n_dst).reshape((n_grp, n_dst))

    # Output lists of base uijs and atoms they are associated with
    base_uijs = []
    base_sels = []

    # Mapping of elements to datasets
    if random_dataset_order is True:
        dataset_hash = flex.size_t(
            numpy.concatenate(
                [flex.random_permutation(n_dst) for _ in range(n_grp)]))
    else:
        dataset_hash = flex.size_t(list(range(n_dst)) * n_grp)

    # base counter
    i_cnt = 0
    for i_grp in range(n_grp):
        # Number of atoms in this group -- at least 2
        if n_grp == 1:
            n_atm_this = n_atm
        else:
            n_atm_this = max(2, iran(n_atm))
        # Which atoms are covered by this group
        i_sel = iran(n_atm, size=n_atm_this, replace=False)
        # Generate some uijs for this
        tls_m = TLSMatrices(TLS_MATRICES[i_grp])
        for _ in range(n_dst):
            # Which dataset?
            i_dst = dataset_hash[i_cnt]
            i_cnt += 1
            # Generate random coordinates
            x_ = 50.0 * (-0.5 + rran(n_atm_this * 3).reshape((n_atm_this, 3)))
            x_ = flex.vec3_double(x_)
            # Generate the base elements
            u_ = tls_m.uijs(x_, origin=(0., 0., 0.))
            base_uijs.append(flex.sym_mat3_double(u_))
            base_sels.append(flex.size_t(i_sel))
            # Generate the amplitude-multiplied equivalent
            u_m = (real_group_amps[i_grp, i_dst] * tls_m).uijs(x_,
                                                               origin=(0., 0.,
                                                                       0.))
            target_uijs[i_dst, i_sel, :] += numpy.array(u_m)
    # Reshape
    target_uijs = flex.sym_mat3_double(target_uijs.reshape((n_dst * n_atm, 6)))
    target_uijs.reshape(flex.grid((n_dst, n_atm)))

    return (
      target_uijs, target_weights, \
      base_uijs, base_sels, dataset_hash, \
      atomic_base, \
      real_group_amps.flatten(), real_atomic_amps,
    )
Пример #18
0
def scale_map_coeffs(n_real=None,
                     randomized_map_coeffs=None,
                     map_coeffs=None,
                     high_resolution_noise_fraction=None,
                     low_resolution_noise_fraction=None,
                     random_selection_within_bins=False,
                     low_resolution_noise_cutoff=None,
                     log=sys.stdout):
    '''
    Scale map coefficients to target value vs resolution, optionally randomize

    Scales map coefficients in resolution bins, scale factor adjusted
    to yield high_resolution_noise_fraction at high-resolution limit
    and low_resolution_noise_fraction at low_resolution_noise_cutoff and
    linearly between in 1/resolution.

    Optionally randomizes amplitudes and phases by shuffling within bins

  '''

    assert random_selection_within_bins or randomized_map_coeffs

    if not hasattr(map_coeffs, 'binner') or not map_coeffs.binner():
        map_coeffs.setup_binner(auto_binning=True)

    d_max, d_min = map_coeffs.d_max_min()
    if d_max < 0: d_max = 1.e+10

    if random_selection_within_bins:
        new_map_coeffs = map_coeffs.customized_copy(
            data=flex.complex_double(map_coeffs.size(), (0 + 0.j)))
        print("\nGenerating map randomized in Fourier space", file=log)
    else:
        new_map_coeffs = randomized_map_coeffs
    print("Relative error added at high-resolution: %.3f" %
          (high_resolution_noise_fraction),
          file=log)
    print("Relative error added at low-resolution: %.3f" %
          (low_resolution_noise_fraction),
          file=log)

    print("Resolution  Noise ratio   RMS original            RMS error ",
          file=log)

    for i_bin in map_coeffs.binner().range_used():
        sel = map_coeffs.binner().selection(i_bin)
        dd = map_coeffs.d_spacings().data().select(sel)
        local_d_mean = dd.min_max_mean().mean
        local_s_mean = 1 / local_d_mean
        s_max = 1 / max(1.e-10, d_min)
        if low_resolution_noise_cutoff:
            s_min = 1 / max(1.e-10, min(d_max, low_resolution_noise_cutoff))
        else:
            s_min = 1 / max(1.e-10, d_max)
        fraction_high = max(
            0., min(1., (local_s_mean - s_min) / max(1.e-10, s_max - s_min)))

        noise_ratio=low_resolution_noise_fraction+\
          fraction_high * (
           high_resolution_noise_fraction-
            low_resolution_noise_fraction)

        mc = map_coeffs.select(sel)
        rms_original = norm(mc.data())
        if random_selection_within_bins:  # randomize, normalize, scale
            fp, phi = map_coeffs_as_fp_phi(mc)
            sel_fp = flex.random_permutation(fp.size())
            new_fp = fp.select(sel_fp)
            data = new_fp.data()
            data *= noise_ratio
            sel_phi = flex.random_permutation(phi.size())
            new_phi = phi.select(sel_phi)
            new_mc = fp_phi_as_map_coeffs(new_fp, new_phi)
        else:  # just normalize and scale
            randomized_mc = randomized_map_coeffs.select(sel)
            rms_new = norm(randomized_mc.data())
            scale = rms_original / max(1.e-10, rms_new)
            new_fp, new_phi = map_coeffs_as_fp_phi(randomized_mc)
            data = new_fp.data()
            data *= noise_ratio * scale
            new_mc = fp_phi_as_map_coeffs(new_fp, new_phi)

        rms_new = norm(new_mc.data())
        new_map_coeffs.data().set_selected(sel, new_mc.data())
        print("  %.3f         %.3f         %.3f               %.3f " %
              (local_d_mean, noise_ratio, rms_original, rms_new),
              file=log)

    # Convert to map
    from cctbx import maptbx
    return maptbx.map_coefficients_to_map(
        map_coeffs=new_map_coeffs,
        crystal_symmetry=new_map_coeffs.crystal_symmetry(),
        n_real=n_real)
Пример #19
0
 def update_minimum_covering_sphere(self):
   n_points = min(1000, self.points.size())
   isel = flex.random_permutation(self.points.size())[:n_points]
   self.minimum_covering_sphere = minimum_covering_sphere(
     self.points.select(isel))
def discover_better_experimental_model(imagesets,
                                       spot_lists,
                                       params,
                                       dps_params,
                                       nproc=1,
                                       wide_search_binning=1):
    assert len(imagesets) == len(spot_lists)
    assert len(imagesets) > 0
    # XXX should check that all the detector and beam objects are the same

    spot_lists_mm = []
    max_cell_list = []

    detector = imagesets[0].get_detector()
    beam = imagesets[0].get_beam()

    beam_panel = detector.get_panel_intersection(beam.get_s0())

    if beam_panel == -1:

        raise Sorry("input beam does not intersect detector")

    for imageset, spots in zip(imagesets, spot_lists):
        if "imageset_id" not in spots:
            spots["imageset_id"] = spots["id"]

        spots_mm = copy.deepcopy(spots)
        spots_mm.centroid_px_to_mm(imageset.get_detector(),
                                   scan=imageset.get_scan())

        spots_mm.map_centroids_to_reciprocal_space(
            detector=imageset.get_detector(),
            beam=imageset.get_beam(),
            goniometer=imageset.get_goniometer(),
        )

        if dps_params.d_min is not None:
            d_spacings = 1 / spots_mm["rlp"].norms()
            sel = d_spacings > dps_params.d_min
            spots_mm = spots_mm.select(sel)

        # derive a max_cell from mm spots

        if params.max_cell is None:
            max_cell = find_max_cell(spots_mm,
                                     max_cell_multiplier=1.3,
                                     step_size=45).max_cell
            max_cell_list.append(max_cell)

        if (params.max_reflections is not None
                and spots_mm.size() > params.max_reflections):
            logger.info("Selecting subset of %i reflections for analysis" %
                        params.max_reflections)
            perm = flex.random_permutation(spots_mm.size())
            sel = perm[:params.max_reflections]
            spots_mm = spots_mm.select(sel)

        spot_lists_mm.append(spots_mm)

    if params.max_cell is None:
        max_cell = flex.median(flex.double(max_cell_list))
    else:
        max_cell = params.max_cell
    args = [(imageset, spots, max_cell, dps_params)
            for imageset, spots in zip(imagesets, spot_lists_mm)]

    results = easy_mp.parallel_map(
        func=run_dps,
        iterable=args,
        processes=nproc,
        method="multiprocessing",
        preserve_order=True,
        asynchronous=True,
        preserve_exception_message=True,
    )
    solution_lists = [r["solutions"] for r in results]
    amax_list = [r["amax"] for r in results]
    assert len(solution_lists) > 0

    detector = imagesets[0].get_detector()
    beam = imagesets[0].get_beam()

    # perform calculation
    if dps_params.indexing.improve_local_scope == "origin_offset":
        discoverer = better_experimental_model_discovery(
            imagesets,
            spot_lists_mm,
            solution_lists,
            amax_list,
            dps_params,
            wide_search_binning=wide_search_binning,
        )
        new_detector = discoverer.optimize_origin_offset_local_scope()
        old_panel, old_beam_centre = detector.get_ray_intersection(
            beam.get_s0())
        new_panel, new_beam_centre = new_detector.get_ray_intersection(
            beam.get_s0())

        old_beam_centre_px = detector[old_panel].millimeter_to_pixel(
            old_beam_centre)
        new_beam_centre_px = new_detector[new_panel].millimeter_to_pixel(
            new_beam_centre)

        logger.info("Old beam centre: %.2f, %.2f mm" % old_beam_centre +
                    " (%.1f, %.1f px)" % old_beam_centre_px)
        logger.info("New beam centre: %.2f, %.2f mm" % new_beam_centre +
                    " (%.1f, %.1f px)" % new_beam_centre_px)
        logger.info(
            "Shift: %.2f, %.2f mm" %
            (matrix.col(old_beam_centre) - matrix.col(new_beam_centre)).elems +
            " (%.1f, %.1f px)" % (matrix.col(old_beam_centre_px) -
                                  matrix.col(new_beam_centre_px)).elems)
        return new_detector, beam
    elif dps_params.indexing.improve_local_scope == "S0_vector":
        raise NotImplementedError()