Ejemplo n.º 1
0
 def add_hydrogen_to(self, reparametrisation, bond_length, pivot_site,
                     pivot_neighbour_sites, pivot_site_param,
                     pivot_neighbour_site_params,
                     pivot_neighbour_substituent_site_params, hydrogens,
                     **kwds):
     if len(pivot_neighbour_site_params) != 1:
         raise InvalidConstraint(_.bad_connectivity_msg %
                                 (self.__class__.__name__,
                                  pivot_site_param.scatterers[0].label))
     if not len(pivot_neighbour_substituent_site_params):
         raise InvalidConstraint(need_at_least_one_substituent_msg %
                                 (self.__class__.__name__,
                                  pivot_site_param.scatterers[0].label))
     if self.stagger_on is None:
         if len(pivot_neighbour_substituent_site_params) == 1:
             stagger_on = pivot_neighbour_substituent_site_params[0]
         else:
             # staggered with respect to the shortest
             # pivot_neighbour - pivot_neighbour_substituent bond
             #
             # If the two bond lengths are similar, then the hydrogen could have a
             # tendancy to flip between the positions. If this is the case, a
             # staggered hydrogen constraint is probably unsuitable, and a freely
             # rotatable constraint could be used.
             #
             uc = reparametrisation.structure.unit_cell()
             x_s = col(pivot_neighbour_sites[0])
             d_s = sorted((uc.distance(s.value, x_s), i)
                          for i, s in enumerate(
                              pivot_neighbour_substituent_site_params))
             stagger_on = pivot_neighbour_substituent_site_params[d_s[0][1]]
     else:
         for p in pivot_neighbour_substituent_site_params:
             if p.index == self.stagger_on:
                 stagger_on = p
                 break
         # The stagger_on atom must be one of the pivot_neighbour_substituents.
         # If we reach here, this is not the case so an error is raised.
         raise InvalidConstraint(_.bad_connectivity_msg %
                                 (self.__class__.__name__,
                                  pivot_site_param.scatterers[0].label))
     for j, ops in reparametrisation.pair_sym_table[self.pivot].items():
         for k, ops in reparametrisation.pair_sym_table[self.pivot].items():
             if j == k: continue
             reparametrisation.fixed_angles.setdefault((j, self.pivot, k),
                                                       tetrahedral_angle)
     return reparametrisation.add(
         getattr(_, self.__class__.__name__),
         pivot=pivot_site_param,
         pivot_neighbour=pivot_neighbour_site_params[0],
         length=bond_length,
         stagger_on=stagger_on,
         hydrogen=hydrogens)
Ejemplo n.º 2
0
Archivo: rigid.py Proyecto: dials/cctbx
 def __init__(self, groups, angles=(0,0,0), fix_xyz=True, fix_u=True):
   """ fix_xyz and fix_u are to be used for debugging purposes only:
   if the coordinates are not fixed, then the refined angles should
   be stored externally and passed to this object
   """
   if len(groups) < 2:
     raise InvalidConstraint("at least two atom sets are expected")
   l = len(groups[0])
   for g in groups[1:]:
     if len(g) != l:
       raise InvalidConstraint("atoms sets differ in size")
   self.groups = groups
   self.fix_xyz = fix_xyz
   self.fix_u = fix_u
   self.angles = angles
Ejemplo n.º 3
0
 def add_hydrogen_to(self, reparametrisation, bond_length, pivot_site,
                     pivot_neighbour_sites, pivot_site_param,
                     pivot_neighbour_site_params, hydrogens, **kwds):
     if len(pivot_neighbour_site_params) != 1:
         raise InvalidConstraint(_.bad_connectivity_msg %
                                 (self.__class__.__name__,
                                  pivot_site_param.scatterers[0].label))
     azimuth = reparametrisation.add(_.independent_scalar_parameter,
                                     value=0,
                                     variable=self.rotating)
     uc = reparametrisation.structure.unit_cell()
     for j, ops in reparametrisation.pair_sym_table[self.pivot].items():
         for k, ops in reparametrisation.pair_sym_table[self.pivot].items():
             if j == k: continue
             reparametrisation.fixed_angles.setdefault((j, self.pivot, k),
                                                       tetrahedral_angle)
     return reparametrisation.add(
         getattr(_, self.__class__.__name__),
         pivot=pivot_site_param,
         pivot_neighbour=pivot_neighbour_site_params[0],
         length=bond_length,
         azimuth=azimuth,
         e_zero_azimuth=uc.orthogonalize(
             col(hydrogens[0].site) - col(pivot_site)),
         hydrogen=hydrogens)
Ejemplo n.º 4
0
Archivo: rigid.py Proyecto: dials/cctbx
 def __init__(self, center, ind_sequence, sizeable, rotatable):
   if len(ind_sequence) == 0:
     raise InvalidConstraint("at least one atom is expected")
   self.pivot = center
   self.indices = ind_sequence
   self.sizeable = sizeable
   self.rotatable = rotatable
Ejemplo n.º 5
0
    def add_to(self, reparametrisation):
        scatterers = reparametrisation.structure.scatterers()
        src_uses_u = scatterers[self.indices[0]].flags.use_u_aniso()
        for i in range(1, len(self.indices)):
            if scatterers[self.indices[i]].flags.use_u_aniso() != src_uses_u:
                raise InvalidConstraint(
                    "mixing isotropic and anisotropic atoms is not allowed for shared ADP"
                )

        u_c = reparametrisation.add_new_thermal_displacement_parameter(
            self.indices[0])
        for i in range(1, len(self.indices)):
            if src_uses_u:
                param = reparametrisation.add(
                    _.shared_u_star,
                    reference=u_c,
                    scatterer=scatterers[self.indices[i]])
            else:
                param = reparametrisation.add(
                    _.shared_u_iso,
                    reference=u_c,
                    scatterer=scatterers[self.indices[i]])
            reparametrisation.shared_Us[self.indices[i]] = u_c
            reparametrisation.asu_scatterer_parameters[
                self.indices[i]].u = param
        self.value = u_c
Ejemplo n.º 6
0
 def ideal_bond_length(self, pivot, temperature):
     pivot_element = pivot.scattering_type
     d = self.room_temperature_bond_length.get(pivot_element)
     if d is None:
         raise InvalidConstraint(
             "Invalid %s constraint involving %s:"
             " ideal bond length not defined to atom type %s" %
             (self.__class__.__name__, pivot.label, pivot_element))
     if temperature is not None:
         if temperature < -70: d += 0.02
         elif temperature < -20: d += 0.01
     return d
Ejemplo n.º 7
0
 def add_hydrogen_to(self, reparametrisation, bond_length, pivot_site,
                     pivot_neighbour_sites, pivot_site_param,
                     pivot_neighbour_site_params, hydrogens, **kwds):
     if len(pivot_neighbour_site_params) != 4 and\
        len(pivot_neighbour_site_params) != 5:
         raise InvalidConstraint(_.bad_connectivity_msg %
                                 (self.__class__.__name__,
                                  pivot_site_param.scatterers[0].label))
     return reparametrisation.add(
         _.polyhedral_bh_site,
         pivot=pivot_site_param,
         pivot_neighbours=pivot_neighbour_site_params,
         length=bond_length,
         hydrogen=hydrogens[0])
Ejemplo n.º 8
0
 def add_hydrogen_to(self, reparametrisation, bond_length, pivot_site,
                     pivot_neighbour_sites, pivot_site_param,
                     pivot_neighbour_site_params, hydrogens, **kwds):
     if len(pivot_neighbour_site_params) != 3:
         raise InvalidConstraint(_.bad_connectivity_msg %
                                 (self.__class__.__name__,
                                  pivot_site_param.scatterers[0].label))
     return reparametrisation.add(
         _.tertiary_xh_site,
         pivot=pivot_site_param,
         pivot_neighbour_0=pivot_neighbour_site_params[0],
         pivot_neighbour_1=pivot_neighbour_site_params[1],
         pivot_neighbour_2=pivot_neighbour_site_params[2],
         length=bond_length,
         hydrogen=hydrogens[0])
Ejemplo n.º 9
0
 def add_hydrogen_to(self, reparametrisation, bond_length, pivot_site,
                     pivot_neighbour_sites, pivot_site_param,
                     pivot_neighbour_site_params, hydrogens, **kwds):
     if len(pivot_neighbour_site_params) != 1:
         raise InvalidConstraint(_.bad_connectivity_msg %
                                 (self.__class__.__name__,
                                  pivot_site_param.scatterers[0].label))
     for j, ops in reparametrisation.pair_sym_table[self.pivot].items():
         for k, ops in reparametrisation.pair_sym_table[self.pivot].items():
             if j == k: continue
             reparametrisation.fixed_angles.setdefault((j, self.pivot, k),
                                                       180.0)
     return reparametrisation.add(
         _.terminal_linear_ch_site,
         pivot=pivot_site_param,
         pivot_neighbour=pivot_neighbour_site_params[0],
         length=bond_length,
         hydrogen=hydrogens[0])
Ejemplo n.º 10
0
 def add_hydrogen_to(self, reparametrisation, bond_length, pivot_site,
                     pivot_neighbour_sites, pivot_site_param,
                     pivot_neighbour_site_params, hydrogens, **kwds):
     # e.g. Carbon atoms in Cyclopentadienyl complexes will have
     #      3 pivot neighbours
     if len(pivot_neighbour_site_params) not in (2, 3):
         raise InvalidConstraint(_.bad_connectivity_msg %
                                 (self.__class__.__name__,
                                  pivot_site_param.scatterers[0].label))
     uc = reparametrisation.structure.unit_cell()
     x_s = col(pivot_site)
     d_s = sorted((uc.distance(s, x_s), i)
                  for i, s in enumerate(pivot_neighbour_sites))
     return reparametrisation.add(
         _.secondary_planar_xh_site,
         pivot=pivot_site_param,
         pivot_neighbour_0=pivot_neighbour_site_params[d_s[0][1]],
         pivot_neighbour_1=pivot_neighbour_site_params[d_s[1][1]],
         length=bond_length,
         hydrogen=hydrogens[0])
Ejemplo n.º 11
0
 def add_hydrogen_to(self, reparametrisation, bond_length, pivot_site,
                     pivot_neighbour_sites, pivot_site_param,
                     pivot_neighbour_site_params, hydrogens, **kwds):
     if len(pivot_neighbour_site_params) != 2:
         raise InvalidConstraint(_.bad_connectivity_msg %
                                 (self.__class__.__name__,
                                  pivot_site_param.scatterers[0].label))
     x_h = [col(h.site) for h in hydrogens]
     x_p = col(pivot_site)
     uc = reparametrisation.structure.unit_cell()
     theta = col(uc.orthogonalize(x_h[0] - x_p)).angle(
         col(uc.orthogonalize(x_h[1] - x_p)))
     angle_param = None
     if self.flapping:
         angle_param = reparametrisation.add(_.independent_scalar_parameter,
                                             value=theta,
                                             variable=True)
     else:
         if self.angle is not None:
             angle_param = reparametrisation.add(
                 _.independent_scalar_parameter,
                 value=self.angle,
                 variable=False)
         else:
             angle_param = reparametrisation.add(
                 _.angle_parameter,
                 left=pivot_neighbour_site_params[0],
                 center=pivot_site_param,
                 right=pivot_neighbour_site_params[1],
                 value=theta)
     return reparametrisation.add(
         _.secondary_xh2_sites,
         pivot=pivot_site_param,
         pivot_neighbour_0=pivot_neighbour_site_params[0],
         pivot_neighbour_1=pivot_neighbour_site_params[1],
         length=bond_length,
         h_c_h_angle=angle_param,
         hydrogen_0=hydrogens[0],
         hydrogen_1=hydrogens[1])
Ejemplo n.º 12
0
    def add_to(self, reparametrisation):
        scatterers = reparametrisation.structure.scatterers()
        if not scatterers[self.ind_ref].flags.use_u_aniso() or\
           not scatterers[self.ind_atom].flags.use_u_aniso():
            raise InvalidConstraint(
                "only anisotropic atoms are allowed for shared rotated ADP")

        u_c = reparametrisation.add_new_thermal_displacement_parameter(
            self.ind_ref)
        angle = reparametrisation.add(_.independent_scalar_parameter,
                                      value=self.angle_value * pi / 180,
                                      variable=self.refine_angle)
        param = reparametrisation.add(
            _.shared_rotated_u_star,
            scatterer=scatterers[self.ind_atom],
            reference=u_c,
            direction=reparametrisation.find_direction(self.direction),
            angle=angle)
        reparametrisation.shared_Us[self.ind_atom] = u_c
        reparametrisation.asu_scatterer_parameters[self.ind_atom].u = param
        self.value = u_c
        self.angle = angle
Ejemplo n.º 13
0
 def __init__(self, var_refs, var_minus_one_refs):
     if (len(var_refs) + len(var_minus_one_refs)) == 0:
         raise InvalidConstraint("at least one atom is expected")
     self.as_var = var_refs
     self.as_one_minus_var = var_minus_one_refs
Ejemplo n.º 14
0
Archivo: rigid.py Proyecto: dials/cctbx
 def add_to(self, reparametrisation):
   if not self.fix_u and not self.fix_xyz:
     return
   scatterers = reparametrisation.structure.scatterers()
   ref_sites = []
   ref_u_isos = []
   ref_u_stars = []
   ref_adps = []
   src_crds = []
   inv_src_crds = []
   uc = reparametrisation.structure.unit_cell()
   for i in self.groups[0]:
     src_crds.append(uc.orthogonalize(scatterers[i].site))
     if self.fix_xyz:
       ref_sites.append(reparametrisation.add_new_site_parameter(i))
     if self.fix_u:
       if scatterers[i].flags.use_u_iso():
         ref_u_isos.append(
           reparametrisation.add_new_thermal_displacement_parameter(i))
       else:
         ref_u_stars.append(
           reparametrisation.add_new_thermal_displacement_parameter(i))
   for g in self.groups[1:]:
     if len(g) != len(self.groups[0]):
       raise InvalidConstraint("Group size mismatch")
     g_scatterers = []
     g_u_iso_scatterers  =[]
     g_u_star_scatterers = []
     crds = []
     for idx, i in enumerate(g):
       if scatterers[i].flags.use_u_iso() !=\
          scatterers[self.groups[0][idx]].flags.use_u_iso():
         raise InvalidConstraint("Mixing isotropic and anisotropic parameters")
       g_scatterers.append(scatterers[i])
       crds.append(uc.orthogonalize(scatterers[i].site))
       if scatterers[i].flags.use_u_iso():
         g_u_iso_scatterers.append(scatterers[i])
       else:
         g_u_star_scatterers.append(scatterers[i])
     #need to map reference to target
     lsf = superpose.least_squares_fit(
       flex.vec3_double(crds), flex.vec3_double(src_crds))
     #create a list of inverted coordinates if needed
     if len(inv_src_crds) == 0:
       for i in range(0, len(g)):
         inv_src_crds.append(
           2*matrix.col(lsf.other_shift)-matrix.col(src_crds[i]))
     rm = lsf.r
     t = matrix.col(lsf.reference_shift)-matrix.col(lsf.other_shift)
     new_crd = lsf.other_sites_best_fit()
     d = 0
     for i, c in enumerate(new_crd):
       d += matrix.col(matrix.col(c)-matrix.col(crds[i])).length_sq()
     lsf = superpose.least_squares_fit(
       flex.vec3_double(crds), flex.vec3_double(inv_src_crds))
     new_crd = lsf.other_sites_best_fit()
     d_inv = 0
     for i, c in enumerate(new_crd):
       d_inv += matrix.col(matrix.col(c)-matrix.col(crds[i])).length_sq()
     if d_inv < d:
       rm = -lsf.r
     if self.fix_xyz:
       shifts_and_angles =\
         reparametrisation.add(_.independent_small_6_vector_parameter,
                               value=(t[0],t[1],t[2],0,0,0), variable=True)
       if len(ref_u_stars) > 0:
         u_star_param = reparametrisation.add(
           _.same_group_u_star,
           scatterers=g_u_star_scatterers,
           u_stars=ref_u_stars,
           alignment_matrix=rm,
           shifts_and_angles=shifts_and_angles
         )
     elif len(ref_u_stars) > 0:
       angles =\
         reparametrisation.add(_.independent_small_3_vector_parameter,
                               value=self.angles, variable=True)
       u_star_param = reparametrisation.add(
         _.same_group_u_star,
         scatterers=g_u_star_scatterers,
         u_stars=ref_u_stars,
         alignment_matrix=rm,
         angles=angles
       )
     if self.fix_xyz:
       site_param = reparametrisation.add(
         _.same_group_xyz,
         scatterers=g_scatterers,
         sites=ref_sites,
         alignment_matrix=rm,
         shifts_and_angles=shifts_and_angles
       )
     if len(ref_u_isos) > 0:
       u_iso_param = reparametrisation.add(
         _.same_group_u_iso,
         scatterers=g_u_iso_scatterers,
         u_isos=ref_u_isos
       )
     site_proxy_index = 0
     u_star_proxy_index = 0
     u_iso_proxy_index = 0
     for i in g:
       if self.fix_xyz:
         reparametrisation.asu_scatterer_parameters[i].site = site_param
         reparametrisation.add_new_same_group_site_proxy_parameter(
           site_param, site_proxy_index, i)
         site_proxy_index += 1
       if self.fix_u:
         if scatterers[i].flags.use_u_iso():
           reparametrisation.asu_scatterer_parameters[i].u = u_iso_param
           reparametrisation.shared_Us[i] = reparametrisation.add(
             _.same_group_u_iso_proxy,
             parent=u_iso_param,
             index=u_iso_proxy_index
             )
           u_iso_proxy_index += 1
         else:
           reparametrisation.asu_scatterer_parameters[i].u = u_star_param
           reparametrisation.shared_Us[i] = reparametrisation.add(
             _.same_group_u_star_proxy,
             parent=u_star_param,
             index=u_star_proxy_index
             )
           u_star_proxy_index += 1
Ejemplo n.º 15
0
 def __init__(self, ind_sequence):
     if len(ind_sequence) < 2:
         raise InvalidConstraint("at least two atoms are expected")
     self.indices = ind_sequence