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
Beispiel #7
0
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()
Beispiel #9
0
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()
Beispiel #11
0
    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