Exemple #1
0
 def __init__(O, f_obs, i_obs, i_sig, i_calc=None, f_calc=None, wa=0.1, wb=0):
   assert [i_calc, f_calc].count(None) == 1
   if (i_calc is None):
     from cctbx.array_family import flex
     i_calc = flex.norm(f_calc)
   from cctbx import xray
   raw = xray.targets_shelxl_wght_ls_kwt_b_dv(
     f_obs=f_obs,
     i_obs=i_obs,
     i_sig=i_sig,
     ic=i_calc,
     wa=wa,
     wb=wb)
   assert len(raw) == 5
   O.scale_factor, \
   O.weights, \
   O.target, \
   O.i_gradients, \
   O.i_curvatures = raw
   if (f_calc is None):
     O.f_gradients = None
     O.f_hessians = None
   else:
     g = O.i_gradients
     c = O.i_curvatures
     O.f_gradients = 2 * g * f_calc
     a = flex.real(f_calc)
     b = flex.imag(f_calc)
     aa = 2 * g + 4 * a * a * c
     bb = 2 * g + 4 * b * b * c
     ab =         4 * a * b * c
     O.f_hessians = flex.vec3_double(aa, bb, ab)
Exemple #2
0
 def __call__(self,
              xray_structure,
              u_iso_refinable_params,
              dp,
              n_parameters,
              verbose=0):
     omptbx.env.num_threads = libtbx.introspection.number_of_processors()
     result = xray.fast_gradients(
         unit_cell=xray_structure.unit_cell(),
         scatterers=xray_structure.scatterers(),
         scattering_type_registry=xray_structure.scattering_type_registry(),
         u_base=self.u_base(),
         wing_cutoff=self.wing_cutoff(),
         exp_table_one_over_step_size=self.exp_table_one_over_step_size(),
         tolerance_positive_definite=1.e-5)
     if (0 or verbose):
         print("u_base:", result.u_base())
         print("u_extra:", result.u_extra())
     gradient_map = self.ft_dp(dp, u_extra=result.u_extra())
     if (not gradient_map.anomalous_flag()):
         gradient_map = gradient_map.real_map()
     else:
         gradient_map = gradient_map.complex_map()
         assert not gradient_map.is_padded()
         if (0 or verbose):
             print("grid:", gradient_map.focus())
             print("ft_dt_map real: %.4g %.4g" %
                   (flex.min(flex.real(gradient_map)),
                    flex.max(flex.real(gradient_map))))
             print("ft_dt_map imag: %.4g %.4g" %
                   (flex.min(flex.imag(gradient_map)),
                    flex.max(flex.imag(gradient_map))))
             print()
     result.sampling(
         scatterers=xray_structure.scatterers(),
         u_iso_refinable_params=u_iso_refinable_params,
         scattering_type_registry=xray_structure.scattering_type_registry(),
         site_symmetry_table=xray_structure.site_symmetry_table(),
         ft_d_target_d_f_calc=gradient_map,
         n_parameters=n_parameters,
         sampled_density_must_be_positive=False)
     if (0 or verbose):
         print("max_sampling_box_edges:", result.max_sampling_box_edges())
         print("exp_table_size:", result.exp_table_size())
         print()
     return result
 def __call__(self, xray_structure,
                    u_iso_refinable_params,
                    dp,
                    n_parameters,
                    verbose=0):
   omptbx.env.num_threads = libtbx.introspection.number_of_processors()
   result = xray.fast_gradients(
     unit_cell=xray_structure.unit_cell(),
     scatterers=xray_structure.scatterers(),
     scattering_type_registry=xray_structure.scattering_type_registry(),
     u_base=self.u_base(),
     wing_cutoff=self.wing_cutoff(),
     exp_table_one_over_step_size=self.exp_table_one_over_step_size(),
     tolerance_positive_definite=1.e-5)
   if (0 or verbose):
     print "u_base:", result.u_base()
     print "u_extra:", result.u_extra()
   gradient_map = self.ft_dp(dp, u_extra=result.u_extra())
   if (not gradient_map.anomalous_flag()):
     gradient_map = gradient_map.real_map()
   else:
     gradient_map = gradient_map.complex_map()
     assert not gradient_map.is_padded()
     if (0 or verbose):
       print "grid:", gradient_map.focus()
       print "ft_dt_map real: %.4g %.4g" % (
         flex.min(flex.real(gradient_map)),
         flex.max(flex.real(gradient_map)))
       print "ft_dt_map imag: %.4g %.4g" % (
         flex.min(flex.imag(gradient_map)),
         flex.max(flex.imag(gradient_map)))
       print
   result.sampling(
     scatterers=xray_structure.scatterers(),
     u_iso_refinable_params=u_iso_refinable_params,
     scattering_type_registry=xray_structure.scattering_type_registry(),
     site_symmetry_table=xray_structure.site_symmetry_table(),
     ft_d_target_d_f_calc=gradient_map,
     n_parameters=n_parameters,
     sampled_density_must_be_positive=False)
   if (0 or verbose):
     print "max_sampling_box_edges:", result.max_sampling_box_edges()
     print "exp_table_size:", result.exp_table_size()
     print
   return result
Exemple #4
0
    def do_exercise(self, verbose=False):
        xs = self.xs
        sg = xs.space_group_info().group()
        origin_centric_case = sg.is_origin_centric()

        indices = self.miller_indices(xs.space_group_info())
        f = structure_factors.f_calc_modulus_squared(xs)
        f1 = structure_factors.f_calc_modulus_squared(xs)

        for h in indices:
            f.linearise(h)
            fl = f.f_calc
            f1.evaluate(h)
            fe = f1.f_calc
            assert f1.grad_f_calc is None
            assert approx_equal_relatively(fe, fl,
                                           relative_error=1e-12), (fe, fl)

        if (xs.space_group().is_origin_centric()
                and not self.inelastic_scattering):
            for h in indices:
                f.linearise(h)
                assert f.f_calc.imag == 0
                assert flex.imag(f.grad_f_calc).all_eq(0)

        eta = 1e-8
        xs_forward = xs.deep_copy_scatterers()
        f_forward = structure_factors.f_calc_modulus_squared(xs_forward)

        deltas = flex.double()
        for direction in islice(self.structures_forward(xs, xs_forward, eta),
                                self.n_directions):
            for h in indices:
                f.linearise(h)
                assert approx_equal(abs(f.f_calc)**2, f.observable)
                f_forward.linearise(h)
                diff_num = (f_forward.observable - f.observable) / eta
                diff = f.grad_observable.dot(direction)
                delta = abs(1 - diff / diff_num)
                deltas.append(delta)
        stats = median_statistics(deltas)
        tol = 1e-5
        assert stats.median < tol, (xs.space_group_info().symbol_and_number(),
                                    stats.median)
        assert stats.median_absolute_deviation < tol, (
            xs.space_group_info().symbol_and_number(),
            stats.median_absolute_deviation)
    def do_exercise(self, verbose=False):
        xs = self.xs
        sg = xs.space_group_info().group()
        origin_centric_case = sg.is_origin_centric()

        indices = self.miller_indices(xs.space_group_info())
        f = structure_factors.f_calc_modulus_squared(xs)
        f1 = structure_factors.f_calc_modulus_squared(xs)

        for h in indices:
            f.linearise(h)
            fl = f.f_calc
            f1.evaluate(h)
            fe = f1.f_calc
            assert f1.grad_f_calc is None
            assert approx_equal_relatively(fe, fl, relative_error=1e-12), (fe, fl)

        if xs.space_group().is_origin_centric() and not self.inelastic_scattering:
            for h in indices:
                f.linearise(h)
                assert f.f_calc.imag == 0
                assert flex.imag(f.grad_f_calc).all_eq(0)

        eta = 1e-8
        xs_forward = xs.deep_copy_scatterers()
        f_forward = structure_factors.f_calc_modulus_squared(xs_forward)

        deltas = flex.double()
        for direction in islice(self.structures_forward(xs, xs_forward, eta), self.n_directions):
            for h in indices:
                f.linearise(h)
                assert approx_equal(abs(f.f_calc) ** 2, f.observable)
                f_forward.linearise(h)
                diff_num = (f_forward.observable - f.observable) / eta
                diff = f.grad_observable.dot(direction)
                delta = abs(1 - diff / diff_num)
                deltas.append(delta)
        stats = median_statistics(deltas)
        tol = 1e-3
        assert stats.median < tol, (str(space_group_info), stats.median)
        assert stats.median_absolute_deviation < tol, (str(space_group_info), stats.median_absolute_deviation)
Exemple #6
0
 def __init__(O,
              f_obs,
              i_obs,
              i_sig,
              i_calc=None,
              f_calc=None,
              wa=0.1,
              wb=0):
     assert [i_calc, f_calc].count(None) == 1
     if (i_calc is None):
         from cctbx.array_family import flex
         i_calc = flex.norm(f_calc)
     from cctbx import xray
     raw = xray.targets_shelxl_wght_ls_kwt_b_dv(f_obs=f_obs,
                                                i_obs=i_obs,
                                                i_sig=i_sig,
                                                ic=i_calc,
                                                wa=wa,
                                                wb=wb)
     assert len(raw) == 5
     O.scale_factor, \
     O.weights, \
     O.target, \
     O.i_gradients, \
     O.i_curvatures = raw
     if (f_calc is None):
         O.f_gradients = None
         O.f_hessians = None
     else:
         g = O.i_gradients
         c = O.i_curvatures
         O.f_gradients = 2 * g * f_calc
         a = flex.real(f_calc)
         b = flex.imag(f_calc)
         aa = 2 * g + 4 * a * a * c
         bb = 2 * g + 4 * b * b * c
         ab = 4 * a * b * c
         O.f_hessians = flex.vec3_double(aa, bb, ab)
Exemple #7
0
    def add_miller_array(self,
                         array,
                         array_type=None,
                         column_name=None,
                         column_names=None):
        """
    Accepts a miller array, and one of array_type, column_name or column_names.
    """

        assert [array_type, column_name, column_names].count(None) == 2
        if array_type is not None:
            assert array_type in ('calc', 'meas')
        elif column_name is not None:
            column_names = [column_name]
        if array.is_complex_array():
            if column_names is None:
                column_names = [
                    self.prefix + 'F_' + array_type,
                    self.prefix + 'phase_' + array_type
                ]
            else:
                assert len(column_names) == 2
            if (('_A_' in column_names[0] and '_B_' in column_names[1]) or
                ('.A_' in column_names[0] and '.B_' in column_names[1])):
                data = [
                    flex.real(array.data()).as_string(),
                    flex.imag(array.data()).as_string()
                ]
            else:
                data = [
                    flex.abs(array.data()).as_string(),
                    array.phases(deg=True).data().as_string()
                ]
        elif array.is_hendrickson_lattman_array():
            if column_names is None:
                column_names = [
                    self.prefix + 'HL_%s_iso' % abcd for abcd in 'ABCD'
                ]
            else:
                assert len(column_names) == 4
            data = [d.as_string() for d in array.data().as_abcd()]
        else:
            if array_type is not None:
                if array.is_xray_intensity_array():
                    obs_ext = 'squared_'
                else:
                    obs_ext = ''
                column_names = [self.prefix + 'F_' + obs_ext + array_type]
                if array.sigmas() is not None:
                    column_names.append(self.prefix + 'F_' + obs_ext + 'sigma')
            if isinstance(array.data(), flex.std_string):
                data = [array.data()]
            else:
                data = [array.data().as_string()]
            if array.anomalous_flag():
                if ((array.sigmas() is not None and len(column_names) == 4) or
                    (array.sigmas() is None and len(column_names) == 2)):
                    data = []
                    asu, matches = array.match_bijvoet_mates()
                    for anomalous_sign in ("+", "-"):
                        sel = matches.pairs_hemisphere_selection(
                            anomalous_sign)
                        sel.extend(
                            matches.singles_hemisphere_selection(
                                anomalous_sign))
                        if (anomalous_sign == "+"):
                            indices = asu.indices().select(sel)
                            hemisphere_column_names = column_names[:len(
                                column_names) // 2]
                        else:
                            indices = -asu.indices().select(sel)
                            hemisphere_column_names = column_names[
                                len(column_names) // 2:]
                        hemisphere_data = asu.data().select(sel)
                        hemisphere_array = miller.array(
                            miller.set(array.crystal_symmetry(), indices),
                            hemisphere_data)
                        if array.sigmas() is not None:
                            hemisphere_array.set_sigmas(
                                asu.sigmas().select(sel))
                        if self.refln_loop is None:
                            # then this is the first array to be added to the loop,
                            # hack so we don't have both hemispheres of indices
                            self.indices = indices
                        self.add_miller_array(
                            hemisphere_array,
                            column_names=hemisphere_column_names)
                    return
            if array.sigmas() is not None and len(column_names) == 2:
                data.append(array.sigmas().as_string())
        if not (self.indices.size() == array.indices().size()
                and self.indices.all_eq(array.indices())):
            from cctbx.miller import match_indices
            other_indices = array.indices().deep_copy()
            match = match_indices(self.indices, other_indices)
            if match.singles(0).size():
                # array is missing some reflections indices that already appear in the loop
                # therefore pad the data with '?' values
                other_indices.extend(
                    self.indices.select(match.single_selection(0)))
                for d in data:
                    d.extend(
                        flex.std_string(['?'] *
                                        (other_indices.size() - d.size())))
                for d in data:
                    assert d.size() == other_indices.size()
                match = match_indices(self.indices, other_indices)
            if match.singles(1).size():
                # this array contains some reflections that are not already present in the
                # cif loop, therefore need to add rows of '?' values
                single_indices = other_indices.select(
                    match.single_selection(1))
                self.indices.extend(single_indices)
                n_data_columns = len(self.refln_loop.keys()) - 3
                for hkl in single_indices:
                    row = list(hkl) + ['?'] * n_data_columns
                    self.refln_loop.add_row(row)
                match = match_indices(self.indices, other_indices)

            match = match_indices(self.indices, other_indices)
            perm = match.permutation()
            data = [d.select(perm) for d in data]

        if self.refln_loop is None:
            self.refln_loop = miller_indices_as_cif_loop(self.indices,
                                                         prefix=self.prefix)
        columns = OrderedDict(zip(column_names, data))
        for key in columns:
            assert key not in self.refln_loop
        self.refln_loop.add_columns(columns)
Exemple #8
0
def exercise(space_group_info,
             const_gaussian,
             negative_gaussian,
             anomalous_flag,
             allow_mix,
             use_u_iso,
             use_u_aniso,
             d_min=1.,
             resolution_factor=1. / 3,
             max_prime=5,
             quality_factor=100,
             wing_cutoff=1.e-6,
             exp_table_one_over_step_size=-100,
             force_complex=False,
             verbose=0):
    if (const_gaussian):
        elements = ["const"] * 8
    elif (negative_gaussian):
        elements = ["H"] * 8
    else:
        elements = ["N", "C", "C", "O", "N", "C", "C", "O"]
    if (random.random() < 0.5):
        random_f_prime_scale = 0.6
    else:
        random_f_prime_scale = 0
    structure = random_structure.xray_structure(
        space_group_info,
        elements=elements,
        random_f_prime_d_min=1,
        random_f_prime_scale=random_f_prime_scale,
        random_f_double_prime=anomalous_flag,
        use_u_aniso=True,
        use_u_iso=False,
        random_u_cart_scale=0.3,
        random_u_iso=True,
        random_occupancy=True)
    random_structure.random_modify_adp_and_adp_flags_2(
        scatterers=structure.scatterers(),
        use_u_iso=use_u_iso,
        use_u_aniso=use_u_aniso,
        allow_mix=allow_mix,
        random_u_iso_scale=0.3,
        random_u_iso_min=0.0)
    sampled_density_must_be_positive = True
    if (negative_gaussian):
        reg = structure.scattering_type_registry(
            custom_dict={"H": eltbx.xray_scattering.gaussian(-1)})
        assert reg.gaussian("H").n_terms() == 0
        assert reg.gaussian("H").c() == -1
        sampled_density_must_be_positive = False
    elif (not const_gaussian and random.random() < 0.5):
        if (random.random() < 0.5):
            sampled_density_must_be_positive = False
        assign_custom_gaussians(
            structure, negative_a=not sampled_density_must_be_positive)
    f_direct = structure.structure_factors(anomalous_flag=anomalous_flag,
                                           d_min=d_min,
                                           algorithm="direct").f_calc()
    crystal_gridding = f_direct.crystal_gridding(
        resolution_factor=resolution_factor, d_min=d_min, max_prime=max_prime)
    assert crystal_gridding.symmetry_flags() is None
    rfft = fftpack.real_to_complex_3d(crystal_gridding.n_real())
    u_base = xray.calc_u_base(d_min, resolution_factor, quality_factor)
    omptbx.env.num_threads = libtbx.introspection.number_of_processors()
    sampled_density = xray.sampled_model_density(
        unit_cell=structure.unit_cell(),
        scatterers=structure.scatterers(),
        scattering_type_registry=structure.scattering_type_registry(),
        fft_n_real=rfft.n_real(),
        fft_m_real=rfft.m_real(),
        u_base=u_base,
        wing_cutoff=wing_cutoff,
        exp_table_one_over_step_size=exp_table_one_over_step_size,
        force_complex=force_complex,
        sampled_density_must_be_positive=sampled_density_must_be_positive,
        tolerance_positive_definite=1.e-5,
        use_u_base_as_u_extra=False)
    focus = sampled_density.real_map_unpadded().focus()
    all = sampled_density.real_map_unpadded().all()
    last = sampled_density.real_map_unpadded().last()
    assert approx_equal(focus, last)
    assert approx_equal(all, last)
    assert sampled_density.anomalous_flag() == (anomalous_flag
                                                or force_complex)
    if (0 or verbose):
        print("const_gaussian:", const_gaussian)
        print("negative_gaussian:", negative_gaussian)
        print("number of scatterers passed:", \
          sampled_density.n_scatterers_passed())
        print("number of contributing scatterers:", \
          sampled_density.n_contributing_scatterers())
        print("number of anomalous scatterers:", \
          sampled_density.n_anomalous_scatterers())
        print("wing_cutoff:", sampled_density.wing_cutoff())
        print("exp_table_one_over_step_size:", \
          sampled_density.exp_table_one_over_step_size())
        print("exp_table_size:", sampled_density.exp_table_size())
        print("max_sampling_box_edges:",
              sampled_density.max_sampling_box_edges(),
              end=' ')
        print("(%.4f, %.4f, %.4f)" %
              sampled_density.max_sampling_box_edges_frac())
        if (not sampled_density.anomalous_flag()):
            print("map min:", flex.min(sampled_density.real_map()))
            print("map max:", flex.max(sampled_density.real_map()))
        else:
            print("map min:",
                  flex.min(flex.real(sampled_density.complex_map())),
                  end=' ')
            print(flex.min(flex.imag(sampled_density.complex_map())))
            print("map max:",
                  flex.max(flex.real(sampled_density.complex_map())),
                  end=' ')
            print(flex.max(flex.imag(sampled_density.complex_map())))
    if (not sampled_density.anomalous_flag() and negative_gaussian):
        assert flex.min(sampled_density.real_map()) < 0
        assert flex.max(sampled_density.real_map()) == 0
    if (not sampled_density.anomalous_flag()):
        map = sampled_density.real_map()
        assert map.all() == rfft.m_real()
        assert map.focus() == rfft.n_real()
        sf_map = rfft.forward(map)
        assert sf_map.all() == rfft.n_complex()
        assert sf_map.focus() == rfft.n_complex()
        collect_conj = True
    else:
        cfft = fftpack.complex_to_complex_3d(rfft.n_real())
        map = sampled_density.complex_map()
        assert map.all() == cfft.n()
        assert map.focus() == cfft.n()
        sf_map = cfft.backward(map)
        assert sf_map.all() == cfft.n()
        assert sf_map.focus() == cfft.n()
        collect_conj = False
    f_fft_data = maptbx.structure_factors.from_map(
        space_group=f_direct.space_group(),
        anomalous_flag=sampled_density.anomalous_flag(),
        miller_indices=f_direct.indices(),
        complex_map=sf_map,
        conjugate_flag=collect_conj).data()
    sampled_density.eliminate_u_extra_and_normalize(f_direct.indices(),
                                                    f_fft_data)
    structure_factor_utils.check_correlation("direct/fft_regression",
                                             f_direct.indices(),
                                             0,
                                             f_direct.data(),
                                             f_fft_data,
                                             min_corr_ampl=1 * 0.99,
                                             max_mean_w_phase_error=1 * 3.,
                                             verbose=verbose)
    f_fft = xray.structure_factors.from_scatterers(
        miller_set=f_direct,
        grid_resolution_factor=resolution_factor,
        quality_factor=quality_factor,
        wing_cutoff=wing_cutoff,
        exp_table_one_over_step_size=exp_table_one_over_step_size,
        sampled_density_must_be_positive=sampled_density_must_be_positive,
        max_prime=max_prime)(xray_structure=structure,
                             miller_set=f_direct,
                             algorithm="fft").f_calc()
    structure_factor_utils.check_correlation("direct/fft_xray",
                                             f_direct.indices(),
                                             0,
                                             f_direct.data(),
                                             f_fft.data(),
                                             min_corr_ampl=1 * 0.99,
                                             max_mean_w_phase_error=1 * 3.,
                                             verbose=verbose)
  def add_miller_array(self, array, array_type=None,
                       column_name=None, column_names=None):
    """
    Accepts a miller array, and one of array_type, column_name or column_names.
    """

    assert [array_type, column_name, column_names].count(None) == 2
    if array_type is not None:
      assert array_type in ('calc', 'meas')
    elif column_name is not None:
      column_names = [column_name]
    if array.is_complex_array():
      if column_names is None:
        column_names = [self.prefix+'F_'+array_type,
                        self.prefix+'phase_'+array_type]
      else: assert len(column_names) == 2
      if (('_A_' in column_names[0] and '_B_' in column_names[1]) or
          ('.A_' in column_names[0] and '.B_' in column_names[1])):
        data = [flex.real(array.data()).as_string(),
                 flex.imag(array.data()).as_string()]
      else:
        data = [flex.abs(array.data()).as_string(),
                 array.phases(deg=True).data().as_string()]
    elif array.is_hendrickson_lattman_array():
      if column_names is None:
        column_names = [self.prefix+'HL_%s_iso' %abcd for abcd in 'ABCD']
      else: assert len(column_names) == 4
      data = [d.as_string() for d in array.data().as_abcd()]
    else:
      if array_type is not None:
        if array.is_xray_intensity_array():
          obs_ext = 'squared_'
        else: obs_ext = ''
        column_names = [self.prefix+'F_'+obs_ext+array_type]
        if array.sigmas() is not None:
          column_names.append(self.prefix+'F_'+obs_ext+'sigma')
      if isinstance(array.data(), flex.std_string):
        data = [array.data()]
      else:
        data = [array.data().as_string()]
      if array.anomalous_flag():
        if ((array.sigmas() is not None and len(column_names) == 4) or
            (array.sigmas() is None and len(column_names) == 2)):
          data = []
          asu, matches = array.match_bijvoet_mates()
          for anomalous_sign in ("+", "-"):
            sel = matches.pairs_hemisphere_selection(anomalous_sign)
            sel.extend(matches.singles_hemisphere_selection(anomalous_sign))
            if (anomalous_sign == "+"):
              indices = asu.indices().select(sel)
              hemisphere_column_names = column_names[:len(column_names)//2]
            else:
              indices = -asu.indices().select(sel)
              hemisphere_column_names = column_names[len(column_names)//2:]
            hemisphere_data = asu.data().select(sel)
            hemisphere_array = miller.array(miller.set(
              array.crystal_symmetry(), indices), hemisphere_data)
            if array.sigmas() is not None:
              hemisphere_array.set_sigmas(asu.sigmas().select(sel))
            if self.refln_loop is None:
              # then this is the first array to be added to the loop,
              # hack so we don't have both hemispheres of indices
              self.indices = indices
            self.add_miller_array(
              hemisphere_array, column_names=hemisphere_column_names)
          return
      if array.sigmas() is not None and len(column_names) == 2:
        data.append(array.sigmas().as_string())
    if not (self.indices.size() == array.indices().size() and
            self.indices.all_eq(array.indices())):
      from cctbx.miller import match_indices
      other_indices = array.indices().deep_copy()
      match = match_indices(self.indices, other_indices)
      if match.singles(0).size():
        # array is missing some reflections indices that already appear in the loop
        # therefore pad the data with '?' values
        other_indices.extend(self.indices.select(match.single_selection(0)))
        for d in data:
          d.extend(flex.std_string(['?']*(other_indices.size() - d.size())))
        for d in data:
          assert d.size() == other_indices.size()
        match = match_indices(self.indices, other_indices)
      if match.singles(1).size():
        # this array contains some reflections that are not already present in the
        # cif loop, therefore need to add rows of '?' values
        single_indices = other_indices.select(match.single_selection(1))
        self.indices.extend(single_indices)
        n_data_columns = len(self.refln_loop.keys()) - 3
        for hkl in single_indices:
          row = list(hkl) + ['?'] * n_data_columns
          self.refln_loop.add_row(row)
        match = match_indices(self.indices, other_indices)

      match = match_indices(self.indices, other_indices)
      perm = match.permutation()
      data = [d.select(perm) for d in data]

    if self.refln_loop is None:
      self.refln_loop = miller_indices_as_cif_loop(self.indices, prefix=self.prefix)
    columns = OrderedDict(zip(column_names, data))
    for key in columns:
      assert key not in self.refln_loop
    self.refln_loop.add_columns(columns)
def exercise(space_group_info, const_gaussian, negative_gaussian,
             anomalous_flag,
             allow_mix,
             use_u_iso,
             use_u_aniso,
             d_min=1., resolution_factor=1./3, max_prime=5,
             quality_factor=100, wing_cutoff=1.e-6,
             exp_table_one_over_step_size=-100,
             force_complex=False,
             verbose=0):
  if (const_gaussian):
    elements=["const"]*8
  elif (negative_gaussian):
    elements=["H"]*8
  else:
    elements=["N", "C", "C", "O", "N", "C", "C", "O"]
  if (random.random() < 0.5):
    random_f_prime_scale=0.6
  else:
    random_f_prime_scale=0
  structure = random_structure.xray_structure(
    space_group_info,
    elements=elements,
    random_f_prime_d_min=1,
    random_f_prime_scale=random_f_prime_scale,
    random_f_double_prime=anomalous_flag,
    use_u_aniso= True,
    use_u_iso= False,
    random_u_cart_scale=0.3,
    random_u_iso=True,
    random_occupancy=True)
  random_structure.random_modify_adp_and_adp_flags_2(
                                 scatterers         = structure.scatterers(),
                                 use_u_iso          = use_u_iso,
                                 use_u_aniso        = use_u_aniso,
                                 allow_mix          = allow_mix,
                                 random_u_iso_scale = 0.3,
                                 random_u_iso_min   = 0.0)
  sampled_density_must_be_positive = True
  if (negative_gaussian):
    reg = structure.scattering_type_registry(
      custom_dict={"H": eltbx.xray_scattering.gaussian(-1)})
    assert reg.gaussian("H").n_terms() == 0
    assert reg.gaussian("H").c() == -1
    sampled_density_must_be_positive = False
  elif (not const_gaussian and random.random() < 0.5):
    if (random.random() < 0.5):
      sampled_density_must_be_positive = False
    assign_custom_gaussians(
      structure,
      negative_a=not sampled_density_must_be_positive)
  f_direct = structure.structure_factors(
    anomalous_flag=anomalous_flag,
    d_min=d_min,
    algorithm="direct").f_calc()
  crystal_gridding = f_direct.crystal_gridding(
    resolution_factor=resolution_factor,
    d_min=d_min,
    max_prime=max_prime)
  assert crystal_gridding.symmetry_flags() is None
  rfft = fftpack.real_to_complex_3d(crystal_gridding.n_real())
  u_base = xray.calc_u_base(d_min, resolution_factor, quality_factor)
  omptbx.env.num_threads = libtbx.introspection.number_of_processors()
  sampled_density = xray.sampled_model_density(
    unit_cell=structure.unit_cell(),
    scatterers=structure.scatterers(),
    scattering_type_registry=structure.scattering_type_registry(),
    fft_n_real=rfft.n_real(),
    fft_m_real=rfft.m_real(),
    u_base=u_base,
    wing_cutoff=wing_cutoff,
    exp_table_one_over_step_size=exp_table_one_over_step_size,
    force_complex=force_complex,
    sampled_density_must_be_positive=sampled_density_must_be_positive,
    tolerance_positive_definite=1.e-5,
    use_u_base_as_u_extra=False)
  focus = sampled_density.real_map_unpadded().focus()
  all   = sampled_density.real_map_unpadded().all()
  last  = sampled_density.real_map_unpadded().last()
  assert approx_equal(focus, last)
  assert approx_equal(all, last)
  assert sampled_density.anomalous_flag() == (anomalous_flag or force_complex)
  if (0 or verbose):
    print "const_gaussian:", const_gaussian
    print "negative_gaussian:", negative_gaussian
    print "number of scatterers passed:", \
      sampled_density.n_scatterers_passed()
    print "number of contributing scatterers:", \
      sampled_density.n_contributing_scatterers()
    print "number of anomalous scatterers:", \
      sampled_density.n_anomalous_scatterers()
    print "wing_cutoff:", sampled_density.wing_cutoff()
    print "exp_table_one_over_step_size:", \
      sampled_density.exp_table_one_over_step_size()
    print "exp_table_size:", sampled_density.exp_table_size()
    print "max_sampling_box_edges:", sampled_density.max_sampling_box_edges(),
    print "(%.4f, %.4f, %.4f)" % sampled_density.max_sampling_box_edges_frac()
    if (not sampled_density.anomalous_flag()):
      print "map min:", flex.min(sampled_density.real_map())
      print "map max:", flex.max(sampled_density.real_map())
    else:
      print "map min:", flex.min(flex.real(sampled_density.complex_map())),
      print             flex.min(flex.imag(sampled_density.complex_map()))
      print "map max:", flex.max(flex.real(sampled_density.complex_map())),
      print             flex.max(flex.imag(sampled_density.complex_map()))
  if (not sampled_density.anomalous_flag() and negative_gaussian):
    assert flex.min(sampled_density.real_map()) < 0
    assert flex.max(sampled_density.real_map()) == 0
  if (not sampled_density.anomalous_flag()):
    map = sampled_density.real_map()
    assert map.all() == rfft.m_real()
    assert map.focus() == rfft.n_real()
    sf_map = rfft.forward(map)
    assert sf_map.all() == rfft.n_complex()
    assert sf_map.focus() == rfft.n_complex()
    collect_conj = True
  else:
    cfft = fftpack.complex_to_complex_3d(rfft.n_real())
    map = sampled_density.complex_map()
    assert map.all() == cfft.n()
    assert map.focus() == cfft.n()
    sf_map = cfft.backward(map)
    assert sf_map.all() == cfft.n()
    assert sf_map.focus() == cfft.n()
    collect_conj = False
  f_fft_data = maptbx.structure_factors.from_map(
    space_group=f_direct.space_group(),
    anomalous_flag=sampled_density.anomalous_flag(),
    miller_indices=f_direct.indices(),
    complex_map=sf_map,
    conjugate_flag=collect_conj).data()
  sampled_density.eliminate_u_extra_and_normalize(
    f_direct.indices(),
    f_fft_data)
  structure_factor_utils.check_correlation(
    "direct/fft_regression", f_direct.indices(), 0,
    f_direct.data(), f_fft_data,
    min_corr_ampl=1*0.99, max_mean_w_phase_error=1*3.,
    verbose=verbose)
  f_fft = xray.structure_factors.from_scatterers(
    miller_set=f_direct,
    grid_resolution_factor=resolution_factor,
    quality_factor=quality_factor,
    wing_cutoff=wing_cutoff,
    exp_table_one_over_step_size=exp_table_one_over_step_size,
    sampled_density_must_be_positive=sampled_density_must_be_positive,
    max_prime=max_prime)(
      xray_structure=structure,
      miller_set=f_direct,
      algorithm="fft").f_calc()
  structure_factor_utils.check_correlation(
    "direct/fft_xray", f_direct.indices(), 0,
    f_direct.data(), f_fft.data(),
    min_corr_ampl=1*0.99, max_mean_w_phase_error=1*3.,
    verbose=verbose)
def exercise_under_sampled(space_group_info,
                           anomalous_flag,
                           conjugate_flag,
                           under_sampling,
                           d_min=2.,
                           resolution_factor=0.5,
                           max_prime=5,
                           verbose=0):
    structure_factors = random_structure.xray_structure(
        space_group_info,
        elements=("N", "C", "C", "O"),
        random_f_prime_d_min=1,
        random_f_double_prime=anomalous_flag,
        use_u_aniso=True,
        random_u_iso=True,
        random_occupancy=True).structure_factors(anomalous_flag=anomalous_flag,
                                                 d_min=d_min,
                                                 algorithm="direct")
    f_calc = structure_factors.f_calc()
    n_real = maptbx.crystal_gridding(unit_cell=f_calc.unit_cell(),
                                     d_min=d_min,
                                     resolution_factor=resolution_factor,
                                     max_prime=max_prime,
                                     mandatory_factors=(under_sampling, ) *
                                     3).n_real()
    if (not anomalous_flag):
        rfft = fftpack.real_to_complex_3d(n_real)
        n_complex = rfft.n_complex()
    else:
        cfft = fftpack.complex_to_complex_3d(n_real)
        n_complex = cfft.n()
    map = maptbx.structure_factors.to_map(space_group=f_calc.space_group(),
                                          anomalous_flag=anomalous_flag,
                                          miller_indices=f_calc.indices(),
                                          structure_factors=f_calc.data(),
                                          n_real=n_real,
                                          map_grid=flex.grid(n_complex),
                                          conjugate_flag=conjugate_flag)
    f_calc_p1 = f_calc.expand_to_p1()
    map_p1 = maptbx.structure_factors.to_map(
        space_group=f_calc_p1.space_group(),
        anomalous_flag=anomalous_flag,
        miller_indices=f_calc_p1.indices(),
        structure_factors=f_calc_p1.data(),
        n_real=n_real,
        map_grid=flex.grid(n_complex),
        conjugate_flag=conjugate_flag)
    assert flex.max(
        flex.abs(map_p1.complex_map() - map.complex_map())) < 1.e-10
    if (not anomalous_flag):
        real_map = rfft.backward(map.complex_map())
        assert real_map.all() == rfft.m_real()
    else:
        real_map = cfft.backward(map.complex_map())
        assert not real_map.is_padded()
    if (0 or verbose):
        if (not anomalous_flag):
            maptbx.statistics(real_map).show_summary()
            maptbx.statistics(real_map).show_summary()
        else:
            maptbx.statistics(flex.real(real_map)).show_summary()
            maptbx.statistics(flex.imag(real_map)).show_summary()
    n_real_under_sampled = [n // under_sampling for n in n_real]
    if (not anomalous_flag):
        rfft = fftpack.real_to_complex_3d(n_real_under_sampled)
        n_complex_under_sampled = rfft.n_complex()
    else:
        cfft = fftpack.complex_to_complex_3d(n_real_under_sampled)
        n_complex_under_sampled = cfft.n()
    under_sampled_map = maptbx.structure_factors.to_map(
        space_group=f_calc.space_group(),
        anomalous_flag=anomalous_flag,
        miller_indices=f_calc.indices(),
        structure_factors=f_calc.data(),
        n_real=n_real_under_sampled,
        map_grid=flex.grid(n_complex_under_sampled),
        conjugate_flag=conjugate_flag)
    under_sampled_map_p1 = maptbx.structure_factors.to_map(
        space_group=f_calc_p1.space_group(),
        anomalous_flag=anomalous_flag,
        miller_indices=f_calc_p1.indices(),
        structure_factors=f_calc_p1.data(),
        n_real=n_real_under_sampled,
        map_grid=flex.grid(n_complex_under_sampled),
        conjugate_flag=conjugate_flag)
    assert flex.max(
        flex.abs(under_sampled_map_p1.complex_map() -
                 under_sampled_map.complex_map())) < 1.e-10
    if (not anomalous_flag):
        under_sampled_map_before_fft = under_sampled_map.complex_map(
        ).deep_copy()
        under_sampled_real_map = rfft.backward(under_sampled_map.complex_map())
        assert under_sampled_real_map.all() == rfft.m_real()
    else:
        under_sampled_real_map = cfft.backward(under_sampled_map.complex_map())
        assert not under_sampled_real_map.is_padded()
    if (0 or verbose):
        if (not anomalous_flag):
            maptbx.statistics(under_sampled_real_map).show_summary()
            maptbx.statistics(under_sampled_real_map).show_summary()
        else:
            maptbx.statistics(flex.real(under_sampled_real_map)).show_summary()
            maptbx.statistics(flex.imag(under_sampled_real_map)).show_summary()
    if (0 or verbose):
        print(real_map.all(), n_complex)
        print(under_sampled_real_map.all(), n_complex_under_sampled)
    if (not anomalous_flag):
        x_source = real_map
        y_source = under_sampled_real_map
    else:
        x_source = flex.real(real_map)
        y_source = flex.real(under_sampled_real_map)
    x = flex.double()
    n = x_source.focus()
    for i in range(0, n[0], under_sampling):
        for j in range(0, n[1], under_sampling):
            for k in range(0, n[2], under_sampling):
                x.append(x_source[(i, j, k)])
    y = maptbx.copy(y_source, flex.grid(y_source.focus())).as_1d()
    if (0 or verbose):
        print("x:", tuple(x))
        print("y:", tuple(y))
    assert flex.max(flex.abs(x-y)) \
        < (flex.max(flex.abs(x))+flex.max(flex.abs(y)))/2*1.e-6
    if (under_sampling == 1):
        x = maptbx.copy(x_source, flex.grid(x_source.focus())).as_1d()
        c = flex.linear_correlation(x, y)
        assert c.coefficient() >= 0.9999
def exercise_under_sampled(space_group_info, anomalous_flag, conjugate_flag,
                           under_sampling,
                           d_min=2., resolution_factor=0.5, max_prime=5,
                           verbose=0):
  structure_factors = random_structure.xray_structure(
    space_group_info,
    elements=("N", "C", "C", "O"),
    random_f_prime_d_min=1,
    random_f_double_prime=anomalous_flag,
    use_u_aniso=True,
    random_u_iso=True,
    random_occupancy=True
    ).structure_factors(
        anomalous_flag=anomalous_flag, d_min=d_min, algorithm="direct")
  f_calc = structure_factors.f_calc()
  n_real = maptbx.crystal_gridding(
    unit_cell=f_calc.unit_cell(),
    d_min=d_min,
    resolution_factor=resolution_factor,
    max_prime=max_prime,
    mandatory_factors=(under_sampling,)*3).n_real()
  if (not anomalous_flag):
    rfft = fftpack.real_to_complex_3d(n_real)
    n_complex = rfft.n_complex()
  else:
    cfft = fftpack.complex_to_complex_3d(n_real)
    n_complex = cfft.n()
  map = maptbx.structure_factors.to_map(
    space_group=f_calc.space_group(),
    anomalous_flag=anomalous_flag,
    miller_indices=f_calc.indices(),
    structure_factors=f_calc.data(),
    n_real=n_real,
    map_grid=flex.grid(n_complex),
    conjugate_flag=conjugate_flag)
  f_calc_p1 = f_calc.expand_to_p1()
  map_p1 = maptbx.structure_factors.to_map(
    space_group=f_calc_p1.space_group(),
    anomalous_flag=anomalous_flag,
    miller_indices=f_calc_p1.indices(),
    structure_factors=f_calc_p1.data(),
    n_real=n_real,
    map_grid=flex.grid(n_complex),
    conjugate_flag=conjugate_flag)
  assert flex.max(flex.abs(map_p1.complex_map() - map.complex_map())) < 1.e-10
  if (not anomalous_flag):
    real_map = rfft.backward(map.complex_map())
    assert real_map.all() == rfft.m_real()
  else:
    real_map = cfft.backward(map.complex_map())
    assert not real_map.is_padded()
  if (0 or verbose):
    if (not anomalous_flag):
      maptbx.statistics(real_map).show_summary()
      maptbx.statistics(real_map).show_summary()
    else:
      maptbx.statistics(flex.real(real_map)).show_summary()
      maptbx.statistics(flex.imag(real_map)).show_summary()
  n_real_under_sampled = [n//under_sampling for n in n_real]
  if (not anomalous_flag):
    rfft = fftpack.real_to_complex_3d(n_real_under_sampled)
    n_complex_under_sampled = rfft.n_complex()
  else:
    cfft = fftpack.complex_to_complex_3d(n_real_under_sampled)
    n_complex_under_sampled = cfft.n()
  under_sampled_map = maptbx.structure_factors.to_map(
    space_group=f_calc.space_group(),
    anomalous_flag=anomalous_flag,
    miller_indices=f_calc.indices(),
    structure_factors=f_calc.data(),
    n_real=n_real_under_sampled,
    map_grid=flex.grid(n_complex_under_sampled),
    conjugate_flag=conjugate_flag)
  under_sampled_map_p1 = maptbx.structure_factors.to_map(
    space_group=f_calc_p1.space_group(),
    anomalous_flag=anomalous_flag,
    miller_indices=f_calc_p1.indices(),
    structure_factors=f_calc_p1.data(),
    n_real=n_real_under_sampled,
    map_grid=flex.grid(n_complex_under_sampled),
    conjugate_flag=conjugate_flag)
  assert flex.max(flex.abs(under_sampled_map_p1.complex_map()
                         - under_sampled_map.complex_map())) < 1.e-10
  if (not anomalous_flag):
    under_sampled_map_before_fft = under_sampled_map.complex_map().deep_copy()
    under_sampled_real_map = rfft.backward(under_sampled_map.complex_map())
    assert under_sampled_real_map.all() == rfft.m_real()
  else:
    under_sampled_real_map = cfft.backward(under_sampled_map.complex_map())
    assert not under_sampled_real_map.is_padded()
  if (0 or verbose):
    if (not anomalous_flag):
      maptbx.statistics(under_sampled_real_map).show_summary()
      maptbx.statistics(under_sampled_real_map).show_summary()
    else:
      maptbx.statistics(flex.real(under_sampled_real_map)).show_summary()
      maptbx.statistics(flex.imag(under_sampled_real_map)).show_summary()
  if (0 or verbose):
    print real_map.all(), n_complex
    print under_sampled_real_map.all(), n_complex_under_sampled
  if (not anomalous_flag):
    x_source = real_map
    y_source = under_sampled_real_map
  else:
    x_source = flex.real(real_map)
    y_source = flex.real(under_sampled_real_map)
  x = flex.double()
  n = x_source.focus()
  for i in xrange(0, n[0], under_sampling):
    for j in xrange(0, n[1], under_sampling):
      for k in xrange(0, n[2], under_sampling):
        x.append(x_source[(i,j,k)])
  y = maptbx.copy(y_source, flex.grid(y_source.focus())).as_1d()
  if (0 or verbose):
    print "x:", tuple(x)
    print "y:", tuple(y)
  assert flex.max(flex.abs(x-y)) \
      < (flex.max(flex.abs(x))+flex.max(flex.abs(y)))/2*1.e-6
  if (under_sampling == 1):
    x = maptbx.copy(x_source, flex.grid(x_source.focus())).as_1d()
    c = flex.linear_correlation(x, y)
    assert c.coefficient() >= 0.9999