def exercise_tensor_constraints_core(crystal_symmetry):
  from cctbx import crystal
  from cctbx import adptbx
  from scitbx import matrix
  site_symmetry = crystal.special_position_settings(
    crystal_symmetry).site_symmetry(site=(0,0,0))
  unit_cell = crystal_symmetry.unit_cell()
  group = crystal_symmetry.space_group()
  assert site_symmetry.n_matrices() == group.order_p()
  for reciprocal_space in [False, True]:
    c_tensor_constraints = sgtbx.tensor_rank_2_constraints(
      space_group=group,
      reciprocal_space=reciprocal_space).row_echelon_form()
    p_tensor_constraints = python_tensor_constraints(
      self=group, reciprocal_space=reciprocal_space)
    assert c_tensor_constraints.all_eq(p_tensor_constraints)
  adp_constraints = group.adp_constraints()
  u_cart_p1 = adptbx.random_u_cart()
  u_star_p1 = adptbx.u_cart_as_u_star(unit_cell, u_cart_p1)
  u_star = site_symmetry.average_u_star(u_star_p1)
  f = unit_cell.volume()**(2/3.)
  assert approx_equal(
    list(matrix.col(group.average_u_star(u_star=u_star_p1))*f),
    list(matrix.col(u_star)*f))
  independent_params = adp_constraints.independent_params(u_star)
  assert adp_constraints.n_independent_params() == len(independent_params)
  assert adp_constraints.n_independent_params() \
       + adp_constraints.n_dependent_params() == 6
  u_star_vfy = adp_constraints.all_params(independent_params)
  u_cart = adptbx.u_star_as_u_cart(unit_cell, u_star)
  u_cart_vfy = adptbx.u_star_as_u_cart(unit_cell, list(u_star_vfy))
  assert approx_equal(u_cart_vfy, u_cart)
Beispiel #2
0
def exercise_tensor_constraints_core(crystal_symmetry):
    from cctbx import crystal
    from cctbx import adptbx
    from scitbx import matrix
    site_symmetry = crystal.special_position_settings(
        crystal_symmetry).site_symmetry(site=(0, 0, 0))
    unit_cell = crystal_symmetry.unit_cell()
    group = crystal_symmetry.space_group()
    assert site_symmetry.n_matrices() == group.order_p()
    for reciprocal_space in [False, True]:
        c_tensor_constraints = sgtbx.tensor_rank_2_constraints(
            space_group=group,
            reciprocal_space=reciprocal_space).row_echelon_form()
        p_tensor_constraints = python_tensor_constraints(
            self=group, reciprocal_space=reciprocal_space)
        assert c_tensor_constraints.all_eq(p_tensor_constraints)
    adp_constraints = group.adp_constraints()
    u_cart_p1 = adptbx.random_u_cart()
    u_star_p1 = adptbx.u_cart_as_u_star(unit_cell, u_cart_p1)
    u_star = site_symmetry.average_u_star(u_star_p1)
    f = unit_cell.volume()**(2 / 3.)
    assert approx_equal(
        list(matrix.col(group.average_u_star(u_star=u_star_p1)) * f),
        list(matrix.col(u_star) * f))
    independent_params = adp_constraints.independent_params(u_star)
    assert adp_constraints.n_independent_params() == len(independent_params)
    assert adp_constraints.n_independent_params() \
         + adp_constraints.n_dependent_params() == 6
    u_star_vfy = adp_constraints.all_params(independent_params)
    u_cart = adptbx.u_star_as_u_cart(unit_cell, u_star)
    u_cart_vfy = adptbx.u_star_as_u_cart(unit_cell, list(u_star_vfy))
    assert approx_equal(u_cart_vfy, u_cart)
def run_00():
    time_aniso_u_scaler = 0
    for symbol in sgtbx.bravais_types.acentric + sgtbx.bravais_types.centric:
        #print symbol, "-"*50
        space_group_info = sgtbx.space_group_info(symbol=symbol)
        xrs = random_structure.xray_structure(
            space_group_info=space_group_info,
            elements=["N"] * 100,
            volume_per_atom=50.0,
            random_u_iso=True)
        # XXX ad a method to adptbx to do this
        point_group = sgtbx.space_group_info(
            symbol=symbol).group().build_derived_point_group()
        adp_constraints = sgtbx.tensor_rank_2_constraints(
            space_group=point_group, reciprocal_space=True)
        u_star = adptbx.u_cart_as_u_star(
            xrs.unit_cell(), adptbx.random_u_cart(u_scale=1, u_min=0.1))
        u_indep = adp_constraints.independent_params(all_params=u_star)
        u_star = adp_constraints.all_params(independent_params=u_indep)
        b_cart_start = adptbx.u_as_b(
            adptbx.u_star_as_u_cart(xrs.unit_cell(), u_star))
        #
        tr = (b_cart_start[0] + b_cart_start[1] + b_cart_start[2]) / 3
        b_cart_start = [
            b_cart_start[0] - tr, b_cart_start[1] - tr, b_cart_start[2] - tr,
            b_cart_start[3], b_cart_start[4], b_cart_start[5]
        ]
        tr = (b_cart_start[0] + b_cart_start[1] + b_cart_start[2]) / 3
        #
        #print "Input b_cart :", " ".join(["%8.4f"%i for i in b_cart_start]), "tr:", tr
        F = xrs.structure_factors(d_min=2.0).f_calc()
        u_star = adptbx.u_cart_as_u_star(F.unit_cell(),
                                         adptbx.b_as_u(b_cart_start))
        fbc = mmtbx.f_model.ext.k_anisotropic(F.indices(), u_star)
        fc = F.structure_factors_from_scatterers(xray_structure=xrs).f_calc()
        f_obs = F.customized_copy(data=flex.abs(fc.data() * fbc))
        t0 = time.time()
        #
        obj = bulk_solvent.aniso_u_scaler(
            f_model_abs=flex.abs(fc.data()),
            f_obs=f_obs.data(),
            miller_indices=f_obs.indices(),
            adp_constraint_matrix=adp_constraints.gradient_sum_matrix())
        time_aniso_u_scaler += (time.time() - t0)
        b_cart_final = adptbx.u_as_b(
            adptbx.u_star_as_u_cart(
                f_obs.unit_cell(),
                adp_constraints.all_params(tuple(obj.u_star_independent))))
        #
        obj = bulk_solvent.aniso_u_scaler(f_model_abs=flex.abs(fc.data()),
                                          f_obs=f_obs.data(),
                                          miller_indices=f_obs.indices())
        b_cart_final2 = adptbx.u_as_b(
            adptbx.u_star_as_u_cart(f_obs.unit_cell(), tuple(obj.u_star)))
        #
        assert approx_equal(b_cart_final, b_cart_final2)
        #print "Output b_cart:", " ".join(["%8.4f"%i for i in b_cart_final])
        assert approx_equal(b_cart_start, b_cart_final, 1.e-4)
    print("Time (aniso_u_scaler only): %6.4f" % time_aniso_u_scaler)
def run_00():
  time_aniso_u_scaler = 0
  for symbol in sgtbx.bravais_types.acentric + sgtbx.bravais_types.centric:
    #print symbol, "-"*50
    space_group_info = sgtbx.space_group_info(symbol = symbol)
    xrs = random_structure.xray_structure(
      space_group_info  = space_group_info,
      elements          = ["N"]*100,
      volume_per_atom   = 50.0,
      random_u_iso      = True)
    # XXX ad a method to adptbx to do this
    point_group = sgtbx.space_group_info(
      symbol=symbol).group().build_derived_point_group()
    adp_constraints = sgtbx.tensor_rank_2_constraints(
      space_group=point_group,
      reciprocal_space=True)
    u_star = adptbx.u_cart_as_u_star(xrs.unit_cell(),
      adptbx.random_u_cart(u_scale=1,u_min=0.1))
    u_indep = adp_constraints.independent_params(all_params=u_star)
    u_star = adp_constraints.all_params(independent_params=u_indep)
    b_cart_start=adptbx.u_as_b(adptbx.u_star_as_u_cart(xrs.unit_cell(), u_star))
    #
    tr = (b_cart_start[0]+b_cart_start[1]+b_cart_start[2])/3
    b_cart_start = [b_cart_start[0]-tr,b_cart_start[1]-tr,b_cart_start[2]-tr,
           b_cart_start[3],b_cart_start[4],b_cart_start[5]]
    tr = (b_cart_start[0]+b_cart_start[1]+b_cart_start[2])/3
    #
    #print "Input b_cart :", " ".join(["%8.4f"%i for i in b_cart_start]), "tr:", tr
    F = xrs.structure_factors(d_min = 2.0).f_calc()
    u_star = adptbx.u_cart_as_u_star(
      F.unit_cell(), adptbx.b_as_u(b_cart_start))
    fbc = mmtbx.f_model.ext.k_anisotropic(F.indices(), u_star)
    fc = F.structure_factors_from_scatterers(xray_structure=xrs).f_calc()
    f_obs = F.customized_copy(data = flex.abs(fc.data()*fbc))
    t0 = time.time()
    #
    obj = bulk_solvent.aniso_u_scaler(
      f_model_abs    = flex.abs(fc.data()),
      f_obs          = f_obs.data(),
      miller_indices = f_obs.indices(),
      adp_constraint_matrix = adp_constraints.gradient_sum_matrix())
    time_aniso_u_scaler += (time.time()-t0)
    b_cart_final = adptbx.u_as_b(adptbx.u_star_as_u_cart(f_obs.unit_cell(),
      adp_constraints.all_params(tuple(obj.u_star_independent))))
    #
    obj = bulk_solvent.aniso_u_scaler(
      f_model_abs    = flex.abs(fc.data()),
      f_obs          = f_obs.data(),
      miller_indices = f_obs.indices())
    b_cart_final2 = adptbx.u_as_b(adptbx.u_star_as_u_cart(f_obs.unit_cell(),
      tuple(obj.u_star)))
    #
    assert approx_equal(b_cart_final, b_cart_final2)
    #print "Output b_cart:", " ".join(["%8.4f"%i for i in b_cart_final])
    assert approx_equal(b_cart_start, b_cart_final, 1.e-4)
  print "Time (aniso_u_scaler only): %6.4f"%time_aniso_u_scaler
def ru(crystal_symmetry, u_scale=1, u_min=0.1):
    from cctbx import sgtbx
    symbol = crystal_symmetry.space_group().type().lookup_symbol()
    point_group = sgtbx.space_group_info(
        symbol=symbol).group().build_derived_point_group()
    adp_constraints = sgtbx.tensor_rank_2_constraints(space_group=point_group,
                                                      reciprocal_space=True)
    u_star = adptbx.u_cart_as_u_star(
        crystal_symmetry.unit_cell(),
        adptbx.random_u_cart(u_scale=u_scale, u_min=u_min))
    u_indep = adp_constraints.independent_params(all_params=u_star)
    u_star = adp_constraints.all_params(independent_params=u_indep)
    r = flex.sym_mat3_double()
    r.append(adptbx.u_star_as_u_cart(crystal_symmetry.unit_cell(), u_star))
    return r
def ru(crystal_symmetry, u_scale=1, u_min=0.1):
  from cctbx import sgtbx
  symbol = crystal_symmetry.space_group().type().lookup_symbol()
  point_group = sgtbx.space_group_info(
    symbol=symbol).group().build_derived_point_group()
  adp_constraints = sgtbx.tensor_rank_2_constraints(
    space_group=point_group,
    reciprocal_space=True)
  u_star = adptbx.u_cart_as_u_star(crystal_symmetry.unit_cell(),
    adptbx.random_u_cart(u_scale=u_scale,u_min=u_min))
  u_indep = adp_constraints.independent_params(all_params=u_star)
  u_star = adp_constraints.all_params(independent_params=u_indep)
  r = flex.sym_mat3_double()
  r.append(adptbx.u_star_as_u_cart(crystal_symmetry.unit_cell(), u_star))
  return r
Beispiel #7
0
    def calc_debye_waller_factor(self, observations, b_cart):
        #apply space-group constraints on B-tensor
        space_group = self.observations.space_group()
        adp_constraints = sgtbx.tensor_rank_2_constraints(
            space_group=space_group, reciprocal_space=True)
        #convert B tensor direct-space to reciprocal space
        fmx = sqr(self.unit_cell.fractionalization_matrix())
        u_cart = b_cart / (8 * math.pi**2)
        u_star_mat = fmx * u_cart * fmx.transpose()
        u_star = u_star_mat.as_sym_mat3()
        u_star = space_group.average_u_star(u_star)
        u_indep = adp_constraints.independent_params(all_params=u_star)
        u_star = adp_constraints.all_params(independent_params=u_indep)
        dw_c = adptbx.debye_waller_factor_u_star(observations.indices(),
                                                 u_star)

        return dw_c
Beispiel #8
0
def random_traceless_symmetry_constrained_b_cart(crystal_symmetry, u_scale=1,
      u_min=0.1):
  from cctbx import sgtbx
  symbol = crystal_symmetry.space_group().type().lookup_symbol()
  point_group = sgtbx.space_group_info(
    symbol=symbol).group().build_derived_point_group()
  adp_constraints = sgtbx.tensor_rank_2_constraints(
    space_group=point_group,
    reciprocal_space=True)
  u_star = u_cart_as_u_star(crystal_symmetry.unit_cell(),
    random_u_cart(u_scale=u_scale,u_min=u_min))
  u_indep = adp_constraints.independent_params(all_params=u_star)
  u_star = adp_constraints.all_params(independent_params=u_indep)
  b_cart = u_as_b(u_star_as_u_cart(crystal_symmetry.unit_cell(), u_star))
  tr = (b_cart[0]+b_cart[1]+b_cart[2])/3
  b_cart = [b_cart[0]-tr, b_cart[1]-tr, b_cart[2]-tr,
           b_cart[3],b_cart[4],b_cart[5]]
  return b_cart
Beispiel #9
0
def random_traceless_symmetry_constrained_b_cart(crystal_symmetry, u_scale=1,
      u_min=0.1):
  from cctbx import sgtbx
  symbol = crystal_symmetry.space_group().type().lookup_symbol()
  point_group = sgtbx.space_group_info(
    symbol=symbol).group().build_derived_point_group()
  adp_constraints = sgtbx.tensor_rank_2_constraints(
    space_group=point_group,
    reciprocal_space=True)
  u_star = u_cart_as_u_star(crystal_symmetry.unit_cell(),
    random_u_cart(u_scale=u_scale,u_min=u_min))
  u_indep = adp_constraints.independent_params(all_params=u_star)
  u_star = adp_constraints.all_params(independent_params=u_indep)
  b_cart = u_as_b(u_star_as_u_cart(crystal_symmetry.unit_cell(), u_star))
  tr = (b_cart[0]+b_cart[1]+b_cart[2])/3
  b_cart = [b_cart[0]-tr, b_cart[1]-tr, b_cart[2]-tr,
           b_cart[3],b_cart[4],b_cart[5]]
  return b_cart
  def __init__(self, two_thetas_obs, miller_indices, wavelength, unit_cell,
               space_group=None):
    self.two_thetas_obs = two_thetas_obs
    self.miller_indices = miller_indices
    #self.unit_cell = unit_cell
    self.space_group = space_group
    self.wavelength = wavelength

    if space_group is not None:
      self.constraints = sgtbx.tensor_rank_2_constraints(
        space_group=self.space_group,reciprocal_space=False)
    else:
      self.constraints = None

    if self.space_group is not None:
      unit_cell = self.space_group.average_unit_cell(unit_cell)

    self.x = flex.double(self.reduce(unit_cell.metrical_matrix()))
    self.minimizer = scitbx.lbfgs.run(target_evaluator=self)
def run_02():
    time_aniso_u_scaler = 0
    for symbol in sgtbx.bravais_types.acentric + sgtbx.bravais_types.centric:
        #print symbol, "-"*50
        space_group_info = sgtbx.space_group_info(symbol=symbol)
        xrs = random_structure.xray_structure(
            space_group_info=space_group_info,
            elements=["N"] * 100,
            volume_per_atom=50.0,
            random_u_iso=True)
        xrs.scattering_type_registry(table="wk1995")
        # XXX ad a method to adptbx to do this
        point_group = sgtbx.space_group_info(
            symbol=symbol).group().build_derived_point_group()
        adp_constraints = sgtbx.tensor_rank_2_constraints(
            space_group=point_group, reciprocal_space=True)
        u_star = adptbx.u_cart_as_u_star(
            xrs.unit_cell(), adptbx.random_u_cart(u_scale=1, u_min=0.1))
        u_indep = adp_constraints.independent_params(all_params=u_star)
        u_star = adp_constraints.all_params(independent_params=u_indep)
        b_cart_start = adptbx.u_as_b(
            adptbx.u_star_as_u_cart(xrs.unit_cell(), u_star))
        #
        tr = (b_cart_start[0] + b_cart_start[1] + b_cart_start[2]) / 3
        b_cart_start = [
            b_cart_start[0] - tr, b_cart_start[1] - tr, b_cart_start[2] - tr,
            b_cart_start[3], b_cart_start[4], b_cart_start[5]
        ]
        tr = (b_cart_start[0] + b_cart_start[1] + b_cart_start[2]) / 3
        #
        #print "Input b_cart :", " ".join(["%8.4f"%i for i in b_cart_start]), "tr:", tr
        reg = xrs.scattering_type_registry(table="wk1995", d_min=1 / 12)
        f_000 = reg.sum_of_scattering_factors_at_diffraction_angle_0()
        F = xrs.structure_factors(d_min=2.0).f_calc()
        i = F.indices()
        i.append([0, 0, 0])
        d = F.data()
        d.append(f_000)
        F = F.customized_copy(indices=i, data=d)

        u_star = adptbx.u_cart_as_u_star(F.unit_cell(),
                                         adptbx.b_as_u(b_cart_start))
        fbc = mmtbx.f_model.ext.k_anisotropic(F.indices(), u_star)
        fc = F.structure_factors_from_scatterers(xray_structure=xrs).f_calc()
        f_obs = F.customized_copy(data=flex.abs(fc.data() * fbc))
        #print bulk_solvent.r_factor(f_obs.data(), fmodel.f_model().data())
        obj = bulk_solvent.aniso_u_scaler(f_model_abs=flex.abs(fc.data()),
                                          f_obs=f_obs.data(),
                                          miller_indices=f_obs.indices(),
                                          unit_cell=f_obs.unit_cell())
        a = obj.a
        ####
        #print "Input a :", " ".join(["%7.3f"%i for i in a])
        overall_anisotropic_scale = mmtbx.f_model.ext.k_anisotropic(
            f_obs.indices(), a, f_obs.unit_cell())
        #print bulk_solvent.r_factor(f_obs.data(), fmodel.f_model().data()*overall_anisotropic_scale)
        f_obs = abs(fc)
        f_obs = f_obs.customized_copy(data=f_obs.data() *
                                      overall_anisotropic_scale)
        #print bulk_solvent.r_factor(f_obs.data(), fmodel.f_model().data())
        #print bulk_solvent.r_factor(f_obs.data(), fmodel.f_model().data())
        t0 = time.time()
        obj = bulk_solvent.aniso_u_scaler(f_model_abs=flex.abs(fc.data()),
                                          f_obs=f_obs.data(),
                                          miller_indices=f_obs.indices(),
                                          unit_cell=f_obs.unit_cell())
        time_aniso_u_scaler += (time.time() - t0)
        overall_anisotropic_scale = mmtbx.f_model.ext.k_anisotropic(
            f_obs.indices(), obj.a, f_obs.unit_cell())
        assert approx_equal(
            bulk_solvent.r_factor(f_obs.data(),
                                  fc.data() * overall_anisotropic_scale), 0.0,
            1.e-2)  # XXX seems to be low
        #print "Output a:", " ".join(["%7.3f"%i for i in obj.a])
        assert approx_equal(a, obj.a, 1.e-4)  # XXX can it be smaller?
        assert overall_anisotropic_scale[len(overall_anisotropic_scale) -
                                         1] == 1
    print("Time (aniso_u_scaler only): %6.4f" % time_aniso_u_scaler)
def run_02():
  time_aniso_u_scaler = 0
  for symbol in sgtbx.bravais_types.acentric + sgtbx.bravais_types.centric:
    #print symbol, "-"*50
    space_group_info = sgtbx.space_group_info(symbol = symbol)
    xrs = random_structure.xray_structure(
      space_group_info  = space_group_info,
      elements          = ["N"]*100,
      volume_per_atom   = 50.0,
      random_u_iso      = True)
    xrs.scattering_type_registry(table = "wk1995")
    # XXX ad a method to adptbx to do this
    point_group = sgtbx.space_group_info(
      symbol=symbol).group().build_derived_point_group()
    adp_constraints = sgtbx.tensor_rank_2_constraints(
      space_group=point_group,
      reciprocal_space=True)
    u_star = adptbx.u_cart_as_u_star(xrs.unit_cell(),
      adptbx.random_u_cart(u_scale=1,u_min=0.1))
    u_indep = adp_constraints.independent_params(all_params=u_star)
    u_star = adp_constraints.all_params(independent_params=u_indep)
    b_cart_start=adptbx.u_as_b(adptbx.u_star_as_u_cart(xrs.unit_cell(), u_star))
    #
    tr = (b_cart_start[0]+b_cart_start[1]+b_cart_start[2])/3
    b_cart_start = [b_cart_start[0]-tr,b_cart_start[1]-tr,b_cart_start[2]-tr,
           b_cart_start[3],b_cart_start[4],b_cart_start[5]]
    tr = (b_cart_start[0]+b_cart_start[1]+b_cart_start[2])/3
    #
    #print "Input b_cart :", " ".join(["%8.4f"%i for i in b_cart_start]), "tr:", tr
    reg = xrs.scattering_type_registry(table="wk1995", d_min=1/12)
    f_000 = reg.sum_of_scattering_factors_at_diffraction_angle_0()
    F = xrs.structure_factors(d_min = 2.0).f_calc()
    i = F.indices()
    i.append([0,0,0])
    d = F.data()
    d.append(f_000)
    F = F.customized_copy(indices = i, data = d)

    u_star = adptbx.u_cart_as_u_star(
      F.unit_cell(), adptbx.b_as_u(b_cart_start))
    fbc = mmtbx.f_model.ext.k_anisotropic(F.indices(), u_star)
    fc = F.structure_factors_from_scatterers(xray_structure=xrs).f_calc()
    f_obs = F.customized_copy(data = flex.abs(fc.data()*fbc))
    #print bulk_solvent.r_factor(f_obs.data(), fmodel.f_model().data())
    obj = bulk_solvent.aniso_u_scaler(
      f_model        = fc.data(),
      f_obs          = f_obs.data(),
      miller_indices = f_obs.indices(),
      unit_cell      = f_obs.unit_cell())
    a = obj.a
    ####
    #print "Input a :", " ".join(["%7.3f"%i for i in a])
    overall_anisotropic_scale = mmtbx.f_model.ext.k_anisotropic(
      f_obs.indices(), a, f_obs.unit_cell())
    #print bulk_solvent.r_factor(f_obs.data(), fmodel.f_model().data()*overall_anisotropic_scale)
    f_obs = abs(fc)
    f_obs = f_obs.customized_copy(data = f_obs.data() * overall_anisotropic_scale)
    #print bulk_solvent.r_factor(f_obs.data(), fmodel.f_model().data())
    #print bulk_solvent.r_factor(f_obs.data(), fmodel.f_model().data())
    t0 = time.time()
    obj = bulk_solvent.aniso_u_scaler(
      f_model        = fc.data(),
      f_obs          = f_obs.data(),
      miller_indices = f_obs.indices(),
      unit_cell      = f_obs.unit_cell())
    time_aniso_u_scaler += (time.time()-t0)
    overall_anisotropic_scale = mmtbx.f_model.ext.k_anisotropic(
      f_obs.indices(), obj.a, f_obs.unit_cell())
    assert approx_equal(bulk_solvent.r_factor(f_obs.data(),
      fc.data()*overall_anisotropic_scale), 0.0, 1.e-2) # XXX seems to be low
    #print "Output a:", " ".join(["%7.3f"%i for i in obj.a])
    assert approx_equal(a, obj.a, 1.e-4) # XXX can it be smaller?
    assert overall_anisotropic_scale[len(overall_anisotropic_scale)-1]==1
  print "Time (aniso_u_scaler only): %6.4f"%time_aniso_u_scaler
Beispiel #13
0
  def parameter_based_model_one_frame_detail(self,frame_id,iframe,all_model):
      PIXEL_SZ = 0.11 # mm/pixel
      SIGN = -1.
      if iframe < self.n_refined_frames:
        detector_origin = col((-self.FRAMES["beam_x"][iframe]
                             + SIGN * PIXEL_SZ * self.frame_translations.x[2*iframe],
                             -self.FRAMES["beam_y"][iframe]
                             + SIGN * PIXEL_SZ * self.frame_translations.x[1+2*iframe],
                             0.))
        self.OUTPUT["beam_x"][iframe] = -detector_origin[0]
        self.OUTPUT["beam_y"][iframe] = -detector_origin[1]
      else:
        detector_origin = col((-self.FRAMES["beam_x"][iframe],-self.FRAMES["beam_y"][iframe],0.))

      if not self.bandpass_models.has_key(frame_id):

        reserve_orientation = self.FRAMES["orientation"][iframe]
        effective_orientation = reserve_orientation

        #Not necessary to apply the 3 offset rotations; they have apparently
        #  been applied already.\
        #  .rotate_thru((1,0,0),self.FRAMES["rotation100_rad"][iframe]
        # ).rotate_thru((0,1,0),self.FRAMES["rotation010_rad"][iframe]
        # ).rotate_thru((0,0,1),self.FRAMES["rotation001_rad"][iframe])

        crystal = symmetry(unit_cell=effective_orientation.unit_cell(),space_group = "P1")
        indices = all_model.frame_indices(frame_id)

        parameters = parameters_bp3(
           indices=indices, orientation=effective_orientation,
           incident_beam=col(correction_vectors.INCIDENT_BEAM),
           packed_tophat=col((1.,1.,0.)),
           detector_normal=col(correction_vectors.DETECTOR_NORMAL),
           detector_fast=col((0.,1.,0.)),detector_slow=col((1.,0.,0.)),
           pixel_size=col((PIXEL_SZ,PIXEL_SZ,0)),
           pixel_offset=col((0.,0.,0.0)),
           distance=self.FRAMES["distance"][iframe],
           detector_origin=detector_origin
        )

        #print "PARAMETER check   ", effective_orientation
        #print "PARAMETER distance", self.FRAMES['distance'][iframe]
        #print "PARAMETER origin  ", detector_origin

        ucbp3 = bandpass_gaussian(parameters=parameters)
        ucbp3.set_active_areas( self.tiles ) #self.params.effective_tile_boundaries
        integration_signal_penetration=0.0 # easier to calculate distance derivatives

        ucbp3.set_sensor_model( thickness_mm = 0.5, mu_rho = 8.36644, # CS_PAD detector at 1.3 Angstrom
          signal_penetration = integration_signal_penetration)
        #ucbp3.set_subpixel( flex.double(tp038_trans_values) ) #back off this; let minimizer figure it out.

        half_mosaicity_rad = self.FRAMES["half_mosaicity_deg"][iframe] * pi/180.
        ucbp3.set_mosaicity(half_mosaicity_rad)
        ucbp3.set_bandpass(self.FRAMES["wave_HE_ang"][iframe],self.FRAMES["wave_LE_ang"][iframe])
        ucbp3.set_orientation(effective_orientation)
        ucbp3.set_domain_size(self.FRAMES["domain_size_ang"][iframe])
        ucbp3.set_vector_output_pointers(self.vector_data,
                                         frame_id,iframe<self.n_refined_frames)

        if not self.bandpass_models.has_key("best_index"):
          from labelit.dptbx import lepage
          M = lepage.character(effective_orientation)
          s = len(M.best())
          for index in M.best():
            index['counter'] = s
            s-=1
            if index["max_angular_difference"]==0.0:
              best_index = index
              break

          self.bandpass_models["best_index"] = best_index
          self.bandpass_models["constraints"] = tensor_rank_2_constraints(space_group=best_index['reduced_group'],reciprocal_space=True)
          self.bandpass_models["n_independent"] = self.bandpass_models["constraints"].n_independent_params()

        self.bandpass_models[frame_id]=ucbp3

      if iframe < self.n_refined_frames:
        self.bandpass_models[frame_id].set_detector_origin(detector_origin)
        self.bandpass_models[frame_id].set_distance(
          self.FRAMES["distance"][iframe] + self.frame_distances.x[iframe])
        self.OUTPUT["distance"][iframe] = self.FRAMES["distance"][iframe] + self.frame_distances.x[iframe]
        #half_mosaicity_rad = self.FRAMES["half_mosaicity_deg"][iframe] * pi/180. + \
        #                     self.half_mosaicity_rad.x[iframe]
        #self.bandpass_models[frame_id].set_mosaicity(half_mosaicity_rad)
        reserve_orientation = self.FRAMES["orientation"][iframe]
        effective_orientation =   reserve_orientation.rotate_thru((0,0,1),self.frame_rotz.x[iframe])
        effective_orientation = effective_orientation.rotate_thru((0,1,0),self.frame_roty.x[iframe])
        effective_orientation = effective_orientation.rotate_thru((1,0,0),self.frame_rotx.x[iframe])

        convert = AGconvert()
        convert.forward(effective_orientation)
        u_independent = list(self.bandpass_models["constraints"].independent_params(all_params=convert.G))
        for x in xrange(self.bandpass_models["n_independent"]):
          u_independent[x] *= self.g_factor.x[x+6*iframe]
        u_star = self.bandpass_models["constraints"].all_params(independent_params=tuple(u_independent))
        convert.validate_and_setG(u_star)
        effective_orientation = convert.back_as_orientation()
        self.OUTPUT["orientation"][iframe]=effective_orientation
        self.bandpass_models[frame_id].set_orientation(effective_orientation)
        mean_wave = (self.FRAMES["wave_HE_ang"][iframe] + self.FRAMES["wave_LE_ang"][iframe])/2.
        #mean_wave *= self.mean_energy_factor.x[iframe]
        bandpassHW =(self.FRAMES["wave_LE_ang"][iframe] - self.FRAMES["wave_HE_ang"][iframe])/2.
        self.bandpass_models[frame_id].set_bandpass(mean_wave - bandpassHW, mean_wave + bandpassHW)

      return detector_origin
  def __init__(self, space_group):

    self.space_group = space_group
    self.constraints = sgtbx.tensor_rank_2_constraints(
      space_group=self.space_group,reciprocal_space=True)
Beispiel #15
0
def table1_tex(merging_stats):
    # based on table1 from
    #
    # http://journals.iucr.org/d/issues/2018/02/00/di5011/index.html

    ncols = len(merging_stats)

    print("\\begin{tabular}{%s}" % ("l" * (ncols + 1)))

    # name_str = ['']
    # for cp in crystal_params:
    # name_str.append(cp['name'].replace('_', '\_'))

    # print(' & '.join(name_str) + ' \\\\')
    print("Crystal parameters" + " & " * ncols + "\\\\")
    print("Space group & " +
          " & ".join(ms.crystal_symmetry.space_group().type().lookup_symbol()
                     for ms in merging_stats) + " \\\\")

    # witchcraft to work out how to write out the unit cell
    cell_str = ["Unit-cell parameters (\\AA)"]
    for ms in merging_stats:
        sg = ms.crystal_symmetry.space_group()
        constraints = sgtbx.tensor_rank_2_constraints(space_group=sg,
                                                      reciprocal_space=False)
        cell_tmp = "$"
        cell = ms.crystal_symmetry.unit_cell().parameters()
        independent = constraints.independent_indices

        # weird case spotted with P3 - this set is impossible
        if independent == (2, 3):
            independent = (1, 2)

        if 0 in independent:
            cell_tmp += "a=%.5f, " % cell[0]
        else:
            cell_tmp += "a="
        if 1 in independent:
            cell_tmp += "b=%.5f, " % cell[1]
        else:
            cell_tmp += "b="
        cell_tmp += "c=%.5f" % cell[2]
        if 3 in independent:
            cell_tmp += ", \\alpha=%.5f" % cell[3]
        if 4 in independent:
            cell_tmp += ", \\beta=%.5f" % cell[4]
        if 5 in independent:
            cell_tmp += ", \\gamma=%.5f" % cell[5]
        cell_tmp += "$"
        cell_str.append(cell_tmp)
    print(" & ".join(cell_str) + " \\\\")
    print("Data statistics" + " & " * ncols + "\\\\")

    # resolution ranges, shells

    resolution_str = ["Resolution range (\\AA)"]

    for ms in merging_stats:
        low = (ms.bins[0].d_max, ms.bins[0].d_min)
        high = (ms.bins[-1].d_max, ms.bins[-1].d_min)
        resolution_str.append("%.2f-%.2f (%.2f-%.2f)" %
                              (low[0], high[1], high[0], high[1]))

    print(" & ".join(resolution_str) + " \\\\")

    # loopy boiler plate stuff - https://xkcd.com/1421/ - sorry - and why do
    # grown ups sometimes need things in %ages? x_x

    magic_words_and_places_and_multipliers = [
        ("No. of unique reflections", "n_uniq", 1, "%d"),
        ("Multiplicity", "multiplicity", 1, "%.1f"),
        ("$R_{\\rm{merge}}$", "r_merge", 1, "%.3f"),
        ("$R_{\\rm{meas}}$", "r_meas", 1, "%.3f"),
        ("$R_{\\rm{pim}}$", "r_pim", 1, "%.3f"),
        ("Completeness (\\%)", "completeness", 1, "%.1f"),
        ("$<I/\\sigma(I)>$", "i_over_sigma_mean", 1, "%.1f"),
        ("$CC_{\\frac{1}{2}}$", "cc_one_half", 1, "%.3f"),
    ]

    for mw, p, m, fmt in magic_words_and_places_and_multipliers:

        magic_str = [mw]

        for ms in merging_stats:
            ms_d = ms.as_dict()
            magic_str.append(("%s (%s)" % (fmt, fmt)) %
                             (ms_d["overall"][p] * m, ms_d[p][-1] * m))

        print(" & ".join(magic_str) + " \\\\")

    print("\\end{tabular}")
Beispiel #16
0
    def __init__(
            self,
            f_obs,
            f_calc,  # can be a sum: f_calc=f_hydrogens+f_calc+f_part
            f_mask,  # only one shell is supported
            r_free_flags,
            ss,
            bin_selections=None,
            scale_method="combo",
            number_of_cycles=20,  # termination occures much earlier
            auto_convergence_tolerance=1.e-4,
            log=None,
            auto=True,
            auto_convergence=True,
            bulk_solvent=True,
            try_poly=True,
            try_expanal=True,
            try_expmin=False,
            verbose=False):
        assert f_obs.indices().all_eq(r_free_flags.indices())
        self.log = log
        self.scale_method = scale_method
        self.verbose = verbose
        self.r_free_flags = r_free_flags
        self.ss = ss
        self.bulk_solvent = bulk_solvent
        self.try_poly = try_poly
        self.try_expanal = try_expanal
        self.try_expmin = try_expmin
        self.d_spacings = f_obs.d_spacings()
        self.r_low = None
        self.poly_approx_cutoff = None
        self.f_obs = f_obs
        self.r_free_flags = r_free_flags
        self.auto_convergence = auto_convergence
        self.auto_convergence_tolerance = auto_convergence_tolerance
        self.scale_matrices = None
        self.auto = auto
        self.bin_selections = bin_selections
        self.k_exp_overall, self.b_exp_overall = None, None
        if (self.bin_selections is None):
            self.bin_selections = self.f_obs.log_binning()
        # If R-free flags are bad - discard them and use all reflections instead.
        ifg = self.is_flags_good()
        if (ifg):
            self.selection_work = miller.array(miller_set=self.f_obs,
                                               data=~self.r_free_flags.data())
        else:
            self.selection_work = miller.array(miller_set=self.f_obs,
                                               data=flex.bool(
                                                   self.f_obs.data().size(),
                                                   True))
        #
        self.ss = ss

        def init_result():
            return group_args(k_mask_bin_orig=None,
                              k_mask_bin_smooth=None,
                              k_mask=None,
                              k_isotropic=None,
                              k_mask_fit_params=None)

        self.bss_result = init_result()
        if (log is None): log = sys.stdout
        if (verbose):
            print >> log, "-" * 80
            print >> log, \
              "Overall, iso- and anisotropic scaling and bulk-solvent modeling:"
        point_group = sgtbx.space_group_info(symbol=f_obs.space_group().type(
        ).lookup_symbol()).group().build_derived_point_group()
        self.adp_constraints = sgtbx.tensor_rank_2_constraints(
            space_group=point_group, reciprocal_space=True)
        self.core = mmtbx.arrays.init(f_calc=f_calc, f_masks=f_mask)
        if (abs(self.core.f_mask()).data().all_eq(0)):
            self.bulk_solvent = False
        self.cores_and_selections = []
        self.low_resolution_selection = self._low_resolution_selection()
        self.high_resolution_selection = self._high_resolution_selection()
        if (verbose):
            print >> log, "  Using %d resolution bins" % len(
                self.bin_selections)
        self.ss_bin_values = []
        sel_positive = self.f_obs.data() > 0
        self.selection_work = self.selection_work.customized_copy(
            data=self.selection_work.data() & sel_positive)
        for i_sel, sel in enumerate(self.bin_selections):
            core_selected = self.core.select(selection=sel)
            sel_use = self.selection_work.data().select(sel)
            sel_work = sel & self.selection_work.data()
            self.cores_and_selections.append(
                [sel, core_selected, sel_use, sel_work])
            ss = self.ss.select(sel)
            self.ss_bin_values.append(
                [flex.min(ss), flex.max(ss),
                 flex.mean(ss)])
        for cycle in xrange(number_of_cycles):
            r_start = self.r_factor(use_scale=True)
            r_start0 = r_start
            use_scale_r = False
            if (cycle == 0): use_scale_r = True
            if (verbose):
                print >> log, "  cycle %d:" % cycle
                print >> log, "    r(start): %6.4f" % (r_start)
            # bulk-solvent and overall isotropic scale
            if (self.bulk_solvent):
                if (cycle == 0):
                    r_start = self.set_k_isotropic_exp(r_start=r_start,
                                                       use_scale_r=use_scale_r,
                                                       verbose=verbose)
                    r_start = self.k_mask_grid_search(r_start=r_start)
                    if (verbose):
                        print >> self.log, "    r(bulk_solvent_grid_search): %6.4f" % r_start
                    r_start = self.set_k_isotropic_exp(r_start=r_start,
                                                       use_scale_r=use_scale_r,
                                                       verbose=verbose)
                else:
                    r_start = self.bulk_solvent_scaling(r_start=r_start)
            # anisotropic scale
            if ([try_poly, try_expanal, try_expmin].count(True)):
                if (verbose): print >> log, "    anisotropic scaling:"
                self.anisotropic_scaling(r_start=r_start)
            if (self.auto_convergence
                    and self.is_converged(
                        r_start=r_start0,
                        tolerance=self.auto_convergence_tolerance)):
                break
        self.apply_overall_scale()
        if (verbose):
            print >> log, "  r(final): %6.4f" % (self.r_factor())
            self.show()
        #
        self.r_low = self._r_low()
        self.r_high = self._r_high()
        if (verbose):
            d = self.d_spacings.data().select(self.low_resolution_selection)
            d1 = ("%7.4f" % flex.min(d)).strip()
            d2 = ("%7.4f" % flex.max(d)).strip()
            n = d.size()
            print >> self.log, "r(low-resolution: %s-%s A; %d reflections): %6.4f" % (
                d2, d1, n, self.r_low)
            print >> log, "-" * 80
        self.r_final = self.r_factor()
def run():
  #
  # try these Hall symbols:
  #   "P 1", "P 2", "P 3", "P 3*", "P 4", "P 6", "P 2 2 3"
  #
  space_group = sgtbx.space_group("P 3*") # Hall symbol

  #
  # initialization of space group symmetry constraints
  #
  adp_constraints = sgtbx.tensor_rank_2_constraints(
    space_group=space_group,
    reciprocal_space=True)

  #
  # number of independent u_star parameters
  #
  n_indep = adp_constraints.n_independent_params()

  #
  # arbitrary Miller index and u_star tensor
  #
  h = (3,1,2)
  u_star=(0.000004, 0.000004, 0.000007, 0.000002, 0.0000000, 0.0000000)
  # optional: enforce symmetry at the beginning
  u_star = space_group.average_u_star(u_star)

  #
  # pass u_indep to the minimizer
  #
  u_indep = adp_constraints.independent_params(all_params=u_star)
  assert len(u_indep) == n_indep

  #
  # "expand" the independent parameters modified by the minimizer
  #
  u_star = adp_constraints.all_params(independent_params=u_indep)
  assert len(u_star) == 6

  #
  # these calculations are completely independent of the symmetry
  #
  dwf = adptbx.debye_waller_factor_u_star(h, u_star)
  gc = adptbx.debye_waller_factor_u_star_gradient_coefficients(h)
  # all_gradients is an array of six values
  all_gradients = [-2*math.pi**2 * dwf * c for c in gc]
  assert len(all_gradients) == 6
  cc = adptbx.debye_waller_factor_u_star_curvature_coefficients(h)
  # all_curvatures is an array of 21 values (upper triangle of 6x6 matrix)
  all_curvatures = (-2*math.pi**2)**2 * dwf * cc
  assert len(all_curvatures) == 6*(6+1)//2

  #
  # here we apply the symmetry constraints to the gradients and curvatures
  #
  # g_indep is an array of n_indep values
  g_indep = adp_constraints.independent_gradients(
    all_gradients=all_gradients)
  assert len(g_indep) == n_indep
  # c_indep is an array of n_indep*(n_indep+1)/2 values (upper triangle)
  c_indep = adp_constraints.independent_curvatures(
    all_curvatures=all_curvatures)
  assert len(c_indep) == n_indep*(n_indep+1)//2
  # feed g_indep and c_indep to the minimizer

  #
  # initialization of site symmetry constraints
  # (for sites on special positions)
  #
  unit_cell = uctbx.unit_cell((12,12,15,90,90,120))
  space_group = sgtbx.space_group_info("P 6").group()
  site_symmetry = sgtbx.site_symmetry(
    unit_cell=unit_cell,
    space_group=space_group,
    original_site=(1/3.,2/3.,0), # site on 3-fold axis
    min_distance_sym_equiv=0.5)
  assert len(site_symmetry.matrices()) == 3
  adp_constraints = site_symmetry.adp_constraints()
  # use adp_constraints as before

  print "OK"
Beispiel #18
0
  def __init__(self, space_group):

    self.space_group = space_group
    self.constraints = sgtbx.tensor_rank_2_constraints(
      space_group=self.space_group,reciprocal_space=True)
Beispiel #19
0
def table1_tex(crystal_params, merging_stats):
    # based on table1 from
    #
    # http://journals.iucr.org/d/issues/2018/02/00/di5011/index.html

    assert len(crystal_params) == len(merging_stats)

    # first iterate through and work out how many columns we will be needing
    columns = [len(ms) for ms in merging_stats]

    if max(columns) > 1:
        raise RuntimeError(
            ":TODO: make this work for multiwavelength data sets")

    ncols = sum(columns)

    print("\\begin{tabular}{%s}" % ("l" * (ncols + 1)))

    name_str = [""]
    for cp in crystal_params:
        name_str.append(cp["name"].replace("_", r"\_"))

    print(" & ".join(name_str) + " \\\\")
    print("Crystal parameters" + " & " * ncols + "\\\\")
    print("Space group & " + " & ".join(cp["space_group"]
                                        for cp in crystal_params) + " \\\\")

    # witchcraft to work out how to write out the unit cell
    cell_str = ["Unit-cell parameters (\\AA)"]
    for cp in crystal_params:
        sgi = sgtbx.space_group_info(str(cp["space_group"]))
        sg = sgi.group()
        constraints = sgtbx.tensor_rank_2_constraints(space_group=sg,
                                                      reciprocal_space=False)
        cell_tmp = "$"
        cell = cp["cell"]
        independent = constraints.independent_indices

        # weird case spotted with P3 - this set is impossible
        if independent == (2, 3):
            independent = (1, 2)

        if 0 in independent:
            cell_tmp += "a=%.5f, " % cell[0]
        else:
            cell_tmp += "a="
        if 1 in independent:
            cell_tmp += "b=%.5f, " % cell[1]
        else:
            cell_tmp += "b="
        cell_tmp += "c=%.5f" % cell[2]
        if 3 in independent:
            cell_tmp += ", \\alpha=%.5f" % cell[3]
        if 4 in independent:
            cell_tmp += ", \\beta=%.5f" % cell[4]
        if 5 in independent:
            cell_tmp += ", \\gamma=%.5f" % cell[5]
        cell_tmp += "$"
        cell_str.append(cell_tmp)
    print(" & ".join(cell_str) + " \\\\")
    print("Data statistics" + " & " * ncols + "\\\\")

    # resolution ranges, shells

    resolution_str = ["Resolution range (\\AA)"]

    for ms in merging_stats:
        for name in ms:
            low = ms[name]["Low resolution limit"]
            high = ms[name]["High resolution limit"]
            resolution_str.append("%.2f-%.2f (%.2f-%.2f)" %
                                  (low[0], high[0], low[2], high[2]))

    print(" & ".join(resolution_str) + " \\\\")

    # loopy boiler plate stuff - https://xkcd.com/1421/ - sorry - and why do
    # grown ups sometimes need things in %ages? x_x

    magic_words_and_places_and_multipliers = [
        ("No. of unique reflections", "Total unique", 1, "%d"),
        ("Multiplicity", "Multiplicity", 1, "%.1f"),
        ("$R_{\\rm{merge}}$", "Rmerge(I)", 1, "%.3f"),
        ("$R_{\\rm{meas}}$", "Rmeas(I)", 1, "%.3f"),
        ("$R_{\\rm{pim}}$", "Rpim(I)", 1, "%.3f"),
        ("Completeness (\\%)", "Completeness", 1, "%.1f"),
        ("$<I/\\sigma(I)>$", "I/sigma", 1, "%.1f"),
        ("$CC_{\\frac{1}{2}}$", "CC half", 1, "%.3f"),
    ]

    for mw, p, m, fmt in magic_words_and_places_and_multipliers:

        magic_str = [mw]

        for ms in merging_stats:
            for name in ms:
                data = ms[name][p]
                magic_str.append(
                    ("%s (%s)" % (fmt, fmt)) % (data[0] * m, data[2] * m))

        print(" & ".join(magic_str) + " \\\\")

    print("\\end{tabular}")
Beispiel #20
0
def run():
    #
    # try these Hall symbols:
    #   "P 1", "P 2", "P 3", "P 3*", "P 4", "P 6", "P 2 2 3"
    #
    space_group = sgtbx.space_group("P 3*")  # Hall symbol

    #
    # initialization of space group symmetry constraints
    #
    adp_constraints = sgtbx.tensor_rank_2_constraints(space_group=space_group,
                                                      reciprocal_space=True)

    #
    # number of independent u_star parameters
    #
    n_indep = adp_constraints.n_independent_params()

    #
    # arbitrary Miller index and u_star tensor
    #
    h = (3, 1, 2)
    u_star = (0.000004, 0.000004, 0.000007, 0.000002, 0.0000000, 0.0000000)
    # optional: enforce symmetry at the beginning
    u_star = space_group.average_u_star(u_star)

    #
    # pass u_indep to the minimizer
    #
    u_indep = adp_constraints.independent_params(all_params=u_star)
    assert len(u_indep) == n_indep

    #
    # "expand" the independent parameters modified by the minimizer
    #
    u_star = adp_constraints.all_params(independent_params=u_indep)
    assert len(u_star) == 6

    #
    # these calculations are completely independent of the symmetry
    #
    dwf = adptbx.debye_waller_factor_u_star(h, u_star)
    gc = adptbx.debye_waller_factor_u_star_gradient_coefficients(h)
    # all_gradients is an array of six values
    all_gradients = [-2 * math.pi**2 * dwf * c for c in gc]
    assert len(all_gradients) == 6
    cc = adptbx.debye_waller_factor_u_star_curvature_coefficients(h)
    # all_curvatures is an array of 21 values (upper triangle of 6x6 matrix)
    all_curvatures = (-2 * math.pi**2)**2 * dwf * cc
    assert len(all_curvatures) == 6 * (6 + 1) // 2

    #
    # here we apply the symmetry constraints to the gradients and curvatures
    #
    # g_indep is an array of n_indep values
    g_indep = adp_constraints.independent_gradients(
        all_gradients=all_gradients)
    assert len(g_indep) == n_indep
    # c_indep is an array of n_indep*(n_indep+1)/2 values (upper triangle)
    c_indep = adp_constraints.independent_curvatures(
        all_curvatures=all_curvatures)
    assert len(c_indep) == n_indep * (n_indep + 1) // 2
    # feed g_indep and c_indep to the minimizer

    #
    # initialization of site symmetry constraints
    # (for sites on special positions)
    #
    unit_cell = uctbx.unit_cell((12, 12, 15, 90, 90, 120))
    space_group = sgtbx.space_group_info("P 6").group()
    site_symmetry = sgtbx.site_symmetry(
        unit_cell=unit_cell,
        space_group=space_group,
        original_site=(1 / 3., 2 / 3., 0),  # site on 3-fold axis
        min_distance_sym_equiv=0.5)
    assert len(site_symmetry.matrices()) == 3
    adp_constraints = site_symmetry.adp_constraints()
    # use adp_constraints as before

    print("OK")
Beispiel #21
0
 def __init__(self,
              f_obs,
              f_calc, # can be a sum: f_calc=f_hydrogens+f_calc+f_part
              f_mask, # only one shell is supported
              r_free_flags,
              ss,
              bin_selections=None,
              scale_method="combo",
              number_of_cycles=20, # termination occures much earlier
              auto_convergence_tolerance = 1.e-4,
              log=None,
              auto=True,
              auto_convergence=True,
              bulk_solvent = True,
              try_poly = True,
              try_expanal = True,
              try_expmin = False,
              verbose=False):
   assert f_obs.indices().all_eq(r_free_flags.indices())
   self.log = log
   self.scale_method = scale_method
   self.verbose = verbose
   self.r_free_flags = r_free_flags
   self.ss = ss
   self.bulk_solvent = bulk_solvent
   self.try_poly    = try_poly
   self.try_expanal = try_expanal
   self.try_expmin  = try_expmin
   self.d_spacings = f_obs.d_spacings()
   self.r_low = None
   self.poly_approx_cutoff = None
   self.f_obs = f_obs
   self.r_free_flags = r_free_flags
   self.auto_convergence = auto_convergence
   self.auto_convergence_tolerance = auto_convergence_tolerance
   self.scale_matrices = None
   self.auto = auto
   self.bin_selections = bin_selections
   self.k_exp_overall, self.b_exp_overall = None,None
   if(self.bin_selections is None):
     self.bin_selections = self.f_obs.log_binning()
   # If R-free flags are bad - discard them and use all reflections instead.
   ifg = self.is_flags_good()
   if(ifg):
     self.selection_work = miller.array(
       miller_set = self.f_obs,
       data       = ~self.r_free_flags.data())
   else:
     self.selection_work = miller.array(
       miller_set = self.f_obs,
       data       = flex.bool(self.f_obs.data().size(), True))
   #
   self.ss = ss
   def init_result():
     return group_args(
       k_mask_bin_orig   = None,
       k_mask_bin_smooth = None,
       k_mask            = None,
       k_isotropic       = None,
       k_mask_fit_params = None)
   self.bss_result = init_result()
   if(log is None): log = sys.stdout
   if(verbose):
     print >> log, "-"*80
     print >> log, \
       "Overall, iso- and anisotropic scaling and bulk-solvent modeling:"
   point_group = sgtbx.space_group_info(
     symbol=f_obs.space_group().type().lookup_symbol()
     ).group().build_derived_point_group()
   self.adp_constraints = sgtbx.tensor_rank_2_constraints(
     space_group=point_group,
     reciprocal_space=True)
   self.core = mmtbx.arrays.init(f_calc = f_calc, f_masks = f_mask)
   if(abs(self.core.f_mask()).data().all_eq(0)): self.bulk_solvent=False
   self.cores_and_selections = []
   self.low_resolution_selection = self._low_resolution_selection()
   self.high_resolution_selection = self._high_resolution_selection()
   if(verbose):
     print >> log, "  Using %d resolution bins"%len(self.bin_selections)
   self.ss_bin_values=[]
   sel_positive = self.f_obs.data()>0
   self.selection_work = self.selection_work.customized_copy(
     data = self.selection_work.data() & sel_positive)
   for i_sel, sel in enumerate(self.bin_selections):
     core_selected = self.core.select(selection=sel)
     sel_use = self.selection_work.data().select(sel)
     sel_work = sel & self.selection_work.data()
     self.cores_and_selections.append([sel, core_selected, sel_use, sel_work])
     ss = self.ss.select(sel)
     self.ss_bin_values.append([
       flex.min(ss),
       flex.max(ss),
       flex.mean(ss)])
   for cycle in xrange(number_of_cycles):
     r_start = self.r_factor(use_scale=True)
     r_start0 = r_start
     use_scale_r=False
     if(cycle==0): use_scale_r=True
     if(verbose):
       print >> log, "  cycle %d:"%cycle
       print >> log, "    r(start): %6.4f"%(r_start)
     # bulk-solvent and overall isotropic scale
     if(self.bulk_solvent):
       if(cycle==0):
         r_start = self.set_k_isotropic_exp(r_start = r_start,
           use_scale_r=use_scale_r, verbose=verbose)
         r_start = self.k_mask_grid_search(r_start=r_start)
         if(verbose):
           print >> self.log, "    r(bulk_solvent_grid_search): %6.4f"%r_start
         r_start = self.set_k_isotropic_exp(r_start = r_start,
           use_scale_r=use_scale_r, verbose=verbose)
       else:
         r_start = self.bulk_solvent_scaling(r_start = r_start)
     # anisotropic scale
     if([try_poly, try_expanal, try_expmin].count(True)):
       if(verbose): print >> log, "    anisotropic scaling:"
       self.anisotropic_scaling(r_start = r_start)
     if(self.auto_convergence and self.is_converged(r_start=r_start0,
        tolerance=self.auto_convergence_tolerance)):
       break
   self.apply_overall_scale()
   if(verbose):
     print >> log, "  r(final): %6.4f"%(self.r_factor())
     self.show()
   #
   self.r_low = self._r_low()
   self.r_high = self._r_high()
   if(verbose):
     d = self.d_spacings.data().select(self.low_resolution_selection)
     d1 = ("%7.4f"%flex.min(d)).strip()
     d2 = ("%7.4f"%flex.max(d)).strip()
     n = d.size()
     print >> self.log, "r(low-resolution: %s-%s A; %d reflections): %6.4f"%(
       d2,d1,n,self.r_low)
     print >> log, "-"*80
   self.r_final = self.r_factor()