예제 #1
0
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
예제 #2
0
 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
예제 #3
0
 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)
예제 #4
0
 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
예제 #5
0
 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)
예제 #6
0
    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
예제 #7
0
    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
예제 #8
0
 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
예제 #9
0
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
예제 #10
0
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)))
예제 #11
0
 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
예제 #12
0
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)
예제 #13
0
 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
예제 #14
0
 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
예제 #15
0
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)
예제 #16
0
 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
예제 #17
0
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
예제 #18
0
 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
예제 #19
0
 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
예제 #20
0
 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
예제 #21
0
 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
예제 #22
0
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
예제 #23
0
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
예제 #24
0
 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
예제 #25
0
 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
예제 #26
0
 def test___isub__(self):
     """check Structure.__isub__()
     """
     cdse = Structure(filename=cdsefile)
     lat = cdse.lattice
     lst = cdse.tolist()
     cdse -= cdse[2:]
     self.assertEqual(2, len(cdse))
     self.assertEqual(4, len(lst))
     self.assertEqual('Cd', cdse[0].element)
     self.assertEqual('Cd', cdse[1].element)
     self.assertEqual(lat, cdse.lattice)
     self.assertEqual(lst[:2], cdse.tolist())
     return
예제 #27
0
 def test___isub__(self):
     """check Structure.__isub__()
     """
     cdse = Structure(filename=cdsefile)
     lat = cdse.lattice
     lst = cdse.tolist()
     cdse -= cdse[2:]
     self.assertEqual(2, len(cdse))
     self.assertEqual(4, len(lst))
     self.assertEqual('Cd', cdse[0].element)
     self.assertEqual('Cd', cdse[1].element)
     self.assertEqual(lat, cdse.lattice)
     self.assertEqual(lst[:2], cdse.tolist())
     return
예제 #28
0
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
예제 #29
0
파일: emsoft_h5ebsd.py 프로젝트: bceh/orix
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
예제 #30
0
    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()
예제 #31
0
    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
예제 #32
0
파일: phase_list.py 프로젝트: haal9751/orix
    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"
예제 #33
0
 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
예제 #34
0
 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
예제 #35
0
 def test_rwStr_xcfg_CdSe(self):
     """check conversion to XCFG file format"""
     stru = self.stru
     stru.read(datafile('CdSe_bulk.stru'), 'pdffit')
     s = stru.writeStr(self.format)
     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))
     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))
예제 #36
0
 def test___imul__(self):
     """check Structure.__imul__()
     """
     cdse = Structure(filename=cdsefile)
     lat = cdse.lattice
     els = cdse.element
     xyz = cdse.xyz
     lst = cdse.tolist()
     cdse *= 2
     self.assertEqual(8, len(cdse))
     self.assertEqual(lst, cdse[:4].tolist())
     self.assertEqual(numpy.tile(els, 2).tolist(), cdse.element.tolist())
     self.assertTrue(numpy.array_equal(numpy.tile(xyz, (2, 1)), cdse.xyz))
     self.assertEqual(8, len(set(cdse)))
     self.assertEqual(8 * [lat], [a.lattice for a in cdse])
     self.stru *= -3
     self.assertEqual(0, len(self.stru))
     return
예제 #37
0
 def test___imul__(self):
     """check Structure.__imul__()
     """
     cdse = Structure(filename=cdsefile)
     lat = cdse.lattice
     els = cdse.element
     xyz = cdse.xyz
     lst = cdse.tolist()
     cdse *= 2
     self.assertEqual(8, len(cdse))
     self.assertEqual(lst, cdse[:4].tolist())
     self.assertEqual(numpy.tile(els, 2).tolist(), cdse.element.tolist())
     self.assertTrue(numpy.array_equal(numpy.tile(xyz, (2, 1)), cdse.xyz))
     self.assertEqual(8, len(set(cdse)))
     self.assertEqual(8 * [lat], [a.lattice for a in cdse])
     self.stru *= -3
     self.assertEqual(0, len(self.stru))
     return
예제 #38
0
파일: conftest.py 프로젝트: pyxem/diffsims
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)],
        ),
    )
예제 #39
0
 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
예제 #40
0
    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
예제 #41
0
 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()]
예제 #42
0
    def _parseCifBlock(self, blockname):
        """Translate CIF file block, skip blocks without _atom_site_label.
        Updates data members stru, eau.

        blockname  -- name of top level block in self.ciffile

        No return value.
        """
        block = self.ciffile[blockname]
        if '_atom_site_label' not in block:   return
        # here block contains structure, initialize output data
        self.stru = Structure()
        self.labelindex.clear()
        # execute specialized block parsers
        self._parse_lattice(block)
        self._parse_atom_site_label(block)
        self._parse_atom_site_aniso_label(block)
        self._parse_space_group_symop_operation_xyz(block)
        return
예제 #43
0
 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
예제 #44
0
 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
예제 #45
0
 def test_stepcut_parsing(self):
     """check parsing of stepcut record from a file.
     """
     stru = self.stru
     stru.read(datafile('Ni.stru'), self.format)
     self.assertEqual(0, stru.pdffit['stepcut'])
     snoshape = stru.writeStr(format=self.format)
     self.assertTrue(not re.search('(?m)^shape', snoshape))
     # produce a string with non-zero stepcut
     stru.pdffit['stepcut'] = 13
     s13 = stru.writeStr(format=self.format)
     self.assertTrue(re.search('(?m)^shape +stepcut, ', s13))
     stru13 = Structure()
     stru13.readStr(s13)
     self.assertEqual(13, stru13.pdffit['stepcut'])
     with open(datafile('Ni.stru')) as fp:
         ni_lines = fp.readlines()
     ni_lines.insert(3, 'shape invalid, 7\n')
     sbad = ''.join(ni_lines)
     self.assertRaises(StructureFormatError, self.stru.readStr,
             sbad, format=self.format)
     return
예제 #46
0
def main():
    import getopt
    # default parameters
    try:
        opts, args = getopt.getopt(sys.argv[1:], "hV",
                ["help", "version"])
    except getopt.GetoptError as errmsg:
        print(errmsg, file=sys.stderr)
        sys.exit(2)
    # process options
    for o, a in opts:
        if o in ("-h", "--help"):
            usage()
            sys.exit()
        elif o in ("-V", "--version"):
            version()
            sys.exit()
    if len(args) < 1:
        usage('brief')
        sys.exit()
    # process arguments
    from diffpy.structure.parsers import inputFormats, outputFormats
    try:
        infmt, outfmt = args[0].split('..', 1)
        if infmt not in inputFormats():
            print("'%s' is not valid input format" % infmt, file=sys.stderr)
            sys.exit(2)
        if outfmt not in outputFormats():
            print("'%s' is not valid output format" % outfmt, file=sys.stderr)
            sys.exit(2)
    except ValueError:
        print("invalid format specification '%s' does not contain .." % args[0], file=sys.stderr)
        sys.exit(2)
    # ready to do some real work
    try:
        strufile = args[1]
        stru = Structure()
        if args[1] == "-":
            stru.readStr(sys.stdin.read(), infmt)
        else:
            stru.read(strufile, infmt)
        sys.stdout.write( stru.writeStr(outfmt) )
    except IndexError:
        print("strufile not specified", file=sys.stderr)
        sys.exit(2)
    except IOError as xxx_todo_changeme:
        (errno, errmsg) = xxx_todo_changeme.args
        print("%s: %s" % (strufile, errmsg), file=sys.stderr)
        sys.exit(1)
    except StructureFormatError as errmsg:
        print("%s: %s" % (strufile, errmsg), file=sys.stderr)
        sys.exit(1)
    return
예제 #47
0
    def _parseCifBlock(self, blockname):
        """Translate CIF file block, skip blocks without _atom_site_label.
        Updates data members stru, eau.

        blockname  -- name of top level block in self.ciffile

        No return value.
        """
        block = self.ciffile[blockname]
        if '_atom_site_label' not in block:   return
        # here block contains structure, initialize output data
        self.stru = Structure()
        self.labelindex.clear()
        # execute specialized block parsers
        self._parse_lattice(block)
        self._parse_atom_site_label(block)
        self._parse_atom_site_aniso_label(block)
        self._parse_space_group_symop_operation_xyz(block)
        return
예제 #48
0
 def setUp(self):
     self.stru = Structure()
     self.format = "pdffit"
     self.places = 8
예제 #49
0
# class DistancePrinter

# define nickel structure data
nickel_discus_data = '''
title   Ni
spcgr   P1
cell    3.523870,  3.523870,  3.523870, 90.000000, 90.000000, 90.000000
ncell          1,         1,         1,         4
atoms
NI          0.00000000        0.00000000        0.00000000       0.1000
NI          0.00000000        0.50000000        0.50000000       0.1000
NI          0.50000000        0.00000000        0.50000000       0.1000
NI          0.50000000        0.50000000        0.00000000       0.1000
'''

nickel = Structure()
nickel.readStr(nickel_discus_data, format='discus')

bucky = Structure(filename='datafiles/C60bucky.stru', format='discus')
distprint = DistancePrinter()
distprint._setDoubleAttr('rmax', 10)

def get_pyobjcryst_sphalerite():
    from pyobjcryst import loadCrystal
    crst = loadCrystal('datafiles/sphalerite.cif')
    return crst

def main():
    s = input('Enter rmin: ')
    if s.strip():  distprint.rmin = float(s)
    print("rmin = %g" % distprint.rmin)
예제 #50
0
def makeLaMnO3_P1():
    from diffpy.structure import Structure
    stru = Structure()
    stru.read(datafile('LaMnO3.stru'))
    return stru
예제 #51
0
    def setStructure(self, strufile):
        """Set the structure used in the calculation.

        strufile    --  The name of a structure file. A
                        diffpy.structure.Structure object will be created from
                        the file, and that object will be passed to the 'iofq'
                        function whenever it is called.

        This will create the refinement Parameters using the
        DiffpyStructureParSet adapter from diffpy.srfit.structure.diffpyparset.
        DiffpyStructureParSet is a ParameterSet object that organizes and gives
        attribute access to Parameters and ParameterSets adapted from a diffpy
        Structure object.  The Parameters embedded in the DiffpyStructureParSet
        are proxies for attributes of the diffpy.structure.Structure object
        that is needed by the 'iofq' function. The Parameters will be
        accessible by name under the 'phase' attribute of this generator, and
        are organized hierarchically:

        phase
          - lattice (retrieved with 'getLattice')
            - a
            - b
            - c
            - alpha
            - beta
            - gamma
          - scatterers (retrieved with 'getScatterers')
            - atom1 (the name depends on the element)
              - x
              - y
              - z
              - occ
              - U11
              - U22
              - U33
              - U12
              - U13
              - U23
              - Uiso
            - etc.

        The diffpy.structure.Structure instance is held within the
        DiffpyStructureParSet as the 'stru' attribute.

        """
        # Load the structure from file
        from diffpy.structure import Structure
        stru = Structure()
        stru.read(strufile)

        # Create a ParameterSet designed to interface with
        # diffpy.structure.Structure objects that organizes the Parameter
        # hierarchy. Note that the DiffpyStructureParSet holds a handle to the
        # loaded structure that we use in the __call__ method below.
        #
        # We pass the diffpy.structure.Structure instance, and give the
        # DiffpyStructureParSet the name "phase".
        parset = DiffpyStructureParSet("phase", stru)

        # Put this ParameterSet in the ProfileGenerator.
        self.addParameterSet(parset)

        return
예제 #52
0
        # Discard atom if (x/a)**2 + (y/b)**2 + (z/c)**2 > 1
        if d > 1:
            delList.append(j)

    for i in delList:
        newS.pop(i)

    return newS

# ----------------------------------------------------------------------------

if __name__ == "__main__":
    import os.path
    datadir = "../../tests/testdata"
    S = Structure()
    S.read(os.path.join(datadir, "CdSe_bulk.stru"), "pdffit")
    newS = makeEllipsoid(S, 12)
    newS.write("CdSe_d24.stru", "pdffit")
    newS = makeEllipsoid(S, 20, 10, 10)
    newS.write("CdSe_a20_b10_c10.stru", "pdffit")
    newS = makeEllipsoid(S, 20, 15, 10)
    newS.write("CdSe_a20_b15_c10.stru", "pdffit")
    S = Structure()
    S.read(os.path.join(datadir, "Ni.stru"), "pdffit")
    newS = makeEllipsoid(S, 10)
    newS.write("Ni_d20.stru", "pdffit")
    newS = makeEllipsoid(S, 20, 4)
    newS.write("Ni_a20_b4_c20.stru", "pdffit")
    newS = makeEllipsoid(S, 20, 15, 10)
    newS.write("Ni_a20_b15_c10.stru", "pdffit")
예제 #53
0
    def parseLines(self, lines):
        """Parse list of lines in PDB format.

        Return Structure instance or raise StructureFormatError.
        """
        try:
            stru = Structure()
            scale = numpy.identity(3, dtype=float)
            scaleU = numpy.zeros(3, dtype=float)
            p_nl = 0
            for line in lines:
                p_nl += 1
                # skip blank lines
                if not line.strip():    continue
                # make sure line has 80 characters
                if len(line) < 80:
                    line = "%-80s" % line
                words = line.split()
                record = words[0]
                if record == "TITLE":
                    continuation = line[8:10]
                    if continuation.strip():
                        stru.title += line[10:].rstrip()
                    else:
                        stru.title = line[10:].rstrip()
                elif record == "CRYST1":
                    a = float(line[7:15])
                    b = float(line[15:24])
                    c = float(line[24:33])
                    alpha = float(line[33:40])
                    beta = float(line[40:47])
                    gamma = float(line[47:54])
                    stru.lattice.setLatPar(a, b, c, alpha, beta, gamma)
                    scale = numpy.transpose(stru.lattice.recbase)
                elif record == "SCALE1":
                    sc = numpy.zeros((3,3), dtype=float)
                    sc[0,:] = [float(x) for x in line[10:40].split()]
                    scaleU[0] = float(line[45:55])
                elif record == "SCALE2":
                    sc[1,:] = [float(x) for x in line[10:40].split()]
                    scaleU[1] = float(line[45:55])
                elif record == "SCALE3":
                    sc[2,:] = [float(x) for x in line[10:40].split()]
                    scaleU[2] = float(line[45:55])
                    base = numpy.transpose(numpy.linalg.inv(sc))
                    abcABGcryst = numpy.array(stru.lattice.abcABG())
                    stru.lattice.setLatBase(base)
                    abcABGscale = numpy.array(stru.lattice.abcABG())
                    reldiff = numpy.fabs(1.0 - abcABGscale/abcABGcryst)
                    if not numpy.all(reldiff < 1.0e-4):
                        emsg = "%d: " % p_nl + \
                                "SCALE and CRYST1 are not consistent."
                        raise StructureFormatError(emsg)
                    if numpy.any(scaleU != 0.0):
                        emsg = "Origin offset not yet implemented."
                        raise NotImplementedError(emsg)
                elif record in ("ATOM", "HETATM"):
                    name = line[12:16].strip()
                    rc = [float(x) for x in line[30:54].split()]
                    try:
                        occupancy = float(line[54:60])
                    except ValueError:
                        occupancy = 1.0
                    try:
                        B = float(line[60:66])
                        uiso = B/(8*pi**2)
                    except ValueError:
                        uiso = 0.0
                    element = line[76:78].strip()
                    if element == "":
                        # get element from the first 2 characters of name
                        element = line[12:14].strip()
                        element = element[0].upper() + element[1:].lower()
                    stru.addNewAtom(element,
                            occupancy=occupancy, label=name)
                    last_atom = stru.getLastAtom()
                    last_atom.xyz_cartn = rc
                    last_atom.Uisoequiv = uiso
                elif record == "SIGATM":
                    sigrc = [float(x) for x in line[30:54].split()]
                    sigxyz = numpy.dot(scale, sigrc)
                    try:
                        sigo = float(line[54:60])
                    except ValueError:
                        sigo = 0.0
                    try:
                        sigB = float(line[60:66])
                        sigU = numpy.identity(3)*sigB/(8*pi**2)
                    except ValueError:
                        sigU = numpy.zeros((3,3), dtype=float)
                    last_atom.sigxyz = sigxyz
                    last_atom.sigo = sigo
                    last_atom.sigU = sigU
                elif record == "ANISOU":
                    last_atom.anisotropy = True
                    Uij = [ float(x)*1.0e-4 for x in line[28:70].split() ]
                    Ua = last_atom.U
                    for i in range(3):
                        Ua[i,i] = Uij[i]
                    Ua[0,1] = Ua[1,0] = Uij[3]
                    Ua[0,2] = Ua[2,0] = Uij[4]
                    Ua[1,2] = Ua[2,1] = Uij[5]
                elif record == "SIGUIJ":
                    sigUij = [ float(x)*1.0e-4 for x in line[28:70].split() ]
                    for i in range(3):
                        last_atom.sigU[i,i] = sigUij[i]
                    last_atom.sigU[0,1] = last_atom.sigU[1,0] = sigUij[3]
                    last_atom.sigU[0,2] = last_atom.sigU[2,0] = sigUij[4]
                    last_atom.sigU[1,2] = last_atom.sigU[2,1] = sigUij[5]
                elif record in P_pdb.validRecords:
                    pass
                else:
                    emsg = "%d: invalid record name '%r'" % (p_nl, record)
                    raise StructureFormatError(emsg)
        except (ValueError, IndexError):
            emsg = "%d: invalid PDB record" % p_nl
            exc_type, exc_value, exc_traceback = sys.exc_info()
            e = StructureFormatError(emsg)
            six.reraise(StructureFormatError, e, exc_traceback)
        return stru
예제 #54
0
 def __copy__(self):
     rv = MyDerivedStructure()
     Structure.__copy__(self, target=rv)
     return rv
예제 #55
0
    def parseLines(self, lines):
        """Parse list of lines in PDB format.

        Return Structure object or raise StructureFormatError.
        """
        xcfg_Number_of_particles = None
        xcfg_A = None
        xcfg_H0 = numpy.zeros((3,3), dtype=float)
        xcfg_H0_set = numpy.zeros((3,3), dtype=bool)
        xcfg_NO_VELOCITY = False
        xcfg_entry_count = None
        p_nl = 0
        p_auxiliary_re = re.compile(r"^auxiliary\[(\d+)\] =")
        p_auxiliary = {}
        stru = Structure()
        # ignore trailing blank lines
        stop = len(lines)
        for line in reversed(lines):
            if line.strip():
                break
            stop -= 1
        # iterator over the valid data lines
        ilines = iter(lines[:stop])
        try:
            # read XCFG header
            for line in ilines:
                p_nl += 1
                stripped_line = line.strip()
                # blank lines and lines starting with # are ignored
                if stripped_line == "" or line[0] == '#':
                    continue
                elif xcfg_Number_of_particles is None:
                    if line.find("Number of particles =") != 0:
                        emsg = ("%d: first line must " +
                                "contain 'Number of particles ='") % p_nl
                        raise StructureFormatError(emsg)
                    xcfg_Number_of_particles = int(line[21:].split(None, 1)[0])
                    p_natoms = xcfg_Number_of_particles
                elif line.find("A =") == 0:
                    xcfg_A = float(line[3:].split(None, 1)[0])
                elif line.find("H0(") == 0:
                    i, j = (int(line[3]) - 1, int(line[5]) - 1)
                    xcfg_H0[i,j] = float(line[10:].split(None, 1)[0])
                    xcfg_H0_set[i,j] = True
                elif line.find(".NO_VELOCITY.") == 0:
                    xcfg_NO_VELOCITY = True
                elif line.find("entry_count =") == 0:
                    xcfg_entry_count = int(line[13:].split(None, 1)[0])
                elif p_auxiliary_re.match(line):
                    m = p_auxiliary_re.match(line)
                    idx = int(m.group(1))
                    p_auxiliary[idx] = line[m.end():].split(None, 1)[0]
                else:
                    break
            # check header for consistency
            if numpy.any(xcfg_H0_set == False):
                emsg = "H0 tensor is not properly defined"
                raise StructureFormatError(emsg)
            p_auxnum = len(p_auxiliary) and max(p_auxiliary.keys())+1
            for i in range(p_auxnum):
                if not i in p_auxiliary:
                    p_auxiliary[i] = "aux%d" % i
            sorted_aux_keys = sorted(p_auxiliary.keys())
            if p_auxnum != 0:
                stru.xcfg = {
                    'auxiliaries' : [ p_auxiliary[k]
                                      for k in sorted_aux_keys ]
                }
            ecnt = len(p_auxiliary) + (3 if xcfg_NO_VELOCITY else 6)
            if ecnt != xcfg_entry_count:
                emsg = ("%d: auxiliary fields are "
                        "not consistent with entry_count") % p_nl
                raise StructureFormatError(emsg)
            # define proper lattice
            stru.lattice.setLatBase(xcfg_H0)
            # here we are inside the data block
            p_element = None
            for line in ilines:
                p_nl += 1
                words = line.split()
                # ignore atom mass
                if len(words) == 1 and isfloat(words[0]):
                    continue
                # parse element allowing empty symbol
                elif len(words) <= 1:
                    w = line.strip()
                    p_element = w[:1].upper() + w[1:].lower()
                elif len(words) == xcfg_entry_count and p_element is not None:
                    fields = [float(w) for w in words]
                    xyz = [xcfg_A * xi for xi in fields[:3]]
                    stru.addNewAtom(p_element, xyz=xyz)
                    a = stru[-1]
                    _assign_auxiliaries(a, fields, auxiliaries=p_auxiliary,
                                        no_velocity=xcfg_NO_VELOCITY)
                else:
                    emsg = "%d: invalid record" % p_nl
                    raise StructureFormatError(emsg)
            if len(stru) != p_natoms:
                emsg = "expected %d atoms, read %d" % (p_natoms, len(stru))
                raise StructureFormatError(emsg)
        except (ValueError, IndexError):
            emsg = "%d: file is not in XCFG format" % p_nl
            exc_type, exc_value, exc_traceback = sys.exc_info()
            e = StructureFormatError(emsg)
            six.reraise(StructureFormatError, e, exc_traceback)
        return stru
예제 #56
0
def makeRecipe(ciffile, datname):
    """Create a fitting recipe for crystalline PDF data."""

    ## The Profile
    # This will be used to store the observed and calculated PDF profile.
    profile = Profile()

    # Load data and add it to the Profile. Unlike in other examples, we use a
    # class (PDFParser) to help us load the data. This class will read the data
    # and relevant metadata from a two- to four-column data file generated
    # with PDFGetX2 or PDFGetN. The metadata will be passed to the PDFGenerator
    # when they are associated in the FitContribution, which saves some
    # configuration steps.
    parser = PDFParser()
    parser.parseFile(datname)
    profile.loadParsedData(parser)
    profile.setCalculationRange(xmax = 20)

    ## The ProfileGenerator
    # The PDFGenerator is for configuring and calculating a PDF profile. Here,
    # we want to refine a Structure object from diffpy.structure. We tell the
    # PDFGenerator that with the 'setStructure' method. All other configuration
    # options will be inferred from the metadata that is read by the PDFParser.
    # In particular, this will set the scattering type (x-ray or neutron), the
    # Qmax value, as well as initial values for the non-structural Parameters.
    generator = PDFGenerator("G")
    stru = Structure()
    stru.read(ciffile)
    generator.setStructure(stru)

    ## The FitContribution
    # Here we associate the Profile and ProfileGenerator, as has been done
    # before.
    contribution = FitContribution("nickel")
    contribution.addProfileGenerator(generator)
    contribution.setProfile(profile, xname = "r")

    ## Make the FitRecipe and add the FitContribution.
    recipe = FitRecipe()
    recipe.addContribution(contribution)

    ## Configure the fit variables

    # The PDFGenerator class holds the ParameterSet associated with the
    # Structure passed above in a data member named "phase". (We could have
    # given the ParameterSet a name other than "phase" when we added it to the
    # PDFGenerator.) The ParameterSet in this case is a StructureParameterSet,
    # the documentation for which is found in the
    # diffpy.srfit.structure.diffpystructure module.
    phase = generator.phase

    # We start by constraining the phase to the known space group. We could do
    # this by hand, but there is a method in diffpy.srfit.structure named
    # 'constrainAsSpaceGroup' for this purpose. The constraints will by default
    # be applied to the sites, the lattice and to the ADPs. See the method
    # documentation for more details. The 'constrainAsSpaceGroup' method may
    # create new Parameters, which it returns in a SpaceGroupParameters object.
    from diffpy.srfit.structure import constrainAsSpaceGroup
    sgpars = constrainAsSpaceGroup(phase, "Fm-3m")

    # The SpaceGroupParameters object returned by 'constrainAsSpaceGroup' holds
    # the free Parameters allowed by the space group constraints. Once a
    # structure is constrained, we need (should) only use the Parameters
    # provided in the SpaceGroupParameters, as the relevant structure
    # Parameters are constrained to these.
    #
    # We know that the space group does not allow for any free sites because
    # each atom is on a special position. There is one free (cubic) lattice
    # parameter and one free (isotropic) ADP. We can access these Parameters in
    # the xyzpars, latpars, and adppars members of the SpaceGroupParameters
    # object.
    for par in sgpars.latpars:
        recipe.addVar(par)
    for par in sgpars.adppars:
        recipe.addVar(par, 0.005)

    # We now select non-structural parameters to refine.
    # This controls the scaling of the PDF.
    recipe.addVar(generator.scale, 1)
    # This is a peak-damping resolution term.
    recipe.addVar(generator.qdamp, 0.01)
    # This is a vibrational correlation term that sharpens peaks at low-r.
    recipe.addVar(generator.delta2, 5)

    # Give the recipe away so it can be used!
    return recipe
예제 #57
0
class TestP_pdffit(unittest.TestCase):
    """test Parser for PDFFit file format"""

    def setUp(self):
        self.stru = Structure()
        self.format = "pdffit"
        self.places = 8


    def test_read_pdffit_ZnSb(self):
        """check reading of ZnSb pdffit structure file"""
        stru = self.stru
        stru.read(datafile('ZnSb_RT_Q28X_VM_20_fxiso.rstr'), self.format)
        f_title = "Cell structure file of Zn4Sb3 #167 interstitial"
        self.assertEqual(stru.title, f_title)
        self.assertAlmostEqual(stru.pdffit['scale'], 0.826145)
        self.assertAlmostEqual(stru.pdffit['delta2'], 4.687951)
        self.assertAlmostEqual(stru.pdffit['delta1'], 0.01)
        self.assertAlmostEqual(stru.pdffit['sratio'], 1.02)
        self.assertAlmostEqual(stru.pdffit['rcut'], 0.03)
        self.assertEqual(stru.pdffit['spcgr'], 'R-3c')
        s_lat = [ stru.lattice.a, stru.lattice.b, stru.lattice.c,
            stru.lattice.alpha, stru.lattice.beta, stru.lattice.gamma ]
        f_lat = [12.309436, 12.309436, 12.392839, 90.0, 90.0, 120.0]
        self.assertTrue(numpy.allclose(s_lat, f_lat))
        s_dcell = stru.pdffit['dcell']
        f_dcell = [0.000008, 0.000008, 0.000013, 0.0, 0.0, 0.0]
        self.assertTrue(numpy.allclose(s_dcell, f_dcell))
        self.assertEqual(stru.pdffit['ncell'], [1,1,1,66])
        s_els = [a.element for a in stru]
        self.assertEqual(s_els, 36*['Zn']+30*['Sb'])
        a0 = stru[0]
        s_xyz = a0.xyz
        f_xyz = [0.09094387, 0.24639539, 0.40080261];
        s_o = a0.occupancy
        f_o = 0.9
        s_sigxyz = a0.sigxyz
        f_sigxyz = [ 0.00000079, 0.00000076, 0.00000064];
        s_sigo = a0.sigo
        f_sigo = 0.0
        s_U = [ a0.U[i][i] for i in range(3) ]
        f_U = 3*[0.01]
        self.assertTrue(numpy.allclose(s_xyz, f_xyz))
        self.assertTrue(numpy.allclose(s_sigxyz, f_sigxyz))
        self.assertTrue(numpy.allclose(s_U, f_U))
        self.assertAlmostEqual(s_o, f_o)
        self.assertAlmostEqual(s_sigo, f_sigo)


    def test_read_pdffit_Ni(self):
        """check reading of Ni pdffit structure file"""
        stru = self.stru
        stru.read(datafile('Ni.stru'), self.format)
        f_title = "structure Ni  FCC"
        self.assertEqual(stru.title, f_title)
        self.assertEqual(stru.pdffit['spcgr'], 'Fm-3m')
        s_lat = [ stru.lattice.a, stru.lattice.b, stru.lattice.c,
            stru.lattice.alpha, stru.lattice.beta, stru.lattice.gamma ]
        f_lat = [3.52, 3.52, 3.52, 90.0, 90.0, 90.0]
        for i in range(len(s_lat)):
            self.assertAlmostEqual(s_lat[i], f_lat[i])
        self.assertEqual(stru.pdffit['ncell'], [1,1,1,4])
        s_els = [a.element for a in stru]
        self.assertEqual(s_els, 4*['Ni'])
        a0 = stru[0]
        s_xyz = a0.xyz
        f_xyz = [0.0, 0.0, 0.0];
        s_o = a0.occupancy
        f_o = 1.0
        s_U = [ a0.U[i][i] for i in range(3) ]
        f_U = 3*[0.00126651]
        for i in range(3):
            self.assertAlmostEqual(s_xyz[i], f_xyz[i])
            self.assertAlmostEqual(s_U[i], f_U[i])
        self.assertAlmostEqual(s_o, f_o)


    def test_read_pdffit_Ni_prim123(self):
        """check reading of Ni_prim supercell 1x2x3"""
        stru = self.stru
        stru.read(datafile('Ni_prim123.stru'), self.format)
        s_lat = [ stru.lattice.a, stru.lattice.b, stru.lattice.c,
            stru.lattice.alpha, stru.lattice.beta, stru.lattice.gamma ]
        f_lat = [2.489016,  2*2.489016,  3*2.489016, 60.0, 60.0, 60.0]
        for i in range(len(s_lat)):
            self.assertAlmostEqual(s_lat[i], f_lat[i])
        s_els = [a.element for a in stru]
        self.assertEqual(s_els, 6*['Ni'])
        a5 = stru[5]
        s_xyz = a5.xyz
        f_xyz = [0.0, 1.0/2.0, 2.0/3.0];
        for i in range(3):
            self.assertAlmostEqual(s_xyz[i], f_xyz[i])
        s_o = a5.occupancy
        f_o = 1.0
        self.assertAlmostEqual(s_o, f_o)
        s_U = [ a5.U[ij[0],ij[1]]
                for ij in [(0,0), (1,1), (2,2), (0,1), (0,2), (1,2)] ]
        f_U = 3*[0.00126651] + 3*[-0.00042217]
        for i in range(len(s_U)):
            self.assertAlmostEqual(s_U[i], f_U[i])
        return


    def test_read_pdffit_bad(self):
        """check exceptions when reading invalid pdffit file"""
        stru = self.stru
        self.assertRaises(StructureFormatError, stru.read,
                datafile('Ni-bad.stru'), self.format)
        self.assertRaises(StructureFormatError, stru.read,
                datafile('bucky.xyz'), self.format)
        return


    def test_writeStr_pdffit(self):
        """check writing of normal xyz file"""
        stru = self.stru
        stru.read(datafile('Ni.stru'), self.format)
        with open(datafile('Ni.stru')) as fp:
            f_s = fp.read()
        f_s = re.sub('[ \t]+', ' ', f_s)
        f_s = re.sub('[ \t]+\n', '\n', f_s)
        s_s = stru.writeStr(self.format)
        s_s = re.sub('[ \t]+', ' ', s_s)
        self.assertEqual(f_s, s_s)
        return


    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_ignored_lines(self):
        """check skipping of ignored lines in the header
        """
        r1 = 'ignored record 1'
        r2 = 'ignored record 2'
        with open(datafile('Ni.stru')) as fp:
            ni_lines = fp.readlines()
        ni_lines.insert(2, r1 + '\n')
        ni_lines.insert(4, r2 + '\n')
        s_s1 = "".join(ni_lines)
        p = self.stru.readStr(s_s1, self.format)
        self.assertEqual([r1, r2], p.ignored_lines)
        ni_lines.insert(-3, r1 + '\n')
        s_s2 = "".join(ni_lines)
        self.assertRaises(StructureFormatError, self.stru.readStr,
                s_s2, self.format)
        return


    def test_spdiameter_parsing(self):
        """check parsing of spdiameter record from a file.
        """
        stru = self.stru
        stru.read(datafile('Ni.stru'), self.format)
        self.assertEqual(0, stru.pdffit['spdiameter'])
        snoshape = stru.writeStr(format=self.format)
        self.assertTrue(not re.search('(?m)^shape', snoshape))
        # produce a string with non-zero spdiameter
        stru.pdffit['spdiameter'] = 13
        s13 = stru.writeStr(format=self.format)
        self.assertTrue(re.search('(?m)^shape +sphere, ', s13))
        stru13 = Structure()
        stru13.readStr(s13)
        self.assertEqual(13, stru13.pdffit['spdiameter'])
        with open(datafile('Ni.stru')) as fp:
            ni_lines = fp.readlines()
        ni_lines.insert(3, 'shape invalid, 7\n')
        sbad = ''.join(ni_lines)
        self.assertRaises(StructureFormatError, self.stru.readStr,
                sbad, format=self.format)
        return


    def test_stepcut_parsing(self):
        """check parsing of stepcut record from a file.
        """
        stru = self.stru
        stru.read(datafile('Ni.stru'), self.format)
        self.assertEqual(0, stru.pdffit['stepcut'])
        snoshape = stru.writeStr(format=self.format)
        self.assertTrue(not re.search('(?m)^shape', snoshape))
        # produce a string with non-zero stepcut
        stru.pdffit['stepcut'] = 13
        s13 = stru.writeStr(format=self.format)
        self.assertTrue(re.search('(?m)^shape +stepcut, ', s13))
        stru13 = Structure()
        stru13.readStr(s13)
        self.assertEqual(13, stru13.pdffit['stepcut'])
        with open(datafile('Ni.stru')) as fp:
            ni_lines = fp.readlines()
        ni_lines.insert(3, 'shape invalid, 7\n')
        sbad = ''.join(ni_lines)
        self.assertRaises(StructureFormatError, self.stru.readStr,
                sbad, format=self.format)
        return