Beispiel #1
0
 def __str__(self):
   result = []
   for elt, n in self.element_count_pairs:
     r = continued_fraction.from_real(n, eps=1e-5).as_rational()
     if r.denominator() == 1:
       if r.numerator() > 1: m = "%i" % r.numerator()
       else: m = ""
     elif r.denominator() < 10: m = "%i/%i" % (r.numerator(), r.denominator())
     else: m = "%.5f" % n
     result.append("%s%s" % (elt, m))
   return ' '.join(result)
Beispiel #2
0
def derive_change_of_basis_op(from_hkl, to_hkl):

    # exclude those reflections that we couldn't index
    sel = (to_hkl != (0, 0, 0)) & (from_hkl != (0, 0, 0))
    assert sel.count(True) >= 3  # need minimum of 3 equations ?
    to_hkl = to_hkl.select(sel)
    from_hkl = from_hkl.select(sel)

    # for each miller index, solve a system of linear equations to find the
    # change of basis operator
    h, k, l = to_hkl.as_vec3_double().parts()

    r = []
    from scitbx.lstbx import normal_eqns

    for i in range(3):
        eqns = normal_eqns.linear_ls(3)
        for index, hkl in zip((h, k, l)[i], from_hkl):
            eqns.add_equation(
                right_hand_side=index, design_matrix_row=flex.double(hkl), weight=1
            )
        eqns.solve()
        r.extend(eqns.solution())

    from scitbx import matrix
    from scitbx.math import continued_fraction

    denom = 12
    r = [
        int(denom * continued_fraction.from_real(r_, eps=1e-2).as_rational())
        for r_ in r
    ]
    r = matrix.sqr(r).transpose()
    # print (1/denom)*r

    # now convert into a cctbx change_of_basis_op object
    change_of_basis_op = sgtbx.change_of_basis_op(
        sgtbx.rt_mx(sgtbx.rot_mx(r, denominator=denom))
    ).inverse()
    print("discovered change_of_basis_op=%s" % (str(change_of_basis_op)))

    # sanity check that this is the right cb_op
    assert (change_of_basis_op.apply(from_hkl) == to_hkl).count(False) == 0

    return change_of_basis_op
Beispiel #3
0
def derive_change_of_basis_op(from_hkl, to_hkl):

  # exclude those reflections that we couldn't index
  sel = (to_hkl != (0,0,0)) & (from_hkl != (0,0,0))
  assert sel.count(True) >= 3 # need minimum of 3 equations ?
  to_hkl = to_hkl.select(sel)
  from_hkl = from_hkl.select(sel)

  # for each miller index, solve a system of linear equations to find the
  # change of basis operator
  h, k, l = to_hkl.as_vec3_double().parts()

  r = []
  from scitbx.lstbx import normal_eqns
  for i in range(3):
    eqns = normal_eqns.linear_ls(3)
    for index, hkl in zip((h,k,l)[i], from_hkl):
      eqns.add_equation(right_hand_side=index,
                        design_matrix_row=flex.double(hkl),
                        weight=1)
    eqns.solve()
    r.extend(eqns.solution())

  from scitbx.math import continued_fraction
  from scitbx import matrix
  denom = 12
  r = [int(denom * continued_fraction.from_real(r_, eps=1e-2).as_rational())
       for r_ in r]
  r = matrix.sqr(r).transpose()
  #print (1/denom)*r

  # now convert into a cctbx change_of_basis_op object
  change_of_basis_op = sgtbx.change_of_basis_op(
    sgtbx.rt_mx(sgtbx.rot_mx(r, denominator=denom))).inverse()
  print "discovered change_of_basis_op=%s" %(str(change_of_basis_op))

  # sanity check that this is the right cb_op
  assert (change_of_basis_op.apply(from_hkl) == to_hkl).count(False) == 0

  return change_of_basis_op
Beispiel #4
0
 def filtered_commands(self):
   from scitbx.math import continued_fraction
   temperature = 20
   for command, line in self.command_stream:
     cmd, args = command[0], command[-1]
     n_args = len(args)
     if cmd == 'OMIT':
       if n_args == 3 and isinstance(args[0], float):
         self.instructions.setdefault('omit_hkl', [])
         self.instructions['omit_hkl'].append([int(i) for i in args])
       elif n_args == 2 and isinstance(args[0], float):
         self.instructions['omit'] = {
           's': args[0],
           'two_theta': args[1]}
       else:
         yield command, line
     elif cmd == 'SHEL':
       if args:
         shel = {'lowres': args[0]}
         if n_args > 1:
           shel['highres'] = args[1]
     elif cmd == 'MERG':
       if args:
         self.instructions['merg'] = args[0]
     elif cmd == 'TEMP':
       if len(args) > 1:
         raise shelx_error("TEMP takes at most 1 argument")
       if args: temperature = args[0]
       self.instructions['temp'] = temperature
       self.builder.temperature_in_celsius = temperature
     elif cmd == 'WGHT':
       if n_args > 6:
         raise shelx_error("Too many argument for %s" % cmd, line)
       default_weighting_scheme = { 'a': 0.1,
                                    'b': 0,
                                    'c': 0,
                                    'd': 0,
                                    'e': 0,
                                    'f': 1/3 }
       weighting_scheme = dict([
         (key, (arg is not None and arg) or default_weighting_scheme[key])
         for key, arg in itertools.izip_longest('abcdef', args) ])
       self.instructions['wght'] = weighting_scheme
       self.builder.make_shelx_weighting_scheme(**weighting_scheme)
     elif cmd == 'HKLF':
       # only ONE HKLF instruction allowed
       assert 'hklf' not in self.instructions
       hklf = {'s': 1, 'matrix': sgtbx.rot_mx()}
       hklf['n'] = args[0]
       if n_args > 1:
         hklf['s'] = args[1]
         if n_args > 2:
           assert n_args > 10
           mx = [ continued_fraction.from_real(e, eps=1e-3).as_rational()
                  for e in args[2:11] ]
           den = reduce(rational.lcm, [ r.denominator() for r in mx ])
           nums = [ r.numerator()*(den//r.denominator()) for r in mx ]
           hklf['matrix'] = sgtbx.rot_mx(nums, den)
           if n_args > 11:
             hklf['wt'] = args[11]
             if n_args == 13:
               hklf['m'] = args[12]
       self.instructions['hklf'] = hklf
       assert not self.builder or ('wt' not in hklf and 'm' not in hklf)
       self.builder.create_shelx_reflection_data_source(
         format=hklf['n'],
         indices_transform=hklf['matrix'],
         data_scale=hklf['s'])
       if 'basf' in self.instructions and hklf['n'] == 5:
         self.builder.make_non_merohedral_twinning_with_transformed_hkl(
           fractions=self.instructions['basf'])
     elif cmd == 'TWIN':
       # only ONE twin instruction allowed
       assert 'twin' not in self.instructions
       twin = {}
       if n_args > 0:
         assert n_args >= 9
         twin['matrix'] = sgtbx.rt_mx(
           sgtbx.rot_mx([int(i) for i in args[0:9]]))
         if n_args > 9:
           twin['n'] = args[9]
       self.instructions['twin'] = twin
       if 'basf' in self.instructions: self.issue_merohedral_twinning()
     elif cmd == 'BASF':
       self.instructions['basf'] = args
       if 'twin' in self.instructions: self.issue_merohedral_twinning()
     elif cmd == 'EXTI':
       if len(args) == 1:
         self.instructions['exti'] = args[0]
     else:
       yield command, line
   else:
     # All token have been read without errors or early bailout
     assert 'hklf' in self.instructions, "Missing HKLF instruction"
Beispiel #5
0
 def filtered_commands(self):
   from scitbx.math import continued_fraction
   temperature = 20
   for command, line in self.command_stream:
     cmd, args = command[0], command[-1]
     n_args = len(args)
     if cmd == 'OMIT':
       if n_args == 3 and isinstance(args[0], float):
         self.instructions.setdefault('omit_hkl', [])
         self.instructions['omit_hkl'].append([int(i) for i in args])
       elif n_args == 2 and isinstance(args[0], float):
         self.instructions['omit'] = {
           's': args[0],
           'two_theta': args[1]}
       else:
         yield command, line
     elif cmd == 'SHEL':
       if args:
         shel = {'lowres': args[0]}
         if n_args > 1:
           shel['highres'] = args[1]
     elif cmd == 'MERG':
       if args:
         self.instructions['merg'] = args[0]
     elif cmd == 'TEMP':
       if len(args) > 1:
         raise shelx_error("TEMP takes at most 1 argument")
       if args: temperature = args[0]
       self.instructions['temp'] = temperature
       self.builder.temperature_in_celsius = temperature
     elif cmd == 'WGHT':
       if n_args > 6:
         raise shelx_error("Too many argument for %s" % cmd, line)
       default_weighting_scheme = { 'a': 0.1,
                                    'b': 0,
                                    'c': 0,
                                    'd': 0,
                                    'e': 0,
                                    'f': 1/3 }
       weighting_scheme = dict([
         (key, (arg is not None and arg) or default_weighting_scheme[key])
         for key, arg in itertools.izip_longest('abcdef', args) ])
       self.instructions['wght'] = weighting_scheme
       self.builder.make_shelx_weighting_scheme(**weighting_scheme)
     elif cmd == 'HKLF':
       # only ONE HKLF instruction allowed
       assert 'hklf' not in self.instructions
       hklf = {'s': 1, 'matrix': sgtbx.rot_mx()}
       hklf['n'] = args[0]
       if n_args > 1:
         hklf['s'] = args[1]
         if n_args > 2:
           assert n_args > 10
           mx = [ continued_fraction.from_real(e, eps=1e-3).as_rational()
                  for e in args[2:11] ]
           den = reduce(rational.lcm, [ r.denominator() for r in mx ])
           nums = [ r.numerator()*(den//r.denominator()) for r in mx ]
           hklf['matrix'] = sgtbx.rot_mx(nums, den)
           if n_args > 11:
             hklf['wt'] = args[11]
             if n_args == 13:
               hklf['m'] = args[12]
       self.instructions['hklf'] = hklf
       assert not self.builder or ('wt' not in hklf and 'm' not in hklf)
       self.builder.create_shelx_reflection_data_source(
         format=hklf['n'],
         indices_transform=hklf['matrix'],
         data_scale=hklf['s'])
       if 'basf' in self.instructions and hklf['n'] == 5:
         self.builder.make_non_merohedral_twinning_with_transformed_hkl(
           fractions=self.instructions['basf'])
     elif cmd == 'TWIN':
       # only ONE twin instruction allowed
       assert 'twin' not in self.instructions
       twin = {}
       if n_args > 0:
         assert n_args >= 9
         twin['matrix'] = sgtbx.rt_mx(
           sgtbx.rot_mx([int(i) for i in args[0:9]]))
         if n_args > 9:
           twin['n'] = args[9]
       self.instructions['twin'] = twin
       if 'basf' in self.instructions: self.issue_merohedral_twinning()
     elif cmd == 'BASF':
       self.instructions['basf'] = args
       if 'twin' in self.instructions: self.issue_merohedral_twinning()
     elif cmd == 'EXTI':
       if len(args) == 1:
         self.instructions['exti'] = args[0]
     else:
       yield command, line
   else:
     # All token have been read without errors or early bailout
     assert 'hklf' in self.instructions, "Missing HKLF instruction"