def test_write_and_read(self): """high-level check of P_cif.tostring() """ # high-level check stru_check = Structure() stru_check.read(self.cdsebulkpdffitfile) s_s = stru_check.writeStr('cif') stru = Structure() stru.readStr(s_s, 'cif') self.assertAlmostEqual(4.2352, stru.lattice.a, self.places) self.assertAlmostEqual(4.2352, stru.lattice.b, self.places) self.assertAlmostEqual(6.90603, stru.lattice.c, self.places) self.assertEqual(4, len(stru)) a0 = stru[0] self.assertEqual('Cd', a0.element) self.assertTrue(numpy.allclose([0.3334, 0.6667, 0.0], a0.xyz)) self.assertTrue(a0.anisotropy) self.assertAlmostEqual(0.01303, a0.U[0, 0]) self.assertAlmostEqual(0.01303, a0.U[1, 1]) self.assertAlmostEqual(0.01402, a0.U[2, 2]) a3 = stru[3] self.assertEqual('Se', a3.element) self.assertTrue(numpy.allclose([0.6666, 0.333300, 0.87667], a3.xyz)) self.assertAlmostEqual(0.015673, a3.U[0, 0]) self.assertAlmostEqual(0.015673, a3.U[1, 1]) self.assertAlmostEqual(0.046164, a3.U[2, 2]) return
def test__get_lattice(self): """check Structure._get_lattice() """ lat = Lattice() stru = Structure() self.assertEqual((1, 1, 1, 90, 90, 90), stru.lattice.abcABG()) stru2 = Structure(lattice=lat) self.assertTrue(lat is stru2.lattice) return
def test_is_hexagonal(self): p1 = Phase( point_group="321", structure=Structure(lattice=Lattice(1, 1, 2, 90, 90, 120)), ) p2 = Phase( point_group="m-3m", structure=Structure(lattice=Lattice(1, 1, 1, 90, 90, 90)), ) assert p1.is_hexagonal assert not p2.is_hexagonal
def setUp(self): # load test structures once if TestSuperCell.stru_cdse is None: cdsefile = datafile("CdSe_bulk.stru") TestSuperCell.stru_cdse = Structure(filename=cdsefile) if TestSuperCell.stru_ni is None: nifile = datafile("Ni.stru") TestSuperCell.stru_ni = Structure(filename=nifile) # bring them to the instance self.stru_cdse = TestSuperCell.stru_cdse self.stru_ni = TestSuperCell.stru_ni return
def setUp(self): self.stru = Structure( [Atom('C', [0, 0, 0]), Atom('C', [1, 1, 1])], lattice=Lattice(1, 1, 1, 90, 90, 120)) if not self._loaded_structures: self._loaded_structures.update([ ('cdse', Structure(filename=cdsefile)), ('tei', Structure(filename=teifile)), ('pbte', Structure(filename=pbtefile)), ]) self.__dict__.update(self._loaded_structures) self.places = 12 return
def _get_phase(data_group): """Return phase information from a phase data group in an EMsoft dot product file. Parameters ---------- data_group : h5py.Group HDF5 group with the property data sets. Returns ------- name : str Phase name. point_group : str Phase point group. structure : diffpy.structure.Structure Phase structure. """ name = re.search(r"([A-z0-9]+)", data_group["MaterialName"][:][0].decode()).group(1) point_group = re.search(r"\[([A-z0-9]+)\]", data_group["Point Group"][:][0].decode()).group(1) lattice = Lattice(*tuple( data_group[f"Lattice Constant {i}"][:] for i in ["a", "b", "c", "alpha", "beta", "gamma"])) structure = Structure(title=name, lattice=lattice) return name, point_group, structure
def test_init_phase( self, name, point_group, space_group, color, color_alias, color_rgb, structure ): p = Phase( name=name, point_group=point_group, space_group=space_group, structure=structure, color=color, ) if name is None: assert p.name == structure.title else: assert p.name == str(name) if space_group is None: assert p.space_group is None else: assert p.space_group.number == space_group if point_group == "43": point_group = "432" if isinstance(point_group, Symmetry): point_group = point_group.name assert p.point_group.name == point_group assert p.color == color_alias assert np.allclose(p.color_rgb, color_rgb, atol=1e-6) if structure is not None: assert p.structure == structure else: assert p.structure == Structure()
def main(): s = input('Enter rmin: ') if s.strip(): distprint.rmin = float(s) print("rmin = %g" % distprint.rmin) s = input('Enter rmax: ') if s.strip(): distprint.rmax = float(s) print("rmax = %g" % distprint.rmax) print() linesep = 78 * '-' # C60bucky print(linesep) input('Press enter for distances in C60 molecule.') distprint.eval(bucky) # nickel print(linesep) input('Press enter for distances in a nickel crystal.') distprint.eval(nickel) # objcryst sphalerite print(linesep) input('Press enter for distances in objcryst loaded sphalerite.cif.') crst = get_pyobjcryst_sphalerite() distprint.eval(crst) print(linesep) input('Press enter for distances in diffpy.structure sphalerite.cif.') crst = Structure(filename='datafiles/sphalerite.cif') distprint.eval(crst) return
def makeRecipe(ciffile, datname): """Create a fitting recipe for crystalline PDF data.""" # Work directly with a custom PDFContribution to load the data contribution = PDFContribution("nickel") contribution.loadData(datname) contribution.setCalculationRange(xmin = 1, xmax = 20, dx = 0.1) # and the phase stru = Structure() stru.read(ciffile) contribution.addStructure("nickel", stru) ## Make the FitRecipe and add the FitContribution. recipe = FitRecipe() recipe.addContribution(contribution) ## Configure the fit variables phase = contribution.nickel.phase from diffpy.srfit.structure import constrainAsSpaceGroup sgpars = constrainAsSpaceGroup(phase, "Fm-3m") for par in sgpars.latpars: recipe.addVar(par) for par in sgpars.adppars: recipe.addVar(par, 0.005) recipe.addVar(contribution.scale, 1) recipe.addVar(contribution.qdamp, 0.03, fixed = True) recipe.addVar(contribution.nickel.delta2, 5) # Give the recipe away so it can be used! return recipe
def test___getitem__(self): """check Structure.__getitem__() """ stru = self.stru self.assertTrue(stru[0] is stru.tolist()[0]) intidx = list(range(len(stru)))[::-1] self.assertEqual(stru[intidx].tolist(), stru.tolist()[::-1]) flagidx = (numpy.arange(len(stru)) > 0) self.assertEqual(stru[flagidx].tolist(), stru.tolist()[1:]) cdse = Structure(self.cdse) self.assertEqual([cdse[0], cdse[-2]], cdse[0, -2].tolist()) cdse013 = cdse.tolist() cdse013.pop(2) self.assertEqual(cdse013, cdse[:2, 3].tolist()) self.assertRaises(IndexError, cdse.__getitem__, 'Cd1') cdse.assignUniqueLabels() self.assertTrue(cdse[0] is cdse['Cd1']) cdse[0].label = 'Hohenzollern' self.assertRaises(IndexError, cdse.__getitem__, 'Cd1') self.assertTrue(cdse[0] is cdse['Hohenzollern']) self.assertEqual([cdse[0], cdse[3], cdse[1]], cdse['Hohenzollern', 3:0:-2].tolist()) stru.label = ['A', 'B'] self.assertTrue(stru[0] is stru['A']) self.assertTrue(stru[1] is stru['B']) stru[1].label = 'A' self.assertRaises(IndexError, stru.__getitem__, 'A') return
def test_rwStr_pdb_CdSe(self): """check conversion to PDB file format""" stru = self.stru stru.read(datafile('CdSe_bulk.stru'), 'pdffit') s = stru.writeStr(self.format) # all lines should be 80 characters long linelens = [len(l) for l in s.split('\n') if l != ""] self.assertEqual(linelens, len(linelens) * [80]) # now clean and re-read structure stru = Structure() stru.readStr(s, self.format) s_els = [a.element for a in stru] f_els = ['Cd', 'Cd', 'Se', 'Se'] self.assertEqual(s_els, f_els) s_lat = [ stru.lattice.a, stru.lattice.b, stru.lattice.c, stru.lattice.alpha, stru.lattice.beta, stru.lattice.gamma ] f_lat = [4.235204, 4.235204, 6.906027, 90.0, 90.0, 120.0] self.assertTrue(numpy.allclose(s_lat, f_lat, atol=5e-4)) a0 = stru[0] s_Uii = [a0.U[i, i] for i in range(3)] f_Uii = [0.01303035, 0.01303035, 0.01401959] self.assertTrue(numpy.allclose(s_Uii, f_Uii, atol=5e-4)) s_sigUii = [a0.sigU[i, i] for i in range(3)] f_sigUii = [0.00011127, 0.00011127, 0.00019575] self.assertTrue(numpy.allclose(s_sigUii, f_sigUii, atol=5e-4)) s_title = stru.title f_title = "Cell structure file of CdSe #186" self.assertEqual(s_title, f_title)
def test_init_with_single_structure(self): structure = Structure() names = ["a", "b"] pl = PhaseList(names=names, structures=structure) assert pl.names == names assert pl.structures == [structure] * 2
def __init__(self, name=None, space_group=None, point_group=None, structure=None, color=None): """ Parameters ---------- name : str, optional Phase name. Overwrites the name in the `structure` object. space_group : int or diffpy.structure.spacegroups.SpaceGroup,\ optional Space group describing the symmetry operations resulting from associating the point group with a Bravais lattice, according to the International Tables of Crystallography. If None is passed (default), it is set to None. point_group : str or orix.quaternion.symmetry.Symmetry, optional Point group describing the symmetry operations of the phase's crystal structure, according to the International Tables of Crystallography. If None is passed (default) and `space_group` is None, it set to None. If None is passed but `space_group` is not None, it is derived from the space group. If both `point_group` and `space_group` is not None, the space group needs to be derived from the point group. structure : diffpy.structure.Structure, optional Unit cell with atoms and a lattice. If None is passed (default), a default :class:`diffpy.structure.Structure` object is created. color : str, optional Phase color. If None is passed (default), it is set to 'tab:blue' (first among the default Matplotlib colors). Examples -------- >>> from diffpy.structure import Atom, Lattice, Structure >>> from orix.crystal_map import Phase >>> p = Phase( ... name="al", ... space_group=225, ... structure=Structure( ... atoms=[Atom("al", [0, 0, 0])], ... lattice=Lattice(0.405, 0.405, 0.405, 90, 90, 90) ... ) ... ) >>> p <name: al. space group: Fm-3m. point group: m-3m. proper point \ ... group: 432. color: tab:blue> >>> p.structure [al 0.000000 0.000000 0.000000 1.0000] >>> p.structure.lattice Lattice(a=0.405, b=0.405, c=0.405, alpha=90, beta=90, gamma=90) """ self.structure = structure if structure is not None else Structure() if name is not None: self.name = name self.space_group = space_group # Needs to be set before point group self.point_group = point_group self.color = color if color is not None else "tab:blue"
def parseLines(self, lines): """Parse list of lines in RAWXYZ format. Return Structure object or raise StructureFormatError. """ linefields = [l.split() for l in lines] # prepare output structure stru = Structure() # find first valid record start = 0 for field in linefields: if len(field) == 0 or field[0] == "#": start += 1 else: break # find the last valid record stop = len(lines) while stop > start and len(linefields[stop - 1]) == 0: stop -= 1 # get out for empty structure if start >= stop: return stru # here we have at least one valid record line # figure out xyz layout from the first line for plain and raw formats floatfields = [isfloat(f) for f in linefields[start]] nfields = len(linefields[start]) if nfields not in (3, 4): emsg = ("%d: invalid RAWXYZ format, expected 3 or 4 columns" % (start + 1)) raise StructureFormatError(emsg) if floatfields[:3] == [True, True, True]: el_idx, x_idx = (None, 0) elif floatfields[:4] == [False, True, True, True]: el_idx, x_idx = (0, 1) else: emsg = "%d: invalid RAWXYZ format" % (start + 1) raise StructureFormatError(emsg) # now try to read all record lines try: p_nl = start for fields in linefields[start:]: p_nl += 1 if fields == []: continue elif len(fields) != nfields: emsg = ('%d: all lines must have ' + 'the same number of columns') % p_nl raise StructureFormatError(emsg) element = el_idx is not None and fields[el_idx] or "" xyz = [float(f) for f in fields[x_idx:x_idx + 3]] if len(xyz) == 2: xyz.append(0.0) stru.addNewAtom(element, xyz=xyz) except ValueError: emsg = "%d: invalid number" % p_nl exc_type, exc_value, exc_traceback = sys.exc_info() e = StructureFormatError(emsg) six.reraise(StructureFormatError, e, exc_traceback) return stru
def test_angle(self): """check Structure.angle() """ cdse = Structure(filename=cdsefile) cdse.assignUniqueLabels() self.assertEqual(109, round(cdse.angle(0, 2, 1))) self.assertEqual(109, round(cdse.angle("Cd1", "Se1", "Cd2"))) return
def test_add_structure(self): """check PdfFit.add_structure() """ from diffpy.structure import Structure ni = Structure(filename=datafile('Ni.stru')) self.P.add_structure(ni) self.assertEqual(4, self.P.num_atoms()) return
def main(): # load structure from a specified file, by default "lj50.xyz" filename = len(sys.argv) > 1 and sys.argv[1] or "lj50.xyz" stru = Structure() stru.read(filename) # create an instance of LennardJonesCalculator ljcalc = LennardJonesCalculator() # calculate and print the LJ potential. print("LJ potential of %s is %g" % (filename, ljcalc(stru)))
def nickel_phase(): return Phase( name="nickel", space_group=225, structure=Structure( lattice=Lattice(3.5236, 3.5236, 3.5236, 90, 90, 90), atoms=[Atom(xyz=[0, 0, 0], atype="Ni", Uisoequiv=0.006332)], ), )
def loadStructureFile(filename, format="auto"): """Load structure from specified file. Return a tuple of (Structure, fileformat). """ from diffpy.structure import Structure stru = Structure() p = stru.read(filename, format) fileformat = p.format return (stru, fileformat)
def test_add_phase_in_empty_phaselist(self): """Add Phase to empty PhaseList.""" sg_no = 10 name = "a" pl = PhaseList() pl.add(Phase(name, space_group=sg_no)) assert pl.ids == [0] assert pl.names == [name] assert pl.space_groups == [GetSpaceGroup(sg_no)] assert pl.structures == [Structure()]
def test_init_set_to_nones(self): phase_ids = [1, 2] pl = PhaseList(ids=phase_ids) assert pl.ids == phase_ids assert pl.names == [""] * 2 assert pl.point_groups == [None] * 2 assert pl.space_groups == [None] * 2 assert pl.colors == ["tab:blue", "tab:orange"] assert pl.structures == [Structure()] * 2
def test_huge_occupancy(self): """check structure with huge occupancy can be read. """ self.stru.read(datafile('Ni.stru'), self.format) self.stru[0].occupancy = 16e16 s_s = self.stru.writeStr(self.format) stru1 = Structure() stru1.readStr(s_s, self.format) self.assertEqual(16e16, stru1[0].occupancy) return
def test_label(self): """check Structure.label """ cdse = Structure(filename=cdsefile) self.assertEqual(4 * [''], cdse.label.tolist()) cdse.assignUniqueLabels() self.assertEqual('Cd1 Cd2 Se1 Se2'.split(), cdse.label.tolist()) cdse.label = cdse.label.lower() self.assertEqual('cd1 cd2 se1 se2'.split(), cdse.label.tolist()) return
def test_pickling(self): """Test pickling of DiffpyStructureParSet. """ stru = Structure([Atom("C", [0, 0.2, 0.5])]) dsps = DiffpyStructureParSet("dsps", stru) data = pickle.dumps(dsps) dsps2 = pickle.loads(data) self.assertEqual(1, len(dsps2.atoms)) self.assertEqual(0.2, dsps2.atoms[0].y.value) return
def supercell(S, mno): """Perform supercell expansion for a structure. New lattice parameters are multiplied and fractional coordinates divided by corresponding multiplier. New atoms are grouped with their source in the original cell. S -- an instance of Structure from diffpy.structure. mno -- sequence of 3 integers for cell multipliers along the a, b and c axes. Return a new expanded structure instance. Raise TypeError when S is not Structure instance. Raise ValueError for invalid mno argument. """ # check arguments if len(mno) != 3: emsg = "Argument mno must contain 3 numbers." raise ValueError(emsg) elif min(mno) < 1: emsg = "Multipliers must be greater or equal 1" raise ValueError(emsg) if not isinstance(S, Structure): emsg = "The first argument must be a Structure instance." raise TypeError(emsg) # convert mno to a tuple of integers so it can be used as range limit. mno = (int(mno[0]), int(mno[1]), int(mno[2])) # create return instance newS = Structure(S) if mno == (1, 1, 1): return newS # back to business ijklist = [(i, j, k) for i in range(mno[0]) for j in range(mno[1]) for k in range(mno[2])] # numpy.floor returns float array mnofloats = numpy.array(mno, dtype=float) # build a list of new atoms newAtoms = [] for a in S: for ijk in ijklist: adup = Atom(a) adup.xyz = (a.xyz + ijk) / mnofloats newAtoms.append(adup) # newS can own references in newAtoms, no need to make copies newS.__setitem__(slice(None), newAtoms, copy=False) # take care of lattice parameters newS.lattice.setLatPar(a=mno[0] * S.lattice.a, b=mno[1] * S.lattice.b, c=mno[2] * S.lattice.c) return newS
def test___repr__(self): """Test representation of DiffpyStructureParSet objects. """ lat = Lattice(3, 3, 2, 90, 90, 90) atom = Atom("C", [0, 0.2, 0.5]) stru = Structure([atom], lattice=lat) dsps = DiffpyStructureParSet("dsps", stru) self.assertEqual(repr(stru), repr(dsps)) self.assertEqual(repr(lat), repr(dsps.lattice)) self.assertEqual(repr(atom), repr(dsps.atoms[0])) return
def phase_list(request): names, space_groups, point_group_names, colors, lattices, atoms = request.param # Apparently diffpy.structure don't allow iteration over a list of lattices structures = [Structure(lattice=lattices[i], atoms=a) for i, a in enumerate(atoms)] return PhaseList( names=names, space_groups=space_groups, point_groups=point_group_names, colors=colors, structures=structures, )
def makeData(strufile, q, datname, scale, a, Uiso, sig, bkgc, nl=1): """Make some fake data and save it to file. Make some data to fit. This uses iofq to calculate an intensity curve, and adds to it a background, broadens the peaks, and noise. strufile-- A filename holding the sample structure q -- The q-range to calculate over. datname -- The name of the file we're saving to. scale -- The scale factor a -- The lattice constant to use Uiso -- The thermal factor for all atoms sig -- The broadening factor bkgc -- A parameter that gives minor control of the background. nl -- Noise level (0, inf), default 1, larger -> less noise. """ from diffpy.structure import Structure S = Structure() S.read(strufile) # Set the lattice parameters S.lattice.setLatPar(a, a, a) # Set a DW factor for a in S: a.Uisoequiv = Uiso y = iofq(S, q) # We want to broaden the peaks as well. This simulates instrument effects. q0 = q[len(q) // 2] g = numpy.exp(-0.5 * ((q - q0) / sig)**2) y = numpy.convolve(y, g, mode='same') / sum(g) # Add a polynomial background. bkgd = (q + bkgc)**2 * (1.5 * max(q) - q)**5 bkgd *= 0.2 * max(y) / max(bkgd) y += bkgd # Multipy by a scale factor y *= scale # Calculate the uncertainty u = (y / nl)**0.5 # And apply the noise if nl > 0: y = numpy.random.poisson(y * nl) / nl # Now save it numpy.savetxt(datname, numpy.transpose([q, y, u])) return
def test___copy__(self): """check Structure.__copy__() """ cdse = Structure(filename=cdsefile) cdse_str = cdse.writeStr('pdffit') cdse2 = copy.copy(cdse) self.assertEqual(cdse_str, cdse2.writeStr('pdffit')) self.assertFalse(cdse.lattice is cdse2.lattice) sameatoms = set(cdse).intersection(cdse2) self.assertFalse(sameatoms) return
def test_extend(self): """check Structure.extend() """ stru = self.stru cdse = Structure(filename=cdsefile) lst = stru.tolist() stru.extend(cdse) self.assertEqual(6, len(stru)) self.assertTrue(all(a.lattice is stru.lattice for a in stru)) self.assertEqual(lst, stru.tolist()[:2]) self.assertFalse(stru[-1] is cdse[-1]) return