def test_rotaion_translation_input(self):
   """ Verify correct processing    """
   r1 = matrix.sqr([-0.955168,0.257340,-0.146391,
                    0.248227,0.426599,-0.869711,
                    -0.161362,-0.867058,-0.471352])
   r2 = matrix.sqr([-0.994267,-0.046533,-0.096268,
                    -0.065414,-0.447478,0.89189,
                    -0.084580,0.893083,0.441869])
   t1 = matrix.col([167.54320,-4.09250,41.98070])
   t2 = matrix.col([176.73730,27.41760,-5.85930])
   trans_obj = ncs.input(
     hierarchy=iotbx.pdb.input(source_info=None, lines=pdb_str2).construct_hierarchy(),
     rotations=[r1,r2],
     translations=[t1,t2])
   nrg = trans_obj.get_ncs_restraints_group_list()[0]
   self.assertEqual(list(nrg.master_iselection),[0, 1, 2, 3, 4, 5, 6, 7, 8])
   c1 = nrg.copies[0]
   self.assertEqual(list(c1.iselection),[9,10,11,12,13,14,15,16,17])
   c2 = nrg.copies[1]
   self.assertEqual(list(c2.iselection),[18,19,20,21,22,23,24,25,26])
   #
   self.assertEqual(r1,c1.r)
   self.assertEqual(r2,c2.r)
   self.assertEqual(t1,c1.t)
   self.assertEqual(t2,c2.t)
Exemplo n.º 2
0
  def get_detector_2theta (self) :
    from scitbx.matrix import col

    n = col(self._raw.get_detector()[0].get_normal())
    s0 = col(self._raw.get_beam().get_unit_s0())

    return s0.angle(n, deg=False)
Exemplo n.º 3
0
def exercise_similarity():

  model_1 = crystal_model(real_space_a=(10,0,0),
                          real_space_b=(0,11,0),
                          real_space_c=(0,0,12),
                          space_group_symbol="P 1",
                          mosaicity=0.5)
  model_2 = crystal_model(real_space_a=(10,0,0),
                          real_space_b=(0,11,0),
                          real_space_c=(0,0,12),
                          space_group_symbol="P 1",
                          mosaicity=0.5)
  assert model_1.is_similar_to(model_2)

  # mosaicity tests
  model_1.set_mosaicity(-1)
  model_2.set_mosaicity(-0.5)
  assert model_1.is_similar_to(model_2) # test ignores negative mosaicity
  model_1.set_mosaicity(0.5)
  model_2.set_mosaicity(0.63) # outside tolerance
  assert not model_1.is_similar_to(model_2)
  model_2.set_mosaicity(0.625) #just inside tolerance
  assert model_1.is_similar_to(model_2)

  # orientation tests
  R = model_2.get_U()
  dr1 = matrix.col((1, 0, 0)).axis_and_angle_as_r3_rotation_matrix(0.0101, deg=True)
  dr2 = matrix.col((1, 0, 0)).axis_and_angle_as_r3_rotation_matrix(0.0099, deg=True)
  model_2.set_U(dr1 * R)
  assert not model_1.is_similar_to(model_2) # outside tolerance
  model_2.set_U(dr2 * R)
  assert model_1.is_similar_to(model_2) # inside tolerance

  # unit_cell.is_similar_to is tested elsewhere
  return
Exemplo n.º 4
0
def reeke_model_for_use_case(phi_beg, phi_end, margin):
    """Construct a reeke_model for the geometry of the Use Case Thaumatin
  dataset, taken from the XDS XPARM. The values are hard-
  coded here so that this module does not rely on the location of that
  file."""

    axis = matrix.col([0.0, 1.0, 0.0])

    # original (unrotated) setting
    ub = matrix.sqr(
        [
            -0.0133393674072,
            -0.00541609051856,
            -0.00367748834997,
            0.00989309470346,
            0.000574825936669,
            -0.0054505379664,
            0.00475395109417,
            -0.0163935257377,
            0.00102384915696,
        ]
    )
    r_beg = matrix.sqr(scitbx.math.r3_rotation_axis_and_angle_as_matrix(axis=self._axis, angle=phi_beg, deg=True))
    r_osc = matrix.sqr(
        scitbx.math.r3_rotation_axis_and_angle_as_matrix(axis=self._axis, angle=(phi_end - phi_beg), deg=True)
    )

    ub_beg = r_beg * ub
    ub_end = self._r_osc * ub_mid
    s0 = matrix.col([0.00237878589035, 1.55544539299e-16, -1.09015329696])
    dmin = 1.20117776325

    return reeke_model(ub_beg, ub_end, axis, s0, dmin, margin)
Exemplo n.º 5
0
def _bipyramid(base):
  """
  Returns
  -------
  list of scitbx.matrix.col
  """
  return _concatenate(base, col([0, 0, 1]), col([0, 0, -1]))
Exemplo n.º 6
0
  def radial_transverse_analysis(self):
    # very time consuming; should be recoded (C++?)
    SIGN = -1.
    PIXEL_SZ = 0.11 # mm/pixel
    zunit = col([0.,0.,1.])
    self.frame_del_radial = {}
    self.frame_del_azimuthal = {}
    for x in xrange(len(self.frame_id)):
      frame_id = self.frame_id[x]
      frame_param_no = self.frame_id_to_param_no[frame_id]
      if frame_param_no >= self.n_refined_frames: continue
      if not self.frame_del_radial.has_key(frame_id):
        self.frame_del_radial[frame_id] = flex.double()
        self.frame_del_azimuthal[frame_id] = flex.double()

      correction_vector = col([self.correction_vector_x[x],self.correction_vector_y[x],0.])
      position_vector = col([self.spotfx[x] -
                      SIGN * self.FRAMES["detector_origin_x_refined"][frame_param_no]/PIXEL_SZ,
                             self.spotfy[x] -
                      SIGN * self.FRAMES["detector_origin_y_refined"][frame_param_no]/PIXEL_SZ,
                             0.])
      position_unit = position_vector.normalize()
      transverse_unit = position_unit.cross(zunit)

      self.frame_del_radial[frame_id].append(correction_vector.dot(position_unit))
      self.frame_del_azimuthal[frame_id].append(correction_vector.dot(transverse_unit))
Exemplo n.º 7
0
def water_bond_angle(o,h1,h2):
  result = None
  a = h1[0]-o[0], h1[1]-o[1], h1[2]-o[2]
  b = h2[0]-o[0], h2[1]-o[1], h2[2]-o[2]
  a = matrix.col(a)
  b = matrix.col(b)
  return a.angle(b, deg=True)
    def _goniometer(self):
        """Return a model for a simple single-axis goniometer. This should
    probably be checked against the image header, though for miniCBF
    there are limited options for this."""

        if "Phi" in self._cif_header_dictionary:
            phi_value = float(self._cif_header_dictionary["Phi"].split()[0])
        else:
            phi_value = 0.0

        if "Kappa" in self._cif_header_dictionary:
            kappa_value = float(self._cif_header_dictionary["Kappa"].split()[0])
        else:
            kappa_value = 0.0

        from scitbx import matrix

        axis = matrix.col((1, 0, 0))
        phi = matrix.col((1, 0, 0))
        kappa = matrix.col((0.914, 0.279, -0.297))

        Rphi = phi.axis_and_angle_as_r3_rotation_matrix(phi_value, deg=True)
        Rkappa = kappa.axis_and_angle_as_r3_rotation_matrix(kappa_value, deg=True)
        fixed = Rkappa * Rphi

        return self._goniometer_factory.make_goniometer(axis, fixed)
    def jacobian_callable(self,values):
      PB = self.get_partiality_array(values)
      EXP = flex.exp(-2.*values.BFACTOR*self.DSSQ)
      G_terms = (EXP * PB * self.ICALCVEC)
      B_terms = (values.G * EXP * PB * self.ICALCVEC)*(-2.*self.DSSQ)
      P_terms = (values.G * EXP * self.ICALCVEC)

      thetax = values.thetax; thetay = values.thetay;
      Rx = matrix.col((1,0,0)).axis_and_angle_as_r3_rotation_matrix(thetax)
      dRx_dthetax = matrix.col((1,0,0)).axis_and_angle_as_r3_derivative_wrt_angle(thetax)
      Ry = matrix.col((0,1,0)).axis_and_angle_as_r3_rotation_matrix(thetay)
      dRy_dthetay = matrix.col((0,1,0)).axis_and_angle_as_r3_derivative_wrt_angle(thetay)
      ref_ori = matrix.sqr(self.ORI.reciprocal_matrix())
      miller_vec = self.MILLER.as_vec3_double()
      ds1_dthetax = flex.mat3_double(len(self.MILLER),Ry * dRx_dthetax * ref_ori) * miller_vec
      ds1_dthetay = flex.mat3_double(len(self.MILLER),dRy_dthetay * Rx * ref_ori) * miller_vec

      s1vec = self.get_s1_array(values)
      s1lenvec = flex.sqrt(s1vec.dot(s1vec))
      dRh_dthetax = s1vec.dot(ds1_dthetax)/s1lenvec
      dRh_dthetay = s1vec.dot(ds1_dthetay)/s1lenvec
      rs = values.RS
      Rh = self.get_Rh_array(values)
      rs_sq = rs*rs
      denomin = (2. * Rh * Rh + rs_sq)
      dPB_dRh = -PB * 4. * Rh / denomin
      dPB_dthetax = dPB_dRh * dRh_dthetax
      dPB_dthetay = dPB_dRh * dRh_dthetay
      Px_terms = P_terms * dPB_dthetax; Py_terms = P_terms * dPB_dthetay

      dPB_drs = 4 * rs * Rh * Rh / (denomin * denomin)
      Prs_terms = P_terms * dPB_drs

      return [G_terms,B_terms,Prs_terms,Px_terms,Py_terms]
Exemplo n.º 10
0
  def LP_calculations(self, experiment, s1):
    '''See Kabsch, J. Appl. Cryst 1988 21 916-924.'''

    tpl_n = experiment.beam.get_polarization_normal()
    tpl_s0 = experiment.beam.get_s0()
    tpl_m2 = experiment.goniometer.get_rotation_axis()
    tpl_s1 = s1
    p = experiment.beam.get_polarization_fraction()

    # FIXME hack for testing
    # p = 0.5

    from scitbx import matrix

    n = matrix.col(tpl_n)
    s0 = matrix.col(tpl_s0)
    u = matrix.col(tpl_m2)
    s = matrix.col(tpl_s1)

    L_f = abs(s.dot(u.cross(s0))) / (s.length() * s0.length())

    P_f = (1 - 2 * p) * (1 - (n.dot(s) / s.length()) ** 2.0) + \
          p * (1 + (s.dot(s0) / (s.length() * s0.length())) ** 2.0)

    return L_f / P_f
 def as_g_alpha(self, hkl, d_star_sq):
     return g_exp_i_alpha_derivatives.parameters(
         g=self.w * math.exp(-2 * math.pi ** 2 * self.u * d_star_sq),
         ffp=1 + self.fp,
         fdp=self.fdp,
         alpha=2 * math.pi * matrix.col(self.xyz).dot(matrix.col(hkl)),
     )
Exemplo n.º 12
0
  def test_axis_orthogonal(self):
    """Ensure that the following are true:

    e1.s0 = 0, e1.s1 = 0
    e2.s1 = 0, e2.e1 = 0
    e3.e1 = 0, e3.p* = 0

    """
    from scitbx import matrix

    # Get as matrices
    e1 = matrix.col(self.cs.e1_axis())
    e2 = matrix.col(self.cs.e2_axis())
    e3 = matrix.col(self.cs.e3_axis())
    s0 = matrix.col(self.s0)
    s1 = matrix.col(self.s1)

    eps = 1e-7

    # Check that e1 is orthogonal to s0 and s1
    assert(abs(e1.dot(s0) - 0.0) <= eps)
    assert(abs(e1.dot(s1) - 0.0) <= eps)

    # Check that e2 is orthogonal to s1 and e1
    assert(abs(e2.dot(s1) - 0.0) <= eps)
    assert(abs(e2.dot(e1) - 0.0) <= eps)

    # Check that e3 is orthogonal to e1 and p* = s1 - s0
    assert(abs(e3.dot(e1) - 0.0) <= eps)
    assert(abs(e3.dot(s1 - s0) - 0.0) <= eps)

    # Test passed
    print "OK"
Exemplo n.º 13
0
    def __init__(self, phi0, misset0, phi1, misset1):
        """Initialise the rotation axis and what have you from some
    experimental results. N.B. all input values in DEGREES."""

        # canonical: X = X-ray beam
        #            Z = rotation axis
        #            Y = Z ^ X

        z = matrix.col([0, 0, 1])

        # then calculate the rotation axis

        R = (
            (
                z.axis_and_angle_as_r3_rotation_matrix(phi1, deg=True)
                * matrix.sqr(xyz_matrix(misset1[0], misset1[1], misset1[2]))
            )
            * (
                z.axis_and_angle_as_r3_rotation_matrix(phi0, deg=True)
                * matrix.sqr(xyz_matrix(misset0[0], misset0[1], misset0[2]))
            ).inverse()
        )

        self._z = z
        self._r = matrix.col(r3_rotation_axis_and_angle_from_matrix(R).axis)
        self._M0 = matrix.sqr(xyz_matrix(misset0[0], misset0[1], misset0[2]))

        return
Exemplo n.º 14
0
  def __init__(self,detector=None,camera=None,structure=None,simulation=None):
    ext.xfel1.__init__(self)

    self.detector=detector
    self.camera=camera
    self.structure=structure
    self.sim=simulation

    self.uc = self.structure.p1_cell()

    self.bmat = matrix.sqr(self.uc.orthogonalization_matrix()).inverse().transpose()
    self.Ori = crystal_orientation.crystal_orientation( self.bmat,
      crystal_orientation.basis_type.reciprocal )

    energy_in_eV = eV_per_inv_meter / (self.camera.lambda0) # lambda in meters

    # top hat function for dispersion
    self.full_pass_eV = energy_in_eV * matrix.col([1.-(self.sim.bandpass/2.),
                                              1.+(self.sim.bandpass/2.)])

    self.full_pass_lambda = eV_per_inv_meter * matrix.col((1./self.full_pass_eV[0],
                                                           1./self.full_pass_eV[1]))

    intensities = self.structure.p1_intensities()
    self.set_indices(intensities.indices())
    self.set_intensities(intensities.data())
Exemplo n.º 15
0
  def test_limit(self):
    """ Calculate the coordinate at the limits.

    Ensure that coordinate where s1' is orthogonal to s1 is at limit.

    """
    from scitbx import matrix
    from math import sqrt
    from random import uniform
    eps = 1e-7

    # Get the limit of s1'
    s_dash = matrix.col(self.s1).cross(matrix.col(self.s0))
    s_dash = s_dash.normalize() * matrix.col(self.s1).length()

    # Rotate arbitrarily
    s_dash = s_dash.rotate(matrix.col(self.s1), uniform(0, 360), deg=True)

    # Get the c1, c2 coordinate
    c1, c2 = self.cs.from_beam_vector(s_dash)

    # Check the point is equal to the limit in rs
    assert(abs(sqrt(c1**2 + c2**2) - abs(self.cs.limits()[0])) <= eps)

    # Test passed
    print 'OK'
Exemplo n.º 16
0
  def __init__(self, crystal, experiment_ids=[0]):

    # The state of a crystal orientation parameterisation is an orientation
    # matrix '[U]'. The initial state is a snapshot of the crystal
    # orientation at the time of initialisation '[U0]'. Future states are
    # composed by rotations around axes of the phi-axis frame by Tait-Bryan
    # angles.
    #
    # [U] = [Phi3][Phi2][Phi1][U0]

    ### Set up the initial state
    istate = crystal.get_U()

    ### Set up the parameters
    phi1 = Parameter(.0, matrix.col((1, 0, 0)), 'angle (mrad)', 'Phi1')
    phi2 = Parameter(.0, matrix.col((0, 1, 0)), 'angle (mrad)', 'Phi2')
    phi3 = Parameter(.0, matrix.col((0, 0, 1)), 'angle (mrad)', 'Phi3')

    # build the parameter list in a specific,  maintained order
    p_list = [phi1, phi2, phi3]

    # set up the base class
    ModelParameterisation.__init__(self, crystal, istate, p_list,
                                   experiment_ids=experiment_ids)

    # call compose to calculate all the derivatives
    self.compose()

    return
Exemplo n.º 17
0
def analyse_corrections(distance, wavelength, thickness):
  x_corr = read_xds_calibration_file('X-CORRECTIONS.cbf').as_double() * 0.1
  y_corr = read_xds_calibration_file('Y-CORRECTIONS.cbf').as_double() * 0.1
  o_squared = x_corr * x_corr + y_corr * y_corr

  dir_x = 2463 * 0.5
  dir_y = 2527 * 0.5

  pixel = 0.172

  from scitbx import matrix
  import math

  n = matrix.col((0, 0, 1))

  theta_o = { }

  for j in range(101):
    x = 0.01 * dir_x * j
    y = 0.01 * dir_y * j
    nx = nint(x / 4)
    ny = nint(y / 4)
    o = math.sqrt(o_squared[ny, nx])
    p = matrix.col((4 * pixel * (dir_x - x), 4 * pixel * (dir_y - y), distance))
    theta = p.angle(n)
    theta_o[theta] = o

  return theta_o
Exemplo n.º 18
0
  def __init__(self, orientation = None, translation = None, panelgroup = None):
    if orientation is None or translation is None:
      """
      Provide only orientation + translation or a panelgroup

      @param orientation rotation in the form of a quarternion
      @param translation vector translation in relation to the parent frame
      @param panelgroup dxtbx panelgroup object whose local d matrix will represent the
      basis shift
      """
      assert orientation is None and translation is None

      d_mat = panelgroup.get_local_d_matrix()
      fast = matrix.col((d_mat[0],d_mat[3],d_mat[6])).normalize()
      slow = matrix.col((d_mat[1],d_mat[4],d_mat[7])).normalize()
      orig = matrix.col((d_mat[2],d_mat[5],d_mat[8]))

      v3 = fast.cross(slow).normalize()

      r3 = matrix.sqr((fast[0],slow[0],v3[0],
                       fast[1],slow[1],v3[1],
                       fast[2],slow[2],v3[2]))

      self.orientation = r3.r3_rotation_matrix_as_unit_quaternion()
      self.translation = orig

    else:
      assert panelgroup is None
      self.orientation = orientation
      self.translation = translation
Exemplo n.º 19
0
def predict_angles(p0_star, experiment, s0=None):
  '''Predict Ewald sphere crossing angle for RLP x, returned in order
  (entering, exiting).'''

  from scitbx import matrix
  import math

  a = matrix.col(experiment.goniometer.get_rotation_axis())
  if s0 is None:
    b = matrix.col(experiment.beam.get_s0())
  else:
    b = s0

  m2 = a.normalize()
  m1 = m2.cross(b.normalize())
  m3 = m1.cross(m2)

  p0_sqr = p0_star.dot(p0_star)
  rho = math.sqrt(p0_sqr - p0_star.dot(m2) ** 2)
  p_star_m3 = (-0.5 * p0_sqr - p0_star.dot(m2) * b.dot(m2)) / b.dot(m3)
  p_star_m2 = p0_star.dot(m2)
  if rho ** 2 < p_star_m3 ** 2:
    return None
  p_star_m1 = math.sqrt(rho ** 2 - p_star_m3 ** 2)

  p0_star_m1 = p0_star.dot(m1)
  p0_star_m2 = p0_star.dot(m2)
  p0_star_m3 = p0_star.dot(m3)

  cp1 = + p_star_m1 * p0_star_m1 +  p_star_m3 * p0_star_m3
  cp2 = - p_star_m1 * p0_star_m1 +  p_star_m3 * p0_star_m3
  sp1 = + p_star_m1 * p0_star_m3 -  p_star_m3 * p0_star_m1
  sp2 = - p_star_m1 * p0_star_m3 -  p_star_m3 * p0_star_m1

  return math.atan2(sp1, cp1), math.atan2(sp2, cp2)
Exemplo n.º 20
0
def kabsch_rotation(reference_sites, other_sites):
  """
Kabsch, W. (1976). Acta Cryst. A32, 922-923.
A solution for the best rotation to relate two sets of vectors

Based on a prototype by Erik McKee and Reetal K. Pai.

This implementation does not handle degenerate situations correctly
(e.g. if all atoms are on a line or plane) and should therefore not
be used in applications. It is retained here for development purposes
only.
  """
  assert reference_sites.size() == other_sites.size()
  sts = matrix.sqr(other_sites.transpose_multiply(reference_sites))
  eigs = eigensystem.real_symmetric((sts * sts.transpose()).as_sym_mat3())
  vals = list(eigs.values())
  vecs = list(eigs.vectors())
  a3 = list(matrix.col(vecs[:3]).cross(matrix.col(vecs[3:6])))
  a = matrix.sqr(list(vecs[:6])+a3)
  b = list(a * sts)
  for i in xrange(3):
    d = math.sqrt(math.fabs(vals[i]))
    if (d > 0):
      for j in xrange(3):
        b[i*3+j] /= d
  b3 = list(matrix.col(b[:3]).cross(matrix.col(b[3:6])))
  b = matrix.sqr(b[:6]+b3)
  return b.transpose() * a
Exemplo n.º 21
0
  def add_sensor(quad_id, sensor_id, sensor):
    metro[(0,quad_id,sensor_id)] = basis_from_geo(sensor)

    x, y, z = sensor.get_pixel_coords()
    x/=1000; y/=1000; z/=1000
    assert x.shape == y.shape == z.shape
    sensor_px_slow = x.shape[0]
    sensor_px_fast = x.shape[1]
    assert sensor_px_fast % 2 == 0

    a0ul = sul = matrix.col((x[0,0],y[0,0],z[0,0]))
    a1ur = sur = matrix.col((x[0,sensor_px_fast-1],y[0,sensor_px_fast-1],z[0,sensor_px_fast-1]))
    a1lr = slr = matrix.col((x[sensor_px_slow-1,sensor_px_fast-1],y[sensor_px_slow-1,sensor_px_fast-1],z[sensor_px_slow-1,sensor_px_fast-1]))
    a0ll = sll = matrix.col((x[sensor_px_slow-1,0],y[sensor_px_slow-1,0],z[sensor_px_slow-1,0]))

    a0ur = matrix.col((x[0,sensor_px_fast//2-1],y[0,sensor_px_fast//2-1],z[0,sensor_px_fast//2-1]))
    a0lr = matrix.col((x[sensor_px_slow-1,sensor_px_fast//2-1],y[sensor_px_slow-1,sensor_px_fast//2-1],z[sensor_px_slow-1,sensor_px_fast//2-1]))

    a1ul = matrix.col((x[0,sensor_px_fast//2],y[0,sensor_px_fast//2],z[0,sensor_px_fast//2]))
    a1ll = matrix.col((x[sensor_px_slow-1,sensor_px_fast//2],y[sensor_px_slow-1,sensor_px_fast//2],z[sensor_px_slow-1,sensor_px_fast//2]))

    sensor_center = center([sul,sur,slr,sll])
    asic0_center = center([a0ul,a0ur,a0lr,a0ll])
    asic1_center = center([a1ul,a1ur,a1lr,a1ll])

    asic_trans0 = (asic0_center-sensor_center).length()
    asic_trans1 = (asic1_center-sensor_center).length()

    metro[(0,quad_id,sensor_id,0)] = basis(orientation=null_ori,translation=matrix.col((-asic_trans0,0,0)))
    metro[(0,quad_id,sensor_id,1)] = basis(orientation=null_ori,translation=matrix.col((+asic_trans1,0,0)))
Exemplo n.º 22
0
def exercise_is_simple_interaction():
  for space_group_symbol in ["P1", "P41"]:
    for shifts in flex.nested_loop((-2,-2,-2),(2,2,2),False):
      shifts = matrix.col(shifts)
      structure = xray.structure(
        crystal_symmetry=crystal.symmetry(
          unit_cell=(10,10,20,90,90,90),
          space_group_symbol=space_group_symbol),
        scatterers=flex.xray_scatterer([
          xray.scatterer(label="O", site=shifts+matrix.col((0,0,0))),
          xray.scatterer(label="N", site=shifts+matrix.col((0.5,0.5,0))),
          xray.scatterer(label="C", site=shifts+matrix.col((0.25,0.25,0)))]))
      asu_mappings = structure.asu_mappings(buffer_thickness=7)
      pair_generator = crystal.neighbors_simple_pair_generator(
        asu_mappings=asu_mappings,
        distance_cutoff=7)
      simple_interactions = {}
      for i_pair,pair in enumerate(pair_generator):
        if (asu_mappings.is_simple_interaction(pair)):
          assert asu_mappings_is_simple_interaction_emulation(
            asu_mappings, pair)
          key = (pair.i_seq,pair.j_seq)
          assert simple_interactions.get(key, None) is None
          simple_interactions[key] = 1
        else:
          assert not asu_mappings_is_simple_interaction_emulation(
            asu_mappings, pair)
      assert len(simple_interactions) == 2
      assert simple_interactions[(0,2)] == 1
      assert simple_interactions[(1,2)] == 1
Exemplo n.º 23
0
  def unstable_matrix_inversion_diagonal(self,Lower,Diag,Transpose):
    ### Can't use the Cholesky factorization to derive the Variance-Covariance matrix
    ### Demonstrate that inverting the matrix is numerically unstable
    Nx = len(self.helper.x)
    error_diagonal_elems = flex.double(Nx)
    for j_element in xrange(Nx):

      # now solve for the vector p = D * LT * x by substitution in eqn L * p = b
      # b is the column vector of zeroes except jth_element is 1.
      p = flex.double(Nx)
      p[j_element] = 1.
      for p_idx in xrange(j_element+1,Nx):
        for subs_idx in xrange(j_element,p_idx):
          p[p_idx] -= Lower(p_idx,subs_idx) * p[subs_idx]

      Pvec = col(p)

      # now solve for the vector q = LT * x by division in eqn D * q = b
      q = flex.double([ p[i] / Diag(i,i) for i in xrange(Nx)] )
      #  this is the unstable step.  We can't divide by tiny denominators
      Qvec = col(q)

      # now solve for the jth element of x in the eqn LT * x = q
      xelem = flex.double(Qvec.elems)

      for x_idx in xrange(Nx-1,j_element-1,-1):  #comment this in for production
      #for x_idx in xrange(Nx-1,-1,-1):
        for subs_idx in xrange(x_idx+1, Nx):
          xelem[x_idx] -= Transpose(x_idx,subs_idx) * xelem[subs_idx]
      Xvec = col(xelem) # got the whole vector; only need j_element for the error matrix diagonal
      error_diagonal_elems[j_element] = xelem[j_element]
    return col(error_diagonal_elems)
  def understand(image_file):
    '''Check to see if this looks like an Rayonix TIFF format image,
    i.e. we can make sense of it.  Returns true if the beam center is specified
    in pixels.'''

    width, height, depth, order, bytes = FormatTIFFRayonix.get_tiff_header(
        image_file)

    import struct
    from scitbx.matrix import col
    from dxtbx.format.FormatTIFFHelpers import LITTLE_ENDIAN, BIG_ENDIAN
    format = {LITTLE_ENDIAN:'<', BIG_ENDIAN:'>'}[order]
    offset = 1024

    detector_size_pixels = col(struct.unpack(format+'ii',bytes[offset+80:offset+88]))
    detector_center_px   = 0.5 * detector_size_pixels

    detector_pixel_sz_mm =  1.E-6 * col( # convert from nano to milli
                                struct.unpack(format+'ii',bytes[offset+772:offset+780]))

    header_beam_center = 0.001 * col( # Rayonix says this should be pixels
                                struct.unpack(format+'ii',bytes[offset+644:offset+652]))

    disagreement = header_beam_center[0]/detector_center_px[0]
    return header_beam_center[0] > 0 and header_beam_center[1] > 0 \
           and disagreement < 0.5  # if header was in mm, disagreement should be
Exemplo n.º 25
0
def exercise_ellipsoid(n_trials=100, n_sub_trials=10):
  from gltbx import quadrics
  rnd = random.Random(0)
  for i in xrange(n_trials):
    centre = matrix.col([ rnd.random() for k in xrange(3) ])
    half_lengths = matrix.col([ 0.1 + rnd.random() for k in xrange(3) ])
    r = scitbx.math.euler_angles_as_matrix(
      [ rnd.uniform(0, 360) for i in xrange(3) ], deg=True)
    metrics = r * matrix.diag([ x**2 for x in half_lengths ]) * r.transpose()
    t = quadrics.ellipsoid_to_sphere_transform(centre, metrics.as_sym_mat3())
    assert approx_equal(t.translation_part(), centre)
    m = matrix.sqr(t.linear_part())
    assert m.determinant() > 0
    for j in xrange(n_sub_trials):
      y = matrix.col([ rnd.random() for k in xrange(3) ])
      c_y = y.transpose() * y
      x = m*y
      c_x = x.transpose() * metrics.inverse() * x
      assert approx_equal(c_x, c_y)
  r = scitbx.math.euler_angles_as_matrix((30, 115, 260), deg=True)
  centre = matrix.col((-1, 2, 3))
  metrics = r * matrix.diag((-1, 0.1, 1)) * r.transpose()
  t = quadrics.ellipsoid_to_sphere_transform(centre, metrics.as_sym_mat3())
  assert t.non_positive_definite()
  x = r * matrix.col((1,0,0))
  assert x.transpose() * metrics.inverse() * x > 0
Exemplo n.º 26
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)
Exemplo n.º 27
0
def ersatz_misset(integrate_lp):
    a_s = []
    b_s = []
    c_s = []

    for record in open(integrate_lp):
        if 'COORDINATES OF UNIT CELL A-AXIS' in record:
            a = map(float, record.split()[-3:])
            a_s.append(matrix.col(a))
        elif 'COORDINATES OF UNIT CELL B-AXIS' in record:
            b = map(float, record.split()[-3:])
            b_s.append(matrix.col(b))
        elif 'COORDINATES OF UNIT CELL C-AXIS' in record:
            c = map(float, record.split()[-3:])
            c_s.append(matrix.col(c))

    assert(len(a_s) == len(b_s) == len(c_s))

    ub0 = matrix.sqr(a_s[0].elems + b_s[0].elems + c_s[0].elems).inverse()

    for j in range(len(a_s)):
        ub = matrix.sqr(a_s[j].elems + b_s[j].elems + c_s[j].elems).inverse()
        print '%7.3f %7.3f %7.3f' % tuple(xyz_angles(ub.inverse() * ub0))

    return
Exemplo n.º 28
0
def apply_sub_pixel_metrology(tile, x, y, tcx, tcy, phil,handedness=0):
  handedness -= 1
  if handedness < 0:
    return (x,y)

  if tile < 0: return None

  r = col((x, y))      # point of interest
  Ti = col((tcx,tcy))  # center of tile i

  # sub pixel translation/rotation
  if handednesses[handedness][h_swapped]:
    ti = col((phil.integration.subpixel_joint_model.translations[(tile*2)+1] * handednesses[handedness][h_y],
              phil.integration.subpixel_joint_model.translations[tile*2]     * handednesses[handedness][h_x]))
  else:
    ti = col((phil.integration.subpixel_joint_model.translations[tile*2]     * handednesses[handedness][h_x],
              phil.integration.subpixel_joint_model.translations[(tile*2)+1] * handednesses[handedness][h_y]))
  theta = phil.integration.subpixel_joint_model.rotations[tile] * (math.pi/180) * handednesses[handedness][h_theta]

  Ri = sqr((math.cos(theta),-math.sin(theta),math.sin(theta),math.cos(theta)))

  # apply sub-pixel translation to point of interest and tile center
  rp = r + ti     # p: prime
  Tip = Ti + ti

  result = (Ri*(rp-Tip))+Tip

  return (result[0], result[1])
Exemplo n.º 29
0
def tst_set_direction_wavelength():
  """Test setting direction and wavelength"""
  from scitbx import matrix
  direction = matrix.col((0.013142, 0.002200, 1.450476))
  unit_direction = direction.normalize()
  wavelength = 0.689400

  # Create the beam
  b = Beam(direction, wavelength)

  eps = 1e-7

  # Check direction is a unit vector
  assert(abs(matrix.col(b.get_direction()).length() - 1) <= eps)
  assert(abs(matrix.col(b.get_direction()) - unit_direction) <= eps)

  # Check wavelength is correct
  assert(abs(b.get_wavelength() - wavelength) <= eps)

  # Check s0 is in direction and has length 1/wavelength
  assert(abs(matrix.col(b.get_s0()).length() - 1.0 / wavelength) <= eps)
  assert(abs(-matrix.col(b.get_s0()).normalize() - unit_direction) <= eps)

  # Test passed
  print "OK"
Exemplo n.º 30
0
def unit_cell_bases_mean_square_difference(self, other):
  diff_sqs = flex.double()
  for basis_vector in [(1,0,0),(0,1,0),(0,0,1)]:
    self_v = matrix.col(self.orthogonalize(basis_vector))
    other_v = matrix.col(other.orthogonalize(basis_vector))
    diff_sqs.append((self_v - other_v).norm_sq())
  return flex.mean(diff_sqs)
Exemplo n.º 31
0
def exercise(verbose=0):
    distance_ideal = 1.8
    default_vdw_distance = 3.6
    vdw_1_4_factor = 3.5 / 3.6
    sites_cart_manual = flex.vec3_double([(1, 3, 0), (2, 3, 0), (3, 2, 0),
                                          (3, 1, 0), (4, 1, 0), (3, 4, 0),
                                          (4, 3, 0), (5, 3, 0), (6, 2, 0),
                                          (7, 2, 0), (8, 3, 0), (7, 4, 0),
                                          (6, 4, 0), (7, 5, 0), (6, 6, 0),
                                          (8, 6, 0)])
    bond_proxies = geometry_restraints.bond_sorted_asu_proxies(
        asu_mappings=None)
    for i_seqs in [(0, 1), (1, 2), (2, 3), (3, 4), (1, 5), (2, 6), (5, 6),
                   (6, 7), (7, 8), (8, 9), (9, 10), (10, 11), (11, 12),
                   (12, 7), (11, 13), (13, 14), (14, 15), (15, 13)]:
        bond_proxies.process(
            geometry_restraints.bond_simple_proxy(
                i_seqs=i_seqs, distance_ideal=distance_ideal, weight=100))
    angle_proxies = geometry_restraints.shared_angle_proxy()
    for i_seqs, angle_ideal in [[(0, 1, 2), 135], [(0, 1, 5), 135],
                                [(1, 2, 3), 135], [(3, 2, 6), 135],
                                [(2, 3, 4), 120], [(1, 2, 6), 90],
                                [(2, 6, 5), 90], [(6, 5, 1), 90],
                                [(5, 1, 2), 90], [(2, 6, 7), 135],
                                [(5, 6, 7), 135], [(6, 7, 8), 120],
                                [(6, 7, 12), 120], [(7, 8, 9), 120],
                                [(8, 9, 10), 120], [(9, 10, 11), 120],
                                [(10, 11, 12), 120], [(11, 12, 7), 120],
                                [(12, 7, 8), 120], [(10, 11, 13), 120],
                                [(12, 11, 13), 120], [(11, 13, 15), 150],
                                [(11, 13, 14), 150], [(13, 15, 14), 60],
                                [(15, 14, 13), 60], [(14, 13, 15), 60]]:
        angle_proxies.append(
            geometry_restraints.angle_proxy(i_seqs=i_seqs,
                                            angle_ideal=angle_ideal,
                                            weight=1))
    if (0 or verbose):
        dump_pdb(file_name="manual.pdb", sites_cart=sites_cart_manual)
    for traditional_convergence_test in [True, False]:
        for sites_cart_selection in [True, False]:
            sites_cart = sites_cart_manual.deep_copy()
            if sites_cart_selection:
                sites_cart_selection = flex.bool(sites_cart.size(), True)
                sites_cart_selection[1] = False
            assert bond_proxies.asu.size() == 0
            bond_params_table = geometry_restraints.extract_bond_params(
                n_seq=sites_cart.size(),
                bond_simple_proxies=bond_proxies.simple)
            manager = geometry_restraints.manager.manager(
                bond_params_table=bond_params_table,
                angle_proxies=angle_proxies)
            minimized = geometry_restraints.lbfgs.lbfgs(
                sites_cart=sites_cart,
                geometry_restraints_manager=manager,
                lbfgs_termination_params=scitbx.lbfgs.termination_parameters(
                    traditional_convergence_test=traditional_convergence_test,
                    drop_convergence_test_max_drop_eps=1.e-20,
                    drop_convergence_test_iteration_coefficient=1,
                    max_iterations=1000),
                sites_cart_selection=sites_cart_selection,
            )
            assert minimized.minimizer.iter() > 100
            sites_cart_minimized_1 = sites_cart.deep_copy()
            if (0 or verbose):
                dump_pdb(file_name="minimized_1.pdb",
                         sites_cart=sites_cart_minimized_1)
            bond_deltas = geometry_restraints.bond_deltas(
                sites_cart=sites_cart_minimized_1, proxies=bond_proxies.simple)
            angle_deltas = geometry_restraints.angle_deltas(
                sites_cart=sites_cart_minimized_1, proxies=angle_proxies)
            if (0 or verbose):
                for proxy, delta in zip(bond_proxies.simple, bond_deltas):
                    print("bond:", proxy.i_seqs, delta)
                for proxy, delta in zip(angle_proxies, angle_deltas):
                    print("angle:", proxy.i_seqs, delta)
            assert is_below_limit(value=flex.max(flex.abs(bond_deltas)),
                                  limit=0,
                                  eps=1.e-6)
            assert is_below_limit(value=flex.max(flex.abs(angle_deltas)),
                                  limit=0,
                                  eps=2.e-6)
    sites_cart += matrix.col((1, 1, 0)) - matrix.col(sites_cart.min())
    unit_cell_lengths = list(
        matrix.col(sites_cart.max()) + matrix.col((1, -1.2, 4)))
    unit_cell_lengths[1] *= 2
    unit_cell_lengths[2] *= 2
    xray_structure = xray.structure(crystal_symmetry=crystal.symmetry(
        unit_cell=unit_cell_lengths, space_group_symbol="P112"))
    for serial, site in zip(count(1), sites_cart):
        xray_structure.add_scatterer(
            xray.scatterer(
                label="C%02d" % serial,
                site=xray_structure.unit_cell().fractionalize(site)))
    if (0 or verbose):
        xray_structure.show_summary().show_scatterers()
    p1_structure = (xray_structure.apply_shift(
        (-.5, -.5, 0)).expand_to_p1().apply_shift((.5, .5, 0)))
    for shift in [(1, 0, 0), (0, 1, 0), (0, 0, 1)]:
        p1_structure.add_scatterers(
            p1_structure.apply_shift(shift).scatterers())
    if (0 or verbose):
        open("p1_structure.pdb", "w").write(p1_structure.as_pdb_file())
    nonbonded_cutoff = 6.5
    asu_mappings = xray_structure.asu_mappings(
        buffer_thickness=nonbonded_cutoff)
    bond_asu_table = crystal.pair_asu_table(asu_mappings=asu_mappings)
    geometry_restraints.add_pairs(bond_asu_table, bond_proxies.simple)
    shell_asu_tables = crystal.coordination_sequences.shell_asu_tables(
        pair_asu_table=bond_asu_table, max_shell=3)
    shell_sym_tables = [
        shell_asu_table.extract_pair_sym_table()
        for shell_asu_table in shell_asu_tables
    ]
    bond_params_table = geometry_restraints.extract_bond_params(
        n_seq=sites_cart.size(), bond_simple_proxies=bond_proxies.simple)
    atom_energy_types = flex.std_string(sites_cart.size(), "Default")
    nonbonded_params = geometry_restraints.nonbonded_params(
        factor_1_4_interactions=vdw_1_4_factor,
        const_shrink_1_4_interactions=0,
        default_distance=default_vdw_distance)
    nonbonded_params.distance_table.setdefault(
        "Default")["Default"] = default_vdw_distance
    pair_proxies = geometry_restraints.pair_proxies(
        bond_params_table=bond_params_table,
        shell_asu_tables=shell_asu_tables,
        model_indices=None,
        conformer_indices=None,
        nonbonded_params=nonbonded_params,
        nonbonded_types=atom_energy_types,
        nonbonded_distance_cutoff_plus_buffer=nonbonded_cutoff)
    if (0 or verbose):
        print("pair_proxies.bond_proxies.n_total():", \
               pair_proxies.bond_proxies.n_total(), end=' ')
        print("simple:", pair_proxies.bond_proxies.simple.size(), end=' ')
        print("sym:", pair_proxies.bond_proxies.asu.size())
        print("pair_proxies.nonbonded_proxies.n_total():", \
               pair_proxies.nonbonded_proxies.n_total(), end=' ')
        print("simple:", pair_proxies.nonbonded_proxies.simple.size(), end=' ')
        print("sym:", pair_proxies.nonbonded_proxies.asu.size())
        print("min_distance_nonbonded: %.2f" % flex.min(
            geometry_restraints.nonbonded_deltas(
                sites_cart=sites_cart,
                sorted_asu_proxies=pair_proxies.nonbonded_proxies)))
    s = StringIO()
    pair_proxies.bond_proxies.show_histogram_of_model_distances(
        sites_cart=sites_cart, f=s, prefix="[]")
    assert s.getvalue().splitlines()[0] == "[]Histogram of bond lengths:"
    assert s.getvalue().splitlines()[5].startswith("[]      1.80 -     1.80:")
    s = StringIO()
    pair_proxies.bond_proxies.show_histogram_of_deltas(sites_cart=sites_cart,
                                                       f=s,
                                                       prefix="][")
    assert s.getvalue().splitlines()[0] == "][Histogram of bond deltas:"
    assert s.getvalue().splitlines()[5].startswith("][     0.000 -    0.000:")
    s = StringIO()
    pair_proxies.bond_proxies.show_sorted(by_value="residual",
                                          sites_cart=sites_cart,
                                          max_items=3,
                                          f=s,
                                          prefix=":;")
    l = s.getvalue().splitlines()
    assert l[0] == ":;Bond restraints: 18"
    assert l[1] == ":;Sorted by residual:"
    assert l[2].startswith(":;bond ")
    assert l[3].startswith(":;     ")
    assert l[4] == ":;  ideal  model  delta    sigma   weight residual"
    for i in [5, -2]:
        assert l[i].startswith(":;  1.800  1.800 ")
    assert l[-1] == ":;... (remaining 15 not shown)"
    s = StringIO()
    pair_proxies.nonbonded_proxies.show_histogram_of_model_distances(
        sites_cart=sites_cart, f=s, prefix="]^")
    assert not show_diff(
        s.getvalue(), """\
]^Histogram of nonbonded interaction distances:
]^      2.16 -     3.03: 3
]^      3.03 -     3.89: 12
]^      3.89 -     4.75: 28
]^      4.75 -     5.61: 44
]^      5.61 -     6.48: 54
""")
    s = StringIO()
    pair_proxies.nonbonded_proxies.show_sorted(by_value="delta",
                                               sites_cart=sites_cart,
                                               max_items=7,
                                               f=s,
                                               prefix=">,")
    assert not show_diff(s.getvalue(),
                         """\
>,Nonbonded interactions: 141
>,Sorted by model distance:
>,nonbonded 15
>,          15
>,   model   vdw sym.op.
>,   2.164 3.600 -x+2,-y+1,z
...
>,nonbonded 4
>,          8
>,   model   vdw
>,   3.414 3.600
>,... (remaining 134 not shown)
""",
                         selections=[range(6), range(-5, 0)])
    vdw_1_sticks = []
    vdw_2_sticks = []
    for proxy in pair_proxies.nonbonded_proxies.simple:
        if (proxy.vdw_distance == default_vdw_distance):
            vdw_1_sticks.append(
                pml_stick(begin=sites_cart[proxy.i_seqs[0]],
                          end=sites_cart[proxy.i_seqs[1]]))
        else:
            vdw_2_sticks.append(
                pml_stick(begin=sites_cart[proxy.i_seqs[0]],
                          end=sites_cart[proxy.i_seqs[1]]))
    mps = asu_mappings.mappings()
    for proxy in pair_proxies.nonbonded_proxies.asu:
        if (proxy.vdw_distance == default_vdw_distance):
            vdw_1_sticks.append(
                pml_stick(begin=mps[proxy.i_seq][0].mapped_site(),
                          end=mps[proxy.j_seq][proxy.j_sym].mapped_site()))
        else:
            vdw_2_sticks.append(
                pml_stick(begin=mps[proxy.i_seq][0].mapped_site(),
                          end=mps[proxy.j_seq][proxy.j_sym].mapped_site()))
    if (0 or verbose):
        pml_write(f=open("vdw_1.pml", "w"), label="vdw_1", sticks=vdw_1_sticks)
        pml_write(f=open("vdw_2.pml", "w"), label="vdw_2", sticks=vdw_2_sticks)
    #
    i_pdb = count(2)
    for use_crystal_symmetry in [False, True]:
        if (not use_crystal_symmetry):
            crystal_symmetry = None
            site_symmetry_table = None
        else:
            crystal_symmetry = xray_structure
            site_symmetry_table = xray_structure.site_symmetry_table()
        for sites_cart in [
                sites_cart_manual.deep_copy(),
                sites_cart_minimized_1.deep_copy()
        ]:
            manager = geometry_restraints.manager.manager(
                crystal_symmetry=crystal_symmetry,
                site_symmetry_table=site_symmetry_table,
                nonbonded_params=nonbonded_params,
                nonbonded_types=atom_energy_types,
                nonbonded_function=geometry_restraints.
                prolsq_repulsion_function(),
                bond_params_table=bond_params_table,
                shell_sym_tables=shell_sym_tables,
                nonbonded_distance_cutoff=nonbonded_cutoff,
                nonbonded_buffer=1,
                angle_proxies=angle_proxies,
                plain_pairs_radius=5)
            manager = manager.select(
                selection=flex.bool(sites_cart.size(), True))
            manager = manager.select(iselection=flex.size_t_range(
                stop=sites_cart.size()))
            pair_proxies = manager.pair_proxies(sites_cart=sites_cart)
            minimized = geometry_restraints.lbfgs.lbfgs(
                sites_cart=sites_cart,
                geometry_restraints_manager=manager,
                lbfgs_termination_params=scitbx.lbfgs.termination_parameters(
                    max_iterations=1000))
            if (0 or verbose):
                minimized.final_target_result.show()
                print("number of function evaluations:",
                      minimized.minimizer.nfun())
                print("n_updates_pair_proxies:",
                      manager.n_updates_pair_proxies)
            if (not use_crystal_symmetry):
                assert minimized.final_target_result.bond_residual_sum < 1.e-3
                assert minimized.final_target_result.nonbonded_residual_sum < 0.1
            else:
                assert minimized.final_target_result.bond_residual_sum < 1.e-2
                assert minimized.final_target_result.nonbonded_residual_sum < 0.1
            assert minimized.final_target_result.angle_residual_sum < 1.e-3
            if (0 or verbose):
                pdb_file_name = "minimized_%d.pdb" % next(i_pdb)
                print("Writing file:", pdb_file_name)
                dump_pdb(file_name=pdb_file_name, sites_cart=sites_cart)
            if (manager.site_symmetry_table is None):
                additional_site_symmetry_table = None
            else:
                additional_site_symmetry_table = sgtbx.site_symmetry_table()
            assert manager.new_including_isolated_sites(
              n_additional_sites=0,
              site_symmetry_table=additional_site_symmetry_table,
              nonbonded_types=flex.std_string()).plain_pairs_radius \
                == manager.plain_pairs_radius
            if (crystal_symmetry is not None):
                assert len(manager.plain_pair_sym_table) == 16
                if (0 or verbose):
                    manager.plain_pair_sym_table.show()
    #
    xray_structure.set_u_iso(values=flex.double([
        0.77599982480241358, 0.38745781137212021, 0.20667558236418682,
        0.99759840171302094, 0.8917287406687805, 0.64780251325379845,
        0.24878590382983534, 0.59480621182194615, 0.58695637792905142,
        0.33997130213653637, 0.51258699130743735, 0.79760289141276675,
        0.39996577657875021, 0.4329328819341467, 0.70422156561726479,
        0.87260110626999332
    ]))

    class parameters:
        pass

    parameters.sphere_radius = 5
    parameters.distance_power = 0.7
    parameters.average_power = 0.9
    parameters.wilson_b_weight = 1.3952
    parameters.wilson_b_weight_auto = False
    adp_energies = adp_restraints.energies_iso(
        geometry_restraints_manager=manager,
        xray_structure=xray_structure,
        parameters=parameters,
        wilson_b=None,
        use_hd=False,
        use_u_local_only=False,
        compute_gradients=False,
        gradients=None,
        normalization=False,
        collect=True)
    assert adp_energies.number_of_restraints == 69
    assert approx_equal(adp_energies.residual_sum, 6.24865382467)
    assert adp_energies.gradients is None
    assert adp_energies.u_i.size() == adp_energies.number_of_restraints
    assert adp_energies.u_j.size() == adp_energies.number_of_restraints
    assert adp_energies.r_ij.size() == adp_energies.number_of_restraints
    for wilson_b in [None, 10, 100]:
        finite_difference_gradients = flex.double()
        eps = 1.e-6
        for i_scatterer in range(xray_structure.scatterers().size()):
            rs = []
            for signed_eps in [eps, -eps]:
                xray_structure_eps = xray_structure.deep_copy_scatterers()
                xray_structure_eps.scatterers(
                )[i_scatterer].u_iso += signed_eps
                adp_energies = adp_restraints.energies_iso(
                    geometry_restraints_manager=manager,
                    xray_structure=xray_structure_eps,
                    parameters=parameters,
                    wilson_b=wilson_b,
                    use_u_local_only=False,
                    use_hd=False,
                    compute_gradients=True,
                    gradients=None,
                    normalization=False,
                    collect=False)
                rs.append(adp_energies.residual_sum)
                assert adp_energies.gradients.size() \
                    == xray_structure.scatterers().size()
                assert adp_energies.u_i == None
                assert adp_energies.u_j == None
                assert adp_energies.r_ij == None
            finite_difference_gradients.append((rs[0] - rs[1]) / (2 * eps))
        sel = flex.bool(xray_structure.scatterers().size(), True)
        xray_structure.scatterers().flags_set_grad_u_iso(sel.iselection())
        adp_energies = adp_restraints.energies_iso(
            geometry_restraints_manager=manager,
            xray_structure=xray_structure,
            parameters=parameters,
            wilson_b=wilson_b,
            use_u_local_only=False,
            use_hd=False,
            compute_gradients=True,
            gradients=None,
            normalization=False,
            collect=False)
        assert approx_equal(adp_energies.gradients,
                            finite_difference_gradients)
    print("OK")
Exemplo n.º 32
0
    def __call__(self, reflections, experiments, d_min=None):
        from libtbx.math_utils import nearest_integer as nint
        from scitbx import matrix

        reciprocal_lattice_points = reflections["rlp"]
        if "miller_index" not in reflections:
            reflections["miller_index"] = flex.miller_index(len(reflections))
        if d_min is not None:
            d_spacings = 1 / reciprocal_lattice_points.norms()
            inside_resolution_limit = d_spacings > d_min
        else:
            inside_resolution_limit = flex.bool(
                reciprocal_lattice_points.size(), True)
        sel = inside_resolution_limit & (reflections["id"] == -1)
        isel = sel.iselection()
        rlps = reciprocal_lattice_points.select(isel)
        refs = reflections.select(isel)
        phi = refs["xyzobs.mm.value"].parts()[2]

        if len(rlps) <= self._nearest_neighbours:
            raise DialsIndexError(
                "index_assignment.local.nearest_neighbour must be smaller than the number of accepted reflections (%d)"
                % len(rlps))

        UB_matrices = flex.mat3_double(
            [cm.get_A() for cm in experiments.crystals()])

        result = ext.AssignIndicesLocal(
            rlps,
            phi,
            UB_matrices,
            epsilon=self._epsilon,
            delta=self._delta,
            l_min=self._l_min,
            nearest_neighbours=self._nearest_neighbours,
        )
        miller_indices = result.miller_indices()
        crystal_ids = result.crystal_ids()
        hkl = miller_indices.as_vec3_double().iround()

        assert miller_indices.select(crystal_ids < 0).all_eq((0, 0, 0))

        for i_cryst in set(crystal_ids):
            if i_cryst < 0:
                continue

            A = matrix.sqr(experiments[i_cryst].crystal.get_A())
            A_inv = A.inverse()

            cryst_sel = crystal_ids == i_cryst
            rlp_sel = rlps.select(cryst_sel)
            hkl_sel = hkl.select(cryst_sel).as_vec3_double()

            d_sel = 1 / rlp_sel.norms()
            d_perm = flex.sort_permutation(d_sel, reverse=True)

            hf_0 = A_inv * rlp_sel[d_perm[0]]
            h_0 = matrix.col([nint(j) for j in hf_0.elems])
            offset = h_0 - matrix.col(hkl_sel[d_perm[0]])
            # print "offset:", offset.elems

            h = hkl_sel + flex.vec3_double(hkl_sel.size(), offset.elems)

            refs["miller_index"].set_selected(
                cryst_sel, flex.miller_index(list(h.iround())))
            refs["id"].set_selected(cryst_sel, i_cryst)

        crystal_ids.set_selected(crystal_ids < 0, -1)
        refs["id"] = crystal_ids
        refs["miller_index"].set_selected(crystal_ids < 0, (0, 0, 0))

        reflections["miller_index"].set_selected(isel, refs["miller_index"])
        reflections["id"].set_selected(isel, refs["id"])
        reflections.set_flags(reflections["miller_index"] != (0, 0, 0),
                              reflections.flags.indexed)
Exemplo n.º 33
0
    def _detector(self):
        '''Return a model for the detector, allowing for two-theta offsets
    and the detector position. This will be rather more complex...'''

        from scitbx import matrix

        detector_name = self._header_dictionary['DETECTOR_NAMES'].split(
        )[0].strip()

        detector_axes = map(
            float, self._header_dictionary['%sDETECTOR_VECTORS' %
                                           detector_name].split())

        fast = matrix.col(tuple(detector_axes[:3]))
        slow = matrix.col(tuple(detector_axes[3:]))

        distortion = map(
            int, self._header_dictionary['%sSPATIAL_DISTORTION_VECTORS' %
                                         detector_name].split())

        # multiply through by the distortion to get the true detector fast, slow

        detector_fast, detector_slow = distortion[0] * fast + distortion[1] * slow, \
          distortion[2] * fast + distortion[3] * slow

        beam_pixels = map(
            float, self._header_dictionary['%sSPATIAL_DISTORTION_INFO' %
                                           detector_name].split()[:2])
        pixel_size = map(
            float, self._header_dictionary['%sSPATIAL_DISTORTION_INFO' %
                                           detector_name].split()[2:])
        image_size = map(
            int, self._header_dictionary['%sDETECTOR_DIMENSIONS' %
                                         detector_name].split())

        detector_origin = - (beam_pixels[0] * pixel_size[0] * detector_fast + \
                             beam_pixels[1] * pixel_size[1] * detector_slow)

        gonio_axes = map(
            float,
            self._header_dictionary['%sGONIO_VECTORS' % detector_name].split())
        gonio_values = map(
            float,
            self._header_dictionary['%sGONIO_VALUES' % detector_name].split())
        gonio_units = self._header_dictionary['%sGONIO_UNITS' %
                                              detector_name].split()
        gonio_num_axes = int(self._header_dictionary['%sGONIO_NUM_VALUES' %
                                                     detector_name])

        rotations = []
        translations = []

        for j, unit in enumerate(gonio_units):
            axis = matrix.col(gonio_axes[3 * j:3 * (j + 1)])
            if unit == 'deg':
                rotations.append(
                    axis.axis_and_angle_as_r3_rotation_matrix(gonio_values[j],
                                                              deg=True))
                translations.append(matrix.col((0.0, 0.0, 0.0)))
            elif unit == 'mm':
                rotations.append(
                    matrix.sqr((1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0)))
                translations.append(gonio_values[j] * axis)
            else:
                raise RuntimeError, 'unknown axis unit %s' % unit

        rotations.reverse()
        translations.reverse()

        for j in range(gonio_num_axes):
            detector_fast = rotations[j] * detector_fast
            detector_slow = rotations[j] * detector_slow
            detector_origin = rotations[j] * detector_origin
            detector_origin = translations[j] + detector_origin

        overload = int(float(self._header_dictionary['SATURATED_VALUE']))
        underload = 0

        return self._detector_factory.complex('PAD', detector_origin.elems,
                                              detector_fast.elems,
                                              detector_slow.elems, pixel_size,
                                              image_size,
                                              (underload, overload))
Exemplo n.º 34
0
    def _detector(self):
        """Detector model, allowing for small offsets in the positions of 60
        detector modules"""

        distance = float(
            self._cif_header_dictionary["Detector_distance"].split()[0])

        beam_xy = (self._cif_header_dictionary["Beam_xy"].replace(
            "(", "").replace(")", "").replace(",", "").split()[:2])

        beam_x, beam_y = map(float, beam_xy)

        wavelength = float(
            self._cif_header_dictionary["Wavelength"].split()[0])

        pixel_xy = (self._cif_header_dictionary["Pixel_size"].replace(
            "m", "").replace("x", "").split())

        pixel_x, pixel_y = map(float, pixel_xy)

        thickness = float(
            self._cif_header_dictionary["Silicon"].split()[2]) * 1000.0

        nx = int(
            self._cif_header_dictionary["X-Binary-Size-Fastest-Dimension"])
        ny = int(self._cif_header_dictionary["X-Binary-Size-Second-Dimension"])

        overload = int(self._cif_header_dictionary["Count_cutoff"].split()[0])
        underload = -1

        # take into consideration here the thickness of the sensor also the
        # wavelength of the radiation (which we have in the same file...)
        table = attenuation_coefficient.get_table("Si")
        mu = table.mu_at_angstrom(wavelength) / 10.0
        t0 = thickness

        # FIXME would also be very nice to be able to take into account the
        # misalignment of the individual modules given the calibration...

        # single detector or multi-module detector

        pixel_x *= 1000.0
        pixel_y *= 1000.0
        distance *= 1000.0

        if not self._multi_panel:
            detector = self._detector_factory.simple(
                "PAD",
                distance,
                (beam_x * pixel_x, beam_y * pixel_y),
                "+x",
                "-y",
                (pixel_x, pixel_y),
                (nx, ny),
                (underload, overload),
                [],
                ParallaxCorrectedPxMmStrategy(mu, t0),
            )

            for f0, f1, s0, s1 in determine_pilatus_mask(detector):
                detector[0].add_mask(f0 - 1, s0 - 1, f1, s1)

            detector[0].set_thickness(thickness)
            detector[0].set_material("Si")
            detector[0].set_mu(mu)

            return detector

        # got to here means 60-panel version
        d = Detector()

        beam_centre = matrix.col((beam_x * pixel_x, beam_y * pixel_y, 0))

        fast = matrix.col((1.0, 0.0, 0.0))
        slow = matrix.col((0.0, -1.0, 0.0))
        s0 = matrix.col((0, 0, -1))
        origin = (distance * s0) - (fast * beam_centre[0]) - (slow *
                                                              beam_centre[1])

        root = d.hierarchy()
        root.set_local_frame(fast.elems, slow.elems, origin.elems)

        xmins = [0, 494, 988, 1482, 1976]
        xmaxes = [487, 981, 1475, 1969, 2463]
        ymins = [
            0, 212, 424, 636, 848, 1060, 1272, 1484, 1696, 1908, 2120, 2332
        ]
        ymaxes = [
            195, 407, 619, 831, 1043, 1255, 1467, 1679, 1891, 2103, 2315, 2527
        ]

        self.coords = {}

        fast = matrix.col((1.0, 0.0, 0.0))
        slow = matrix.col((0.0, 1.0, 0.0))
        panel_idx = 0
        for ymin, ymax in zip(ymins, ymaxes):
            for xmin, xmax in zip(xmins, xmaxes):
                xmin_mm = xmin * pixel_x
                ymin_mm = ymin * pixel_y

                origin_panel = fast * xmin_mm + slow * ymin_mm

                panel_name = "Panel%d" % panel_idx
                panel_idx += 1

                p = d.add_panel()
                p.set_type("SENSOR_PAD")
                p.set_name(panel_name)
                p.set_raw_image_offset((xmin, ymin))
                p.set_image_size((xmax - xmin, ymax - ymin))
                p.set_trusted_range((underload, overload))
                p.set_pixel_size((pixel_x, pixel_y))
                p.set_thickness(thickness)
                p.set_material("Si")
                p.set_mu(mu)
                p.set_px_mm_strategy(ParallaxCorrectedPxMmStrategy(mu, t0))
                p.set_local_frame(fast.elems, slow.elems, origin_panel.elems)
                p.set_raw_image_offset((xmin, ymin))
                self.coords[panel_name] = (xmin, ymin, xmax, ymax)

        return d
Exemplo n.º 35
0
  def _detector(self):
    '''Detector model, allowing for small offsets in the positions of 60
    detector modules'''

    # Module positional offsets in x, y, in pixels - for the moment ignoring the
    # rotational offsets as these are not well defined. To be honest these
    # positional offsets are also not well defined as I do not know how they
    # should be applied...

    x = {
      (0, 0):  -0.477546,   (0, 1):   0.130578,   (0, 2):   0.045041,
      (0, 3):  -0.439872,   (0, 4):  -0.382077,   (1, 0):   0.087405,
      (1, 1):   0.249597,   (1, 2):   0.184265,   (1, 3):   0.158342,
      (1, 4):   0.025225,   (2, 0):  -0.179892,   (2, 1):  -0.010974,
      (2, 2):  -0.139207,   (2, 3):   0.282851,   (2, 4):  -0.442219,
      (3, 0):  -0.185027,   (3, 1):   0.218601,   (3, 2):   0.092585,
      (3, 3):    0.35862,   (3, 4):   -0.29161,   (4, 0):   0.145368,
      (4, 1):   0.609289,   (4, 2):   0.396265,   (4, 3):    0.41625,
      (4, 4):    0.07152,   (5, 0):   0.247142,   (5, 1):   0.046563,
      (5, 2):   0.248714,   (5, 3):  -0.044628,   (5, 4):  -0.391509,
      (6, 0):   0.516643,   (6, 1):   0.358453,   (6, 2):   0.069219,
      (6, 3):   0.095861,   (6, 4):  -0.167403,   (7, 0):  -0.381352,
      (7, 1):   -0.35338,   (7, 2):   0.348656,   (7, 3):   0.024543,
      (7, 4):   0.328706,   (8, 0):   0.150886,   (8, 1):   0.244987,
      (8, 2):  -0.102911,   (8, 3):    0.16633,   (8, 4):   0.386622,
      (9, 0):   0.037924,   (9, 1):   0.314392,   (9, 2):   0.238818,
      (9, 3):   0.815028,   (9, 4):  -0.048818,  (10, 0):  -0.670524,
      (10, 1):  -0.304119,  (10, 2):   0.252284,  (10, 3):   -0.05485,
      (10, 4):  -0.355264,  (11, 0):  -0.404947,  (11, 1):  -0.020622,
      (11, 2):   0.648473,  (11, 3):  -0.277175,  (11, 4):  -0.711951
    }

    y = {
      (0, 0):  -0.494797,   (0, 1):  -0.212976,   (0, 2):   0.085351,
      (0, 3):    0.35494,   (0, 4):   0.571189,   (1, 0):  -0.421708,
      (1, 1):   0.061914,   (1, 2):   0.238996,   (1, 3):   0.146692,
      (1, 4):   0.407145,   (2, 0):  -0.313212,   (2, 1):  -0.225025,
      (2, 2):   0.031613,   (2, 3):  -0.047839,   (2, 4):    0.42716,
      (3, 0):  -0.361193,   (3, 1):   0.057663,   (3, 2):   0.022357,
      (3, 3):   0.062717,   (3, 4):   0.150611,   (4, 0):   0.035511,
      (4, 1):  -0.271567,   (4, 2):   0.007761,   (4, 3):  -0.124021,
      (4, 4):   0.093017,   (5, 0):  -0.238897,   (5, 1):  -0.179724,
      (5, 2):  -0.113608,   (5, 3):   0.017841,   (5, 4):  -0.012933,
      (6, 0):  -0.166337,   (6, 1):  -0.272922,   (6, 2):  -0.194665,
      (6, 3):  -0.058535,   (6, 4):  -0.405404,   (7, 0):  -0.318824,
      (7, 1):  -0.311276,   (7, 2):  -0.205223,   (7, 3):  -0.292664,
      (7, 4):  -0.474762,   (8, 0):  -0.039504,   (8, 1):  -0.239887,
      (8, 2):  -0.343485,   (8, 3):  -0.459429,   (8, 4):  -0.426901,
      (9, 0):  -0.187805,   (9, 1):   0.282727,   (9, 2):  -0.601164,
      (9, 3):  -0.467605,   (9, 4):  -0.589271,  (10, 0):   0.028311,
      (10, 1):  -0.391571,  (10, 2):  -0.463112,  (10, 3):  -0.358092,
      (10, 4):  -0.285396,  (11, 0):    0.01863,  (11, 1):  -0.380099,
      (11, 2):  -0.234953,  (11, 3):  -0.593992,  (11, 4):  -0.801247
    }

    distance = float(
        self._cif_header_dictionary['Detector_distance'].split()[0])

    beam_xy = self._cif_header_dictionary['Beam_xy'].replace(
        '(', '').replace(')', '').replace(',', '').split()[:2]

    beam_x, beam_y = map(float, beam_xy)

    wavelength = float(
        self._cif_header_dictionary['Wavelength'].split()[0])

    pixel_xy = self._cif_header_dictionary['Pixel_size'].replace(
        'm', '').replace('x', '').split()

    pixel_x, pixel_y = map(float, pixel_xy)

    thickness = float(
      self._cif_header_dictionary['Silicon'].split()[2]) * 1000.0

    nx = int(
        self._cif_header_dictionary['X-Binary-Size-Fastest-Dimension'])
    ny = int(
        self._cif_header_dictionary['X-Binary-Size-Second-Dimension'])

    overload = int(
        self._cif_header_dictionary['Count_cutoff'].split()[0])
    underload = -1

    # take into consideration here the thickness of the sensor also the
    # wavelength of the radiation (which we have in the same file...)

    from cctbx.eltbx import attenuation_coefficient
    table = attenuation_coefficient.get_table("Si")
    mu = table.mu_at_angstrom(wavelength) / 10.0
    t0 = thickness

    # FIXME would also be very nice to be able to take into account the
    # misalignment of the individual modules given the calibration...

    # single detector or multi-module detector

    pixel_x *= 1000.0
    pixel_y *= 1000.0
    distance *= 1000.0

    if not self._multi_panel:
      detector = self._detector_factory.simple(
        'PAD', distance, (beam_x * pixel_x, beam_y * pixel_y),
        '+x', '-y', (pixel_x, pixel_y), (nx, ny), (underload, overload), [],
        ParallaxCorrectedPxMmStrategy(mu, t0))

      for f0, s0, f1, s1 in determine_pilatus_mask(detector):
        detector[0].add_mask(f0, s0, f1, s1)

      detector[0].set_thickness(thickness)
      detector[0].set_material('Si')
      detector[0].set_mu(mu)

      return detector

    # got to here means 60-panel version

    from dxtbx.model.detector import Detector
    from scitbx import matrix

    d = Detector()

    beam_centre = matrix.col((beam_x * pixel_x,
                              beam_y * pixel_y, 0))

    fast = matrix.col((1.0, 0.0, 0.0))
    slow = matrix.col((0.0,-1.0, 0.0))
    s0 = matrix.col((0, 0, -1))
    origin = (distance * s0) - (fast * beam_centre[0]) - \
      (slow * beam_centre[1])

    root = d.hierarchy()
    root.set_local_frame(
      fast.elems,
      slow.elems,
      origin.elems)

    xmins  = [0, 494, 988, 1482, 1976]
    xmaxes = [487, 981, 1475, 1969, 2463]
    ymins  = [0, 212, 424, 636, 848, 1060, 1272,
              1484, 1696, 1908, 2120, 2332]
    ymaxes = [195, 407, 619, 831, 1043, 1255, 1467,
              1679, 1891, 2103, 2315, 2527]

    self.coords = {}

    fast = matrix.col((1.0, 0.0, 0.0))
    slow = matrix.col((0.0, 1.0, 0.0))
    panel_idx = 0
    for ymin, ymax in zip(ymins, ymaxes):
      for xmin, xmax in zip(xmins, xmaxes):
        xmin_mm = xmin * pixel_x
        ymin_mm = ymin * pixel_y

        origin_panel = fast * xmin_mm + slow * ymin_mm

        panel_name = "Panel%d" % panel_idx
        panel_idx += 1

        p = d.add_panel()
        p.set_type('SENSOR_PAD')
        p.set_name(panel_name)
        p.set_raw_image_offset((xmin, ymin))
        p.set_image_size((xmax-xmin, ymax-ymin))
        p.set_trusted_range((underload, overload))
        p.set_pixel_size((pixel_x,pixel_y))
        p.set_thickness(thickness)
        p.set_material('Si')
        p.set_mu(mu)
        p.set_px_mm_strategy(ParallaxCorrectedPxMmStrategy(mu, t0))
        p.set_local_frame(
          fast.elems,
          slow.elems,
          origin_panel.elems)
        p.set_raw_image_offset((xmin, ymin))
        self.coords[panel_name] = (xmin,ymin,xmax,ymax)

    return d
Exemplo n.º 36
0
    def _detector(self):

        # module positions from detector blueprints - modelling at the moment as
        # 24 modules, each consisting of 5 sensors (the latter is ignored)

        from dxtbx.model import Detector
        from scitbx import matrix
        import math

        x = matrix.col((-1, 0, 0))
        y = matrix.col((0, 1, 0))
        z = matrix.col((0, 0, 1))

        beam_xy = self._cif_header_dictionary["Beam_xy"]
        beam_xy = beam_xy.replace("(", "").replace(")",
                                                   "").replace(",",
                                                               "").split()[:2]
        obs_beam_x, obs_beam_y = [float(f) for f in beam_xy]

        ideal_beam_x = 1075
        ideal_beam_y = 2594

        beam_shift_x = 0.172 * (ideal_beam_x - obs_beam_x)
        beam_shift_y = 0.172 * (ideal_beam_y - obs_beam_y)

        distance = (float(
            self._cif_header_dictionary["Detector_distance"].split()[0]) *
                    1000.0)

        wavelength = float(
            self._cif_header_dictionary["Wavelength"].split()[0])

        thickness = float(
            self._cif_header_dictionary["Silicon"].split()[2]) * 1000.0

        off_x = 184.9

        detector = Detector()
        root = detector.hierarchy()
        root.set_frame(
            x.elems,
            y.elems,
            (-distance * z + (beam_shift_x * x) + (beam_shift_y * y)).elems,
        )

        from cctbx.eltbx import attenuation_coefficient

        table = attenuation_coefficient.get_table("Si")
        mu = table.mu_at_angstrom(wavelength) / 10.0
        t0 = thickness
        px_mm = ParallaxCorrectedPxMmStrategy(mu, t0)

        self.coords = {}

        for j in range(24):
            shift_y = 195 + 17
            ymin, ymax = j * shift_y, j * shift_y + 195

            angle = math.pi * (-12.2 + 0.5 * 7.903 + j *
                               (7.903 + 0.441)) / 180.0
            fast = matrix.col((1, 0, 0))
            slow = matrix.col((0, math.sin(angle), math.cos(angle)))
            normal = fast.cross(slow)

            row_origin = 250.0 * normal - off_x * fast - 16.8 * slow

            if not self._multi_panel:
                xmin, xmax = 0, 2463

                # OK two calls to add_panel here for detector like things => two
                # copies of the panel then? https://github.com/dials/dials/issues/189
                # ... this is also not the source of the leak

                # OBS! you need to set the panel to a root before set local frame...
                p = root.add_panel()
                p.set_type("SENSOR_PAD")
                p.set_name("row-%02d" % j)
                p.set_raw_image_offset((xmin, ymin))
                p.set_image_size((2463, 195))
                p.set_trusted_range((-1, 1000000))
                p.set_pixel_size((0.172, 0.172))
                p.set_local_frame(fast.elems, slow.elems, row_origin.elems)
                p.set_thickness(thickness)
                p.set_material("Si")
                p.set_mu(mu)
                p.set_px_mm_strategy(px_mm)
                p.set_raw_image_offset((xmin, ymin))
                self.coords[p.get_name()] = (xmin, ymin, xmax, ymax)

            else:
                shift_x = 487 + 7

                for i in range(5):
                    xmin, xmax = i * shift_x, i * shift_x + 487
                    origin = row_origin + i * (487 + 7) * 0.172 * fast

                    # OBS! you need to set the panel to a root before set local frame...
                    p = root.add_panel()
                    p.set_type("SENSOR_PAD")
                    p.set_name("row-%02d-col-%02d" % (j, i))
                    p.set_raw_image_offset((xmin, ymin))
                    p.set_image_size((487, 195))
                    p.set_trusted_range((-1, 1000000))
                    p.set_pixel_size((0.172, 0.172))
                    p.set_local_frame(fast.elems, slow.elems, origin.elems)
                    p.set_thickness(thickness)
                    p.set_material("Si")
                    p.set_mu(mu)
                    p.set_px_mm_strategy(px_mm)
                    p.set_raw_image_offset((xmin, ymin))
                    self.coords[p.get_name()] = (xmin, ymin, xmax, ymax)

        return detector
Exemplo n.º 37
0
    def get_goniometer_shadow_masker(self, goniometer=None):
        from dials.util.masking import GoniometerShadowMaskGenerator
        from scitbx.array_family import flex
        import math

        coords = flex.vec3_double(((0, 0, 0), ))

        alpha = flex.double_range(0, 190, step=10) * math.pi / 180
        r = flex.double(alpha.size(), 40)
        x = flex.double(r.size(), 107.61)
        y = -r * flex.sin(alpha)
        z = -r * flex.cos(alpha)
        coords.extend(flex.vec3_double(x, y, z))

        coords.extend(
            flex.vec3_double((
                # fixed
                (107.49, 7.84, 39.49),
                (107.39, 15.69, 38.97),
                (107.27, 23.53, 38.46),
                (107.16, 31.37, 37.94),
                (101.76, 33.99, 36.25),
                (96.37, 36.63, 34.56),
                (90.98, 39.25, 33.00),
                (85.58, 41.88, 31.18),
                (80.89, 47.06, 31.00),
                (76.55, 51.51, 31.03),
                (72.90, 55.04, 31.18),
                (66.86, 60.46, 31.67),
                (62.10, 64.41, 32.25),
            )))

        alpha = flex.double_range(180, 370, step=10) * math.pi / 180
        r = flex.double(alpha.size(), 33)
        x = flex.sqrt(flex.pow2(r * flex.sin(alpha)) + 89.02**2) * flex.cos(
            (50 * math.pi / 180) - flex.atan(r / 89.02 * flex.sin(alpha)))
        y = flex.sqrt(flex.pow2(r * flex.sin(alpha)) + 89.02**2) * flex.sin(
            (50 * math.pi / 180) - flex.atan(r / 89.02 * flex.sin(alpha)))
        z = -r * flex.cos(alpha)
        coords.extend(flex.vec3_double(x, y, z))

        coords.extend(
            flex.vec3_double((
                # fixed
                (62.10, 64.41, -32.25),
                (66.86, 60.46, -31.67),
                (72.90, 55.04, -31.18),
                (76.55, 51.51, -31.03),
                (80.89, 47.06, -31.00),
                (85.58, 41.88, -31.18),
                (90.98, 39.25, -33.00),
                (96.37, 36.63, -34.56),
                (101.76, 33.99, -36.25),
                (107.16, 31.37, -37.94),
                (107.27, 23.53, -38.46),
                (107.39, 15.69, -38.97),
                (107.49, 7.84, -39.49),
                (107.61, 0.00, -40.00),
            )))

        # I23 end station coordinate system:
        #   X-axis: positive direction is facing away from the storage ring (from
        #           sample towards goniometer)
        #   Y-axis: positive direction is vertically up
        #   Z-axis: positive direction is in the direction of the beam (from
        #           sample towards detector)
        #   K-axis (kappa): at an angle of +50 degrees from the X-axis
        #   K & phi rotation axes: clockwise rotation is positive (right hand
        #           thumb rule)
        #   Omega-axis: along the X-axis; clockwise rotation is positive

        # End station x-axis is parallel to ImgCIF x-axis
        # End station z-axis points in opposite direction to ImgCIF definition
        # (ImgCIF: The Z-axis is derived from the source axis which goes from
        # the sample to the source)
        # Consequently end station y-axis (to complete set following right hand
        # rule) points in opposite direction to ImgCIF y-axis.
        # Kappa arm aligned with -y in ImgCIF convention

        from rstbx.cftbx.coordinate_frame_helpers import align_reference_frame
        from scitbx import matrix

        R = align_reference_frame(
            matrix.col((1, 0, 0)),
            matrix.col((1, 0, 0)),
            matrix.col((0, 1, 0)),
            matrix.col((0, -1, 0)),
        )
        coords = R.elems * coords

        if goniometer is None:
            goniometer = self.get_goniometer()
        return GoniometerShadowMaskGenerator(goniometer, coords,
                                             flex.size_t(len(coords), 1))
Exemplo n.º 38
0
    def find_basis_vectors(self, reciprocal_lattice_vectors):
        """Find a list of likely basis vectors.

        Args:
            reciprocal_lattice_vectors (scitbx.array_family.flex.vec3_double):
                The list of reciprocal lattice vectors to search for periodicity.

        Returns:
            A tuple containing the list of basis vectors and a flex.bool array
            identifying which reflections were used in indexing.
        """
        if self._params.reciprocal_space_grid.d_min is libtbx.Auto:
            # rough calculation of suitable d_min based on max cell
            # see also Campbell, J. (1998). J. Appl. Cryst., 31(3), 407-413.
            # fft_cell should be greater than twice max_cell, so say:
            #   fft_cell = 2.5 * max_cell
            # then:
            #   fft_cell = n_points * d_min/2
            #   2.5 * max_cell = n_points * d_min/2
            # a little bit of rearrangement:
            #   d_min = 5 * max_cell/n_points

            max_cell = self._max_cell
            d_min = 5 * max_cell / self._n_points
            d_spacings = 1 / reciprocal_lattice_vectors.norms()
            d_min = max(d_min, min(d_spacings))
            logger.info("Setting d_min: %.2f" % d_min)
        else:
            d_min = self._params.reciprocal_space_grid.d_min

        grid_real, used_in_indexing = self._fft(reciprocal_lattice_vectors,
                                                d_min)
        self.sites, self.volumes = self._find_peaks(grid_real, d_min)

        # hijack the xray.structure class to facilitate calculation of distances

        self.crystal_symmetry = crystal.symmetry(unit_cell=self._fft_cell,
                                                 space_group_symbol="P1")
        xs = xray.structure(crystal_symmetry=self.crystal_symmetry)
        for i, site in enumerate(self.sites):
            xs.add_scatterer(xray.scatterer("C%i" % i, site=site))

        xs = xs.sites_mod_short()
        sites_cart = xs.sites_cart()
        lengths = flex.double([matrix.col(sc).length() for sc in sites_cart])
        perm = flex.sort_permutation(lengths)
        xs = xs.select(perm)
        volumes = self.volumes.select(perm)

        vectors = xs.sites_cart()
        norms = vectors.norms()
        sel = (norms > self._min_cell) & (norms < (2 * self._max_cell))
        vectors = vectors.select(sel)
        vectors = [matrix.col(v) for v in vectors]
        volumes = volumes.select(sel)

        vector_groups = group_vectors(vectors, volumes)
        vectors = [g.mean for g in vector_groups]
        volumes = flex.double(max(g.weights) for g in vector_groups)

        # sort by peak size
        perm = flex.sort_permutation(volumes, reverse=True)
        volumes = volumes.select(perm)
        vectors = [vectors[i] for i in perm]

        for i, (v, volume) in enumerate(zip(vectors, volumes)):
            logger.debug("%s %s %s" % (i, v.length(), volume))

        # sort by length
        lengths = flex.double(v.length() for v in vectors)
        perm = flex.sort_permutation(lengths)

        # exclude vectors that are (approximately) integer multiples of a shorter
        # vector
        unique_vectors = []
        unique_volumes = flex.double()
        for p in perm:
            v = vectors[p]
            is_unique = True
            for i, v_u in enumerate(unique_vectors):
                if (unique_volumes[i] > volumes[p]
                    ) and is_approximate_integer_multiple(v_u, v):
                    logger.debug("rejecting %s: integer multiple of %s" %
                                 (v.length(), v_u.length()))
                    is_unique = False
                    break
            if is_unique:
                unique_vectors.append(v)
                unique_volumes.append(volumes[p])

        # re-sort by peak volume
        perm = flex.sort_permutation(unique_volumes, reverse=True)
        self.candidate_basis_vectors = [unique_vectors[i] for i in perm]
        return self.candidate_basis_vectors, used_in_indexing
Exemplo n.º 39
0
def euler_angles_xyz_qE_as_euler_params_qE(qE):
    s1, s2, s3 = [math.sin(q / 2.) for q in qE]
    c1, c2, c3 = [math.cos(q / 2.) for q in qE]
    return matrix.col(
        (c1 * c2 * c3 + s1 * s2 * s3, c1 * c2 * s3 - s1 * s2 * c3,
         c1 * s2 * c3 + s1 * c2 * s3, s1 * c2 * c3 - c1 * s2 * s3))
def run_single(experiments1, filename):
    # Dump the file
    params = phil_scope.extract().nxs
    params.hklout = filename
    dials.util.nexus.dump(experiments1, None, params)

    # Load the file
    experiments2, reflections = dials.util.nexus.load(filename)
    assert experiments2 is not None
    assert reflections is None
    assert len(experiments2) == len(experiments1)

    index1 = []
    index2 = []

    for exp1, exp2 in zip(experiments1, experiments2):

        # Check the beam
        b1 = exp1.beam
        b2 = exp2.beam
        assert all(
            d1 == pytest.approx(d2)
            for d1, d2 in zip(
                b1.get_sample_to_source_direction(), b2.get_sample_to_source_direction()
            )
        )
        assert b1.get_wavelength() == pytest.approx(b2.get_wavelength())
        assert b1.get_polarization_fraction() == pytest.approx(
            b2.get_polarization_fraction()
        )
        n1 = matrix.col(b1.get_polarization_normal())
        n2 = matrix.col(b2.get_polarization_normal())
        angle = n2.angle(n1)
        assert (
            angle == pytest.approx(0, abs=1e-7)
            or angle == pytest.approx(math.pi)
            or angle == pytest.approx(2 * math.pi)
        )

        # Check the goniometer
        g1 = exp1.goniometer
        g2 = exp2.goniometer
        if g1 is None:
            assert g2 is None
        else:
            assert all(
                d1 == pytest.approx(d2)
                for d1, d2 in zip(g1.get_rotation_axis(), g2.get_rotation_axis())
            )
            assert all(
                d1 == pytest.approx(d2)
                for d1, d2 in zip(g1.get_fixed_rotation(), g2.get_fixed_rotation())
            )
            assert all(
                d1 == pytest.approx(d2)
                for d1, d2 in zip(g1.get_setting_rotation(), g2.get_setting_rotation())
            )

        # Check the scan
        s1 = exp1.scan
        s2 = exp2.scan
        if s1 is None:
            assert s2 is None
        else:
            assert len(s1) == len(s2)
            assert s1.get_image_range() == s2.get_image_range()
            assert s1.get_oscillation() == pytest.approx(s2.get_oscillation())
            assert s1.get_exposure_times() == pytest.approx(s2.get_exposure_times())
            assert s1.get_epochs() == pytest.approx(s2.get_epochs())

        # Check the detector
        d1 = exp1.detector
        d2 = exp2.detector
        assert len(d1) == len(d2)
        for p1, p2 in zip(d1, d2):
            assert p1.get_type() == p2.get_type()
            assert p1.get_material() == p2.get_material()
            assert p1.get_thickness() == p2.get_thickness()
            assert p1.get_image_size() == p2.get_image_size()
            assert p1.get_pixel_size() == p2.get_pixel_size()
            assert p1.get_trusted_range() == p2.get_trusted_range()
            assert p1.get_fast_axis() == pytest.approx(p2.get_fast_axis())
            assert p1.get_slow_axis() == pytest.approx(p2.get_slow_axis())
            assert p1.get_origin() == pytest.approx(p2.get_origin())

        # Check the crystal
        c1 = exp1.crystal
        c2 = exp2.crystal
        assert c1.get_space_group() == c2.get_space_group()
        assert c1.get_unit_cell().parameters() == pytest.approx(
            c2.get_unit_cell().parameters()
        )
        assert c1.get_A() == pytest.approx(c2.get_A())
        assert c1.num_scan_points == c2.num_scan_points
        for i in range(c1.num_scan_points):
            assert c1.get_A_at_scan_point(i) == pytest.approx(c2.get_A_at_scan_point(i))
            uc1 = c1.get_unit_cell_at_scan_point(i)
            uc2 = c2.get_unit_cell_at_scan_point(i)
            assert uc1.parameters() == pytest.approx(uc2.parameters())

        index1.append(
            (
                id(exp1.beam),
                id(exp1.detector),
                id(exp1.goniometer),
                id(exp1.scan),
                id(exp1.crystal),
            )
        )

        index2.append(
            (
                id(exp2.beam),
                id(exp2.detector),
                id(exp2.goniometer),
                id(exp2.scan),
                id(exp2.crystal),
            )
        )

    # Get a list of all beam etc
    beam1, detector1, goniometer1, scan1, crystal1 = zip(*index1)
    beam2, detector2, goniometer2, scan2, crystal2 = zip(*index2)

    # If any models are shared then check they are shared in both
    num = len(beam1)
    for i in range(0, num - 1):
        for j in range(1, num):
            assert (beam1[i] == beam1[j]) is (beam2[i] == beam2[j])
            assert (detector1[i] == detector1[j]) is (detector2[i] == detector2[j])
            assert (goniometer1[i] == goniometer1[j]) is (
                goniometer2[i] == goniometer2[j]
            )
            assert (scan1[i] == scan1[j]) is (scan2[i] == scan2[j])
            assert (crystal1[i] == crystal1[j]) is (crystal2[i] == crystal2[j])
Exemplo n.º 41
0
 def new_q(O, q):
     return spherical(type=O.type, qE=matrix.col(q))
Exemplo n.º 42
0
    uc = unit_cell([5.01, 5.01, 5.47, 90.0, 90.0, 120.0])

    bmat = matrix.sqr(uc.orthogonalization_matrix()).inverse().transpose()

    #----------------------------
    # prove that the matrix bmat is consistent with the ewald_sphere class
    # requirements:
    #               / A*x B*x C*x \
    #  Matrix A* =  | A*y B*y C*y |
    #               \ A*z B*z C*z /

    uc_reciprocal = uc.reciprocal()
    astar, bstar, cstar, alphastar, betastar, gammastar = uc_reciprocal.parameters(
    )
    astar_vec = matrix.col([bmat[0], bmat[3], bmat[6]])
    bstar_vec = matrix.col([bmat[1], bmat[4], bmat[7]])
    cstar_vec = matrix.col([bmat[2], bmat[5], bmat[8]])

    assert approx_equal(astar, math.sqrt(astar_vec.dot(astar_vec)))
    assert approx_equal(bstar, math.sqrt(bstar_vec.dot(bstar_vec)))
    assert approx_equal(cstar, math.sqrt(cstar_vec.dot(cstar_vec)))
    assert approx_equal(bstar * cstar * math.cos(math.pi * alphastar / 180),
                        bstar_vec.dot(cstar_vec))
    assert approx_equal(cstar * astar * math.cos(math.pi * betastar / 180),
                        cstar_vec.dot(astar_vec))
    assert approx_equal(astar * bstar * math.cos(math.pi * gammastar / 180),
                        astar_vec.dot(bstar_vec))

    # proof complete, bmat == A*
    #----------------------------
def random_vector():
    v = matrix.col((1, 0, 0)).rotate_around_origin(matrix.col((0, 1, 0)),
                                                   random.uniform(0, math.pi))
    return v.rotate_around_origin(matrix.col((1, 0, 0)),
                                  random.uniform(0,
                                                 2.0 * math.pi)).normalize()
Exemplo n.º 44
0
 def new_q(O, q):
     return revolute(qE=matrix.col(q))
Exemplo n.º 45
0
def exercise_frac_orth():
    u = uctbx.unit_cell(())
    assert approx_equal(u.fractionalization_matrix(),
                        u.orthogonalization_matrix())
    u = uctbx.unit_cell((2, 3, 5))
    assert approx_equal(u.fractionalize((1, 2, 4)), (1 / 2., 2 / 3., 4 / 5.))
    assert approx_equal(u.orthogonalize((1 / 2., 2 / 3., 4 / 5.)), (1, 2, 4))
    assert approx_equal(u.fractionalize(flex.vec3_double([(1, 2, 4)])),
                        [(1 / 2., 2 / 3., 4 / 5.)])
    assert approx_equal(
        u.orthogonalize(flex.vec3_double([(1 / 2., 2 / 3., 4 / 5.)])),
        [(1, 2, 4)])
    assert approx_equal(
        u.length((1 / 2., 2 / 3., 4 / 5.))**2, 1**2 + 2**2 + 4**2)
    assert approx_equal(
        u.distance((7 / 2., 8 / 3., 9 / 5.), (3, 2, 1))**2, 1**2 + 2**2 + 4**2)
    assert approx_equal(u.angle((0, 0, 0), (1 / 2., 0, 0), (1, 0, 0)), 180.)
    assert approx_equal(
        u.angle((0, 0, 0), (1 / 2., 0, 0), (1 / 2., 1 / 3., 0)), 90.)
    assert approx_equal(
        u.angle((1 / 2., 0, 0), (1 / 2., 1 / 3., 0), (0, 0, 0)), 45.)
    assert u.angle((0, 0, 0), (0, 0, 0), (1, 0, 0)) is None
    assert approx_equal(
        u.dihedral((0, 0, 0), (1 / 2., 0, 0), (1 / 2., 0, 1 / 5.),
                   (1, 0, 1 / 5.)), 180.)
    assert approx_equal(
        u.dihedral((0, 0, 0), (1 / 2., 0, 0), (1 / 2., 0, 1 / 5.),
                   (1 / 2., -1 / 3., 1 / 5.)), 90.)
    assert approx_equal(
        u.dihedral((0, 0, 0), (1 / 2., 0, 0), (1 / 2., 0, 1 / 5.),
                   (1, -1 / 3., 1 / 5.)), 135.)
    assert approx_equal(
        u.dihedral((0, 0, 0), (1 / 2., 0, 0), (1 / 2., 0, 1 / 5.),
                   (1, 1 / 3., 1 / 5.)), -135.)
    assert u.dihedral((0, 0, 0), (1 / 2., 0, 0), (1 / 2., 0, 0),
                      (1, 0, 1 / 5.)) is None
    assert approx_equal(u.mod_short_length((1 / 4., 2 / 3., 4 / 5.)),
                        u.length((1 / 4., -1 / 3., -1 / 5.)))
    assert approx_equal(
        u.mod_short_distance((13 / 4., 8 / 3., 9 / 5.), (3, 2, 1)),
        u.length((1 / 4., -1 / 3., -1 / 5.)))
    c = flex.vec3_double(((7 / 2., 8 / 3., 9 / 5.), (13 / 4., 8 / 3., 9 / 5.)))
    assert approx_equal(
        u.min_mod_short_distance(c, (3, 2, 1)),
        u.mod_short_distance((13 / 4., 8 / 3., 9 / 5.), (3, 2, 1)))
    #
    u = uctbx.unit_cell((13, 17, 19, 83, 111, 95))
    fm = matrix.sqr(u.fractionalization_matrix())
    assert ",".join(["%.3g" % e for e in fm.elems]) \
        == "0.0769,0.00673,0.029,0,0.059,-0.00578,0,0,0.0566"
    om = matrix.sqr(u.orthogonalization_matrix())
    assert ",".join(["%.3g" % e for e in om.elems]) \
        == "13,-1.48,-6.81,0,16.9,1.73,0,0,17.7"
    gm = matrix.sqr(u.grid_index_as_site_cart_matrix(gridding=(11, 13, 17)))
    pg = matrix.col((5, -7, 23))
    pf = matrix.col((5 / 11, -7 / 13, 23 / 17))
    assert approx_equal(u.orthogonalize(pf), om * pf)
    assert approx_equal(gm * pg, om * pf)
    f = flex.vec3_double(flex.random_double(size=12) * 2 - 1)
    c = u.orthogonalize(sites_frac=f)
    assert approx_equal(u.fractionalize(sites_cart=c), f)
    for fi, ci in zip(f, c):
        assert approx_equal(u.orthogonalize(site_frac=fi), ci)
        assert approx_equal(u.fractionalize(site_cart=ci), fi)
        assert approx_equal(om * matrix.col(fi), ci)
        assert approx_equal(fm * matrix.col(ci), fi)
    #
    from cctbx import sgtbx
    s = sgtbx.rt_mx("-x,-x+y,-x+z", r_den=12)
    assert approx_equal(u.matrix_cart(rot_mx=s.r()), [
        -0.3622586, -0.1191822, -0.5137527, -1.435689, 0.8743934, -0.5414459,
        -1.357969, -0.1188069, 0.4878651
    ])
    from scitbx.math import r3_rotation_axis_and_angle_from_matrix as from_matrix

    def check(u, sg):
        for s in sg:
            t = s.r().info().type()
            c = matrix.sqr(u.matrix_cart(rot_mx=s.r()))
            d = c.determinant()
            assert approx_equal(abs(d), 1)
            assert (t < 0) is (d < 0)
            fm = from_matrix(r=c * d)
            expected = {
                1: [0],
                2: [180, -180],
                3: [120, -120],
                4: [90, -90],
                6: [60, -60]
            }[abs(t)]
            observed = round(fm.angle(deg=True))
            if (observed not in expected):
                raise RuntimeError(
                    "%s not in %s (%s)" %
                    (str(observed), str(expected), s.r().as_xyz()))

    check(  # primitive settig of space group No. 230
        u=uctbx.unit_cell([10.911236359717213] * 3 + [109.47122063449069] * 3),
        sg=sgtbx.space_group("-I 4bd 2c 3 (y+z,x+z,x+y)"))
    check(  # P 6/m m m
        u=uctbx.unit_cell((13, 13, 17, 90, 90, 120)),
        sg=sgtbx.space_group("-P 6 2"))
Exemplo n.º 46
0
def tst_overlapping(reflections, overlapping, adjacency_list, image_size):
    """Ensure masks for overlapping reflections are set properly."""
    from scitbx import matrix
    from dials.algorithms import shoebox

    # Loop through all overlaps
    shoeboxes = reflections["shoebox"]
    coord = reflections["xyzcal.px"]
    for i in overlapping:
        r1 = shoeboxes[i]
        bbox_1 = r1.bbox
        r1_coord = matrix.col(coord[i])

        # Create a mask that we expect
        r1_size = (bbox_1[5] - bbox_1[4], bbox_1[3] - bbox_1[2],
                   bbox_1[1] - bbox_1[0])
        expected_mask = np.zeros(shape=r1_size, dtype=np.int32)
        expected_mask[:, :, :] = shoebox.MaskCode.Valid

        # Loop through all reflections which this reflection overlaps
        for j in adjacency_list.adjacent_vertices(i):
            r2 = shoeboxes[j]
            bbox_2 = r2.bbox
            r2_coord = matrix.col(coord[j])

            # Get bounding box of intersection
            bbox_3 = (
                max(bbox_1[0], bbox_2[0]),
                min(bbox_1[1], bbox_2[1]),
                max(bbox_1[2], bbox_2[2]),
                min(bbox_1[3], bbox_2[3]),
                max(bbox_1[4], bbox_2[4]),
                min(bbox_1[5], bbox_2[5]),
            )

            # Check intersection is valid
            assert bbox_3[0] < bbox_3[1]
            assert bbox_3[2] < bbox_3[3]
            assert bbox_3[4] < bbox_3[5]

            # Get the coordinates are all mask values
            mask_coord = []
            for k in range(bbox_3[4], bbox_3[5]):
                for j in range(bbox_3[2], bbox_3[3]):
                    for i in range(bbox_3[0], bbox_3[1]):
                        mask_coord.append(
                            matrix.col((i + 0.5, j + 0.5, k + 0.5)))

            def dist(a, m):
                return np.array([(a - b).length() for b in m])

            # Find the indices in the intersection area where r2 is closer to
            # the point than r1
            ind = np.where(
                dist(r1_coord, mask_coord) > dist(r2_coord, mask_coord))[0]

            # Set the mask values for r1 where r2 is closer to 0
            k0, k1 = bbox_3[4] - bbox_1[4], bbox_3[5] - bbox_1[4]
            j0, j1 = bbox_3[2] - bbox_1[2], bbox_3[3] - bbox_1[2]
            i0, i1 = bbox_3[0] - bbox_1[0], bbox_3[1] - bbox_1[0]
            intersect_mask = expected_mask[k0:k1, j0:j1, i0:i1]
            intersect_mask_1d = intersect_mask.reshape(-1)
            intersect_mask_1d[ind] = 0
            intersect_mask[:, :] = intersect_mask_1d.reshape(
                intersect_mask.shape)
            expected_mask[k0:k1, j0:j1, i0:i1] = intersect_mask

        # Check the masks are the same
        calculated_mask = r1.mask.as_numpy_array()
        assert np.all(calculated_mask == expected_mask)
Exemplo n.º 47
0
    def find_basis_vector_combinations_cluster_analysis(self):
        self.fft()

        # hijack the xray.structure class to facilitate calculation of distances
        xs = xray.structure(crystal_symmetry=self.crystal_symmetry)
        for i, site in enumerate(self.sites):
            xs.add_scatterer(xray.scatterer("C%i" % i, site=site))

        xs = xs.sites_mod_short()
        xs = xs.select(xs.sites_frac().norms() < 0.45)
        cell_multiplier = 10
        xs1 = xs.customized_copy(unit_cell=uctbx.unit_cell(
            [xs.unit_cell().parameters()[0] * cell_multiplier] * 3))
        xs1.set_sites_cart(xs.sites_cart())
        xs = xs1
        sites_cart = xs.sites_cart()
        lengths = flex.double([matrix.col(sc).length() for sc in sites_cart])
        xs = xs.select(flex.sort_permutation(lengths))
        if self.params.debug:
            with open('peaks.pdb', 'wb') as f:
                f.write(xs.as_pdb_file())

        vector_heights = flex.double()

        sites_frac = xs.sites_frac()
        pair_asu_table = xs.pair_asu_table(
            distance_cutoff=self.params.max_cell)
        asu_mappings = pair_asu_table.asu_mappings()
        distances = crystal.calculate_distances(pair_asu_table, sites_frac)
        vectors = []
        difference_vectors = []
        pairs = []
        for di in distances:
            if di.distance < self.params.min_cell: continue
            i_seq, j_seq = di.i_seq, di.j_seq
            if i_seq > j_seq: continue
            pairs.append((i_seq, j_seq))
            rt_mx_ji = di.rt_mx_ji
            site_frac_ji = rt_mx_ji * sites_frac[j_seq]
            site_cart_ji = xs.unit_cell().orthogonalize(site_frac_ji)
            site_cart_i = xs.unit_cell().orthogonalize(sites_frac[i_seq])
            vectors.append(matrix.col(site_cart_ji))
            diff_vec = matrix.col(site_cart_i) - matrix.col(site_cart_ji)
            if diff_vec[0] < 0:
                # only one hemisphere of difference vector space
                diff_vec = -diff_vec
            difference_vectors.append(diff_vec)

        params = self.params.multiple_lattice_search.cluster_analysis
        if params.method == 'dbscan':
            i_cluster = self.cluster_analysis_dbscan(difference_vectors)
            min_cluster_size = 1
        elif params.method == 'hcluster':
            i_cluster = self.cluster_analysis_hcluster(difference_vectors)
            i_cluster -= 1  # hcluster starts counting at 1
            min_cluster_size = params.min_cluster_size

        if self.params.debug_plots:
            self.debug_plot_clusters(difference_vectors,
                                     i_cluster,
                                     min_cluster_size=min_cluster_size)

        clusters = []
        min_cluster_size = params.min_cluster_size
        for i in range(max(i_cluster) + 1):
            isel = (i_cluster == i).iselection()
            if len(isel) < min_cluster_size:
                continue
            clusters.append(isel)

        cluster_point_sets = []
        centroids = []
        cluster_sizes = flex.int()

        difference_vectors = flex.vec3_double(difference_vectors)

        from libtbx.utils import flat_list
        for cluster in clusters:
            points = flat_list([pairs[i] for i in cluster])
            cluster_point_sets.append(set(points))
            d_vectors = difference_vectors.select(cluster)
            cluster_sizes.append(len(d_vectors))
            centroids.append(d_vectors.mean())

        # build a graph where each node is a centroid from the difference vector
        # cluster analysis above, and an edge is defined when there is a
        # significant overlap between the sets of peaks in the FFT map that
        # contributed to the difference vectors in two clusters
        import networkx as nx
        G = nx.Graph()
        G.add_nodes_from(range(len(cluster_point_sets)))

        cutoff_frac = 0.25
        for i in range(len(cluster_point_sets)):
            for j in range(i + 1, len(cluster_point_sets)):
                intersection_ij = cluster_point_sets[i].intersection(
                    cluster_point_sets[j])
                union_ij = cluster_point_sets[i].union(cluster_point_sets[j])
                frac_connected = len(intersection_ij) / len(union_ij)
                if frac_connected > cutoff_frac:
                    G.add_edge(i, j)

        # iteratively find the maximum cliques in the graph
        # break from the loop if there are no cliques remaining or there are
        # fewer than 3 vectors in the remaining maximum clique
        # Allow 1 basis vector to be shared between two cliques, to allow for
        # cases where two lattices share one basis vectors (e.g. two plate
        # crystals exactly aligned in one direction, but not in the other two)
        distinct_cliques = []
        cliques = list(nx.find_cliques(G))
        cliques = sorted(cliques, key=len, reverse=True)
        for i, clique in enumerate(cliques):
            clique = set(clique)
            if len(clique) < 3:
                break
            is_distinct = True
            for c in distinct_cliques:
                if len(c.intersection(clique)) > 1:
                    is_distinct = False
                    break
            if is_distinct:
                distinct_cliques.append(clique)
                this_set = set()
                for i_cluster in clique:
                    this_set = this_set.union(cluster_point_sets[i_cluster])
                logger.info("Clique %i: %i lattice points" %
                            (i + 1, len(this_set)))

        assert len(distinct_cliques) > 0

        logger.info("Estimated number of lattices: %i" % len(distinct_cliques))

        self.candidate_basis_vectors = []
        self.candidate_crystal_models = []

        for clique in distinct_cliques:
            sel = flex.size_t(list(clique))
            vectors = flex.vec3_double(centroids).select(sel)
            perm = flex.sort_permutation(vectors.norms())
            vectors = [matrix.col(vectors[p]) for p in perm]

            # exclude vectors that are (approximately) integer multiples of a shorter
            # vector
            unique_vectors = []
            for v in vectors:
                is_unique = True
                for v_u in unique_vectors:
                    if is_approximate_integer_multiple(v_u,
                                                       v,
                                                       relative_tolerance=0.01,
                                                       angular_tolerance=0.5):
                        is_unique = False
                        break
                if is_unique:
                    unique_vectors.append(v)
            vectors = unique_vectors

            self.candidate_basis_vectors.extend(vectors)
            candidate_orientation_matrices \
              = self.find_candidate_orientation_matrices(vectors)
            if len(candidate_orientation_matrices) == 0:
                continue
            crystal_model, n_indexed = self.choose_best_orientation_matrix(
                candidate_orientation_matrices)
            if crystal_model is None: continue
            # map to minimum reduced cell
            crystal_symmetry = crystal.symmetry(
                unit_cell=crystal_model.get_unit_cell(),
                space_group=crystal_model.get_space_group())
            cb_op = crystal_symmetry.change_of_basis_op_to_minimum_cell()
            crystal_model = crystal_model.change_basis(cb_op)
            self.candidate_crystal_models.append(crystal_model)

        if self.params.debug:
            file_name = "vectors.pdb"
            a = self.params.max_cell
            cs = crystal.symmetry(unit_cell=(a, a, a, 90, 90, 90),
                                  space_group="P1")
            xs = xray.structure(crystal_symmetry=cs)
            for v in difference_vectors:
                v = matrix.col(v)
                xs.add_scatterer(xray.scatterer("C", site=v / (a / 10)))
            xs.sites_mod_short()
            with open(file_name, 'wb') as f:
                f.write(xs.as_pdb_file())

        for crystal_model in self.candidate_crystal_models:
            logger.debug(crystal_model)
    def _detector(self):
        """Dummy detector"""
        from scitbx import matrix

        # 55 mu pixels
        pixel_size = 0.055, 0.055
        trusted_range = (-1, 65535)
        material = "Si"
        thickness = 0.3  # assume 300 mu thick. This is actually in the header too
        # so could take it from there

        # Initialise detector frame - dummy origin to place detector at the header
        # distance along the canonical beam direction
        distance = (float(
            self._cif_header_dictionary["Detector_distance"].split()[0]) *
                    1000)
        fast = matrix.col((1.0, 0.0, 0.0))
        slow = matrix.col((0.0, -1.0, 0.0))
        cntr = matrix.col((0.0, 0.0, -100.0))

        # shifts to go from the centre to the origin
        off_x = (self._array_size[0] / 2) * pixel_size[0]
        shift_x = -1.0 * fast * off_x
        off_y = (self._array_size[1] / 2) * pixel_size[1]
        shift_y = -1.0 * slow * off_y
        orig = cntr + shift_x + shift_y

        d = Detector()

        root = d.hierarchy()
        root.set_local_frame(fast.elems, slow.elems, orig.elems)

        self.coords = {}
        panel_idx = 0

        # set panel extent in pixel numbers and x, y mm shifts. Origins taken from
        # an XDS.INP
        pnl_data = []
        pnl_data.append({
            "xmin": 0,
            "ymin": 0,
            "xmax": 516,
            "ymax": 516,
            "xmin_mm": 0,
            "ymin_mm": 0
        })
        pnl_data.append({
            "xmin": 516,
            "ymin": 0,
            "xmax": 1032,
            "ymax": 516,
            "xmin_mm": (516 + 163.0) * pixel_size[0],
            "ymin_mm": -3.6969 * pixel_size[1],
        })
        pnl_data.append({
            "xmin": 0,
            "ymin": 516,
            "xmax": 516,
            "ymax": 1032,
            "xmin_mm": -2.5455 * pixel_size[0],
            "ymin_mm": (516 + 35.0) * pixel_size[1],
        })
        pnl_data.append({
            "xmin": 516,
            "ymin": 516,
            "xmax": 1032,
            "ymax": 1032,
            "xmin_mm": (516 + 165.866) * pixel_size[0],
            "ymin_mm": (516 + 32.4545) * pixel_size[1],
        })

        # redefine fast, slow for the local frame
        fast = matrix.col((1.0, 0.0, 0.0))
        slow = matrix.col((0.0, 1.0, 0.0))

        for ipanel, pd in enumerate(pnl_data):
            xmin = pd["xmin"]
            xmax = pd["xmax"]
            ymin = pd["ymin"]
            ymax = pd["ymax"]
            xmin_mm = pd["xmin_mm"]
            ymin_mm = pd["ymin_mm"]

            origin_panel = fast * xmin_mm + slow * ymin_mm

            panel_name = "Panel%d" % panel_idx
            panel_idx += 1

            p = d.add_panel()
            p.set_type("SENSOR_PAD")
            p.set_name(panel_name)
            p.set_raw_image_offset((xmin, ymin))
            p.set_image_size((xmax - xmin, ymax - ymin))
            p.set_trusted_range(trusted_range)
            p.set_pixel_size((pixel_size[0], pixel_size[1]))
            p.set_thickness(thickness)
            p.set_material("Si")
            # p.set_mu(mu)
            # p.set_px_mm_strategy(ParallaxCorrectedPxMmStrategy(mu, t0))
            p.set_local_frame(fast.elems, slow.elems, origin_panel.elems)
            p.set_raw_image_offset((xmin, ymin))
            p.set_gain(3.0)  # exact gain
            self.coords[panel_name] = (xmin, ymin, xmax, ymax)

        return d
Exemplo n.º 49
0
    def __init__(self, measurements_orig, params, i_model, miller_set, result,
                 out):
        measurements = measurements_orig.deep_copy()
        # Now manipulate the data to conform to unit cell, asu, and space group
        # of reference.  The resolution will be cut later.
        # Only works if there is NOT an indexing ambiguity!
        observations = measurements.customized_copy(
            anomalous_flag=not params.merge_anomalous,
            crystal_symmetry=miller_set.crystal_symmetry()).map_to_asu()

        observations_original_index = measurements.customized_copy(
            anomalous_flag=not params.merge_anomalous,
            crystal_symmetry=miller_set.crystal_symmetry())

        # Ensure that match_multi_indices() will return identical results
        # when a frame's observations are matched against the
        # pre-generated Miller set, self.miller_set, and the reference
        # data set, self.i_model.  The implication is that the same match
        # can be used to map Miller indices to array indices for intensity
        # accumulation, and for determination of the correlation
        # coefficient in the presence of a scaling reference.

        assert len(i_model.indices()) == len(miller_set.indices()) \
            and  (i_model.indices() ==
                  miller_set.indices()).count(False) == 0
        matches = miller.match_multi_indices(
            miller_indices_unique=miller_set.indices(),
            miller_indices=observations.indices())

        pair1 = flex.int([pair[1] for pair in matches.pairs()])
        pair0 = flex.int([pair[0] for pair in matches.pairs()])
        # narrow things down to the set that matches, only
        observations_pair1_selected = observations.customized_copy(
            indices=flex.miller_index(
                [observations.indices()[p] for p in pair1]),
            data=flex.double([observations.data()[p] for p in pair1]),
            sigmas=flex.double([observations.sigmas()[p] for p in pair1]),
        )
        observations_original_index_pair1_selected = observations_original_index.customized_copy(
            indices=flex.miller_index(
                [observations_original_index.indices()[p] for p in pair1]),
            data=flex.double(
                [observations_original_index.data()[p] for p in pair1]),
            sigmas=flex.double(
                [observations_original_index.sigmas()[p] for p in pair1]),
        )
        ###################
        I_observed = observations_pair1_selected.data()
        chosen = chosen_weights(observations_pair1_selected, params)

        MILLER = observations_original_index_pair1_selected.indices()
        ORI = result["current_orientation"][0]
        Astar = matrix.sqr(ORI.reciprocal_matrix())
        WAVE = result["wavelength"]
        BEAM = matrix.col((0.0, 0.0, -1. / WAVE))
        BFACTOR = 0.

        #calculation of correlation here
        I_reference = flex.double(
            [i_model.data()[pair[0]] for pair in matches.pairs()])
        I_invalid = flex.bool(
            [i_model.sigmas()[pair[0]] < 0. for pair in matches.pairs()])
        use_weights = False  # New facility for getting variance-weighted correlation

        if use_weights:
            #variance weighting
            I_weight = flex.double([
                1. / (observations_pair1_selected.sigmas()[pair[1]])**2
                for pair in matches.pairs()
            ])
        else:
            I_weight = flex.double(len(observations_pair1_selected.sigmas()),
                                   1.)
        I_weight.set_selected(I_invalid, 0.)
        chosen.set_selected(I_invalid, 0.)
        """Explanation of 'include_negatives' semantics as originally implemented in cxi.merge postrefinement:
       include_negatives = True
       + and - reflections both used for Rh distribution for initial estimate of RS parameter
       + and - reflections both used for calc/obs correlation slope for initial estimate of G parameter
       + and - reflections both passed to the refinery and used in the target function (makes sense if
                           you look at it from a certain point of view)

       include_negatives = False
       + and - reflections both used for Rh distribution for initial estimate of RS parameter
       +       reflections only used for calc/obs correlation slope for initial estimate of G parameter
       + and - reflections both passed to the refinery and used in the target function (makes sense if
                           you look at it from a certain point of view)
    """
        if params.include_negatives:
            SWC = simple_weighted_correlation(I_weight, I_reference,
                                              I_observed)
        else:
            non_positive = (observations_pair1_selected.data() <= 0)
            SWC = simple_weighted_correlation(
                I_weight.select(~non_positive),
                I_reference.select(~non_positive),
                I_observed.select(~non_positive))

        print("Old correlation is", SWC.corr, file=out)
        assert params.postrefinement.algorithm == "rs_hybrid"
        Rhall = flex.double()
        for mill in MILLER:
            H = matrix.col(mill)
            Xhkl = Astar * H
            Rh = (Xhkl + BEAM).length() - (1. / WAVE)
            Rhall.append(Rh)
        Rs = math.sqrt(flex.mean(Rhall * Rhall))

        RS = 1. / 10000.  # reciprocal effective domain size of 1 micron
        RS = Rs  # try this empirically determined approximate, monochrome, a-mosaic value

        self.rs2_current = flex.double([SWC.slope, BFACTOR, RS, 0., 0.])
        self.rs2_parameterization_class = rs_parameterization

        self.rs2_refinery = rs2_refinery(ORI=ORI,
                                         MILLER=MILLER,
                                         BEAM=BEAM,
                                         WAVE=WAVE,
                                         ICALCVEC=I_reference,
                                         IOBSVEC=I_observed,
                                         WEIGHTS=chosen)
        self.rs2_refinery.set_profile_shape(params.postrefinement.lineshape)
        self.nave1_refinery = nave1_refinery(ORI=ORI,
                                             MILLER=MILLER,
                                             BEAM=BEAM,
                                             WAVE=WAVE,
                                             ICALCVEC=I_reference,
                                             IOBSVEC=I_observed,
                                             WEIGHTS=chosen)
        self.nave1_refinery.set_profile_shape(params.postrefinement.lineshape)

        self.out = out
        self.params = params
        self.miller_set = miller_set
        self.observations_pair1_selected = observations_pair1_selected
        self.observations_original_index_pair1_selected = observations_original_index_pair1_selected
        self.i_model = i_model
Exemplo n.º 50
0
    def XDS(self):

        sensor = self.get_detector().get_type()
        fast, slow = map(int, self.get_detector().get_image_size())
        f, s = self.get_detector().get_pixel_size()
        df = int(1000 * f)
        ds = int(1000 * s)

        # FIXME probably need to rotate by pi about the X axis

        R = matrix.col(
            (1.0, 0.0, 0.0)).axis_and_angle_as_r3_rotation_matrix(180.0,
                                                                  deg=True)

        detector = xds_detector_name(
            detector_helpers_types.get(sensor, fast, slow, df, ds))
        trusted = self.get_detector().get_trusted_range()

        print 'DETECTOR=%s MINIMUM_VALID_PIXEL_VALUE=%d OVERLOAD=%d' % \
              (detector, trusted[0] + 1, trusted[1])

        if detector == 'PILATUS':
            print 'SENSOR_THICKNESS= 0.32'

        print 'DIRECTION_OF_DETECTOR_X-AXIS= %.3f %.3f %.3f' % \
              (R * self.get_detector().get_fast_axis()).elems

        print 'DIRECTION_OF_DETECTOR_Y-AXIS= %.3f %.3f %.3f' % \
              (R * self.get_detector().get_slow_axis()).elems

        print 'NX=%d NY=%d QX=%.4f QY=%.4f' % (fast, slow, f, s)

        F = R * self.get_detector().get_fast_axis()
        S = R * self.get_detector().get_slow_axis()
        N = F.cross(S)

        origin = R * self.get_detector().get_origin()
        beam = R * self.get_beam().get_direction() / \
               math.sqrt(matrix.col(self.get_beam().get_direction()).dot())
        centre = -(origin - origin.dot(N) * N)
        x = centre.dot(F)
        y = centre.dot(S)

        print 'DETECTOR_DISTANCE= %.3f' % origin.dot(N)
        print 'ORGX= %.1f ORGY= %.1f' % (x / f, y / s)
        print 'ROTATION_AXIS= %.3f %.3f %.3f' % \
              (R * self.get_goniometer().get_rotation_axis()).elems
        print 'STARTING_ANGLE= %.3f' % \
              self.get_scan().get_oscillation()[0]
        print 'OSCILLATION_RANGE= %.3f' % \
              self.get_scan().get_oscillation()[1]
        print 'X-RAY_WAVELENGTH= %.5f' % \
              self.get_beam().get_wavelength()
        print 'INCIDENT_BEAM_DIRECTION= %.3f %.3f %.3f' % \
              (- beam).elems
        print 'FRACTION_OF_POLARIZATION= %.3f' % \
              self.get_beam().get_polarization_fraction()
        print 'POLARIZATION_PLANE_NORMAL= %.3f %.3f %.3f' % \
              self.get_beam().get_polarization_normal()
        print 'NAME_TEMPLATE_OF_DATA_FRAMES= %s' % self._template.replace(
            '#', '?')
        print 'TRUSTED_REGION= 0.0 1.41'
        for f0, f1, s0, s1 in self.get_detector().get_mask():
            print 'UNTRUSTED_RECTANGLE= %d %d %d %d' % \
                  (f0 - 1, f1 + 1, s0 - 1, s1 + 1)

        start_end = self.get_scan().get_image_range()

        if start_end[0] == 0:
            start_end = (1, start_end[1])

        print 'DATA_RANGE= %d %d' % start_end
        print 'JOB=XYCORR INIT COLSPOT IDXREF DEFPIX INTEGRATE CORRECT'
Exemplo n.º 51
0
    def tst_outer_bounds(self):

        from scitbx import matrix
        from random import uniform
        from dials.algorithms.profile_model.gaussian_rs import CoordinateSystem

        assert (len(self.detector) == 1)
        s0 = self.beam.get_s0()
        m2 = self.gonio.get_rotation_axis()
        s0_length = matrix.col(self.beam.get_s0()).length()
        width, height = self.detector[0].get_image_size()
        zrange = self.scan.get_array_range()

        for i in range(1000):

            # Get random x, y, z
            x = uniform(0, 2000)
            y = uniform(0, 2000)
            z = uniform(0, 9)

            # Get random s1, phi, panel
            s1 = matrix.col(self.detector[0].get_pixel_lab_coord(
                (x, y))).normalize() * s0_length
            phi = self.scan.get_angle_from_array_index(z, deg=False)
            panel = 0

            # Calculate the bounding box
            bbox = self.calculate_bbox(s1, z, panel)
            x1, x2 = bbox[0], bbox[1]
            y1, y2 = bbox[2], bbox[3]
            z1, z2 = bbox[4], bbox[5]

            # Calculate the rotation angle for each point
            phi_dash1 = self.scan.get_angle_from_array_index(z1, deg=False)
            phi_dash2 = self.scan.get_angle_from_array_index(z2, deg=False)

            # Create the XDS coordinate system
            xcs = CoordinateSystem(m2, s0, s1, phi)

            # Calculate reciprocal space coordinates at each point
            e11, e21, e31 = xcs.from_beam_vector_and_rotation_angle(
                s1, phi_dash1)
            e12, e22, e32 = xcs.from_beam_vector_and_rotation_angle(
                s1, phi_dash2)

            # Check vertical edges
            for j in range(bbox[2], bbox[3] + 1):
                xyz1 = self.detector[0].get_pixel_lab_coord((bbox[0], j))
                xyz2 = self.detector[0].get_pixel_lab_coord((bbox[1] + 1, j))
                sdash1 = matrix.col(xyz1).normalize() * s0_length
                sdash2 = matrix.col(xyz2).normalize() * s0_length
                e11, e21, e3 = xcs.from_beam_vector_and_rotation_angle(
                    sdash1, phi)
                e12, e22, e3 = xcs.from_beam_vector_and_rotation_angle(
                    sdash2, phi)
                if bbox[0] > 0 and bbox[1] < width:
                    assert (abs(e11) >= self.delta_divergence
                            or abs(e21) >= self.delta_divergence)
                    assert (abs(e12) >= self.delta_divergence
                            or abs(e22) >= self.delta_divergence)

            # Check horizontal edges
            for i in range(bbox[0], bbox[1] + 1):
                xyz1 = self.detector[0].get_pixel_lab_coord((i, bbox[2]))
                xyz2 = self.detector[0].get_pixel_lab_coord((i, bbox[3] + 1))
                sdash1 = matrix.col(xyz1).normalize() * s0_length
                sdash2 = matrix.col(xyz2).normalize() * s0_length
                e11, e21, e3 = xcs.from_beam_vector_and_rotation_angle(
                    sdash1, phi)
                e12, e22, e3 = xcs.from_beam_vector_and_rotation_angle(
                    sdash2, phi)
                if bbox[2] > 0 and bbox[3] < height:
                    assert (abs(e11) >= self.delta_divergence
                            or abs(e21) >= self.delta_divergence)
                    assert (abs(e12) >= self.delta_divergence
                            or abs(e22) >= self.delta_divergence)

            # All e3 coords >= delta_mosaicity
            if bbox[4] > zrange[0] and bbox[5] < zrange[1]:
                assert (abs(e31) >= self.delta_mosaicity)
                assert (abs(e32) >= self.delta_mosaicity)

        print 'OK'
Exemplo n.º 52
0
    def find_candidate_basis_vectors(self):
        self.fft()

        # hijack the xray.structure class to facilitate calculation of distances
        xs = xray.structure(crystal_symmetry=self.crystal_symmetry)
        for i, site in enumerate(self.sites):
            xs.add_scatterer(xray.scatterer("C%i" % i, site=site))

        xs = xs.sites_mod_short()
        sites_cart = xs.sites_cart()
        lengths = flex.double([matrix.col(sc).length() for sc in sites_cart])
        perm = flex.sort_permutation(lengths)
        xs = xs.select(perm)
        volumes = self.volumes.select(perm)
        if self.params.debug:
            with open('peaks.pdb', 'wb') as f:
                f.write(xs.as_pdb_file())

        sites_frac = xs.sites_frac()
        vectors = xs.sites_cart()
        norms = vectors.norms()
        sel = (norms > self.params.min_cell) & (norms <
                                                (2 * self.params.max_cell))
        vectors = vectors.select(sel)
        vectors = [matrix.col(v) for v in vectors]
        volumes = volumes.select(sel)

        # XXX loop over these vectors and sort into groups similar to further down
        # group similar angle and lengths, also catch integer multiples of vectors

        vector_groups = []
        relative_length_tolerance = 0.1
        angle_tolerance = 5  # degrees

        orth = self.fft_cell.orthogonalize
        for v, volume in zip(vectors, volumes):
            length = v.length()
            if length < self.params.min_cell or length > (
                    2 * self.params.max_cell):
                continue
            matched_group = False
            for group in vector_groups:
                mean_v = group.mean()
                mean_v_length = mean_v.length()
                if (abs(mean_v_length - length) / max(mean_v_length, length) <
                        relative_length_tolerance):
                    angle = mean_v.angle(v, deg=True)
                    if angle < angle_tolerance:
                        group.append(v, length, volume)
                        matched_group = True
                        break
                    elif abs(180 - angle) < angle_tolerance:
                        group.append(-v, length, volume)
                        matched_group = True
                        break
            if not matched_group:
                group = vector_group()
                group.append(v, length, volume)
                vector_groups.append(group)

        vectors = [g.mean() for g in vector_groups]
        volumes = flex.double(max(g.volumes) for g in vector_groups)

        ## sort by length
        #lengths = flex.double([v.length() for v in vectors])
        #perm = flex.sort_permutation(lengths)
        # sort by peak size
        perm = flex.sort_permutation(volumes, reverse=True)
        volumes = volumes.select(perm)
        vectors = [vectors[i] for i in perm]

        for i, (v, volume) in enumerate(zip(vectors, volumes)):
            logger.debug("%s %s %s" % (i, v.length(), volume))

        lengths = flex.double(v.length() for v in vectors)
        perm = flex.sort_permutation(lengths)

        # exclude vectors that are (approximately) integer multiples of a shorter
        # vector
        unique_vectors = []
        unique_volumes = flex.double()
        for p in perm:
            v = vectors[p]
            is_unique = True
            for i, v_u in enumerate(unique_vectors):
                if ((unique_volumes[i] > volumes[p])
                        and is_approximate_integer_multiple(v_u, v)):
                    logger.debug("rejecting %s: integer multiple of %s" %
                                 (v.length(), v_u.length()))
                    is_unique = False
                    break
            if is_unique:
                unique_vectors.append(v)
                unique_volumes.append(volumes[p])

        # re-sort by peak volume
        perm = flex.sort_permutation(unique_volumes, reverse=True)
        vectors = [unique_vectors[i] for i in perm]
        volumes = unique_volumes.select(perm)

        #for i, (v, volume) in enumerate(zip(vectors, volumes)):
        #logger.debug("%s %s %s" %(i, v.length(), volume))

        self.candidate_basis_vectors = vectors
        return self.candidate_basis_vectors
Exemplo n.º 53
0
def test_ensure_axes_have_length_of_one(xdscoordinates):
    eps = 1e-7
    assert abs(matrix.col(xdscoordinates["cs"].e1_axis()).length() - 1.0) <= eps
    assert abs(matrix.col(xdscoordinates["cs"].e2_axis()).length() - 1.0) <= eps
    assert abs(matrix.col(xdscoordinates["cs"].e3_axis()).length() - 1.0) <= eps
Exemplo n.º 54
0
    for ispot in range(len(pixel)):
        dials_roi = dials[ispot].roi
        pixel_roi = pixel[ispot].roi
        focus = dials_roi.focus()

        S = flex.double(range(focus[0]))
        F = flex.double(range(focus[1]))
        # matrix giving the slow coordinate:
        cslow = S.matrix_outer_product(flex.double([1] * focus[1]))
        # matrix giving the fast coordinate:
        cfast = flex.double([1] * focus[0]).matrix_outer_product(F)

        sum_dials_roi = flex.sum(dials_roi)
        dials_expectation_value = col(
            (flex.sum(cfast * dials_roi) / sum_dials_roi,
             flex.sum(cslow * dials_roi) / sum_dials_roi))

        sum_pixel_roi = flex.sum(pixel_roi)
        pixel_expectation_value = col(
            (flex.sum(cfast * pixel_roi) / sum_pixel_roi,
             flex.sum(cslow * pixel_roi) / sum_pixel_roi))

        delta_position = pixel_expectation_value - dials_expectation_value
        deltafast.append(delta_position[0])
        deltaslow.append(delta_position[1])
        print(delta_position.elems)

from matplotlib import pyplot as plt
#from IPython import embed; embed()
statss = flex.mean_and_variance(deltaslow)
Exemplo n.º 55
0
  def plot_isotropic_umats(UMAT_nm, mos_spread_deg):

    # analysis of rotation angles
    from simtbx.nanoBragg.tst_gaussian_mosaicity import check_distributions
    angle_deg, rot_ax = check_distributions.get_angle_deg_and_axes(UMAT_nm) # in degrees
    nm_rms_angle = math.sqrt(flex.mean(angle_deg*angle_deg))

    from matplotlib import pyplot as plt
    fig_angles,axis_angles = plt.subplots(1,1)
    axis_angles.set_xlabel("rotation (°)")
    axis_angles.hist(angle_deg,bins=int(math.sqrt(len(UMAT_nm))))
    axis_angles.set_title(
    "Histogram of rotation angles\nrms %.4f° expected %.4f°"%(nm_rms_angle, mos_spread_deg))

    # analysis of rotation axes
    fig, axes = plt.subplots(1, 3,figsize=(10,5))
    axes[0].plot(rot_ax.parts()[0], rot_ax.parts()[1], "b,") # looking down from the pole
    axes[0].set_aspect("equal")
    axes[0].set_title("Rot_ax projected on z")
    axes[0].set_xlim(-1.1,1.1)
    axes[0].set_ylim(-1.1,1.1)

    axes[1].plot(rot_ax.parts()[1], rot_ax.parts()[2], "b,") # looking at equator above prime meridian
    axes[1].set_aspect("equal")
    axes[1].set_title("Rot_ax projected on x")
    axes[1].set_xlim(-1.1,1.1)
    axes[1].set_ylim(-1.1,1.1)

    axes[2].plot(rot_ax.parts()[2], rot_ax.parts()[0], "b,") # looking at equator above 90-deg meridian
    axes[2].set_aspect("equal")
    axes[2].set_title("Rot_ax projected on y")
    axes[2].set_xlim(-1.1,1.1)
    axes[2].set_ylim(-1.1,1.1)

    # action on unit vectors
    cube_diag = math.sqrt(1./3) # 0.57735
    unit_vectors = [(1,0,0), (0,1,0), (0,0,1), (cube_diag, cube_diag, cube_diag)]
    fig3,axes3 = plt.subplots(1,4,sharey=True,figsize=(15,7))
    axes3[0].set_ylabel("unit projection")
    for icol, RLP in enumerate(unit_vectors):
          RLP = col(RLP)
          axis = axes3[icol]
          unit = RLP.normalize()
          seed = col(unit_vectors[(icol+2)%(len(unit_vectors))])
          perm2 = unit.cross(seed)
          perm3 = unit.cross(perm2)
          a2 = flex.double(); a3 = flex.double()
          angles_deg = flex.double()
          for u in UMAT_nm:
            U = sqr(u)
            newvec = U * unit
            angles_deg.append((180./math.pi)*math.acos(newvec.dot(unit)))
            a2.append(newvec.dot(perm2)); a3.append(newvec.dot(perm3))
          rms_angle = math.sqrt(flex.mean(angles_deg*angles_deg))
          axis.plot (a2,a3,'r,')[0]
          axis.set_aspect("equal")
          axis_str = "(%5.3f,%5.3f,%5.3f)"%(RLP.elems) if icol==3 else "(%.0f,%.0f,%.0f)"%(RLP.elems)
          axis.set_title("Transformation of unit vector\n%s\nrms %.4f° expected %.4f°"%(
            axis_str, rms_angle, math.sqrt(mos_spread_deg*mos_spread_deg*(2/3)))) # Pythagorean thm
          axis.set_xlabel("unit projection")
          axis.set_xlim(-0.0005,0.0005)
          axis.set_ylim(-0.0005,0.0005)

    plt.show()
Exemplo n.º 56
0
def test_to_beamvector_xds_origin(beamvector):
    """Test the beam vector at the XDS origin is equal to s1."""
    eps = 1e-7
    s_dash = beamvector["cs"].to_beam_vector((0, 0))
    assert abs(matrix.col(s_dash) - matrix.col(beamvector["s1"])) <= eps
Exemplo n.º 57
0
 def get_coefficients(self, ih):
     """
 This function determines parameters for three cases:
 1. planar geometry
 2. two tetragonal CH2 geometry
 3. H out of plane of its 3 neighbors (should be rare and not in AA)
 """
     neighbors = self.h_connectivity[ih]
     if (neighbors.number_h_neighbors == 1):
         i_h1 = neighbors.h1['iseq']
     else:
         i_h1 = None
     i_a0 = neighbors.a0['iseq']
     i_a1 = neighbors.a1['iseq']
     i_a2 = neighbors.a2['iseq']
     rh = matrix.col(self.sites_cart[ih])
     r0 = matrix.col(self.sites_cart[i_a0])
     r1 = matrix.col(self.sites_cart[i_a1])
     r2 = matrix.col(self.sites_cart[i_a2])
     self.check_if_atoms_superposed(rh, r0, ih, i_a0)
     self.check_if_atoms_superposed(r1, r0, i_a1, i_a0)
     self.check_if_atoms_superposed(r2, r0, i_a2, i_a0)
     uh0 = (rh - r0).normalize()
     u10 = (r1 - r0).normalize()
     u20 = (r2 - r0).normalize()
     if self.use_ideal_bonds_angles:
         alpha0 = math.radians(neighbors.a0['angle_a1a0a2'])
         alpha1 = math.radians(neighbors.a1['angle_ideal'])
         alpha2 = math.radians(neighbors.a2['angle_ideal'])
         c0, c1, c2 = math.cos(alpha0), math.cos(alpha1), math.cos(alpha2)
     else:
         alpha0 = (u10).angle(u20)
         alpha0 = math.acos(u10.dot(u20))
         alpha1 = (u10).angle(uh0)
         alpha2 = (uh0).angle(u20)
         c0 = (u10).dot(u20)
         c1 = (u10).dot(uh0)
         c2 = (uh0).dot(u20)
     sumang = alpha0 + alpha1 + alpha2
     denom = (1.0 - c0**2)
     if (denom == 0):
         self.broadcast_problem(ih=ih, i_a0=i_a0)
         #raise RuntimeError(
         #  "Denominator zero: (1-c0*c0) in get_h_parameterization.")
     a = (c1 - c0 * c2) / (1 - c0 * c0)
     b = (c2 - c0 * c1) / (1 - c0 * c0)
     root = None
     #  # check if H, A0, A1, A2 are in a plane
     if (sumang < (2 * math.pi + 0.05) and (sumang > 2 * math.pi - 0.05)):
         h = None
     elif (sumang > (2 * math.pi + 0.05)
           and 1 - c1 * c1 - c2 * c2 - c0 * c0 + 2 * c0 * c1 * c2 < 0):
         root = 1 - c1 * c1 - c2 * c2 - c0 * c0 + 2 * c0 * c1 * c2
         h = None
         return sumang, a, b, h, root
     else:
         # two tetragonal geometry: e.g. CH2 group
         if (i_h1 is not None):
             rh2 = matrix.col(self.sites_cart[neighbors.h1['iseq']])
             #print(i_h1, neighbors.h1['iseq'], i_a0)
             self.check_if_atoms_superposed(rh2, r0, neighbors.h1['iseq'],
                                            i_a0)
             uh02 = (rh2 - r0).normalize()
             if self.use_ideal_bonds_angles:
                 h = math.radians(neighbors.h1['angle_ideal']) * 0.5
             else:
                 h = (uh0).angle(uh02) * 0.5
             #test if vector v points to same 'side' as uh0
             if ((u10.cross(u20)).dot(uh0) < 0):
                 h = -h
         else:
             # if H is out of plane, but not in tetrahedral geometry
             root = 1 - c1 * c1 - c2 * c2 - c0 * c0 + 2 * c0 * c1 * c2
             if (root < 0):
                 self.broadcast_problem(
                     ih=ih,
                     i_a0=i_a0,
                     msg=
                     '(Square root of zero in get_coefficients: H out of plane)'
                 )
             denom = math.sin(alpha0)
             if (denom == 0):
                 self.broadcast_problem(
                     ih=ih,
                     i_a0=i_a0,
                     msg=
                     '(Denominator zero in get_coefficients: H out of plane)'
                 )
             cz = (math.sqrt(1 - c1 * c1 - c2 * c2 - c0 * c0 +
                             2 * c0 * c1 * c2)) / math.sin(alpha0)
             h = cz
             #test if vector v points to same 'side' as uh0
             if ((u10.cross(u20)).dot(uh0) < 0):
                 h = -h
     return sumang, a, b, h, root
    def compose(self, reflections, skip_derivatives=False):
        """Compose scan-varying crystal parameterisations at the specified image
        number, for the specified experiment, for each image. Put the varying
        matrices in the reflection table, and cache the derivatives."""

        self._prepare_for_compose(reflections, skip_derivatives)

        for iexp, exp in enumerate(self._experiments):

            # select the reflections of interest
            sel = reflections["id"] == iexp
            isel = sel.iselection()

            # skip empty experiments (https://github.com/dials/dials/issues/1417)
            if len(isel) == 0:
                continue

            blocks = reflections["block"].select(isel)

            # identify which parameterisations to use for this experiment
            xl_op = self._get_xl_orientation_parameterisation(iexp)
            xl_ucp = self._get_xl_unit_cell_parameterisation(iexp)
            bp = self._get_beam_parameterisation(iexp)
            dp = self._get_detector_parameterisation(iexp)
            gp = self._get_goniometer_parameterisation(iexp)

            # reset current frame cache for scan-varying parameterisations
            self._current_frame = {}

            # get state and derivatives for each block
            for block in range(flex.min(blocks), flex.max(blocks) + 1):

                # determine the subset of reflections this affects
                subsel = isel.select(blocks == block)
                if len(subsel) == 0:
                    continue

                # get the panels hit by these reflections
                panels = reflections["panel"].select(subsel)

                # get the integer frame number nearest the centre of that block
                frames = reflections["block_centre"].select(subsel)

                # can only be false if original block assignment has gone wrong
                assert frames.all_eq(
                    frames[0]
                ), "Failing: a block contains reflections that shouldn't be there"
                frame = int(math.floor(frames[0]))

                # model states at current frame
                U = self._get_state_from_parameterisation(xl_op, frame)
                if U is None:
                    U = matrix.sqr(exp.crystal.get_U())

                B = self._get_state_from_parameterisation(xl_ucp, frame)
                if B is None:
                    B = matrix.sqr(exp.crystal.get_B())

                s0 = self._get_state_from_parameterisation(bp, frame)
                if s0 is None:
                    s0 = matrix.col(exp.beam.get_s0())

                S = self._get_state_from_parameterisation(gp, frame)
                if S is None:
                    S = matrix.sqr(exp.goniometer.get_setting_rotation())

                # set states for crystal, beam and goniometer
                reflections["u_matrix"].set_selected(subsel, U.elems)
                reflections["b_matrix"].set_selected(subsel, B.elems)
                reflections["s0_vector"].set_selected(subsel, s0.elems)
                reflections["S_matrix"].set_selected(subsel, S.elems)

                # set states and derivatives for this detector
                if dp is not None:  # detector is parameterised
                    if dp.is_multi_state():  # parameterised detector is multi panel

                        # loop through the panels in this detector
                        for panel_id, _ in enumerate(exp.detector):

                            # get the right subset of array indices to set for this panel
                            subsel2 = subsel.select(panels == panel_id)
                            if len(subsel2) == 0:
                                # if no reflections intersect this panel, skip calculation
                                continue

                            dmat = self._get_state_from_parameterisation(
                                dp, frame, multi_state_elt=panel_id
                            )
                            if dmat is None:
                                dmat = exp.detector[panel_id].get_d_matrix()
                            Dmat = exp.detector[panel_id].get_D_matrix()
                            reflections["d_matrix"].set_selected(subsel2, dmat)
                            reflections["D_matrix"].set_selected(subsel2, Dmat)

                            if self._varying_detectors and not skip_derivatives:
                                for j, dd in enumerate(
                                    dp.get_ds_dp(
                                        multi_state_elt=panel_id, use_none_as_null=True
                                    )
                                ):
                                    if dd is None:
                                        continue
                                    self._derivative_cache.append(dp, j, dd, subsel)

                    else:  # parameterised detector is single panel
                        dmat = self._get_state_from_parameterisation(dp, frame)
                        if dmat is None:
                            dmat = exp.detector[0].get_d_matrix()
                        Dmat = exp.detector[0].get_D_matrix()
                        reflections["d_matrix"].set_selected(subsel, dmat)
                        reflections["D_matrix"].set_selected(subsel, Dmat)

                        if self._varying_detectors and not skip_derivatives:
                            for j, dd in enumerate(dp.get_ds_dp(use_none_as_null=True)):
                                if dd is None:
                                    continue
                                self._derivative_cache.append(dp, j, dd, subsel)

                else:  # set states for unparameterised detector (dp is None)
                    # loop through the panels in this detector
                    for panel_id, _ in enumerate(exp.detector):

                        # get the right subset of array indices to set for this panel
                        subsel2 = subsel.select(panels == panel_id)
                        if len(subsel2) == 0:
                            # if no reflections intersect this panel, skip to the next
                            continue

                        dmat = exp.detector[panel_id].get_d_matrix()
                        Dmat = exp.detector[panel_id].get_D_matrix()
                        reflections["d_matrix"].set_selected(subsel2, dmat)
                        reflections["D_matrix"].set_selected(subsel2, Dmat)

                # set derivatives of the states for crystal, beam and goniometer
                if not skip_derivatives:
                    if xl_op is not None and self._varying_xl_orientations:
                        for j, dU in enumerate(xl_op.get_ds_dp(use_none_as_null=True)):
                            if dU is None:
                                continue
                            self._derivative_cache.append(xl_op, j, dU, subsel)
                    if xl_ucp is not None and self._varying_xl_unit_cells:
                        for j, dB in enumerate(xl_ucp.get_ds_dp(use_none_as_null=True)):
                            if dB is None:
                                continue
                            self._derivative_cache.append(xl_ucp, j, dB, subsel)
                    if bp is not None and self._varying_beams:
                        for j, ds0 in enumerate(bp.get_ds_dp(use_none_as_null=True)):
                            if ds0 is None:
                                continue
                            self._derivative_cache.append(bp, j, ds0, subsel)
                    if gp is not None and self._varying_goniometers:
                        for j, dS in enumerate(gp.get_ds_dp(use_none_as_null=True)):
                            if dS is None:
                                continue
                            self._derivative_cache.append(gp, j, dS, subsel)

        # set the UB matrices for prediction
        reflections["ub_matrix"] = reflections["u_matrix"] * reflections["b_matrix"]
Exemplo n.º 59
0
 def process_1_neighbor_type_arg(self, neighbors):
     """
   alg1a: X-H2 planar groups, such as in ARG, ASN, GLN
   requires that dihedral angle restraint exists for at least one H atom
 """
     ih = neighbors.ih
     i_h1 = neighbors.h1['iseq']
     i_a0 = neighbors.a0['iseq']
     rh = matrix.col(self.sites_cart[ih])
     r0 = matrix.col(self.sites_cart[i_a0])
     if self.use_ideal_bonds_angles:
         disth = neighbors.a0['dist_ideal']
     else:
         disth = (r0 - rh).length()
     i_a1 = neighbors.a1['iseq']
     r1 = matrix.col(self.sites_cart[i_a1])
     if ('dihedral_ideal' in neighbors.b1):
         ih_dihedral = ih
         ih_no_dihedral = i_h1
     else:
         if ('dihedral_ideal' in self.h_connectivity[i_h1].b1):
             ih_dihedral = i_h1
             ih_no_dihedral = ih
         else:
             self.unk_list.append(ih)
             return
     i_b1 = self.h_connectivity[ih_dihedral].b1['iseq']
     rb1 = matrix.col(self.sites_cart[i_b1])
     # check if angle is typical for propeller
     # catches case of missing propeller atom
     if (neighbors.h1['angle_ideal'] > 107
             and neighbors.h1['angle_ideal'] < 111):
         self.unk_list.append(ih)
     else:
         dihedral = dihedral_angle(sites=[
             self.sites_cart[i_b1], self.sites_cart[i_a1],
             self.sites_cart[i_a0], self.sites_cart[ih_dihedral]
         ])
         self.check_if_atoms_superposed(rh, r0, ih, i_a0)
         self.check_if_atoms_superposed(r1, r0, i_a1, i_a0)
         uh0 = (rh - r0).normalize()
         u10 = (r1 - r0).normalize()
         if self.use_ideal_bonds_angles:
             alpha = math.radians(neighbors.a1['angle_ideal'])
             phi = math.radians(
                 self.h_connectivity[ih_dihedral].b1['dihedral_ideal'])
         else:
             alpha = (u10).angle(uh0)
             phi = dihedral
         u1 = (r0 - r1).normalize()
         rb10 = rb1 - r1
         # TODO check needed?
         u2 = (rb10 - ((rb10).dot(u10)) * u10).normalize()
         u3 = u1.cross(u2)
         for ih_alg1a, phi_alg1a in zip([ih_dihedral, ih_no_dihedral],
                                        [phi, phi + math.pi]):
             if self.h_parameterization[ih_alg1a] is None:
                 self.h_parameterization[ih_alg1a] = riding_coefficients(
                     htype='alg1a',
                     ih=ih_alg1a,
                     a0=i_a0,
                     a1=i_a1,
                     a2=i_b1,
                     a3=-1,
                     a=alpha,
                     b=phi_alg1a,
                     n=0,
                     h=0,
                     disth=disth)
Exemplo n.º 60
0
 def process_1_neighbor(self, neighbors):
     ih = neighbors.ih
     # if used for hydrogenate, make sure that first we use the H with dihedral angle
     # However, this needs some tweaking for neutron H/D situations
     if (neighbors.number_h_neighbors == 2):
         i_h1, i_h2 = neighbors.h1['iseq'], neighbors.h2['iseq']
         if ('dihedral_ideal' in neighbors.b1):
             neighbors = self.h_connectivity[ih]
         elif ('dihedral_ideal' in self.h_connectivity[i_h1].b1):
             if self.h_parameterization[i_h1] is None:
                 neighbors = self.h_connectivity[i_h1]
         elif ('dihedral_ideal' in self.h_connectivity[i_h2].b1):
             if self.h_parameterization[i_h2] is None:
                 neighbors = self.h_connectivity[i_h2]
     ih = neighbors.ih
     #print(self.site_labels[ih])
     i_a0 = neighbors.a0['iseq']
     rh = matrix.col(self.sites_cart[ih])
     r0 = matrix.col(self.sites_cart[i_a0])
     if self.use_ideal_bonds_angles:
         disth = neighbors.a0['dist_ideal']
     else:
         disth = (r0 - rh).length()
     if (not neighbors.a1 or not neighbors.b1):
         self.unk_list.append(ih)
         return
     i_a1 = neighbors.a1['iseq']
     i_b1 = neighbors.b1['iseq']
     r1 = matrix.col(self.sites_cart[i_a1])
     rb1 = matrix.col(self.sites_cart[i_b1])
     self.check_if_atoms_superposed(rh, r0, ih, i_a0)
     self.check_if_atoms_superposed(r1, r0, i_a1, i_a0)
     uh0 = (rh - r0).normalize()
     u10 = (r1 - r0).normalize()
     dihedral = dihedral_angle(sites=[
         self.sites_cart[ih], self.sites_cart[i_a0], self.sites_cart[i_a1],
         self.sites_cart[i_b1]
     ])
     if self.use_ideal_bonds_angles:
         alpha = math.radians(neighbors.a1['angle_ideal'])
         #allow for rotation even for idealize = True
         phi = dihedral
         if self.use_ideal_dihedral:
             #phi = math.radians(b1.dihedral_ideal)
             if 'dihedral_ideal' in neighbors.b1:
                 phi = math.radians(neighbors.b1['dihedral_ideal'])
     else:
         alpha = (u10).angle(uh0)
         phi = dihedral
     #print(math.degrees(phi))
     u1 = (r0 - r1).normalize()
     rb10 = rb1 - r1
     # TODO check needed?
     u2 = (rb10 - ((rb10).dot(u1)) * u1).normalize()
     u3 = u1.cross(u2)
     if (neighbors.number_h_neighbors == 0):
         self.h_parameterization[ih] = riding_coefficients(htype='alg1b',
                                                           ih=ih,
                                                           a0=i_a0,
                                                           a1=i_a1,
                                                           a2=i_b1,
                                                           a3=-1,
                                                           a=alpha,
                                                           b=phi,
                                                           h=0,
                                                           n=0,
                                                           disth=disth)
     if (neighbors.number_h_neighbors == 2):
         i_h1, i_h2 = neighbors.h1['iseq'], neighbors.h2['iseq']
         i_h1, i_h2 = self.check_propeller_order(i_a0=i_a0,
                                                 i_a1=i_a1,
                                                 ih=ih,
                                                 i_h1=i_h1,
                                                 i_h2=i_h2)
         for nprop, hprop in zip([0, 1, 2], [ih, i_h1, i_h2]):
             self.h_parameterization[hprop] = riding_coefficients(
                 htype='prop',
                 ih=hprop,
                 a0=i_a0,
                 a1=i_a1,
                 a2=i_b1,
                 a3=-1,
                 a=alpha,
                 n=nprop,
                 b=phi,
                 h=0,
                 disth=disth)