Error in simplepdftwophase.py

32 views
Skip to first unread message

Philipp Hans

unread,
Jul 3, 2015, 4:11:30 PM7/3/15
to diffp...@googlegroups.com
Good day,

I try to create some scripts for analysing some coated nano-particles. I don't trust the coating-status so I want do a normal fit using two phases.

I wanted to do this via altering your example "simplepdftwophase.py" because I wasn't able to write the whole program on my own. The experimental PDFs of Nickel and Si shall be fitted with a structural model in this example.
https://github.com/diffpy/cmi_exchange

Like some other scripts e.g. "simplepdftwophase.py" or "simplepdftwophase.py" they are, although surely well-intentioned, rather unhelpful examples, I have to admit unfortunately. There occur several error-messages. I hadn't the potential up to now to solve all those.


In the case of "simplepdftwophase.py" my solution was to add Biso on my own. The script is intended to search parameters in the *.cif-file and add e.g. an "_ni" to there names. But as there are none of those parameters in the *.cif-file, so it is not successful, I suggest.


This is how the original error message looks like:

"...Programme/diffpy_cmi-1.0/lib/python2.7/site-packages/diffpy.srfit-1.0.post25-py2.7.egg/diffpy/srfit/equation/builder.pyc in _prepareBuilders(self, eqstr, buildargs, argclass, argkw)
282 eqargsstr = ", ".join(eqargs)
283 msg = "The equation contains undefined arguments: %s"%eqargsstr
--> 284 raise ValueError(msg)
285
286 # Make the arguments

ValueError: The equation contains undefined arguments: Biso_0_ni"



According to your documentation this error means:
"Raises ValueError if ns uses a name that is already used for a Parameter. Raises ValueError if res depends on a Parameter that is not part of the RecipeOrganizer and that is not defined in ns.

Returns the Restraint object for use with the ‘unrestrain’ method."

But I can't do very much with that information; I don't know where to look in the overall routine for coping with this bug.


So I added the following line to the script.
recipe.newVar("Biso_0_ni", 1)
recipe.newVar("Biso_0_si", 1)


I got the script running with the lines I added, but the calculated-profile has nothing to do with the experimental data. I am not really sure if this is the right solution. Unfortunately I couldn't upload modified script into the appendix. I think one has to add additional parameters. Wherefrom should the program know what I mean?

best regards,
Philipp Hans
======================================================
Script-file
======================================================
#!/usr/bin/env python
########################################################################
#
# diffpy.srfit by DANSE Diffraction group
# Simon J. L. Billinge
# (c) 2010 Trustees of the Columbia University
# in the City of New York. All rights reserved.
#
# File coded by: Chris Farrow
#
# See AUTHORS.txt for a list of people who contributed.
# See LICENSE.txt for license information.
#
########################################################################
"""Example of a simplified PDF refinement of two-phase structure."""

import numpy

from pyobjcryst.crystal import CreateCrystalFromCIF

from diffpy.srfit.pdf import PDFContribution
from diffpy.srfit.fitbase import FitRecipe, FitResults

from gaussianrecipe import scipyOptimize
from crystalpdftwophase import plotResults

####### Example Code

def makeRecipe(niciffile, siciffile, datname):
"""Create a fitting recipe for crystalline PDF data."""

# Load data and add it to the profile
contribution = PDFContribution("nisi")
contribution.loadData(datname)
contribution.setCalculationRange(xmax = 20)

stru = CreateCrystalFromCIF(file(niciffile))
contribution.addStructure("ni", stru)

stru = CreateCrystalFromCIF(file(siciffile))
contribution.addStructure("si", stru)

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

## Configure the fit variables
# Start by configuring the scale factor and resolution factors.
# We want the sum of the phase scale factors to be 1.
recipe.newVar("scale_ni", 0.1)
recipe.constrain(contribution.ni.scale, "scale_ni")
recipe.constrain(contribution.si.scale, "1 - scale_ni")
# We also want the resolution factor to be the same on each. This is done
# for free by the PDFContribution. We simply need to add it to the recipe.
recipe.addVar(contribution.qdamp, 0.03)

# Vary the gloabal scale as well.
recipe.addVar(contribution.scale, 1)

# Now we can configure the structural parameters. Since we're using
# ObjCrystCrystalParSets, the space group constraints are automatically
# applied to each phase. We must selectively vary the free parameters.
#
# First the nickel parameters.
# Note that ni is the name of the PDFGenerator that was automatically
# created by the PDFContribution. We selected this name in addStructure
# above.
phase_ni = contribution.ni.phase
for par in phase_ni.sgpars:
recipe.addVar(par, name = par.name + "_ni")
recipe.addVar(contribution.ni.delta2, name = "delta2_ni")
recipe.newVar("Biso_0_ni", 1)
# Next the silicon parameters
phase_si = contribution.si.phase
for par in phase_si.sgpars:
recipe.addVar(par, name = par.name + "_si")
recipe.addVar(contribution.si.delta2, name = "delta2_si")
recipe.newVar("Biso_0_si", 1)

# We have prior information from the earlier examples so we'll use it here
# in the form of restraints.
#
# The nickel lattice parameter was measured to be 3.527. The uncertainty
# values are invalid for that measurement, since the data from which it is
# derived has no uncertainty. Thus, we will tell the recipe to scale the
# residual, which means that it will be weighted as much as the average
# data point during the fit.
recipe.restrain("a_ni", lb = 3.527, ub = 3.527, scaled = True)
# Now we do the same with the delta2 and Biso parameters (remember that
# Biso = 8*pi**2*Uiso)
recipe.restrain("delta2_ni", lb = 2.22, ub = 2.22, scaled = True)
recipe.restrain("Biso_0_ni", lb = 0.454, ub = 0.454, sig = 1, scaled = True)
#
# We can do the same with the silicon values. We haven't done a thorough
# job of measuring the uncertainties in the results, so we'll scale these
# as well.
recipe.restrain("a_si", lb = 5.430, ub = 5.430, scaled = True)
recipe.restrain("delta2_si", lb = 3.54, ub = 3.54, scaled = True)
recipe.restrain("Biso_0_si", lb = 0.645, ub = 0.645, sig = 1, scaled = True)

# Give the recipe away so it can be used!
return recipe


if __name__ == "__main__":

# Make the data and the recipe
niciffile = "data/ni.cif"
siciffile = "data/si.cif"
data = "data/si90ni10-q27r60-xray.gr"

# Make the recipe
recipe = makeRecipe(niciffile, siciffile, data)

# Optimize
scipyOptimize(recipe)

# Generate and print the FitResults
res = FitResults(recipe)
res.printResults()

# Plot!
plotResults(recipe)

# End of file
Reply all
Reply to author
Forward
0 new messages