def setUp(self): """Write out a file, then read it in again. Non alphabetic ordering to check order preservation.""" # fill up the block with stuff items = (('_item_1', 'Some data'), ('_item_3', '34.2332'), ( '_item_4', 'Some very long data which we hope will overflow the single line and force printing of another line aaaaa bbbbbb cccccc dddddddd eeeeeeeee fffffffff hhhhhhhhh iiiiiiii jjjjjj' ), ('_item_2', 'Some_underline_data'), ('_item_empty', ''), ( '_item_quote', "'ABC" ), ('_item_apost', '"def'), ( '_item_sws', " \n " ), (('_item_5', '_item_7', '_item_6'), ([1, 2, 3, 4], [ 'a', 'b', 'c', 'd' ], [5, 6, 7, 8])), (('_string_1', '_string_2'), ([ ';this string begins with a semicolon', 'this string is way way too long and should overflow onto the next line eventually if I keep typing for long enough', ';just_any_old_semicolon-starting-string' ], [ 'a string with a final quote"', 'a string with a " and a safe\';', 'a string with a final \'' ]))) # save block items as well s_items = (('_sitem_1', 'Some save data'), ( '_sitem_2', 'Some_underline_data' ), ('_sitem_3', '34.2332'), ( '_sitem_4', 'Some very long data which we hope will overflow the single line and force printing of another line aaaaa bbbbbb cccccc dddddddd eeeeeeeee fffffffff hhhhhhhhh iiiiiiii jjjjjj' ), ( ( '_sitem_5', '_sitem_6', '_sitem_7'), ([1, 2, 3, 4], [5, 6, 7, 8], ['a', 'b', 'c', 'd']) ), (('_string_1', '_string_2'), ([ ';this string begins with a semicolon', 'this string is way way too long and should overflow onto the next line eventually if I keep typing for long enough', ';just_any_old_semicolon-starting-string' ], [ 'a string with a final quote"', 'a string with a " and a safe\';', 'a string with a final \'' ]))) self.cf = CifFile.CifBlock(items) self.save_block = CifFile.CifBlock(s_items) self.cf["saves"]["test_save_frame"] = self.save_block self.cfs = self.cf["saves"]["test_save_frame"] cif = CifFile.CifFile() cif['testblock'] = self.cf outfile = open('test.cif', 'w') outfile.write(str(cif)) outfile.close() self.ef = CifFile.CifFile('test.cif') self.df = self.ef['testblock'] self.dfs = self.df["saves"]["test_save_frame"] flfile = CifFile.ReadCif('test.cif', scantype="flex") self.flf = flfile['testblock'] self.flfs = self.flf["saves"]["test_save_frame"]
def testBlockOverwrite(self): """Upper/lower case should be seen as identical""" df = CifFile.CifBlock() ef = CifFile.CifBlock() cf = CifFile.CifFile() df['_random_1'] = 'oldval' ef['_random_1'] = 'newval' cf['_lowercaseblock'] = df cf['_LowerCaseBlock'] = ef assert (cf['_Lowercaseblock']['_random_1'] == 'newval') assert (len(cf) == 1)
def setUp(self): self.cf = CifFile.CifBlock() self.names = (('_item_name_1', '_item_name#2', '_item_%$#3'), ) self.values = (((1, 2, 3, 4), ('hello', 'good_bye', 'a space', '# 4'), (15.462, -99.34, 10804, 0.0001)), ) self.cf.AddCifItem((self.names, self.values)) self.cf['_non_loop_item'] = 'Non loop string item' self.cf['_number_item'] = 15.65
def testBlockName(self): """Make sure long block names cause errors""" df = CifFile.CifBlock() cf = CifFile.CifFile() try: cf['a_very_long_block_name_which_should_be_rejected_out_of_hand123456789012345678'] = df except CifFile.CifError: pass else: self.fail()
def setUp(self): #self.ddl1dic = CifFile.CifFile("dictionaries/cif_core.dic") #items = (("_atom_site_label","S1"), # ("_atom_site_fract_x","0.74799(9)"), # ("_atom_site_adp_type","Umpe"), # ("_this_is_not_in_dict","not here")) bl = CifFile.CifBlock() self.cf = CifFile.ValidCifFile(dic=ddl1dic) self.cf["test_block"] = bl self.cf["test_block"].AddCifItem( ("_atom_site_label", ["C1", "Cr2", "H3", "U4"]))
def testAddSaveFrame(self): """Test adding a save frame""" s_items = (('_sitem_1', 'Some save data'), ( '_sitem_2', 'Some_underline_data' ), ('_sitem_3', '34.2332'), ( '_sitem_4', 'Some very long data which we hope will overflow the single line and force printing of another line aaaaa bbbbbb cccccc dddddddd eeeeeeeee fffffffff hhhhhhhhh iiiiiiii jjjjjj' ), (('_sitem_5', '_sitem_6', '_sitem_7'), ([1, 2, 3, 4], [5, 6, 7, 8], ['a', 'b', 'c', 'd']))) bb = CifFile.CifBlock(s_items) self.cf["saves"]["some_name"] = bb
def write_cif(filename, struct): """Q'n'D Cif writer. Uses PyCifRW. length: Angstrom Parameters ---------- filename : str name of output .cif file struct : Structure, length units Angstrom assumed """ ffmt = "%.16e" cf = pycifrw_CifFile.CifFile() block = pycifrw_CifFile.CifBlock() block['_cell_length_a'] = frepr(struct.cryst_const[0], ffmt=ffmt) block['_cell_length_b'] = frepr(struct.cryst_const[1], ffmt=ffmt) block['_cell_length_c'] = frepr(struct.cryst_const[2], ffmt=ffmt) block['_cell_angle_alpha'] = frepr(struct.cryst_const[3], ffmt=ffmt) block['_cell_angle_beta'] = frepr(struct.cryst_const[4], ffmt=ffmt) block['_cell_angle_gamma'] = frepr(struct.cryst_const[5], ffmt=ffmt) block['_symmetry_space_group_name_H-M'] = 'P 1' block['_symmetry_Int_Tables_number'] = 1 # assigning a list produces a "loop_" block['_symmetry_equiv_pos_as_xyz'] = ['x,y,z'] # atoms # # _atom_site_label: We just use symbols, which is then = # _atom_site_type_symbol, but we *could* use that to number atoms of each # specie, e.g. Si1, Si2, ..., Al1, Al2, ... data_names = [ '_atom_site_label', '_atom_site_fract_x', '_atom_site_fract_y', '_atom_site_fract_z', '_atom_site_type_symbol' ] _xyz2str = lambda arr: [ffmt % x for x in arr] data = [ struct.symbols, _xyz2str(struct.coords_frac[:, 0]), _xyz2str(struct.coords_frac[:, 1]), _xyz2str(struct.coords_frac[:, 2]), struct.symbols ] # "loop_" with multiple columns block.AddCifItem([[data_names], [data]]) cf['pwtools'] = block # maxoutlength = 2048 is default for cif 1.1 standard (which is default in # pycifrw 3.x). Reset default wraplength=80 b/c ASE's cif reader cannot # handle wrapped lines. common.file_write(filename, cf.WriteOut(wraplength=2048))
def save(self, path, verbose=0): cif = pycif.CifFile() block = pycif.CifBlock() cif['block'] = block cif['block']['_symmetry.space_group_name_h-m'] = f'{self.spg}' cif['block']['_cell.angle_alpha'] = np.degrees(self.alpha) cif['block']['_cell.angle_beta'] = np.degrees(self.beta) cif['block']['_cell.angle_gamma'] = np.degrees(self.gamma) cif['block']['_cell.length_a'] = self.a_mag cif['block']['_cell.length_b'] = self.b_mag cif['block']['_cell.length_c'] = self.c_mag cif['block']['_refln.index_h'] = self.scat_bragg[:,0] cif['block']['_refln.index_k'] = self.scat_bragg[:,1] cif['block']['_refln.index_l'] = self.scat_bragg[:,2] cif['block']['_refln.intensity_meas'] = self.scat_bragg[:,3] cif['block'].CreateLoop( ['_refln.index_h', '_refln.index_k', '_refln.index_l', '_refln.intensity_meas'] ) outfile = open(path, 'w') outfile.write(cif.WriteOut()) outfile.close()
def write_cif_from_dataframe(dataframe, filename, chemical_name_common, cell_length_a, cell_length_b, cell_length_c, cell_angle_alpha=90, cell_angle_beta=90, cell_angle_gamma=90, space_group_name_H_M_alt='P 1', space_group_IT_number=1): """ Write a cif file from a Pandas Dataframe. This Dataframe can be created with temul.model_creation.create_dataframe_for_cif(). Parameters ---------- dataframe : dataframe object pandas dataframe containing rows of atomic position information chemical_name_common : string name of chemical cell_length_a, _cell_length_b, _cell_length_c : float lattice dimensions in angstrom cell_angle_alpha, cell_angle_beta, cell_angle_gamma : float lattice angles in degrees space_group_name_H-M_alt : string space group name space_group_IT_number : float """ # create cif import CifFile cif_file = CifFile.CifFile() # create block to hold values params = CifFile.CifBlock() cif_file['block_1'] = params # set unit cell properties params.AddItem('_chemical_name_common', chemical_name_common) params.AddItem('_cell_length_a', format(cell_length_a, '.6f')) params.AddItem('_cell_length_b', format(cell_length_b, '.6f')) params.AddItem('_cell_length_c', format(cell_length_c, '.6f')) params.AddItem('_cell_angle_alpha', cell_angle_alpha) params.AddItem('_cell_angle_beta', cell_angle_beta) params.AddItem('_cell_angle_gamma', cell_angle_gamma) params.AddItem('_space_group_name_H-M_alt', space_group_name_H_M_alt) params.AddItem('_space_group_IT_number', space_group_IT_number) # loop 1 - _space_group_symop_operation_xyz params.AddCifItem( ([['_space_group_symop_operation_xyz']], [[['x, y, z']]])) # [[['x, y, z', # 'x, y, z+1/2']]])) # loop 2 - individual atom positions and properties params.AddCifItem(([[ '_atom_site_label', '_atom_site_occupancy', '_atom_site_fract_x', '_atom_site_fract_y', '_atom_site_fract_z', '_atom_site_adp_type', '_atom_site_B_iso_or_equiv', '_atom_site_type_symbol' ]], [[ dataframe['_atom_site_label'], dataframe['_atom_site_occupancy'], dataframe['_atom_site_fract_x'], dataframe['_atom_site_fract_y'], dataframe['_atom_site_fract_z'], dataframe['_atom_site_adp_type'], dataframe['_atom_site_B_iso_or_equiv'], dataframe['_atom_site_type_symbol'] ]])) # put it all together in a cif outFile = open(filename + ".cif", "w") outFile.write(str(cif_file)) outFile.close()
def setUp(self): # we want to get a datablock ready so that the test # case will be able to write a single item self.cf = CifFile.CifBlock()
def __init__(self, struct, find_spacegroup=False): block = CifFile.CifBlock() latt = struct.lattice comp = struct.composition no_oxi_comp = Composition(comp.formula) spacegroup = ("P 1", 1) if find_spacegroup: sf = SymmetryFinder(struct, 0.001) spacegroup = (sf.get_spacegroup_symbol(), sf.get_spacegroup_number()) block["_symmetry_space_group_name_H-M"] = spacegroup[0] for cell_attr in ['a', 'b', 'c']: block["_cell_length_" + cell_attr] = str(getattr(latt, cell_attr)) for cell_attr in ['alpha', 'beta', 'gamma']: block["_cell_angle_" + cell_attr] = float(getattr(latt, cell_attr)) block["_chemical_name_systematic"] = "Generated by pymatgen" block["_symmetry_Int_Tables_number"] = spacegroup[1] block["_chemical_formula_structural"] = str( no_oxi_comp.reduced_formula) block["_chemical_formula_sum"] = str(no_oxi_comp.formula) block["_cell_volume"] = str(latt.volume) reduced_comp = Composition.from_formula(no_oxi_comp.reduced_formula) el = no_oxi_comp.elements[0] amt = comp[el] fu = int(amt / reduced_comp[Element(el.symbol)]) block["_cell_formula_units_Z"] = str(fu) block.AddCifItem( ([["_symmetry_equiv_pos_site_id", "_symmetry_equiv_pos_as_xyz"]], [[["1"], ["x, y, z"]]])) contains_oxidation = True try: symbol_to_oxinum = { str(el): float(el.oxi_state) for el in comp.elements } except AttributeError: symbol_to_oxinum = {el.symbol: 0 for el in comp.elements} contains_oxidation = False if contains_oxidation: block.AddCifItem( ([["_atom_type_symbol", "_atom_type_oxidation_number"]], [[symbol_to_oxinum.keys(), symbol_to_oxinum.values()]])) atom_site_type_symbol = [] atom_site_symmetry_multiplicity = [] atom_site_fract_x = [] atom_site_fract_y = [] atom_site_fract_z = [] atom_site_attached_hydrogens = [] atom_site_B_iso_or_equiv = [] atom_site_label = [] atom_site_occupancy = [] count = 1 for site in struct: for sp, occu in site.species_and_occu.items(): atom_site_type_symbol.append(str(sp)) atom_site_symmetry_multiplicity.append("1") atom_site_fract_x.append("{0:f}".format(site.a)) atom_site_fract_y.append("{0:f}".format(site.b)) atom_site_fract_z.append("{0:f}".format(site.c)) atom_site_attached_hydrogens.append("0") atom_site_B_iso_or_equiv.append(".") atom_site_label.append("{}{}".format(sp.symbol, count)) atom_site_occupancy.append(str(occu)) count += 1 block["_atom_site_type_symbol"] = atom_site_type_symbol block.AddToLoop("_atom_site_type_symbol", {"_atom_site_label": atom_site_label}) block.AddToLoop("_atom_site_type_symbol", { "_atom_site_symmetry_multiplicity": atom_site_symmetry_multiplicity }) block.AddToLoop("_atom_site_type_symbol", {"_atom_site_fract_x": atom_site_fract_x}) block.AddToLoop("_atom_site_type_symbol", {"_atom_site_fract_y": atom_site_fract_y}) block.AddToLoop("_atom_site_type_symbol", {"_atom_site_fract_z": atom_site_fract_z}) block.AddToLoop( "_atom_site_type_symbol", {"_atom_site_attached_hydrogens": atom_site_attached_hydrogens}) block.AddToLoop( "_atom_site_type_symbol", {"_atom_site_B_iso_or_equiv": atom_site_B_iso_or_equiv}) block.AddToLoop("_atom_site_type_symbol", {"_atom_site_occupancy": atom_site_occupancy}) self._cf = CifFile.CifFile() # AJ says: CIF Block names cannot be more than 75 characters or you # get an Exception self._cf[comp.reduced_formula[0:74]] = block