def _makeRecipe(self, x, y, dy): '''Make a FitRecipe for fitting a Gaussian curve to data. ''' profile = Profile() profile.setObservedProfile(x, y, dy) contribution = FitContribution("g1") contribution.setProfile(profile, xname="x") contribution.registerStringFunction('1/sqrt(2 * pi * sig**2)', name='gaussnorm') contribution.setEquation( "A * gaussnorm * exp(-0.5 * (x - x0)**2/sig**2)") recipe = FitRecipe() recipe.addContribution(contribution) recipe.addVar(contribution.A) recipe.addVar(contribution.x0) recipe.addVar(contribution.sig) recipe.clearFitHooks() self.recipe = recipe return
def _makeRecipe(self, x, y, dy): '''Make a FitRecipe for fitting a Gaussian curve to data. ''' profile = Profile() profile.setObservedProfile(x, y, dy) contribution = FitContribution("g1") contribution.setProfile(profile, xname="x") contribution.registerStringFunction( '1/sqrt(2 * pi * sig**2)', name='gaussnorm') contribution.setEquation( "A * gaussnorm * exp(-0.5 * (x - x0)**2/sig**2)") recipe = FitRecipe() recipe.addContribution(contribution) recipe.addVar(contribution.A) recipe.addVar(contribution.x0) recipe.addVar(contribution.sig) recipe.clearFitHooks() self.recipe = recipe return
for par in spaceGroupParams.latpars: MnOFit.addVar(par) # Set initial value for the ADP parameters, because CIF had no ADP data. for par in spaceGroupParams.adppars: MnOFit.addVar(par, value=0.003, fixed=True) # As usual, we add variables for the overall scale of the PDF and a delta2 # parameter for correlated motion of neighboring atoms. MnOFit.addVar(MnOPDF.scale, 1) MnOFit.addVar(MnOPDF.MnO.delta2, 1.5) # We fix Qdamp based on prior information about our beamline. MnOFit.addVar(MnOPDF.qdamp, 0.03, fixed=True) # Turn off printout of iteration number. MnOFit.clearFitHooks() # We can now execute the fit using scipy's least square optimizer. print("Refine PDF using scipy's least-squares optimizer:") print(" variables:", MnOFit.names) print(" initial values:", MnOFit.values) leastsq(MnOFit.residual, MnOFit.values) print(" final values:", MnOFit.values) print() # Obtain and display the fit results. MnOResults = FitResults(MnOFit) print("FIT RESULTS\n") print(MnOResults) # Get the experimental data from the recipe
for par in spaceGroupParams.latpars: niFit.addVar(par) # Set initial value for the ADP parameters, because CIF had no ADP data. for par in spaceGroupParams.adppars: niFit.addVar(par, value=0.005) # As usual, we add variables for the overall scale of the PDF and a delta2 # parameter for correlated motion of neighboring atoms. niFit.addVar(niPDF.scale, 1) niFit.addVar(niPDF.nickel.delta2, 5) # We fix Qdamp based on prior information about our beamline. niFit.addVar(niPDF.qdamp, 0.03, fixed=True) # Turn off printout of iteration number. niFit.clearFitHooks() # We can now execute the fit using scipy's least square optimizer. print "Refine PDF using scipy's least-squares optimizer:" print " variables:", niFit.names print " initial values:", niFit.values leastsq(niFit.residual, niFit.values) print " final values:", niFit.values print # Obtain and display the fit results. niResults = FitResults(niFit) print "FIT RESULTS\n" print niResults # Plot the observed and refined PDF.
for par in sgpars.latpars: mnofit.addVar(par) # Set initial value for the ADP parameters, because CIF had no ADP data. for par in sgpars.adppars: mnofit.addVar(par, value=0.003) # As usual, we add variables for the overall scale of the PDF and a delta2 # parameter for correlated motion of neighboring atoms. mnofit.addVar(totpdf.nucscale, 1) mnofit.addVar(nucpdf.delta2, 1.5) # We fix Qdamp based on prior information about our beamline. mnofit.addVar(nucpdf.qdamp, 0.03) # Turn off printout of iteration number. mnofit.clearFitHooks() # Initial structural fit print("Refine PDF using scipy's least-squares optimizer:") print(" variables:", mnofit.names) print(" initial values:", mnofit.values) leastsq(mnofit.residual, mnofit.values) print(" final values:", mnofit.values) print() # Obtain and display the fit results. mnoresults = FitResults(mnofit) print("FIT RESULTS\n") print(mnoresults) # Get the experimental data from the recipe r = mnofit.totpdf.profile.x
for par in spaceGroupParams.latpars: niFit.addVar(par) # Set initial value for the ADP parameters, because CIF had no ADP data. for par in spaceGroupParams.adppars: niFit.addVar(par, value=0.005) # As usual, we add variables for the overall scale of the PDF and a delta2 # parameter for correlated motion of neighboring atoms. niFit.addVar(niPDF.scale, 1) niFit.addVar(niPDF.nickel.delta2, 5) # We fix Qdamp based on prior information about our beamline. niFit.addVar(niPDF.qdamp, 0.03, fixed=True) # Turn off printout of iteration number. niFit.clearFitHooks() # We can now execute the fit using scipy's least square optimizer. print("Refine PDF using scipy's least-squares optimizer:") print(" variables:", niFit.names) print(" initial values:", niFit.values) leastsq(niFit.residual, niFit.values) print(" final values:", niFit.values) print() # Obtain and display the fit results. niResults = FitResults(niFit) print("FIT RESULTS\n") print(niResults) # Plot the observed and refined PDF.
def make(self, crystal, r, g, dg=None, meta=None): """ Construct new srfit recipe from CIF structure and PDF data Parameters ---------- crystal : pyobjcryst.Crystal The CIF structure to be fitted to the PDF data in-place. r : array_like The r-grid of the fitted PDF dataset in Angstroms. g : array_like The fitted PDF values per each `r` point. dg : array_like, optional The estimated standard deviations at each of `g` values. When unspecified, *dg* is assumed 1 leading to underestimated standard errors of the refined variables. meta : dict, optional A dictionary of extra metadata to be used when constructing `PDFContribution` in the srfit recipe. The common recognized keys are ``stype`` for radiation type ("X" or "N"), ``qmax`` for the Q-range used in the experiment, ``delta1``, ``delta2``, ``qbroad`` for peak sharpening and broadening factors and ``qdamp`` for the Q-resolution related signal dampening. Returns ------- recipe : FitRecipe The new FitRecipe for in-place fitting of `crystal` to PDF data. """ if not isinstance(crystal, Crystal): emsg = "crystal must be of the pyobjcryst.Crystal type." raise TypeError(emsg) cpdf = PDFContribution('cpdf') cpdf.profile.setObservedProfile(r, g, dg) m = {} if meta is None else dict(meta) cpdf.profile.meta.update(m) cpdf.addStructure('cif', crystal) cpdf.setCalculationRange(self.rmin, self.rmax) if self.nyquist: if not 'qmax' in m: emsg = "Nyquist spacing requires 'qmax' metadata." raise ValueError(emsg) assert m['qmax'] == cpdf.cif.getQmax() cpdf.setCalculationRange(dx=numpy.pi / m['qmax']) # create FitRecipe recipe = FitRecipe() recipe.clearFitHooks() recipe.addContribution(cpdf) recipe.addVar(cpdf.scale) # get symmetry allowed structure parameters sgpars = cpdf.cif.phase.sgpars # constrain available lattice parameters for p in sgpars.latpars: recipe.addVar(p, tags=['phase', 'lattice']) # constrain free atom positions for p in sgpars.xyzpars: recipe.addVar(p, tags=['phase', 'positions']) # constrain adps isosymbol = sgpars.isosymbol fbbiso = self.fbbiso # make a dummy diffpy.structure.Atom with isotropic Biso = fbbiso afbiso = _dummyAtomWithBiso(crystal, self.fbbiso) tags = ['phase', 'adps'] for p in sgpars.adppars: if p.name.startswith(isosymbol): recipe.addVar(p, value=p.value or fbbiso, tags=tags) continue # we have anisotropic site here, but constrain as isotropic # if so requested if self.isotropy: # extract site index for this sg parameter. Use it to get # the parameter for its Biso value. idx = int(p.name.split('_')[-1]) psite = cpdf.cif.phase.scatterers[idx] pbiso = psite.Biso n = isosymbol + '_{}'.format(idx) v = pbiso.value or fbbiso # avoid applying duplicate constrain to pbiso if recipe.get(n) is None: recipe.addVar(pbiso, name=n, value=v, tags=tags) continue # here we constrain an anisotropic site. # make sure its ADPs are nonzero. spa = p.par.obj if not all((spa.B11, spa.B22, spa.B33)): spa.B11 = afbiso.B11 spa.B22 = afbiso.B22 spa.B33 = afbiso.B33 spa.B12 = afbiso.B12 spa.B13 = afbiso.B13 spa.B23 = afbiso.B23 recipe.addVar(p, tags=tags) # constrain delta2, qdamp and qbroad p = cpdf.cif.delta2 v = p.value or self.fbdelta2 recipe.addVar(p, value=v, tag='phase') p = cpdf.qdamp v = p.value or self.fbqdamp recipe.addVar(p, value=v, tag='experiment') p = cpdf.qbroad v = p.value or self.fbqbroad recipe.addVar(p, value=v, tag='experiment') return recipe
mnofit.addVar(par, value=0.003, fixed=True) # As usual, we add variables for the overall scale of the PDF and a delta2 # parameter for correlated motion of neighboring atoms. mnofit.addVar(totpdf.nucscale, 1) mnofit.addVar(nucpdf.delta2, 1.5) # We fix Qdamp based on prior information about our beamline. mnofit.addVar(nucpdf.qdamp, 0.03, fixed=True) # add the mPDF variables mnofit.addVar(totpdf.parascale, 4) mnofit.addVar(totpdf.ordscale, 1.5) # Turn off printout of iteration number. mnofit.clearFitHooks() # Initial structural fit print "Refine PDF using scipy's least-squares optimizer:" print " variables:", mnofit.names print " initial values:", mnofit.values leastsq(mnofit.residual, mnofit.values) print " final values:", mnofit.values print # Obtain and display the fit results. mnoresults = FitResults(mnofit) print "FIT RESULTS\n" print mnoresults # Get the experimental data from the recipe
cdseFit.constrain(atom.Biso, SeBiso) # Now we create a zoomscale factor which stretches the structure model, this is # useful when you want to fit the bond length. Note that the relative position # of atoms are not changed during the refinements zoomscale = cdseFit.newVar('zoomscale', value=1.0) # Here is a simple we to assign the zoomscale to the structure. Note that this # only works for NON-PERIODIC structure lattice = cdsePDF.CdSe.phase.getLattice() cdseFit.constrain(lattice.a, zoomscale) cdseFit.constrain(lattice.b, zoomscale) cdseFit.constrain(lattice.c, zoomscale) # Turn off printout of iteration number. cdseFit.clearFitHooks() # We can now execute the fit using scipy's least square optimizer. print("Refine PDF using scipy's least-squares optimizer:") print(" variables:", cdseFit.names) print(" initial values:", cdseFit.values) leastsq(cdseFit.residual, cdseFit.values) print(" final values:", cdseFit.values) print() # Obtain and display the fit results. cdseResults = FitResults(cdseFit) print("FIT RESULTS\n") print(cdseResults) # Plot the observed and refined PDF.
print("linefit.evaluate() =", linefit.evaluate()) print("linefit.residual() =", linefit.residual()) plt.plot(xobs, yobs, 'x', linedata.x, linefit.evaluate(), '-') plt.title('Line simulated at A=3, B=5') # <demo> --- stop --- # We want to find optimum model parameters that fit the simulated curve # to the observations. This is done by associating FitContribution with # a FitRecipe object. FitRecipe can manage multiple fit contributions and # optimize all models to fit their respective profiles. from diffpy.srfit.fitbase import FitRecipe rec = FitRecipe() # clearFitHooks suppresses printout of iteration number rec.clearFitHooks() rec.addContribution(linefit) rec.show() # <demo> --- stop --- # FitContributions may have many parameters. We need to tell the recipe # which of them should be tuned by the fit. rec.addVar(rec.linefit.A) rec.addVar(rec.linefit.B) # The addVar function created two attributes A, B for the rec object # which link ot the A and B parameters of the linefit contribution.
plt.title( 'Two Gaussians simulated at A=25000, x0=40, sig=20 and A=500, x0=68, sig=3' ) # <demo> --- stop --- # We want to find optimum model parameters that fit the simulated curve # to the observations. This is done by associating FitContribution with # a FitRecipe object. FitRecipe can manage multiple fit contributions and # optimize all models to fit their respective profiles. from diffpy.srfit.fitbase import FitRecipe recipe = FitRecipe() # clearFitHooks suppresses printout of iteration number recipe.clearFitHooks() recipe.addContribution(large_gaussian) recipe.addContribution(small_gaussian) recipe.show() # <demo> --- stop --- # FitContributions may have many parameters. We need to tell the recipe # which of them should be tuned by the fit. recipe.addVar(large_gaussian.lgA) recipe.addVar(large_gaussian.lgx0) recipe.addVar(large_gaussian.lgsig)
import numpy as np from pyobjcryst import loadCrystal from diffpy.srfit.pdf import PDFContribution from diffpy.srfit.fitbase import Profile, FitRecipe, FitResults nphcrystal = loadCrystal('naphthalene.cif') pdfcntb = PDFContribution('pdfcntb') pdfcntb.loadData('naphthalene.gr') pdfcntb.qdamp = 0.06 pdfcntb.setCalculationRange(1.1, 25) pdfcntb.addStructure('nph', nphcrystal) nphfit = FitRecipe() nphfit.clearFitHooks() nphfit.addContribution(pdfcntb) nphfit.addVar(pdfcntb.scale, name='scale') nphfit.addVar(pdfcntb.nph.delta2, value=1.0) nphase = pdfcntb.nph.phase # unit cell parameters nphfit.addVar(nphase.a) nphfit.addVar(nphase.b) nphfit.addVar(nphase.c) # cell-angle beta is in radians in ObjCryst Crystal # we will refine angle in degrees. nphfit.newVar('beta', value=np.degrees(nphase.beta.value)) nphfit.constrain(nphase.beta, 'radians(beta)') # all carbon species have the same displacement parameter, # it is sufficient to add constraint for the C1 atom
for par in spaceGroupParams.latpars: MnOFit.addVar(par) # Set initial value for the ADP parameters, because CIF had no ADP data. for par in spaceGroupParams.adppars: MnOFit.addVar(par, value=0.003,fixed=True) # As usual, we add variables for the overall scale of the PDF and a delta2 # parameter for correlated motion of neighboring atoms. MnOFit.addVar(MnOPDF.scale, 1) MnOFit.addVar(MnOPDF.MnO.delta2, 1.5) # We fix Qdamp based on prior information about our beamline. MnOFit.addVar(MnOPDF.qdamp, 0.03, fixed=True) # Turn off printout of iteration number. MnOFit.clearFitHooks() # We can now execute the fit using scipy's least square optimizer. print("Refine PDF using scipy's least-squares optimizer:") print(" variables:", MnOFit.names) print(" initial values:", MnOFit.values) leastsq(MnOFit.residual, MnOFit.values) print(" final values:", MnOFit.values) print() # Obtain and display the fit results. MnOResults = FitResults(MnOFit) print("FIT RESULTS\n") print(MnOResults) # Get the experimental data from the recipe