diff --git a/diffpy/__init__.py b/diffpy/__init__.py index ebd7ab11..0590714f 100644 --- a/diffpy/__init__.py +++ b/diffpy/__init__.py @@ -19,6 +19,7 @@ from pkgutil import extend_path + __path__ = extend_path(__path__, __name__) diff --git a/diffpy/pdfmorph/__init__.py b/diffpy/pdfmorph/__init__.py index 532ffe37..5b1dc543 100644 --- a/diffpy/pdfmorph/__init__.py +++ b/diffpy/pdfmorph/__init__.py @@ -20,6 +20,6 @@ __version__ = '0.0.1' # top-level import -from diffpy.pdfmorph.pdfmorph_api import (pdfmorph, morph_default_config, - plot_morph) +from diffpy.pdfmorph.pdfmorph_api import pdfmorph, morph_default_config, plot_morph + # End of file diff --git a/diffpy/pdfmorph/log.py b/diffpy/pdfmorph/log.py index 782cb707..42e5d507 100644 --- a/diffpy/pdfmorph/log.py +++ b/diffpy/pdfmorph/log.py @@ -45,4 +45,5 @@ def setVerbosity(vb): plog.info("log level set to %r", level) return + # End of file diff --git a/diffpy/pdfmorph/morphs/__init__.py b/diffpy/pdfmorph/morphs/__init__.py index aa4bbe65..3cb0be47 100644 --- a/diffpy/pdfmorph/morphs/__init__.py +++ b/diffpy/pdfmorph/morphs/__init__.py @@ -31,8 +31,19 @@ from diffpy.pdfmorph.morphs.morphstretch import MorphStretch # List of morphs -morphs = [ MorphRGrid, MorphScale, MorphStretch, MorphXtalPDFtoRDF, MorphSmear, - MorphXtalRDFtoPDF, MorphSphere, MorphSpheroid, MorphISphere, - MorphISpheroid, MorphResolutionDamping, MorphShift] +morphs = [ + MorphRGrid, + MorphScale, + MorphStretch, + MorphXtalPDFtoRDF, + MorphSmear, + MorphXtalRDFtoPDF, + MorphSphere, + MorphSpheroid, + MorphISphere, + MorphISpheroid, + MorphResolutionDamping, + MorphShift, +] # End of file diff --git a/diffpy/pdfmorph/morphs/morph.py b/diffpy/pdfmorph/morphs/morph.py index 57b1ee31..1799643b 100644 --- a/diffpy/pdfmorph/morphs/morph.py +++ b/diffpy/pdfmorph/morphs/morph.py @@ -18,9 +18,10 @@ """ -LABEL_RA = 'r (A)' # r-grid -LABEL_GR = 'G (1/A^2)' # PDF G(r) -LABEL_RR = 'R (1/A)' # RDF R(r) +LABEL_RA = 'r (A)' # r-grid +LABEL_GR = 'G (1/A^2)' # PDF G(r) +LABEL_RR = 'R (1/A)' # RDF R(r) + class Morph(object): '''Base class for implementing a morph on an objective given a reference. @@ -75,17 +76,26 @@ class Morph(object): # Properties - xyobjin = property(lambda self: (self.xobjin, self.yobjin), - doc='Return a tuple of objective input arrays') - xyobjout = property(lambda self: (self.xobjout, self.yobjout), - doc='Return a tuple of objective output arrays') - xyrefin = property(lambda self: (self.xrefin, self.yrefin), - doc='Return a tuple of reference input arrays') - xyrefout = property(lambda self: (self.xrefout, self.yrefout), - doc='Return a tuple of reference output arrays') - xyallout = property(lambda self: - (self.xobjout, self.yobjout, self.xrefout, self.yrefout), - doc='Return a tuple of all output arrays') + xyobjin = property( + lambda self: (self.xobjin, self.yobjin), + doc='Return a tuple of objective input arrays', + ) + xyobjout = property( + lambda self: (self.xobjout, self.yobjout), + doc='Return a tuple of objective output arrays', + ) + xyrefin = property( + lambda self: (self.xrefin, self.yrefin), + doc='Return a tuple of reference input arrays', + ) + xyrefout = property( + lambda self: (self.xrefout, self.yrefout), + doc='Return a tuple of reference output arrays', + ) + xyallout = property( + lambda self: (self.xobjout, self.yobjout, self.xrefout, self.yrefout), + doc='Return a tuple of all output arrays', + ) def __init__(self, config=None): '''Create a default Morph instance. @@ -107,7 +117,6 @@ def __init__(self, config=None): self.applyConfig(config) return - def morph(self, xobj, yobj, xref, yref): '''Morph arrays objective or reference. @@ -130,13 +139,10 @@ def morph(self, xobj, yobj, xref, yref): self.checkConfig() return self.xyallout - def __call__(self, xobj, yobj, xref, yref): - '''Alias for morph. - ''' + '''Alias for morph.''' return self.morph(xobj, yobj, xref, yref) - def applyConfig(self, config): '''Process any configuration data from a dictionary. @@ -147,7 +153,6 @@ def applyConfig(self, config): self.config = config return - def checkConfig(self): '''Verify data in self.config. No action by default. @@ -155,7 +160,6 @@ def checkConfig(self): ''' return - def plotInputs(self, xylabels=True): '''Plot input arrays using matplotlib.pyplot @@ -164,14 +168,14 @@ def plotInputs(self, xylabels=True): Return a list of matplotlib line objects. ''' from matplotlib.pyplot import plot, xlabel, ylabel - rv = plot(self.xrefin, self.yrefin, label = "reference") - rv = plot(self.xobjin, self.yobjin, label = "objective") + + rv = plot(self.xrefin, self.yrefin, label="reference") + rv = plot(self.xobjin, self.yobjin, label="objective") if xylabels: xlabel(self.xinlabel) ylabel(self.yinlabel) return rv - def plotOutputs(self, xylabels=True, **plotargs): '''Plot output arrays using matplotlib.pyplot @@ -182,16 +186,16 @@ def plotOutputs(self, xylabels=True, **plotargs): Return a list of matplotlib line objects. ''' from matplotlib.pyplot import plot, xlabel, ylabel + pargs = dict(plotargs) pargs.pop("label", None) - rv = plot(self.xrefout, self.yrefout, label = "reference", **pargs) - rv = plot(self.xobjout, self.yobjout, label = "objective", **pargs) + rv = plot(self.xrefout, self.yrefout, label="reference", **pargs) + rv = plot(self.xobjout, self.yobjout, label="objective", **pargs) if xylabels: xlabel(self.xoutlabel) ylabel(self.youtlabel) return rv - def __getattr__(self, name): '''Obtain the value from self.config, when normal lookup fails. @@ -206,7 +210,6 @@ def __getattr__(self, name): emsg = 'Object has no attribute %r' % name raise AttributeError(emsg) - def __setattr__(self, name, val): '''Set configuration variables to config. @@ -220,5 +223,5 @@ def __setattr__(self, name, val): object.__setattr__(self, name, val) return -# End class Morph +# End class Morph diff --git a/diffpy/pdfmorph/morphs/morphchain.py b/diffpy/pdfmorph/morphs/morphchain.py index 090e4cdd..d062aff9 100644 --- a/diffpy/pdfmorph/morphs/morphchain.py +++ b/diffpy/pdfmorph/morphs/morphchain.py @@ -52,41 +52,32 @@ class MorphChain(list): ''' - xobjin = property( - lambda self: None if len(self) == 0 else self[0].xobjin) - yobjin = property( - lambda self: None if len(self) == 0 else self[0].yobjin) - xrefin = property( - lambda self: None if len(self) == 0 else self[0].xrefin) - yrefin = property( - lambda self: None if len(self) == 0 else self[0].yrefin) - xobjout = property( - lambda self: None if len(self) == 0 else self[-1].xobjout) - yobjout = property( - lambda self: None if len(self) == 0 else self[-1].yobjout) - xrefout = property( - lambda self: None if len(self) == 0 else self[-1].xrefout) - yrefout = property( - lambda self: None if len(self) == 0 else self[-1].yrefout) - xyobjin = property( - lambda self: (None, None) if len(self) == 0 else self[0].xyobjin) + xobjin = property(lambda self: None if len(self) == 0 else self[0].xobjin) + yobjin = property(lambda self: None if len(self) == 0 else self[0].yobjin) + xrefin = property(lambda self: None if len(self) == 0 else self[0].xrefin) + yrefin = property(lambda self: None if len(self) == 0 else self[0].yrefin) + xobjout = property(lambda self: None if len(self) == 0 else self[-1].xobjout) + yobjout = property(lambda self: None if len(self) == 0 else self[-1].yobjout) + xrefout = property(lambda self: None if len(self) == 0 else self[-1].xrefout) + yrefout = property(lambda self: None if len(self) == 0 else self[-1].yrefout) + xyobjin = property(lambda self: (None, None) if len(self) == 0 else self[0].xyobjin) xyobjout = property( - lambda self: (None, None) if len(self) == 0 else self[-1].xyobjout) - xyrefin = property( - lambda self: (None, None) if len(self) == 0 else self[0].xyrefin) + lambda self: (None, None) if len(self) == 0 else self[-1].xyobjout + ) + xyrefin = property(lambda self: (None, None) if len(self) == 0 else self[0].xyrefin) xyrefout = property( - lambda self: (None, None) if len(self) == 0 else self[-1].xyrefout) + lambda self: (None, None) if len(self) == 0 else self[-1].xyrefout + ) xyallout = property( - lambda self: (None, None, None, None) if len(self) == 0 \ - else self[-1].xyallout) + lambda self: (None, None, None, None) if len(self) == 0 else self[-1].xyallout + ) parnames = property(lambda self: set(p for m in self for p in m.parnames)) - def __init__(self, config, *args): """Initialize the configuration. config -- Configuration dictionary. - + Additional arguments are morphs that will extend the queue of morphs. """ @@ -94,7 +85,6 @@ def __init__(self, config, *args): self.extend(args) return - def morph(self, xobj, yobj, xref, yref): '''Apply the chain of morphs to the input data. @@ -112,13 +102,10 @@ def morph(self, xobj, yobj, xref, yref): xyall = morph(*xyall) return xyall - def __call__(self, xobj, yobj, xref, yref): - '''Alias for morph. - ''' + '''Alias for morph.''' return self.morph(xobj, yobj, xref, yref) - def __getattr__(self, name): '''Obtain the value from self.config, when normal lookup fails. @@ -133,7 +120,6 @@ def __getattr__(self, name): emsg = 'Object has no attribute %r' % name raise AttributeError(emsg) - def __setattr__(self, name, val): '''Set configuration variables to config. @@ -149,4 +135,3 @@ def __setattr__(self, name, val): # End class MorphChain - diff --git a/diffpy/pdfmorph/morphs/morphishape.py b/diffpy/pdfmorph/morphs/morphishape.py index 7f396c6f..f2d191f5 100644 --- a/diffpy/pdfmorph/morphs/morphishape.py +++ b/diffpy/pdfmorph/morphs/morphishape.py @@ -22,6 +22,7 @@ class MorphISpheroid -- apply inverse spheroidal shape function from diffpy.pdfmorph.morphs.morph import * from diffpy.pdfmorph.morphs.morphshape import _sphericalCF, _spheroidalCF + class MorphISphere(Morph): '''Apply inverse spherical characteristic function to the objective @@ -47,8 +48,10 @@ def morph(self, xobj, yobj, xref, yref): self.yobjout[f == 0] = 0 return self.xyallout + # End of class MorphISphere + class MorphISpheroid(Morph): '''Apply inverse spherical characteristic function to the objective @@ -75,4 +78,5 @@ def morph(self, xobj, yobj, xref, yref): self.yobjout[f == 0] == 0 return self.xyallout + # End of class MorphSpheroid diff --git a/diffpy/pdfmorph/morphs/morphpdftordf.py b/diffpy/pdfmorph/morphs/morphpdftordf.py index 8579ebf3..130a146e 100644 --- a/diffpy/pdfmorph/morphs/morphpdftordf.py +++ b/diffpy/pdfmorph/morphs/morphpdftordf.py @@ -20,6 +20,7 @@ from diffpy.pdfmorph.morphs.morph import * + class MorphXtalPDFtoRDF(Morph): '''Morph crystal PDFs to RDFs. @@ -53,4 +54,5 @@ def morph(self, xobj, yobj, xref, yref): self.yrefout = self.xrefin * (self.yrefin - refbaseline) return self.xyallout + # End of class MorphXtalPDFtoRDF diff --git a/diffpy/pdfmorph/morphs/morphrdftopdf.py b/diffpy/pdfmorph/morphs/morphrdftopdf.py index 8e4e7f89..e6577064 100644 --- a/diffpy/pdfmorph/morphs/morphrdftopdf.py +++ b/diffpy/pdfmorph/morphs/morphrdftopdf.py @@ -50,12 +50,13 @@ def morph(self, xobj, yobj, xref, yref): Morph.morph(self, xobj, yobj, xref, yref) objbaseline = self.baselineslope * self.xobjin refbaseline = self.baselineslope * self.xrefin - self.yrefout = self.yrefin / self.xrefin + refbaseline + self.yrefout = self.yrefin / self.xrefin + refbaseline if self.xrefin[0] == 0: self.yrefout[0] = 0 - self.yobjout = self.yobjin / self.xobjin + objbaseline + self.yobjout = self.yobjin / self.xobjin + objbaseline if self.xobjin[0] == 0: self.yobjout[0] = 0 return self.xyallout + # End of class MorphScale diff --git a/diffpy/pdfmorph/morphs/morphresolution.py b/diffpy/pdfmorph/morphs/morphresolution.py index ef2f85e6..a57c8991 100644 --- a/diffpy/pdfmorph/morphs/morphresolution.py +++ b/diffpy/pdfmorph/morphs/morphresolution.py @@ -22,6 +22,7 @@ from diffpy.pdfmorph.morphs.morph import * + class MorphResolutionDamping(Morph): '''Apply resolution damping and broadening to the objective. @@ -44,9 +45,9 @@ class MorphResolutionDamping(Morph): def morph(self, xobj, yobj, xref, yref): """Apply a resolution damping.""" Morph.morph(self, xobj, yobj, xref, yref) - b = numpy.exp(-0.5 * (self.xobjin*self.qdamp)**2) + b = numpy.exp(-0.5 * (self.xobjin * self.qdamp) ** 2) self.yobjout *= b return self.xyallout -# End of class MorphResolutionDamping +# End of class MorphResolutionDamping diff --git a/diffpy/pdfmorph/morphs/morphrgrid.py b/diffpy/pdfmorph/morphs/morphrgrid.py index 7a8ecc08..8c620e0d 100644 --- a/diffpy/pdfmorph/morphs/morphrgrid.py +++ b/diffpy/pdfmorph/morphs/morphrgrid.py @@ -24,6 +24,7 @@ # roundoff tolerance for selecting bounds on arrays. epsilon = 1e-8 + class MorphRGrid(Morph): '''Resample to specified r-grid. @@ -40,7 +41,7 @@ class MorphRGrid(Morph): If any of these is not defined or outside the bounds of the input arrays, then it will be taken to be the most inclusive value from the input arrays. These modified values will be stored as the above attributes. - + ''' # Define input output types @@ -72,4 +73,5 @@ def morph(self, xobj, yobj, xref, yref): self.yrefout = numpy.interp(self.xrefout, self.xrefin, self.yrefin) return self.xyallout + # End of class MorphRGrid diff --git a/diffpy/pdfmorph/morphs/morphscale.py b/diffpy/pdfmorph/morphs/morphscale.py index f98f6511..e5f4ad2d 100644 --- a/diffpy/pdfmorph/morphs/morphscale.py +++ b/diffpy/pdfmorph/morphs/morphscale.py @@ -20,6 +20,7 @@ from diffpy.pdfmorph.morphs.morph import * + class MorphScale(Morph): '''Scale the objective. @@ -45,4 +46,5 @@ def morph(self, xobj, yobj, xref, yref): self.yobjout *= self.scale return self.xyallout + # End of class MorphScale diff --git a/diffpy/pdfmorph/morphs/morphshape.py b/diffpy/pdfmorph/morphs/morphshape.py index b65b2cb9..a7f75bc7 100644 --- a/diffpy/pdfmorph/morphs/morphshape.py +++ b/diffpy/pdfmorph/morphs/morphshape.py @@ -26,6 +26,7 @@ class MorphSpheroid -- apply a spheroidal shape function to the objective from diffpy.pdfmorph.morphs.morph import * + class MorphSphere(Morph): '''Apply a spherical characteristic function to the objective @@ -50,8 +51,10 @@ def morph(self, xobj, yobj, xref, yref): self.yobjout *= f return self.xyallout + # End of class MorphSphere + class MorphSpheroid(Morph): '''Apply a spherical characteristic function to the objective @@ -77,26 +80,29 @@ def morph(self, xobj, yobj, xref, yref): self.yobjout *= f return self.xyallout + # End of class MorphSpheroid + def _sphericalCF(r, psize): """Spherical nanoparticle characteristic function. - + r -- distance of interaction psize -- The particle diameter - - From Kodama et al., Acta Cryst. A, 62, 444-453 + + From Kodama et al., Acta Cryst. A, 62, 444-453 (converted from radius to diameter) """ f = numpy.zeros_like(r) - if psize > 0: - x = r/psize - g = (1.0 - 1.5*x + 0.5*x*x*x) + if psize > 0: + x = r / psize + g = 1.0 - 1.5 * x + 0.5 * x * x * x g[x > 1] = 0 f += g return f + def _spheroidalCF(r, erad, prad): """Spheroidal characteristic function specified using radii. @@ -110,74 +116,102 @@ def _spheroidalCF(r, erad, prad): erad == prad is a sphere """ - psize = 2*erad + psize = 2 * erad pelpt = prad / erad return _spheroidalCF2(r, psize, pelpt) + def _spheroidalCF2(r, psize, axrat): """Spheroidal nanoparticle characteristic function. Form factor for ellipsoid with radii (psize/2, psize/2, axrat*psize/2) - + r -- distance of interaction psize -- The equatorial diameter axrat -- The ratio of axis lengths From Lei et al., Phys. Rev. B, 80, 024118 (2009) - + """ pelpt = axrat - if psize <= 0 or pelpt <= 0: + if psize <= 0 or pelpt <= 0: return numpy.zeros_like(r) # to simplify the equations v = pelpt d = psize - d2 = d*d - v2 = v*v + d2 = d * d + v2 = v * v - if v == 1: + if v == 1: return _sphericalCF(r, psize) rx = r if v < 1: - - r = rx[rx <= v*psize] - r2 = r*r - f1 = 1 - 3*r/(4*d*v)*(1-r2/(4*d2)*(1+2.0/(3*v2))) \ - - 3*r/(4*d)*(1-r2/(4*d2))*v/sqrt(1-v2)*atanh(sqrt(1-v2)) - - r = rx[numpy.logical_and(rx > v*psize, rx <= psize)] - r2 = r*r - f2 = (3*d/(8*r)*(1+r2/(2*d2))*sqrt(1-r2/d2) \ - - 3*r/(4*d)*(1-r2/(4*d2))*atanh(sqrt(1-r2/d2)) \ - ) * v/sqrt(1-v2) + r = rx[rx <= v * psize] + r2 = r * r + f1 = ( + 1 + - 3 * r / (4 * d * v) * (1 - r2 / (4 * d2) * (1 + 2.0 / (3 * v2))) + - 3 + * r + / (4 * d) + * (1 - r2 / (4 * d2)) + * v + / sqrt(1 - v2) + * atanh(sqrt(1 - v2)) + ) + + r = rx[numpy.logical_and(rx > v * psize, rx <= psize)] + r2 = r * r + f2 = ( + ( + 3 * d / (8 * r) * (1 + r2 / (2 * d2)) * sqrt(1 - r2 / d2) + - 3 * r / (4 * d) * (1 - r2 / (4 * d2)) * atanh(sqrt(1 - r2 / d2)) + ) + * v + / sqrt(1 - v2) + ) r = rx[rx > psize] f3 = numpy.zeros_like(r) - f = numpy.concatenate((f1,f2,f3)) + f = numpy.concatenate((f1, f2, f3)) elif v > 1: - r = rx[rx <= psize] - r2 = r*r - f1 = 1 - 3*r/(4*d*v)*(1-r2/(4*d2)*(1+2.0/(3*v2))) \ - - 3*r/(4*d)*(1-r2/(4*d2))*v/sqrt(v2-1)*atan(sqrt(v2-1)) - - r = rx[numpy.logical_and(rx > psize, rx <= v*psize)] - r2 = r*r - f2 = 1 - 3*r/(4*d*v)*(1-r2/(4*d2)*(1+2.0/(3*v2))) \ - - 3.0/8*(1+r2/(2*d2))*sqrt(1-d2/r2)*v/sqrt(v2-1) \ - - 3*r/(4*d)*(1-r2/(4*d2))*v/sqrt(v2-1) \ - * (atan(sqrt(v2-1)) - atan(sqrt(r2/d2-1))) - - r = rx[rx > v*psize] + r2 = r * r + f1 = ( + 1 + - 3 * r / (4 * d * v) * (1 - r2 / (4 * d2) * (1 + 2.0 / (3 * v2))) + - 3 + * r + / (4 * d) + * (1 - r2 / (4 * d2)) + * v + / sqrt(v2 - 1) + * atan(sqrt(v2 - 1)) + ) + + r = rx[numpy.logical_and(rx > psize, rx <= v * psize)] + r2 = r * r + f2 = ( + 1 + - 3 * r / (4 * d * v) * (1 - r2 / (4 * d2) * (1 + 2.0 / (3 * v2))) + - 3.0 / 8 * (1 + r2 / (2 * d2)) * sqrt(1 - d2 / r2) * v / sqrt(v2 - 1) + - 3 + * r + / (4 * d) + * (1 - r2 / (4 * d2)) + * v + / sqrt(v2 - 1) + * (atan(sqrt(v2 - 1)) - atan(sqrt(r2 / d2 - 1))) + ) + + r = rx[rx > v * psize] f3 = numpy.zeros_like(r) - f = numpy.concatenate((f1,f2,f3)) + f = numpy.concatenate((f1, f2, f3)) return f - - diff --git a/diffpy/pdfmorph/morphs/morphshift.py b/diffpy/pdfmorph/morphs/morphshift.py index c9c63a2d..18148a2d 100644 --- a/diffpy/pdfmorph/morphs/morphshift.py +++ b/diffpy/pdfmorph/morphs/morphshift.py @@ -21,6 +21,7 @@ from diffpy.pdfmorph.morphs.morph import * import numpy + class MorphShift(Morph): '''Shift the objective. @@ -50,4 +51,5 @@ def morph(self, xobj, yobj, xref, yref): self.yobjout += self.vshift return self.xyallout + # End of class MorphShift diff --git a/diffpy/pdfmorph/morphs/morphsmear.py b/diffpy/pdfmorph/morphs/morphsmear.py index bbafe1f9..0484acca 100644 --- a/diffpy/pdfmorph/morphs/morphsmear.py +++ b/diffpy/pdfmorph/morphs/morphsmear.py @@ -21,6 +21,7 @@ import numpy from diffpy.pdfmorph.morphs.morph import * + class MorphSmear(Morph): '''Smear the objective function. @@ -53,17 +54,17 @@ def morph(self, xobj, yobj, xref, yref): r = self.xobjin rr = self.yobjin r0 = r[len(r) // 2] - gaussian = numpy.exp(-0.5 * ((r - r0)/self.smear)**2 ) + gaussian = numpy.exp(-0.5 * ((r - r0) / self.smear) ** 2) # Get the full convolution c = numpy.convolve(rr, gaussian, mode="full") # Find the centroid of the RDF, we don't want this to change from the # convolution. x1 = numpy.arange(len(rr), dtype=float) - c1idx = numpy.sum(rr * x1)/sum(rr) + c1idx = numpy.sum(rr * x1) / sum(rr) # Find the centroid of the convolution xc = numpy.arange(len(c), dtype=float) - ccidx = numpy.sum(c * xc)/sum(c) + ccidx = numpy.sum(c * xc) / sum(c) # Interpolate the convolution such that the centroids line up. This # uses linear interpolation. shift = ccidx - c1idx @@ -77,4 +78,5 @@ def morph(self, xobj, yobj, xref, yref): return self.xyallout + # End of class MorphSmear diff --git a/diffpy/pdfmorph/morphs/morphstretch.py b/diffpy/pdfmorph/morphs/morphstretch.py index 37470802..eec7b8ab 100644 --- a/diffpy/pdfmorph/morphs/morphstretch.py +++ b/diffpy/pdfmorph/morphs/morphstretch.py @@ -21,6 +21,7 @@ import numpy from diffpy.pdfmorph.morphs.morph import * + class MorphStretch(Morph): '''Smear the objective function. @@ -51,4 +52,5 @@ def morph(self, xobj, yobj, xref, yref): self.yobjout = numpy.interp(r, self.xobjin, self.yobjin) return self.xyallout + # End of class MorphSmear diff --git a/diffpy/pdfmorph/pdfmorph_api.py b/diffpy/pdfmorph/pdfmorph_api.py index e1f0506d..750f3a91 100644 --- a/diffpy/pdfmorph/pdfmorph_api.py +++ b/diffpy/pdfmorph/pdfmorph_api.py @@ -15,6 +15,7 @@ import sys + if sys.version_info.major < 3: # old import for py2.7 from collections import Iterable @@ -28,14 +29,15 @@ # map of operation dict # TODO: include morphing on psize -_morph_step_dict = dict(scale=morphs.MorphScale, - stretch=morphs.MorphStretch, - smear=[morphs.MorphXtalPDFtoRDF, - morphs.MorphSmear, - morphs.MorphXtalRDFtoPDF], - qdamp=morphs.MorphResolutionDamping) -_default_config = dict(scale=None, stretch=None, smear=None, - baselineslope=None, qdamp=None) +_morph_step_dict = dict( + scale=morphs.MorphScale, + stretch=morphs.MorphStretch, + smear=[morphs.MorphXtalPDFtoRDF, morphs.MorphSmear, morphs.MorphXtalRDFtoPDF], + qdamp=morphs.MorphResolutionDamping, +) +_default_config = dict( + scale=None, stretch=None, smear=None, baselineslope=None, qdamp=None +) def morph_default_config(**kwargs): @@ -66,9 +68,21 @@ def morph_default_config(**kwargs): return rv -def pdfmorph(xobj, yobj, xref, yref, rmin=None, rmax=None, rstep=None, - pearson=False, add_pearson=False, fixed_operations=None, - refine=True, verbose=False, **kwargs): +def pdfmorph( + xobj, + yobj, + xref, + yref, + rmin=None, + rmax=None, + rstep=None, + pearson=False, + add_pearson=False, + fixed_operations=None, + refine=True, + verbose=False, + **kwargs +): """function to perfom PDF morphing. Parameters @@ -156,14 +170,14 @@ def pdfmorph(xobj, yobj, xref, yref, rmin=None, rmax=None, rstep=None, # input config rv_cfg = dict(kwargs) # configure morph operations - active_morphs = [k for k, v in rv_cfg.items() if (v is not None) and k in - _morph_step_dict] + active_morphs = [ + k for k, v in rv_cfg.items() if (v is not None) and k in _morph_step_dict + ] rv_cfg['rmin'] = rmin rv_cfg['rmax'] = rmax rv_cfg['rstep'] = rstep # configure smear, guess baselineslope when it is not provided - if (rv_cfg.get('smear') is not None - and rv_cfg.get('baselineslope') is None): + if rv_cfg.get('smear') is not None and rv_cfg.get('baselineslope') is None: rv_cfg['baselineslope'] = -0.5 # config dict defines initial guess of parameters chain = morphs.MorphChain(rv_cfg) @@ -189,7 +203,7 @@ def pdfmorph(xobj, yobj, xref, yref, rmin=None, rmax=None, rstep=None, if pearson: refiner.residual = refiner._pearson if add_pearson: - refiner.residual = refiner._addpearson + refiner.residual = refiner._addpearson # execute morphing if refpars and refine: # This works better when we adjust scale and smear first. @@ -216,14 +230,14 @@ def pdfmorph(xobj, yobj, xref, yref, rmin=None, rmax=None, rstep=None, print("== INFO: Following steps are fixed during morphing ==:\n") print('\n'.join(fixed_operations)) print("== INFO: Refined morph parameters ==:\n") - output = "\n".join(["# %s = %f" % (k, v) for k, v in \ - rv_cfg.items() if v is not None]) + output = "\n".join( + ["# %s = %f" % (k, v) for k, v in rv_cfg.items() if v is not None] + ) output += "\n# Rw = %f" % rw output += "\n# Pearson = %f" % pcc print(output) - rv_dict = dict(morph_chain=chain, morphed_config=rv_cfg, - rw=rw, pcc=pcc) + rv_dict = dict(morph_chain=chain, morphed_config=rv_cfg, rw=rw, pcc=pcc) return rv_dict diff --git a/diffpy/pdfmorph/pdfmorphapp.py b/diffpy/pdfmorph/pdfmorphapp.py index 15b64545..ac211ea7 100755 --- a/diffpy/pdfmorph/pdfmorphapp.py +++ b/diffpy/pdfmorph/pdfmorphapp.py @@ -28,82 +28,154 @@ def createOptionParser(): - import optparse - parser = optparse.OptionParser( - usage = '\n'.join([ - "%prog [options] FILE1 FILE2", - "Manipulate and compare PDFs.", - ]), - epilog="Please report bugs to diffpy-dev@googlegroups.com." - ) - parser.add_option('-V', '--version', action="version", - help="Show program version and exit.") + parser = optparse.OptionParser( + usage='\n'.join( + [ + "%prog [options] FILE1 FILE2", + "Manipulate and compare PDFs.", + ] + ), + epilog="Please report bugs to diffpy-dev@googlegroups.com.", + ) + + parser.add_option( + '-V', '--version', action="version", help="Show program version and exit." + ) parser.version = __version__ - parser.add_option('-s', '--save', metavar="FILE", dest="savefile", - help="Save manipulated PDF from FILE1 to FILE.") - parser.add_option('--rmin', type="float", - help="Minimum r-value to use for PDF comparisons.") - parser.add_option('--rmax', type="float", - help="Maximum r-value to use for PDF comparisons.") - parser.add_option('--pearson', action="store_true", dest="pearson", - help="Maximize agreement in the Pearson function. Note that this is insensitive to scale.") - parser.add_option('--addpearson', action="store_true", dest="addpearson", - help="""Maximize agreement in the Pearson function as well as -minimizing the residual.""") - + parser.add_option( + '-s', + '--save', + metavar="FILE", + dest="savefile", + help="Save manipulated PDF from FILE1 to FILE.", + ) + parser.add_option( + '--rmin', type="float", help="Minimum r-value to use for PDF comparisons." + ) + parser.add_option( + '--rmax', type="float", help="Maximum r-value to use for PDF comparisons." + ) + parser.add_option( + '--pearson', + action="store_true", + dest="pearson", + help="Maximize agreement in the Pearson function. Note that this is insensitive to scale.", + ) + parser.add_option( + '--addpearson', + action="store_true", + dest="addpearson", + help="""Maximize agreement in the Pearson function as well as +minimizing the residual.""", + ) # Manipulations - group = optparse.OptionGroup(parser, "Manipulations", - """These options select the manipulations that are to be applied to + group = optparse.OptionGroup( + parser, + "Manipulations", + """These options select the manipulations that are to be applied to the PDF from FILE1. The passed values will be refined unless specifically excluded with the -a or -x options. If no option is specified, the PDFs from FILE1 and FILE2 will -be plotted without any manipulations.""") +be plotted without any manipulations.""", + ) parser.add_option_group(group) - group.add_option('-a', '--apply', action="store_false", dest="refine", - help="Apply manipulations but do not refine.") - group.add_option('-x', '--exclude', action="append", dest="exclude", - metavar="MANIP", - help="""Exclude a manipulation from refinement by name. This can -appear multiple times.""") - group.add_option('--scale', type="float", metavar="SCALE", - help="Apply scale factor SCALE.") - group.add_option('--smear', type="float", metavar="SMEAR", - help="Smear peaks with a Gaussian of width SMEAR.") - group.add_option('--stretch', type="float", metavar="STRETCH", - help="Stretch PDF by a fraction STRETCH.") - group.add_option('--slope', type="float", dest="baselineslope", - help="""Slope of the baseline. This is used when applying the smear -factor. It will be estimated if not provided.""") - group.add_option('--qdamp', type="float", metavar="QDAMP", - help="Dampen PDF by a factor QDAMP. (See PDFGui manual.)") - group.add_option('--radius', type="float", metavar="RADIUS", - help="""Apply characteristic function of sphere with radius RADIUS. -If PRADIUS is also specified, instead apply characteristic function of spheroid with equatorial radius RADIUS and polar radius PRADIUS.""") - group.add_option('--pradius', type="float", metavar="PRADIUS", - help="""Apply characteristic function of spheroid with equatorial -radius RADIUS and polar radius PRADIUS. If only PRADIUS is specified, instead apply characteristic function of sphere with radius PRADIUS.""") - group.add_option('--iradius', type="float", metavar="IRADIUS", - help="""Apply inverse characteristic function of sphere with radius IRADIUS. If IPRADIUS is also specified, instead apply inverse characteristic function of spheroid with equatorial radius IRADIUS and polar radius IPRADIUS.""") - group.add_option('--ipradius', type="float", metavar="IPRADIUS", - help="""Apply inverse characteristic function of spheroid with equatorial radius IRADIUS and polar radius IPRADIUS. If only IPRADIUS is specified, instead apply inverse characteristic function of sphere with radius IPRADIUS.""") + group.add_option( + '-a', + '--apply', + action="store_false", + dest="refine", + help="Apply manipulations but do not refine.", + ) + group.add_option( + '-x', + '--exclude', + action="append", + dest="exclude", + metavar="MANIP", + help="""Exclude a manipulation from refinement by name. This can +appear multiple times.""", + ) + group.add_option( + '--scale', type="float", metavar="SCALE", help="Apply scale factor SCALE." + ) + group.add_option( + '--smear', + type="float", + metavar="SMEAR", + help="Smear peaks with a Gaussian of width SMEAR.", + ) + group.add_option( + '--stretch', + type="float", + metavar="STRETCH", + help="Stretch PDF by a fraction STRETCH.", + ) + group.add_option( + '--slope', + type="float", + dest="baselineslope", + help="""Slope of the baseline. This is used when applying the smear +factor. It will be estimated if not provided.""", + ) + group.add_option( + '--qdamp', + type="float", + metavar="QDAMP", + help="Dampen PDF by a factor QDAMP. (See PDFGui manual.)", + ) + group.add_option( + '--radius', + type="float", + metavar="RADIUS", + help="""Apply characteristic function of sphere with radius RADIUS. +If PRADIUS is also specified, instead apply characteristic function of spheroid with equatorial radius RADIUS and polar radius PRADIUS.""", + ) + group.add_option( + '--pradius', + type="float", + metavar="PRADIUS", + help="""Apply characteristic function of spheroid with equatorial +radius RADIUS and polar radius PRADIUS. If only PRADIUS is specified, instead apply characteristic function of sphere with radius PRADIUS.""", + ) + group.add_option( + '--iradius', + type="float", + metavar="IRADIUS", + help="""Apply inverse characteristic function of sphere with radius IRADIUS. If IPRADIUS is also specified, instead apply inverse characteristic function of spheroid with equatorial radius IRADIUS and polar radius IPRADIUS.""", + ) + group.add_option( + '--ipradius', + type="float", + metavar="IPRADIUS", + help="""Apply inverse characteristic function of spheroid with equatorial radius IRADIUS and polar radius IPRADIUS. If only IPRADIUS is specified, instead apply inverse characteristic function of sphere with radius IPRADIUS.""", + ) # Plot Options - group = optparse.OptionGroup(parser, "Plot Options", - """These options control plotting.""") + group = optparse.OptionGroup( + parser, "Plot Options", """These options control plotting.""" + ) parser.add_option_group(group) - group.add_option('-n', '--noplot', action="store_false", dest="plot", - help="Do not show the plot.") - group.add_option('--pmin', type="float", - help="Minimum r-value to plot. Defaults to RMIN.") - group.add_option('--pmax', type="float", - help="Maximum r-value to plot. Defaults to RMAX.") - group.add_option('--maglim', type="float", - help="Magnify plot curves beyond MAGLIM by MAG.") - group.add_option('--mag', type="float", - help="Magnify plot curves beyond MAGLIM by MAG.") - + group.add_option( + '-n', + '--noplot', + action="store_false", + dest="plot", + help="Do not show the plot.", + ) + group.add_option( + '--pmin', type="float", help="Minimum r-value to plot. Defaults to RMIN." + ) + group.add_option( + '--pmax', type="float", help="Maximum r-value to plot. Defaults to RMAX." + ) + group.add_option( + '--maglim', type="float", help="Magnify plot curves beyond MAGLIM by MAG." + ) + group.add_option( + '--mag', type="float", help="Magnify plot curves beyond MAGLIM by MAG." + ) # Defaults parser.set_defaults(plot=True) @@ -114,6 +186,7 @@ def createOptionParser(): return parser + def main(): parser = createOptionParser() (opts, pargs) = parser.parse_args() @@ -130,32 +203,31 @@ def main(): config["rmin"] = opts.rmin config["rmax"] = opts.rmax config["rstep"] = None - if opts.rmin is not None and opts.rmax is not None and \ - opts.rmax <= opts.rmin: + if opts.rmin is not None and opts.rmax is not None and opts.rmax <= opts.rmin: e = "rmin must be less than rmax" parser.error(e) # Set up the morphs chain = morphs.MorphChain(config) # Add the r-range morph, we will remove it when saving and plotting - chain.append( morphs.MorphRGrid() ) + chain.append(morphs.MorphRGrid()) refpars = [] ## Scale if opts.scale is not None: - chain.append( morphs.MorphScale() ) + chain.append(morphs.MorphScale()) config["scale"] = opts.scale refpars.append("scale") ## Stretch if opts.stretch is not None: - chain.append( morphs.MorphStretch() ) + chain.append(morphs.MorphStretch()) config["stretch"] = opts.stretch refpars.append("stretch") ## Smear if opts.smear is not None: - chain.append( morphs.MorphXtalPDFtoRDF() ) - chain.append( morphs.MorphSmear() ) - chain.append( morphs.MorphXtalRDFtoPDF() ) + chain.append(morphs.MorphXtalPDFtoRDF()) + chain.append(morphs.MorphSmear()) + chain.append(morphs.MorphXtalRDFtoPDF()) refpars.append("smear") config["smear"] = opts.smear config["baselineslope"] = opts.baselineslope @@ -168,31 +240,31 @@ def main(): if nrad == 1: radii.remove(None) config["radius"] = radii[0] - chain.append( morphs.MorphSphere() ) + chain.append(morphs.MorphSphere()) refpars.append("radius") elif nrad == 2: config["radius"] = radii[0] refpars.append("radius") config["pradius"] = radii[1] refpars.append("pradius") - chain.append( morphs.MorphSpheroid() ) + chain.append(morphs.MorphSpheroid()) iradii = [opts.iradius, opts.ipradius] inrad = 2 - iradii.count(None) if inrad == 1: iradii.remove(None) config["iradius"] = iradii[0] - chain.append( morphs.MorphISphere() ) + chain.append(morphs.MorphISphere()) refpars.append("iradius") elif inrad == 2: config["iradius"] = iradii[0] refpars.append("iradius") config["ipradius"] = iradii[1] refpars.append("ipradius") - chain.append( morphs.MorphISpheroid() ) + chain.append(morphs.MorphISpheroid()) ## Resolution if opts.qdamp is not None: - chain.append( morphs.MorphResolutionDamping() ) + chain.append(morphs.MorphResolutionDamping()) refpars.append("qdamp") config["qdamp"] = opts.qdamp @@ -220,7 +292,7 @@ def main(): parser.error(str(e)) elif "smear" in refpars and opts.baselineslope is None: try: - refiner.refine("baselineslope", baselineslope = -0.5) + refiner.refine("baselineslope", baselineslope=-0.5) except ValueError as e: parser.error(str(e)) else: @@ -235,7 +307,7 @@ def main(): items = list(config.items()) items.sort() - output = "\n".join("# %s = %f"%i for i in items) + output = "\n".join("# %s = %f" % i for i in items) output += "\n# Rw = %f" % rw output += "\n# Pearson = %f" % pcc print(output) @@ -249,8 +321,7 @@ def main(): else: outfile = open(opts.savefile, 'w') print(header, file=outfile) - numpy.savetxt(outfile, numpy.transpose([chain.xobjout, - chain.yobjout])) + numpy.savetxt(outfile, numpy.transpose([chain.xobjout, chain.yobjout])) outfile.close() if opts.plot: @@ -261,14 +332,16 @@ def main(): pmax = opts.pmax if opts.pmax is not None else opts.rmax maglim = opts.maglim mag = opts.mag - pdfplot.comparePDFs(pairlist, labels, rmin = pmin, rmax = pmax, maglim - = maglim, mag = mag, rw = rw) + pdfplot.comparePDFs( + pairlist, labels, rmin=pmin, rmax=pmax, maglim=maglim, mag=mag, rw=rw + ) return def getPDFFromFile(fn): from diffpy.pdfmorph.tools import readPDF + try: r, gr = readPDF(fn) except IOError as errmsg: diff --git a/diffpy/pdfmorph/pdfplot.py b/diffpy/pdfmorph/pdfplot.py index 70bed23c..56efbd9e 100644 --- a/diffpy/pdfmorph/pdfplot.py +++ b/diffpy/pdfmorph/pdfplot.py @@ -20,9 +20,10 @@ plt.style.use(bg_mpl_style) + # FIXME - make this return the figure object in the future, so several views # can be composed. -def plotPDFs(pairlist, labels=None, offset ='auto', rmin = None, rmax = None): +def plotPDFs(pairlist, labels=None, offset='auto', rmin=None, rmax=None): """Plots several PDFs on top of one another. pairlist -- iterable of (r, gr) pairs to plot @@ -50,11 +51,11 @@ def plotPDFs(pairlist, labels=None, offset ='auto', rmin = None, rmax = None): for idx, pair in enumerate(pairlist): r, gr = pair - plt.plot(r, gr + idx * offset, label = labels(fit)) + plt.plot(r, gr + idx * offset, label=labels(fit)) plt.xlim(rmin, rmax) if gap == 0: - plt.legend(loc = 0) + plt.legend(loc=0) plt.legend() plt.xlabel(r"$r (\mathrm{\AA})$") @@ -62,8 +63,18 @@ def plotPDFs(pairlist, labels=None, offset ='auto', rmin = None, rmax = None): plt.show() return -def comparePDFs(pairlist, labels=None, rmin = None, rmax = None, show = True, - maglim = None, mag = 5, rw = None, legend = True): + +def comparePDFs( + pairlist, + labels=None, + rmin=None, + rmax=None, + show=True, + maglim=None, + mag=5, + rw=None, + legend=True, +): """Plot two PDFs on top of each other and difference curve. pairlist -- iterable of (r, gr) pairs to plot @@ -83,7 +94,7 @@ def comparePDFs(pairlist, labels=None, rmin = None, rmax = None, show = True, The second PDF will be shown as blue circles below and the first as a red line. The difference curve will be in green and offset for clarity. - + """ if labels is None: @@ -115,7 +126,7 @@ def comparePDFs(pairlist, labels=None, rmin = None, rmax = None, show = True, # Put rw in the label labeldiff = "difference" if len(labels) < 3 else labels[2] if rw is not None: - labeldiff += " (Rw = %.3f)"%rw + labeldiff += " (Rw = %.3f)" % rw # Magnify if necessary if maglim is not None: @@ -128,10 +139,10 @@ def comparePDFs(pairlist, labels=None, rmin = None, rmax = None, show = True, gtemp[sel] *= mag # Determine the offset for the difference curve. - sel = numpy.logical_and( rdat <= rvmax, rdat >= rvmin) + sel = numpy.logical_and(rdat <= rvmax, rdat >= rvmin) ymin = min(min(grdat[sel]), min(gtemp[sel])) ymax = max(diff[sel]) - offset = -1.1*(ymax - ymin) + offset = -1.1 * (ymax - ymin) # Scale the x-limit based on the r-extent of the signal. This gives a nice # density of PDF peaks. @@ -140,8 +151,8 @@ def comparePDFs(pairlist, labels=None, rmin = None, rmax = None, show = True, # Set a reasonable minimum of .8 and maximum of 1 scale = min(1, max(scale, 0.8)) figsize = [13.5, 4.5] - figsize[0] *= scale - fig = plt.figure(1, figsize = figsize) + figsize[0] *= scale + fig = plt.figure(1, figsize=figsize) # Get the margins based on the figure size lm = 0.12 / scale bm = 0.20 / scale @@ -151,21 +162,22 @@ def comparePDFs(pairlist, labels=None, rmin = None, rmax = None, show = True, fig.add_axes(axes) plt.minorticks_on() - plt.plot(rdat, grdat, label = labeldata) - plt.plot(rfit, grfit, label = labelfit) - plt.plot(rdat, offset*numpy.ones_like(diff), color = 'black') + plt.plot(rdat, grdat, label=labeldata) + plt.plot(rfit, grfit, label=labelfit) + plt.plot(rdat, offset * numpy.ones_like(diff), color='black') diff += offset - plt.plot(rdat, diff, label = labeldiff) + plt.plot(rdat, diff, label=labeldiff) if maglim is not None: # Add a line for the magnification cutoff - plt.axvline(maglim, 0, 1, linestyle = '--', color = 'black', - linewidth = 1.5, dashes = (14, 7)) + plt.axvline( + maglim, 0, 1, linestyle='--', color='black', linewidth=1.5, dashes=(14, 7) + ) # FIXME - look for a place to put the maglim - xpos = (rvmax*0.85 + maglim) / 2 / (rvmax - rvmin) + xpos = (rvmax * 0.85 + maglim) / 2 / (rvmax - rvmin) if xpos <= 0.9: - plt.figtext(xpos, 0.7, "x%.1f"%mag, backgroundcolor='w') + plt.figtext(xpos, 0.7, "x%.1f" % mag, backgroundcolor='w') # Get a tight view plt.xlim(rvmin, rvmax) @@ -182,13 +194,20 @@ def comparePDFs(pairlist, labels=None, rmin = None, rmax = None, show = True, plt.xlabel(r"r ($\mathrm{\AA})$") plt.ylabel(r"G $(\mathrm{\AA}^{-1})$") if legend: - plt.legend(bbox_to_anchor=(0.005, 1.02, 0.99, .10), loc=3, - ncol=3, mode="expand", borderaxespad=0) - if show: plt.show() + plt.legend( + bbox_to_anchor=(0.005, 1.02, 0.99, 0.10), + loc=3, + ncol=3, + mode="expand", + borderaxespad=0, + ) + if show: + plt.show() return -def truncatePDFs(r, gr, rmin = None, rmax = None): + +def truncatePDFs(r, gr, rmin=None, rmax=None): """Truncate a PDF to specified bounds. r -- r-values of the PDF @@ -212,6 +231,7 @@ def truncatePDFs(r, gr, rmin = None, rmax = None): return r, gr + def _findOffset(pairlist): """Find an optimal offset between PDFs.""" maxlist = [max(p[1]) for p in pairlist] diff --git a/diffpy/pdfmorph/refine.py b/diffpy/pdfmorph/refine.py index d7a0d1f5..26454ea2 100644 --- a/diffpy/pdfmorph/refine.py +++ b/diffpy/pdfmorph/refine.py @@ -23,6 +23,7 @@ # Map of scipy minimizer names to the method that uses them + class Refiner(object): """Class for refining a Morph or MorphChain. @@ -64,8 +65,9 @@ def _updateChain(self, pvals): def _residual(self, pvals): """Standard vector residual.""" self._updateChain(pvals) - _xobj, _yobj, _xref, _yref = self.chain(self.xobj, self.yobj, - self.xref, self.yref) + _xobj, _yobj, _xref, _yref = self.chain( + self.xobj, self.yobj, self.xref, self.yref + ) rvec = _yref - _yobj return rvec @@ -77,8 +79,9 @@ def _pearson(self, pvals): largest. """ self._updateChain(pvals) - _xobj, _yobj, _xref, _yref = self.chain(self.xobj, self.yobj, - self.xref, self.yref) + _xobj, _yobj, _xref, _yref = self.chain( + self.xobj, self.yobj, self.xref, self.yref + ) pcc, pval = pearsonr(_yobj, _yref) return ones_like(_xobj) * exp(-pcc) @@ -116,9 +119,9 @@ def refine(self, *args, **kw): return 0.0 initial = [config[p] for p in self.pars] - out = leastsq(self.residual, initial, full_output = 1) + out = leastsq(self.residual, initial, full_output=1) fvec = out[2]["fvec"] - if out[4] not in (1,2,3,4): + if out[4] not in (1, 2, 3, 4): mesg = out[3] raise ValueError(mesg) @@ -131,5 +134,4 @@ def refine(self, *args, **kw): return dot(fvec, fvec) - # End class Refiner diff --git a/diffpy/pdfmorph/tests/run.py b/diffpy/pdfmorph/tests/run.py index c4a1fd4c..d7a89c16 100644 --- a/diffpy/pdfmorph/tests/run.py +++ b/diffpy/pdfmorph/tests/run.py @@ -1,4 +1,3 @@ - #!/usr/bin/env python ############################################################################## # @@ -21,12 +20,15 @@ if __name__ == '__main__': import sys + # show warnings by default if not sys.warnoptions: import os, warnings + warnings.simplefilter("default") # also affect subprocesses os.environ["PYTHONWARNINGS"] = "default" from diffpy.pdfmorph.tests import test + # produce zero exit code for a successful test sys.exit(not test().wasSuccessful()) diff --git a/diffpy/pdfmorph/tests/test_morph_func.py b/diffpy/pdfmorph/tests/test_morph_func.py index c8591f48..bc38e356 100644 --- a/diffpy/pdfmorph/tests/test_morph_func.py +++ b/diffpy/pdfmorph/tests/test_morph_func.py @@ -12,9 +12,10 @@ def test_morphfunc_verbose(): stretch = 0.3 xobj = xref.copy() yobj = heaviside(xref, lb * (1 + stretch), ub * (1 + stretch)) - cfg = morph_default_config(stretch=0.1) # off init + cfg = morph_default_config(stretch=0.1) # off init morph_rv = pdfmorph(xobj, yobj, xref, yref, verbose=True, **cfg) + def test_fixed_morph_with_morphfunc(): lb, ub = 1, 2 xref = np.arange(0.01, 5, 0.01) @@ -23,10 +24,12 @@ def test_fixed_morph_with_morphfunc(): stretch = 0.3 xobj = xref.copy() yobj = heaviside(xref, lb * (1 + stretch), ub * (1 + stretch)) - cfg = morph_default_config(stretch=0.1) # off init + cfg = morph_default_config(stretch=0.1) # off init cfg['scale'] = 30 - morph_rv = pdfmorph(xobj, yobj, xref, yref, verbose=True, - fixed_operations=['scale'], **cfg) + morph_rv = pdfmorph( + xobj, yobj, xref, yref, verbose=True, fixed_operations=['scale'], **cfg + ) + def test_stretch_with_morphfunc(): # use the same setup as test_moprhchain @@ -37,7 +40,7 @@ def test_stretch_with_morphfunc(): stretch = 0.3 xobj = xref.copy() yobj = heaviside(xref, lb * (1 + stretch), ub * (1 + stretch)) - cfg = morph_default_config(stretch=0.1) # off init + cfg = morph_default_config(stretch=0.1) # off init morph_rv = pdfmorph(xobj, yobj, xref, yref, **cfg) morphed_cfg = morph_rv['morphed_config'] # verified they are morphable @@ -59,7 +62,7 @@ def test_scale_with_morphfunc(): xobj = xref.copy() yobj = yref.copy() yobj *= scale - cfg = morph_default_config(scale=1.5) # off init + cfg = morph_default_config(scale=1.5) # off init morph_rv = pdfmorph(xobj, yobj, xref, yref, **cfg) morphed_cfg = morph_rv['morphed_config'] # verified they are morphable @@ -67,25 +70,25 @@ def test_scale_with_morphfunc(): assert np.allclose(x0, x1) assert np.allclose(y0, y1) # verify morphed param - assert np.allclose(scale, 1/morphed_cfg['scale'], atol=1e-1) + assert np.allclose(scale, 1 / morphed_cfg['scale'], atol=1e-1) def test_smear_with_morph_func(): # gaussian func sigma0 = 0.1 smear = 0.15 - sigbroad = (sigma0**2 + smear**2)**0.5 + sigbroad = (sigma0**2 + smear**2) ** 0.5 r0 = 7 * np.pi / 22.0 * 2 xref = np.arange(0.01, 5, 0.01) - yref = np.exp(-0.5 * ((xref-r0)/sigbroad)**2) + yref = np.exp(-0.5 * ((xref - r0) / sigbroad) ** 2) xobj = xref.copy() - yobj = np.exp(-0.5 * ((xobj-r0)/sigma0)**2) - cfg = morph_default_config(smear=0.1, scale=1.1, stretch=0.1) # off init + yobj = np.exp(-0.5 * ((xobj - r0) / sigma0) ** 2) + cfg = morph_default_config(smear=0.1, scale=1.1, stretch=0.1) # off init morph_rv = pdfmorph(xobj, yobj, xref, yref, **cfg) morphed_cfg = morph_rv['morphed_config'] # verified they are morphable x1, y1, x0, y0 = morph_rv['morph_chain'].xyallout assert np.allclose(x0, x1) - assert np.allclose(y0, y1, atol=1e-3) # numerical error -> 1e-4 + assert np.allclose(y0, y1, atol=1e-3) # numerical error -> 1e-4 # verify morphed param assert np.allclose(smear, morphed_cfg['smear'], atol=1e-1) diff --git a/diffpy/pdfmorph/tests/test_morphchain.py b/diffpy/pdfmorph/tests/test_morphchain.py index 72e102b5..20ba2fb0 100644 --- a/diffpy/pdfmorph/tests/test_morphchain.py +++ b/diffpy/pdfmorph/tests/test_morphchain.py @@ -15,8 +15,8 @@ from diffpy.pdfmorph.morphs.morphscale import MorphScale from diffpy.pdfmorph.morphs.morphrgrid import MorphRGrid -class TestMorphChain(unittest.TestCase): +class TestMorphChain(unittest.TestCase): def setUp(self): self.xobj = numpy.arange(0.01, 5, 0.01) self.yobj = numpy.ones_like(self.xobj) @@ -26,22 +26,20 @@ def setUp(self): return def test_morph(self): - """check MorphChain.morph() - """ + """check MorphChain.morph()""" # Define the morphs config = { - "rmin" : 1, - "rmax" : 6, - "rstep" : 0.1, - "scale" : 3.0, - } + "rmin": 1, + "rmax": 6, + "rstep": 0.1, + "scale": 3.0, + } mgrid = MorphRGrid() mscale = MorphScale() chain = MorphChain(config, mgrid, mscale) - xobj, yobj, xref, yref = chain(self.xobj, self.yobj, self.xref, - self.yref) + xobj, yobj, xref, yref = chain(self.xobj, self.yobj, self.xref, self.yref) self.assertTrue((xobj == xref).all()) self.assertAlmostEqual(xobj[0], 1.0) @@ -53,6 +51,7 @@ def test_morph(self): self.assertTrue(numpy.allclose(yobj, yref)) return + # End of class TestMorphChain if __name__ == '__main__': diff --git a/diffpy/pdfmorph/tests/test_morphpdftordf.py b/diffpy/pdfmorph/tests/test_morphpdftordf.py index 5e268281..19f7cc0f 100644 --- a/diffpy/pdfmorph/tests/test_morphpdftordf.py +++ b/diffpy/pdfmorph/tests/test_morphpdftordf.py @@ -13,26 +13,24 @@ from diffpy.pdfmorph.morphs.morphpdftordf import MorphXtalPDFtoRDF -class TestMorphXtalPDFtoRDF(unittest.TestCase): +class TestMorphXtalPDFtoRDF(unittest.TestCase): def setUp(self): self.xobj = numpy.arange(0.01, 5, 0.01) - self.yobj = numpy.exp(-0.5 * (self.xobj-1.0)**2)/self.xobj - self.xobj + self.yobj = numpy.exp(-0.5 * (self.xobj - 1.0) ** 2) / self.xobj - self.xobj self.xref = numpy.arange(0.01, 5, 0.01) - self.yref = numpy.exp(-0.5 * (self.xobj-2.0)**2)/self.xobj - self.xobj + self.yref = numpy.exp(-0.5 * (self.xobj - 2.0) ** 2) / self.xobj - self.xobj return def test_morph(self): - """check MorphXtalPDFtoRDF.morph() - """ - config = { "baselineslope" : -1.0 } + """check MorphXtalPDFtoRDF.morph()""" + config = {"baselineslope": -1.0} morph = MorphXtalPDFtoRDF(config) - xobj, yobj, xref, yref = morph(self.xobj, self.yobj, self.xref, - self.yref) + xobj, yobj, xref, yref = morph(self.xobj, self.yobj, self.xref, self.yref) - rdf1 = numpy.exp(-0.5 * (xobj-1.0)**2) - rdf2 = numpy.exp(-0.5 * (xref-2.0)**2) + rdf1 = numpy.exp(-0.5 * (xobj - 1.0) ** 2) + rdf2 = numpy.exp(-0.5 * (xref - 2.0) ** 2) self.assertTrue(numpy.allclose(rdf1, yobj)) self.assertTrue(numpy.allclose(rdf2, yref)) return diff --git a/diffpy/pdfmorph/tests/test_morphrdftopdf.py b/diffpy/pdfmorph/tests/test_morphrdftopdf.py index ce7773c3..f8b4bc37 100644 --- a/diffpy/pdfmorph/tests/test_morphrdftopdf.py +++ b/diffpy/pdfmorph/tests/test_morphrdftopdf.py @@ -13,26 +13,24 @@ from diffpy.pdfmorph.morphs.morphrdftopdf import MorphXtalRDFtoPDF -class TestMorphXtalRDFtoPDF(unittest.TestCase): +class TestMorphXtalRDFtoPDF(unittest.TestCase): def setUp(self): self.xobj = numpy.arange(0.01, 5, 0.01) - self.yobj = numpy.exp(-0.5 * (self.xobj-1.0)**2) + self.yobj = numpy.exp(-0.5 * (self.xobj - 1.0) ** 2) self.xref = numpy.arange(0.01, 5, 0.01) - self.yref = numpy.exp(-0.5 * (self.xobj-2.0)**2) + self.yref = numpy.exp(-0.5 * (self.xobj - 2.0) ** 2) return def test_morph(self): - """check MorphXtalRDFtoPDF.morph() - """ - config = { "baselineslope" : -1.0 } + """check MorphXtalRDFtoPDF.morph()""" + config = {"baselineslope": -1.0} morph = MorphXtalRDFtoPDF(config) - xobj, yobj, xref, yref = morph(self.xobj, self.yobj, self.xref, - self.yref) + xobj, yobj, xref, yref = morph(self.xobj, self.yobj, self.xref, self.yref) - rdf1 = numpy.exp(-0.5 * (xobj-1.0)**2) / xobj - xobj - rdf2 = numpy.exp(-0.5 * (xref-2.0)**2) / xref - xref + rdf1 = numpy.exp(-0.5 * (xobj - 1.0) ** 2) / xobj - xobj + rdf2 = numpy.exp(-0.5 * (xref - 2.0) ** 2) / xref - xref self.assertTrue(numpy.allclose(rdf1, yobj)) self.assertTrue(numpy.allclose(rdf2, yref)) return diff --git a/diffpy/pdfmorph/tests/test_morphresolution.py b/diffpy/pdfmorph/tests/test_morphresolution.py index 43ef643b..670f34be 100644 --- a/diffpy/pdfmorph/tests/test_morphresolution.py +++ b/diffpy/pdfmorph/tests/test_morphresolution.py @@ -13,28 +13,27 @@ from diffpy.pdfmorph.morphs.morphresolution import MorphResolutionDamping -class TestMorphScale(unittest.TestCase): +class TestMorphScale(unittest.TestCase): def setUp(self): objfile = os.path.join(testdata_dir, "ni_qmax25.cgr") - self.xobj, self.yobj = numpy.loadtxt(objfile, unpack = True) + self.xobj, self.yobj = numpy.loadtxt(objfile, unpack=True) reffile = os.path.join(testdata_dir, "ni_qmax25_qdamp0.01.cgr") - self.xref, self.yref = numpy.loadtxt(reffile, unpack = True) + self.xref, self.yref = numpy.loadtxt(reffile, unpack=True) return def test_morph(self): - """check MorphScale.morph() - """ - config = {"qdamp" : 0.01} + """check MorphScale.morph()""" + config = {"qdamp": 0.01} morph = MorphResolutionDamping(config) - xobj, yobj, xref, yref = morph(self.xobj, self.yobj, self.xref, - self.yref) + xobj, yobj, xref, yref = morph(self.xobj, self.yobj, self.xref, self.yref) self.assertTrue(numpy.allclose(self.yref, yref)) self.assertTrue(numpy.allclose(yobj, yref)) return + # End of class TestMorphScale if __name__ == '__main__': diff --git a/diffpy/pdfmorph/tests/test_morphrgrid.py b/diffpy/pdfmorph/tests/test_morphrgrid.py index 04732035..bf485121 100644 --- a/diffpy/pdfmorph/tests/test_morphrgrid.py +++ b/diffpy/pdfmorph/tests/test_morphrgrid.py @@ -13,9 +13,9 @@ from diffpy.pdfmorph.morphs.morphrgrid import MorphRGrid + ############################################################################## class TestMorphRGrid(unittest.TestCase): - def setUp(self): self.xobj = numpy.arange(0, 10, 0.01) self.yobj = self.xobj.copy() @@ -33,13 +33,13 @@ def _runTests(self, xyallout, morph): return def testRangeInBounds(self): - """Selected range is within input bounds - """ + """Selected range is within input bounds""" - config = { "rmin" : 1.0, - "rmax" : 2.0, - "rstep" : 0.1, - } + config = { + "rmin": 1.0, + "rmax": 2.0, + "rstep": 0.1, + } morph = MorphRGrid(config) xyallout = morph(self.xobj, self.yobj, self.xref, self.yref) self.assertAlmostEqual(config["rmin"], morph.rmin) @@ -48,15 +48,14 @@ def testRangeInBounds(self): self._runTests(xyallout, morph) return - def testRmaxOut(self): - """Selected rmax is outside of input bounds - """ + """Selected rmax is outside of input bounds""" - config = { "rmin" : 1.0, - "rmax" : 15.0, - "rstep" : 0.1, - } + config = { + "rmin": 1.0, + "rmax": 15.0, + "rstep": 0.1, + } morph = MorphRGrid(config) xyallout = morph(self.xobj, self.yobj, self.xref, self.yref) self.assertAlmostEqual(config["rmin"], morph.rmin) @@ -65,15 +64,14 @@ def testRmaxOut(self): self._runTests(xyallout, morph) return - def testRminOut(self): - """Selected rmin is outside of input bounds - """ + """Selected rmin is outside of input bounds""" - config = { "rmin" : 0.0, - "rmax" : 2.0, - "rstep" : 0.01, - } + config = { + "rmin": 0.0, + "rmax": 2.0, + "rstep": 0.01, + } morph = MorphRGrid(config) xyallout = morph(self.xobj, self.yobj, self.xref, self.yref) self.assertAlmostEqual(1.0, morph.rmin) @@ -82,15 +80,14 @@ def testRminOut(self): self._runTests(xyallout, morph) return - def testRstepOut(self): - """Selected rstep is outside of input bounds - """ + """Selected rstep is outside of input bounds""" - config = { "rmin" : 1.0, - "rmax" : 2.0, - "rstep" : 0.001, - } + config = { + "rmin": 1.0, + "rmax": 2.0, + "rstep": 0.001, + } morph = MorphRGrid(config) xyallout = morph(self.xobj, self.yobj, self.xref, self.yref) self.assertAlmostEqual(config["rmin"], morph.rmin) diff --git a/diffpy/pdfmorph/tests/test_morphscale.py b/diffpy/pdfmorph/tests/test_morphscale.py index 4d8edf09..de8cd20b 100644 --- a/diffpy/pdfmorph/tests/test_morphscale.py +++ b/diffpy/pdfmorph/tests/test_morphscale.py @@ -13,8 +13,8 @@ from diffpy.pdfmorph.morphs.morphscale import MorphScale -class TestMorphScale(unittest.TestCase): +class TestMorphScale(unittest.TestCase): def setUp(self): self.xobj = numpy.arange(0.01, 5, 0.01) self.yobj = numpy.ones_like(self.xobj) @@ -23,18 +23,17 @@ def setUp(self): return def test_morph(self): - """check MorphScale.morph() - """ - config = {"scale" : 2.0} + """check MorphScale.morph()""" + config = {"scale": 2.0} morph = MorphScale(config) - xobj, yobj, xref, yref = morph(self.xobj, self.yobj, self.xref, - self.yref) + xobj, yobj, xref, yref = morph(self.xobj, self.yobj, self.xref, self.yref) self.assertTrue(numpy.allclose(2 * self.yobj, yobj)) self.assertTrue(numpy.allclose(self.yref, yref)) return + # End of class TestMorphScale if __name__ == '__main__': diff --git a/diffpy/pdfmorph/tests/test_morphshape.py b/diffpy/pdfmorph/tests/test_morphshape.py index 5d231635..e9077d0f 100644 --- a/diffpy/pdfmorph/tests/test_morphshape.py +++ b/diffpy/pdfmorph/tests/test_morphshape.py @@ -13,54 +13,53 @@ from diffpy.pdfmorph.morphs.morphshape import MorphSphere, MorphSpheroid -class TestMorphSphere(unittest.TestCase): +class TestMorphSphere(unittest.TestCase): def setUp(self): objfile = os.path.join(testdata_dir, "ni_qmax25.cgr") - self.xobj, self.yobj = numpy.loadtxt(objfile, unpack = True) + self.xobj, self.yobj = numpy.loadtxt(objfile, unpack=True) reffile = os.path.join(testdata_dir, "ni_qmax25_psize30.cgr") - self.xref, self.yref = numpy.loadtxt(reffile, unpack = True) + self.xref, self.yref = numpy.loadtxt(reffile, unpack=True) return def test_morph(self): - """check MorphSphere.morph() - """ - config = {"radius" : 17.5} + """check MorphSphere.morph()""" + config = {"radius": 17.5} morph = MorphSphere(config) - xobj, yobj, xref, yref = morph(self.xobj, self.yobj, self.xref, - self.yref) + xobj, yobj, xref, yref = morph(self.xobj, self.yobj, self.xref, self.yref) self.assertTrue(numpy.allclose(self.yref, yref)) self.assertTrue(numpy.allclose(yobj, yref)) return + # End of class TestMorphSphere -class TestMorphSpheroid(unittest.TestCase): +class TestMorphSpheroid(unittest.TestCase): def setUp(self): objfile = os.path.join(testdata_dir, "ni_qmax25.cgr") - self.xobj, self.yobj = numpy.loadtxt(objfile, unpack = True) + self.xobj, self.yobj = numpy.loadtxt(objfile, unpack=True) reffile = os.path.join(testdata_dir, "ni_qmax25_e17.5_p5.0.cgr") - self.xref, self.yref = numpy.loadtxt(reffile, unpack = True) + self.xref, self.yref = numpy.loadtxt(reffile, unpack=True) return def test_morph(self): - """check MorphSphere.morph() - """ - config = {"radius" : 17.5, - "pradius" : 5.0, - } + """check MorphSphere.morph()""" + config = { + "radius": 17.5, + "pradius": 5.0, + } morph = MorphSpheroid(config) - xobj, yobj, xref, yref = morph(self.xobj, self.yobj, self.xref, - self.yref) + xobj, yobj, xref, yref = morph(self.xobj, self.yobj, self.xref, self.yref) self.assertTrue(numpy.allclose(self.yref, yref)) self.assertTrue(numpy.allclose(yobj, yref)) return + # End of class TestMorphSpheroid if __name__ == '__main__': diff --git a/diffpy/pdfmorph/tests/test_morphsmear.py b/diffpy/pdfmorph/tests/test_morphsmear.py index 856c74e9..2d74e237 100644 --- a/diffpy/pdfmorph/tests/test_morphsmear.py +++ b/diffpy/pdfmorph/tests/test_morphsmear.py @@ -13,37 +13,36 @@ from diffpy.pdfmorph.morphs.morphsmear import MorphSmear -class TestMorphSmear(unittest.TestCase): +class TestMorphSmear(unittest.TestCase): def setUp(self): self.smear = 0.1 self.r0 = 7 * numpy.pi / 22.0 * 2 self.xobj = numpy.arange(0.01, 5, 0.01) - self.yobj = numpy.exp(-0.5 * ((self.xobj-self.r0)/self.smear)**2) + self.yobj = numpy.exp(-0.5 * ((self.xobj - self.r0) / self.smear) ** 2) self.xref = self.xobj.copy() self.yref = self.xref.copy() return def test_morph(self): - """check MorphSmear.morph() - """ + """check MorphSmear.morph()""" morph = MorphSmear() morph.smear = 0.15 - xobj, yobj, xref, yref = morph(self.xobj, self.yobj, self.xref, - self.yref) + xobj, yobj, xref, yref = morph(self.xobj, self.yobj, self.xref, self.yref) # Reference should be unchanged self.assertTrue(numpy.allclose(self.yref, yref)) # Compare to broadened Gaussian - sigbroad = (self.smear**2 + morph.smear**2)**0.5 - ysmear = numpy.exp(-0.5 * ((self.xobj-self.r0)/sigbroad)**2) + sigbroad = (self.smear**2 + morph.smear**2) ** 0.5 + ysmear = numpy.exp(-0.5 * ((self.xobj - self.r0) / sigbroad) ** 2) ysmear *= self.smear / sigbroad self.assertTrue(numpy.allclose(ysmear, yobj)) return + # End of class TestMorphSmear if __name__ == '__main__': diff --git a/diffpy/pdfmorph/tests/test_morphstretch.py b/diffpy/pdfmorph/tests/test_morphstretch.py index 9ee3a3f3..e2d4812a 100644 --- a/diffpy/pdfmorph/tests/test_morphstretch.py +++ b/diffpy/pdfmorph/tests/test_morphstretch.py @@ -13,8 +13,8 @@ from diffpy.pdfmorph.morphs.morphstretch import MorphStretch -class TestMorphStretch(unittest.TestCase): +class TestMorphStretch(unittest.TestCase): def setUp(self): self.xobj = numpy.arange(0.01, 5, 0.01) # A step function between 2 and 3 @@ -24,14 +24,12 @@ def setUp(self): return def test_morph(self): - """check MorphStretch.morph() - """ + """check MorphStretch.morph()""" morph = MorphStretch() # Stretch by 50% morph.stretch = 0.5 - xobj, yobj, xref, yref = morph(self.xobj, self.yobj, self.xref, - self.yref) + xobj, yobj, xref, yref = morph(self.xobj, self.yobj, self.xref, self.yref) # Reference should be unchanged self.assertTrue(numpy.allclose(self.yref, yref)) @@ -46,8 +44,7 @@ def test_morph(self): # Stretch by -10% morph.stretch = -0.1 - xobj, yobj, xref, yref = morph(self.xobj, self.yobj, self.xref, - self.yref) + xobj, yobj, xref, yref = morph(self.xobj, self.yobj, self.xref, self.yref) # Reference should be unchanged self.assertTrue(numpy.allclose(self.yref, yref)) @@ -61,8 +58,10 @@ def test_morph(self): self.assertTrue(res < 1) return + # End of class TestMorphSmear + def heaviside(x, lb, ub): """The Heaviside function.""" y = numpy.ones_like(x) diff --git a/diffpy/pdfmorph/tests/test_plot_morph.py b/diffpy/pdfmorph/tests/test_plot_morph.py index 4e636d07..82ac88ad 100644 --- a/diffpy/pdfmorph/tests/test_plot_morph.py +++ b/diffpy/pdfmorph/tests/test_plot_morph.py @@ -4,6 +4,7 @@ from diffpy.pdfmorph import pdfmorph, morph_default_config, plot_morph from diffpy.pdfmorph.tests.test_morphstretch import heaviside + # smoke test def test_plot_morph(): lb, ub = 1, 2 @@ -13,7 +14,7 @@ def test_plot_morph(): stretch = 0.3 xobj = xref.copy() yobj = heaviside(xref, lb * (1 + stretch), ub * (1 + stretch)) - cfg = morph_default_config(stretch=0.1) # off init + cfg = morph_default_config(stretch=0.1) # off init morph_rv = pdfmorph(xobj, yobj, xref, yref, verbose=True, **cfg) chain = morph_rv['morph_chain'] fig, ax = plt.subplots() diff --git a/diffpy/pdfmorph/tests/test_refine.py b/diffpy/pdfmorph/tests/test_refine.py index 3a93cd30..ece635c1 100644 --- a/diffpy/pdfmorph/tests/test_refine.py +++ b/diffpy/pdfmorph/tests/test_refine.py @@ -19,8 +19,8 @@ from diffpy.pdfmorph.morphs.morphrdftopdf import MorphXtalRDFtoPDF from diffpy.pdfmorph.refine import Refiner -class TestRefine(unittest.TestCase): +class TestRefine(unittest.TestCase): def setUp(self): self.xobj = numpy.arange(0.01, 5, 0.01) self.yobj = numpy.ones_like(self.xobj) @@ -29,12 +29,11 @@ def setUp(self): return def test_refine_morph(self): - """refine a morph - """ + """refine a morph""" # Define the morphs config = { - "scale" : 1.0, - } + "scale": 1.0, + } mscale = MorphScale(config) refiner = Refiner(mscale, self.xobj, self.yobj, self.xref, self.yref) @@ -48,17 +47,13 @@ def test_refine_morph(self): return def test_refine_chain(self): - """refine a chain - """ + """refine a chain""" # Give this some texture self.yobj[30:] = 5 self.yref[33:] = 15 # Define the morphs - config = { - "scale" : 1.0, - "stretch" : 0.0 - } + config = {"scale": 1.0, "stretch": 0.0} mscale = MorphScale(config) mstretch = MorphStretch(config) @@ -71,34 +66,33 @@ def test_refine_chain(self): # interpolation, there will be issues at the boundary of the step # function. xobj, yobj, xref, yref = chain.xyallout - err = 15. * 2 + err = 15.0 * 2 res = sum(numpy.fabs(yref - yobj)) self.assertTrue(res < err) self.assertAlmostEqual(chain.scale, 3, 2) self.assertAlmostEqual(chain.stretch, 0.1, 2) return + # End of class TestRefine -class TestRefineUC(unittest.TestCase): +class TestRefineUC(unittest.TestCase): def setUp(self): objfile = os.path.join(testdata_dir, "nickel_ss0.01.cgr") - self.xobj, self.yobj = numpy.loadtxt(objfile, unpack = True, skiprows - = 8) + self.xobj, self.yobj = numpy.loadtxt(objfile, unpack=True, skiprows=8) reffile = os.path.join(testdata_dir, "nickel_ss0.02_eps0.002.cgr") - self.xref, self.yref = numpy.loadtxt(reffile, unpack = True, skiprows - = 8) + self.xref, self.yref = numpy.loadtxt(reffile, unpack=True, skiprows=8) self.yref *= 1.5 return def test_refine(self): config = { - "scale" : 1.0, - "stretch" : 0, - "smear" : 0, - "baselineslope" : -4 * numpy.pi * 0.0917132 - } + "scale": 1.0, + "stretch": 0, + "smear": 0, + "baselineslope": -4 * numpy.pi * 0.0917132, + } # Note that scale must go first, since it does not commute with the # PDF <--> RDF conversion. @@ -122,10 +116,11 @@ def test_refine(self): sel = xobj < 9.5 yrsel = yref[sel] diff = yrsel - yobj[sel] - rw = (numpy.dot(diff, diff) / numpy.dot(yrsel, yrsel))**0.5 + rw = (numpy.dot(diff, diff) / numpy.dot(yrsel, yrsel)) ** 0.5 self.assertTrue(rw < 0.01) return + if __name__ == '__main__': unittest.main() diff --git a/diffpy/pdfmorph/tests/test_tools.py b/diffpy/pdfmorph/tests/test_tools.py index 4cde10dd..77cddc34 100644 --- a/diffpy/pdfmorph/tests/test_tools.py +++ b/diffpy/pdfmorph/tests/test_tools.py @@ -15,27 +15,26 @@ import diffpy.pdfmorph.tools as tools + ############################################################################## class TestTools(unittest.TestCase): - def setUp(self): objfile = os.path.join(testdata_dir, "nickel_ss0.01.cgr") - self.xobj, self.yobj = numpy.loadtxt(objfile, unpack = True) + self.xobj, self.yobj = numpy.loadtxt(objfile, unpack=True) self.rho0 = 0.0917132 return def test_estimateBaselineSlope(self): - """check estimateBaselineSlope() using calculated data - """ + """check estimateBaselineSlope() using calculated data""" slope = tools.estimateBaselineSlope(self.xobj, self.yobj) slopecalc = -4 * numpy.pi * self.rho0 self.assertTrue(numpy.allclose(slopecalc, slope, 1e-2)) return def test_estimateScale(self): - """check estimateScale() using calculated data - """ + """check estimateScale() using calculated data""" import random + x = random.random() scale = tools.estimateScale(self.yobj, x * self.yobj) self.assertAlmostEqual(x, scale) diff --git a/diffpy/pdfmorph/tools.py b/diffpy/pdfmorph/tools.py index 0f6e81a0..0daa7479 100644 --- a/diffpy/pdfmorph/tools.py +++ b/diffpy/pdfmorph/tools.py @@ -20,13 +20,15 @@ import numpy + def estimateScale(yobjin, yrefin): """Set the scale that best matches the objective to the reference.""" dot = numpy.dot scale = dot(yobjin, yrefin) / dot(yobjin, yobjin) return scale -def estimateBaselineSlope(r, gr, rmin = None, rmax = None): + +def estimateBaselineSlope(r, gr, rmin=None, rmax=None): """Estimate the slope of the linear baseline of a PDF. This fits a the equation slope*r through the bottom of the PDF. @@ -48,14 +50,13 @@ def estimateBaselineSlope(r, gr, rmin = None, rmax = None): rp = r.copy() grp = gr.copy() if rmax is not None: - grp = grp[ rp <= rmax ] - rp = rp[ rp <= rmax ] + grp = grp[rp <= rmax] + rp = rp[rp <= rmax] if rmin is not None: - grp = grp[ rp >= rmin ] - rp = rp[ rp >= rmin ] + grp = grp[rp >= rmin] + rp = rp[rp >= rmin] def chiv(pars): - slope = pars[0] # This tries to fit the baseline through the center of the PDF. chiv = grp - slope * rp @@ -65,7 +66,7 @@ def chiv(pars): diff = chiv.copy() diff[diff > 0] = 0 negpenalty = dot(diff, diff) - chiv *= 1 + 0.5*negpenalty + chiv *= 1 + 0.5 * negpenalty return chiv @@ -86,12 +87,15 @@ def getRw(chain): rw = rw**0.5 return rw + def getPearson(chain): from scipy.stats.stats import pearsonr + xobj, yobj, xref, yref = chain.xyallout pcc, pval = pearsonr(yobj, yref) return pcc + def readPDF(fname): """Reads an .gr file, loads r and G(r) vectors. @@ -106,4 +110,3 @@ def readPDF(fname): if len(rv) >= 2: return rv[:2] return (None, None) - diff --git a/diffpy/pdfmorph/version.py b/diffpy/pdfmorph/version.py index d2a5b338..c773dfa0 100644 --- a/diffpy/pdfmorph/version.py +++ b/diffpy/pdfmorph/version.py @@ -19,10 +19,10 @@ # obtain version information from pkg_resources import get_distribution + __version__ = get_distribution('diffpy.pdfmorph').version # we assume that tag_date was used and __version__ ends in YYYYMMDD -__date__ = __version__[-8:-4] + '-' + \ - __version__[-4:-2] + '-' + __version__[-2:] +__date__ = __version__[-8:-4] + '-' + __version__[-4:-2] + '-' + __version__[-2:] # End of file