def __init__(self, r, d, symmetry_agreement, status):
    assert r.den() == 1
    self.r = r
    order = r.order()
    self.r_info = sgtbx.rot_mx_info(r)
    type = self.r_info.type()
    axis = self.r_info.ev()

    self.symmetry_agreement = symmetry_agreement
    self.status = status

    # compute intrinsic and location part of d, using p, which is
    # the order times the projector onto r's invariant space
    p = mat.sqr(r.accumulate().as_double())
    t_i_num = (p*d).as_int()
    t_l = d - t_i_num/order
    t_i = sgtbx.tr_vec(sg_t_den//order*t_i_num, tr_den=sg_t_den)

    # compute the origin corresponding to t_l by solving
    # (1 - r) o = t_l
    one_minus_r = -mat.sqr(self.r.minus_unit_mx().num())
    one_minus_r_row_echelon = one_minus_r.as_flex_int_matrix()
    q = mat.identity(3).as_flex_int_matrix()
    rank = scitbx.math.row_echelon_form_t(one_minus_r_row_echelon, q)
    qd = flex.double(mat.sqr(q)*t_l)[:rank]
    o = flex.double((0,0,0))
    scitbx.math.row_echelon_back_substitution_float(
      one_minus_r_row_echelon, qd, o)

    # construct object state
    self.t_i, self.raw_origin = t_i, mat.col(o)
    self.origin = None
    self.one_minus_r = one_minus_r
  def find_space_group(self):
    decorated_symmetry_pool = []
    denominator = 12**3
    for i, (r, d) in enumerate(self.cross_correlation_peaks()):
      t = sgtbx.tr_vec((d*denominator).as_int(), tr_den=denominator)
      cb_op = sgtbx.change_of_basis_op(sgtbx.rt_mx(r, t))
      phi_sym = self.f_in_p1.symmetry_agreement_factor(
        cb_op, assert_is_similar_symmetry=False)
      if phi_sym < self.phi_sym_acceptance_cutoff:
        status = possible_symmetry.accepted
      elif phi_sym < self.phi_sym_rejection_cutoff:
        status = possible_symmetry.unsure
      else:
        status = possible_symmetry.rejected
      decorated_symmetry_pool.append(
        (-status, i, possible_symmetry(r, d, phi_sym, status)))
    decorated_symmetry_pool.sort()
    self.symmetry_pool = [ item[-1] for item in decorated_symmetry_pool ]

    self.origin = mat.mutable_zeros(3)
    for symm in self.symmetry_pool:
      if symm.status != symm.accepted: continue
      symm.set_components_of_global_origin(self.origin)
      if self.origin.elems.count(0) == 0: break
    for symm in self.symmetry_pool:
      if symm.status != symm.accepted: continue
      symm.change_origin(self.origin)
      self.space_group.expand_smx(symm.rt)
Example #3
0
def list_all_axes(space_group_symbol=None, space_group_info=None):
  assert space_group_symbol is None or space_group_info is None
  shift_range = 1 # XXX Works for the 230 reference settings; it is not
                  # XXX clear to me (rwgk) what value is needed in general.
  if (space_group_symbol is not None):
    space_group_info = sgtbx.space_group_info(symbol=space_group_symbol)
  space_group_info.show_summary()
  print
  print "Rotation type, Axis direction, Intrinsic part, Origin shift"
  axes_dict = {}
  for s in space_group_info.group():
    r = s.r()
    t = s.t()
    shift = [0,0,0]
    for shift[0] in xrange(-shift_range,shift_range+1):
      for shift[1] in xrange(-shift_range,shift_range+1):
        for shift[2] in xrange(-shift_range,shift_range+1):
          ts = t.plus(sgtbx.tr_vec(shift, 1)).new_denominator(t.den())
          ss = sgtbx.rt_mx(r, ts)
          axes_dict[rt_mx_analysis(ss)] = 0
  axes_list = axes_dict.keys()
  axes_list.sort()
  for a in axes_list:
    print a
  print
Example #4
0
 def find_centring_translations(self):
     for d in self.centring_translation_peak_sites():
         t = [
             scitbx.math.continued_fraction.from_real(x,
                                                      1e-2).as_rational()
             for x in d
         ]
         if t.count(0) > 1: continue
         unique_denominators = dict([(r.denominator(), 1) for r in t
                                     if r.numerator() != 0]).keys()
         assert len(unique_denominators) in (0, 1)
         if len(unique_denominators) == 1:
             den = unique_denominators[0]
             num = [r.numerator() for r in t]
             tr_vec = sgtbx.tr_vec(num, den)
             try:
                 tr_vec = tr_vec.new_denominator(sg_t_den)
             except RuntimeError, e:
                 if (not str(e).endswith(
                         "Unsuitable value for rational translation vector."
                 )):
                     raise
                 raise RuntimeError(
                     "Sorry not implemented: handling of translation vector %s"
                     % str(tuple(t)))
             self.space_group.expand_ltr(tr_vec)
def convert(file_object):
    """ Examplify the direct use of the tool from shelx.lexer

  In practice, one is strongly encouraged to make use of the tools
  from shelx.parsers: that is to say, for the task handled here,
  crystal_symmetry_parser (the code to follow just parrots
  the implementation of crystal_symmetry_parser).
  """
    space_group = None
    for command, line in shelx.command_stream(file=file_object):
        cmd, args = command[0], command[-1]
        if cmd == "LATT":
            assert space_group is None
            assert len(args) == 1
            space_group = sgtbx.space_group()
            n = int(args[0])
            if n > 0:
                space_group.expand_inv(sgtbx.tr_vec((0, 0, 0)))
            z = "*PIRFABC"[abs(n)]
            space_group.expand_conventional_centring_type(z)
        elif cmd == "SYMM":
            assert space_group is not None
            assert len(args) == 1
            s = sgtbx.rt_mx(args[0])
            space_group.expand_smx(s)
        elif cmd == "SFAC":
            return sgtbx.space_group_info(group=space_group)
Example #6
0
    def find_space_group(self):
        decorated_symmetry_pool = []
        denominator = 12**3
        for i, (r, d) in enumerate(self.cross_correlation_peaks()):
            t = sgtbx.tr_vec((d * denominator).as_int(), tr_den=denominator)
            cb_op = sgtbx.change_of_basis_op(sgtbx.rt_mx(r, t))
            phi_sym = self.f_in_p1.symmetry_agreement_factor(
                cb_op, assert_is_similar_symmetry=False)
            if phi_sym < self.phi_sym_acceptance_cutoff:
                status = possible_symmetry.accepted
            elif phi_sym < self.phi_sym_rejection_cutoff:
                status = possible_symmetry.unsure
            else:
                status = possible_symmetry.rejected
            decorated_symmetry_pool.append(
                (-status, i, possible_symmetry(r, d, phi_sym, status)))
        decorated_symmetry_pool.sort()
        self.symmetry_pool = [item[-1] for item in decorated_symmetry_pool]

        self.origin = mat.mutable_zeros(3)
        for symm in self.symmetry_pool:
            if symm.status != symm.accepted: continue
            symm.set_components_of_global_origin(self.origin)
            if self.origin.elems.count(0) == 0: break
        for symm in self.symmetry_pool:
            if symm.status != symm.accepted: continue
            symm.change_origin(self.origin)
            self.space_group.expand_smx(symm.rt)
Example #7
0
def get_all_axes(space_group_symbol=None, space_group_info=None, extension=0):
    assert space_group_symbol is None or space_group_info is None
    shift_range = 1  # RWGK Works for the 230 reference settings; it is not
    # RWGK clear to me (rwgk) what value is needed in general.
    if (space_group_symbol is not None):
        space_group_info = sgtbx.space_group_info(symbol=space_group_symbol)
    #space_group_info.show_summary()

    axes_dict = {}
    for smx in space_group_info.group():
        r = smx.r()
        t = smx.t()
        shift = [0, 0, 0]
        for shift[0] in range(-shift_range, shift_range + 1):
            for shift[1] in range(-shift_range, shift_range + 1):
                for shift[2] in range(-shift_range, shift_range + 1):
                    ts = t.plus(sgtbx.tr_vec(shift,
                                             1)).new_denominator(t.den())
                    m = sgtbx.rt_mx(r, ts)
                    #print m
                    rtmxanal = rlc_RTMxAnalysis(m)
                    #print r, t, shift, ts, m
                    if rtmxanal:
                        #print rtmxanal
                        axes_dict[rtmxanal] = 0
    axes_list = axes_dict.keys()
    axes_list.sort()

    # reject nonenantiomorphic space groups
    if len(axes_list) > 0 and not re.compile("[A-z]").search(
            space_group_symbol[1:]):
        try:
            sgtbx.space_group_info(space_group_symbol).show_summary(),
            #print len(axes_list), space_group_symbol
        except:
            print space_group, space_group_symbol
            print
            sys.exit(1)
        axes = []
        for a in axes_list:
            if len(a) == 3 and len(a[1]) == 3 and len(a[2]) == 3:
                tmp_dict = {}
                print "%4s %7.4f %7.4f %7.4f    %7.4f %7.4f %7.4f " % (
                    a[0], a[1][0], a[1][1], a[1][2], a[2][0], a[2][1], a[2][2])
                tmp_dict['symb'] = a[0]
                start_array = N.asarray(a[1])
                end_array = N.asarray(a[2])
                start_vec = start_array - (end_array - start_array) * extension
                end_vec = end_array + (end_array - start_array) * extension
                tmp_dict['start'] = start_vec
                tmp_dict['end'] = end_vec
                #rlc#        tmp_dict['start'] = a[1]
                #rlc#        tmp_dict['end'] = a[2]
                axes.append(tmp_dict)
            else:
                print a
    else:
        return None

    return axes
Example #8
0
def list_all_axes(space_group_symbol=None, space_group_info=None):
  assert space_group_symbol is None or space_group_info is None
  shift_range = 1 # XXX Works for the 230 reference settings; it is not
                  # XXX clear to me (rwgk) what value is needed in general.
  if (space_group_symbol is not None):
    space_group_info = sgtbx.space_group_info(symbol=space_group_symbol)
  space_group_info.show_summary()
  print()
  print("Rotation type, Axis direction, Intrinsic part, Origin shift")
  axes_dict = {}
  for s in space_group_info.group():
    r = s.r()
    t = s.t()
    shift = [0,0,0]
    for shift[0] in range(-shift_range,shift_range+1):
      for shift[1] in range(-shift_range,shift_range+1):
        for shift[2] in range(-shift_range,shift_range+1):
          ts = t.plus(sgtbx.tr_vec(shift, 1)).new_denominator(t.den())
          ss = sgtbx.rt_mx(r, ts)
          axes_dict[rt_mx_analysis(ss)] = 0
  axes_list = list(axes_dict.keys())
  axes_list.sort()
  for a in axes_list:
    print(a)
  print()
 def __init__(self, file_name, header_only=False):
   self.file_name = os.path.normpath(file_name)
   f = open(file_name)
   line = f.readline()
   assert line[5] == " "
   n_sym_ops_from_file = int(line[:5].strip())
   assert n_sym_ops_from_file > 0
   self.space_group_symbol = line[6:].strip()
   self.space_group_from_ops = sgtbx.space_group()
   for i in xrange(n_sym_ops_from_file):
     line = f.readline().rstrip()
     assert len(line) == 27
     r = sgtbx.rot_mx([int(line[j*3:(j+1)*3]) for j in xrange(9)], 1)
     line = f.readline().rstrip()
     assert len(line) == 9
     t = sgtbx.tr_vec([int(line[j*3:(j+1)*3]) for j in xrange(3)], 12)
     self.space_group_from_ops.expand_smx(sgtbx.rt_mx(r, t))
   f.close()
   if (header_only):
     self.original_indices = None
     return
   all_arrays = scalepack_ext.no_merge_original_index_arrays(
     file_name, n_sym_ops_from_file*2+1)
   self.original_indices = all_arrays.original_indices()
   self.unique_indices = all_arrays.unique_indices()
   self.batch_numbers = all_arrays.batch_numbers()
   self.centric_tags = all_arrays.centric_tags()
   self.spindle_flags = all_arrays.spindle_flags()
   self.asymmetric_unit_indices = all_arrays.asymmetric_unit_indices()
   self.i_obs = all_arrays.i_obs()
   self.sigmas = all_arrays.sigmas()
Example #10
0
 def possible_point_group_generators(self):
     lattice_group = lattice_symmetry.group(self.f_in_p1.unit_cell(),
                                            max_delta=1)
     lattice_group.expand_inv(sgtbx.tr_vec((0, 0, 0)))
     rot_parts = set()
     decorated_rot_parts = []
     for op in lattice_group:
         r = op.r()
         if r.is_unit_mx(): continue
         if op.inverse() in rot_parts: continue
         r_info = sgtbx.rot_mx_info(r)
         if r_info.type() < -2: continue
         rot_parts.add(op)
         decorated_rot_parts.append((
             r_info.type() == -1,  # inversion shall come first,
             list(r_info.ev()).count(
                 0),  # axes // to unit cell shall come first
             # note Python 2.5- compatibility
             r_info.type() == -2,  # mirrors preferred.
             r.order(),  # higher order preferred
             op))
     decorated_rot_parts.sort()
     decorated_rot_parts.reverse()
     for item in decorated_rot_parts:
         yield item[-1]
Example #11
0
 def __init__(self, file_name, header_only=False):
   self.file_name = os.path.normpath(file_name)
   f = open(file_name)
   line = f.readline()
   assert line[5] == " "
   n_sym_ops_from_file = int(line[:5].strip())
   assert n_sym_ops_from_file > 0
   self.space_group_symbol = line[6:].strip()
   self.space_group_from_ops = sgtbx.space_group()
   for i in range(n_sym_ops_from_file):
     line = f.readline().rstrip()
     assert len(line) == 27
     r = sgtbx.rot_mx([int(line[j*3:(j+1)*3]) for j in range(9)], 1)
     line = f.readline().rstrip()
     assert len(line) == 9
     t = sgtbx.tr_vec([int(line[j*3:(j+1)*3]) for j in range(3)], 12)
     self.space_group_from_ops.expand_smx(sgtbx.rt_mx(r, t))
   f.close()
   if (header_only):
     self.original_indices = None
     return
   all_arrays = scalepack_ext.no_merge_original_index_arrays(
     file_name, n_sym_ops_from_file*2+1)
   self.original_indices = all_arrays.original_indices()
   self.unique_indices = all_arrays.unique_indices()
   self.batch_numbers = all_arrays.batch_numbers()
   self.centric_tags = all_arrays.centric_tags()
   self.spindle_flags = all_arrays.spindle_flags()
   self.asymmetric_unit_indices = all_arrays.asymmetric_unit_indices()
   self.i_obs = all_arrays.i_obs()
   self.sigmas = all_arrays.sigmas()
Example #12
0
    def __init__(self, r, d, symmetry_agreement, status):
        assert r.den() == 1
        self.r = r
        order = r.order()
        self.r_info = sgtbx.rot_mx_info(r)
        type = self.r_info.type()
        axis = self.r_info.ev()

        self.symmetry_agreement = symmetry_agreement
        self.status = status

        # compute intrinsic and location part of d, using p, which is
        # the order times the projector onto r's invariant space
        p = mat.sqr(r.accumulate().as_double())
        t_i_num = (p * d).as_int()
        t_l = d - t_i_num / order
        t_i = sgtbx.tr_vec(sg_t_den // order * t_i_num, tr_den=sg_t_den)

        # compute the origin corresponding to t_l by solving
        # (1 - r) o = t_l
        one_minus_r = -mat.sqr(self.r.minus_unit_mx().num())
        one_minus_r_row_echelon = one_minus_r.as_flex_int_matrix()
        q = mat.identity(3).as_flex_int_matrix()
        rank = scitbx.math.row_echelon_form_t(one_minus_r_row_echelon, q)
        qd = flex.double(mat.sqr(q) * t_l)[:rank]
        o = flex.double((0, 0, 0))
        scitbx.math.row_echelon_back_substitution_float(
            one_minus_r_row_echelon, qd, o)

        # construct object state
        self.t_i, self.raw_origin = t_i, mat.col(o)
        self.origin = None
        self.one_minus_r = one_minus_r
def convert(file_object):
  """ Examplify the direct use of the tool from shelx.lexer

  In practice, one is strongly encouraged to make use of the tools
  from shelx.parsers: that is to say, for the task handled here,
  crystal_symmetry_parser (the code to follow just parrots
  the implementation of crystal_symmetry_parser).
  """
  space_group = None
  for command, line in shelx.command_stream(file=file_object):
    cmd, args = command[0], command[-1]
    if cmd == "LATT":
      assert space_group is None
      assert len(args) == 1
      space_group = sgtbx.space_group()
      n = int(args[0])
      if n > 0:
        space_group.expand_inv(sgtbx.tr_vec((0,0,0)))
      z = "*PIRFABC"[abs(n)]
      space_group.expand_conventional_centring_type(z)
    elif cmd == "SYMM":
      assert space_group is not None
      assert len(args) == 1
      s = sgtbx.rt_mx(args[0])
      space_group.expand_smx(s)
    elif cmd == "SFAC":
      return sgtbx.space_group_info(group=space_group)
Example #14
0
 def change_origin(self, origin):
   o = self.raw_origin - origin
   t_l = self.one_minus_r*o
   t_l = sgtbx.tr_vec((sg_t_den*t_l).as_int(), tr_den=sg_t_den)
   self.rt = sgtbx.rt_mx(self.r, self.t_i.plus(t_l).new_denominator(sg_t_den))
   tr_info = sgtbx.translation_part_info(self.rt)
   self.origin = tr_info.origin_shift()
   self.t_i = tr_info.intrinsic_part()
Example #15
0
 def change_origin(self, origin):
   o = self.raw_origin - origin
   t_l = self.one_minus_r*o
   t_l = sgtbx.tr_vec((sg_t_den*t_l).as_int(), tr_den=sg_t_den)
   self.rt = sgtbx.rt_mx(self.r, self.t_i.plus(t_l).new_denominator(sg_t_den))
   tr_info = sgtbx.translation_part_info(self.rt)
   self.origin = tr_info.origin_shift()
   self.t_i = tr_info.intrinsic_part()
def get_all_axes(space_group_symbol=None, space_group_info=None, extension=0):
  assert space_group_symbol is None or space_group_info is None
  shift_range = 1 # RWGK Works for the 230 reference settings; it is not
          # RWGK clear to me (rwgk) what value is needed in general.
  if (space_group_symbol is not None):
    space_group_info = sgtbx.space_group_info(symbol=space_group_symbol)
  #space_group_info.show_summary()

  axes_dict = {}
  for smx in space_group_info.group():
    r = smx.r()
    t = smx.t()
    shift = [0,0,0]
    for shift[0] in range(-shift_range,shift_range+1):
      for shift[1] in range(-shift_range,shift_range+1):
        for shift[2] in range(-shift_range,shift_range+1):
          ts = t.plus(sgtbx.tr_vec(shift, 1)).new_denominator(t.den())
          m = sgtbx.rt_mx(r, ts)
          #print m
          rtmxanal = rlc_RTMxAnalysis(m)
          #print r, t, shift, ts, m
          if rtmxanal:
            #print rtmxanal
            axes_dict[rtmxanal] = 0
  axes_list = axes_dict.keys()
  axes_list.sort()

  # reject nonenantiomorphic space groups
  if len(axes_list) > 0 and not re.compile("[A-z]").search(space_group_symbol[1:]):
    try:
      sgtbx.space_group_info(space_group_symbol).show_summary(), 
      #print len(axes_list), space_group_symbol
    except:
      print space_group, space_group_symbol
      print
      sys.exit(1)
    axes = []
    for a in axes_list:
      if len(a) == 3 and len(a[1]) == 3 and len(a[2]) == 3:
        tmp_dict = {}
        print "%4s %7.4f %7.4f %7.4f    %7.4f %7.4f %7.4f " % (a[0],a[1][0],a[1][1],a[1][2],a[2][0],a[2][1],a[2][2])
        tmp_dict['symb'] = a[0]
        start_array = N.asarray(a[1])
        end_array = N.asarray(a[2])
        start_vec = start_array - (end_array - start_array)*extension
        end_vec = end_array + (end_array - start_array)*extension
        tmp_dict['start'] = start_vec
        tmp_dict['end'] = end_vec
#rlc#        tmp_dict['start'] = a[1]
#rlc#        tmp_dict['end'] = a[2]
        axes.append(tmp_dict)
      else:
        print a
  else:
    return None

  return axes
Example #17
0
 def __init__(self, lf):
     self.symbol = None
     l = lf.next()
     print l.strip()
     if (lf.eof): return
     no, number, symbol, m = l.split()
     assert no == "NO."
     number = int(number)
     assert int(float(m)) == float(m)
     m = int(float(m))
     space_group = sgtbx.space_group()
     if (m < 0):
         space_group.expand_inv(sgtbx.tr_vec((0, 0, 0)))
     space_group.expand_conventional_centring_type(symbol[0])
     t_den = space_group.t_den()
     matrices = []
     for i in xrange(abs(m)):
         l = lf.next()
         assert not lf.eof
         flds = l.split()
         assert len(flds) == 12
         r = [int(e) for e in flds[1:4] + flds[5:8] + flds[9:12]]
         t = [
             int(round(float(e) * t_den))
             for e in (flds[0], flds[4], flds[8])
         ]
         try:
             s = sgtbx.rt_mx(sgtbx.rot_mx(r), sgtbx.tr_vec(t))
         except RuntimeError, e:
             print e
             print l
         else:
             try:
                 matrices.append(s)
                 space_group.expand_smx(s)
             except RuntimeError, e:
                 print e
                 print l
                 print s
 def __init__(self,
              input,
              n_bins,
              lattice_symmetry_max_delta,
              completeness_as_non_anomalous=None):
     self.completeness_as_non_anomalous = completeness_as_non_anomalous
     self.input = input.eliminate_sys_absent(integral_only=True,
                                             log=sys.stdout)
     self.lattice_symmetry_max_delta = lattice_symmetry_max_delta
     if (not self.input.is_unique_set_under_symmetry()):
         print("Merging symmetry-equivalent reflections:")
         merged = self.input.merge_equivalents()
         merged.show_summary(prefix="  ")
         print()
         self.input = merged.array()
         del merged
         if (input.info() is not None):
             self.input.set_info(input.info().customized_copy(merged=True))
         else:
             self.input.set_info(miller.array_info(merged=True))
     self.input.show_comprehensive_summary()
     print()
     self.input.setup_binner(n_bins=n_bins)
     self.resolution_range = self.input.resolution_range()
     self.change_of_basis_op_to_minimum_cell \
       = self.input.change_of_basis_op_to_minimum_cell()
     self.observations = self.input.change_basis(
       cb_op=self.change_of_basis_op_to_minimum_cell) \
         .expand_to_p1() \
         .map_to_asu()
     if (self.input.anomalous_flag()):
         self.anom_diffs = abs(self.input.anomalous_differences()).change_basis(
           cb_op=self.change_of_basis_op_to_minimum_cell) \
             .expand_to_p1() \
             .map_to_asu()
     else:
         self.anom_diffs = None
     self.minimum_cell_symmetry = crystal.symmetry.change_basis(
         self.input, cb_op=self.change_of_basis_op_to_minimum_cell)
     self.intensity_symmetry = \
       self.minimum_cell_symmetry.reflection_intensity_symmetry(
         anomalous_flag=self.input.anomalous_flag())
     self.lattice_group = sgtbx.lattice_symmetry.group(
         self.minimum_cell_symmetry.unit_cell(),
         max_delta=self.lattice_symmetry_max_delta)
     self.lattice_group.expand_inv(sgtbx.tr_vec((0, 0, 0)))
     self.lattice_group.make_tidy()
     self.lattice_symmetry = crystal.symmetry(
         unit_cell=self.minimum_cell_symmetry.unit_cell(),
         space_group_info=sgtbx.space_group_info(group=self.lattice_group),
         assert_is_compatible_unit_cell=False)
 def __init__(self, lf):
   self.symbol = None
   l = lf.next()
   print l.strip()
   if (lf.eof): return
   no, number, symbol, m = l.split()
   assert no == "NO."
   number = int(number)
   assert int(float(m)) == float(m)
   m = int(float(m))
   space_group = sgtbx.space_group()
   if (m < 0):
     space_group.expand_inv(sgtbx.tr_vec((0,0,0)))
   space_group.expand_conventional_centring_type(symbol[0])
   t_den = space_group.t_den()
   matrices = []
   for i in xrange(abs(m)):
     l = lf.next()
     assert not lf.eof
     flds = l.split()
     assert len(flds) == 12
     r = [int(e) for e in flds[1:4] + flds[5:8] + flds[9:12]]
     t = [int(round(float(e)*t_den)) for e in (flds[0],flds[4],flds[8])]
     try:
       s = sgtbx.rt_mx(sgtbx.rot_mx(r), sgtbx.tr_vec(t))
     except RuntimeError, e:
       print e
       print l
     else:
       try:
         matrices.append(s)
         space_group.expand_smx(s)
       except RuntimeError, e:
         print e
         print l
         print s
 def __init__(self, input, n_bins, lattice_symmetry_max_delta, completeness_as_non_anomalous=None):
     self.completeness_as_non_anomalous = completeness_as_non_anomalous
     self.input = input.eliminate_sys_absent(integral_only=True, log=sys.stdout)
     self.lattice_symmetry_max_delta = lattice_symmetry_max_delta
     if not self.input.is_unique_set_under_symmetry():
         print "Merging symmetry-equivalent reflections:"
         merged = self.input.merge_equivalents()
         merged.show_summary(prefix="  ")
         print
         self.input = merged.array()
         del merged
         if input.info() is not None:
             self.input.set_info(input.info().customized_copy(merged=True))
         else:
             self.input.set_info(miller.array_info(merged=True))
     self.input.show_comprehensive_summary()
     print
     self.input.setup_binner(n_bins=n_bins)
     self.resolution_range = self.input.resolution_range()
     self.change_of_basis_op_to_minimum_cell = self.input.change_of_basis_op_to_minimum_cell()
     self.observations = (
         self.input.change_basis(cb_op=self.change_of_basis_op_to_minimum_cell).expand_to_p1().map_to_asu()
     )
     if self.input.anomalous_flag():
         self.anom_diffs = (
             abs(self.input.anomalous_differences())
             .change_basis(cb_op=self.change_of_basis_op_to_minimum_cell)
             .expand_to_p1()
             .map_to_asu()
         )
     else:
         self.anom_diffs = None
     self.minimum_cell_symmetry = crystal.symmetry.change_basis(
         self.input, cb_op=self.change_of_basis_op_to_minimum_cell
     )
     self.intensity_symmetry = self.minimum_cell_symmetry.reflection_intensity_symmetry(
         anomalous_flag=self.input.anomalous_flag()
     )
     self.lattice_group = sgtbx.lattice_symmetry.group(
         self.minimum_cell_symmetry.unit_cell(), max_delta=self.lattice_symmetry_max_delta
     )
     self.lattice_group.expand_inv(sgtbx.tr_vec((0, 0, 0)))
     self.lattice_group.make_tidy()
     self.lattice_symmetry = crystal.symmetry(
         unit_cell=self.minimum_cell_symmetry.unit_cell(),
         space_group_info=sgtbx.space_group_info(group=self.lattice_group),
         assert_is_compatible_unit_cell=False,
     )
def compatible_symmetries(point_group):
  """ Primitive setting assumed """
  for op in point_group:
    r = op.r()
    order = r.order()
    if r.info().type() == 1: continue
    yield op
    invariants = [ matrix.col(u) for u in r.info().basis_of_invariant() ]
    if len(invariants) == 2:
      t1, t2 = invariants
      invariants.extend((t1 + t2, t1 - t2))
    translations = []
    for t in invariants:
      t = sgtbx.tr_vec(t, order).mod_short()
      if not t.is_zero() and t not in translations:
        translations.append(t)
    for t in translations:
      yield sgtbx.rt_mx(r, t.new_denominator(sgtbx.sg_t_den))
Example #22
0
def compatible_symmetries(point_group):
    """ Primitive setting assumed """
    for op in point_group:
        r = op.r()
        order = r.order()
        if r.info().type() == 1: continue
        yield op
        invariants = [matrix.col(u) for u in r.info().basis_of_invariant()]
        if len(invariants) == 2:
            t1, t2 = invariants
            invariants.extend((t1 + t2, t1 - t2))
        translations = []
        for t in invariants:
            t = sgtbx.tr_vec(t, order).mod_short()
            if not t.is_zero() and t not in translations:
                translations.append(t)
        for t in translations:
            yield sgtbx.rt_mx(r, t.new_denominator(sgtbx.sg_t_den))
Example #23
0
 def find_centring_translations(self):
   for d in self.centring_translation_peak_sites():
     t = [ scitbx.math.continued_fraction.from_real(x, 1e-2).as_rational()
           for x in d ]
     if t.count(0) > 1: continue
     unique_denominators = dict(
       [ (r.denominator(), 1) for r in t if r.numerator() != 0 ]).keys()
     assert len(unique_denominators) in (0, 1)
     if len(unique_denominators) == 1:
       den = unique_denominators[0]
       num = [ r.numerator() for r in t ]
       tr_vec = sgtbx.tr_vec(num, den)
       try:
         tr_vec = tr_vec.new_denominator(sg_t_den)
       except RuntimeError, e:
         if (not str(e).endswith(
               "Unsuitable value for rational translation vector.")):
           raise
         raise RuntimeError(
           "Sorry not implemented: handling of translation vector %s"
             % str(tuple(t)))
       self.space_group.expand_ltr(tr_vec)
def exercise_change_of_basis_between_arbitrary_space_groups():
  from random import randint
  from scitbx import matrix as mat

  g = sgtbx.space_group_info('hall: P 2')
  h = sgtbx.space_group_info('hall: P 2c')
  assert g.change_of_basis_op_to(h) is None

  g = sgtbx.space_group_info('hall: C 2c 2 (x+y,x-y,z)')
  h = g.change_basis(sgtbx.change_of_basis_op(sgtbx.rt_mx('-y,x,z')))
  cb_op = g.change_of_basis_op_to(h)
  assert cb_op.as_xyz() == 'x,y,z+1/4'
  assert g.change_basis(cb_op).group() == h.group()

  g = sgtbx.space_group_info('hall: I 4 2 3')
  z2p_op = g.change_of_basis_op_to_primitive_setting()
  h = g.change_basis(z2p_op)
  cb_op = g.change_of_basis_op_to(h)
  assert cb_op.c() == z2p_op.c(), (cb_op.as_xyz(), z2p_op.as_xyz())

  for i in xrange(1, 231):
    s = sgtbx.space_group_symbols(space_group_number=i)
    g = sgtbx.space_group_info(group=sgtbx.space_group(s, t_den=24))

    o = tuple([ randint(0, 23) for j in xrange(3) ])
    cb_op = sgtbx.change_of_basis_op(sgtbx.rt_mx(sgtbx.tr_vec(o, 24)))
    h = g.change_basis(cb_op)
    cb_op_1 = g.change_of_basis_op_to(h)
    assert cb_op_1.c().r().is_unit_mx()
    delta = (mat.col(cb_op_1.c().t().as_double())
             - mat.col(cb_op.c().t().as_double()))
    assert h.is_allowed_origin_shift(delta, tolerance=1e-12)

    z2p_op = g.change_of_basis_op_to_primitive_setting()
    h = g.change_basis(z2p_op)
    cb_op = g.change_of_basis_op_to(h)
    h1 = g.change_basis(cb_op)
    assert (h.as_reference_setting().group()
            == h1.as_reference_setting().group())
Example #25
0
def exercise_change_of_basis_between_arbitrary_space_groups():
    from random import randint
    from scitbx import matrix as mat

    g = sgtbx.space_group_info('hall: P 2')
    h = sgtbx.space_group_info('hall: P 2c')
    assert g.change_of_basis_op_to(h) is None

    g = sgtbx.space_group_info('hall: C 2c 2 (x+y,x-y,z)')
    h = g.change_basis(sgtbx.change_of_basis_op(sgtbx.rt_mx('-y,x,z')))
    cb_op = g.change_of_basis_op_to(h)
    assert cb_op.as_xyz() == 'x,y,z+1/4'
    assert g.change_basis(cb_op).group() == h.group()

    g = sgtbx.space_group_info('hall: I 4 2 3')
    z2p_op = g.change_of_basis_op_to_primitive_setting()
    h = g.change_basis(z2p_op)
    cb_op = g.change_of_basis_op_to(h)
    assert cb_op.c() == z2p_op.c(), (cb_op.as_xyz(), z2p_op.as_xyz())

    for i in range(1, 231):
        s = sgtbx.space_group_symbols(space_group_number=i)
        g = sgtbx.space_group_info(group=sgtbx.space_group(s, t_den=24))

        o = tuple([randint(0, 23) for j in range(3)])
        cb_op = sgtbx.change_of_basis_op(sgtbx.rt_mx(sgtbx.tr_vec(o, 24)))
        h = g.change_basis(cb_op)
        cb_op_1 = g.change_of_basis_op_to(h)
        assert cb_op_1.c().r().is_unit_mx()
        delta = (mat.col(cb_op_1.c().t().as_double()) -
                 mat.col(cb_op.c().t().as_double()))
        assert h.is_allowed_origin_shift(delta, tolerance=1e-12)

        z2p_op = g.change_of_basis_op_to_primitive_setting()
        h = g.change_basis(z2p_op)
        cb_op = g.change_of_basis_op_to(h)
        h1 = g.change_basis(cb_op)
        assert (h.as_reference_setting().group() ==
                h1.as_reference_setting().group())
Example #26
0
 def filtered_commands(self):
     """ Yields those command in self.command_stream
     that this parser is not concerned with. On the contrary,
     LATT, SYMM are swallowed (CELL is yielded because it carries
     the wavelength too).
 """
     unit_cell = None
     unit_cell_param_sigmas = None
     space_group = sgtbx.space_group()
     for command, line in self.command_stream:
         cmd, args = command[0], command[-1]
         if cmd == 'CELL':
             assert unit_cell is None
             unit_cell = uctbx.unit_cell(args[1:])
             yield command, line
         elif cmd == 'ZERR':
             assert unit_cell_param_sigmas is None
             unit_cell_param_sigmas = args[1:]
             yield command, line
         elif cmd == 'LATT':
             assert len(args) == 1
             n = int(args[0])
             if n > 0:
                 space_group.expand_inv(sgtbx.tr_vec((0, 0, 0)))
             z = "*PIRFABC"[abs(n)]
             space_group.expand_conventional_centring_type(z)
         elif cmd == 'SYMM':
             assert len(args) == 1
             s = sgtbx.rt_mx(args[0])
             space_group.expand_smx(s)
         else:
             if cmd == 'SFAC':
                 assert unit_cell is not None
                 self.builder.make_crystal_symmetry(unit_cell=unit_cell,
                                                    space_group=space_group)
                 self.builder.set_unit_cell_parameter_sigmas(
                     unit_cell_param_sigmas)
             yield command, line
Example #27
0
 def possible_point_group_generators(self):
   lattice_group = lattice_symmetry.group(self.f_in_p1.unit_cell(),
                                          max_delta=1)
   lattice_group.expand_inv(sgtbx.tr_vec((0,0,0)))
   rot_parts = set()
   decorated_rot_parts = []
   for op in lattice_group:
     r = op.r()
     if r.is_unit_mx(): continue
     if op.inverse() in rot_parts: continue
     r_info = sgtbx.rot_mx_info(r)
     if r_info.type() < -2: continue
     rot_parts.add(op)
     decorated_rot_parts.append(
       (r_info.type() == -1, # inversion shall come first,
        list(r_info.ev()).count(0), # axes // to unit cell shall come first
                                    # note Python 2.5- compatibility
        r_info.type() == -2, # mirrors preferred.
        r.order(), # higher order preferred
        op))
   decorated_rot_parts.sort()
   decorated_rot_parts.reverse()
   for item in decorated_rot_parts: yield item[-1]
Example #28
0
 def filtered_commands(self):
   """ Yields those command in self.command_stream
       that this parser is not concerned with. On the contrary,
       LATT, SYMM are swallowed (CELL is yielded because it carries
       the wavelength too).
   """
   unit_cell = None
   unit_cell_param_sigmas = None
   space_group = sgtbx.space_group()
   for command, line in self.command_stream:
     cmd, args = command[0], command[-1]
     if cmd == 'CELL':
       assert unit_cell is None
       unit_cell = uctbx.unit_cell(args[1:])
       yield command, line
     elif cmd == 'ZERR':
       assert unit_cell_param_sigmas is None
       unit_cell_param_sigmas = args[1:]
       yield command, line
     elif cmd == 'LATT':
       assert len(args) == 1
       n = int(args[0])
       if n > 0:
         space_group.expand_inv(sgtbx.tr_vec((0,0,0)))
       z = "*PIRFABC"[abs(n)]
       space_group.expand_conventional_centring_type(z)
     elif cmd == 'SYMM':
       assert len(args) == 1
       s = sgtbx.rt_mx(args[0])
       space_group.expand_smx(s)
     else:
       if cmd == 'SFAC':
         assert unit_cell is not None
         self.builder.make_crystal_symmetry(unit_cell=unit_cell,
                                            space_group=space_group)
         self.builder.set_unit_cell_parameter_sigmas(unit_cell_param_sigmas)
       yield command, line
  def derive_result_group_list(self,group_of_interest):

    # Get list of sub-spacegroups
    subgrs = subgroups.subgroups(group_of_interest).groups_parent_setting()

    # Order sub-groups
    sort_values = flex.double()
    for group in subgrs:
      order_z = group.order_z()
      space_group_number = sgtbx.space_group_type(group, False).number()
      assert 1 <= space_group_number <= 230
      sort_values.append(order_z*1000+space_group_number)
    perm = flex.sort_permutation(sort_values, True)

    for i_subgr in perm:
      acentric_subgroup = subgrs[i_subgr]
      acentric_supergroup = metric_supergroup(acentric_subgroup)
      # Add centre of inversion to acentric lattice symmetry
      centric_group = sgtbx.space_group(acentric_subgroup)
      centric_group.expand_inv(sgtbx.tr_vec((0,0,0)))
      # Make symmetry object: unit-cell + space-group
      # The unit cell is potentially modified to be exactly compatible
      # with the space group symmetry.
      subsym = crystal.symmetry(
        unit_cell=self.minimum_symmetry.unit_cell(),
        space_group=centric_group,
        assert_is_compatible_unit_cell=False)
      supersym = crystal.symmetry(
        unit_cell=self.minimum_symmetry.unit_cell(),
        space_group=acentric_supergroup,
        assert_is_compatible_unit_cell=False)
      # Convert subgroup to reference setting
      cb_op_minimum_ref = subsym.space_group_info().type().cb_op()
      ref_subsym = subsym.change_basis(cb_op_minimum_ref)
      # Ignore unwanted groups
      if (self.bravais_types_only and
          not str(ref_subsym.space_group_info()) in bravais_types.centric):
        continue
      # Choose best setting for monoclinic and orthorhombic systems
      cb_op_best_cell = self.change_of_basis_op_to_best_cell(ref_subsym)
      best_subsym = ref_subsym.change_basis(cb_op_best_cell)
      # Total basis transformation
      cb_op_best_cell = change_of_basis_op(str(cb_op_best_cell),stop_chars='',r_den=144,t_den=144)
      cb_op_minimum_ref=change_of_basis_op(str(cb_op_minimum_ref),stop_chars='',r_den=144,t_den=144)
      self.cb_op_inp_minimum=change_of_basis_op(str(self.cb_op_inp_minimum),stop_chars='',r_den=144,t_den=144)
      cb_op_inp_best = cb_op_best_cell * cb_op_minimum_ref * self.cb_op_inp_minimum
      # Use identity change-of-basis operator if possible
      if (best_subsym.unit_cell().is_similar_to(self.input_symmetry.unit_cell())):
        cb_op_corr = cb_op_inp_best.inverse()
        try:
          best_subsym_corr = best_subsym.change_basis(cb_op_corr)
        except RuntimeError, e:
          if (str(e).find("Unsuitable value for rational rotation matrix.") < 0):
            raise
        else:
          if (best_subsym_corr.space_group() == best_subsym.space_group()):
            cb_op_inp_best = cb_op_corr * cb_op_inp_best
      self.result_groups.append({'subsym':subsym,
                                 'supersym':supersym,
                                 'ref_subsym':ref_subsym,
                                 'best_subsym':best_subsym,
                                 'cb_op_inp_best':cb_op_inp_best,
                                 'max_angular_difference':
                                  find_max_delta(
                                  reduced_cell=self.minimum_symmetry.unit_cell(),
                                  space_group=acentric_supergroup)
                               })
Example #30
0
def exercise(space_group_info,
             fixed_random_seed=True,
             shifted_origin=None,
             elements=None,
             d_min=0.8,
             grid_resolution_factor=1/3.,
             verbose=False,
             **kwds):
  if elements is None:
    n_C = 5
    n_O = 1
    n_N = 1
    elements = ["C"]*n_C + ["O"]*n_O + ["N"]*n_N
  if verbose:
    print elements

  target_space_group_type = space_group_info.type()
  hall = sgtbx.space_group_symbols(
    target_space_group_type.lookup_symbol()).hall()
  print hall

  if fixed_random_seed:
    random.seed(1)
    flex.set_random_seed(1)

  # Generate a random structure in real space,
  # compute its structure factors,
  # that we will try to recover the symmetry of
  target_structure = random_structure.xray_structure(
    space_group_info=space_group_info,
    elements=elements,
    use_u_iso=True,
    random_u_iso=True,
    random_u_iso_scale=0.04,
    use_u_aniso=False,
  )
  if shifted_origin is None:
    shifted_origin = flex.random_double(3)
  shifted_origin = mat.col(shifted_origin)
  if verbose:
    print "new origin = (%.3f, %.3f, %.3f)" % shifted_origin.elems
    print
  target_structure_in_p1 = target_structure\
                         .expand_to_p1().apply_shift(shifted_origin)
  target_f_in_p1 = miller.build_set(
    crystal_symmetry=target_structure_in_p1,
    anomalous_flag=False,
    d_min=d_min
    ).structure_factors_from_scatterers(
      xray_structure=target_structure_in_p1,
      algorithm="direct").f_calc()

  # Recover space group?
  sf_symm = symmetry_search.structure_factor_symmetry(target_f_in_p1)
  if verbose:
    print sf_symm

  solution_hall, target_hall = [
    sgi.as_reference_setting().type().hall_symbol()
    for sgi in (sf_symm.space_group_info,
                target_structure.space_group_info()) ]
  assert solution_hall == target_hall, (solution_hall, target_hall)

  # Shift maximises goodness of symmetry?
  gos, solution_f = sf_symm.symmetrised_structure_factors()
  if space_group_info.type().hall_symbol() != ' P 1':
    assert gos.correlation > 0.99
    assert gos.gradient == (0, 0, 0)
    gos_away_from_max = sf_symm.symmetrised_structure_factors(
      delta=mat.col((0.1, 0.1, 0.1)))[0]
    assert gos_away_from_max.correlation < 0.9, gos_away_from_max.correlation

  # Recovered origin
  """The sequence of transform read:
  ----->target structure
  ^           V
  ^           V  (1, shifted_origin=sigma)
  ^           V
  ^      shifted target
  ^           V
  ^           V sf_symm.cb_op_to_primitive = (P, 0)
  ^           V
  ^      shifted target in primitive cell = shifted solution in primitive cell
  ^           V
  ^           V (1, -sf_symm.origin=-s)
  ^           V
  ^      solution in primitive cell
  ^           V
  ^           V solution_to_target_cb_op = (Q, q)
  ^           V
  ^------------

  The total transfrom from the target structure back to it reads
  (QP, q') with q' = (Q,q)(-s + P sigma) = (Q,q)delta_o
  with
  delta_o = sf_symm.cb_op_to_primitive(shifted_origin) - sf_symm.origin

  (Q, q') must leave the target structure space group invariant.
  Most of the time Q is the unit matrix and the test boils down to check
  whether delta is an allowed origin shift after changing to the input cell
  but it does not hurt to do the more general test all the time.
  """

  solution_to_target_cb_op = (
    target_structure.space_group_info()
    .change_of_basis_op_to_reference_setting().inverse()
    *
    sf_symm.space_group_info
    .change_of_basis_op_to_reference_setting())

  if verbose:
    print
    print "solution -> target: %s" % solution_to_target_cb_op.as_xyz()
  delta_o = (mat.col(sf_symm.cb_op_to_primitive(shifted_origin))
             - sf_symm.origin)
  delta = mat.col(solution_to_target_cb_op(delta_o))
  stabilising_cb_op = sgtbx.change_of_basis_op(sgtbx.rt_mx(
    (solution_to_target_cb_op*sf_symm.cb_op_to_primitive).c().r(),
    sgtbx.tr_vec((delta*72).as_int()*2, tr_den=144)))
    # guarding against rounding errors on some platforms (e.g. FC8)
    # meaning that (delta*144).as_int() would not work.
  target_sg = target_structure.space_group()
  assert target_sg == target_sg.change_basis(stabilising_cb_op)
Example #31
0
def exercise_unmerged(space_group_info):
    import random
    from cctbx import sgtbx

    # shuffle the
    space_group = sgtbx.space_group("P 1", no_expand=True)
    perm = list(range(len(space_group_info.group())))
    random.shuffle(perm)
    for i in perm:
        space_group.expand_smx(space_group_info.group()[i])
    unit_cell = space_group_info.any_compatible_unit_cell(volume=1000)
    for cb_op in (
        None,
        space_group.info().change_of_basis_op_to_primitive_setting(),
        unit_cell.change_of_basis_op_to_niggli_cell(),
    ):
        miller_set = crystal.symmetry(unit_cell=unit_cell, space_group=space_group).build_miller_set(
            d_min=1, anomalous_flag=True
        )
        miller_set = miller_set.expand_to_p1().customized_copy(space_group_info=miller_set.space_group_info())
        if cb_op is not None:
            miller_set = miller_set.change_basis(cb_op)

        m = mtz.object()
        m.set_title("This is a title")
        m.set_space_group_info(miller_set.space_group_info())
        x = m.add_crystal("XTAL", "CCTBX", miller_set.unit_cell().parameters())
        d = x.add_dataset("TEST", 1)

        indices = miller_set.indices()
        original_indices = indices.deep_copy()

        # map the miller indices to one hemisphere (i.e. just I+)
        miller.map_to_asu(m.space_group().type(), False, indices)

        h, k, l = [i.iround() for i in indices.as_vec3_double().parts()]
        m.adjust_column_array_sizes(len(h))
        m.set_n_reflections(len(h))

        # assign H, K, L
        d.add_column("H", "H").set_values(h.as_double().as_float())
        d.add_column("K", "H").set_values(k.as_double().as_float())
        d.add_column("L", "H").set_values(l.as_double().as_float())

        d.add_column("M_ISYM", "Y").set_values(flex.float(len(indices)))

        m.replace_original_index_miller_indices(original_indices)

        assert (m.extract_original_index_miller_indices() == original_indices).count(False) == 0
        # check the indices in the mtz file are actually in the asu
        extracted_indices = m.extract_miller_indices()
        miller.map_to_asu(m.space_group().type(), False, extracted_indices)
        assert (extracted_indices == m.extract_miller_indices()).count(False) == 0

        # test change_basis_in_place if appropriate for current space group
        import cctbx.sgtbx.cosets

        cb_op_to_niggli_cell = miller_set.change_of_basis_op_to_niggli_cell()

        minimum_cell_symmetry = crystal.symmetry.change_basis(miller_set.crystal_symmetry(), cb_op=cb_op_to_niggli_cell)

        lattice_group = sgtbx.lattice_symmetry.group(minimum_cell_symmetry.unit_cell(), max_delta=3.0)
        lattice_group.expand_inv(sgtbx.tr_vec((0, 0, 0)))
        lattice_group.make_tidy()

        cosets = sgtbx.cosets.left_decomposition_point_groups_only(
            g=lattice_group,
            h=minimum_cell_symmetry.reflection_intensity_symmetry(anomalous_flag=True)
            .space_group()
            .build_derived_acentric_group()
            .make_tidy(),
        )

        possible_twin_laws = cosets.best_partition_representatives(
            cb_op=cb_op_to_niggli_cell.inverse(), omit_first_partition=True, omit_negative_determinants=True
        )

        for twin_law in possible_twin_laws:
            cb_op = sgtbx.change_of_basis_op(twin_law.as_xyz())
            # print cb_op.as_hkl()
            # forward direction
            m.change_basis_in_place(cb_op)
            assert (m.extract_original_index_miller_indices() == cb_op.apply(original_indices)).count(False) == 0
            ## check the indices in the mtz file are actually in the asu
            # extracted_indices = m.extract_miller_indices()
            # miller.map_to_asu(m.space_group().type(), False, extracted_indices)
            # assert (extracted_indices == m.extract_miller_indices()).count(False) == 0
            # and back again
            m.change_basis_in_place(cb_op.inverse())
            assert (m.extract_original_index_miller_indices() == original_indices).count(False) == 0
Example #32
0
 def __init__(self, lf):
     self.symbol = None
     l = next(lf)
     print(l.strip())
     if (lf.eof): return
     no, number, symbol, m = l.split()
     assert no == "NO."
     number = int(number)
     assert int(float(m)) == float(m)
     m = int(float(m))
     space_group = sgtbx.space_group()
     if (m < 0):
         space_group.expand_inv(sgtbx.tr_vec((0, 0, 0)))
     space_group.expand_conventional_centring_type(symbol[0])
     t_den = space_group.t_den()
     matrices = []
     for i in range(abs(m)):
         l = next(lf)
         assert not lf.eof
         flds = l.split()
         assert len(flds) == 12
         r = [int(e) for e in flds[1:4] + flds[5:8] + flds[9:12]]
         t = [
             int(round(float(e) * t_den))
             for e in (flds[0], flds[4], flds[8])
         ]
         try:
             s = sgtbx.rt_mx(sgtbx.rot_mx(r), sgtbx.tr_vec(t))
         except RuntimeError as e:
             print(e)
             print(l)
         else:
             try:
                 matrices.append(s)
                 space_group.expand_smx(s)
             except RuntimeError as e:
                 print(e)
                 print(l)
                 print(s)
     space_group_info = sgtbx.space_group_info(group=space_group)
     if (space_group_info.type().number() != number):
         print("Space group number mismatch:")
         print("   from file:", number)
         print("  operations:", space_group_info.type().number())
         for s in matrices:
             space_group = sgtbx.space_group_info(symbol=number).group()
             order_z = space_group.order_z()
             space_group.expand_smx(s)
             if (space_group.order_z() != order_z):
                 print("  misfit:", s)
         space_group = sgtbx.space_group_info(symbol=number).group()
         for i_smx in range(space_group.n_smx()):
             OK = False
             for i_inv in range(space_group.f_inv()):
                 for i_ltr in range(space_group.n_ltr()):
                     sg = space_group(i_ltr, i_inv, i_smx).mod_positive()
                     for sm in matrices:
                         sm = sm.mod_positive()
                         if (sm == sg):
                             OK = True
                             break
                     if (OK): break
                 if (OK): break
             if (not OK):
                 print("  missing:", sg)
     self.number = number
     self.symbol = symbol
     self.space_group_info = space_group_info
try:
    from crys3d.qttbx.xray_structure_viewer import display
except IOError:
    def display(*args, **kwds): pass
# then use it
#display(xray_structure=xs)

# Let's look at symmetries
info = xs.space_group_info()
info.show_summary()
print "Hall: %s" % info.type().hall_symbol()
# List of all symmetries
print "Symmetries:"
for rt in info.group():
    print rt.as_xyz()
# The mathematical object representing the group
g = info.group()
print "Inversion at origin:%s" % ('no', 'yes')[g.is_origin_centric()]

# Let's triple the cell
from cctbx import sgtbx
g.expand_ltr(sgtbx.tr_vec((1,0,1),3).new_denominator(g.t_den()))
g.expand_ltr(sgtbx.tr_vec((2,0,2),3).new_denominator(g.t_den()))
tripled_info = sgtbx.space_group_info(group=g)
tripled_info.show_summary()
print tripled_info.type().hall_symbol()

# Let's change the space group of the structure now
xs.as_cif_simple(open('03srv209x3.cif', 'w'))

Example #34
0
def exercise_space_group_info():
    i = sgtbx.space_group_info("P 1")
    assert i.type().number() == 1
    i = sgtbx.space_group_info("P -1")
    assert i.type().number() == 2
    i = sgtbx.space_group_info("P 2", "I", space_group_t_den=24)
    assert str(i) == "P 1 1 2"
    assert i.group().t_den() == 24
    i = sgtbx.space_group_info("P32 (a,b,3c)", space_group_t_den=36)
    assert str(i) == "P 32 (a,b,3*c)"
    assert i.group().t_den() == 36
    i = sgtbx.space_group_info("P 2", "I")
    assert str(i) == "P 1 1 2"
    i = sgtbx.space_group_info("P 2", "a")
    assert str(i) == "P 1 2 1"
    assert i.group() == i.type().group()
    assert i.reciprocal_space_asu().reference_as_string() \
        == "k>=0 and (l>0 or (l==0 and h>=0))"
    assert str(i.brick()) == "0<=x<=1/2; 0<=y<1; 0<=z<1"
    assert i.wyckoff_table().space_group_type().group() == i.type().group()
    assert len(i.structure_seminvariants().vectors_and_moduli()) == 3
    assert i.number_of_continuous_allowed_origin_shifts() == 1
    for sg_number in (1, 3, 15, 75, 143, 195):
        assert approx_equal(
            sgtbx.space_group_info(sg_number).any_compatible_unit_cell(
                100).volume(), 100)
    s = pickle.dumps(i)
    j = pickle.loads(s)
    assert str(i) == str(j)
    i = sgtbx.space_group_info("B 2", "i")
    assert not i.is_reference_setting()
    assert str(i.change_of_basis_op_to_reference_setting().c()) == "-x,z,y"
    assert str(i.reference_setting()) == "C 1 2 1"
    assert str(i.as_reference_setting()) == "C 1 2 1"
    assert str(i.primitive_setting()) == "C 1 2 1 (-x+y,z,x+y)"
    asu = i.direct_space_asu()
    assert len(asu.cuts) == 6
    assert sgtbx.space_group(asu.hall_symbol) == i.group()
    j = i.primitive_setting()
    asu = j.direct_space_asu()
    assert len(asu.cuts) == 6
    assert sgtbx.space_group(asu.hall_symbol) == j.group()
    i = sgtbx.space_group_info(number=19)
    assert [
        str(sgtbx.space_group_info(group=group))
        for group in i.reflection_intensity_equivalent_groups()
    ] == [
        "P 2 2 2", "P 2 2 21", "P 21 2 2", "P 2 21 2", "P 21 21 2",
        "P 2 21 21", "P 21 2 21", "P 21 21 21"
    ]
    assert len(i.reflection_intensity_equivalent_groups(anomalous_flag=False)) \
        == 127
    #
    i = sgtbx.space_group_info(symbol="C 1 2 1")
    assert str(i.change_of_basis_op_to_reference_setting().c()) == "x,y,z"
    assert approx_equal(
        i.subtract_continuous_allowed_origin_shifts(
            translation_frac=[1, 2, 3]), [1, 0, 3])
    i = sgtbx.space_group_info(symbol="B 2 1 1")
    assert str(i.change_of_basis_op_to_reference_setting().c()) == "z,x,y"
    assert approx_equal(
        i.subtract_continuous_allowed_origin_shifts(
            translation_frac=[1, 2, 3]), [0, 2, 3])
    #
    for space_group_symbol, addl_smx, uhm in [
        ("P 21 21 21", "x+1/2,y+1/2,z", "C 2 2 21 (a-1/4,b,c)"),
        ("C 1 2 1", "x,y+1/2,z", "P 1 2 1 (2*a,2*b,c)")
    ]:
        for f in range(1, 12 + 1):
            sg_t_den = sgtbx.sg_t_den * f
            cb_r_den = sgtbx.cb_r_den * f
            cb_t_den = sgtbx.cb_t_den * f
            #
            sg_i = sgtbx.space_group_info(symbol=space_group_symbol)
            t = sg_i.type()
            assert sg_i.type(tidy_cb_op=True) is t
            assert sg_i.type(tidy_cb_op=False) is not t
            if (f != 1):
                t = sg_i.type()
                c = t.cb_op().c()
                assert c.r().den() == sgtbx.cb_r_den
                assert c.t().den() == sgtbx.cb_t_den
                for t_den in [cb_t_den, None]:
                    if (t_den is not None):
                        tt = sg_i.type(t_den=t_den)
                        assert tt is not t
                    else:
                        assert sg_i.type(t_den=t_den) is tt
                    c = tt.cb_op().c()
                    assert c.r().den() == sgtbx.cb_r_den
                    assert c.t().den() == cb_t_den
                for r_den in [cb_r_den, None]:
                    if (r_den is not None):
                        tr = sg_i.type(r_den=r_den)
                        assert tr is not tt
                    else:
                        sg_i.type(r_den=r_den) is tr
                    c = tr.cb_op().c()
                    assert c.r().den() == cb_r_den
                    assert c.t().den() == cb_t_den
            #
            sg_i = sgtbx.space_group_info(symbol=space_group_symbol,
                                          space_group_t_den=sg_t_den)
            sgx = sgtbx.space_group(sg_i.group())
            rt_mx = sgtbx.rt_mx(addl_smx)
            rt_mx = rt_mx.new_denominators(sgx.r_den(), sgx.t_den())
            sgx.expand_smx(rt_mx)
            sgx_i = sgx.info()
            assert str(sgx_i) == uhm
            t = sgx_i.type()
            c = t.cb_op().c()
            assert c.r().den() == cb_r_den
            assert c.t().den() == cb_t_den
            for r_den, t_den in [(None, None), (cb_r_den, None),
                                 (None, cb_t_den), (cb_r_den, cb_t_den)]:
                assert sgx_i.type(r_den=r_den, t_den=t_den) is t
            assert sgx_i.type(tidy_cb_op=False, r_den=r_den,
                              t_den=t_den) is not t
            for i, op in enumerate(sgx_i.group()):
                assert sgx_i.cif_symmetry_code(op) == "%i" % (i + 1)
                assert sgx_i.cif_symmetry_code(op, full_code=True,
                                               sep=" ") == "%i 555" % (i + 1)
                tr = [random.randint(-4, 4) for j in range(3)]
                rt_mx = sgtbx.rt_mx(
                    op.r(),
                    op.t().plus(
                        sgtbx.tr_vec(tr,
                                     tr_den=1).new_denominator(op.t().den())))
                assert sgx_i.cif_symmetry_code(rt_mx, full_code=True) \
                       == "%i_%i%i%i" %(i+1, 5+tr[0], 5+tr[1], 5+tr[2])
Example #35
0
def rt_plus_unit_shifts(rt, unit_shifts):
    return sgtbx.rt_mx(rt.r(), rt.t().plus(sgtbx.tr_vec(unit_shifts, 1)))
Example #36
0
def exercise_unmerged(space_group_info):
    import random
    from cctbx import sgtbx
    # shuffle the
    space_group = sgtbx.space_group('P 1', no_expand=True)
    perm = list(range(len(space_group_info.group())))
    random.shuffle(perm)
    for i in perm:
        space_group.expand_smx(space_group_info.group()[i])
    unit_cell = space_group_info.any_compatible_unit_cell(volume=1000)
    for cb_op in (None,
                  space_group.info().change_of_basis_op_to_primitive_setting(),
                  unit_cell.change_of_basis_op_to_niggli_cell()):
        miller_set = crystal.symmetry(
            unit_cell=unit_cell,
            space_group=space_group).build_miller_set(d_min=1,
                                                      anomalous_flag=True)
        miller_set = miller_set.expand_to_p1().customized_copy(
            space_group_info=miller_set.space_group_info())
        if cb_op is not None:
            miller_set = miller_set.change_basis(cb_op)

        m = mtz.object()
        m.set_title('This is a title')
        m.set_space_group_info(miller_set.space_group_info())
        x = m.add_crystal('XTAL', 'CCTBX', miller_set.unit_cell().parameters())
        d = x.add_dataset('TEST', 1)

        indices = miller_set.indices()
        original_indices = indices.deep_copy()

        # map the miller indices to one hemisphere (i.e. just I+)
        miller.map_to_asu(m.space_group().type(), False, indices)

        h, k, l = [i.iround() for i in indices.as_vec3_double().parts()]
        m.adjust_column_array_sizes(len(h))
        m.set_n_reflections(len(h))

        # assign H, K, L
        d.add_column('H', 'H').set_values(h.as_double().as_float())
        d.add_column('K', 'H').set_values(k.as_double().as_float())
        d.add_column('L', 'H').set_values(l.as_double().as_float())

        d.add_column('M_ISYM', 'Y').set_values(flex.float(len(indices)))

        m.replace_original_index_miller_indices(original_indices)

        assert (m.extract_original_index_miller_indices() == original_indices
                ).count(False) == 0
        # check the indices in the mtz file are actually in the asu
        extracted_indices = m.extract_miller_indices()
        miller.map_to_asu(m.space_group().type(), False, extracted_indices)
        assert (
            extracted_indices == m.extract_miller_indices()).count(False) == 0

        # test change_basis_in_place if appropriate for current space group
        import cctbx.sgtbx.cosets

        cb_op_to_niggli_cell \
          = miller_set.change_of_basis_op_to_niggli_cell()

        minimum_cell_symmetry = crystal.symmetry.change_basis(
            miller_set.crystal_symmetry(), cb_op=cb_op_to_niggli_cell)

        lattice_group = sgtbx.lattice_symmetry.group(
            minimum_cell_symmetry.unit_cell(), max_delta=3.0)
        lattice_group.expand_inv(sgtbx.tr_vec((0, 0, 0)))
        lattice_group.make_tidy()

        cosets = sgtbx.cosets.left_decomposition_point_groups_only(
            g=lattice_group,
            h=minimum_cell_symmetry.reflection_intensity_symmetry(
                anomalous_flag=True).space_group(
                ).build_derived_acentric_group().make_tidy())

        possible_twin_laws = cosets.best_partition_representatives(
            cb_op=cb_op_to_niggli_cell.inverse(),
            omit_first_partition=True,
            omit_negative_determinants=True)

        for twin_law in possible_twin_laws:
            cb_op = sgtbx.change_of_basis_op(twin_law.as_xyz())
            #print cb_op.as_hkl()
            # forward direction
            m.change_basis_in_place(cb_op)
            assert (m.extract_original_index_miller_indices() == cb_op.apply(
                original_indices)).count(False) == 0
            ## check the indices in the mtz file are actually in the asu
            #extracted_indices = m.extract_miller_indices()
            #miller.map_to_asu(m.space_group().type(), False, extracted_indices)
            #assert (extracted_indices == m.extract_miller_indices()).count(False) == 0
            # and back again
            m.change_basis_in_place(cb_op.inverse())
            assert (m.extract_original_index_miller_indices() ==
                    original_indices).count(False) == 0
Example #37
0
    def derive_result_group_list(self, group_of_interest):

        # Get list of sub-spacegroups
        subgrs = subgroups.subgroups(group_of_interest).groups_parent_setting()

        # Order sub-groups
        sort_values = flex.double()
        for group in subgrs:
            order_z = group.order_z()
            space_group_number = sgtbx.space_group_type(group, False).number()
            assert 1 <= space_group_number <= 230
            sort_values.append(order_z * 1000 + space_group_number)
        perm = flex.sort_permutation(sort_values, True)

        for i_subgr in perm:
            acentric_subgroup = subgrs[i_subgr]
            acentric_supergroup = metric_supergroup(acentric_subgroup)
            # Add centre of inversion to acentric lattice symmetry
            centric_group = sgtbx.space_group(acentric_subgroup)
            centric_group.expand_inv(sgtbx.tr_vec((0, 0, 0)))
            # Make symmetry object: unit-cell + space-group
            # The unit cell is potentially modified to be exactly compatible
            # with the space group symmetry.
            subsym = crystal.symmetry(
                unit_cell=self.minimum_symmetry.unit_cell(),
                space_group=centric_group,
                assert_is_compatible_unit_cell=False)
            supersym = crystal.symmetry(
                unit_cell=self.minimum_symmetry.unit_cell(),
                space_group=acentric_supergroup,
                assert_is_compatible_unit_cell=False)
            # Convert subgroup to reference setting
            cb_op_minimum_ref = subsym.space_group_info().type().cb_op()
            ref_subsym = subsym.change_basis(cb_op_minimum_ref)
            # Ignore unwanted groups
            if (self.bravais_types_only and not str(
                    ref_subsym.space_group_info()) in bravais_types.centric):
                continue
            # Choose best setting for monoclinic and orthorhombic systems
            cb_op_best_cell = self.change_of_basis_op_to_best_cell(ref_subsym)
            best_subsym = ref_subsym.change_basis(cb_op_best_cell)
            # Total basis transformation
            cb_op_best_cell = change_of_basis_op(str(cb_op_best_cell),
                                                 stop_chars='',
                                                 r_den=144,
                                                 t_den=144)
            cb_op_minimum_ref = change_of_basis_op(str(cb_op_minimum_ref),
                                                   stop_chars='',
                                                   r_den=144,
                                                   t_den=144)
            self.cb_op_inp_minimum = change_of_basis_op(str(
                self.cb_op_inp_minimum),
                                                        stop_chars='',
                                                        r_den=144,
                                                        t_den=144)
            cb_op_inp_best = cb_op_best_cell * cb_op_minimum_ref * self.cb_op_inp_minimum
            # Use identity change-of-basis operator if possible
            if (best_subsym.unit_cell().is_similar_to(
                    self.input_symmetry.unit_cell())):
                cb_op_corr = cb_op_inp_best.inverse()
                try:
                    best_subsym_corr = best_subsym.change_basis(cb_op_corr)
                except RuntimeError, e:
                    if (str(e).find(
                            "Unsuitable value for rational rotation matrix.") <
                            0):
                        raise
                else:
                    if (best_subsym_corr.space_group() ==
                            best_subsym.space_group()):
                        cb_op_inp_best = cb_op_corr * cb_op_inp_best
            self.result_groups.append({
                'subsym':
                subsym,
                'supersym':
                supersym,
                'ref_subsym':
                ref_subsym,
                'best_subsym':
                best_subsym,
                'cb_op_inp_best':
                cb_op_inp_best,
                'max_angular_difference':
                find_max_delta(reduced_cell=self.minimum_symmetry.unit_cell(),
                               space_group=acentric_supergroup)
            })
Example #38
0
def exercise(space_group_info,
             anomalous_flag,
             use_u_aniso,
             n_elements=3,
             d_min=3.,
             verbose=0):
    structure_z = random_structure.xray_structure(
        space_group_info,
        elements=("Se", ) * n_elements,
        volume_per_atom=200,
        random_f_prime_d_min=1.0,
        random_f_double_prime=anomalous_flag,
        random_u_iso=True,
        use_u_aniso=use_u_aniso,
        random_occupancy=True)
    check_weight_without_occupancy(structure_z)
    f_z = structure_z.structure_factors(anomalous_flag=anomalous_flag,
                                        d_min=d_min,
                                        algorithm="direct").f_calc()
    f_abs_z = abs(f_z)
    f_rad_z = f_z.phases()
    f_deg_z = f_z.phases(deg=True)
    hl_z = generate_random_hl(miller_set=f_z)
    hl_z_rad = hl_z.phase_integrals()
    if (0 or verbose):
        structure_z.show_summary().show_scatterers()
        print("n_special_positions:", \
              structure_z.special_position_indices().size())
    z2p_op = structure_z.space_group().z2p_op()
    z2p_op = sgtbx.change_of_basis_op(z2p_op.c() + sgtbx.tr_vec(
        (2, -1, 3), 12).new_denominator(z2p_op.c().t().den()))
    for change_hand in [False, True]:
        if (change_hand):
            z2p_op = z2p_op * sgtbx.change_of_basis_op("-x,-y,-z")
        structure_p = structure_z.change_basis(z2p_op)
        check_weight_without_occupancy(structure_p)
        check_site_symmetry_table(structure_z, z2p_op, structure_p)
        if (0 or verbose):
            structure_p.show_summary().show_scatterers()
            print("n_special_positions:", \
                  structure_p.special_position_indices().size())
        assert tuple(structure_p.special_position_indices()) \
            == tuple(structure_z.special_position_indices())
        structure_pz = structure_p.change_basis(z2p_op.inverse())
        check_weight_without_occupancy(structure_pz)
        check_site_symmetry_table(structure_p, z2p_op.inverse(), structure_pz)
        assert structure_pz.unit_cell().is_similar_to(structure_z.unit_cell())
        assert structure_pz.space_group() == structure_z.space_group()
        f_pz = f_z.structure_factors_from_scatterers(
            xray_structure=structure_pz, algorithm="direct").f_calc()
        f_abs_pz = abs(f_pz)
        f_rad_pz = f_pz.phases()
        f_deg_pz = f_pz.phases(deg=True)
        c = flex.linear_correlation(f_abs_z.data(), f_abs_pz.data())
        assert c.is_well_defined()
        if (0 or verbose):
            print("correlation:", c.coefficient())
        assert c.coefficient() > 0.999
        f_p_cb = f_z.change_basis(z2p_op)
        f_abs_p_cb = f_abs_z.change_basis(z2p_op)
        f_rad_p_cb = f_rad_z.change_basis(z2p_op, deg=False)
        f_deg_p_cb = f_deg_z.change_basis(z2p_op, deg=True)
        hl_p_cb = hl_z.change_basis(z2p_op)
        hl_p_cb_rad = hl_p_cb.phase_integrals()
        assert approx_equal(
            hl_z_rad.change_basis(z2p_op).data(), hl_p_cb_rad.data())
        assert f_abs_p_cb.indices().all_eq(f_p_cb.indices())
        if (not change_hand):
            o = flex.order(f_abs_p_cb.indices(), f_abs_z.indices())
        else:
            o = flex.order(-f_abs_p_cb.indices(), f_abs_z.indices())
        if (f_abs_z.space_group().n_ltr() == 1):
            assert o == 0
        else:
            assert o != 0
        f_pz = f_p_cb.change_basis(z2p_op.inverse())
        f_abs_pz = f_abs_p_cb.change_basis(z2p_op.inverse())
        f_rad_pz = f_rad_p_cb.change_basis(z2p_op.inverse(), deg=False)
        f_deg_pz = f_deg_p_cb.change_basis(z2p_op.inverse(), deg=True)
        hl_pz = hl_p_cb.change_basis(z2p_op.inverse())
        hl_pz_rad = hl_pz.phase_integrals()
        assert approx_equal(hl_z_rad.data(), hl_pz_rad.data())
        for i, o in zip(hl_z.data(), hl_pz.data()):
            assert approx_equal(i, o)
        assert approx_equal(flex.max(flex.abs(f_pz.data() - f_z.data())), 0)
        assert flex.order(f_abs_pz.indices(), f_abs_z.indices()) == 0
        assert f_abs_pz.indices().all_eq(f_pz.indices())
        assert approx_equal(
            flex.max(
                scitbx.math.phase_error(phi1=f_rad_pz.data(),
                                        phi2=f_rad_z.data())), 0)
        assert approx_equal(
            flex.max(
                scitbx.math.phase_error(phi1=f_deg_pz.data(),
                                        phi2=f_deg_z.data(),
                                        deg=True)), 0)
        assert approx_equal(f_deg_pz.data(), f_rad_pz.data() * (180 / math.pi))
        f_p_sf = f_p_cb.structure_factors_from_scatterers(
            xray_structure=structure_p, algorithm="direct").f_calc()
        det = abs(z2p_op.c().r().determinant())
        assert approx_equal(
            flex.max(flex.abs(f_p_sf.data() * complex(det) - f_p_cb.data())),
            0)
        f_abs_p_sf = abs(f_p_sf)
        f_rad_p_sf = f_p_sf.phases()
        f_deg_p_sf = f_p_sf.phases(deg=True)
        assert approx_equal(
            flex.max(
                scitbx.math.phase_error(phi1=f_rad_p_sf.data(),
                                        phi2=f_rad_p_cb.data())), 0)
        assert approx_equal(
            flex.max(
                scitbx.math.phase_error(phi1=f_deg_p_sf.data(),
                                        phi2=f_deg_p_cb.data(),
                                        deg=True)), 0)
        c = flex.linear_correlation(f_abs_p_sf.data(), f_abs_p_cb.data())
        assert c.is_well_defined()
        if (0 or verbose):
            print("correlation:", c.coefficient())
        assert c.coefficient() > 0.999
def exercise(
      space_group_info,
      anomalous_flag,
      use_u_aniso,
      n_elements=3,
      d_min=3.,
      verbose=0):
  structure_z = random_structure.xray_structure(
    space_group_info,
    elements=("Se",)*n_elements,
    volume_per_atom=200,
    random_f_prime_d_min=1.0,
    random_f_double_prime=anomalous_flag,
    random_u_iso=True,
    use_u_aniso=use_u_aniso,
    random_occupancy=True)
  check_weight_without_occupancy(structure_z)
  f_z = structure_z.structure_factors(
    anomalous_flag=anomalous_flag, d_min=d_min, algorithm="direct").f_calc()
  f_abs_z = abs(f_z)
  f_rad_z = f_z.phases()
  f_deg_z = f_z.phases(deg=True)
  hl_z = generate_random_hl(miller_set=f_z)
  hl_z_rad = hl_z.phase_integrals()
  if (0 or verbose):
    structure_z.show_summary().show_scatterers()
    print "n_special_positions:", \
          structure_z.special_position_indices().size()
  z2p_op = structure_z.space_group().z2p_op()
  z2p_op = sgtbx.change_of_basis_op(
      z2p_op.c()
    + sgtbx.tr_vec((2,-1,3), 12).new_denominator(z2p_op.c().t().den()))
  for change_hand in [False, True]:
    if (change_hand):
      z2p_op = z2p_op * sgtbx.change_of_basis_op("-x,-y,-z")
    structure_p = structure_z.change_basis(z2p_op)
    check_weight_without_occupancy(structure_p)
    check_site_symmetry_table(structure_z, z2p_op, structure_p)
    if (0 or verbose):
      structure_p.show_summary().show_scatterers()
      print "n_special_positions:", \
            structure_p.special_position_indices().size()
    assert tuple(structure_p.special_position_indices()) \
        == tuple(structure_z.special_position_indices())
    structure_pz = structure_p.change_basis(z2p_op.inverse())
    check_weight_without_occupancy(structure_pz)
    check_site_symmetry_table(structure_p, z2p_op.inverse(), structure_pz)
    assert structure_pz.unit_cell().is_similar_to(structure_z.unit_cell())
    assert structure_pz.space_group() == structure_z.space_group()
    f_pz = f_z.structure_factors_from_scatterers(
      xray_structure=structure_pz,
      algorithm="direct").f_calc()
    f_abs_pz = abs(f_pz)
    f_rad_pz = f_pz.phases()
    f_deg_pz = f_pz.phases(deg=True)
    c = flex.linear_correlation(f_abs_z.data(), f_abs_pz.data())
    assert c.is_well_defined()
    if (0 or verbose):
      print "correlation:", c.coefficient()
    assert c.coefficient() > 0.999
    f_p_cb = f_z.change_basis(z2p_op)
    f_abs_p_cb = f_abs_z.change_basis(z2p_op)
    f_rad_p_cb = f_rad_z.change_basis(z2p_op, deg=False)
    f_deg_p_cb = f_deg_z.change_basis(z2p_op, deg=True)
    hl_p_cb = hl_z.change_basis(z2p_op)
    hl_p_cb_rad = hl_p_cb.phase_integrals()
    assert approx_equal(
      hl_z_rad.change_basis(z2p_op).data(), hl_p_cb_rad.data())
    assert f_abs_p_cb.indices().all_eq(f_p_cb.indices())
    if (not change_hand):
      o = flex.order(f_abs_p_cb.indices(), f_abs_z.indices())
    else:
      o = flex.order(-f_abs_p_cb.indices(), f_abs_z.indices())
    if (f_abs_z.space_group().n_ltr() == 1):
      assert o == 0
    else:
      assert o != 0
    f_pz = f_p_cb.change_basis(z2p_op.inverse())
    f_abs_pz = f_abs_p_cb.change_basis(z2p_op.inverse())
    f_rad_pz = f_rad_p_cb.change_basis(z2p_op.inverse(), deg=False)
    f_deg_pz = f_deg_p_cb.change_basis(z2p_op.inverse(), deg=True)
    hl_pz = hl_p_cb.change_basis(z2p_op.inverse())
    hl_pz_rad = hl_pz.phase_integrals()
    assert approx_equal(hl_z_rad.data(), hl_pz_rad.data())
    for i,o in zip(hl_z.data(), hl_pz.data()):
      assert approx_equal(i, o)
    assert approx_equal(
      flex.max(flex.abs(f_pz.data() - f_z.data())), 0)
    assert flex.order(f_abs_pz.indices(), f_abs_z.indices()) == 0
    assert f_abs_pz.indices().all_eq(f_pz.indices())
    assert approx_equal(flex.max(scitbx.math.phase_error(
      phi1=f_rad_pz.data(), phi2=f_rad_z.data())), 0)
    assert approx_equal(flex.max(scitbx.math.phase_error(
      phi1=f_deg_pz.data(), phi2=f_deg_z.data(), deg=True)), 0)
    assert approx_equal(f_deg_pz.data(), f_rad_pz.data()*(180/math.pi))
    f_p_sf = f_p_cb.structure_factors_from_scatterers(
      xray_structure=structure_p,
      algorithm="direct").f_calc()
    det = abs(z2p_op.c().r().determinant())
    assert approx_equal(
      flex.max(flex.abs(f_p_sf.data()*complex(det) - f_p_cb.data())), 0)
    f_abs_p_sf = abs(f_p_sf)
    f_rad_p_sf = f_p_sf.phases()
    f_deg_p_sf = f_p_sf.phases(deg=True)
    assert approx_equal(flex.max(scitbx.math.phase_error(
      phi1=f_rad_p_sf.data(), phi2=f_rad_p_cb.data())), 0)
    assert approx_equal(flex.max(scitbx.math.phase_error(
      phi1=f_deg_p_sf.data(), phi2=f_deg_p_cb.data(), deg=True)), 0)
    c = flex.linear_correlation(f_abs_p_sf.data(), f_abs_p_cb.data())
    assert c.is_well_defined()
    if (0 or verbose):
      print "correlation:", c.coefficient()
    assert c.coefficient() > 0.999
Example #40
0
def exercise(space_group_info,
             fixed_random_seed=True,
             shifted_origin=None,
             elements=None,
             d_min=0.8,
             grid_resolution_factor=1/3.,
             verbose=False,
             **kwds):
  if elements is None:
    n_C = 5
    n_O = 1
    n_N = 1
    elements = ["C"]*n_C + ["O"]*n_O + ["N"]*n_N
  if verbose:
    print(elements)

  target_space_group_type = space_group_info.type()
  hall = sgtbx.space_group_symbols(
    target_space_group_type.lookup_symbol()).hall()
  print(hall)

  if fixed_random_seed:
    random.seed(1)
    flex.set_random_seed(1)

  # Generate a random structure in real space,
  # compute its structure factors,
  # that we will try to recover the symmetry of
  target_structure = random_structure.xray_structure(
    space_group_info=space_group_info,
    elements=elements,
    use_u_iso=True,
    random_u_iso=True,
    random_u_iso_scale=0.04,
    use_u_aniso=False,
  )
  if shifted_origin is None:
    shifted_origin = flex.random_double(3)
  shifted_origin = mat.col(shifted_origin)
  if verbose:
    print("new origin = (%.3f, %.3f, %.3f)" % shifted_origin.elems)
    print()
  target_structure_in_p1 = target_structure\
                         .expand_to_p1().apply_shift(shifted_origin)
  target_f_in_p1 = miller.build_set(
    crystal_symmetry=target_structure_in_p1,
    anomalous_flag=False,
    d_min=d_min
    ).structure_factors_from_scatterers(
      xray_structure=target_structure_in_p1,
      algorithm="direct").f_calc()

  # Recover space group?
  sf_symm = symmetry_search.structure_factor_symmetry(target_f_in_p1)
  if verbose:
    print(sf_symm)

  solution_hall, target_hall = [
    sgi.as_reference_setting().type().hall_symbol()
    for sgi in (sf_symm.space_group_info,
                target_structure.space_group_info()) ]
  assert solution_hall == target_hall, (solution_hall, target_hall)

  # Shift maximises goodness of symmetry?
  gos, solution_f = sf_symm.symmetrised_structure_factors()
  if space_group_info.type().hall_symbol() != ' P 1':
    assert gos.correlation > 0.99
    assert gos.gradient == (0, 0, 0)
    gos_away_from_max = sf_symm.symmetrised_structure_factors(
      delta=mat.col((0.1, 0.1, 0.1)))[0]
    assert gos_away_from_max.correlation < 0.9, gos_away_from_max.correlation

  # Recovered origin
  """The sequence of transform read:
  ----->target structure
  ^           V
  ^           V  (1, shifted_origin=sigma)
  ^           V
  ^      shifted target
  ^           V
  ^           V sf_symm.cb_op_to_primitive = (P, 0)
  ^           V
  ^      shifted target in primitive cell = shifted solution in primitive cell
  ^           V
  ^           V (1, -sf_symm.origin=-s)
  ^           V
  ^      solution in primitive cell
  ^           V
  ^           V solution_to_target_cb_op = (Q, q)
  ^           V
  ^------------

  The total transfrom from the target structure back to it reads
  (QP, q') with q' = (Q,q)(-s + P sigma) = (Q,q)delta_o
  with
  delta_o = sf_symm.cb_op_to_primitive(shifted_origin) - sf_symm.origin

  (Q, q') must leave the target structure space group invariant.
  Most of the time Q is the unit matrix and the test boils down to check
  whether delta is an allowed origin shift after changing to the input cell
  but it does not hurt to do the more general test all the time.
  """

  solution_to_target_cb_op = (
    target_structure.space_group_info()
    .change_of_basis_op_to_reference_setting().inverse()
    *
    sf_symm.space_group_info
    .change_of_basis_op_to_reference_setting())

  if verbose:
    print()
    print("solution -> target: %s" % solution_to_target_cb_op.as_xyz())
  delta_o = (mat.col(sf_symm.cb_op_to_primitive(shifted_origin))
             - sf_symm.origin)
  delta = mat.col(solution_to_target_cb_op(delta_o))
  stabilising_cb_op = sgtbx.change_of_basis_op(sgtbx.rt_mx(
    (solution_to_target_cb_op*sf_symm.cb_op_to_primitive).c().r(),
    sgtbx.tr_vec((delta*72).as_int()*2, tr_den=144)))
    # guarding against rounding errors on some platforms (e.g. FC8)
    # meaning that (delta*144).as_int() would not work.
  target_sg = target_structure.space_group()
  assert target_sg == target_sg.change_basis(stabilising_cb_op)
def exercise_space_group_info():
  i = sgtbx.space_group_info("P 1")
  assert i.type().number() == 1
  i = sgtbx.space_group_info("P -1")
  assert i.type().number() == 2
  i = sgtbx.space_group_info("P 2", "I", space_group_t_den=24)
  assert str(i) == "P 1 1 2"
  assert i.group().t_den() == 24
  i = sgtbx.space_group_info("P32 (a,b,3c)", space_group_t_den=36)
  assert str(i) == "P 32 (a,b,3*c)"
  assert i.group().t_den() == 36
  i = sgtbx.space_group_info("P 2", "I")
  assert str(i) == "P 1 1 2"
  i = sgtbx.space_group_info("P 2", "a")
  assert str(i) == "P 1 2 1"
  assert i.group() == i.type().group()
  assert i.reciprocal_space_asu().reference_as_string() \
      == "k>=0 and (l>0 or (l==0 and h>=0))"
  assert str(i.brick()) == "0<=x<=1/2; 0<=y<1; 0<=z<1"
  assert i.wyckoff_table().space_group_type().group() == i.type().group()
  assert len(i.structure_seminvariants().vectors_and_moduli()) == 3
  assert i.number_of_continuous_allowed_origin_shifts() == 1
  for sg_number in (1,3,15,75,143,195):
    assert approx_equal(
      sgtbx.space_group_info(sg_number).any_compatible_unit_cell(100).volume(),
      100)
  s = pickle.dumps(i)
  j = pickle.loads(s)
  assert str(i) == str(j)
  i = sgtbx.space_group_info("B 2", "i")
  assert not i.is_reference_setting()
  assert str(i.change_of_basis_op_to_reference_setting().c()) == "-x,z,y"
  assert str(i.reference_setting()) == "C 1 2 1"
  assert str(i.as_reference_setting()) == "C 1 2 1"
  assert str(i.primitive_setting()) == "C 1 2 1 (-x+y,z,x+y)"
  asu = i.direct_space_asu()
  assert len(asu.cuts) == 6
  assert sgtbx.space_group(asu.hall_symbol) == i.group()
  j = i.primitive_setting()
  asu = j.direct_space_asu()
  assert len(asu.cuts) == 6
  assert sgtbx.space_group(asu.hall_symbol) == j.group()
  i = sgtbx.space_group_info(number=19)
  assert [str(sgtbx.space_group_info(group=group))
    for group in i.reflection_intensity_equivalent_groups()] == [
      "P 2 2 2",
      "P 2 2 21",
      "P 21 2 2",
      "P 2 21 2",
      "P 21 21 2",
      "P 2 21 21",
      "P 21 2 21",
      "P 21 21 21"]
  assert len(i.reflection_intensity_equivalent_groups(anomalous_flag=False)) \
      == 127
  #
  i = sgtbx.space_group_info(symbol="C 1 2 1")
  assert str(i.change_of_basis_op_to_reference_setting().c()) == "x,y,z"
  assert approx_equal(
    i.subtract_continuous_allowed_origin_shifts(translation_frac=[1,2,3]),
    [1,0,3])
  i = sgtbx.space_group_info(symbol="B 2 1 1")
  assert str(i.change_of_basis_op_to_reference_setting().c()) == "z,x,y"
  assert approx_equal(
    i.subtract_continuous_allowed_origin_shifts(translation_frac=[1,2,3]),
    [0,2,3])
  #
  for space_group_symbol, addl_smx, uhm in [
        ("P 21 21 21", "x+1/2,y+1/2,z", "C 2 2 21 (a-1/4,b,c)"),
        ("C 1 2 1", "x,y+1/2,z", "P 1 2 1 (2*a,2*b,c)")]:
    for f in xrange(1,12+1):
      sg_t_den = sgtbx.sg_t_den * f
      cb_r_den = sgtbx.cb_r_den * f
      cb_t_den = sgtbx.cb_t_den * f
      #
      sg_i = sgtbx.space_group_info(symbol=space_group_symbol)
      t = sg_i.type()
      assert sg_i.type(tidy_cb_op=True) is t
      assert sg_i.type(tidy_cb_op=False) is not t
      if (f != 1):
        t = sg_i.type()
        c = t.cb_op().c()
        assert c.r().den() == sgtbx.cb_r_den
        assert c.t().den() == sgtbx.cb_t_den
        for t_den in [cb_t_den, None]:
          if (t_den is not None):
            tt = sg_i.type(t_den=t_den)
            assert tt is not t
          else:
            assert sg_i.type(t_den=t_den) is tt
          c = tt.cb_op().c()
          assert c.r().den() == sgtbx.cb_r_den
          assert c.t().den() == cb_t_den
        for r_den in [cb_r_den, None]:
          if (r_den is not None):
            tr = sg_i.type(r_den=r_den)
            assert tr is not tt
          else:
            sg_i.type(r_den=r_den) is tr
          c = tr.cb_op().c()
          assert c.r().den() == cb_r_den
          assert c.t().den() == cb_t_den
      #
      sg_i = sgtbx.space_group_info(
        symbol=space_group_symbol,
        space_group_t_den=sg_t_den)
      sgx = sgtbx.space_group(sg_i.group())
      rt_mx = sgtbx.rt_mx(addl_smx)
      rt_mx = rt_mx.new_denominators(sgx.r_den(), sgx.t_den())
      sgx.expand_smx(rt_mx)
      sgx_i = sgx.info()
      assert str(sgx_i) == uhm
      t = sgx_i.type()
      c = t.cb_op().c()
      assert c.r().den() == cb_r_den
      assert c.t().den() == cb_t_den
      for r_den,t_den in [(None, None),
                          (cb_r_den, None),
                          (None, cb_t_den),
                          (cb_r_den, cb_t_den)]:
        assert sgx_i.type(r_den=r_den, t_den=t_den) is t
      assert sgx_i.type(tidy_cb_op=False, r_den=r_den, t_den=t_den) is not t
      for i, op in enumerate(sgx_i.group()):
        assert sgx_i.cif_symmetry_code(op) == "%i" %(i+1)
        assert sgx_i.cif_symmetry_code(
          op, full_code=True, sep=" ") == "%i 555" %(i+1)
        tr = [random.randint(-4, 4) for j in range(3)]
        rt_mx = sgtbx.rt_mx(op.r(), op.t().plus(
          sgtbx.tr_vec(tr, tr_den=1).new_denominator(op.t().den())))
        assert sgx_i.cif_symmetry_code(rt_mx, full_code=True) \
               == "%i_%i%i%i" %(i+1, 5+tr[0], 5+tr[1], 5+tr[2])