def __init__(self,unit_cell,max_delta,bravais_types_only=True, space_group_symbol="P 1",force_minimum=False,best_monoclinic_beta=True, interest_focus="metric_symmetry",sort=True): # with regard to "force_minimum": when autoindexing, the orientation # matrix may be derived from comparison to a previously indexed case; # the setting may be non-standard; therefore we do not want to # convert to the reduced cell when calculating metric subgroups. if interest_focus=="metric_symmetry": input_symmetry = crystal.symmetry(unit_cell=unit_cell, space_group_symbol=space_group_symbol) elif interest_focus=="input_symmetry": input_symmetry = crystal.symmetry(unit_cell=unit_cell, space_group_symbol=space_group_symbol, force_compatible_unit_cell=False) metric_subgroups.__init__(self,input_symmetry,max_delta, enforce_max_delta_for_generated_two_folds=True, bravais_types_only=bravais_types_only, force_minimum=force_minimum, best_monoclinic_beta=best_monoclinic_beta, interest_focus=interest_focus) for subgroup in self.result_groups: # required keys for subgroup: # max_angular_difference # subsym: the centrosymmetric group, referred to the input_cell basis # cb_op_inp_best: change of basis from the input cell to the best reference cell # derived keys added in other frames: # orient: the orientation matrix, in the reference setting # methods: # to_reference_setting_as_double_array_transpose (formerly 'matrix') # number: the group number of subsym # other attributes: # reduced_group: the acentric group, expressed in input_cell basis # supersym: acentric metric supergroup, input_cell basis group_classification = bravais_lattice(sgtbx.space_group_info( group=subgroup['supersym'].space_group()).type().number()) subgroup['bravais'] = str(group_classification) subgroup['system'] = group_classification.crystal_system.lower() # ad-hoc fix to support the s_minimizer; remove this when # Orientation.constrain() is re-implemented. if subgroup['bravais']=="hR" and subgroup['system']=="trigonal": subgroup['system']="rhombohedral" if subgroup['bravais']=="hP" and subgroup['system']=="trigonal": subgroup['system']="hexagonal" #end of ad-hoc section subgroup['best_group']=subgroup['best_subsym'].space_group() #special procedure to get non-centrosymmetric group subgroup['reduced_group']=\ subgroup['subsym'].space_group().build_derived_acentric_group() subgroup['constraints']=echelon_constraints(subgroup['reduced_group']) self.append(MetricSubgroup().import_iotbx_style(subgroup)) if (sort): self.sort(bestcmp)
def run(args): command_line = (option_parser( usage="iotbx.lattice_symmetry [options] [centring_type_symbol]", description="Example: iotbx.lattice_symmetry" +" --unit_cell=12,12,12.1,89,90,92 F") .enable_symmetry_comprehensive() .option(None, "--delta", action="store", type="float", default=3., help="angular tolerance in degrees") ).process(args=args, max_nargs=1) # Pick up symmetry object input_symmetry = command_line.symmetry # Check that we have what we need if (input_symmetry.unit_cell() is None): print print "***********************************" print "Please specify unit cell parameters" print "***********************************" print command_line.parser.show_help() return if (len(command_line.args) > 0): input_symmetry = crystal.symmetry( unit_cell=input_symmetry.unit_cell(), space_group_symbol="Hall: %s 1" % command_line.args[0]) elif (input_symmetry.space_group_info() is None): input_symmetry = crystal.symmetry( unit_cell=input_symmetry.unit_cell(), space_group_symbol="P 1") # Do it groups = metric_subgroups(input_symmetry, command_line.options.delta, enforce_max_delta_for_generated_two_folds=True) groups.show()
def validate_params(params): if ( (params.input.map_1 is None) or (params.input.map_2 is None) ): raise Sorry('Two CCP4-formatted maps are required.') # check files p = [params.input.map_1, params.input.map_2] maps = [None, None] for i in xrange(2): maps[i] = file_reader.any_file(p[i]) if (maps[i].file_type != 'ccp4_map'): raise Sorry('Please input a CCP4-formatted map for %s.' % p[i]) # check symmetry m1 = maps[0].file_object m2 = maps[1].file_object cs1 = crystal.symmetry(m1.unit_cell().parameters(), m1.space_group_number) cs2 = crystal.symmetry(m2.unit_cell().parameters(), m2.space_group_number) if (cs1.is_similar_symmetry(cs2) is False): raise Sorry('The symmetry of the two maps is not similar.') # check maps m1 = m1.map_data() m2 = m2.map_data() if ( (m1.accessor().all() != m2.accessor().all()) or (m1.accessor().focus() != m2.accessor().focus()) or (m1.accessor().origin() != m2.accessor().origin()) ): raise Sorry('The two maps are not similar.') return True
def select_crystal_symmetry( from_command_line, from_parameter_file, from_coordinate_files, from_reflection_files): result = crystal.symmetry( unit_cell=None, space_group_info=None) if (from_command_line is not None): result = result.join_symmetry( other_symmetry=from_command_line, force=False) if (from_parameter_file is not None): result = result.join_symmetry( other_symmetry=from_parameter_file, force=False) if (result.unit_cell() is None): for crystal_symmetry in from_reflection_files: unit_cell = crystal_symmetry.unit_cell() if (unit_cell is not None): result = crystal.symmetry( unit_cell=unit_cell, space_group_info=result.space_group_info(), assert_is_compatible_unit_cell=False) break for crystal_symmetry in from_coordinate_files: result = result.join_symmetry(other_symmetry=crystal_symmetry, force=False) if (result.space_group_info() is None): for crystal_symmetry in from_reflection_files: space_group_info = crystal_symmetry.space_group_info() if (space_group_info is not None): result = crystal.symmetry( unit_cell=result.unit_cell(), space_group_info=space_group_info, assert_is_compatible_unit_cell=False) break return result
def get_next(self): if (self.coordinate_format == "generic"): if (self.i_next_model): return None crystal_symmetry = crystal.symmetry( unit_cell=self.get_unit_cell(), space_group_info=self.get_space_group_info()) m = emma.model( crystal.special_position_settings(crystal_symmetry), self.positions) m.label = "Model 2" self.i_next_model += 1 return m if (self.coordinate_format == "pdb"): if (self.i_next_model): return None self.i_next_model += 1 return self.pdb_model if (self.coordinate_format == "sdb"): if (self.i_next_model >= len(self.sdb_files)): return None sdb = self.sdb_files[self.i_next_model] crystal_symmetry = crystal.symmetry( unit_cell=self.get_unit_cell(sdb.unit_cell), space_group_info=self.get_space_group_info(sdb.space_group_info)) if (self.other_symmetry is not None): crystal_symmetry = crystal_symmetry.join_symmetry( other_symmetry=self.other_symmetry, force=False) m = sdb_file_to_emma_model(crystal_symmetry, sdb) self.i_next_model += 1 return m raise RuntimeError("Internal error.")
def run(args): assert len(args) == 0 # print 'This is the "tetragonal I" setting humans like:' tetragonal_i = crystal.symmetry( unit_cell=(10,10,13,90,90,90), space_group_symbol="I4") tetragonal_i.show_summary() print print 'Exact same symmetry, but using a basis system that is not very' print 'accessible to humans:' cb_op = tetragonal_i.change_of_basis_op_to_primitive_setting() print 'Change of basis:', cb_op tetragonal_i.change_basis(cb_op=cb_op).show_summary() print # print 'This is the "trigonal R" setting most humans like best:' trigonal_r = crystal.symmetry( unit_cell=(10,10,13,90,90,120), space_group_symbol="R3") trigonal_r.show_summary() print print 'Same symmetry, sometimes preferred:' cb_op = trigonal_r.change_of_basis_op_to_primitive_setting() print 'Change of basis:', cb_op trigonal_r.change_basis(cb_op).show_summary() print
def test_reference_setting_choices(): buffer = StringIO() for space_group_info in sgtbx.reference_space_group_infos(): space_group = space_group_info.group() uc = space_group_info.any_compatible_unit_cell(volume=57*57*76) xs = crystal.symmetry(uc, space_group=space_group) cobs = pt.reference_setting_choices(space_group) if len(cobs)>1: tmp_array = [] for cob in cobs: xs_new =crystal.symmetry(xs.change_basis( cob ).unit_cell(), space_group=xs.space_group() ) best_cell_finder = fbc(xs_new.unit_cell(), xs_new.space_group() ) xs_new = best_cell_finder.return_best_xs() tmp_array.append(xs_new) count = 0 for tmp_xs1 in xrange(len(tmp_array)): for tmp_xs2 in xrange(len(tmp_array)): if (tmp_xs1 != tmp_xs2): assert (tmp_array[tmp_xs1].space_group() == tmp_array[tmp_xs2].space_group()) assert not approx_equal( tmp_array[tmp_xs1].unit_cell().parameters(), tmp_array[tmp_xs2].unit_cell().parameters(), eps=0.001, out=buffer)
def tst_compare(): uc1 = uctbx.unit_cell("61.28,95.92,145.02,90,90,90") xs1 = crystal.symmetry(uc1, "P212121") uc2 = uctbx.unit_cell("115.5,149.0,115.60,90,115.3,90") xs2 = crystal.symmetry(uc2, "P1211") out = StringIO() compare_object = compare_lattice(xs1, xs2, order=1, out=out) assert len(compare_object.possible_solutions) == 1
def __init__(self, set_a, set_b, out=None, relative_length_tolerance=0.05, absolute_angle_tolerance=3.0, lattice_symmetry_max_delta=3.0, file_name=None): self.relative_length_tolerance=relative_length_tolerance self.absolute_angle_tolerance=absolute_angle_tolerance self.lattice_symmetry_max_delta=lattice_symmetry_max_delta self.out = out if self.out is None: self.out = sys.stdout self.file_name=file_name ## make deep copy for safety, and make it non-anomalous self.set_b_ori = set_b.deep_copy().set_observation_type( set_b ) self.set_a = set_a.deep_copy().set_observation_type( set_a ).average_bijvoet_mates() self.set_b = set_b.deep_copy().set_observation_type( set_b ).average_bijvoet_mates() self.set_a_xs = crystal.symmetry( unit_cell=self.set_a.unit_cell(), space_group=self.set_a.space_group() ) self.set_b_xs = crystal.symmetry( unit_cell=self.set_b.unit_cell(), space_group=self.set_b.space_group() ) self.cosets = reindex.reindexing_operators( xs1=self.set_a_xs, xs2=self.set_b_xs, relative_length_tolerance=self.relative_length_tolerance, absolute_angle_tolerance=self.absolute_angle_tolerance, max_delta=self.lattice_symmetry_max_delta, anomalous_flag=self.set_a.anomalous_flag(), out=self.out ) self.set_a_to_niggli = self.cosets.cb_op_to_n_1 self.set_b_to_niggli = self.cosets.cb_op_to_n_2 self.set_a_nig = self.set_a.change_basis( self.set_a_to_niggli ).map_to_asu() self.set_b_nig = self.set_b.change_basis( self.set_b_to_niggli ).map_to_asu() self.ops_in_niggli_setting = self.cosets.cb_ops_in_niggli_setting() self.nice_cb_ops = self.cosets.combined_cb_ops() self.cc_values = [] self.matches = [] if len(self.nice_cb_ops)>0: self.analyse() self.select_and_transform() else: print >> self.out, "No simple reindexing relation found between unit cells"
def tst_find_best_cell(): uc_array=[ uctbx.unit_cell( '40, 50, 60, 90, 90, 90' ), uctbx.unit_cell( '40, 60, 50, 90, 90, 90' ), uctbx.unit_cell( '50, 40, 60, 90, 90, 90' ), uctbx.unit_cell( '50, 60, 40, 90, 90, 90' ), uctbx.unit_cell( '60, 40, 50, 90, 90, 90' ), uctbx.unit_cell( '60, 50, 40, 90, 90, 90' ) ] uc_correct = [ uctbx.unit_cell( '40, 50, 60, 90, 90, 90' ), uctbx.unit_cell( '40, 60, 50, 90, 90, 90' ), uctbx.unit_cell( '40, 50, 60, 90, 90, 90' ), uctbx.unit_cell( '50, 60, 40, 90, 90, 90' ), uctbx.unit_cell( '40, 60, 50, 90, 90, 90' ), uctbx.unit_cell( '50, 60, 40, 90, 90, 90' ) ] sg_info = sgtbx.space_group_info( 'P 21 21 2' ) sg_info_2 = sgtbx.space_group_info( 'I 21 21 21' ) sg = sg_info.group() sg_2 = sg_info_2.group() for uc, correct in zip(uc_array,uc_correct): best_cell_finder = fbc( uc, sg ) assert approx_equal( correct.parameters(), best_cell_finder.return_best_cell().parameters() ) cb_op = best_cell_finder.return_change_of_basis_op_to_best_cell() xs = crystal.symmetry( uc, space_group=sg) assert approx_equal( correct.parameters(), xs.change_basis(cb_op).unit_cell().parameters() ) best_cell_finder = fbc( uc, sg_2 ) assert approx_equal( uc_array[0].parameters(), best_cell_finder.return_best_cell().parameters() ) xs = crystal.symmetry( uc, space_group=sg_2) cb_op = best_cell_finder.return_change_of_basis_op_to_best_cell() assert approx_equal( uc_array[0].parameters(), xs.change_basis(cb_op).unit_cell().parameters() ) # test with incomming sg not in reference setting uc = uctbx.unit_cell( '60, 40, 30, 90, 90, 90' ) sg_info_3 = sgtbx.space_group_info( 'P 1 1 21' ) sg_3 = sg_info_3.group() best_cell_finder = fbc( uc, sg_3 ) xs_best = best_cell_finder.return_best_xs() uc_correct = uctbx.unit_cell( '40, 30, 60, 90, 90, 90' ) sg_correct = sgtbx.space_group_info( 'P 1 21 1' ).group() assert approx_equal( xs_best.unit_cell().parameters(), uc_correct.parameters() ) assert sg_correct == xs_best.space_group()
def unique_reindexing_operators(self, other, relative_length_tolerance, absolute_angle_tolerance): # make crystal symmetries self_xs = crystal.symmetry(unit_cell=self.input.unit_cell(), space_group=self.input.space_group()) other_xs = crystal.symmetry(unit_cell=other.input.unit_cell(), space_group=other.input.space_group()) # some downstream routines expect things to be in minimum cell self_xs = self_xs.change_basis(self.change_of_basis_op_to_minimum_cell) other_xs = other_xs.change_basis(other.change_of_basis_op_to_minimum_cell) double_cosets = reindex.reindexing_operators( self_xs, other_xs, relative_length_tolerance, absolute_angle_tolerance, self.input.anomalous_flag() ) result = double_cosets.combined_cb_ops() return result
def exercise_quick(): for space_group_symbol in ("P-1", "P2/m", "C2/m", "Pmmm", "Cmmm", "Fmmm", "Immm", "P4/mmm", "I4/mmm", "R-3m", "P6/mmm", "Pm-3m", "Im-3m", "Fm-3m"): parent_group_info = sgtbx.space_group_info(space_group_symbol) non_centric = sgtbx.space_group() for i_ltr in xrange(parent_group_info.group().n_ltr()): for i_smx in xrange(parent_group_info.group().n_smx()): s = parent_group_info.group()(i_ltr,0,i_smx) non_centric.expand_smx(s) assert non_centric.f_inv() == 1 assert non_centric.order_z() * 2 == parent_group_info.group().order_z() non_centric_info = sgtbx.space_group_info(group=non_centric) unit_cell = non_centric_info.any_compatible_unit_cell(volume=1000) crystal_symmetry = crystal.symmetry( unit_cell=unit_cell, space_group_info=non_centric_info) minimum_symmetry = crystal_symmetry.minimum_cell() lattice_group = lattice_symmetry.group( minimum_symmetry.unit_cell(), max_delta=0.5) lattice_group_info = sgtbx.space_group_info(group=lattice_group) assert lattice_group_info.group() == minimum_symmetry.space_group() subgrs = subgroups.subgroups(lattice_group_info).groups_parent_setting() for group in subgrs: subsym = crystal.symmetry( unit_cell=minimum_symmetry.unit_cell(), space_group=group, assert_is_compatible_unit_cell=False) assert subsym.unit_cell().is_similar_to(minimum_symmetry.unit_cell()) assert lattice_symmetry.find_max_delta( reduced_cell=minimum_symmetry.unit_cell(), space_group=group) < 0.6 minimum_symmetry = crystal.symmetry( unit_cell="106.04, 181.78, 110.12, 90, 90, 90", space_group_symbol="P 1").minimum_cell() for max_delta in xrange(10,100,10): lattice_group = lattice_symmetry.group( minimum_symmetry.unit_cell(), max_delta=max_delta) lattice_group_info = sgtbx.space_group_info(group=lattice_group) assert str(lattice_group_info) == "P 4 2 2"
def get_most_frequent_symmetry(self, group_idx): # Should call after self.group_xds_results() symms = filter(lambda x: x[2]>0, self.reference_symmetries[group_idx]) symms.sort(key=lambda x: x[2], reverse=True) if len(symms) == 0: return None if len(symms) > 1 and symms[0][0].group() == sgtbx.space_group_info("P1").group(): return crystal.symmetry(symms[1][1], space_group_info=symms[1][0], assert_is_compatible_unit_cell=False) else: return crystal.symmetry(symms[0][1], space_group_info=symms[0][0], assert_is_compatible_unit_cell=False)
def make_new_xs(self, mat): new_basis = self.basis*mat.as_float() new_uc = uctbx.unit_cell( orthogonalization_matrix = new_basis ) new_xs = crystal.symmetry( new_uc, "P1" ) ecbn = new_xs.change_of_basis_op_to_niggli_cell() cb_new_xs = new_xs.change_basis( ecbn ) new_xs = crystal.symmetry( unit_cell=cb_new_xs.unit_cell(), space_group=sgtbx.lattice_symmetry.group(cb_new_xs.unit_cell(),self.max_delta), assert_is_compatible_unit_cell=False, ) # gather some results please self.metric_r_values.append( self.metric_r(new_xs.unit_cell(),cb_new_xs.unit_cell() ) ) self.xs_expand.append( new_xs ) self.add_to_niggli.append( ecbn )
def demo(): """ Result of ICSD query: N * -Cr2O3-[R3-CH] Baster, M.;Bouree, F.;Kowalska, A.;Latacz, Z(2000) C 4.961950 4.961950 13.597400 90.000000 90.000000 120.000000 S GRUP R -3 C A Cr1 0.000000 0.000000 0.347570 0.000000 A O1 0.305830 0.000000 0.250000 """ crystal_symmetry = crystal.symmetry( unit_cell="4.961950 4.961950 13.597400 90.000000 90.000000 120.000000", space_group_symbol="R -3 C") scatterers = flex.xray_scatterer() scatterers.append(xray.scatterer( label="Cr1", site=(0.000000,0.000000,0.347570))) scatterers.append(xray.scatterer( label="O1", site=(0.305830,0.000000,0.250000))) icsd_structure = xray.structure( crystal_symmetry=crystal_symmetry, scatterers=scatterers) icsd_structure.show_summary().show_scatterers() print icsd_structure.show_distances(distance_cutoff=2.5) print primitive_structure = icsd_structure.primitive_setting() primitive_structure.show_summary().show_scatterers() print p1_structure = primitive_structure.expand_to_p1() p1_structure.show_summary().show_scatterers() print print "OK"
def run_indexing(datablock, strong_spots, crystal_model, rmsds): cwd = os.path.abspath(os.curdir) tmp_dir = os.path.abspath(open_tmp_directory(suffix="test_dials_index")) os.chdir(tmp_dir) sweep_path = os.path.join(tmp_dir, "datablock.json") pickle_path = os.path.join(tmp_dir, "strong.pickle") dump.datablock(datablock, sweep_path) easy_pickle.dump(pickle_path, strong_spots) from dials.test.algorithms.indexing.tst_index import run_one_indexing space_group_info = crystal_model.get_space_group() symmetry = crystal.symmetry(unit_cell=crystal_model.get_unit_cell(), space_group=crystal_model.get_space_group()) expected_rmsds = [1.1*r for r in rmsds] imageset = datablock[0].extract_imagesets()[0] pixel_size = imageset.get_detector()[0].get_pixel_size() phi_width = imageset.get_scan().get_oscillation()[1] * math.pi/180 expected_rmsds = [1.1 * rmsds[0] * pixel_size[0], 1.1 * rmsds[1] * pixel_size[1], 1.1 * rmsds[2] * phi_width] run_one_indexing(pickle_path=pickle_path, sweep_path=sweep_path, extra_args=[], expected_unit_cell=symmetry.minimum_cell().unit_cell(), expected_rmsds=expected_rmsds, #expected_hall_symbol=crystal_model.get_space_group().type().hall_symbol(), expected_hall_symbol=' P 1', )
def make_new_xs(self, mat, cb_op, to_reference=True): # make new lattice new_basis = self.basis * mat.as_float() new_uc = uctbx.unit_cell(orthogonalization_matrix=new_basis) tmp_xs = crystal.symmetry( unit_cell=new_uc, space_group=sgtbx.lattice_symmetry.group(new_uc, self.max_delta), assert_is_compatible_unit_cell=False, ) extra_cb_op = tmp_xs.change_of_basis_op_to_reference_setting() self.extra_cb_op.append(extra_cb_op) # new_sg = None try: new_sg = sgtbx.space_group_info(group=self.basic_xs_n.space_group()).change_basis(cb_op) except Exception: pass if to_reference: tmp_xs = tmp_xs.change_basis(extra_cb_op) try: new_sg = new_sg.change_basis(extra_cb_op) except Exception: pass self.xs_list.append(tmp_xs) self.sg_list.append(new_sg)
def xray_structure(O, u_iso=0): from cctbx import xray from cctbx import crystal return xray.structure( crystal_symmetry=crystal.symmetry( unit_cell=O.unit_cell(), space_group_symbol="P1"), scatterers=O.scatterers(u_iso=u_iso))
def tst_pgtools(): unit_cell = uctbx.unit_cell('40, 40, 60, 90.0, 90.0, 90.0') mi = flex.miller_index(((2,4,6), (2,4,8))) xs = crystal.symmetry(unit_cell, "P 1 2 1") ms = miller.set(xs, mi) # Go to the minimum cell, for safety cob_min_cell = ms.change_of_basis_op_to_minimum_cell() ms_new = ms.change_basis( cob_min_cell ) lattice_group = sgtbx.lattice_symmetry.group( ms_new.unit_cell(), max_delta=5.0) point_group_low = ms_new.space_group().build_derived_point_group() point_group_high = lattice_group.build_derived_point_group() pgtree = pt.point_group_graph(point_group_low,point_group_high) # find the possible routes from 'P 2' to 'P 4 2 2' atlas = pgtree.graph.find_all_paths( 'P 1 2 1', 'P 4 2 2') route_1 = ['P 1 2 1', 'P 4 2 2'] route_2 = ['P 1 2 1', 'P 2 2 2', 'P 4 2 2'] assert route_1 in atlas assert route_2 in atlas assert len(atlas)==2 # Now lets 'disqualify' point group 'P 2 2 2' pgtree.remove_point_group_and_its_super_groups_from_graph( str(sgtbx.space_group_info(16))) assert len(pgtree.graph.node_objects)==1 assert pgtree.graph.node_objects.has_key ( 'P 1 2 1' )
def extract_from(file_name): ''' extract_from takes a file name or a string description. If given a file name, it attempts to open the file with all the known symmetry-containing file-types and extract the symmetry information. If all of these fail, it attempts to interpret the input string according to the function cyrstal_symmetry_from_any.from_string. If given a crystal.symmetry it returns the crystal.symmetry. ''' if type(file_name) == type(crystal.symmetry()): return file_name for fmt in (from_scalepack_hkl, from_xds_hkl, from_dtrek_ref, from_ccp4_map, from_xplor_map, from_mtz, from_shelx_ins, from_cns_inp, from_cns_sdb, from_pdb, from_solve_inp, from_cif): if (fmt is None): continue try: return fmt.extract_from(file_name) except KeyboardInterrupt: raise except Exception: pass return from_string(file_name)
def write_to_mtz_files(O, common_unit_cell): from cctbx import crystal crystal_symmetry = crystal.symmetry( unit_cell=common_unit_cell, space_group_symbol="P1") def write_mtz(file_name, counts=None, miis=None): if (miis is None): isel = (counts != 0).iselection() data = counts.select(isel) else: isel = miis data = flex.size_t(isel.size(), 1) ma = crystal_symmetry.miller_set( indices=O.miller_indices.select(isel), anomalous_flag=True).array(data=data) ma.as_mtz_dataset(column_root_label="NOBS").mtz_object().write( file_name=file_name) n_indices = O.miller_indices.size() from scitbx.array_family import flex counts_all = flex.size_t(n_indices, 0) miis_0 = None for i_img,im in enumerate(O.array): miis = im.miller_index_i_seqs write_mtz(file_name="nobs_%03d.mtz" % i_img, miis=miis) counts_all.increment_and_track_up_from_zero( iselection=im.miller_index_i_seqs) if (miis_0 is None): miis_0 = miis else: counts_pair = flex.size_t(n_indices, 0) for isel in [miis_0, miis]: counts_pair.increment_and_track_up_from_zero(iselection=isel) write_mtz(file_name="nobs_000_%03d.mtz" % i_img, counts=counts_pair) write_mtz(file_name="nobs_all.mtz", counts=counts_all)
def update(self): """Update the unit_cell to a change in lattice parameters. This remakes the unit cell according to a change in the lattice parameters. Call this function before using the CCTBXCrystalParSet. The unit_cell will only be remade if necessary. """ if not self._update: return self._update = False stru = self.stru sgn = stru.space_group().match_tabulated_settings().number() # Create the symmetry object from cctbx.crystal import symmetry symm = symmetry( unit_cell = self.unitcell._latpars, space_group_symbol = sgn ) # Now the new structure newstru = stru.__class__( crystal_symmetry = symm, scatterers = stru.scatterers() ) self.unitcell._latpars = list(newstru.unit_cell().parameters()) self.stru = newstru return
def aniso_convert(uc,sg,map,res): os.system('hkl2vtk %s_friedel.hkl %s_friedel.vtk %s_raw.vtk' %(map,map,map)) os.system('vtk2lat %s_friedel.vtk %s_friedel.lat' %(map,map)) os.system('avgrlt %s_friedel.lat %s_friedel.rf' %(map,map)) os.system('subrflt %s_friedel.rf %s_friedel.lat anisotropic.lat' %(map,map)) os.system('lat2hkl anisotropic.lat anisotropic.hkl') #Read in hkl file and populate miller array from cctbx import crystal inf = open('anisotropic.hkl', "r") indices = flex.miller_index() i_obs = flex.double() #sig_i = flex.double() for line in inf.readlines(): assert len(line.split())==4 line = line.strip().split() i_obs_ = float(line[3])#/10000 #10000 is a uniform scale factor meant to re-size all diffuse intensities (normally too large for scalepack) #sig_i_ = math.sqrt(i_obs_) #if(abs(i_obs_)>1.e-6): # perhaps you don't want zeros if i_obs_ != -32768.0: indices.append([int(line[0]),int(line[1]),int(line[2])]) i_obs.append(i_obs_) #sig_i.append(sig_i_) inf.close() #Get miller array object cs = crystal.symmetry(unit_cell=(float(uc[0]), float(uc[1]), float(uc[2]), float(uc[3]), float(uc[4]), float(uc[5])), space_group=sg) miller_set=miller.set(cs, indices) ma = miller.array(miller_set=miller_set, data=i_obs, sigmas=None) mtz_dataset = ma.as_mtz_dataset(column_root_label="Amplitude") mtz_dataset.mtz_object().write('%s_anisotropic.mtz' %map)
def from_string(string): ''' Interprets a symmetry-string object in the following format: a, b, c, alpha, beta, gamma, space-group Please be aware that this is comma delimited, so you may not have commas within the space-group substring. ''' parts = string.split(",") unit_cell = None space_group = None if len(parts) == 7: unit_cell = parts[:-1] space_group = parts[-1] elif len(parts) == 6: unit_cell = parts elif len(parts) == 1: space_group = parts[0] else: return None if unit_cell is not None: try: unit_cell = [float(number) for number in unit_cell] except KeyboardInterrupt: raise except Exception: return None try: return crystal.symmetry(unit_cell=unit_cell,space_group=space_group) except KeyboardInterrupt: raise except Exception: return None
def as_miller_arrays(self, crystal_symmetry=None, force_symmetry=False, merge_equivalents=True, base_array_info=None): from cctbx import miller from cctbx import crystal if (crystal_symmetry is None): crystal_symmetry = crystal.symmetry() if (base_array_info is None): base_array_info = miller.array_info(source_type="shelx_hklf") miller_set = miller.set( crystal_symmetry=crystal_symmetry, indices=self.indices()).auto_anomalous() miller_arrays = [] obs = (miller.array( miller_set=miller_set, data=self.data(), sigmas=self.sigmas()) .set_info(base_array_info.customized_copy(labels=["obs", "sigmas"]))) miller_arrays.append(obs) if (self.alphas() is not None): miller_arrays.append(miller.array( miller_set=miller_set, data=self.alphas()) .set_info(base_array_info.customized_copy(labels=["alphas"]))) return miller_arrays
def test_spacegroup_tidy_pickling(): quartz_structure = xray.structure( crystal_symmetry=crystal.symmetry( unit_cell=(5.01,5.01,5.47,90,90,120), space_group_symbol="P6222"), scatterers=flex.xray_scatterer( [ xray.scatterer(label="Si", site=(1/2.,1/2.,1/3.), u=0.2), xray.scatterer(label="O", site=(0.197,-0.197,0.83333), u=0) ]) ) asu_mappings = quartz_structure.asu_mappings(buffer_thickness=2) pair_asu_table = crystal.pair_asu_table(asu_mappings=asu_mappings) pair_asu_table.add_all_pairs(distance_cutoff=1.7) pair_sym_table = pair_asu_table.extract_pair_sym_table() new_asu_mappings = quartz_structure.asu_mappings(buffer_thickness=5) new_pair_asu_table = crystal.pair_asu_table(asu_mappings=new_asu_mappings) new_pair_asu_table.add_pair_sym_table(sym_table=pair_sym_table) spg = new_pair_asu_table.asu_mappings().space_group() pspg = pickle.loads(pickle.dumps(spg)) mstr = "" pmstr = "" for rt in spg.all_ops(): mstr += rt.r().as_xyz() + "\n" for rt in pspg.all_ops(): pmstr += rt.r().as_xyz() + "\n" assert mstr == pmstr
def exercise_is_simple_interaction(): for space_group_symbol in ["P1", "P41"]: for shifts in flex.nested_loop((-2,-2,-2),(2,2,2),False): shifts = matrix.col(shifts) structure = xray.structure( crystal_symmetry=crystal.symmetry( unit_cell=(10,10,20,90,90,90), space_group_symbol=space_group_symbol), scatterers=flex.xray_scatterer([ xray.scatterer(label="O", site=shifts+matrix.col((0,0,0))), xray.scatterer(label="N", site=shifts+matrix.col((0.5,0.5,0))), xray.scatterer(label="C", site=shifts+matrix.col((0.25,0.25,0)))])) asu_mappings = structure.asu_mappings(buffer_thickness=7) pair_generator = crystal.neighbors_simple_pair_generator( asu_mappings=asu_mappings, distance_cutoff=7) simple_interactions = {} for i_pair,pair in enumerate(pair_generator): if (asu_mappings.is_simple_interaction(pair)): assert asu_mappings_is_simple_interaction_emulation( asu_mappings, pair) key = (pair.i_seq,pair.j_seq) assert simple_interactions.get(key, None) is None simple_interactions[key] = 1 else: assert not asu_mappings_is_simple_interaction_emulation( asu_mappings, pair) assert len(simple_interactions) == 2 assert simple_interactions[(0,2)] == 1 assert simple_interactions[(1,2)] == 1
def exercise_get_experimental_phases(): crystal_symmetry = crystal.symmetry( unit_cell=(30,31,32,85,95,100), space_group_symbol="P 1") miller_set = miller.build_set( crystal_symmetry=crystal_symmetry, anomalous_flag=False, d_min=3) input_array = miller_set.array( data=flex.hendrickson_lattman(miller_set.indices().size(), (0,0,0,0))) mtz_dataset = input_array.as_mtz_dataset(column_root_label="P") mtz_dataset.mtz_object().write("tmp.mtz") reflection_files = [reflection_file_reader.any_reflection_file( file_name="tmp.mtz")] err = StringIO() reflection_file_srv = reflection_file_server( crystal_symmetry=crystal_symmetry, force_symmetry=True, reflection_files=reflection_files, err=err) experimental_phases = reflection_file_srv.get_experimental_phases( file_name=None, labels=None, ignore_all_zeros=False, parameter_scope="experimental_phases") assert str(experimental_phases.info()) == "tmp.mtz:PA,PB,PC,PD" try: reflection_file_srv.get_experimental_phases( file_name=None, labels=None, ignore_all_zeros=True, parameter_scope="experimental_phases") except Sorry, e: assert str(e) == "No array of experimental phases found." assert err.getvalue() == """\
def run(args): import os to_pickle = "--pickle" in args for file_name in args: if (file_name.startswith("--")): continue print file_name + ":" f = open(file_name, "r") t0 = os.times() reflection_file = cns_reflection_file(f) tn = os.times() t_parse = tn[0]+tn[1]-t0[0]-t0[1] f.close() reflection_file.show_summary() print crystal_symmetry = crystal.symmetry((), "P 1") miller_arrays = reflection_file.as_miller_arrays(crystal_symmetry) for miller_array in miller_arrays: miller_array.show_summary() print if (to_pickle): pickle_file_name = os.path.split(file_name)[1] + ".pickle" t0 = os.times() easy_pickle.dump(pickle_file_name, reflection_file) tn = os.times() t_dump = tn[0]+tn[1]-t0[0]-t0[1] t0 = os.times() easy_pickle.load(pickle_file_name) tn = os.times() t_load = tn[0]+tn[1]-t0[0]-t0[1] print "parse: %.2f, dump: %.2f, load: %.2f" % (t_parse, t_dump, t_load) print t = os.times() print "u+s,u,s: %.2f %.2f %.2f" % (t[0] + t[1], t[0], t[1])
def extract_structure(self, phase_nr=1): """This method tries to extract the crystal structure from the parsed pcrfile. :returns: the extracted structure :rtype: cctbx.xray.structure """ from cctbx import xray from cctbx import crystal from cctbx.array_family import flex p = self.cfg['phases'][str(phase_nr)] atoms = p['atoms'] unit_cell = [ p['a'], p['b'], p['c'], p['alpha'], p['beta'], p['gamma'] ] special_position_settings=crystal.special_position_settings( crystal_symmetry=crystal.symmetry( unit_cell=unit_cell, space_group_symbol=p['SYMB'])) scatterers = [] for k, a in atoms.iteritems(): scatterers.append(xray.scatterer(label=a['LABEL'], scattering_type=a['NTYP'], site=(a['X'], a['Y'], a['Z']), b=a['B'])) scatterers_flex=flex.xray_scatterer(scatterers) structure = xray.structure(special_position_settings=special_position_settings, scatterers=scatterers_flex) return structure.as_py_code()
# cctbx_sources/cctbx/sgtbx/symbols.cpp # in cctbx toolkit file structure # # To run the script, cctbx toolkit must be installed: # 1) source /build/setpaths.sh in cctbx toolkit (after its compiled) # 2) libtbx.python format_Spacegroup_json.py # # Jakub Kaminski, UCLA, 2014 # from cctbx import crystal import json file = open("formated_groups-origins.dat", 'r') jsonData = {} while 1: line = file.readline() if line == "": break line = line.split() symbol = line[1] group = crystal.symmetry(space_group_symbol=symbol) operations = [] for operation in group.space_group(): operations.append(operation.as_xyz()) jsonData[symbol] = operations with open("spacegroups.json", 'w') as outfile: json.dump(jsonData, outfile, indent=4)
def simul_utils(args): if len(args)==0: print_help() elif ( "--help" in args ): print_help() elif ( "--h" in args ): print_help() elif ("-h" in args ): print_help() else: log = multi_out() if (not "--quiet" in args): log.register(label="stdout", file_object=sys.stdout) string_buffer = StringIO() string_buffer_plots = StringIO() log.register(label="log_buffer", file_object=string_buffer) phil_objects = [] argument_interpreter = master_params.command_line_argument_interpreter( home_scope="map_coefs") print >> log, "#phil __OFF__" print >> log, "======================" print >> log, " SIMUL " print >> log, "A data simulation tool" print >> log, "======================" print >> log for arg in args: command_line_params = None arg_is_processed = False # is it a file? if (os.path.isfile(arg)): ## is this a file name? # check if it is a phil file try: command_line_params = iotbx.phil.parse(file_name=arg) if command_line_params is not None: phil_objects.append(command_line_params) arg_is_processed = True except KeyboardInterrupt: raise except Exception : pass else: try: command_line_params = argument_interpreter.process(arg=arg) if command_line_params is not None: phil_objects.append(command_line_params) arg_is_processed = True except KeyboardInterrupt: raise except Exception : pass if not arg_is_processed: print >> log, "##----------------------------------------------##" print >> log, "## Unknown file or keyword:", arg print >> log, "##----------------------------------------------##" print >> log raise Sorry("Unknown file or keyword: %s" % arg) effective_params = master_params.fetch(sources=phil_objects) params = effective_params.extract() """ new_params = master_params.format(python_object=params) new_params.show(out=log) """ # now get the unit cell from the pdb file hkl_xs = crystal_symmetry_from_any.extract_from( file_name=params.simul_utils.input.xray_data.file_name) pdb_xs = crystal_symmetry_from_any.extract_from( file_name=params.simul_utils.input.model.file_name) phil_xs = crystal.symmetry( unit_cell=params.simul_utils.input.unit_cell, space_group_info=params.simul_utils.input.space_group ) combined_xs = select_crystal_symmetry( None,phil_xs, [pdb_xs],[hkl_xs]) # inject the unit cell and symmetry in the phil scope please params.simul_utils.input.unit_cell = combined_xs.unit_cell() params.simul_utils.input.space_group = \ sgtbx.space_group_info( group = combined_xs.space_group() ) print >> log, "#phil __ON__" new_params = master_params.format(python_object=params) new_params.show(out=log) print >> log, "#phil __END__" if params.simul_utils.input.unit_cell is None: raise Sorry("unit cell not specified") if params.simul_utils.input.space_group is None: raise Sorry("space group not specified") if params.simul_utils.input.xray_data.file_name is None: raise Sorry("Xray data not specified") if params.simul_utils.input.model.file_name is None: raise Sorry("pdb file with model not specified") #----------------------------------------------------------- # # step 1: read in the reflection file # phil_xs = crystal.symmetry( unit_cell=params.simul_utils.input.unit_cell, space_group_info=params.simul_utils.input.space_group ) xray_data_server = reflection_file_utils.reflection_file_server( crystal_symmetry = phil_xs, force_symmetry = True, reflection_files=[]) miller_array = None miller_array = xray_data_server.get_xray_data( file_name = params.simul_utils.input.xray_data.file_name, labels = params.simul_utils.input.xray_data.labels, ignore_all_zeros = True, parameter_scope = 'simul_utils.input.xray_data', parameter_name = 'labels' ) info = miller_array.info() miller_array = miller_array.map_to_asu() miller_array = miller_array.select( miller_array.indices() != (0,0,0)) miller_array = miller_array.select( miller_array.data() > 0 ) if miller_array.sigmas() is not None: miller_array = miller_array.select( miller_array.sigmas() > 0 ) if (miller_array.is_xray_intensity_array()): miller_array = miller_array.f_sq_as_f() elif (miller_array.is_complex_array()): miller_array = abs(miller_array) miller_array.set_info(info) print >> log print >> log, "Summary info of observed data" print >> log, "=============================" miller_array.show_summary(f=log) print >> log free_flags = miller_array.generate_r_free_flags() #-------------------------------------------------------------------- # Step 2: get an xray structure from the PDB file # model = pdb.input(file_name=params.simul_utils.input.model.file_name).xray_structure_simple( crystal_symmetry=phil_xs, ) print >> log, "Atomic model summary" print >> log, "====================" model.show_summary() print >> log #------------------------------------------------------------------- # Step 3: make an F_model object to get model phases and amplitudes # print >> log, "Performing bulk solvent scaling" print >> log, "===============================" print >> log print >> log f_model_object = f_model.manager( f_obs = miller_array, r_free_flags = free_flags, xray_structure = model ) f_model_object.update_all_scales(log=log) fmodel = abs( f_model_object.f_model() ).set_observation_type( miller_array ) mockfmodel = None if params.simul_utils.input.mock_model.file_name is not None: print >> log, "Reading in mock model" print >> log, "=====================" print >> log print >> log mock_model = pdb.input(file_name=params.simul_utils.input.mock_model.file_name).xray_structure_simple( crystal_symmetry=phil_xs) mock_f_model = f_model.manager( f_obs = miller_array, r_free_flags = free_flags, xray_structure = mock_model ) mock_f_model.update( k_sol = f_model_object.k_sol() , b_sol = f_model_object.b_sol() , b_cart = f_model_object.b_cart() ) mockfmodel = abs( mock_f_model.f_model() ).set_observation_type( miller_array ) else: mockfmodel = fmodel.deep_copy() print >> log, "Making new data" print >> log, "===============" print >> log print >> log new_data_builder = error_swap( miller_array, fmodel, mockfmodel ) new_data = new_data_builder.new_obs # we now have to write the data actually print >> log, "Writing new data set" print >> log, "====================" mtz_dataset = new_data.as_mtz_dataset( column_root_label="FOBS") mtz_dataset.mtz_object().write( file_name=params.simul_utils.output.hklout)
def exercise_misc(): for flex_type in flex_types(): m = flex_type([1,2,-3,4,-5,6]) maptbx.set_if_less_than(m, 0, 0) assert approx_equal(tuple(m), (1,2,0,4,0,6)) maptbx.set_if_less_than(m, 2, 9) assert approx_equal(tuple(m), (9,2,9,4,9,6)) from cctbx import xray structure = xray.structure( special_position_settings=crystal.special_position_settings( crystal_symmetry=crystal.symmetry( unit_cell=(10.0,10.0,10.0,90,90,90), space_group_symbol="P1")), scatterers=flex.xray_scatterer([ xray.scatterer( label="O", site=(0.5,0.5,0.5), u=0.2)])) fc = structure.structure_factors(d_min=2).f_calc() fc_map = fc.fft_map(resolution_factor=1/4.) fc_map.apply_sigma_scaling() real_map = fc_map.real_map_unpadded() stats = maptbx.spherical_variance_around_point( real_map=real_map, unit_cell=structure.unit_cell(), site_cart=(5.,5.,5.), radius=1.) # XXX exact numbers are *not* consistent across platforms! assert (approx_equal(stats.min, 8.3, eps=0.2)) assert (approx_equal(stats.mean, 8.5, eps=0.1)) assert (stats.standard_deviation < 0.15) stats = maptbx.spherical_variance_around_point( real_map=real_map, unit_cell=structure.unit_cell(), site_cart=(6.,6.,6.), radius=1.) assert (approx_equal(stats.min, -0.75, eps=0.15)) assert (approx_equal(stats.mean, 1.35, eps=0.1)) assert (approx_equal(stats.standard_deviation, 3.25, eps=0.1)) # test principal_axes_of_inertia # XXX d_min=2.01 to get consistent behavior across platforms fc = structure.structure_factors(d_min=2.01).f_calc() assert (fc.indices().size() == 242) fc_map = fc.fft_map(resolution_factor=1/4.) fc_map.apply_sigma_scaling() real_map = fc_map.real_map_unpadded() pai = maptbx.principal_axes_of_inertia( real_map=real_map, unit_cell=structure.unit_cell(), site_cart=(5.,5.,5.), radius=2.0) assert approx_equal(pai.center_of_mass(), (5.0,5.0,5.0), 0.1) assert (approx_equal(pai.inertia_tensor(), (44.89,44.89,44.89,1.87,1.87,1.87), eps=0.5)) assert (approx_equal(list(pai.eigensystem().values()), (48,43,43), eps=1)) # and now with anisotropy structure = xray.structure( special_position_settings=crystal.special_position_settings( crystal_symmetry=crystal.symmetry( unit_cell=(10.0,10.0,10.0,90,90,90), space_group_symbol="P1")), scatterers=flex.xray_scatterer([ xray.scatterer( label="O", site=(0.5,0.5,0.5), u=(0.2,0.2,0.2,0.1,0.0,0.0))])) fc = structure.structure_factors(d_min=2.01).f_calc() assert (fc.indices().size() == 242) fc_map = fc.fft_map(resolution_factor=1/4.) fc_map.apply_sigma_scaling() fc_map.as_ccp4_map("aniso.ccp4") real_map = fc_map.real_map_unpadded() pai = maptbx.principal_axes_of_inertia( real_map=real_map, unit_cell=structure.unit_cell(), site_cart=(5.,5.,5.), radius=2.0) assert (approx_equal(pai.center_of_mass(), (5.0,5.0,5.0), eps=0.2))
def __init__(self, miller_index, batch, intensity, variance, unit_cell, space_group, nbins=10, dmin=None, dmax=None): ''' Initialise :param miller_index: The list of miller indices :param batch: The list of batch numbers :param intensity: The list of intensities :param variance: The list of variances :param unit_cell: The unit cell or list of unit cells :param space_group: The space group :param nbins: The number of bins :param dmin: The maximum resolution :param dmax: The minimum resolution ''' # Reject reflections with negative variance selection = variance > 0 miller_index = miller_index.select(selection) batch = batch.select(selection) intensity = intensity.select(selection) variance = variance.select(selection) # Map the miller indices to the ASU cs = crystal.symmetry(unit_cell, space_group=space_group) ms = miller.set(cs, miller_index) ms_asu = ms.map_to_asu() miller_index = ms_asu.indices() # Save the arrays self._miller_index = miller_index self._batch = batch self._intensity = intensity self._variance = variance # Create the resolution bins D = [unit_cell.d(h) for h in miller_index] self._num_bins = nbins self._dmin = dmin self._dmax = dmax if dmin is None: self._dmin = min(D) if dmax is None: self._dmax = max(D) binner = ResolutionBinner(unit_cell, self._dmin, self._dmax, nbins) # Create lookups for elements by miller index index_lookup = defaultdict(list) for i, h in enumerate(miller_index): index_lookup[h].append(i) # Compute the Overall Sum(X) and Sum(X^2) for each unique reflection reflection_sums = defaultdict(ReflectionSum) for h in index_lookup.keys(): I = [intensity[i] for i in index_lookup[h]] n = len(I) sum_x = sum(I) sum_x2 = sum(II**2 for II in I) reflection_sums[h] = ReflectionSum(sum_x, sum_x2, n) # Compute some numbers self._num_batches = len(set(batch)) self._num_reflections = len(miller_index) self._num_unique = len(reflection_sums.keys()) print "" print "# Batches: ", self._num_batches print "# Reflections: ", self._num_reflections print "# Unique: ", self._num_unique # Compute the CC 1/2 for all the data self._cchalf_mean = self._compute_cchalf(reflection_sums, binner) print "CC 1/2 mean: %.3f" % (100*self._cchalf_mean) # Compute the CC 1/2 excluding each batch in turn self._cchalf = self._compute_cchalf_excluding_each_batch( reflection_sums, binner, miller_index, batch, intensity)
def unit_cell_info(sub_clusters): """ Print unit cell information for a list of clusters. :param sub_clusters: a list of cluster objects :return: a string containing median unit cells, standard deviations and point group composition of each cluster. """ from libtbx.utils import plural_s # 3. print out some information that is useful. out_str = "\n\n{:<16} {:<8} {:<13} {:<13} {:<13} {:<12} {:<12} {:<12}{:<8}\n".format( "Cluster_id", "N_xtals", "Med_a", "Med_b", "Med_c", "Med_alpha", "Med_beta", "Med_gamma", "Delta(deg)") singletons = [] for cluster in sub_clusters: if len(cluster.members) != 1: # New approach, takes niggli setting of the cluster median and converts # back to reference setting for cluster report. Fixes cctbx#97. from cctbx import crystal from cctbx.uctbx import unit_cell from cctbx.sgtbx.lattice_symmetry import metric_subgroups input_symmetry = crystal.symmetry(unit_cell=unit_cell( cluster.medians[0:6]), space_group_symbol="P 1") groups = metric_subgroups( input_symmetry, 3.00, enforce_max_delta_for_generated_two_folds=True) group = groups.result_groups[0] # suppress stdout output for now from six.moves import StringIO SS = StringIO() import sys sys.stdout = SS group['best_subsym'].space_group_info().show_summary() sys.stdout = sys.__stdout__ print(" Unit cell:", group['best_subsym'].unit_cell()) uc_params_conv = group['best_subsym'].unit_cell().parameters() sorted_pg_comp = sorted(list(cluster.pg_composition.items()), key=lambda x: -1 * x[1]) pg_strings = [ "{} in {}".format(pg[1], pg[0]) for pg in sorted_pg_comp ] point_group_string = ", ".join(pg_strings) + "." out_str += point_group_string out_str += ("\n{:<16} {:<8} {:<6.2f}({:<5.2f}) {:<6.2f}({:<5.2f})" " {:<6.2f}({:<5.2f}) {:<6.2f}({:<4.2f}) {:<6.2f}" "({:<4.2f}) {:<6.2f}({:<4.2f})").format( cluster.cname, len(cluster.members), cluster.medians[0], cluster.stdevs[0], cluster.medians[1], cluster.stdevs[1], cluster.medians[2], cluster.stdevs[2], cluster.medians[3], cluster.stdevs[3], cluster.medians[4], cluster.stdevs[4], cluster.medians[5], cluster.stdevs[5]) out_str += ("\n{:>24} {:<6.2f}{:<7} {:<6.2f}{:<7}" " {:<6.2f}{:<7} {:<6.2f}{:<6} {:<6.2f}" "{:<6} {:<6.2f}{:<6} {:<6.2}").format( SS.getvalue().strip()[13:], uc_params_conv[0], "", uc_params_conv[1], "", uc_params_conv[2], "", uc_params_conv[3], "", uc_params_conv[4], "", uc_params_conv[5], "", group["max_angular_difference"]) + "\n\n" else: singletons.append("".join([ ("{:<14} {:<11.2f} {:<11.2f} {:<11.2f}" "{:<12.1f} {:<12.1f} {:<12.1f}").format( list(cluster.pg_composition.keys())[0], cluster.members[0].uc[0], cluster.members[0].uc[1], cluster.members[0].uc[2], cluster.members[0].uc[3], cluster.members[0].uc[4], cluster.members[0].uc[5]), '\n' ])) out_str += "\nStandard deviations are in brackets." explanation = """\nEach cluster: Input lattice count, with integration Bravais setting space group. Cluster median with Niggli cell parameters (std dev in brackets). Highest possible metric symmetry and unit cell using LePage (J Appl Cryst 1982, 15:255) method, maximum delta 3deg.""" out_str += explanation singleton_str = "\n%i singleton%s:" % plural_s(len(singletons)) singleton_str += "\n\n{:<14} {:<11} {:<11} {:<11}{:<12} {:<12} {:<12}\n".format( "Point group", "a", "b", "c", "alpha", "beta", "gamma") singleton_str += "".join(singletons) n_clusters = len(sub_clusters) - len(singletons) out_str = "\n%i cluster%s:" % plural_s(n_clusters) + out_str return singleton_str + out_str
def __init__(self, unit_cell=None, space_group=None, max_delta=5): self._max_delta = max_delta self.target_symmetry_primitive = None self.target_symmetry_reference_setting = None self.cb_op_inp_ref = None target_unit_cell = unit_cell target_space_group = space_group if target_space_group is not None: target_space_group = target_space_group.build_derived_patterson_group( ) if target_unit_cell is not None or target_space_group is not None: if target_unit_cell is not None and target_space_group is not None: self._setup_target_unit_cell_and_space_group( target_unit_cell, target_space_group) elif target_unit_cell is not None: self.target_symmetry_reference_setting = crystal.symmetry( unit_cell=target_unit_cell, space_group=sgtbx.space_group()) self.cb_op_inp_ref = sgtbx.change_of_basis_op() elif target_space_group is not None: self.cb_op_inp_ref = (target_space_group.info( ).change_of_basis_op_to_reference_setting()) self.target_symmetry_reference_setting = crystal.symmetry( space_group=target_space_group.change_basis( self.cb_op_inp_ref)) self.cb_op_reference_to_primitive = ( self.target_symmetry_reference_setting. change_of_basis_op_to_primitive_setting()) if target_unit_cell is not None: self.target_symmetry_primitive = self.target_symmetry_reference_setting.change_basis( self.cb_op_reference_to_primitive) else: self.target_symmetry_primitive = crystal.symmetry( space_group=self.target_symmetry_reference_setting. space_group().change_basis( self.cb_op_reference_to_primitive)) self.cb_op_ref_inp = self.cb_op_inp_ref.inverse() self.cb_op_primitive_inp = ( self.cb_op_ref_inp * self.cb_op_reference_to_primitive.inverse()) if self.target_symmetry_reference_setting is not None: debug_handle = StringIO() self.target_symmetry_reference_setting.show_summary( f=debug_handle) logger.debug("Target symmetry (reference setting):\n" + debug_handle.getvalue()) if self.target_symmetry_primitive is not None: debug_handle = StringIO() self.target_symmetry_primitive.show_summary(f=debug_handle) logger.debug("Target symmetry (primitive cell):\n" + debug_handle.getvalue()) logger.debug("cb_op reference->primitive: " + str(self.cb_op_reference_to_primitive)) logger.debug("cb_op primitive->input: " + str(self.cb_op_primitive_inp))
def run(args=None, imageset=None): dxtbx.util.encode_output_as_utf8() args = sys.argv[1:] if args is None else args # Parse input try: len(args) except TypeError: params = args else: user_phil = [] for arg in args: if "=" in arg: try: user_phil.append(iotbx.phil.parse(arg)) except RuntimeError as e: raise Sorry("Unrecognized argument '%s' (error: %s)" % (arg, str(e))) else: try: user_phil.append(iotbx.phil.parse("""file_path=%s""" % arg)) except ValueError: raise Sorry("Unrecognized argument '%s'" % arg) params = master_phil.fetch(sources=user_phil).extract() if imageset is None: if (params.file_path is None or len(params.file_path) == 0 or not all(os.path.isfile(f) for f in params.file_path)): master_phil.show(attributes_level=2) raise Usage( "file_path must be defined (either file_path=XXX, or the path alone)." ) assert params.n_bins is not None assert params.verbose is not None assert params.output_bins is not None if params.reference_geometry is not None: ref_expts = ExperimentListFactory.from_json_file( params.reference_geometry, check_format=None) assert (len(ref_expts.detectors()) == 1 ), "Provide only one detector in the reference geometry file" detector = ref_expts.detectors()[0] # Allow writing to a file instead of stdout if params.output_file is None: logger = sys.stdout else: logger = open(params.output_file, "w") logger.write("%s " % params.output_file) if params.show_plots: from matplotlib import pyplot as plt colormap = plt.cm.gist_ncar plt.gca().set_prop_cycle(color=[ colormap(i) for i in np.linspace(0, 0.9, len(params.file_path)) ]) if params.mask is not None and not isinstance(params.mask, tuple): params.mask = easy_pickle.load(params.mask) if imageset is None: iterable = params.file_path def load_func(x): try: obj = dxtbx.datablock.DataBlockFactory.from_filenames( [x])[0].extract_imagesets()[0] except IndexError: try: obj = dxtbx.datablock.DataBlockFactory.from_json_file( x)[0].extract_imagesets()[0] except dxtbx.datablock.InvalidDataBlockError: obj = ExperimentListFactory.from_json_file(x)[0].imageset return obj else: iterable = [imageset] def load_func(x): return x # Iterate over each file provided for item in iterable: iset = load_func(item) n_images = len(iset) if params.image_number is None: if params.max_images is None: subiterable = range(n_images) else: subiterable = range(0, min(params.max_images, n_images)) else: subiterable = [params.image_number] for image_number in subiterable: beam = iset.get_beam(image_number) if params.reference_geometry is None: detector = iset.get_detector(image_number) s0 = col(beam.get_s0()) # Search the detector for the panel farthest from the beam. The # number of bins in the radial average will be equal to the # farthest point from the beam on the detector, in pixels, unless # overridden at the command line panel_res = [p.get_max_resolution_at_corners(s0) for p in detector] farthest_panel = detector[panel_res.index(min(panel_res))] size2, size1 = farthest_panel.get_image_size() corners = [(0, 0), (size1 - 1, 0), (0, size2 - 1), (size1 - 1, size2 - 1)] corners_lab = [ col(farthest_panel.get_pixel_lab_coord(c)) for c in corners ] corner_two_thetas = [ farthest_panel.get_two_theta_at_pixel(s0, c) for c in corners ] extent_two_theta = max(corner_two_thetas) max_corner = corners_lab[corner_two_thetas.index(extent_two_theta)] extent = int( math.ceil(max_corner.length() * math.sin(extent_two_theta) / max(farthest_panel.get_pixel_size()))) extent_two_theta *= 180 / math.pi if params.n_bins < extent: params.n_bins = extent # These arrays will store the radial average info sums = flex.double(params.n_bins) * 0 sums_sq = flex.double(params.n_bins) * 0 counts = flex.int(params.n_bins) * 0 all_data = iset[image_number] if not isinstance(all_data, tuple): all_data = (all_data, ) for tile, (panel, data) in enumerate(zip(detector, all_data)): if params.panel is not None and tile != params.panel: continue if params.mask is None: mask = flex.bool(flex.grid(data.focus()), True) else: mask = params.mask[tile] if hasattr(data, "as_double"): data = data.as_double() logger.flush() if params.verbose: logger.write("Average intensity tile %d: %9.3f\n" % (tile, flex.mean(data))) logger.write("N bins: %d\n" % params.n_bins) logger.flush() x1, y1, x2, y2 = ( 0, 0, panel.get_image_size()[1], panel.get_image_size()[0], ) bc = panel.get_beam_centre_px(beam.get_s0()) bc = int(round(bc[1])), int(round(bc[0])) # compute the average radial_average( data, mask, bc, sums, sums_sq, counts, panel.get_pixel_size()[0], panel.get_distance(), (x1, y1), (x2, y2), ) # average the results, avoiding division by zero results = sums.set_selected(counts <= 0, 0) results /= counts.set_selected(counts <= 0, 1).as_double() if params.median_filter_size is not None: logger.write( "WARNING, the median filter is not fully propagated to the variances\n" ) from scipy.ndimage.filters import median_filter results = flex.double( median_filter(results.as_numpy_array(), size=params.median_filter_size)) # calculate standard devations stddev_sel = ((sums_sq - sums * results) >= 0) & (counts > 0) std_devs = flex.double(len(sums), 0) std_devs.set_selected( stddev_sel, (sums_sq.select(stddev_sel) - sums.select(stddev_sel) * results.select(stddev_sel)) / counts.select(stddev_sel).as_double(), ) std_devs = flex.sqrt(std_devs) twotheta = (flex.double(range(len(results))) * extent_two_theta / params.n_bins) q_vals = (4 * math.pi * flex.sin(math.pi * twotheta / 360) / beam.get_wavelength()) # nlmbda = 2dsin(theta) resolution = flex.double(len(twotheta), 0) nonzero = twotheta > 0 resolution.set_selected( nonzero, beam.get_wavelength() / (2 * flex.asin( (math.pi / 180) * twotheta.select(nonzero) / 2)), ) if params.low_max_two_theta_limit is None: subset = results else: subset = results.select( twotheta >= params.low_max_two_theta_limit) max_result = flex.max(subset) if params.x_axis == "two_theta": xvals = twotheta max_x = twotheta[flex.first_index(results, max_result)] elif params.x_axis == "q": xvals = q_vals max_x = q_vals[flex.first_index(results, max_result)] elif params.x_axis == "resolution": xvals = resolution max_x = resolution[flex.first_index(results, max_result)] for i, r in enumerate(results): val = xvals[i] if params.output_bins and "%.3f" % r != "nan": # logger.write("%9.3f %9.3f\n"% (val,r)) #.xy format for Rex.cell. logger.write( "%9.3f %9.3f %9.3f\n" % (val, r, std_devs[i])) # .xye format for GSASII # logger.write("%.3f %.3f %.3f\n"%(val,r,ds[i])) # include calculated d spacings logger.write("Maximum %s: %f, value: %f\n" % (params.x_axis, max_x, max_result)) if params.show_plots: if params.plot_x_max is not None: results = results.select(xvals <= params.plot_x_max) xvals = xvals.select(xvals <= params.plot_x_max) if params.x_axis == "resolution": xvals = 1 / (xvals**2) if params.normalize: plt.plot( xvals.as_numpy_array(), (results / flex.max(results)).as_numpy_array(), "-", ) else: plt.plot(xvals.as_numpy_array(), results.as_numpy_array(), "-") if params.x_axis == "two_theta": plt.xlabel("2 theta") elif params.x_axis == "q": plt.xlabel("q") elif params.x_axis == "resolution": from matplotlib.ticker import FuncFormatter plt.xlabel("Resolution ($\\AA$)") def resolution(x, pos): if x <= 0: return "-" return "%.1f" % (1 / math.sqrt(x)) formatter = FuncFormatter(resolution) plt.gca().xaxis.set_major_formatter(formatter) plt.ylabel("Avg ADUs") if params.plot_y_max is not None: plt.ylim(0, params.plot_y_max) if params.show_plots: if params.unit_cell or params.space_group: assert params.unit_cell and params.space_group sym = symmetry(unit_cell=params.unit_cell, space_group=params.space_group.group()) hkl_list = cctbx.miller.build_set(sym, False, d_min=params.d_min) tt = sym.unit_cell().two_theta(hkl_list.indices(), beam.get_wavelength(), deg=True) if params.x_axis == "q": q_vals = (4 * math.pi * flex.sin(math.pi * tt / 360) / beam.get_wavelength()) vals = q_vals elif params.x_axis == "resolution": # nlmbda = 2dsin(theta) resolution = flex.double(len(tt), 0) nonzero = tt > 0 resolution.set_selected( nonzero, beam.get_wavelength() / (2 * flex.asin( (math.pi / 180) * tt.select(nonzero) / 2)), ) vals = resolution vals = 1 / (vals**2) elif params.x_axis == "two_theta": vals = tt for val in vals: plt.plot([val, val], [0, 50], "r") # plt.legend([os.path.basename(os.path.splitext(f)[0]) for f in params.file_path], ncol=2) plt.show() return xvals, results
def _index(self): if PhilIndex.params.dials.index.method in (libtbx.Auto, None): if self._indxr_input_cell is not None: indexer = self._do_indexing("real_space_grid_search") else: try: indexer_fft3d = self._do_indexing(method="fft3d") nref_3d, rmsd_3d = indexer_fft3d.get_nref_rmsds() except Exception as e: nref_3d = None rmsd_3d = None try: indexer_fft1d = self._do_indexing(method="fft1d") nref_1d, rmsd_1d = indexer_fft1d.get_nref_rmsds() except Exception as e: nref_1d = None rmsd_1d = None if (nref_1d is not None and nref_3d is None or (nref_1d > nref_3d and rmsd_1d[0] < rmsd_3d[0] and rmsd_1d[1] < rmsd_3d[1] and rmsd_1d[2] < rmsd_3d[2])): indexer = indexer_fft1d elif nref_3d is not None: indexer = indexer_fft3d else: raise RuntimeError(e) else: indexer = self._do_indexing( method=PhilIndex.params.dials.index.method) # not strictly the P1 cell, rather the cell that was used in indexing self._p1_cell = indexer._p1_cell self.set_indexer_payload("indexed_filename", indexer.get_indexed_filename()) from cctbx.sgtbx import bravais_types from dxtbx.serialize import load indexed_file = indexer.get_indexed_filename() indexed_experiments = indexer.get_experiments_filename() fast_mode = PhilIndex.params.dials.fast_mode trust_beam_centre = PhilIndex.params.xia2.settings.trust_beam_centre multi_sweep_indexing = PhilIndex.params.xia2.settings.multi_sweep_indexing check_indexing_symmetry = PhilIndex.params.dials.check_indexing_symmetry if check_indexing_symmetry and not (trust_beam_centre or fast_mode or multi_sweep_indexing): checksym = self.CheckIndexingSymmetry() checksym.set_experiments_filename(indexed_experiments) checksym.set_indexed_filename(indexed_file) checksym.set_grid_search_scope(1) checksym.run() hkl_offset = checksym.get_hkl_offset() Debug.write("hkl_offset: %s" % str(hkl_offset)) if hkl_offset is not None and hkl_offset != (0, 0, 0): reindex = self.Reindex() reindex.set_hkl_offset(hkl_offset) reindex.set_indexed_filename(indexed_file) reindex.run() indexed_file = reindex.get_reindexed_reflections_filename() # do some scan-static refinement - run twice, first without outlier # rejection as the model is too far from reality to do a sensible job of # outlier rejection refiner = self.Refine() refiner.set_experiments_filename(indexed_experiments) refiner.set_indexed_filename( reindex.get_reindexed_reflections_filename()) refiner.set_outlier_algorithm(None) refiner.run() indexed_experiments = refiner.get_refined_experiments_filename( ) # now again with outlier rejection (possibly) refiner = self.Refine() refiner.set_experiments_filename(indexed_experiments) refiner.set_indexed_filename(indexed_file) refiner.run() indexed_experiments = refiner.get_refined_experiments_filename( ) if self._indxr_input_lattice is None: # FIXME in here should respect the input unit cell and lattice if provided # FIXME from this (i) populate the helper table, # (ii) try to avoid re-running the indexing # step if we eliminate a solution as we have all of the refined results # already available. rbs = self.RefineBravaisSettings() rbs.set_experiments_filename(indexed_experiments) rbs.set_indexed_filename(indexed_file) if PhilIndex.params.dials.fix_geometry: rbs.set_detector_fix("all") rbs.set_beam_fix("all") FileHandler.record_log_file( "%s LATTICE" % self.get_indexer_full_name(), rbs.get_log_file()) rbs.run() from cctbx import crystal, sgtbx for k in sorted(rbs.get_bravais_summary()): summary = rbs.get_bravais_summary()[k] # FIXME need to do this better - for the moment only accept lattices # where R.M.S. deviation is less than twice P1 R.M.S. deviation. if self._indxr_input_lattice is None: if not summary["recommended"]: continue experiments = load.experiment_list(summary["experiments_file"], check_format=False) cryst = experiments.crystals()[0] cs = crystal.symmetry(unit_cell=cryst.get_unit_cell(), space_group=cryst.get_space_group()) cb_op_best_to_ref = cs.change_of_basis_op_to_reference_setting( ) cs_reference = cs.change_basis(cb_op_best_to_ref) lattice = str( bravais_types.bravais_lattice( group=cs_reference.space_group())) cb_op = cb_op_best_to_ref * sgtbx.change_of_basis_op( str(summary["cb_op"])) self._solutions[k] = { "number": k, "mosaic": 0.0, "metric": summary["max_angular_difference"], "rmsd": summary["rmsd"], "nspots": summary["nspots"], "lattice": lattice, "cell": cs_reference.unit_cell().parameters(), "experiments_file": summary["experiments_file"], "cb_op": str(cb_op), } self._solution = self.get_solution() self._indxr_lattice = self._solution["lattice"] for solution in self._solutions.keys(): lattice = self._solutions[solution]["lattice"] if (self._indxr_input_lattice is not None and self._indxr_input_lattice != lattice): continue if lattice in self._indxr_other_lattice_cell: if (self._indxr_other_lattice_cell[lattice]["metric"] < self._solutions[solution]["metric"]): continue self._indxr_other_lattice_cell[lattice] = { "metric": self._solutions[solution]["metric"], "cell": self._solutions[solution]["cell"], } self._indxr_mosaic = self._solution["mosaic"] experiment_list = load.experiment_list( self._solution["experiments_file"]) self.set_indexer_experiment_list(experiment_list) # reindex the output experiments list to the reference setting # (from the best cell/conventional setting) cb_op_to_ref = (experiment_list.crystals()[0].get_space_group(). info().change_of_basis_op_to_reference_setting()) reindex = self.Reindex() reindex.set_experiments_filename( self._solution["experiments_file"]) reindex.set_cb_op(cb_op_to_ref) reindex.set_space_group( str(lattice_to_spacegroup_number(self._solution["lattice"]))) reindex.run() experiments_file = reindex.get_reindexed_experiments_filename() experiment_list = load.experiment_list(experiments_file) self.set_indexer_experiment_list(experiment_list) self.set_indexer_payload("experiments_filename", experiments_file) # reindex the output reflection list to this solution reindex = self.Reindex() reindex.set_indexed_filename(indexed_file) reindex.set_cb_op(self._solution["cb_op"]) reindex.set_space_group( str(lattice_to_spacegroup_number(self._solution["lattice"]))) reindex.run() indexed_file = reindex.get_reindexed_reflections_filename() self.set_indexer_payload("indexed_filename", indexed_file) else: experiment_list = load.experiment_list(indexed_experiments) self.set_indexer_experiment_list(experiment_list) self.set_indexer_payload("experiments_filename", indexed_experiments) cryst = experiment_list.crystals()[0] lattice = str( bravais_types.bravais_lattice(group=cryst.get_space_group())) self._indxr_lattice = lattice self._solutions = {} self._solutions[0] = { "number": 0, "mosaic": 0.0, "metric": -1, "rmsd": -1, "nspots": -1, "lattice": lattice, "cell": cryst.get_unit_cell().parameters(), "experiments_file": indexed_experiments, "cb_op": "a,b,c", } self._indxr_other_lattice_cell[lattice] = { "metric": self._solutions[0]["metric"], "cell": self._solutions[0]["cell"], } return
def _f_ordered_solvent(self): fo = self._fo fc = fo.structure_factors_from_scatterers( xray_structure=self._structure).f_calc() self._fc = fc if (self.n_real is None): crystal_gridding = maptbx.crystal_gridding( unit_cell=self._structure.unit_cell(), step=self._grid_step) n_real = crystal_gridding.n_real() else: n_real = self.n_real xyzf = flex.vec3_double() atmrad = flex.double() elements = [] for scatterer in self._structure.scatterers(): xyzf.append(list(scatterer.site)) atmrad.append( van_der_waals_radii.vdw.table[scatterer.element_symbol()]) elements.append(scatterer.element_symbol()) assert xyzf.size() == atmrad.size() sel_flag = flex.int(xyzf.size(), 1) # XXX removed 2011-02-14: set sel_flag to zero if resname is HOH assert sel_flag.size() == atmrad.size() self._distribution = wat_dist() self._distribution.do_wat_dist(shell=0.0, xyzf=xyzf, atmrad=atmrad, element_symbol=elements, uc=self._structure.unit_cell(), sg=self._structure.space_group(), nxnynz=n_real, sel_flag=sel_flag, rad=self.rad, nshells=self.nshells) data = self._distribution.data() ############################### #mask_data = mask(0.0, # 1.0, # 1.0, # xyzf, # atmrad, # self._structure.unit_cell(), # self._structure.space_group(), # crystal_gridding.n_real()).data() # #data.set_selected(mask_data == 0.0, 0.0) ############################### map_of_coeff = map_of_coeff_scaled(data, self._structure, n_real) from_map = maptbx.structure_factors.from_map( space_group=self._structure.space_group_info().group(), anomalous_flag=False, miller_indices=fo.indices(), complex_map=map_of_coeff, conjugate_flag=True) self._f = miller.array(miller_set=miller.set( crystal_symmetry=crystal.symmetry( unit_cell=self._structure.unit_cell(), space_group_info=self._structure.space_group_info()), indices=fo.indices(), anomalous_flag=False), data=from_map.data()) assert fc.indices().all_eq(self._f.indices()) == 1 assert fc.indices().all_eq(fo.indices()) == 1 assert flex.max(abs(self._f).data()) < 1.0 return self
def DrawRings(self): frame = self.GetParent().GetParent() try: uc = symmetry(unit_cell=self._cell, space_group_symbol=str(self._spacegroup)) hkl_list = cctbx.miller.build_set(uc, False, d_min=self.d_min_ctrl.GetValue()) except Exception as e: frame.update_statusbar(e.message) return frame.update_statusbar("%d %d %d %d %d %d, " % tuple(self._cell) + "number of indices: %d" % len(hkl_list.indices())) spacings = list(hkl_list.d_spacings()) print("Printing spacings, len: %s" % len(spacings)) def cmp(a, b): if a[1] > b[1]: return 1 elif a[1] < b[1]: return -1 return 0 spacings = sorted(spacings, cmp=cmp, reverse=True) for d in spacings: print(d) detector = self._pyslip.tiles.raw_image.get_detector() wavelength = float(self.wavelength_ctrl.GetValue()) distance = float(self.distance_ctrl.GetValue()) pixel_size = detector[0].get_pixel_size( )[0] # FIXME assumes square pixels, and that all panels use same pixel size twotheta = hkl_list.two_theta(wavelength=wavelength) L_mm = [] L_pixels = [] for tt in twotheta: L_mm.append(distance * math.tan(tt[1])) for lmm in L_mm: L_pixels.append(lmm / pixel_size) xrayframe = self.GetParent().GetParent() panel_id, beam_pixel_fast, beam_pixel_slow = xrayframe.get_beam_center_px( ) if len(detector) > 1: beam_pixel_slow, beam_pixel_fast = xrayframe.pyslip.tiles.flex_image.tile_readout_to_picture( panel_id, beam_pixel_slow - 0.5, beam_pixel_fast - 0.5) center = self._pyslip.tiles.picture_fast_slow_to_map_relative( beam_pixel_fast + self._center[0], beam_pixel_slow + self._center[1]) # XXX Transparency? ring_data = [(center[0], center[1], { "colour": "red", "radius": pxl }) for pxl in L_pixels] # Remove the old ring layer, and draw a new one. if hasattr(self, "_ring_layer") and self._ring_layer is not None: self._pyslip.DeleteLayer(self._ring_layer) self._ring_layer = None self._ring_layer = self._pyslip.AddPointLayer( ring_data, map_rel=True, visible=True, show_levels=[-3, -2, -1, 0, 1, 2, 3, 4, 5], renderer=self._draw_rings_layer, name="<ring_layer>", )
def organize_input(self, observations_pickle, iparams, avg_mode, pickle_filename=None): """Given the pickle file, extract and prepare observations object and the alpha angle (meridional to equatorial). """ identified_isoform = None if iparams.isoform_name is not None: identified_isoform = iparams.isoform_name if "identified_isoform" not in observations_pickle: return None, "No identified isoform" else: identified_isoform = observations_pickle["identified_isoform"] if observations_pickle[ "identified_isoform"] != iparams.isoform_name: return None, "Identified isoform(%s) is not the requested isoform (%s)" % ( observations_pickle["identified_isoform"], iparams.isoform_name) if iparams.flag_weak_anomalous: if avg_mode == 'final': target_anomalous_flag = iparams.target_anomalous_flag else: target_anomalous_flag = False else: target_anomalous_flag = iparams.target_anomalous_flag img_filename_only = '' if pickle_filename is not None: pickle_filepaths = pickle_filename.split('/') img_filename_only = pickle_filepaths[len(pickle_filepaths) - 1] txt_exception = ' {0:40} ==> '.format(img_filename_only) observations = observations_pickle["observations"][0] detector_distance_mm = observations_pickle['distance'] mapped_predictions = observations_pickle['mapped_predictions'][0] #set observations with target space group - !!! required for correct #merging due to map_to_asu command. if iparams.target_crystal_system is not None: target_crystal_system = iparams.target_crystal_system else: target_crystal_system = observations.crystal_symmetry( ).space_group().crystal_system() lph = lbfgs_partiality_handler() if iparams.flag_override_unit_cell: uc_constrained_inp = lph.prep_input( iparams.target_unit_cell.parameters(), target_crystal_system) else: uc_constrained_inp = lph.prep_input( observations.unit_cell().parameters(), target_crystal_system) uc_constrained = list( lph.prep_output(uc_constrained_inp, target_crystal_system)) try: #apply constrain using the crystal system miller_set = symmetry(unit_cell=uc_constrained, space_group_symbol=iparams.target_space_group ).build_miller_set( anomalous_flag=target_anomalous_flag, d_min=iparams.merge.d_min) observations = observations.customized_copy( anomalous_flag=target_anomalous_flag, crystal_symmetry=miller_set.crystal_symmetry()) except Exception: a, b, c, alpha, beta, gamma = uc_constrained txt_exception += 'Mismatch spacegroup (%6.2f,%6.2f,%6.2f,%6.2f,%6.2f,%6.2f)' % ( a, b, c, alpha, beta, gamma) return None, txt_exception #reset systematic absence sys_absent_negate_flags = flex.bool([ sys_absent_flag[1] == False for sys_absent_flag in observations.sys_absent_flags() ]) observations = observations.select(sys_absent_negate_flags) mapped_predictions = mapped_predictions.select(sys_absent_negate_flags) import os.path #remove observations from rejection list if os.path.isfile(iparams.run_no + '/rejections.txt'): txt_out = pickle_filename + ' \nN_before_rejection: ' + str( len(observations.data())) + '\n' file_reject = open(iparams.run_no + '/rejections.txt', 'r') data_reject = file_reject.read().split("\n") miller_indices_ori_rejected = flex.miller_index() for row_reject in data_reject: col_reject = row_reject.split() if len(col_reject) > 0: if col_reject[0].strip() == pickle_filename: miller_indices_ori_rejected.append( (int(col_reject[1].strip()), int(col_reject[2].strip()), int(col_reject[3].strip()))) if len(miller_indices_ori_rejected) > 0: i_sel_flag = flex.bool([True] * len(observations.data())) for miller_index_ori_rejected in miller_indices_ori_rejected: i_index_ori = 0 for miller_index_ori in observations.indices(): if miller_index_ori_rejected == miller_index_ori: i_sel_flag[i_index_ori] = False txt_out += ' -Discard:' + str(miller_index_ori[0]) + \ ','+str(miller_index_ori[1])+','+str(miller_index_ori[2]) + '\n' i_index_ori += 1 observations = observations.customized_copy( indices=observations.indices().select(i_sel_flag), data=observations.data().select(i_sel_flag), sigmas=observations.sigmas().select(i_sel_flag)) mapped_predictions = mapped_predictions.select(i_sel_flag) txt_out += 'N_after_rejection: ' + str(len( observations.data())) + '\n' #filter resolution i_sel_res = observations.resolution_filter_selection( d_max=iparams.merge.d_max, d_min=iparams.merge.d_min) observations = observations.select(i_sel_res) mapped_predictions = mapped_predictions.select(i_sel_res) #Filter weak i_sel = (observations.data() / observations.sigmas()) > iparams.merge.sigma_min observations = observations.select(i_sel) mapped_predictions = mapped_predictions.select(i_sel) #filter icering (if on) #replacing sigI (if set) if iparams.flag_replace_sigI: observations = observations.customized_copy( sigmas=flex.sqrt(observations.data())) #setup spot predicton mm_predictions = iparams.pixel_size_mm * mapped_predictions xbeam = observations_pickle["xbeam"] ybeam = observations_pickle["ybeam"] alpha_angle_obs = flex.double([math.atan(abs(pred[0]-xbeam)/abs(pred[1]-ybeam)) \ for pred in mm_predictions]) spot_pred_x_mm = flex.double( [pred[0] - xbeam for pred in mm_predictions]) spot_pred_y_mm = flex.double( [pred[1] - ybeam for pred in mm_predictions]) #Polarization correction wavelength = observations_pickle["wavelength"] if iparams.flag_LP_correction: fx = 1 - iparams.polarization_horizontal_fraction fy = 1 - fx if fx > 1.0 or fx < 0: print 'Horizontal polarization fraction is not correct. The value must be >= 0 and <= 1' print 'No polarization correction. Continue with post-refinement' else: phi_angle_obs = flex.double([math.atan2(pred[1]-ybeam, pred[0]-xbeam) \ for pred in mm_predictions]) bragg_angle_obs = observations.two_theta(wavelength).data() P = ((fx*((flex.sin(phi_angle_obs)**2)+((flex.cos(phi_angle_obs)**2)*flex.cos(bragg_angle_obs)**2)))+\ (fy*((flex.cos(phi_angle_obs)**2)+((flex.sin(phi_angle_obs)**2)*flex.cos(bragg_angle_obs)**2)))) I_prime = observations.data() / P sigI_prime = observations.sigmas() / P observations = observations.customized_copy( data=flex.double(I_prime), sigmas=flex.double(sigI_prime)) inputs = observations, alpha_angle_obs, spot_pred_x_mm, spot_pred_y_mm, \ detector_distance_mm, identified_isoform, \ mapped_predictions, xbeam, ybeam return inputs, 'OK'
def refine_subgroup(args): assert len(args) == 5 from dials.command_line.check_indexing_symmetry import ( get_symop_correlation_coefficients, normalise_intensities, ) params, subgroup, used_reflections, experiments, refiner_verbosity = args used_reflections = copy.deepcopy(used_reflections) triclinic_miller = used_reflections["miller_index"] cb_op = subgroup["cb_op_inp_best"] higher_symmetry_miller = cb_op.apply(triclinic_miller) used_reflections["miller_index"] = higher_symmetry_miller unrefined_crystal = copy.deepcopy(subgroup.unrefined_crystal) for expt in experiments: expt.crystal = unrefined_crystal from dials.algorithms.indexing.refinement import refine subgroup.max_cc = None subgroup.min_cc = None subgroup.correlation_coefficients = [] subgroup.cc_nrefs = [] with LoggingContext(logging.getLogger(), level=logging.ERROR): try: iqr_multiplier = params.refinement.reflections.outlier.tukey.iqr_multiplier params.refinement.reflections.outlier.tukey.iqr_multiplier = ( 2 * iqr_multiplier) refinery, refined, outliers = refine(params, used_reflections, experiments, verbosity=refiner_verbosity) params.refinement.reflections.outlier.tukey.iqr_multiplier = iqr_multiplier refinery, refined, outliers = refine( params, used_reflections, refinery.get_experiments(), verbosity=refiner_verbosity, ) except RuntimeError as e: if (str(e) == "scitbx Error: g0 - astry*astry -astrz*astrz <= 0." or str(e) == "scitbx Error: g1-bstrz*bstrz <= 0."): subgroup.refined_experiments = None subgroup.rmsd = None subgroup.Nmatches = None else: raise else: dall = refinery.rmsds() dx = dall[0] dy = dall[1] subgroup.rmsd = math.sqrt(dx * dx + dy * dy) subgroup.Nmatches = len(refinery.get_matches()) subgroup.refined_experiments = refinery.get_experiments() assert len(subgroup.refined_experiments.crystals()) == 1 subgroup.refined_crystal = subgroup.refined_experiments.crystals( )[0] cs = crystal.symmetry( unit_cell=subgroup.refined_crystal.get_unit_cell(), space_group=subgroup.refined_crystal.get_space_group(), ) if "intensity.sum.value" in used_reflections: # remove refl with -ve variance sel = used_reflections["intensity.sum.variance"] > 0 good_reflections = used_reflections.select(sel) from cctbx import miller ms = miller.set(cs, good_reflections["miller_index"]) ms = ms.array( good_reflections["intensity.sum.value"] / flex.sqrt(good_reflections["intensity.sum.variance"])) if params.normalise: if params.normalise_bins: ms = normalise_intensities( ms, n_bins=params.normalise_bins) else: ms = normalise_intensities(ms) if params.cc_n_bins is not None: ms.setup_binner(n_bins=params.cc_n_bins) ccs, nrefs = get_symop_correlation_coefficients( ms, use_binning=(params.cc_n_bins is not None)) subgroup.correlation_coefficients = ccs subgroup.cc_nrefs = nrefs ccs = ccs.select(nrefs > 10) if len(ccs) > 1: subgroup.max_cc = flex.max(ccs[1:]) subgroup.min_cc = flex.min(ccs[1:]) return subgroup
def run(args): from dials.util.options import OptionParser import libtbx.load_env usage = "%s [options] find_spots.json" % (libtbx.env.dispatcher_name) parser = OptionParser(usage=usage, phil=phil_scope, epilog=help_message) params, options, args = parser.parse_args(show_diff_phil=True, return_unhandled=True) positions = None if params.positions is not None: with open(params.positions, 'rb') as f: positions = flex.vec2_double() for line in f.readlines(): line = line.replace('(', ' ').replace(')', '').replace( ',', ' ').strip().split() assert len(line) == 3 i, x, y = [float(l) for l in line] positions.append((x, y)) assert len(args) == 1 json_file = args[0] import json with open(json_file, 'rb') as f: results = json.load(f) n_indexed = flex.double() fraction_indexed = flex.double() n_spots = flex.double() n_lattices = flex.double() crystals = [] image_names = flex.std_string() for r in results: n_spots.append(r['n_spots_total']) image_names.append(str(r['image'])) if 'n_indexed' in r: n_indexed.append(r['n_indexed']) n_lattices.append(len(r['lattices'])) for d in r['lattices']: from dxtbx.serialize.crystal import from_dict crystals.append(from_dict(d['crystal'])) else: n_indexed.append(0) n_lattices.append(0) if n_indexed.size(): sel = n_spots > 0 fraction_indexed = flex.double(n_indexed.size(), 0) fraction_indexed.set_selected( sel, n_indexed.select(sel) / n_spots.select(sel)) import matplotlib matplotlib.use('Agg') from matplotlib import pyplot blue = '#3498db' red = '#e74c3c' marker = 'o' alpha = 0.5 lw = 0 plot = True table = True grid = params.grid from libtbx import group_args from dials.algorithms.spot_finding.per_image_analysis \ import plot_stats, print_table estimated_d_min = flex.double() d_min_distl_method_1 = flex.double() d_min_distl_method_2 = flex.double() n_spots_total = flex.int() n_spots_no_ice = flex.int() total_intensity = flex.double() for d in results: estimated_d_min.append(d['estimated_d_min']) d_min_distl_method_1.append(d['d_min_distl_method_1']) d_min_distl_method_2.append(d['d_min_distl_method_2']) n_spots_total.append(d['n_spots_total']) n_spots_no_ice.append(d['n_spots_no_ice']) total_intensity.append(d['total_intensity']) stats = group_args(image=image_names, n_spots_total=n_spots_total, n_spots_no_ice=n_spots_no_ice, n_spots_4A=None, n_indexed=n_indexed, fraction_indexed=fraction_indexed, total_intensity=total_intensity, estimated_d_min=estimated_d_min, d_min_distl_method_1=d_min_distl_method_1, d_min_distl_method_2=d_min_distl_method_2, noisiness_method_1=None, noisiness_method_2=None) if plot: plot_stats(stats) pyplot.clf() if table: print_table(stats) n_rows = 10 n_rows = min(n_rows, len(n_spots_total)) perm_n_spots_total = flex.sort_permutation(n_spots_total, reverse=True) print 'Top %i images sorted by number of spots:' % n_rows print_table(stats, perm=perm_n_spots_total, n_rows=n_rows) if flex.max(n_indexed) > 0: perm_n_indexed = flex.sort_permutation(n_indexed, reverse=True) print 'Top %i images sorted by number of indexed reflections:' % n_rows print_table(stats, perm=perm_n_indexed, n_rows=n_rows) print "Number of indexed lattices: ", (n_indexed > 0).count(True) print "Number with valid d_min but failed indexing: ", ( (d_min_distl_method_1 > 0) & (d_min_distl_method_2 > 0) & (estimated_d_min > 0) & (n_indexed == 0)).count(True) n_bins = 20 spot_count_histogram(n_spots_total, n_bins=n_bins, filename='hist_n_spots_total.png', log=True) spot_count_histogram(n_spots_no_ice, n_bins=n_bins, filename='hist_n_spots_no_ice.png', log=True) spot_count_histogram(n_indexed.select(n_indexed > 0), n_bins=n_bins, filename='hist_n_indexed.png', log=False) if len(crystals): plot_unit_cell_histograms(crystals) if params.stereographic_projections and len(crystals): from dxtbx.datablock import DataBlockFactory datablocks = DataBlockFactory.from_filenames([image_names[0]], verbose=False) assert len(datablocks) == 1 imageset = datablocks[0].extract_imagesets()[0] s0 = imageset.get_beam().get_s0() # XXX what if no goniometer? rotation_axis = imageset.get_goniometer().get_rotation_axis() indices = ((1, 0, 0), (0, 1, 0), (0, 0, 1)) for i, index in enumerate(indices): from cctbx import crystal, miller from scitbx import matrix miller_indices = flex.miller_index([index]) symmetry = crystal.symmetry( unit_cell=crystals[0].get_unit_cell(), space_group=crystals[0].get_space_group()) miller_set = miller.set(symmetry, miller_indices) d_spacings = miller_set.d_spacings() d_spacings = d_spacings.as_non_anomalous_array().expand_to_p1() d_spacings = d_spacings.generate_bijvoet_mates() miller_indices = d_spacings.indices() # plane normal d0 = matrix.col(s0).normalize() d1 = d0.cross(matrix.col(rotation_axis)).normalize() d2 = d1.cross(d0).normalize() reference_poles = (d0, d1, d2) from dials.command_line.stereographic_projection import stereographic_projection projections = [] for cryst in crystals: reciprocal_space_points = list( cryst.get_U() * cryst.get_B()) * miller_indices.as_vec3_double() projections.append( stereographic_projection(reciprocal_space_points, reference_poles)) #from dials.algorithms.indexing.compare_orientation_matrices import \ # difference_rotation_matrix_and_euler_angles #R_ij, euler_angles, cb_op = difference_rotation_matrix_and_euler_angles( # crystals[0], cryst) #print max(euler_angles) from dials.command_line.stereographic_projection import plot_projections plot_projections(projections, filename='projections_%s.png' % ('hkl'[i])) pyplot.clf() def plot_grid(values, grid, file_name, cmap=pyplot.cm.Reds, vmin=None, vmax=None, invalid='white'): values = values.as_double() # At DLS, fast direction appears to be largest direction if grid[0] > grid[1]: values.reshape(flex.grid(reversed(grid))) values = values.matrix_transpose() else: values.reshape(flex.grid(grid)) Z = values.as_numpy_array() #f, (ax1, ax2) = pyplot.subplots(2) f, ax1 = pyplot.subplots(1) mesh1 = ax1.pcolormesh(values.as_numpy_array(), cmap=cmap, vmin=vmin, vmax=vmax) mesh1.cmap.set_under(color=invalid, alpha=None) mesh1.cmap.set_over(color=invalid, alpha=None) #mesh2 = ax2.contour(Z, cmap=cmap, vmin=vmin, vmax=vmax) #mesh2 = ax2.contourf(Z, cmap=cmap, vmin=vmin, vmax=vmax) ax1.set_aspect('equal') ax1.invert_yaxis() #ax2.set_aspect('equal') #ax2.invert_yaxis() pyplot.colorbar(mesh1, ax=ax1) #pyplot.colorbar(mesh2, ax=ax2) pyplot.savefig(file_name, dpi=600) pyplot.clf() def plot_positions(values, positions, file_name, cmap=pyplot.cm.Reds, vmin=None, vmax=None, invalid='white'): values = values.as_double() assert positions.size() >= values.size() positions = positions[:values.size()] if vmin is None: vmin = flex.min(values) if vmax is None: vmax = flex.max(values) x, y = positions.parts() dx = flex.abs(x[1:] - x[:-1]) dy = flex.abs(y[1:] - y[:-1]) dx = dx.select(dx > 0) dy = dy.select(dy > 0) scale = 1 / flex.min(dx) #print scale x = (x * scale).iround() y = (y * scale).iround() from libtbx.math_utils import iceil z = flex.double( flex.grid(iceil(flex.max(y)) + 1, iceil(flex.max(x)) + 1), -2) #print z.all() for x_, y_, z_ in zip(x, y, values): z[y_, x_] = z_ plot_grid(z.as_1d(), z.all(), file_name, cmap=cmap, vmin=vmin, vmax=vmax, invalid=invalid) return if grid is not None or positions is not None: if grid is not None: positions = tuple(reversed(grid)) plotter = plot_grid else: plotter = plot_positions cmap = pyplot.get_cmap(params.cmap) plotter(n_spots_total, positions, 'grid_spot_count_total.png', cmap=cmap, invalid=params.invalid) plotter(n_spots_no_ice, positions, 'grid_spot_count_no_ice.png', cmap=cmap, invalid=params.invalid) plotter(total_intensity, positions, 'grid_total_intensity.png', cmap=cmap, invalid=params.invalid) if flex.max(n_indexed) > 0: plotter(n_indexed, positions, 'grid_n_indexed.png', cmap=cmap, invalid=params.invalid) plotter(fraction_indexed, positions, 'grid_fraction_indexed.png', cmap=cmap, vmin=0, vmax=1, invalid=params.invalid) for i, d_min in enumerate( (estimated_d_min, d_min_distl_method_1, d_min_distl_method_2)): from cctbx import uctbx d_star_sq = uctbx.d_as_d_star_sq(d_min) d_star_sq.set_selected(d_star_sq == 1, 0) vmin = flex.min(d_star_sq.select(d_star_sq > 0)) vmax = flex.max(d_star_sq) vmin = flex.min(d_min.select(d_min > 0)) vmax = flex.max(d_min) cmap = pyplot.get_cmap('%s_r' % params.cmap) d_min.set_selected(d_min <= 0, vmax) if i == 0: plotter(d_min, positions, 'grid_d_min.png', cmap=cmap, vmin=vmin, vmax=vmax, invalid=params.invalid) else: plotter(d_min, positions, 'grid_d_min_method_%i.png' % i, cmap=cmap, vmin=vmin, vmax=vmax, invalid=params.invalid) if flex.max(n_indexed) > 0: pyplot.hexbin(n_spots, n_indexed, bins='log', cmap=pyplot.cm.jet, gridsize=50) pyplot.colorbar() #pyplot.scatter(n_spots, n_indexed, marker=marker, alpha=alpha, c=blue, lw=lw) xlim = pyplot.xlim() ylim = pyplot.ylim() pyplot.plot([0, max(n_spots)], [0, max(n_spots)], c=red) pyplot.xlim(0, xlim[1]) pyplot.ylim(0, ylim[1]) pyplot.xlabel('# spots') pyplot.ylabel('# indexed') pyplot.savefig('n_spots_vs_n_indexed.png') pyplot.clf() pyplot.hexbin(n_spots, fraction_indexed, bins='log', cmap=pyplot.cm.jet, gridsize=50) pyplot.colorbar() #pyplot.scatter( #n_spots, fraction_indexed, marker=marker, alpha=alpha, c=blue, lw=lw) pyplot.xlim(0, pyplot.xlim()[1]) pyplot.ylim(0, pyplot.ylim()[1]) pyplot.xlabel('# spots') pyplot.ylabel('Fraction indexed') pyplot.savefig('n_spots_vs_fraction_indexed.png') pyplot.clf() pyplot.hexbin(n_indexed, fraction_indexed, bins='log', cmap=pyplot.cm.jet, gridsize=50) pyplot.colorbar() #pyplot.scatter( #n_indexed, fraction_indexed, marker=marker, alpha=alpha, c=blue, lw=lw) pyplot.xlim(0, pyplot.xlim()[1]) pyplot.ylim(0, pyplot.ylim()[1]) pyplot.xlabel('# indexed') pyplot.ylabel('Fraction indexed') pyplot.savefig('n_indexed_vs_fraction_indexed.png') pyplot.clf() pyplot.hexbin(n_spots, n_lattices, bins='log', cmap=pyplot.cm.jet, gridsize=50) pyplot.colorbar() #pyplot.scatter( #n_spots, n_lattices, marker=marker, alpha=alpha, c=blue, lw=lw) pyplot.xlim(0, pyplot.xlim()[1]) pyplot.ylim(0, pyplot.ylim()[1]) pyplot.xlabel('# spots') pyplot.ylabel('# lattices') pyplot.savefig('n_spots_vs_n_lattices.png') pyplot.clf() #pyplot.scatter( # estimated_d_min, d_min_distl_method_1, marker=marker, alpha=alpha, c=blue, lw=lw) pyplot.hexbin(estimated_d_min, d_min_distl_method_1, bins='log', cmap=pyplot.cm.jet, gridsize=50) pyplot.colorbar() #pyplot.gca().set_aspect('equal') xlim = pyplot.xlim() ylim = pyplot.ylim() m = max(max(estimated_d_min), max(d_min_distl_method_1)) pyplot.plot([0, m], [0, m], c=red) pyplot.xlim(0, xlim[1]) pyplot.ylim(0, ylim[1]) pyplot.xlabel('estimated_d_min') pyplot.ylabel('d_min_distl_method_1') pyplot.savefig('d_min_vs_distl_method_1.png') pyplot.clf() #pyplot.scatter( # estimated_d_min, d_min_distl_method_2, marker=marker, alpha=alpha, c=blue, lw=lw) pyplot.hexbin(estimated_d_min, d_min_distl_method_2, bins='log', cmap=pyplot.cm.jet, gridsize=50) pyplot.colorbar() #pyplot.gca().set_aspect('equal') xlim = pyplot.xlim() ylim = pyplot.ylim() m = max(max(estimated_d_min), max(d_min_distl_method_2)) pyplot.plot([0, m], [0, m], c=red) pyplot.xlim(0, xlim[1]) pyplot.ylim(0, ylim[1]) pyplot.xlabel('estimated_d_min') pyplot.ylabel('d_min_distl_method_2') pyplot.savefig('d_min_vs_distl_method_2.png') pyplot.clf() #pyplot.scatter( # d_min_distl_method_1, d_min_distl_method_2, marker=marker, alpha=alpha, c=blue, lw=lw) pyplot.hexbin(d_min_distl_method_1, d_min_distl_method_2, bins='log', cmap=pyplot.cm.jet, gridsize=50) pyplot.colorbar() #pyplot.gca().set_aspect('equal') xlim = pyplot.xlim() ylim = pyplot.ylim() m = max(max(d_min_distl_method_1), max(d_min_distl_method_2)) pyplot.plot([0, m], [0, m], c=red) pyplot.xlim(0, xlim[1]) pyplot.ylim(0, ylim[1]) pyplot.xlabel('d_min_distl_method_1') pyplot.ylabel('d_min_distl_method_2') pyplot.savefig('distl_method_1_vs_distl_method_2.png') pyplot.clf() pyplot.hexbin(n_spots, estimated_d_min, bins='log', cmap=pyplot.cm.jet, gridsize=50) pyplot.colorbar() #pyplot.scatter( #n_spots, estimated_d_min, marker=marker, alpha=alpha, c=blue, lw=lw) pyplot.xlim(0, pyplot.xlim()[1]) pyplot.ylim(0, pyplot.ylim()[1]) pyplot.xlabel('# spots') pyplot.ylabel('estimated_d_min') pyplot.savefig('n_spots_vs_d_min.png') pyplot.clf() pyplot.hexbin(n_spots, d_min_distl_method_1, bins='log', cmap=pyplot.cm.jet, gridsize=50) pyplot.colorbar() #pyplot.scatter( #n_spots, d_min_distl_method_1, marker=marker, alpha=alpha, c=blue, lw=lw) pyplot.xlim(0, pyplot.xlim()[1]) pyplot.ylim(0, pyplot.ylim()[1]) pyplot.xlabel('# spots') pyplot.ylabel('d_min_distl_method_1') pyplot.savefig('n_spots_vs_distl_method_1.png') pyplot.clf() pyplot.hexbin(n_spots, d_min_distl_method_2, bins='log', cmap=pyplot.cm.jet, gridsize=50) pyplot.colorbar() #pyplot.scatter( #n_spots, d_min_distl_method_2, marker=marker, alpha=alpha, c=blue, lw=lw) pyplot.xlim(0, pyplot.xlim()[1]) pyplot.ylim(0, pyplot.ylim()[1]) pyplot.xlabel('# spots') pyplot.ylabel('d_min_distl_method_2') pyplot.savefig('n_spots_vs_distl_method_2.png') pyplot.clf()
def find_matching_symmetry(unit_cell, target_space_group, max_delta=5): cs = crystal.symmetry(unit_cell=unit_cell, space_group=sgtbx.space_group()) target_bravais_t = bravais_types.bravais_lattice( group=target_space_group.info().reference_setting().group()) best_subgroup = None best_angular_difference = 1e8 # code based on cctbx/sgtbx/lattice_symmetry.py but optimised to only # look at subgroups with the correct bravais type input_symmetry = cs # Get cell reduction operator cb_op_inp_minimum = input_symmetry.change_of_basis_op_to_minimum_cell() # New symmetry object with changed basis minimum_symmetry = input_symmetry.change_basis(cb_op_inp_minimum) # Get highest symmetry compatible with lattice lattice_group = sgtbx.lattice_symmetry_group( minimum_symmetry.unit_cell(), max_delta=max_delta, enforce_max_delta_for_generated_two_folds=True, ) # Get list of sub-spacegroups subgrs = subgroups.subgroups(lattice_group.info()).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, reverse=True) for i_subgr in perm: acentric_subgroup = subgrs[i_subgr] acentric_supergroup = metric_supergroup(acentric_subgroup) # 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=minimum_symmetry.unit_cell(), space_group=acentric_subgroup, 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 bravais_t = bravais_types.bravais_lattice( group=ref_subsym.space_group()) if bravais_t != target_bravais_t: continue # Choose best setting for monoclinic and orthorhombic systems cb_op_best_cell = ref_subsym.change_of_basis_op_to_best_cell( best_monoclinic_beta=True) 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) cb_op_inp_minimum = change_of_basis_op(str(cb_op_inp_minimum), stop_chars="", r_den=144, t_den=144) cb_op_inp_best = cb_op_best_cell * cb_op_minimum_ref * cb_op_inp_minimum # Use identity change-of-basis operator if possible if best_subsym.unit_cell().is_similar_to(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 as 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 max_angular_difference = find_max_delta( reduced_cell=minimum_symmetry.unit_cell(), space_group=acentric_supergroup) if max_angular_difference < best_angular_difference: best_angular_difference = max_angular_difference best_subgroup = { "subsym": subsym, "ref_subsym": ref_subsym, "best_subsym": best_subsym, "cb_op_inp_best": cb_op_inp_best, "max_angular_difference": max_angular_difference, } if best_subgroup is not None: return best_subgroup
def __init__(self, xs_a, xs_b, max_delta=2.0, out=None, relative_length_tolerance=0.05, absolute_angle_tolerance=10.0, order=1): self.relative_length_tolerance = relative_length_tolerance self.absolute_angle_tolerance = absolute_angle_tolerance self.order=order self.max_delta=max_delta self.out = out if self.out is None: self.out = sys.stdout self.xs_a = xs_a self.xs_b = xs_b # Go to niggli cell self.xs_a_n = self.xs_a.niggli_cell() self.xs_b_n = self.xs_b.niggli_cell() if ( self.xs_a.niggli_cell().unit_cell().volume() > self.xs_b.niggli_cell().unit_cell().volume() ): self.xs_a = xs_b self.xs_b = xs_a # go to niggli cell please self.xs_a_n = self.xs_a.niggli_cell() self.xs_b_n = self.xs_b.niggli_cell() volume_ratio = self.xs_b_n.unit_cell().volume() / self.xs_a_n.unit_cell().volume() n_volume_ratio = math.floor( volume_ratio + 1 ) self.show_basic_info() self.basis_a = matrix.sqr( self.xs_a_n.unit_cell().orthogonalization_matrix() ) print >> self.out, "Cartesian basis (column) vectors of lego cell:" tmp_bas = self.basis_a.as_list_of_lists() print >> self.out, " / %5.1f %5.1f %5.1f \ " %(tmp_bas[0][0], tmp_bas[0][1], tmp_bas[0][2]) print >> self.out, " | %5.1f %5.1f %5.1f | " %(tmp_bas[1][0], tmp_bas[1][1], tmp_bas[1][2]) print >> self.out, " \ %5.1f %5.1f %5.1f / " %(tmp_bas[2][0], tmp_bas[2][1], tmp_bas[2][2]) print >> self.out self.basis_b = matrix.sqr( self.xs_b_n.unit_cell().orthogonalization_matrix() ) print >> self.out, "Cartesian basis (column) vectors of target cell:" tmp_bas = self.basis_b.as_list_of_lists() print >> self.out, " / %5.1f %5.1f %5.1f \ " %(tmp_bas[0][0], tmp_bas[0][1], tmp_bas[0][2]) print >> self.out, " | %5.1f %5.1f %5.1f | " %(tmp_bas[1][0], tmp_bas[1][1], tmp_bas[1][2]) print >> self.out, " \ %5.1f %5.1f %5.1f / " %(tmp_bas[2][0], tmp_bas[2][1], tmp_bas[2][2]) print >> self.out self.lattice_symm_a = sgtbx.lattice_symmetry.group( self.xs_a_n.unit_cell(),self.max_delta ) self.lattice_symm_b = sgtbx.lattice_symmetry.group( self.xs_b_n.unit_cell(),self.max_delta ) self.xs_ref = crystal.symmetry( unit_cell=self.xs_b_n.unit_cell(), space_group=self.lattice_symm_b, assert_is_compatible_unit_cell=False ) # make a list of matrices self.matrix_list = generate_matrix_up_to_order( n_volume_ratio, max(n_volume_ratio-1,1) ) self.uc_and_symm_list=[] self.possible_solutions = [] print >> self.out, "A total of %4i matrices in the hermite normal form have been generated."%( len( self.matrix_list ) ) print >> self.out, "The volume changes they cause lie between %4i and %4i."%(n_volume_ratio, max(n_volume_ratio-1,1)) count =0 print >> self.out print >> self.out, "Trying all matrices" print >> self.out print >> self.out, " 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0" print >> self.out, " ", for mat in self.matrix_list: count+=1 found_it=False tmp_xs = self.make_new_cell_and_symmetry( mat ) self.uc_and_symm_list.append( tmp_xs ) tmp_gen = self.xs_b_n.unit_cell().similarity_transformations( tmp_xs[2].unit_cell(), self.relative_length_tolerance, self.absolute_angle_tolerance, self.order) if tmp_gen.size()>0: found_it = True cb_op = sgtbx.change_of_basis_op(sgtbx.rt_mx( sgtbx.rot_mx(tmp_gen[0]))).inverse() tmp_sol = (mat,cb_op,tmp_xs[2].change_basis( cb_op ) , tmp_xs[3]) # matrix, corresponding cb_op, cell + lattice sym self.possible_solutions.append( tmp_sol ) #self.show_solution(tmp_sol) if found_it: print >> self.out, "*", self.out.flush() else: if count%10==0: print >> self.out, "|", self.out.flush() else: print >> self.out, ".", self.out.flush() if count%20==0: print >> self.out print >> self.out, " ", self.out.flush() print >> self.out print >> self.out, " Listing all possible solutions" count=0 if len(self.possible_solutions)==0: print >> out print >> out, "No relations found for this particular sublattice of the specified target cell." print >> out, " " print >> out for tmp_sol in self.possible_solutions: count+=1 print >> self.out print >> self.out, "Solution %4i"%(count) self.show_solution( tmp_sol )
def run(args): if len(args) == 0: master_params.show(expert_level=0) elif ("--help" in args): print("no help available") elif ("--h" in args): print("no help available") elif ("--show_defaults" in args): master_params.show(expert_level=0) elif ("--show_defaults_all" in args): master_params.show(expert_level=10) else: log = multi_out() if (not "--quiet" in args): log.register(label="stdout", file_object=sys.stdout) string_buffer = StringIO() string_buffer_plots = StringIO() log.register(label="log_buffer", file_object=string_buffer) log_plots = StringIO() print("#phil __OFF__", file=log) print(file=log) print(date_and_time(), file=log) print(file=log) print(file=log) phil_objects = [] argument_interpreter = master_params.command_line_argument_interpreter( home_scope="scaling") reflection_file = None for arg in args: command_line_params = None arg_is_processed = False if arg == '--quiet': arg_is_processed = True ## The associated action with this keyword is implemented above if (os.path.isfile(arg)): ## is this a file name? ## Check if this is a phil file try: command_line_params = iotbx.phil.parse(file_name=arg) except KeyboardInterrupt: raise except Exception: pass if command_line_params is not None: phil_objects.append(command_line_params) arg_is_processed = True ## Check if this file is a reflection file if command_line_params is None: reflection_file = reflection_file_reader.any_reflection_file( file_name=arg, ensure_read_access=False) if (reflection_file is not None): reflection_file = arg arg_is_processed = True ## If it is not a file, it must be a phil command else: try: command_line_params = argument_interpreter.process(arg=arg) if command_line_params is not None: phil_objects.append(command_line_params) arg_is_processed = True except KeyboardInterrupt: raise except Exception: pass if not arg_is_processed: print("##----------------------------------------------##", file=log) print("## Unknown phil-file or phil-command:", arg, file=log) print("##----------------------------------------------##", file=log) print(file=log) raise Sorry("Unknown file format or phil command: %s" % arg) effective_params = master_params.fetch(sources=phil_objects) params = effective_params.extract() ## Now please read in the reflections files ## get symmetry and cell data first please ## By default, the native cell and symmetry are used ## as reference crystal_symmetry_nat = None crystal_symmetry_nat = crystal_symmetry_from_any.extract_from( file_name=params.scaling.input.xray_data.after_burn.file_name) if params.scaling.input.xray_data.space_group is None: params.scaling.input.xray_data.space_group =\ crystal_symmetry_nat.space_group_info() print("Using symmetry of after_burn data", file=log) if params.scaling.input.xray_data.unit_cell is None: params.scaling.input.xray_data.unit_cell =\ crystal_symmetry_nat.unit_cell() print("Using cell of after_burn data", file=log) ## Check if a unit cell is defined if params.scaling.input.xray_data.space_group is None: raise Sorry("No space group defined") if params.scaling.input.xray_data.unit_cell is None: raise Sorry("No unit cell defined") crystal_symmetry = crystal_symmetry = crystal.symmetry( unit_cell=params.scaling.input.xray_data.unit_cell, space_group_symbol=str(params.scaling.input.xray_data.space_group)) effective_params = master_params.fetch(sources=phil_objects) new_params = master_params.format(python_object=params) print("Effective parameters", file=log) print("#phil __ON__", file=log) new_params.show(out=log, expert_level=params.scaling.input.expert_level) print("#phil __END__", file=log) print(file=log) ## define a xray data server xray_data_server = reflection_file_utils.reflection_file_server( crystal_symmetry=crystal_symmetry, force_symmetry=True, reflection_files=[]) ## Read in native data and make appropriatre selections miller_array_native = None miller_array_native = xray_data_server.get_xray_data( file_name=params.scaling.input.xray_data.after_burn.file_name, labels=params.scaling.input.xray_data.after_burn.labels, ignore_all_zeros=True, parameter_scope='scaling.input.SIR_scale.xray_data.after_burn') info_native = miller_array_native.info() miller_array_native = miller_array_native.map_to_asu().select( miller_array_native.indices() != (0, 0, 0)) miller_array_native = miller_array_native.select( miller_array_native.data() > 0) ## Convert to amplitudes if (miller_array_native.is_xray_intensity_array()): miller_array_native = miller_array_native.f_sq_as_f() elif (miller_array_native.is_complex_array()): miller_array_native = abs(miller_array_native) if not miller_array_native.is_real_array(): raise Sorry("miller_array_native is not a real array") miller_array_native.set_info(info=info_native) ## Read in derivative data and make appropriate selections miller_array_derivative = None miller_array_derivative = xray_data_server.get_xray_data( file_name=params.scaling.input.xray_data.before_burn.file_name, labels=params.scaling.input.xray_data.before_burn.labels, ignore_all_zeros=True, parameter_scope='scaling.input.SIR_scale.xray_data.before_burn') info_derivative = miller_array_derivative.info() miller_array_derivative = miller_array_derivative.map_to_asu().select( miller_array_derivative.indices() != (0, 0, 0)) miller_array_derivative = miller_array_derivative.select( miller_array_derivative.data() > 0) ## Convert to amplitudes if (miller_array_derivative.is_xray_intensity_array()): miller_array_derivative = miller_array_derivative.f_sq_as_f() elif (miller_array_derivative.is_complex_array()): miller_array_derivative = abs(miller_array_derivative) if not miller_array_derivative.is_real_array(): raise Sorry("miller_array_derivative is not a real array") miller_array_derivative.set_info(info=info_derivative) ## As this is a SIR case, we will remove any anomalous pairs if miller_array_derivative.anomalous_flag(): miller_array_derivative = miller_array_derivative.average_bijvoet_mates()\ .set_observation_type( miller_array_derivative ) if miller_array_native.anomalous_flag(): miller_array_native = miller_array_native.average_bijvoet_mates()\ .set_observation_type( miller_array_native ) ## Print info print(file=log) print("Native data", file=log) print("===========", file=log) miller_array_native.show_comprehensive_summary(f=log) print(file=log) native_pre_scale = pre_scale.pre_scaler( miller_array_native, params.scaling.input.scaling_strategy.pre_scaler_protocol, params.scaling.input.basic) miller_array_native = native_pre_scale.x1.deep_copy() del native_pre_scale print(file=log) print("Derivative data", file=log) print("===============", file=log) miller_array_derivative.show_comprehensive_summary(f=log) print(file=log) derivative_pre_scale = pre_scale.pre_scaler( miller_array_derivative, params.scaling.input.scaling_strategy.pre_scaler_protocol, params.scaling.input.basic) miller_array_derivative = derivative_pre_scale.x1.deep_copy() del derivative_pre_scale scaler = fa_estimation.combined_scaling( miller_array_native, miller_array_derivative, params.scaling.input.scaling_strategy.iso_protocol) miller_array_native = scaler.x1.deep_copy() miller_array_derivative = scaler.x2.deep_copy() del scaler print(file=log) print("Making delta f's", file=log) print("----------------", file=log) print(file=log) delta_gen = pair_analyses.delta_generator( miller_array_native, miller_array_derivative, params.scaling.input.scaling_strategy.iso_protocol.nsr_bias) print(file=log) print("writing mtz file", file=log) print("----------------", file=log) print(file=log) ## some assertions to make sure nothing went weerd assert miller_array_native.observation_type() is not None assert miller_array_derivative.observation_type() is not None assert delta_gen.abs_delta_f.observation_type() is not None ## Please write out the abs_delta_f array mtz_dataset = delta_gen.abs_delta_f.as_mtz_dataset( column_root_label='F' + params.scaling.input.output.outlabel) mtz_dataset.mtz_object().write( file_name=params.scaling.input.output.hklout)
def exercise(space_group_info, anomalous_flag, verbose): crystal_symmetry_ri = crystal.symmetry( unit_cell=space_group_info.any_compatible_unit_cell(volume=1000), space_group_info=space_group_info) \ .minimum_cell() \ .reflection_intensity_symmetry(anomalous_flag=anomalous_flag) # crystal_symmetry_p1 = crystal_symmetry_ri.cell_equivalent_p1() miller_set = miller.build_set(crystal_symmetry=crystal_symmetry_p1, anomalous_flag=anomalous_flag, d_min=1) miller_array_p1 = miller.array( miller_set=miller_set, data=flex.random_double(size=miller_set.indices().size())) assert miller_array_p1.map_to_asu().indices() \ .all_eq(miller_array_p1.indices()) # lattice_group = sgtbx.lattice_symmetry.group( crystal_symmetry_ri.unit_cell(), max_delta=0.1) miller_array_subs = [] miller_array_sub_as = [] miller_array_sub_bs = [] coset_decompositions = [] subgroups = sgtbx.subgroups.anomalous_reflection_intensity_primitive_cell( space_group=lattice_group) for subgroup in subgroups: subgroup_info = sgtbx.space_group_info(group=subgroup) miller_array_sub = miller_array_p1.customized_copy( space_group_info=subgroup_info) \ .merge_equivalents().array() miller_array_sub_a = miller_array_sub.customized_copy( data=flex.random_double(size=miller_array_sub.indices().size())) \ .expand_to_p1() \ .map_to_asu() miller_array_sub_b = miller_array_sub.customized_copy( data=flex.random_double(size=miller_array_sub.indices().size())) \ .expand_to_p1() \ .map_to_asu() miller_array_subs.append(miller_array_sub) miller_array_sub_as.append(miller_array_sub_a) miller_array_sub_bs.append(miller_array_sub_b) # for s in subgroup_info.group(): cb_op = sgtbx.change_of_basis_op(s) cb = miller_array_sub_a.change_basis(cb_op).map_to_asu() assert approx_equal( miller_array_sub_a.correlation(other=cb).coefficient(), 1) # coset_decomposition = sgtbx.cosets.left_decomposition_point_groups_only( g=lattice_group, h=subgroup_info.group()) coset_decompositions.append(coset_decomposition) # for partition in coset_decomposition.partitions: s = partition[0] expected_match = s.is_unit_mx() cb_op = sgtbx.change_of_basis_op(s) cb = miller_array_sub_a.change_basis(cb_op).map_to_asu() is_match = abs( miller_array_sub_a.correlation(other=cb).coefficient() - 1) < 1.e-6 assert is_match == expected_match for s in partition[1:]: cb_op = sgtbx.change_of_basis_op(s) cb = miller_array_sub_a.change_basis(cb_op).map_to_asu() assert approx_equal(cb.correlation(other=cb).coefficient(), 1) # blur_scale = 3 blurred_data = miller_array_sub_a.data() * blur_scale # set to False to compare data with itself (will lead to failures below) if (True): blurred_data += flex.random_double(size=blurred_data.size()) blurred_data /= blur_scale blurred_array = miller_array_sub_a.customized_copy(data=blurred_data) expected_correlation = "%.6f" % miller_array_sub_a.correlation( other=blurred_array).coefficient() if (verbose): print "blurred_array expected_correlation:", expected_correlation blurred_array_cb = blurred_array.change_basis( random.choice(list(subgroup_info.group())).as_xyz()).map_to_asu() self_ccs = {} for partition in coset_decomposition.partitions: cb_op = sgtbx.change_of_basis_op(partition[0]) cb = miller_array_sub_a.change_basis(cb_op).map_to_asu() cc = blurred_array_cb.correlation(other=cb).coefficient() key = "%.6f" % cc self_ccs.setdefault(key, []).append(str(partition[0])) assert expected_correlation in self_ccs repetitions = [len(v) for v in self_ccs.values()] failure = (max(repetitions) > 1) if (failure or verbose): print subgroup_info print "self_ccs ops:", self_ccs.values() if (failure): for cc, ops in self_ccs.items(): if (len(ops) > 1): print cc, ops for op in ops: ri = sgtbx.rt_mx(op).r().info() print " ", ri.type(), ri.sense(), ri.ev() raise RuntimeError("max(repetitions) > 1") # for i in xrange(len(coset_decompositions)): for j in xrange(len(coset_decompositions)): exercise_double_coset_decomposition( crystal_symmetry_ri, lattice_group, miller_array_subs, miller_array_sub_as, miller_array_sub_bs, coset_decompositions, i, j, verbose)
def create_trial(self, d_min=1.5, n_bins=10, **kwargs): # d_min and n_bins only used if isoforms are in this trial trial = Trial(self, d_min=d_min, **kwargs) if trial.target_phil_str is not None: from iotbx.phil import parse dispatcher = self.params.dispatcher if dispatcher == 'cxi.xtc_process': from spotfinder.applications.xfel import cxi_phil trial_params = cxi_phil.cxi_versioned_extract( ).persist.phil_scope.fetch(parse( trial.target_phil_str)).extract() isoforms = trial_params.isoforms else: from xfel.ui import load_phil_scope_from_dispatcher phil_scope = load_phil_scope_from_dispatcher( self.params.dispatcher) trial_params = phil_scope.fetch(parse( trial.target_phil_str)).extract() isoforms = trial_params.indexing.stills.isoforms if len(isoforms) > 0: for isoform in isoforms: print("Creating isoform", isoform.name) db_isoform = Isoform(self, name=isoform.name, trial_id=trial.id) a, b, c, alpha, beta, gamma = isoform.cell.parameters() cell = self.create_cell( cell_a=a, cell_b=b, cell_c=c, cell_alpha=alpha, cell_beta=beta, cell_gamma=gamma, lookup_symbol=isoform.lookup_symbol, isoform_id=db_isoform.id) from cctbx.crystal import symmetry cs = symmetry(unit_cell=isoform.cell, space_group_symbol=str( isoform.lookup_symbol)) mset = cs.build_miller_set(anomalous_flag=False, d_min=d_min) binner = mset.setup_binner(n_bins=n_bins) for i in binner.range_used(): d_max, d_min = binner.bin_d_range(i) Bin(self, number=i, d_min=d_min, d_max=d_max, total_hkl=binner.counts_complete()[i], cell_id=cell.id) elif dispatcher == 'cxi.xtc_process': pass # TODO: labelit target else: if trial_params.indexing.known_symmetry.unit_cell is not None and \ trial_params.indexing.known_symmetry.space_group is not None: print("Creating target cell") unit_cell = trial_params.indexing.known_symmetry.unit_cell symbol = str( trial_params.indexing.known_symmetry.space_group) a, b, c, alpha, beta, gamma = unit_cell.parameters() cell = self.create_cell(cell_a=a, cell_b=b, cell_c=c, cell_alpha=alpha, cell_beta=beta, cell_gamma=gamma, lookup_symbol=symbol, trial_id=trial.id) from cctbx.crystal import symmetry cs = symmetry(unit_cell=unit_cell, space_group_symbol=symbol) mset = cs.build_miller_set(anomalous_flag=False, d_min=d_min) binner = mset.setup_binner(n_bins=n_bins) for i in binner.range_used(): d_max, d_min = binner.bin_d_range(i) Bin(self, number=i, d_min=d_min, d_max=d_max, total_hkl=binner.counts_complete()[i], cell_id=cell.id) return trial
def prepare_output(self, results, iparams, avg_mode): if avg_mode == 'average': cc_thres = 0 else: cc_thres = iparams.frame_accept_min_cc std_filter = iparams.sigma_rejection if iparams.flag_weak_anomalous: if avg_mode == 'final': target_anomalous_flag = iparams.target_anomalous_flag else: target_anomalous_flag = False else: target_anomalous_flag = iparams.target_anomalous_flag pr_params_mean, pr_params_med, pr_params_std = self.calc_mean_postref_parameters( results) G_mean, B_mean, ry_mean, rz_mean, re_mean, r0_mean, voigt_nu_mean, rotx_mean, roty_mean, R_mean, R_xy_mean, SE_mean = pr_params_mean G_med, B_med, ry_med, rz_med, re_med, r0_med, voigt_nu_med, rotx_med, roty_med, R_med, R_xy_med, SE_med = pr_params_med G_std, B_std, ry_std, rz_std, re_std, r0_std, voigt_nu_std, rotx_std, roty_std, R_std, R_xy_std, SE_std = pr_params_std #prepare data for merging miller_indices_all = flex.miller_index() miller_indices_ori_all = flex.miller_index() I_all = flex.double() sigI_all = flex.double() G_all = flex.double() B_all = flex.double() p_all = flex.double() rx_all = flex.double() rs_all = flex.double() rh_all = flex.double() SE_all = flex.double() sin_sq_all = flex.double() wavelength_all = flex.double() detector_distance_set = flex.double() R_init_all = flex.double() R_final_all = flex.double() R_xy_init_all = flex.double() R_xy_final_all = flex.double() pickle_filename_all = flex.std_string() filtered_results = [] cn_good_frame, cn_bad_frame_SE, cn_bad_frame_uc, cn_bad_frame_cc, cn_bad_frame_G, cn_bad_frame_re = ( 0, 0, 0, 0, 0, 0) crystal_orientation_dict = {} for pres in results: if pres is not None: pickle_filepath = pres.pickle_filename.split('/') img_filename = pickle_filepath[len(pickle_filepath) - 1] flag_pres_ok = True #check SE, CC, UC, G, B, gamma_e if math.isnan(pres.G): flag_pres_ok = False if math.isnan(pres.SE) or np.isinf(pres.SE): flag_pres_ok = False if flag_pres_ok and SE_std > 0: if abs(pres.SE - SE_med) / SE_std > std_filter: flag_pres_ok = False cn_bad_frame_SE += 1 if flag_pres_ok and pres.CC_final < cc_thres: flag_pres_ok = False cn_bad_frame_cc += 1 if flag_pres_ok: if G_std > 0: if abs(pres.G - G_med) / G_std > std_filter: flag_pres_ok = False cn_bad_frame_G += 1 if flag_pres_ok: if re_std > 0: if abs(pres.re - re_med) / re_std > std_filter: flag_pres_ok = False cn_bad_frame_re += 1 if flag_pres_ok and not good_unit_cell( pres.uc_params, iparams, iparams.merge.uc_tolerance): flag_pres_ok = False cn_bad_frame_uc += 1 data_size = pres.observations.size() if flag_pres_ok: cn_good_frame += 1 filtered_results.append(pres) R_init_all.append(pres.R_init) R_final_all.append(pres.R_final) R_xy_init_all.append(pres.R_xy_init) R_xy_final_all.append(pres.R_xy_final) miller_indices_all.extend(pres.observations.indices()) miller_indices_ori_all.extend( pres.observations_original.indices()) I_all.extend(pres.observations.data()) sigI_all.extend(pres.observations.sigmas()) G_all.extend(flex.double([pres.G] * data_size)) B_all.extend(flex.double([pres.B] * data_size)) p_all.extend(pres.partiality) rs_all.extend(pres.rs_set) rh_all.extend(pres.rh_set) sin_sq_all.extend( pres.observations.two_theta(wavelength=pres.wavelength) .sin_theta_over_lambda_sq().data()) SE_all.extend(flex.double([pres.SE] * data_size)) wavelength_all.extend( flex.double([pres.wavelength] * data_size)) detector_distance_set.append(pres.detector_distance_mm) pickle_filename_all.extend( flex.std_string([pres.pickle_filename] * data_size)) crystal_orientation_dict[ pres.pickle_filename] = pres.crystal_orientation #plot stats self.plot_stats(filtered_results, iparams) #write out updated crystal orientation as a pickle file if not iparams.flag_hush: pickle.dump(crystal_orientation_dict, open(iparams.run_no + '/' + "crystal.o", "wb"), pickle.HIGHEST_PROTOCOL) #calculate average unit cell uc_mean, uc_med, uc_std = self.calc_mean_unit_cell(filtered_results) unit_cell_mean = unit_cell(tuple(uc_mean)) #recalculate stats for pr parameters pr_params_mean, pr_params_med, pr_params_std = self.calc_mean_postref_parameters( filtered_results) G_mean, B_mean, ry_mean, rz_mean, re_mean, r0_mean, voigt_nu_mean, rotx_mean, roty_mean, R_mean, R_xy_mean, SE_mean = pr_params_mean G_med, B_med, ry_med, rz_med, re_med, r0_med, voigt_nu_med, rotx_med, roty_med, R_med, R_xy_med, SE_med = pr_params_med G_std, B_std, ry_std, rz_std, re_std, r0_std, voigt_nu_std, rotx_std, roty_std, R_std, R_xy_std, SE_std = pr_params_std #from all observations merge them crystal_symmetry = crystal.symmetry( unit_cell=tuple(uc_mean), space_group_symbol=iparams.target_space_group) miller_set_all = miller.set(crystal_symmetry=crystal_symmetry, indices=miller_indices_all, anomalous_flag=target_anomalous_flag) miller_array_all = miller_set_all.array( data=I_all, sigmas=sigI_all).set_observation_type_xray_intensity() #sort reflections according to asymmetric-unit symmetry hkl perm = miller_array_all.sort_permutation(by_value="packed_indices") miller_indices_all_sort = miller_array_all.indices().select(perm) miller_indices_ori_all_sort = miller_indices_ori_all.select(perm) I_obs_all_sort = miller_array_all.data().select(perm) sigI_obs_all_sort = miller_array_all.sigmas().select(perm) G_all_sort = G_all.select(perm) B_all_sort = B_all.select(perm) p_all_sort = p_all.select(perm) rs_all_sort = rs_all.select(perm) wavelength_all_sort = wavelength_all.select(perm) sin_sq_all_sort = sin_sq_all.select(perm) SE_all_sort = SE_all.select(perm) pickle_filename_all_sort = pickle_filename_all.select(perm) miller_array_uniq = miller_array_all.merge_equivalents().array( ).complete_array(d_min=iparams.merge.d_min, d_max=iparams.merge.d_max) matches_uniq = miller.match_multi_indices( miller_indices_unique=miller_array_uniq.indices(), miller_indices=miller_indices_all_sort) pair_0 = flex.int([pair[0] for pair in matches_uniq.pairs()]) pair_1 = flex.int([pair[1] for pair in matches_uniq.pairs()]) group_id_list = flex.int( [pair_0[pair_1[i]] for i in range(len(matches_uniq.pairs()))]) tally = Counter() for elem in group_id_list: tally[elem] += 1 cn_group = len(tally) #preparte txt out stat txt_out = 'Summary of refinement and merging\n' txt_out += ' No. good frames: %12.0f\n' % (cn_good_frame) txt_out += ' No. bad cc frames: %12.0f\n' % (cn_bad_frame_cc) txt_out += ' No. bad G frames) : %12.0f\n' % (cn_bad_frame_G) txt_out += ' No. bad unit cell frames: %12.0f\n' % (cn_bad_frame_uc) txt_out += ' No. bad gamma_e frames: %12.0f\n' % (cn_bad_frame_re) txt_out += ' No. bad SE: %12.0f\n' % (cn_bad_frame_SE) txt_out += ' No. observations: %12.0f\n' % ( len(I_obs_all_sort)) txt_out += 'Mean target value (BEFORE: Mean Median (Std.))\n' txt_out += ' post-refinement: %12.2f %12.2f (%9.2f)\n' % ( np.mean(R_init_all), np.median(R_init_all), np.std(R_init_all)) txt_out += ' (x,y) restraints: %12.2f %12.2f (%9.2f)\n' % ( np.mean(R_xy_init_all), np.median(R_xy_init_all), np.std(R_xy_init_all)) txt_out += 'Mean target value (AFTER: Mean Median (Std.))\n' txt_out += ' post-refinement: %12.2f %12.2f (%9.2f)\n' % ( np.mean(R_final_all), np.median(R_final_all), np.std(R_final_all)) txt_out += ' (x,y) restraints: %12.2f %12.2f (%9.2f)\n' % ( np.mean(R_xy_final_all), np.median(R_xy_final_all), np.std(R_xy_final_all)) txt_out += ' SE: %12.2f %12.2f (%9.2f)\n' % ( SE_mean, SE_med, SE_std) txt_out += ' G: %12.3e %12.3e (%9.2e)\n' % ( G_mean, G_med, G_std) txt_out += ' B: %12.2f %12.2f (%9.2f)\n' % ( B_mean, B_med, B_std) txt_out += ' Rot.x: %12.2f %12.2f (%9.2f)\n' % ( rotx_mean * 180 / math.pi, rotx_med * 180 / math.pi, rotx_std * 180 / math.pi) txt_out += ' Rot.y: %12.2f %12.2f (%9.2f)\n' % ( roty_mean * 180 / math.pi, roty_med * 180 / math.pi, roty_std * 180 / math.pi) txt_out += ' gamma_y: %12.5f %12.5f (%9.5f)\n' % ( ry_mean, ry_med, ry_std) txt_out += ' gamma_z: %12.5f %12.5f (%9.5f)\n' % ( rz_mean, rz_med, rz_std) txt_out += ' gamma_0: %12.5f %12.5f (%9.5f)\n' % ( r0_mean, r0_med, r0_std) txt_out += ' gamma_e: %12.5f %12.5f (%9.5f)\n' % ( re_mean, re_med, re_std) txt_out += ' voigt_nu: %12.5f %12.5f (%9.5f)\n' % ( voigt_nu_mean, voigt_nu_med, voigt_nu_std) txt_out += ' unit cell\n' txt_out += ' a: %12.2f %12.2f (%9.2f)\n' % ( uc_mean[0], uc_med[0], uc_std[0]) txt_out += ' b: %12.2f %12.2f (%9.2f)\n' % ( uc_mean[1], uc_med[1], uc_std[1]) txt_out += ' c: %12.2f %12.2f (%9.2f)\n' % ( uc_mean[2], uc_med[2], uc_std[2]) txt_out += ' alpha: %12.2f %12.2f (%9.2f)\n' % ( uc_mean[3], uc_med[3], uc_std[3]) txt_out += ' beta: %12.2f %12.2f (%9.2f)\n' % ( uc_mean[4], uc_med[4], uc_std[4]) txt_out += ' gamma: %12.2f %12.2f (%9.2f)\n' % ( uc_mean[5], uc_med[5], uc_std[5]) txt_out += 'Parmeters from integration (not-refined)\n' txt_out += ' Wavelength: %12.5f %12.5f (%9.5f)\n' % ( np.mean(wavelength_all), np.median(wavelength_all), np.std(wavelength_all)) txt_out += ' Detector distance: %12.5f %12.5f (%9.5f)\n' % ( np.mean(detector_distance_set), np.median(detector_distance_set), np.std(detector_distance_set)) txt_out += '* (standard deviation)\n' #write out stat. pickle if not iparams.flag_hush: stat_dict = {"n_frames_good": [cn_good_frame], \ "n_frames_bad_cc": [cn_bad_frame_cc], \ "n_frames_bad_G": [cn_bad_frame_G], \ "n_frames_bad_uc": [cn_bad_frame_uc], \ "n_frames_bad_gamma_e": [cn_bad_frame_re], \ "n_frames_bad_SE": [cn_bad_frame_SE], \ "n_observations": [len(I_obs_all_sort)], \ "R_start": [np.mean(R_init_all)], \ "R_end": [np.mean(R_final_all)], \ "R_xy_start": [np.mean(R_xy_init_all)], \ "R_xy_end": [np.mean(R_xy_final_all)], \ "mean_gamma_y": [ry_mean], \ "std_gamma_y": [ry_std], \ "mean_gamma_z": [rz_mean], \ "std_gamma_z": [rz_std], \ "mean_gamma_0": [r0_mean], \ "std_gamma_0": [r0_std], \ "mean_gamma_e": [re_mean], \ "std_gamma_e": [re_std], \ "mean_voigt_nu": [voigt_nu_mean], \ "std_voigt_nu": [voigt_nu_std], \ "mean_a": [uc_mean[0]], \ "std_a": [uc_std[0]], \ "mean_b": [uc_mean[1]], \ "std_b": [uc_std[1]], \ "mean_c": [uc_mean[2]], \ "std_c": [uc_std[2]], \ "mean_alpha": [uc_mean[3]], \ "std_alpha": [uc_std[3]], \ "mean_beta": [uc_mean[4]], \ "std_beta": [uc_std[4]], \ "mean_gamma": [uc_mean[5]], \ "std_gamma": [uc_std[5]]} self.write_stat_pickle(iparams, stat_dict) return cn_group, group_id_list, miller_indices_all_sort, miller_indices_ori_all_sort, \ I_obs_all_sort, sigI_obs_all_sort,G_all_sort, B_all_sort, \ p_all_sort, rs_all_sort, wavelength_all_sort, sin_sq_all_sort, SE_all_sort, uc_mean, \ np.mean(wavelength_all), pickle_filename_all_sort, txt_out
from __future__ import division from cctbx import xray from cctbx import crystal from cctbx import miller from cctbx.development import random_structure indices = miller.build_set(crystal_symmetry=crystal.symmetry( unit_cell=(10, 11, 12, 90, 105, 90), space_group_symbol="P21/c"), anomalous_flag=False, d_min=0.8) structure = random_structure.xray_structure(indices.space_group_info(), elements=['C'] * 6 + ['O'] * 2 + ['N'], volume_per_atom=18.6, random_u_iso=True) f_ideal = structure.structure_factors(d_min=indices.d_min()).f_calc() f_obs = f_ideal.amplitudes() f_obs *= 2 f_obs.set_observation_type_xray_amplitude() f_obs_square = f_ideal.norm() f_obs_square *= 3 f_obs_square.set_observation_type_xray_intensity() ls_against_f = xray.unified_least_squares_residual(f_obs) ls_against_f_square = xray.unified_least_squares_residual(f_obs_square) residuals = ls_against_f(f_ideal, compute_derivatives=True) print "against F: value=%.3f, scale=%.3f" % (residuals.target(), residuals.scale_factor()) residuals = ls_against_f_square(f_ideal, compute_derivatives=True)
def write(self, experiments, reflections): """ Write the experiments and reflections to file """ # if mmcif filename is auto, then choose scaled.cif or integrated.cif if self.params.mmcif.hklout in (None, Auto, "auto"): if ("intensity.scale.value" in reflections) and ("intensity.scale.variance" in reflections): filename = "scaled.cif" logger.info( "Data appears to be scaled, setting mmcif.hklout = 'scaled.cif'" ) else: filename = "integrated.cif" logger.info( "Data appears to be unscaled, setting mmcif.hklout = 'integrated.cif'" ) else: filename = self.params.mmcif.hklout # Select reflections selection = reflections.get_flags(reflections.flags.integrated, all=True) reflections = reflections.select(selection) # Filter out bad variances and other issues, but don't filter on ice rings # or alter partialities. # Assumes you want to apply the lp and dqe corrections to sum and prf # Do we want to combine partials? reflections = filter_reflection_table( reflections, self.params.intensity, combine_partials=False, partiality_threshold=0.0, d_min=self.params.mtz.d_min, ) # Get the cif block cif_block = iotbx.cif.model.block() # Audit trail dials_version = dials.util.version.dials_version() cif_block["_audit.creation_method"] = dials_version cif_block["_audit.creation_date"] = datetime.date.today().isoformat() cif_block["_computing.data_reduction"] = ( "%s (Winter, G. et al., 2018)" % dials_version) cif_block[ "_publ.section_references"] = "Winter, G. et al. (2018) Acta Cryst. D74, 85-97." # Hard coding X-ray cif_block["_pdbx_diffrn_data_section.id"] = "dials" cif_block["_pdbx_diffrn_data_section.type_scattering"] = "x-ray" cif_block["_pdbx_diffrn_data_section.type_merged"] = "false" cif_block["_pdbx_diffrn_data_section.type_scaled"] = str( "scale" in self.params.intensity).lower() # FIXME finish metadata addition - detector and source details needed # http://mmcif.wwpdb.org/dictionaries/mmcif_pdbx_v50.dic/Categories/index.html # Add source information; # _diffrn_source.pdbx_wavelength_list = (list of wavelengths) # _diffrn_source.source = (general class of source e.g. synchrotron) # _diffrn_source.type = (specific beamline or instrument e.g DIAMOND BEAMLINE I04) wls = [] epochs = [] for exp in experiments: wls.append(round(exp.beam.get_wavelength(), 5)) epochs.append(exp.scan.get_epochs()[0]) unique_wls = set(wls) cif_block["_diffrn_source.pdbx_wavelength_list"] = ", ".join( str(w) for w in unique_wls) # Add detector information; # _diffrn_detector.detector = (general class e.g. PIXEL, PLATE etc) # _diffrn_detector.pdbx_collection_date = (Date of collection yyyy-mm-dd) # _diffrn_detector.type = (full name of detector e.g. DECTRIS PILATUS3 2M) # One date is required, so if multiple just use the first date. min_epoch = min(epochs) date_str = time.strftime("%Y-%m-%d", time.gmtime(min_epoch)) cif_block["_diffrn_detector.pdbx_collection_date"] = date_str # Write the crystal information cif_loop = iotbx.cif.model.loop(header=( "_pdbx_diffrn_unmerged_cell.ordinal", "_pdbx_diffrn_unmerged_cell.crystal_id", "_pdbx_diffrn_unmerged_cell.wavelength", "_pdbx_diffrn_unmerged_cell.cell_length_a", "_pdbx_diffrn_unmerged_cell.cell_length_b", "_pdbx_diffrn_unmerged_cell.cell_length_c", "_pdbx_diffrn_unmerged_cell.cell_angle_alpha", "_pdbx_diffrn_unmerged_cell.cell_angle_beta", "_pdbx_diffrn_unmerged_cell.cell_angle_gamma", "_pdbx_diffrn_unmerged_cell.Bravais_lattice", )) crystals = experiments.crystals() crystal_to_id = {crystal: i + 1 for i, crystal in enumerate(crystals)} for i, exp in enumerate(experiments): crystal = exp.crystal crystal_id = crystal_to_id[crystal] wavelength = exp.beam.get_wavelength() a, b, c, alpha, beta, gamma = crystal.get_unit_cell().parameters() latt_type = str( bravais_types.bravais_lattice(group=crystal.get_space_group())) cif_loop.add_row((i + 1, crystal_id, wavelength, a, b, c, alpha, beta, gamma, latt_type)) cif_block.add_loop(cif_loop) # Write the scan information cif_loop = iotbx.cif.model.loop(header=( "_pdbx_diffrn_scan.scan_id", "_pdbx_diffrn_scan.crystal_id", "_pdbx_diffrn_scan.image_id_begin", "_pdbx_diffrn_scan.image_id_end", "_pdbx_diffrn_scan.scan_angle_begin", "_pdbx_diffrn_scan.scan_angle_end", )) for i, exp in enumerate(experiments): scan = exp.scan crystal_id = crystal_to_id[exp.crystal] image_range = scan.get_image_range() osc_range = scan.get_oscillation_range(deg=True) cif_loop.add_row(( i + 1, crystal_id, image_range[0], image_range[1], osc_range[0], osc_range[1], )) cif_block.add_loop(cif_loop) # Make a dict of unit_cell parameters unit_cell_parameters = {} if crystal.num_scan_points > 1: for i in range(crystal.num_scan_points): a, b, c, alpha, beta, gamma = crystal.get_unit_cell_at_scan_point( i).parameters() unit_cell_parameters[i] = (a, b, c, alpha, beta, gamma) else: unit_cell_parameters[0] = (a, b, c, alpha, beta, gamma) ### _pdbx_diffrn_image_proc has been removed from the dictionary extension. ### Keeping this section commented out as it may be added back in some ### form in future # # Write the image data # scan = experiments[0].scan # z0 = scan.get_image_range()[0] # # cif_loop = iotbx.cif.model.loop( # header=("_pdbx_diffrn_image_proc.image_id", # "_pdbx_diffrn_image_proc.crystal_id", # "_pdbx_diffrn_image_proc.image_number", # "_pdbx_diffrn_image_proc.phi_value", # "_pdbx_diffrn_image_proc.wavelength", # "_pdbx_diffrn_image_proc.cell_length_a", # "_pdbx_diffrn_image_proc.cell_length_b", # "_pdbx_diffrn_image_proc.cell_length_c", # "_pdbx_diffrn_image_proc.cell_angle_alpha", # "_pdbx_diffrn_image_proc.cell_angle_beta", # "_pdbx_diffrn_image_proc.cell_angle_gamma")) # for i in range(len(scan)): # z = z0 + i # if crystal.num_scan_points > 1: # a, b, c, alpha, beta, gamma = unit_cell_parameters[i] # else: # a, b, c, alpha, beta, gamma = unit_cell_parameters[0] # # phi is the angle at the image centre # phi = scan.get_angle_from_image_index(z + 0.5, deg=True) # cif_loop.add_row((i+1, 1, z, phi, wavelength, # a, b, c, alpha, beta, gamma)) # cif_block.add_loop(cif_loop) # Write reflection data # Required columns header = ( "_pdbx_diffrn_unmerged_refln.reflection_id", "_pdbx_diffrn_unmerged_refln.scan_id", "_pdbx_diffrn_unmerged_refln.image_id_begin", "_pdbx_diffrn_unmerged_refln.image_id_end", "_pdbx_diffrn_unmerged_refln.index_h", "_pdbx_diffrn_unmerged_refln.index_k", "_pdbx_diffrn_unmerged_refln.index_l", ) headernames = { "scales": "_pdbx_diffrn_unmerged_refln.scale_value", "intensity.scale.value": "_pdbx_diffrn_unmerged_refln.intensity_meas", "intensity.scale.sigma": "_pdbx_diffrn_unmerged_refln.intensity_sigma", "intensity.sum.value": "_pdbx_diffrn_unmerged_refln.intensity_sum", "intensity.sum.sigma": "_pdbx_diffrn_unmerged_refln.intensity_sum_sigma", "intensity.prf.value": "_pdbx_diffrn_unmerged_refln.intensity_prf", "intensity.prf.sigma": "_pdbx_diffrn_unmerged_refln.intensity_prf_sigma", "angle": "_pdbx_diffrn_unmerged_refln.scan_angle_reflection", "partiality": "_pdbx_diffrn_unmerged_refln.partiality", } variables_present = [] if "scale" in self.params.intensity: reflections["scales"] = 1.0 / reflections["inverse_scale_factor"] reflections["intensity.scale.sigma"] = flex.sqrt( reflections["intensity.scale.variance"]) variables_present.extend( ["scales", "intensity.scale.value", "intensity.scale.sigma"]) if "sum" in self.params.intensity: reflections["intensity.sum.sigma"] = flex.sqrt( reflections["intensity.sum.variance"]) variables_present.extend( ["intensity.sum.value", "intensity.sum.sigma"]) if "profile" in self.params.intensity: reflections["intensity.prf.sigma"] = flex.sqrt( reflections["intensity.prf.variance"]) variables_present.extend( ["intensity.prf.value", "intensity.prf.sigma"]) # Should always exist reflections["angle"] = reflections["xyzcal.mm"].parts()[2] * RAD2DEG variables_present.extend(["angle"]) if "partiality" in reflections: variables_present.extend(["partiality"]) for name in variables_present: if name in reflections: header += (headernames[name], ) if "scale" in self.params.intensity: # Write dataset_statistics - first make a miller array crystal_symmetry = cctbxcrystal.symmetry( space_group=experiments[0].crystal.get_space_group(), unit_cell=experiments[0].crystal.get_unit_cell(), ) miller_set = miller.set( crystal_symmetry=crystal_symmetry, indices=reflections["miller_index"], anomalous_flag=False, ) i_obs = miller.array(miller_set, data=reflections["intensity.scale.value"]) i_obs.set_observation_type_xray_intensity() i_obs.set_sigmas(reflections["intensity.scale.sigma"]) i_obs.set_info( miller.array_info(source="DIALS", source_type="reflection_tables")) result = dataset_statistics( i_obs=i_obs, crystal_symmetry=crystal_symmetry, use_internal_variance=False, eliminate_sys_absent=False, ) cif_block.update(result.as_cif_block()) cif_loop = iotbx.cif.model.loop(header=header) for i, r in enumerate(reflections.rows()): refl_id = i + 1 scan_id = r["id"] + 1 _, _, _, _, z0, z1 = r["bbox"] h, k, l = r["miller_index"] variable_values = tuple((r[name]) for name in variables_present) cif_loop.add_row((refl_id, scan_id, z0, z1, h, k, l) + variable_values) cif_block.add_loop(cif_loop) # Add the block self._cif["dials"] = cif_block # Print to file with open(filename, "w") as fh: self._cif.show(out=fh) # Log logger.info("Wrote reflections to %s" % filename)
def unit_cell_analysis(self): """ Calls unit cell analysis module, which uses hierarchical clustering (Zeldin, et al, Acta D, 2015) to split integration results according to detected morphological groupings (if any). Most useful with preliminary integration without target unit cell specified. """ # Will not run clustering if only one integration result found or if turned off if not self.info.categories['integrated']: util.main_log(self.info.logfile, "\n\n{:-^80}\n".format(' UNIT CELL ANALYSIS '), True) util.main_log(self.info.logfile, '\n UNIT CELL CANNOT BE DETERMINED!', True) elif len(self.info.categories['integrated']) == 1: unit_cell = (self.info.cluster_iterable[0][:5]) point_group = self.info.cluster_iterable[0][6] util.main_log(self.info.logfile, "\n\n{:-^80}\n".format(' UNIT CELL ANALYSIS '), True) uc_line = "{:<6} {:^4}: {:<6.2f}, {:<6.2f}, {:<6.2f}, {:<6.2f}, " \ "{:<6.2f}, {:<6.2f}".format('(1)', point_group, unit_cell[0], unit_cell[1], unit_cell[2], unit_cell[3], unit_cell[4], unit_cell[5]) util.main_log(self.info.logfile, uc_line, True) self.info.best_pg = str(point_group) self.info.best_uc = unit_cell else: uc_table = [] uc_summary = [] if self.params.analysis.clustering.flag_on: # run hierarchical clustering analysis from xfel.clustering.cluster import Cluster counter = 0 self.info.clusters = [] threshold = self.params.analysis.clustering.threshold cluster_limit = self.params.analysis.clustering.limit final_pickles = self.info.categories['integrated'][0] pickles = [] if self.params.analysis.clustering.n_images > 0: import random for i in range( len(self.params.analysis.clustering.n_images)): random_number = random.randrange(0, len(final_pickles)) if final_pickles[random_number] in pickles: while final_pickles[random_number] in pickles: random_number = random.randrange( 0, len(final_pickles)) pickles.append(final_pickles[random_number]) else: pickles = final_pickles # Cluster from files (slow, but will keep for now) ucs = Cluster.from_files(pickle_list=pickles) # Do clustering clusters, _ = ucs.ab_cluster(threshold=threshold, log=False, write_file_lists=False, schnell=False, doplot=False) uc_table.append("\n\n{:-^80}\n" \ "".format(' UNIT CELL ANALYSIS ')) # extract clustering info and add to summary output list if cluster_limit is None: if len(pickles) / 10 >= 10: cluster_limit = 10 else: cluster_limit = len(pickles) / 10 for cluster in clusters: sorted_pg_comp = sorted(cluster.pg_composition.items(), key=lambda x: -1 * x[1]) pg_nums = [pg[1] for pg in sorted_pg_comp] cons_pg = sorted_pg_comp[np.argmax(pg_nums)] if len(cluster.members) > cluster_limit: counter += 1 # Write to file cluster_filenames = [j.path for j in cluster.members] if self.params.analysis.clustering.write_files: output_file = os.path.join( self.info.int_base, "uc_cluster_{}.lst".format(counter)) for fn in cluster_filenames: with open(output_file, 'a') as scf: scf.write('{}\n'.format(fn)) mark_output = os.path.basename(output_file) else: mark_output = '*' output_file = None else: mark_output = '' output_file = None # Populate clustering info for GUI display uc_init = uctbx.unit_cell(cluster.medians) symmetry = crystal.symmetry(unit_cell=uc_init, space_group_symbol='P1') groups = metric_subgroups(input_symmetry=symmetry, max_delta=3) top_group = groups.result_groups[0] best_sg = str(groups.lattice_group_info()).split('(')[0] best_uc = top_group['best_subsym'].unit_cell().parameters() # best_sg = str(top_group['best_subsym'].space_group_info()) uc_no_stdev = "{:<6.2f} {:<6.2f} {:<6.2f} " \ "{:<6.2f} {:<6.2f} {:<6.2f} " \ "".format(best_uc[0], best_uc[1], best_uc[2], best_uc[3], best_uc[4], best_uc[5]) cluster_info = { 'number': len(cluster.members), 'pg': best_sg, 'uc': uc_no_stdev, 'filename': mark_output } self.info.clusters.append(cluster_info) # format and record output # TODO: How to propagate stdevs after conversion from Niggli? # uc_line = "{:<6} {:^4}: {:<6.2f} ({:>5.2f}), {:<6.2f} ({:>5.2f}), "\ # "{:<6.2f} ({:>5.2f}), {:<6.2f} ({:>5.2f}), "\ # "{:<6.2f} ({:>5.2f}), {:<6.2f} ({:>5.2f}) "\ # "{}".format('({})'.format(len(cluster.members)), cons_pg[0], # cluster.medians[0], cluster.stdevs[0], # cluster.medians[1], cluster.stdevs[1], # cluster.medians[2], cluster.stdevs[2], # cluster.medians[3], cluster.stdevs[3], # cluster.medians[4], cluster.stdevs[4], # cluster.medians[5], cluster.stdevs[5], # mark_output) # uc_table.append(uc_line) uc_table.append("{:<6}: {} {}".format( len(cluster.members), uc_no_stdev, mark_output)) lattices = ', '.join( ['{} ({})'.format(i[0], i[1]) for i in sorted_pg_comp]) # uc_info = [len(cluster.members), cons_pg[0], cluster.medians, # output_file, uc_line, lattices] uc_info = [ len(cluster.members), best_sg, best_uc, output_file, uc_no_stdev, lattices ] uc_summary.append(uc_info) else: # generate average unit cell uc_table.append("\n\n{:-^80}\n" \ "".format(' UNIT CELL AVERAGING (no clustering) ')) uc_a, uc_b, uc_c, uc_alpha, \ uc_beta, uc_gamma, uc_sg = list(zip(*self.info.cluster_iterable)) cons_pg = Counter(uc_sg).most_common(1)[0][0] all_pgs = Counter(uc_sg).most_common() unit_cell = (np.median(uc_a), np.median(uc_b), np.median(uc_c), np.median(uc_alpha), np.median(uc_beta), np.median(uc_gamma)) # Populate clustering info for GUI display uc_init = uctbx.unit_cell(unit_cell) symmetry = crystal.symmetry(unit_cell=uc_init, space_group_symbol='P1') groups = metric_subgroups(input_symmetry=symmetry, max_delta=3) top_group = groups.result_groups[0] best_sg = str(groups.lattice_group_info()).split('(')[0] best_uc = top_group['best_subsym'].unit_cell().parameters() # best_sg = str(top_group['best_subsym'].space_group_info()) uc_no_stdev = "{:<6.2f} {:<6.2f} {:<6.2f} " \ "{:<6.2f} {:<6.2f} {:<6.2f} " \ "".format(best_uc[0], best_uc[1], best_uc[2], best_uc[3], best_uc[4], best_uc[5]) cluster_info = { 'number': len(self.info.cluster_iterable), 'pg': best_sg, 'uc': uc_no_stdev, 'filename': None } self.info.clusters.append(cluster_info) # uc_line = "{:<6} {:^4}: {:<6.2f} ({:>5.2f}), {:<6.2f} ({:>5.2f}), " \ # "{:<6.2f} ({:>5.2f}), {:<6.2f} ({:>5.2f}), " \ # "{:<6.2f} ({:>5.2f}), {:<6.2f} ({:>5.2f}) " \ # "{}".format('({})'.format(len(self.final_objects)), cons_pg, # np.median(uc_a), np.std(uc_a), # np.median(uc_b), np.std(uc_b), # np.median(uc_c), np.std(uc_c), # np.median(uc_alpha), np.std(uc_alpha), # np.median(uc_beta), np.std(uc_beta), # np.median(uc_gamma), np.std(uc_gamma), '') # # uc_table.append(uc_line) uc_table.append(uc_no_stdev) lattices = ', '.join( ['{} ({})'.format(i[0], i[1]) for i in all_pgs]) # uc_info = [len(self.final_objects), cons_pg, unit_cell, None, # uc_line, lattices] uc_info = [ len(self.info.cluster_iterable), best_sg, best_uc, None, uc_no_stdev, lattices ] uc_summary.append(uc_info) uc_table.append('\nMost common unit cell:\n') # select the most prevalent unit cell (most members in cluster) uc_freqs = [i[0] for i in uc_summary] uc_pick = uc_summary[np.argmax(uc_freqs)] uc_table.append(uc_pick[4]) uc_table.append('\nBravais Lattices in Biggest Cluster: {}' ''.format(uc_pick[5])) self.info.best_pg = str(uc_pick[1]) self.info.best_uc = uc_pick[2] if uc_pick[3] is not None: self.prime_data_path = uc_pick[3] for item in uc_table: util.main_log(self.info.logfile, item, False) self.info.update(uc_table=uc_table) if self.gui_mode: return self.info.clusters
def find_basis_vectors(self, reciprocal_lattice_vectors): """Find a list of likely basis vectors. Args: reciprocal_lattice_vectors (scitbx.array_family.flex.vec3_double): The list of reciprocal lattice vectors to search for periodicity. Returns: A tuple containing the list of basis vectors and a flex.bool array identifying which reflections were used in indexing. """ if self._params.reciprocal_space_grid.d_min is libtbx.Auto: # rough calculation of suitable d_min based on max cell # see also Campbell, J. (1998). J. Appl. Cryst., 31(3), 407-413. # fft_cell should be greater than twice max_cell, so say: # fft_cell = 2.5 * max_cell # then: # fft_cell = n_points * d_min/2 # 2.5 * max_cell = n_points * d_min/2 # a little bit of rearrangement: # d_min = 5 * max_cell/n_points max_cell = self._max_cell d_min = 5 * max_cell / self._n_points d_spacings = 1 / reciprocal_lattice_vectors.norms() d_min = max(d_min, min(d_spacings)) logger.info("Setting d_min: %.2f", d_min) else: d_min = self._params.reciprocal_space_grid.d_min grid_real, used_in_indexing = self._fft(reciprocal_lattice_vectors, d_min) self.sites, self.volumes = self._find_peaks(grid_real, d_min) # hijack the xray.structure class to facilitate calculation of distances self.crystal_symmetry = crystal.symmetry(unit_cell=self._fft_cell, space_group_symbol="P1") xs = xray.structure(crystal_symmetry=self.crystal_symmetry) for i, site in enumerate(self.sites): xs.add_scatterer(xray.scatterer("C%i" % i, site=site)) xs = xs.sites_mod_short() sites_cart = xs.sites_cart() lengths = flex.double([matrix.col(sc).length() for sc in sites_cart]) perm = flex.sort_permutation(lengths) xs = xs.select(perm) volumes = self.volumes.select(perm) vectors = xs.sites_cart() norms = vectors.norms() sel = (norms > self._min_cell) & (norms < (2 * self._max_cell)) vectors = vectors.select(sel) vectors = [matrix.col(v) for v in vectors] volumes = volumes.select(sel) vector_groups = group_vectors(vectors, volumes) vectors = [g.mean for g in vector_groups] volumes = flex.double(max(g.weights) for g in vector_groups) # sort by peak size perm = flex.sort_permutation(volumes, reverse=True) volumes = volumes.select(perm) vectors = [vectors[i] for i in perm] for i, (v, volume) in enumerate(zip(vectors, volumes)): logger.debug(f"{i} {v.length()} {volume}") # sort by length lengths = flex.double(v.length() for v in vectors) perm = flex.sort_permutation(lengths) # exclude vectors that are (approximately) integer multiples of a shorter # vector unique_vectors = [] unique_volumes = flex.double() for p in perm: v = vectors[p] is_unique = True for i, v_u in enumerate(unique_vectors): if (unique_volumes[i] > volumes[p] ) and is_approximate_integer_multiple(v_u, v): logger.debug("rejecting %s: integer multiple of %s", v.length(), v_u.length()) is_unique = False break if is_unique: unique_vectors.append(v) unique_volumes.append(volumes[p]) # re-sort by peak volume perm = flex.sort_permutation(unique_volumes, reverse=True) self.candidate_basis_vectors = [unique_vectors[i] for i in perm] return self.candidate_basis_vectors, used_in_indexing
def make_prime_input(self, filename='prime.phil', run_zero=False): """ Imports default PRIME input parameters, modifies correct entries and prints out a starting PHIL file to be used with PRIME """ assert self.info pixel_size = self.info.pixel_size hres = self.info.stats['res'] lres = self.info.stats['lres'] # If symmetry / unit cell were not overridden from GUI, set from INFO if not self.best_pg: try: self.best_pg = self.info.best_pg.replace(" ", '') except AttributeError as e: print('PRIME INPUT ERROR, SPACE GROUP: ', e) self.best_pg = 'P1' if not self.best_uc: self.best_uc = self.info.best_uc # Determine crystal system from crystal symmetry sym = crystal.symmetry(space_group_symbol=self.best_pg) crystal_system = str(sym.space_group().crystal_system()) # Determine number of images for indexing ambiguity resolution # My default: 1/2 of images or 300, whichever is smaller if len(self.info.categories['integrated']) >= 600: idx_ambiguity_sample = 300 idx_ambiguity_selected = 100 else: idx_ambiguity_sample = int( round(len(self.info.categories['integrated']) / 2)) idx_ambiguity_selected = int(round(idx_ambiguity_sample / 3)) # Set run number to 000 if running LivePRIME out_dir = os.path.join(os.path.dirname(self.prime_data_path), 'prime') if run_zero: run_path = os.path.join(out_dir, '000') else: run_path = util.set_base_dir(out_dir=out_dir) # Populate pertinent data parameters prime_params = mod_input.master_phil.extract() prime_params.run_no = run_path prime_params.data = [self.prime_data_path] prime_params.title = 'Auto-generated by IOTA v{} on {}' \ ''.format(iota_version, now) prime_params.scale.d_min = hres['mean'] prime_params.scale.d_max = 8 prime_params.postref.scale.d_min = hres['mean'] prime_params.postref.scale.d_max = lres['max'] prime_params.postref.crystal_orientation.d_min = hres['mean'] prime_params.postref.crystal_orientation.d_max = lres['max'] prime_params.postref.reflecting_range.d_min = hres['mean'] prime_params.postref.reflecting_range.d_max = lres['max'] prime_params.postref.unit_cell.d_min = hres['mean'] prime_params.postref.unit_cell.d_max = lres['max'] prime_params.postref.allparams.d_min = hres['mean'] prime_params.postref.allparams.d_max = lres['max'] prime_params.merge.d_min = hres['mean'] prime_params.merge.d_max = lres['max'] prime_params.target_unit_cell = uctbx.unit_cell(self.best_uc) prime_params.target_space_group = self.best_pg prime_params.target_crystal_system = crystal_system prime_params.pixel_size_mm = pixel_size prime_params.n_residues = 500 prime_params.indexing_ambiguity.n_sample_frames = idx_ambiguity_sample prime_params.indexing_ambiguity.n_selected_frames = idx_ambiguity_selected # Determine which queue to run on (i.e. match IOTA queue) # Modify specific options based in IOTA settings # Queue options if (self.params.mp.method == 'lsf' and self.params.mp.queue is not None): prime_params.queue.mode = 'bsub' prime_params.queue.qname = self.params.mp.queue # Number of processors (automatically, 1/2 of IOTA procs) prime_params.n_processors = int(self.params.mp.n_processors / 2) # Generate PRIME param PHIL prime_phil = mod_input.master_phil.format(python_object=prime_params) prime_file = os.path.join(self.info.int_base, filename) with open(prime_file, 'w') as pf: pf.write(prime_phil.as_str()) return prime_phil
def combine_pre_merge(self, result, iparams): mi_all = flex.miller_index() mio_all = flex.miller_index() I_all = flex.double() sigI_all = flex.double() G_all = flex.double() B_all = flex.double() p_all = flex.double() rs_all = flex.double() wavelength_all = flex.double() sin_all = flex.double() SE_all = flex.double() uc_mean_set = [] wavelength_mean_set = [] pickle_filename_all = flex.std_string() for res in result: for prep_output in res: _, _, mi, mio, I, sigI, G, B, p, rs, wavelength, sin, SE, uc_mean, wavelength_mean, pickle_filename_set, txt_out = prep_output mi_all.extend(mi) mio_all.extend(mio) I_all.extend(I) sigI_all.extend(sigI) G_all.extend(G) B_all.extend(B) p_all.extend(p) rs_all.extend(rs) wavelength_all.extend(wavelength) sin_all.extend(sin) SE_all.extend(SE) uc_mean_set.extend(uc_mean) wavelength_mean_set.append(wavelength_mean) pickle_filename_all.extend(pickle_filename_set) uc_mean = np.mean(np.array(uc_mean_set).reshape(-1, 6), axis=0) wavelength_mean = np.mean(wavelength_mean_set) ms_template = crystal.symmetry( unit_cell=tuple(uc_mean), space_group_symbol=iparams.target_space_group).build_miller_set( anomalous_flag=iparams.target_anomalous_flag, d_min=iparams.merge.d_min) ma_all = ms_template.array().customized_copy(indices=mi_all, data=I_all, sigmas=sigI_all) #sort reflections according to asymmetric-unit symmetry hkl perm = ma_all.sort_permutation(by_value="packed_indices") mi_all_sort = mi_all.select(perm) mio_all_sort = mio_all.select(perm) I_all_sort = I_all.select(perm) sigI_all_sort = sigI_all.select(perm) G_all_sort = G_all.select(perm) B_all_sort = B_all.select(perm) p_all_sort = p_all.select(perm) rs_all_sort = rs_all.select(perm) wavelength_all_sort = wavelength_all.select(perm) sin_all_sort = sin_all.select(perm) SE_all_sort = SE_all.select(perm) pickle_filename_all_sort = pickle_filename_all.select(perm) ma_uniq = ma_all.merge_equivalents().array().complete_array( d_min=iparams.merge.d_min, d_max=iparams.merge.d_max) matches_uniq = miller.match_multi_indices( miller_indices_unique=ma_uniq.indices(), miller_indices=mi_all_sort) pair_0 = flex.int([pair[0] for pair in matches_uniq.pairs()]) pair_1 = flex.int([pair[1] for pair in matches_uniq.pairs()]) group_id_list = flex.int( [pair_0[pair_1[i]] for i in range(len(matches_uniq.pairs()))]) tally = Counter() for elem in group_id_list: tally[elem] += 1 cn_group = len(tally) return cn_group, group_id_list, mi_all_sort, mio_all_sort, \ I_all_sort, sigI_all_sort, G_all_sort, B_all_sort, \ p_all_sort, rs_all_sort, wavelength_all_sort, sin_all_sort, SE_all_sort, uc_mean, \ wavelength_mean, pickle_filename_all_sort, ""
def run(args, command_name="phenix.twin_map_utils"): log=sys.stdout params=None if (len(args) == 0 or "--help" in args or "--h" in args or "-h" in args): print_help(command_name=command_name) else: log = multi_out() if (not "--quiet" in args): log.register(label="stdout", file_object=sys.stdout) string_buffer = StringIO() string_buffer_plots = StringIO() log.register(label="log_buffer", file_object=string_buffer) phil_objects = [] argument_interpreter = master_params.command_line_argument_interpreter( home_scope="map_coefs") for arg in args: command_line_params = None arg_is_processed = False # is it a file? if (os.path.isfile(arg)): ## is this a file name? # check if it is a phil file try: command_line_params = iotbx.phil.parse(file_name=arg) if command_line_params is not None: phil_objects.append(command_line_params) arg_is_processed = True except KeyboardInterrupt: raise except Exception : pass else: try: command_line_params = argument_interpreter.process(arg=arg) if command_line_params is not None: phil_objects.append(command_line_params) arg_is_processed = True except KeyboardInterrupt: raise except Exception : pass if not arg_is_processed: print("##----------------------------------------------##", file=log) print("## Unknown file or keyword:", arg, file=log) print("##----------------------------------------------##", file=log) print(file=log) raise Sorry("Unknown file or keyword: %s" % arg) effective_params = master_params.fetch(sources=phil_objects) params = effective_params.extract() """ new_params = master_params.format(python_object=params) new_params.show(out=log) """ # now get the unit cell from the pdb file hkl_xs = crystal_symmetry_from_any.extract_from( file_name=params.twin_utils.input.xray_data.file_name) pdb_xs = crystal_symmetry_from_any.extract_from( file_name=params.twin_utils.input.model.file_name) phil_xs=None if ([params.twin_utils.input.unit_cell, params.twin_utils.input.space_group]).count(None)<2: phil_xs = crystal.symmetry( unit_cell=params.twin_utils.input.unit_cell, space_group_info=params.twin_utils.input.space_group ) combined_xs = crystal.select_crystal_symmetry( None,phil_xs, [pdb_xs],[hkl_xs]) # inject the unit cell and symmetry in the phil scope please params.twin_utils.input.unit_cell = combined_xs.unit_cell() params.twin_utils.input.space_group = \ sgtbx.space_group_info( group = combined_xs.space_group() ) new_params = master_params.format(python_object=params) new_params.show(out=log) if params.twin_utils.input.unit_cell is None: raise Sorry("unit cell not specified") if params.twin_utils.input.space_group is None: raise Sorry("space group not specified") if params.twin_utils.input.xray_data.file_name is None: raise Sorry("Xray data not specified") if params.twin_utils.input.model.file_name is None: raise Sorry("pdb file with model not specified") #----------------------------------------------------------- # # step 1: read in the reflection file # phil_xs = crystal.symmetry( unit_cell=params.twin_utils.input.unit_cell, space_group_info=params.twin_utils.input.space_group ) xray_data_server = reflection_file_utils.reflection_file_server( crystal_symmetry = phil_xs, force_symmetry = True, reflection_files=[]) miller_array = None free_flags = None tmp_params = extract_xtal_data.data_and_flags_master_params().extract() # insert proper values please tmp_params.file_name = params.twin_utils.input.xray_data.file_name tmp_params.labels = params.twin_utils.input.xray_data.obs_labels tmp_params.r_free_flags.file_name=params.twin_utils.input.xray_data.file_name tmp_params.r_free_flags.label=params.twin_utils.input.xray_data.free_flag tmp_object = extract_xtal_data.run( reflection_file_server = xray_data_server) miller_array = tmp_object.extract_data() if miller_array.is_xray_intensity_array(): miller_array = miller_array.f_sq_as_f() assert miller_array.is_xray_amplitude_array() free_flags = tmp_object.extract_flags(data = miller_array) print(file=log) print("Attempting to extract Free R flags", file=log) free_flags = free_flags.customized_copy( data = flex.bool( free_flags.data()==1 ) ) if free_flags is None: free_flags = miller_array.generate_r_free_flags(use_lattice_symmetry=True) assert miller_array.observation_type() is not None print(file=log) print("Summary info of observed data", file=log) print("=============================", file=log) miller_array.show_summary(f=log) print(file=log) if miller_array.indices().size() == 0: raise Sorry("No data available") #---------------------------------------------------------------- # Step 2: get an xray structure from the PDB file # model = pdb.input(file_name=params.twin_utils.input.model.file_name).xray_structure_simple( crystal_symmetry=phil_xs) print("Atomic model summary", file=log) print("====================", file=log) model.show_summary(f=log) print(file=log) #---------------------------------------------------------------- # step 3: get the twin laws for this xs twin_laws = twin_analyses.twin_laws( miller_array, lattice_symmetry_max_delta=\ params.twin_utils.parameters.twinning.max_delta, out=log) print(file=log) print("Preliminary data analyses", file=log) print("==========================", file=log) twin_laws.show(out=log) #--------- # step 3: # make twin model managers for all twin laws print(file=log) print("Overall and bulk solvent scale paranmeters and twin fraction estimation", file=log) print("=======================================================================", file=log) twin_models = [] operator_count = 0 if params.twin_utils.parameters.twinning.twin_law is not None: tmp_law = sgtbx.rt_mx( params.twin_utils.parameters.twinning.twin_law ) tmp_law = twin_analyses.twin_law(tmp_law,None,None,None,None,None) twin_laws.operators = [ tmp_law ] for twin_law in twin_laws.operators: operator_count += 1 operator_hkl = sgtbx.change_of_basis_op( twin_law.operator ).as_hkl() twin_model = twin_f_model.twin_model_manager( f_obs=miller_array, r_free_flags = free_flags, xray_structure=model, twin_law = twin_law.operator, detwin_mode = params.twin_utils.parameters.twinning.detwin_mode, out=log) print("--- bulk solvent scaling ---", file=log) twin_model.update_all_scales() twin_model.r_values() twin_model.target() twin_model.show_k_sol_b_sol_b_cart_target() twin_model.show_essential() wfofc = twin_model.map_coefficients(map_type="mFo-DFc" ) wtfofc = twin_model.map_coefficients(map_type="2mFo-DFc" ) grad = twin_model.map_coefficients(map_type="gradient" ) mtz_dataset = wtfofc.as_mtz_dataset( column_root_label="FWT") mtz_dataset = mtz_dataset.add_miller_array( miller_array = wfofc, column_root_label = "DFWT" ) mtz_dataset = mtz_dataset.add_miller_array( miller_array = grad, column_root_label = "GRAD" ) name = params.twin_utils.output.map_coeffs_root+"_"+str(operator_count)+".mtz" print(file=log) print("Writing %s for twin law %s"%(name,operator_hkl), file=log) print(file=log) mtz_dataset.mtz_object().write( file_name=name) if params.twin_utils.output.obs_and_calc is not None: # i want also a Fobs and Fmodel combined dataset please mtz_dataset = miller_array.as_mtz_dataset( column_root_label="FOBS") mtz_dataset = mtz_dataset.add_miller_array( miller_array = twin_model.f_model(), column_root_label="FMODEL") name = params.twin_utils.output.obs_and_calc mtz_dataset.mtz_object().write( file_name=name) if len(twin_laws.operators)==0: print(file=log) print("No twin laws were found", file=log) print("Performing maximum likelihood based bulk solvent scaling", file=log) f_model_object = f_model.manager( f_obs = miller_array, r_free_flags = free_flags, xray_structure = model ) f_model_object.update_all_scales(log=log) tfofc = f_model_object.map_coefficients(map_type="2mFobs-DFmodel") fofc = f_model_object.map_coefficients(map_type="mFobs-DFmodel") mtz_dataset = tfofc.as_mtz_dataset( column_root_label="FWT") mtz_dataset = mtz_dataset.add_miller_array( miller_array = fofc, column_root_label = "DELFWT" ) name = params.twin_utils.output.map_coeffs_root+"_ML.mtz" mtz_dataset.mtz_object().write( file_name=name) if params.twin_utils.output.obs_and_calc is not None: # i want also a Fobs and Fmodel combined dataset please mtz_dataset = miller_array.as_mtz_dataset( column_root_label="FOBS") mtz_dataset = mtz_dataset.add_miller_array( miller_array = f_model_object.f_model(), column_root_label="FMODEL") name = params.twin_utils.output.obs_and_calc mtz_dataset.mtz_object().write( file_name=name) print(file=log) print(file=log) print("All done \n", file=log) logfile = open(params.twin_utils.output.logfile,'w') print(string_buffer.getvalue(), file=logfile) print(file=log)
def write_output(self, mdh, iparams, output_mtz_file_prefix, avg_mode): if iparams.flag_weak_anomalous: if avg_mode == 'final': target_anomalous_flag = iparams.target_anomalous_flag else: target_anomalous_flag = False else: target_anomalous_flag = iparams.target_anomalous_flag uc_mean = mdh.uc_mean wavelength_mean = mdh.wavelength_mean #output mtz file and report binning stat miller_set_merge = crystal.symmetry( unit_cell=unit_cell(tuple(uc_mean)), space_group_symbol=iparams.target_space_group).build_miller_set( anomalous_flag=target_anomalous_flag, d_min=iparams.merge.d_min) mdh.generate_miller_array_from_miller_set(miller_set_merge, target_anomalous_flag) miller_array_complete = miller_set_merge.array() fake_data = flex.double([1.0] * len(miller_array_complete.indices())) miller_array_template_asu = miller_array_complete.customized_copy(data=fake_data, \ sigmas=fake_data).resolution_filter(d_min=iparams.merge.d_min, \ d_max=iparams.merge.d_max) n_refl_all = mdh.get_size() #do another resolution filter here i_sel_res = mdh.miller_array_merge.resolution_filter_selection( d_min=iparams.merge.d_min, d_max=iparams.merge.d_max) mdh.reduce_by_selection(i_sel_res) n_refl_out_resolutions = n_refl_all - mdh.get_size() #remove outliers sequences = flex.int(range(mdh.get_size())) good_sequences = [] for i_rejection in range(iparams.n_rejection_cycle): binner_merge = mdh.miller_array_merge.setup_binner(n_bins=200) for i_bin in range(1, 201): i_binner = (binner_merge.bin_indices() == i_bin) I_obs_bin = mdh.miller_array_merge.data().select(i_binner) sequences_bin = sequences.select(i_binner) if len(I_obs_bin) > 0: I_obs_bin = mdh.miller_array_merge.data().select(i_binner) try: i_filter = flex.abs( (I_obs_bin - np.median(I_obs_bin)) / np.std(I_obs_bin)) < 10 except Exception as e: print "Warning: outlier rejection by bins failed because of floating point." print e i_filter = flex.bool([True] * len(I_obs_bin)) good_sequences.extend(list(sequences_bin.select(i_filter))) mdh.reduce_by_selection(flex.size_t(good_sequences)) n_refl_outliers = n_refl_all - n_refl_out_resolutions - mdh.get_size() #get iso if given. mxh = mx_handler() flag_hklisoin_found, miller_array_iso = mxh.get_miller_array_from_reflection_file( iparams.hklisoin) #write output files if output_mtz_file_prefix != '': #write as mtz file miller_array_merge_unique = mdh.miller_array_merge.merge_equivalents( ).array() info = miller.array_info(wavelength=wavelength_mean) miller_array_merge_unique.set_info(info) mtz_dataset_merge = miller_array_merge_unique.as_mtz_dataset( column_root_label="IOBS") mtz_dataset_merge.mtz_object().write( file_name=output_mtz_file_prefix + '_merge.mtz') #write as cns file f_cns = open(output_mtz_file_prefix + '_merge.hkl', 'w') miller_array_merge_unique.export_as_cns_hkl(file_object=f_cns) f_cns.close() #calculate merging stat table if True: #calculate isotropic B-factor try: mxh = mx_handler() asu_contents = mxh.get_asu_contents(iparams.n_residues) observations_as_f = mdh.miller_array_merge.as_amplitude_array() observations_as_f.setup_binner(auto_binning=True) wp = statistics.wilson_plot(observations_as_f, asu_contents, e_statistics=True) B_merged = wp.wilson_b except Exception as e: B_merged = 0 print "Warning: b-factor calculation in mod_util failed. Reset b-factor to 0" print e #report binning stats txt_out = '\n' txt_out += 'Isotropic B-factor: %7.2f\n' % (B_merged) txt_out += 'No. of reflections\n' txt_out += ' all: %7.0f\n' % (n_refl_all) txt_out += ' outside resolution: %7.0f\n' % ( n_refl_out_resolutions) txt_out += ' outliers: %7.0f\n' % (n_refl_outliers) txt_out += ' total left: %7.0f\n' % (mdh.get_size()) txt_out += 'Summary for ' + output_mtz_file_prefix + '_merge.mtz\n' txt_out += 'Bin Resolution Range Completeness <N_obs> |Rmerge Rsplit CC1/2 N_ind |CCiso N_ind|CCanoma N_ind| <I/sigI> <I> <sigI> <I**2>\n' txt_out += '--------------------------------------------------------------------------------------------------------------------------------------------------\n' #for stat pickle sp_res, sp_complete, sp_n_obs, sp_cc12, sp_cc12_anom, sp_rmerge, sp_i_o_sigi, sp_isqr = ( [], [], [], [], [], [], [], []) #binning binner_template_asu = miller_array_template_asu.setup_binner( n_bins=iparams.n_bins) binner_template_asu_indices = binner_template_asu.bin_indices() #for stats on axis cones mdh_astar = deepcopy(mdh) mdh_bstar = deepcopy(mdh) mdh_cstar = deepcopy(mdh) mdh_astar.reduce_to_cone_on_axis((1, 0, 0), iparams.percent_cone_fraction) mdh_bstar.reduce_to_cone_on_axis((0, 1, 0), iparams.percent_cone_fraction) mdh_cstar.reduce_to_cone_on_axis((0, 0, 1), iparams.percent_cone_fraction) #prepare text out for axis cones txt_out_cone = 'Summary of CC1/2 on three crystal axes\n' txt_out_cone += 'Bin Resolution Range CC1/2 <I> N_refl \n' txt_out_cone += ' a* b* c* | a* b* c* | a* b* c* \n' txt_out_cone += '---------------------------------------------------------------------------------------------------------\n' for i in range(1, iparams.n_bins + 1): i_binner = (binner_template_asu_indices == i) miller_indices_template_bin = miller_array_template_asu.indices( ).select(i_binner) #for all reflections mdh_bin = deepcopy(mdh) mdh_bin.reduce_by_miller_index(miller_indices_template_bin) cc12, n_refl_cc12 = mdh_bin.get_cc12() cciso, n_refl_cciso = mdh_bin.get_cciso(miller_array_iso) cc_anom_acentric, n_refl_anom_acentric = mdh_bin.get_cc_anom() completeness = (mdh_bin.get_size() / len(miller_indices_template_bin)) * 100 multiplicity = mdh_bin.get_multiplicity() txt_out += '%02d %7.2f - %7.2f %5.1f %6.0f / %6.0f %7.2f %7.2f %7.2f %7.2f %6.0f %7.2f %6.0f %7.2f %6.0f %8.2f %10.1f %8.1f %6.2f\n' \ %(i, binner_template_asu.bin_d_range(i)[0], binner_template_asu.bin_d_range(i)[1], \ completeness, \ mdh_bin.get_size(), len(miller_indices_template_bin),\ multiplicity, mdh_bin.get_r_meas()*100, mdh_bin.get_r_split()*100, \ cc12*100, n_refl_cc12, cciso*100, n_refl_cciso, \ cc_anom_acentric, n_refl_anom_acentric, \ mdh_bin.get_mean_IoversigI(), mdh_bin.get_mean_I(), mdh_bin.get_mean_sigI(), mdh_bin.get_second_moment()) #for reflections on cones mdh_astar_bin = deepcopy(mdh_astar) mdh_astar_bin.reduce_by_miller_index( miller_indices_template_bin) cc12_astar, n_refl_cc12_astar = mdh_astar_bin.get_cc12() mdh_bstar_bin = deepcopy(mdh_bstar) mdh_bstar_bin.reduce_by_miller_index( miller_indices_template_bin) cc12_bstar, n_refl_cc12_bstar = mdh_bstar_bin.get_cc12() mdh_cstar_bin = deepcopy(mdh_cstar) mdh_cstar_bin.reduce_by_miller_index( miller_indices_template_bin) cc12_cstar, n_refl_cc12_cstar = mdh_cstar_bin.get_cc12() txt_out_cone += '%02d %7.2f - %7.2f %7.2f %7.2f %7.2f %10.1f %10.1f %10.1f %6.0f %6.0f %6.0f\n' \ %(i, binner_template_asu.bin_d_range(i)[0], binner_template_asu.bin_d_range(i)[1], \ cc12_astar*100, cc12_bstar*100, cc12_cstar*100, \ mdh_astar_bin.get_mean_I(), mdh_bstar_bin.get_mean_I(), mdh_cstar_bin.get_mean_I(), \ n_refl_cc12_astar, n_refl_cc12_bstar, n_refl_cc12_cstar) #for stat pickle sp_res.append(binner_template_asu.bin_d_range(i)[1]) sp_complete.append(completeness) sp_n_obs.append(multiplicity) sp_cc12.append(cc12) sp_cc12_anom.append(cc_anom_acentric) sp_rmerge.append(mdh_bin.get_r_meas() * 100) sp_i_o_sigi.append(mdh_bin.get_mean_IoversigI()) sp_isqr.append(mdh.get_second_moment()) #txt out total for all reflections cc12, n_refl_cc12 = mdh.get_cc12() cciso, n_refl_cciso = mdh.get_cciso(miller_array_iso) cc_anom_acentric, n_refl_anom_acentric = mdh.get_cc_anom() txt_out += '--------------------------------------------------------------------------------------------------------------------------------------------------\n' txt_out += ' TOTAL %5.1f %6.0f / %6.0f %7.2f %7.2f %7.2f %7.2f %6.0f %7.2f %6.0f %7.2f %6.0f %8.2f %10.1f %8.1f %6.2f\n' \ %((mdh.get_size()/miller_array_template_asu.size())*100, \ mdh.get_size(), miller_array_template_asu.size(),\ mdh.get_multiplicity(), mdh.get_r_meas()*100, mdh.get_r_split()*100, \ cc12*100, n_refl_cc12, cciso*100, n_refl_cciso, \ cc_anom_acentric, n_refl_anom_acentric, \ mdh.get_mean_IoversigI(), mdh.get_mean_I(), mdh.get_mean_sigI(), mdh.get_second_moment()) txt_out += '--------------------------------------------------------------------------------------------------------------------------------------------------\n' txt_out += '\n' #txt out total for reflections on cones cc12_astar, n_refl_cc12_astar = mdh_astar.get_cc12() cc12_bstar, n_refl_cc12_bstar = mdh_bstar.get_cc12() cc12_cstar, n_refl_cc12_cstar = mdh_cstar.get_cc12() txt_out_cone += '----------------------------------------------------------------------------------------------------------\n' txt_out_cone += ' total %7.2f %7.2f %7.2f %10.1f %10.1f %10.1f %6.0f %6.0f %6.0f\n' \ %(cc12_astar*100, cc12_bstar*100, cc12_cstar*100, \ mdh_astar.get_mean_I(), mdh_bstar.get_mean_I(), mdh_cstar.get_mean_I(), \ n_refl_cc12_astar, n_refl_cc12_bstar, n_refl_cc12_cstar) txt_out_cone += '----------------------------------------------------------------------------------------------------------\n' txt_out_cone += '\n' txt_out_table1 = "Table1 (" + avg_mode + ")\n" txt_out_table1 += " Space group: " + str( mdh.miller_array_merge.space_group_info()) + "\n" txt_out_table1 += " Cell dimensions: %6.2f, %6.2f, %6.2f, %6.2f, %6.2f, %6.2f\n" % tuple( mdh.uc_mean) txt_out_table1 += " Resolution (A): %6.2f - %6.2f (%6.2f - %6.2f)\n" % ( mdh.miller_array_merge.d_max_min()[0], mdh.miller_array_merge.d_max_min()[1], sp_res[-2], sp_res[-1]) txt_out_table1 += " Rmerge: %6.2f (%6.2f)\n" % ( mdh.get_r_meas() * 100, sp_rmerge[-1]) txt_out_table1 += " CC1/2: %6.2f (%6.2f)\n" % (mdh.get_cc12()[0] * 100, sp_cc12[-1]) txt_out_table1 += " I/sigI: %6.2f (%6.2f)\n" % ( mdh.get_mean_IoversigI(), sp_i_o_sigi[-1]) txt_out_table1 += " Completeness (%%): %6.2f (%6.2f)\n" % ( (mdh.get_size() / miller_array_template_asu.size()) * 100, sp_complete[-1]) txt_out_table1 += " Redundancy: %6.2f (%6.2f)\n" % ( mdh.get_multiplicity(), sp_n_obs[-1]) #save data for stat. pickle in stat_dict if not iparams.flag_hush: stat_dict = {"binned_resolution": [sp_res], \ "binned_completeness": [sp_complete], \ "binned_n_obs": [sp_n_obs], \ "binned_cc12": [sp_cc12], \ "binned_cc12_anom": [sp_cc12_anom], \ "binned_rmerge": [sp_rmerge], \ "binned_i_o_sigi": [sp_i_o_sigi], \ "binned_isqr": [sp_isqr], \ "total_res_max": [mdh.miller_array_merge.d_max_min()[0]], \ "total_res_min": [mdh.miller_array_merge.d_max_min()[1]], \ "total_completeness": [(mdh.get_size()/miller_array_template_asu.size())*100], \ "total_n_obs": [mdh.get_multiplicity()], \ "total_cc12": [mdh.get_cc12()[0]*100], \ "total_rmerge": [mdh.get_r_meas()*100], \ "total_i_o_sigi": [mdh.get_mean_IoversigI()], \ "space_group_info": [mdh.miller_array_merge.space_group_info()], \ } self.write_stat_pickle(iparams, stat_dict) txt_out += txt_out_cone + txt_out_table1 return mdh, txt_out
def exercise_boxing(): n_real = (60, 100, 160) cs=crystal.symmetry( unit_cell=(21,37,58,80,111,117), space_group_symbol="P1") maptbx.boxes(n_real = n_real, fraction=0.1)
def exercise_get_r_free_flags(): crystal_symmetry = crystal.symmetry(unit_cell=(30, 31, 32, 85, 95, 100), space_group_symbol="P 1") miller_set = miller.build_set(crystal_symmetry=crystal_symmetry, anomalous_flag=False, d_min=3) n = miller_set.indices().size() exercise_flag_arrays = [] exercise_flag_arrays.append( flex.int(list(flex.random_permutation(size=n) % 10))) exercise_flag_arrays.append(flex.int(xrange(n))) exercise_flag_arrays.append(flex.int(n, 0)) for style in ["ccp4", "cns", "shelx", "bool"]: for i_exercise, exercise_flag_array in enumerate(exercise_flag_arrays): for reversed in [False, True]: if (style == "ccp4"): if (reversed): break data = exercise_flag_array test_flag_value = 3 else: if (not reversed): data = (exercise_flag_array == 0) test_flag_value = True else: data = (exercise_flag_array != 0) test_flag_value = False if (style == "cns"): data = data.as_int() test_flag_value = int(test_flag_value) elif (style == "shelx"): data = -data.as_int() data.set_selected((data == 0), 1) if (not reversed): test_flag_value = -1 else: test_flag_value = 1 input_array = miller_set.array(data=data) mtz_dataset = input_array.as_mtz_dataset( column_root_label="FreeRflags") mtz_dataset.mtz_object().write("tmp.mtz") reflection_files = [ reflection_file_reader.any_reflection_file( file_name="tmp.mtz") ] err = StringIO() reflection_file_srv = reflection_file_server( crystal_symmetry=crystal_symmetry, force_symmetry=True, reflection_files=reflection_files, err=err) for trial_test_flag_value in [None, test_flag_value]: for trial_label in [None, "free", "foo"]: try: r_free_flags, actual_test_flag_value = \ reflection_file_srv.get_r_free_flags( file_name=None, label=trial_label, test_flag_value=trial_test_flag_value, disable_suitability_test=False, parameter_scope="r_free_flags") except Sorry, e: if (trial_label != "foo"): assert i_exercise > 0 if (trial_label is None): assert str(e) == """\ No array of R-free flags found. For manual selection define: r_free_flags.label r_free_flags.test_flag_value r_free_flags.disable_suitability_test=True""" else: assert str(e) == \ "Not a suitable array of R-free flags:" \ + " r_free_flags.label=free\n" \ + "To override the suitability test define:" \ + " r_free_flags.disable_suitability_test=True" else: assert str( e ) == "No matching array: r_free_flags.label=foo" if (i_exercise == 0): assert err.getvalue() == """\ No matching array: r_free_flags.label=foo Possible choices: tmp.mtz:FreeRflags Please use r_free_flags.label to specify an unambiguous substring of the target label. """ else: assert err.getvalue() == """\ No matching array: r_free_flags.label=foo """ err = reflection_file_srv.err = StringIO() else: assert i_exercise == 0 actual_test_flag_value_2 = guess_r_free_flag_value( miller_array=r_free_flags, test_flag_value=trial_test_flag_value) assert (actual_test_flag_value_2 == actual_test_flag_value)
def __init__(self, input_index_engine, input_dictionary, horizon_phil, opt_rawframes=None, opt_target=False, reduce_target=True): from libtbx import adopt_init_args adopt_init_args(self, locals()) if self.horizon_phil.target_cell != None: # change target to primitive centering type from cctbx import crystal input_symmetry = crystal.symmetry( unit_cell=self.horizon_phil.target_cell, space_group_symbol="Hall: %s 1" % self.horizon_phil.target_cell_centring_type) from cctbx.sgtbx.lattice_symmetry import metric_subgroups groups = metric_subgroups( input_symmetry, 0.0, enforce_max_delta_for_generated_two_folds=True) #groups.show() primitive_target_cell = groups.result_groups[-1][ "best_subsym"].unit_cell() from rstbx.indexing_api.force_cell import force_cell best = force_cell(self.input_index_engine, primitive_target_cell) try: #print "Best score %.1f, triangle %12s"%(best["score"],str(best["triangle"])),best["orientation"].unit_cell() self.input_index_engine.setOrientation(best["orientation"]) except Exception: raise Sorry( """Cannot index with the target_cell. It is possible the target cell is wrong; try indexing without one. It may be necessary to change the beam position, distance, or two theta angle on the command line. See the http://cci.lbl.gov/labelit usage primer.""") # originally implemented with default conversion to niggli cell (reduce_target=True). # Added this as a configurable option in the context of indexing for sparse # nanocrystal stills, since we want to restrain to the originally-input target # setting, not necessarily the reduced cell: if reduce_target: self.input_index_engine.niggli() return #initial search all_sol = select_best_combo_of(input_index_engine, better_than=0.36, candidates=25, opt_inputs=(self.input_dictionary, opt_rawframes)) best_combo = all_sol.best_combo() if best_combo != None: self.evaluate_combo(best_combo) # XXX revisit the question of codecamp maxcell and whether this test should be functional #if self.horizon_phil.codecamp.maxcell != None: return if opt_rawframes == None or best_combo['lattice_likelihood'] > 3.0: return # quick abort to test out indexing 10/16/13 raise Exception("""No autoindexing solution. Possible: incorrect beam center; multiple lattices; too few spots.""" )