def exercise_05_k_sol_b_sol_only(d_min=2.0):
    xray_structure = get_xray_structure_from_file()
    k_sol = 0.33
    b_sol = 34.0
    b_cart = [1, 2, 3, 0, 4, 0]
    f_obs, r_free_flags = get_f_obs_freer(d_min=d_min,
                                          k_sol=k_sol,
                                          b_sol=b_sol,
                                          b_cart=b_cart,
                                          xray_structure=xray_structure)
    fmodel = mmtbx.f_model.manager(r_free_flags=r_free_flags,
                                   f_obs=f_obs,
                                   xray_structure=xray_structure)
    params = bss.master_params.extract()
    params.anisotropic_scaling = False
    params.number_of_macro_cycles = 5
    u_star = adptbx.u_cart_as_u_star(fmodel.f_obs().unit_cell(),
                                     adptbx.b_as_u(b_cart))
    fmodel_kbu = mmtbx.f_model.manager_kbu(f_obs=fmodel.f_obs(),
                                           f_calc=fmodel.f_calc(),
                                           f_masks=fmodel.arrays.core.f_masks,
                                           f_part1=fmodel.arrays.core.f_part1,
                                           f_part2=fmodel.arrays.core.f_part2,
                                           ss=fmodel.ss,
                                           u_star=u_star)
    r_work_start = fmodel_kbu.r_factor()
    result = bss.bulk_solvent_and_scales(fmodel_kbu=fmodel_kbu, params=params)
    r_work = result.fmodel_kbu.r_factor() * 100.
    assert r_work_start > 0.05
    #
    assert approx_equal(r_work, 0.0, eps=1.e-4)
    assert approx_equal(result.k_sols()[0], k_sol, eps=1.e-4)
    assert approx_equal(result.b_sols()[0], b_sol, eps=1.e-4)
    assert approx_equal(result.b_cart(), b_cart, eps=1.e-4)
def exercise_06_b_cart_only(d_min=2.0):
    xray_structure = get_xray_structure_from_file()
    k_sol = 0.33
    b_sol = 34.0
    b_cart = [1, 2, 3, 0, 4, 0]
    f_obs, r_free_flags = get_f_obs_freer(d_min=d_min,
                                          k_sol=k_sol,
                                          b_sol=b_sol,
                                          b_cart=b_cart,
                                          xray_structure=xray_structure)
    fmodel = mmtbx.f_model.manager(r_free_flags=r_free_flags,
                                   f_obs=f_obs,
                                   xray_structure=xray_structure)
    fmodel_kbu = mmtbx.f_model.manager_kbu(f_obs=fmodel.f_obs(),
                                           f_calc=fmodel.f_calc(),
                                           f_masks=fmodel.arrays.core.f_masks,
                                           f_part1=fmodel.arrays.core.f_part1,
                                           f_part2=fmodel.arrays.core.f_part2,
                                           ss=fmodel.ss,
                                           k_sols=[k_sol],
                                           b_sols=[b_sol])
    r_work_start = fmodel_kbu.r_factor() * 100.
    params = bss.master_params.extract()
    params.bulk_solvent = False
    result = bss.bulk_solvent_and_scales(fmodel_kbu=fmodel_kbu, params=params)
    r_work = result.fmodel_kbu.r_factor() * 100.
    assert r_work_start > 0.0
    assert approx_equal(r_work, 0.0, eps=1.e-6)
    assert approx_equal(result.k_sols()[0], k_sol, eps=1.e-6)
    assert approx_equal(result.b_sols()[0], b_sol, eps=1.e-6)
    assert approx_equal(result.b_cart(), b_cart, eps=1.e-6)
def exercise_06_b_cart_only(d_min = 2.0):
  xray_structure = get_xray_structure_from_file()
  k_sol = 0.33
  b_sol = 34.0
  b_cart = [1,2,3,0,4,0]
  f_obs, r_free_flags = get_f_obs_freer(
    d_min  = d_min,
    k_sol  = k_sol,
    b_sol  = b_sol,
    b_cart = b_cart,
    xray_structure = xray_structure)
  fmodel = mmtbx.f_model.manager(
    r_free_flags   = r_free_flags,
    f_obs          = f_obs,
    xray_structure = xray_structure)
  fmodel_kbu = mmtbx.f_model.manager_kbu(
    f_obs   = fmodel.f_obs(),
    f_calc  = fmodel.f_calc(),
    f_masks = fmodel.arrays.core.f_masks,
    f_part1 = fmodel.arrays.core.f_part1,
    f_part2 = fmodel.arrays.core.f_part2,
    ss      = fmodel.ss,
    k_sols  = [k_sol],
    b_sol   = b_sol)
  r_work_start = fmodel_kbu.r_factor()*100.
  params = bss.master_params.extract()
  params.bulk_solvent = False
  result = bss.bulk_solvent_and_scales(
    fmodel_kbu = fmodel_kbu, params  = params)
  r_work = result.fmodels.r_factor()*100.
  assert r_work_start > 0.0
  assert approx_equal(r_work,          0.0,    eps = 1.e-6)
  assert approx_equal(result.k_sol(0), k_sol,  eps = 1.e-6)
  assert approx_equal(result.b_sol(),  b_sol,  eps = 1.e-6)
  assert approx_equal(result.b_cart(), b_cart, eps = 1.e-6)
def exercise_03_do_nothing(d_min=2.0):
    xray_structure = get_xray_structure_from_file()
    k_sol = 0.98
    b_sol = 127.0
    b_cart = [1, 2, 3, 0, 4, 0]
    f_obs, r_free_flags = get_f_obs_freer(d_min=d_min,
                                          k_sol=k_sol,
                                          b_sol=b_sol,
                                          b_cart=b_cart,
                                          xray_structure=xray_structure)
    fmodel = mmtbx.f_model.manager(r_free_flags=r_free_flags,
                                   f_obs=f_obs,
                                   xray_structure=xray_structure)
    r_work_start = fmodel.r_work() * 100.
    params = bss.master_params.extract()
    params.bulk_solvent = False
    params.anisotropic_scaling = False
    fmodel.update_all_scales(params=params, fast=False, remove_outliers=False)
    result = bss.bulk_solvent_and_scales(fmodel_kbu=fmodel.fmodel_kbu(),
                                         params=params)
    r_work1 = fmodel.r_work() * 100.
    assert r_work_start > 0.0
    assert approx_equal(r_work1, r_work_start, eps=1.e-6)
    assert approx_equal(result.k_sols()[0], 0, eps=1.e-6)
    assert approx_equal(result.b_sols()[0], 0, eps=1.e-6)
    assert approx_equal(result.b_cart(), [0, 0, 0, 0, 0, 0], eps=1.e-6)
def exercise_03_do_nothing(d_min = 2.0):
  xray_structure = get_xray_structure_from_file()
  k_sol = 0.98
  b_sol = 127.0
  b_cart = [1,2,3,0,4,0]
  f_obs, r_free_flags = get_f_obs_freer(
    d_min  = d_min,
    k_sol  = k_sol,
    b_sol  = b_sol,
    b_cart = b_cart,
    xray_structure = xray_structure)
  fmodel = mmtbx.f_model.manager(
    r_free_flags   = r_free_flags,
    f_obs          = f_obs,
    xray_structure = xray_structure)
  r_work_start = fmodel.r_work()*100.
  params = bss.master_params.extract()
  params.bulk_solvent = False
  params.anisotropic_scaling = False
  fmodel.update_solvent_and_scale(params = params, fast=False)
  result = bss.bulk_solvent_and_scales(
    fmodel_kbu = fmodel.fmodel_kbu(), params  = params)
  r_work1 = fmodel.r_work()*100.
  r_work2 = result.fmodels.select(
    selection=~fmodel.r_free_flags().data()).r_factor()*100.
  assert r_work_start > 0.0
  assert approx_equal(r_work1, r_work_start, eps = 1.e-6)
  assert approx_equal(r_work2, r_work_start, eps = 1.e-6)
  assert approx_equal(result.k_sol(0), 0, eps = 1.e-6)
  assert approx_equal(result.b_sol(), 0, eps = 1.e-6)
  assert approx_equal(result.b_cart(), [0,0,0,0,0,0], eps = 1.e-6)
def exercise_01_general(
    d_mins=[
        1.6,
    ],
    solvkb=[(0, 0), (0.39, 58.0), (0.1, 6.), (0.54, 87.)],
    b_carts=[(4., 10., -14., 0, 5., 0.), (0., 0., 0., 0., 0., 0.)],
):
    xray_structure = get_xray_structure_from_file()
    params = bss.master_params.extract()
    params.number_of_macro_cycles = 3
    for fast in [True, False]:
        for d_min in d_mins:
            for kb in solvkb:
                for b_cart in b_carts:
                    f_obs, r_free_flags = \
                      get_f_obs_freer(d_min  = d_min,
                                      k_sol  = [kb[0]],
                                      b_sol  = [kb[1]],
                                      b_cart = b_cart,
                                      xray_structure = xray_structure)
                    #
                    bin_selections = []
                    f_obs.setup_binner(reflections_per_bin=50)
                    for i_bin in f_obs.binner().range_used():
                        sel = f_obs.binner().selection(i_bin)
                        bin_selections.append(sel)
                    #
                    fmodel = mmtbx.f_model.manager(
                        r_free_flags=r_free_flags,
                        f_obs=f_obs,
                        xray_structure=xray_structure,
                        bin_selections=bin_selections)
                    fmodel.update_all_scales(fast=fast,
                                             params=params,
                                             remove_outliers=False)
                    result = bss.bulk_solvent_and_scales(
                        fmodel_kbu=fmodel.fmodel_kbu(), params=params)
                    if (not fast):
                        assert approx_equal(fmodel.r_work(),
                                            result.fmodel_kbu.r_factor())
                    else:
                        assert fmodel.r_work() < 0.02, fmodel.r_work()
                    assert approx_equal(result.fmodel_kbu.r_factor(),
                                        0.0,
                                        eps=1.e-4)
                    assert approx_equal(result.k_sols()[0], kb[0], eps=1.e-4)
                    assert approx_equal(result.b_sols()[0], kb[1], eps=1.e-4)
                    assert approx_equal(result.b_cart(), b_cart, eps=1.e-2)
def exercise_02_b_cart_sym_constr(d_min = 2.0, tolerance = 1.e-6):
  for symbol in sgtbx.bravais_types.acentric + sgtbx.bravais_types.centric:
    space_group_info = sgtbx.space_group_info(symbol = symbol)
    xray_structure = get_xray_structure_random(space_group_info)
    sg = xray_structure.space_group()
    uc = xray_structure.unit_cell()
    u_cart_p1 = adptbx.random_u_cart(u_scale=5, u_min=5)
    u_star_p1 = adptbx.u_cart_as_u_star(uc, u_cart_p1)
    b_cart_1 = adptbx.u_star_as_u_cart(uc, u_star_p1)
    b_cart_2 = adptbx.u_star_as_u_cart(uc, sg.average_u_star(u_star = u_star_p1))
    for b_cart in (b_cart_1, b_cart_2):
      f_obs, r_free_flags = \
        get_f_obs_freer(d_min  = d_min,
                        k_sol  = 0,
                        b_sol  = 0,
                        b_cart = b_cart,
                        xray_structure = xray_structure)
      fmodel = mmtbx.f_model.manager(
        r_free_flags   = r_free_flags,
        f_obs          = f_obs,
        xray_structure = xray_structure)
      for flag in (True, False):
        params = bss.master_params.extract()
        params.bulk_solvent = False
        params.anisotropic_scaling = True
        params.k_sol_b_sol_grid_search = False
        params.minimization_k_sol_b_sol = False
        params.minimization_b_cart = True
        params.symmetry_constraints_on_b_cart = flag
        params.max_iterations = 50
        params.min_iterations = 50
        result = bss.bulk_solvent_and_scales(
          fmodel_kbu = fmodel.fmodel_kbu(), params = params)
        if(flag == False and approx_equal(b_cart, b_cart_1, out=None)):
          assert approx_equal(result.b_cart(), b_cart, tolerance)
        if(flag == True and approx_equal(b_cart, b_cart_2, out=None)):
          assert approx_equal(result.b_cart(), b_cart, tolerance)
        if(flag == False and approx_equal(b_cart, b_cart_2, out=None)):
          assert approx_equal(result.b_cart(), b_cart, tolerance)
        if(flag == True and approx_equal(b_cart, b_cart_1, out=None)):
          for u2, ufm in zip(b_cart_2, result.b_cart()):
            if(abs(u2) < 1.e-6): assert approx_equal(ufm, 0.0, tolerance)
def exercise_02_b_cart_sym_constr(d_min=2.0, tolerance=1.e-6):
    for symbol in sgtbx.bravais_types.acentric + sgtbx.bravais_types.centric:
        space_group_info = sgtbx.space_group_info(symbol=symbol)
        xray_structure = get_xray_structure_random(space_group_info)
        sg = xray_structure.space_group()
        uc = xray_structure.unit_cell()
        u_cart_p1 = adptbx.random_u_cart(u_scale=5, u_min=5)
        u_star_p1 = adptbx.u_cart_as_u_star(uc, u_cart_p1)
        b_cart_1 = adptbx.u_star_as_u_cart(uc, u_star_p1)
        b_cart_2 = adptbx.u_star_as_u_cart(uc,
                                           sg.average_u_star(u_star=u_star_p1))
        for b_cart in (b_cart_1, b_cart_2):
            f_obs, r_free_flags = \
              get_f_obs_freer(d_min  = d_min,
                              k_sol  = 0,
                              b_sol  = 0,
                              b_cart = b_cart,
                              xray_structure = xray_structure)
            fmodel = mmtbx.f_model.manager(r_free_flags=r_free_flags,
                                           f_obs=f_obs,
                                           xray_structure=xray_structure)
            flag = True
            params = bss.master_params.extract()
            params.number_of_macro_cycles = 3
            params.bulk_solvent = False
            params.anisotropic_scaling = True
            params.k_sol_b_sol_grid_search = False
            params.minimization_k_sol_b_sol = False
            params.minimization_b_cart = True
            params.symmetry_constraints_on_b_cart = flag
            params.max_iterations = 50
            params.min_iterations = 50
            result = bss.bulk_solvent_and_scales(
                fmodel_kbu=fmodel.fmodel_kbu(), params=params)
            if (flag == True and approx_equal(b_cart, b_cart_2, out=None)):
                assert approx_equal(result.b_cart(), b_cart, tolerance)
            if (flag == True and approx_equal(b_cart, b_cart_1, out=None)):
                for u2, ufm in zip(b_cart_2, result.b_cart()):
                    if (abs(u2) < 1.e-6):
                        assert approx_equal(ufm, 0.0, tolerance)
def exercise_01_general(d_mins = [1.6,],
             solvkb = [(0,0),(0.1,80.0),(0.6,10.0),(0.1,10.0),(0.6,80.0),
                       (0.1,6.),(0.12,89.),(0.57,17.),(0.14,14.),(0.54,87.)],
             b_carts = [(4., 10., -14., 0, 5., 0.),
                        (0., 0., 0., 0., 0., 0.)],
             nproc=None):
  xray_structure = get_xray_structure_from_file()
  for fast in [True, False]:
    for d_min in d_mins:
      for kb in solvkb:
        for b_cart in b_carts:
          f_obs, r_free_flags = \
            get_f_obs_freer(d_min  = d_min,
                            k_sol  = kb[0],
                            b_sol  = kb[1],
                            b_cart = b_cart,
                            xray_structure = xray_structure)
          #
          bin_selections = []
          f_obs.setup_binner(reflections_per_bin=50)
          for i_bin in f_obs.binner().range_used():
            sel = f_obs.binner().selection(i_bin)
            bin_selections.append(sel)
          #
          fmodel = mmtbx.f_model.manager(
            r_free_flags   = r_free_flags,
            f_obs          = f_obs,
            xray_structure = xray_structure,
            bin_selections = bin_selections)
          fmodel.update_solvent_and_scale(nproc=nproc, fast=fast)
          result = bss.bulk_solvent_and_scales(
            fmodel_kbu = fmodel.fmodel_kbu(), nproc = nproc)
          if(not fast):
            assert approx_equal(fmodel.r_work(), result.fmodels.r_factor())
          else:
            assert fmodel.r_work() < 0.005
          assert approx_equal(result.fmodels.r_factor(), 0.0, eps = 1.e-6)
          assert approx_equal(result.k_sol(0), kb[0],  eps = 1.e-6)
          assert approx_equal(result.b_sol(),  kb[1],  eps = 1.e-6)
          assert approx_equal(result.b_cart(), b_cart, eps = 1.e-6)
def exercise_05_k_sol_b_sol_only(d_min = 2.0):
  xray_structure = get_xray_structure_from_file()
  k_sol = 0.33
  b_sol = 34.0
  b_cart = [1,2,3,0,4,0]
  f_obs, r_free_flags = get_f_obs_freer(
    d_min  = d_min,
    k_sol  = k_sol,
    b_sol  = b_sol,
    b_cart = b_cart,
    xray_structure = xray_structure)
  fmodel = mmtbx.f_model.manager(
    r_free_flags   = r_free_flags,
    f_obs          = f_obs,
    xray_structure = xray_structure)
  params = bss.master_params.extract()
  params.anisotropic_scaling = False
  u_star = adptbx.u_cart_as_u_star(
    fmodel.f_obs().unit_cell(),adptbx.b_as_u(b_cart))
  fmodel_kbu = mmtbx.f_model.manager_kbu(
    f_obs   = fmodel.f_obs(),
    f_calc  = fmodel.f_calc(),
    f_masks = fmodel.arrays.core.f_masks,
    f_part1 = fmodel.arrays.core.f_part1,
    f_part2 = fmodel.arrays.core.f_part2,
    ss      = fmodel.ss,
    u_star  = u_star)
  r_work_start = fmodel_kbu.r_factor()
  result = bss.bulk_solvent_and_scales(
    fmodel_kbu = fmodel_kbu, params = params)
  r_work = result.fmodels.r_factor()*100.
  assert r_work_start > 0.05
  assert approx_equal(r_work,          0.0,    eps = 1.e-6)
  assert approx_equal(result.k_sol(0), k_sol,  eps = 1.e-6)
  assert approx_equal(result.b_sol(),  b_sol,  eps = 1.e-6)
  assert approx_equal(result.b_cart(), b_cart, eps = 1.e-6)
 def update_solvent_and_scale_2(self, fast, params, apply_back_trace,
                                refine_hd_scattering, log):
   if(params is None): params = bss.master_params.extract()
   if(self.xray_structure is not None):
     # Figure out Fcalc and Fmask based on presence of H
     hd_selection = self.xray_structure.hd_selection()
     xrs_no_h = self.xray_structure.select(~hd_selection)
     xrs_h    = self.xray_structure.select(hd_selection)
   # Create data container for scalers. If H scattering is refined then it is
   # assumed that self.f_calc() does not contain H contribution at all.
   fmodel_kbu = mmtbx.f_model.manager_kbu(
     f_obs   = self.f_obs(),
     f_calc  = self.f_calc(),
     f_masks = self.f_masks(),
     ss      = self.ss)
   # Compute k_total and k_mask using one of the two methods (anal or min).
   # Note: this intentionally ignores previously existing f_part1 and f_part2.
   #
   k_sol, b_sol, b_cart, b_adj = [None,]*4
   if(fast): # analytical
     assert len(fmodel_kbu.f_masks)==1
     result = mmtbx.bulk_solvent.scaler.run_simple(
       fmodel_kbu     = fmodel_kbu,
       r_free_flags   = self.r_free_flags(),
       bulk_solvent   = params.bulk_solvent,
       bin_selections = self.bin_selections)
     r_all_from_scaler = result.r_all() # must be here, before apply_back_trace
   else: # using minimization: exp solvent and scale model (k_sol,b_sol,b_cart)
     result = bss.bulk_solvent_and_scales(
       fmodel_kbu = fmodel_kbu,
       params     = params)
     k_sol, b_sol, b_cart = result.k_sols(), result.b_sols(), result.b_cart()
     r_all_from_scaler = result.r_all() # must be here, before apply_back_trace
   if(apply_back_trace and len(fmodel_kbu.f_masks)==1 and
      self.xray_structure is not None):
     o = result.apply_back_trace_of_overall_exp_scale_matrix(
       xray_structure = self.xray_structure)
     b_adj = o.b_adj
     if(not fast): b_sol, b_cart = [o.b_sol], o.b_cart
     self.update_xray_structure(
       xray_structure = o.xray_structure,
       update_f_calc  = True)
     fmodel_kbu = fmodel_kbu.update(f_calc = self.f_calc())
     self.show(prefix = "overall B=%s to atoms"%str("%7.2f"%o.b_adj).strip(),
       log = log)
   # Update self with new arrays so that H correction knows current R factor.
   # If no H to account for, then this is the final result.
   k_masks       = result.k_masks()
   k_anisotropic = result.k_anisotropic()
   k_isotropic   = result.k_isotropic()
   self.update_core(
     k_mask        = k_masks,
     k_anisotropic = k_anisotropic,
     k_isotropic   = k_isotropic)
   self.show(prefix = "bulk-solvent and scaling", log = log)
   # Consistency check
   assert approx_equal(self.r_all(), r_all_from_scaler)
   # Add contribution from H (if present and riding). This goes to f_part2.
   kh, bh = 0, 0
   if(refine_hd_scattering and
      self.need_to_refine_hd_scattering_contribution()):
     # Obsolete previous contribution f_part2
     f_part2 = fmodel_kbu.f_calc.array(data=fmodel_kbu.f_calc.data()*0)
     self.update_core(f_part2 = f_part2)
     xrs_h = xrs_h.set_occupancies(value=1).set_b_iso(value = 0)
     f_h = self.compute_f_calc(xray_structure = xrs_h)
     # Accumulate all mask contributions: Fcalc_atoms+Fbulk_1+...+Fbulk_N
     data = fmodel_kbu.f_calc.data()
     for k_mask_, f_mask_ in zip(k_masks, fmodel_kbu.f_masks):
       data = data + k_mask_*f_mask_.data()
     f_calc_plus_f_bulk_no_scales = fmodel_kbu.f_calc.array(data = data)
     # Consistency check
     assert approx_equal(self.f_model().data(),
       f_calc_plus_f_bulk_no_scales.data()*k_isotropic*k_anisotropic)
     assert approx_equal(self.f_model_no_scales().data(),
       f_calc_plus_f_bulk_no_scales.data())
     #
     # Compute contribution from H (F_H)
     #
     # Coarse sampling
     b_mean = flex.mean(xrs_no_h.extract_u_iso_or_u_equiv())*adptbx.u_as_b(1.)
     b_min = int(max(0,b_mean)*0.5)
     b_max = int(b_mean*1.5)
     sc = 1000.
     kr=[i/sc for i in range(ifloor(0*sc), iceil(1.5*sc)+1, int(0.1*sc))]
     br=[i/sc for i in range(ifloor(b_min*sc), iceil(b_max*sc)+1, int(5.*sc))]
     o = bulk_solvent.k_sol_b_sol_k_anisotropic_scaler_twin(
       f_obs       = fmodel_kbu.f_obs.data(),
       f_calc      = f_calc_plus_f_bulk_no_scales.data(),
       f_mask      = f_h.data(),
       k_total     = k_isotropic*k_anisotropic,
       ss          = fmodel_kbu.ss,
       k_sol_range = flex.double(kr),
       b_sol_range = flex.double(br),
       r_ref       = self.r_work())
     if(o.updated()):
       f_part2 = f_h.array(data = o.k_mask()*f_h.data())
       kh, bh = o.k_sol(), o.b_sol()
       self.show(prefix = "add H (%4.2f, %6.2f)"%(kh, bh), log = log, r=o.r())
     # Fine sampling
     k_min = max(0,o.k_sol()-0.1)
     k_max = o.k_sol()+0.1
     b_min = max(0,o.b_sol()-5.)
     b_max = o.b_sol()+5.
     kr=[i/sc for i in range(ifloor(k_min*sc),iceil(k_max*sc)+1,int(0.01*sc))]
     br=[i/sc for i in range(ifloor(b_min*sc),iceil(b_max*sc)+1,int(1.*sc))]
     o = bulk_solvent.k_sol_b_sol_k_anisotropic_scaler_twin(
       f_obs       = fmodel_kbu.f_obs.data(),
       f_calc      = f_calc_plus_f_bulk_no_scales.data(),
       f_mask      = f_h.data(),
       k_total     = k_isotropic*k_anisotropic,
       ss          = fmodel_kbu.ss,
       k_sol_range = flex.double(kr),
       b_sol_range = flex.double(br),
       r_ref       = o.r())
     if(o.updated()):
       f_part2 = f_h.array(data = o.k_mask()*f_h.data())
       kh, bh = o.k_sol(), o.b_sol()
       self.show(prefix = "add H (%4.2f, %6.2f)"%(kh, bh), log = log, r=o.r())
     # THIS HELPS if fast=true is used, see how it works in reality
     #
     if(fast):
       fmodel_kbu_ = mmtbx.f_model.manager_kbu(
         f_obs   = self.f_obs(),
         f_calc  = f_calc_plus_f_bulk_no_scales,
         f_masks = [f_part2],
         ss      = self.ss)
       result = mmtbx.bulk_solvent.scaler.run_simple(
         fmodel_kbu     = fmodel_kbu_,
         r_free_flags   = self.r_free_flags(),
         bulk_solvent   = params.bulk_solvent,
         bin_selections = self.bin_selections)
       f_part2 = f_part2.array(data = result.core.k_mask()*f_part2.data())
       k_isotropic   = result.core.k_isotropic*result.core.k_isotropic_exp
       k_anisotropic = result.core.k_anisotropic
     # Update self with final scales
     self.update_core(
       k_mask        = k_masks,
       k_anisotropic = k_anisotropic,
       k_isotropic   = k_isotropic,
       f_part2       = f_part2)
     # Make sure what came out of scaling matches what self thinks it really is
     # It must match at least up to 1.e-6.
     self.show(prefix = "add H (%4.2f, %6.2f)"%(kh, bh), log = log)
     if(fast):
       assert approx_equal(result.r_factor(), self.r_work())
     else:
       assert approx_equal(self.r_all(), o.r()), [self.r_all(), o.r()]
   return group_args(
     k_sol  = k_sol,
     b_sol  = b_sol,
     b_cart = b_cart,
     k_h    = kh,
     b_h    = bh,
     b_adj  = b_adj)
Пример #12
0
 def update_solvent_and_scale_2(self, fast, params, apply_back_trace,
                                refine_hd_scattering, log):
     if (params is None): params = bss.master_params.extract()
     if (self.xray_structure is not None):
         # Figure out Fcalc and Fmask based on presence of H
         hd_selection = self.xray_structure.hd_selection()
         xrs_no_h = self.xray_structure.select(~hd_selection)
         xrs_h = self.xray_structure.select(hd_selection)
     # Create data container for scalers. If H scattering is refined then it is
     # assumed that self.f_calc() does not contain H contribution at all.
     fmodel_kbu = mmtbx.f_model.manager_kbu(f_obs=self.f_obs(),
                                            f_calc=self.f_calc(),
                                            f_masks=self.f_masks(),
                                            ss=self.ss)
     # Compute k_total and k_mask using one of the two methods (anal or min).
     # Note: this intentionally ignores previously existing f_part1 and f_part2.
     #
     k_sol, b_sol, b_cart, b_adj = [
         None,
     ] * 4
     if (fast):  # analytical
         assert len(fmodel_kbu.f_masks) == 1
         result = mmtbx.bulk_solvent.scaler.run_simple(
             fmodel_kbu=fmodel_kbu,
             r_free_flags=self.r_free_flags(),
             bulk_solvent=params.bulk_solvent,
             bin_selections=self.bin_selections)
         r_all_from_scaler = result.r_all(
         )  # must be here, before apply_back_trace
     else:  # using minimization: exp solvent and scale model (k_sol,b_sol,b_cart)
         result = bss.bulk_solvent_and_scales(fmodel_kbu=fmodel_kbu,
                                              params=params)
         k_sol, b_sol, b_cart = result.k_sols(), result.b_sols(
         ), result.b_cart()
         r_all_from_scaler = result.r_all(
         )  # must be here, before apply_back_trace
     if (apply_back_trace and len(fmodel_kbu.f_masks) == 1
             and self.xray_structure is not None):
         o = result.apply_back_trace_of_overall_exp_scale_matrix(
             xray_structure=self.xray_structure)
         b_adj = o.b_adj
         if (not fast): b_sol, b_cart = [o.b_sol], o.b_cart
         self.update_xray_structure(xray_structure=o.xray_structure,
                                    update_f_calc=True)
         fmodel_kbu = fmodel_kbu.update(f_calc=self.f_calc())
         self.show(prefix="overall B=%s to atoms" %
                   str("%7.2f" % o.b_adj).strip(),
                   log=log)
     # Update self with new arrays so that H correction knows current R factor.
     # If no H to account for, then this is the final result.
     k_masks = result.k_masks()
     k_anisotropic = result.k_anisotropic()
     k_isotropic = result.k_isotropic()
     self.update_core(k_mask=k_masks,
                      k_anisotropic=k_anisotropic,
                      k_isotropic=k_isotropic)
     self.show(prefix="bulk-solvent and scaling", log=log)
     # Consistency check
     if (not apply_back_trace):
         assert approx_equal(self.r_all(), r_all_from_scaler)
     # Add contribution from H (if present and riding). This goes to f_part2.
     kh, bh = 0, 0
     if (refine_hd_scattering
             and self.need_to_refine_hd_scattering_contribution()):
         # Obsolete previous contribution f_part2
         f_part2 = fmodel_kbu.f_calc.array(data=fmodel_kbu.f_calc.data() *
                                           0)
         self.update_core(f_part2=f_part2)
         xrs_h = xrs_h.set_occupancies(value=1).set_b_iso(value=0)
         f_h = self.compute_f_calc(xray_structure=xrs_h)
         # Accumulate all mask contributions: Fcalc_atoms+Fbulk_1+...+Fbulk_N
         data = fmodel_kbu.f_calc.data()
         for k_mask_, f_mask_ in zip(k_masks, fmodel_kbu.f_masks):
             data = data + k_mask_ * f_mask_.data()
         f_calc_plus_f_bulk_no_scales = fmodel_kbu.f_calc.array(data=data)
         # Consistency check
         assert approx_equal(
             self.f_model().data(),
             f_calc_plus_f_bulk_no_scales.data() * k_isotropic *
             k_anisotropic)
         assert approx_equal(self.f_model_no_scales().data(),
                             f_calc_plus_f_bulk_no_scales.data())
         #
         # Compute contribution from H (F_H)
         #
         # Coarse sampling
         b_mean = flex.mean(
             xrs_no_h.extract_u_iso_or_u_equiv()) * adptbx.u_as_b(1.)
         b_min = int(max(0, b_mean) * 0.5)
         b_max = int(b_mean * 1.5)
         sc = 1000.
         kr = [
             i / sc for i in range(ifloor(0 * sc),
                                   iceil(1.5 * sc) + 1, int(0.1 * sc))
         ]
         br = [
             i / sc for i in range(ifloor(b_min * sc),
                                   iceil(b_max * sc) + 1, int(5. * sc))
         ]
         o = bulk_solvent.k_sol_b_sol_k_anisotropic_scaler_twin(
             f_obs=fmodel_kbu.f_obs.data(),
             f_calc=f_calc_plus_f_bulk_no_scales.data(),
             f_mask=f_h.data(),
             k_total=k_isotropic * k_anisotropic,
             ss=fmodel_kbu.ss,
             k_sol_range=flex.double(kr),
             b_sol_range=flex.double(br),
             r_ref=self.r_work())
         if (o.updated()):
             f_part2 = f_h.array(data=o.k_mask() * f_h.data())
             kh, bh = o.k_sol(), o.b_sol()
             self.show(prefix="add H (%4.2f, %6.2f)" % (kh, bh),
                       log=log,
                       r=o.r())
         # Fine sampling
         k_min = max(0, o.k_sol() - 0.1)
         k_max = o.k_sol() + 0.1
         b_min = max(0, o.b_sol() - 5.)
         b_max = o.b_sol() + 5.
         kr = [
             i / sc for i in range(ifloor(k_min * sc),
                                   iceil(k_max * sc) + 1, int(0.01 * sc))
         ]
         br = [
             i / sc for i in range(ifloor(b_min * sc),
                                   iceil(b_max * sc) + 1, int(1. * sc))
         ]
         o = bulk_solvent.k_sol_b_sol_k_anisotropic_scaler_twin(
             f_obs=fmodel_kbu.f_obs.data(),
             f_calc=f_calc_plus_f_bulk_no_scales.data(),
             f_mask=f_h.data(),
             k_total=k_isotropic * k_anisotropic,
             ss=fmodel_kbu.ss,
             k_sol_range=flex.double(kr),
             b_sol_range=flex.double(br),
             r_ref=o.r())
         if (o.updated()):
             f_part2 = f_h.array(data=o.k_mask() * f_h.data())
             kh, bh = o.k_sol(), o.b_sol()
             self.show(prefix="add H (%4.2f, %6.2f)" % (kh, bh),
                       log=log,
                       r=o.r())
         # THIS HELPS if fast=true is used, see how it works in reality
         #
         if (fast):
             fmodel_kbu_ = mmtbx.f_model.manager_kbu(
                 f_obs=self.f_obs(),
                 f_calc=f_calc_plus_f_bulk_no_scales,
                 f_masks=[f_part2],
                 ss=self.ss)
             result = mmtbx.bulk_solvent.scaler.run_simple(
                 fmodel_kbu=fmodel_kbu_,
                 r_free_flags=self.r_free_flags(),
                 bulk_solvent=params.bulk_solvent,
                 bin_selections=self.bin_selections)
             f_part2 = f_part2.array(data=result.core.k_mask() *
                                     f_part2.data())
             k_isotropic = result.core.k_isotropic * result.core.k_isotropic_exp
             k_anisotropic = result.core.k_anisotropic
         # Update self with final scales
         self.update_core(k_mask=k_masks,
                          k_anisotropic=k_anisotropic,
                          k_isotropic=k_isotropic,
                          f_part2=f_part2)
         # Make sure what came out of scaling matches what self thinks it really is
         # It must match at least up to 1.e-6.
         self.show(prefix="add H (%4.2f, %6.2f)" % (kh, bh), log=log)
         if (fast):
             assert approx_equal(result.r_work(), self.r_work(), 1.e-4)
         else:
             assert approx_equal(self.r_all(), o.r()), [self.r_all(), o.r()]
     return group_args(k_sol=k_sol,
                       b_sol=b_sol,
                       b_cart=b_cart,
                       k_h=kh,
                       b_h=bh,
                       b_adj=b_adj)
def exercise_radial_shells(k_sol=0.33,
                           d_min=1.5,
                           grid_search=False,
                           shell_width=0.6):
    xray_structure = get_xray_structure_from_file()
    b_sol = 34.0
    if (type(k_sol) is list):
        b_sol = [
            b_sol,
        ] * len(k_sol)
    b_cart = [1, 2, 3, 0, 4, 0]
    f_obs, r_free_flags = get_f_obs_freer(d_min=d_min,
                                          k_sol=k_sol,
                                          b_sol=b_sol,
                                          b_cart=b_cart,
                                          xray_structure=xray_structure,
                                          radial_shell_width=shell_width)
    mask_params = mmtbx.masks.mask_master_params.extract()
    mask_params.radial_shell_width = shell_width
    if (type(k_sol) is list):
        mask_params.n_radial_shells = len(k_sol)
    else:
        mask_params.n_radial_shells = 2
    fmodel = mmtbx.f_model.manager(r_free_flags=r_free_flags,
                                   f_obs=f_obs,
                                   xray_structure=xray_structure,
                                   mask_params=mask_params)
    u_star = adptbx.u_cart_as_u_star(fmodel.f_obs().unit_cell(),
                                     adptbx.b_as_u(b_cart))
    fmodel_kbu = fmodel.fmodel_kbu()
    fmodel_kbu.update(u_star=u_star)
    r_work_start = fmodel_kbu.r_factor() * 100.
    msk = fmodel.mask_manager
    print 'Solvent content: ', msk.solvent_content_via_mask
    print 'Layer volume fractions: ', msk.layer_volume_fractions
    if (type(k_sol) is list):
        for i in range(len(k_sol)):
            if (msk.layer_volume_fractions[i] == 0.):
                k_sol[i] = 0.
    params = bss.master_params.extract()
    params.anisotropic_scaling = False
    params.k_sol_b_sol_grid_search = grid_search
    params.number_of_macro_cycles = 10
    params.k_sol_max = 1.2
    result = bss.bulk_solvent_and_scales(fmodel_kbu=fmodel_kbu, params=params)
    r_work = result.fmodel_kbu.r_factor()
    print 'R-work: ', r_work
    print 'Solvent radius: ', fmodel.mask_params.solvent_radius
    assert r_work_start > 0.0
    assert approx_equal(r_work, 0.0, eps=1.e-3)
    if (type(k_sol) is list):
        ksols = list(result.fmodel_kbu.k_sols())
        # XXX if layer_volume_fractions=0, then ksol is more or less undefined ?
        # XXX should it be done in bulk_solvent_and_scaling.py ?
        for i in range(len(ksols)):
            if (msk.layer_volume_fractions[i] == 0.):
                ksols[i] = 0.
        assert len(k_sol) == len(ksols)
        for ik in range(len(k_sol)):
            assert approx_equal(ksols[ik], k_sol[ik],
                                eps=0.005), [ksols[ik], k_sol[ik]]
    else:
        for ksol in result.fmodel_kbu.k_sols():
            assert approx_equal(ksol, k_sol, eps=1.e-3)
    n = len(result.b_sols())
    if (n > 1 and type(b_sol) is float): b_sol = [
            b_sol,
    ] * n
    assert approx_equal(result.b_sols(), b_sol, eps=1.)
    assert approx_equal(result.b_cart(), b_cart, eps=1.e-6)
def exercise_radial_shells(k_sol=0.33,d_min=2,grid_search=False,shell_width=0.3):
  xray_structure = get_xray_structure_from_file()
  b_sol = 34.0
  b_cart = [1,2,3,0,4,0]
  f_obs, r_free_flags = get_f_obs_freer(
    d_min  = d_min,
    k_sol  = k_sol,
    b_sol  = b_sol,
    b_cart = b_cart,
    xray_structure = xray_structure,
    radial_shell_width=shell_width)
  mask_params = mmtbx.masks.mask_master_params.extract()
  mask_params.radial_shell_width = shell_width
  if( type(k_sol) is list ):
    mask_params.n_radial_shells = len(k_sol)
  else:
    mask_params.n_radial_shells = 2
  fmodel = mmtbx.f_model.manager(
    r_free_flags   = r_free_flags,
    f_obs          = f_obs,
    xray_structure = xray_structure,
    mask_params    = mask_params)
  u_star = adptbx.u_cart_as_u_star(
    fmodel.f_obs().unit_cell(),adptbx.b_as_u(b_cart))
  fmodel_kbu = fmodel.fmodel_kbu()
  fmodel_kbu.update(u_star = u_star)
  r_work_start = fmodel_kbu.r_factor()*100.
  msk = fmodel.mask_manager
  print 'Solvent content: ', msk.solvent_content_via_mask
  print 'Layer volume fractions: ', msk.layer_volume_fractions
  if( type(k_sol) is list):
    for i in range(len(k_sol)):
      if( msk.layer_volume_fractions[i] == 0. ):
        k_sol[i] = 0.
  params = bss.master_params.extract()
  params.anisotropic_scaling = False
  params.k_sol_b_sol_grid_search = grid_search
  if( not params.k_sol_b_sol_grid_search ):
    params.number_of_macro_cycles = 3
  params.k_sol_max = 1.2
  result = bss.bulk_solvent_and_scales(
    fmodel_kbu = fmodel_kbu, params = params)
  r_work = result.fmodels.r_factor()
  print 'R-work: ', r_work
  print 'Solvent radius: ', fmodel.mask_params.solvent_radius
  assert r_work_start > 0.0
  assert approx_equal(r_work, 0.0, eps = 1.e-4)
  if( type(k_sol) is list ):
    ksols = list(result.fmodels.fmodel.k_sols())
    # XXX if layer_volume_fractions=0, then ksol is more or less undefined ?
    # XXX should it be done in bulk_solvent_and_scaling.py ?
    for i in range(len(ksols)):
      if(msk.layer_volume_fractions[i] == 0.):
        ksols[i] = 0.
    assert len(k_sol) == len(ksols)
    for ik in range(len(k_sol)):
      assert approx_equal(ksols[ik], k_sol[ik], eps=1.e-6)
  else:
    for ksol in result.fmodels.fmodel.k_sols():
      assert approx_equal(ksol,   k_sol, eps = 1.e-6)
  assert approx_equal(result.b_sol(),   b_sol, eps = 1.e-6)
  assert approx_equal(result.b_cart(), b_cart, eps = 1.e-6)