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)
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
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
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"
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"