From 20d05d920265e6175985455e5cfcf37219f5df92 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Mon, 29 Jul 2024 15:35:55 +0800 Subject: [PATCH 1/2] lint check and change files from python2 to python3 --- devutils/makesdist | 8 +++--- devutils/prep.py | 2 -- diffpy/srmise/applications/extract.py | 38 ++++++++++++------------- diffpy/srmise/applications/plot.py | 15 +++++----- diffpy/srmise/baselines/arbitrary.py | 13 +++++---- diffpy/srmise/baselines/base.py | 2 +- diffpy/srmise/baselines/fromsequence.py | 6 ++-- 7 files changed, 42 insertions(+), 42 deletions(-) diff --git a/devutils/makesdist b/devutils/makesdist index 1d81cf0..a7e2676 100644 --- a/devutils/makesdist +++ b/devutils/makesdist @@ -17,11 +17,11 @@ sys.path.insert(0, BASEDIR) from setup import versiondata timestamp = versiondata.getint('DEFAULT', 'timestamp') -print 'Run "setup.py sdist --formats=tar"', +print('Run "setup.py sdist --formats=tar"',) cmd_sdist = [sys.executable] + 'setup.py sdist --formats=tar'.split() ec = subprocess.call(cmd_sdist, cwd=BASEDIR, stdout=open(os.devnull, 'w')) if ec: sys.exit(ec) -print "[done]" +print("[done]") tarname = max(glob.glob(BASEDIR + '/dist/*.tar'), key=os.path.getmtime) @@ -36,8 +36,8 @@ def fixtarinfo(tinfo): return tinfo -print 'Filter %s --> %s.gz' % (2 * (os.path.basename(tarname),)), +print('Filter %s --> %s.gz' % (2 * (os.path.basename(tarname),)),) for ti in tfin: tfout.addfile(fixtarinfo(ti), tfin.extractfile(ti)) os.remove(tarname) -print "[done]" +print("[done]") diff --git a/devutils/prep.py b/devutils/prep.py index c63ce0f..b765f7d 100644 --- a/devutils/prep.py +++ b/devutils/prep.py @@ -111,5 +111,3 @@ def rm(directory, filerestr): print "==== Scrubbing Endlines ====" # All *.srmise and *.pwa files in examples directory. scrubeol("../doc/examples/output", r".*(\.srmise|\.pwa)") - - diff --git a/diffpy/srmise/applications/extract.py b/diffpy/srmise/applications/extract.py index 5bbc646..97ba8c3 100755 --- a/diffpy/srmise/applications/extract.py +++ b/diffpy/srmise/applications/extract.py @@ -277,10 +277,10 @@ def main(): from diffpy.srmise import peaks try: options.peakfunction = eval("peaks."+options.peakfunction) - except Exception, err: - print err - print "Could not create peak function '%s'. Exiting." \ - %options.peakfunction + except Exception as err: + print(err) + print("Could not create peak function '%s'. Exiting." \ + %options.peakfunction) return if options.modelevaluator is not None: @@ -288,10 +288,10 @@ def main(): try: options.modelevaluator = \ eval("modelevaluators."+options.modelevaluator) - except Exception, err: - print err - print "Could not find ModelEvaluator '%s'. Exiting." \ - %options.modelevaluator + except Exception as err: + print(err) + print("Could not find ModelEvaluator '%s'. Exiting." \ + %options.modelevaluator) return if options.bcrystal is not None: @@ -328,9 +328,9 @@ def main(): from diffpy.srmise import baselines try: options.baseline = eval("baselines."+options.baseline) - except Exception, err: - print err - print "Could not create baseline '%s'. Exiting." %options.baseline + except Exception as err: + print(err) + print("Could not create baseline '%s'. Exiting." %options.baseline) return filename = args[0] @@ -392,22 +392,22 @@ def main(): if options.savefile is not None: try: ext.write(options.savefile) - except SrMiseFileError, err: - print err - print "Could not save result to '%s'." %options.savefile + except SrMiseFileError as err: + print(err) + print("Could not save result to '%s'." %options.savefile) if options.pwafile is not None: try: ext.writepwa(options.pwafile) - except SrMiseFileError, err: - print err - print "Could not save pwa summary to '%s'." %options.pwafile + except SrMiseFileError as err: + print(err) + print("Could not save pwa summary to '%s'." %options.pwafile) - print ext + print(ext) if cov is not None: - print cov + print(cov) if options.plot: from diffpy.srmise.applications.plot import makeplot diff --git a/diffpy/srmise/applications/plot.py b/diffpy/srmise/applications/plot.py index b696aa8..9202dbd 100755 --- a/diffpy/srmise/applications/plot.py +++ b/diffpy/srmise/applications/plot.py @@ -18,6 +18,7 @@ import matplotlib.pyplot as plt import mpl_toolkits.axisartist as AA import numpy as np +from matplotlib.ticker import MultipleLocator from mpl_toolkits.axes_grid1 import make_axes_locatable from mpl_toolkits.axes_grid1.inset_locator import inset_axes @@ -146,8 +147,8 @@ def labelallsubplots(): plt.subplot(221 + i) s = "(%s)" % c ht = plt.text(0.04, 0.95, s, - horizontalalignment='left', verticalalignment='top', - transform=gca().transAxes, weight='bold') + horizontalalignment='left', verticalalignment='top', + transform=plt.gca().transAxes, weight='bold') rv.append(ht) return rv @@ -478,7 +479,7 @@ def readcompare(filename): # TODO: Make this safer try: datastring = open(filename,'rb').read() - except Exception, err: + except Exception as err: raise err import re @@ -491,8 +492,8 @@ def readcompare(filename): try: for line in datastring.split("\n"): distances.append(float(line)) - except (ValueError, IndexError), err: - print "Could not read distances from '%s'. Ignoring file." %filename + except (ValueError, IndexError) as err: + print("Could not read distances from '%s'. Ignoring file." %filename) if len(distances) == 0: return None @@ -539,14 +540,14 @@ def main(): try: toplot.load(filename) except Exception: - print "File '%s' is not a .srmise or PeakStability data file." %filename + print("File '%s' is not a .srmise or PeakStability data file." %filename) return if opts.model is not None: try: toplot.setcurrent(opts.model) except (Exception): - print "Ignoring model, %s is not a PeakStability file." %filename + print("Ignoring model, %s is not a PeakStability file." %filename) distances = None if opts.compare is not None: diff --git a/diffpy/srmise/baselines/arbitrary.py b/diffpy/srmise/baselines/arbitrary.py index 2588740..8658a41 100644 --- a/diffpy/srmise/baselines/arbitrary.py +++ b/diffpy/srmise/baselines/arbitrary.py @@ -17,6 +17,7 @@ import numpy as np import diffpy.srmise.srmiselog +from diffpy.srmise.baselines import Polynomial from diffpy.srmise.baselines.base import BaselineFunction from diffpy.srmise.srmiseerrors import SrMiseEstimationError @@ -114,7 +115,7 @@ def estimate_parameters(self, r, y): # TODO: check that estimatef returns something proper? try: return self.estimatef(r, y) - except Exception, e: + except Exception as e: emsg = "Error within estimation routine provided to Arbitrary:\n"+\ str(e) raise SrMiseEstimationError(emsg) @@ -149,7 +150,7 @@ def _jacobianraw(self, pars, r, free): # large performance implications if all other functions used while # fitting a function define a Jacobian. if nfree == 0: - return [None for p in range(len(par))] + return [None for p in range(len(pars))] # TODO: check that jacobianf returns something proper? return self.jacobianf(pars, r, free) @@ -210,12 +211,12 @@ def getmodule(self): r = np.arange(5) pars = np.array([3, 0, 1, 2]) free = np.array([True, False, True, True]) - print f._valueraw(pars, r) - print f._jacobianraw(pars, r, free) + print(f._valueraw(pars, r)) + print(f._jacobianraw(pars, r, free)) f = Polynomial(degree = -1) r = np.arange(5) pars = np.array([]) free = np.array([]) - print f._valueraw(pars, r) - print f._jacobianraw(pars, r, free) + print(f._valueraw(pars, r)) + print(f._jacobianraw(pars, r, free)) diff --git a/diffpy/srmise/baselines/base.py b/diffpy/srmise/baselines/base.py index d84160a..985cf9f 100644 --- a/diffpy/srmise/baselines/base.py +++ b/diffpy/srmise/baselines/base.py @@ -176,7 +176,7 @@ def factory(baselinestr, ownerlist): from diffpy.srmise.modelcluster import ModelCluster from diffpy.srmise.modelevaluators import AICc - from diffpy.srmise.peaks import GaussianOverR + from diffpy.srmise.peaks import GaussianOverR, Peaks res = 0.01 r = np.arange(2, 4, res) diff --git a/diffpy/srmise/baselines/fromsequence.py b/diffpy/srmise/baselines/fromsequence.py index c06e2de..9085977 100644 --- a/diffpy/srmise/baselines/fromsequence.py +++ b/diffpy/srmise/baselines/fromsequence.py @@ -150,7 +150,7 @@ def _valueraw(self, pars, r): logger.warn("Warning: Evaluating interpolating function over %s, outside safe range of %s.", [r[0], r[-1]], [self.minx, self.maxx]) - except IndexError, TypeError: + except (IndexError, TypeError) as e: if r < self.minx or r > self.maxx: logger.warn("Warning: Evaluating interpolating function at %s, outside safe range of %s.", r, @@ -171,7 +171,7 @@ def readxy(self, filename): # TODO: Make this safer try: datastring = open(filename,'rb').read() - except Exception, err: + except Exception as err: raise err import re @@ -187,7 +187,7 @@ def readxy(self, filename): v = line.split() x.append(float(v[0])) y.append(float(v[1])) - except (ValueError, IndexError), err: + except (ValueError, IndexError) as err: raise SrMiseDataFormatError(str(err)) return (np.array(x), np.array(y)) From 587f0133e1472f5966919b61413d51102834b13b Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Mon, 29 Jul 2024 15:37:12 +0800 Subject: [PATCH 2/2] pre-commit check for these files --- diffpy/srmise/applications/extract.py | 773 +++++++++++++++--------- diffpy/srmise/applications/plot.py | 430 ++++++++----- diffpy/srmise/baselines/arbitrary.py | 43 +- diffpy/srmise/baselines/fromsequence.py | 75 ++- 4 files changed, 804 insertions(+), 517 deletions(-) diff --git a/diffpy/srmise/applications/extract.py b/diffpy/srmise/applications/extract.py index 97ba8c3..59ca6b2 100755 --- a/diffpy/srmise/applications/extract.py +++ b/diffpy/srmise/applications/extract.py @@ -20,254 +20,409 @@ def main(): """Default SrMise entry-point.""" - usage = ("usage: %prog pdf_file [options]\n" - "pdf_file is a file containing a PDF (accepts several " - "common formats), or a .srmise file.") + usage = ( + "usage: %prog pdf_file [options]\n" + "pdf_file is a file containing a PDF (accepts several " + "common formats), or a .srmise file." + ) from diffpy.srmise import __version__ - version = "diffpy.srmise "+__version__ - - descr = ("The SrMise package is a tool to aid extracting and fitting peaks " - "that comprise a pair distribution function. This script exposes " - "basic peak extraction functionality. For many PDFs it is " - "sufficient to specify the range, baseline, and sometimes an ad " - "hoc uncertainty. See the discussion of these options below for " - "further guidance.") - - epilog = ("Options set above override those from an existing .srmise " - "file, as well as the usual defaults summarized here.\n\n" - "Defaults (when qmax > 0)\n" - "------------------------\n" - "baseline - None (identically 0).\n" - "dg - The uncertainty reported in the PDF (if any), otherwise " - "5% of maximum value of PDF.\n" - "nyquist - True\n" - "range - All the data\n" - "cres - The Nyquist rate.\n" - "supersample - 4.0\n" - "scale - (Deprecated) False\n\n" - "Defaults (when qmax = 0)\n" - "------------------------\n" - "baseline - as above\n" - "dg - as above\n" - "nyquist - False (and no effect if True)\n" - "range - as above\n" - "cres - Four times the average distance between data points\n" - "supersample - Parameter has no effect.\n" - "scale - (Deprecated) False, and no effect if True\n\n" - "Known issues\n" - "------------\n" - "1) Peak extraction works best when the data are moderately " - "oversampled first. When qmax > 0 this is handled " - "automatically, but when qmax = 0 no resampling of any kind is " - "performed.\n" - "2) Peak extraction performed on a PDF file and a .srmise file " - "derived from that data with identical extraction parameters " - "can give different results even on the same platform. This is " - "because the original data may undergo some processing before it " - "can be saved by SrMise. For consistent results, always specify " - "the original PDF, or always load the PDF from a .srmise file " - "you save before performing any peak extraction on that data.\n" - "3) Liveplotting depends on the matplotlib backend, and doesn't " - "implement an idle handler, so interaction with its window will " - "likely cause a freeze.") + + version = "diffpy.srmise " + __version__ + + descr = ( + "The SrMise package is a tool to aid extracting and fitting peaks " + "that comprise a pair distribution function. This script exposes " + "basic peak extraction functionality. For many PDFs it is " + "sufficient to specify the range, baseline, and sometimes an ad " + "hoc uncertainty. See the discussion of these options below for " + "further guidance." + ) + + epilog = ( + "Options set above override those from an existing .srmise " + "file, as well as the usual defaults summarized here.\n\n" + "Defaults (when qmax > 0)\n" + "------------------------\n" + "baseline - None (identically 0).\n" + "dg - The uncertainty reported in the PDF (if any), otherwise " + "5% of maximum value of PDF.\n" + "nyquist - True\n" + "range - All the data\n" + "cres - The Nyquist rate.\n" + "supersample - 4.0\n" + "scale - (Deprecated) False\n\n" + "Defaults (when qmax = 0)\n" + "------------------------\n" + "baseline - as above\n" + "dg - as above\n" + "nyquist - False (and no effect if True)\n" + "range - as above\n" + "cres - Four times the average distance between data points\n" + "supersample - Parameter has no effect.\n" + "scale - (Deprecated) False, and no effect if True\n\n" + "Known issues\n" + "------------\n" + "1) Peak extraction works best when the data are moderately " + "oversampled first. When qmax > 0 this is handled " + "automatically, but when qmax = 0 no resampling of any kind is " + "performed.\n" + "2) Peak extraction performed on a PDF file and a .srmise file " + "derived from that data with identical extraction parameters " + "can give different results even on the same platform. This is " + "because the original data may undergo some processing before it " + "can be saved by SrMise. For consistent results, always specify " + "the original PDF, or always load the PDF from a .srmise file " + "you save before performing any peak extraction on that data.\n" + "3) Liveplotting depends on the matplotlib backend, and doesn't " + "implement an idle handler, so interaction with its window will " + "likely cause a freeze." + ) # TODO: Move to argparse (though not in 2.6 by default) to handle # variable-length options without callbacks. Longterm, the major # value is using the same option to specify a baseline that should # use estimation vs. one that should use explicitly provided pars. - parser = OptionParser(usage=usage, description=descr, epilog=epilog, - version=version, - formatter=IndentedHelpFormatterWithNL()) - - parser.set_defaults(plot=False, liveplot=False, wait=False, - performextraction=True, verbosity="warning") - dg_defaults = {'absolute':None, 'data':None, 'max-fraction':.05, - 'ptp-fraction':.05, 'dG-fraction':1.} - - parser.add_option("--extract", action="store_true", - dest="performextraction", - help="[Default] Perform extraction.") - parser.add_option("--no-extract", action="store_false", - dest="performextraction", - help="Do not perform extraction.") - parser.add_option("--range", nargs=2, dest="rng", type="float", - metavar="rmin rmax", - help="Extract over the range (rmin, rmax).") - parser.add_option("--qmax", dest="qmax", type="string", metavar="QMAX", - help="Model peaks with this maximum q value.") - parser.add_option("--nyquist", action="store_true", dest="nyquist", - help="Use Nyquist resampling if qmax > 0.") - parser.add_option("--no-nyquist", action="store_false", dest="nyquist", - help="Do not use Nyquist resampling.") - parser.add_option("--pf", dest="peakfunction", metavar="PF", - help="Fit peak function PF defined in " - "diffpy.srmise.peaks, e.g. " - "'GaussianOverR(maxwidth=0.7)'") - parser.add_option("--cres", dest="cres", type="float", metavar="cres", - help="Clustering resolution.") - parser.add_option("--supersample", dest="supersample", type="float", - metavar="SS", - help="Minimum initial oversampling rate as multiple of " - "Nyquist rate.") - parser.add_option("--me", "-m", dest="modelevaluator", metavar="ME", - help="ModelEvaluator defined in " - "diffpy.srmise.modelevaluators, e.g. 'AIC'") - - group = OptionGroup(parser, "Baseline Options", - "SrMise cannot determine the appropriate type of " - "baseline (e.g. crystalline vs. some nanoparticle) " - "solely from the data, so the user should specify the " - "appropriate type and/or parameters. (Default is " - "identically 0, which is unphysical.) SrMise keeps the " - "PDF baseline fixed at its initial value until the " - "final stages of peak extraction, so results are " - "frequently conditioned on that choice. (See the " - "SrMise documentation for details.) A good estimate " - "is therefore important for best results. SrMise can " - "estimate initial parameters from the data for linear " - "baselines in some situations (all peaks are positive, " - "and the degree of overlap in the region of extraction " - "is not too great), but in most cases it is best to " - "provide reasonable initial parameters. Run 'srmise " - "pdf_file.gr [baseline_option] --no-extract --plot' " - "for different values of the parameters for rapid " - "visual estimation.") - group.add_option("--baseline", dest="baseline", metavar="BL", - help="Estimate baseline from baseline function BL " - "defined in diffpy.srmise.baselines, e.g. " - "'Polynomial(degree=1)'. All parameters are free. " - "(Many POSIX shells attempt to interpret the " - "parentheses, and on these shells the option should " - "be surrounded by quotation marks.)" ) - group.add_option("--bcrystal", dest="bcrystal", type="string", - metavar="rho0[c]", - help="Use linear baseline defined by crystal number " - "density rho0. Append 'c' to make parameter " - "constant. Equivalent to " - "'--bpoly1 -4*pi*rho0[c] 0c'.") - group.add_option("--bsrmise", dest="bsrmise", type="string", metavar="file", - help="Use baseline from specified .srmise file.") - group.add_option("--bpoly0", dest="bpoly0", type="string", metavar="a0[c]", - help="Use constant baseline given by y=a0. " - "Append 'c' to make parameter constant.") - group.add_option("--bpoly1", dest="bpoly1", type="string", nargs=2, - metavar="a1[c] a0[c]", - help="Use baseline given by y=a1*x + a0. Append 'c' to " - "make parameter constant.") - group.add_option("--bpoly2", dest="bpoly2", type="string", nargs=3, - metavar="a2[c] a1[c] a0[c]", - help="Use baseline given by y=a2*x^2+a1*x + a0. Append " - "'c' to make parameter constant.") - group.add_option("--bseq", dest="bseq", type="string", metavar="FILE", - help="Use baseline interpolated from x,y values in FILE. " - "This baseline has no free parameters.") - group.add_option("--bspherical", dest="bspherical", type="string", nargs=2, - metavar="s[c] r[c]", - help="Use spherical nanoparticle baseline with scale s " - "and radius r. Append 'c' to make parameter " - "constant.") + parser = OptionParser( + usage=usage, + description=descr, + epilog=epilog, + version=version, + formatter=IndentedHelpFormatterWithNL(), + ) + + parser.set_defaults( + plot=False, + liveplot=False, + wait=False, + performextraction=True, + verbosity="warning", + ) + dg_defaults = { + "absolute": None, + "data": None, + "max-fraction": 0.05, + "ptp-fraction": 0.05, + "dG-fraction": 1.0, + } + + parser.add_option( + "--extract", + action="store_true", + dest="performextraction", + help="[Default] Perform extraction.", + ) + parser.add_option( + "--no-extract", + action="store_false", + dest="performextraction", + help="Do not perform extraction.", + ) + parser.add_option( + "--range", + nargs=2, + dest="rng", + type="float", + metavar="rmin rmax", + help="Extract over the range (rmin, rmax).", + ) + parser.add_option( + "--qmax", + dest="qmax", + type="string", + metavar="QMAX", + help="Model peaks with this maximum q value.", + ) + parser.add_option( + "--nyquist", + action="store_true", + dest="nyquist", + help="Use Nyquist resampling if qmax > 0.", + ) + parser.add_option( + "--no-nyquist", + action="store_false", + dest="nyquist", + help="Do not use Nyquist resampling.", + ) + parser.add_option( + "--pf", + dest="peakfunction", + metavar="PF", + help="Fit peak function PF defined in " + "diffpy.srmise.peaks, e.g. " + "'GaussianOverR(maxwidth=0.7)'", + ) + parser.add_option( + "--cres", + dest="cres", + type="float", + metavar="cres", + help="Clustering resolution.", + ) + parser.add_option( + "--supersample", + dest="supersample", + type="float", + metavar="SS", + help="Minimum initial oversampling rate as multiple of " "Nyquist rate.", + ) + parser.add_option( + "--me", + "-m", + dest="modelevaluator", + metavar="ME", + help="ModelEvaluator defined in " "diffpy.srmise.modelevaluators, e.g. 'AIC'", + ) + + group = OptionGroup( + parser, + "Baseline Options", + "SrMise cannot determine the appropriate type of " + "baseline (e.g. crystalline vs. some nanoparticle) " + "solely from the data, so the user should specify the " + "appropriate type and/or parameters. (Default is " + "identically 0, which is unphysical.) SrMise keeps the " + "PDF baseline fixed at its initial value until the " + "final stages of peak extraction, so results are " + "frequently conditioned on that choice. (See the " + "SrMise documentation for details.) A good estimate " + "is therefore important for best results. SrMise can " + "estimate initial parameters from the data for linear " + "baselines in some situations (all peaks are positive, " + "and the degree of overlap in the region of extraction " + "is not too great), but in most cases it is best to " + "provide reasonable initial parameters. Run 'srmise " + "pdf_file.gr [baseline_option] --no-extract --plot' " + "for different values of the parameters for rapid " + "visual estimation.", + ) + group.add_option( + "--baseline", + dest="baseline", + metavar="BL", + help="Estimate baseline from baseline function BL " + "defined in diffpy.srmise.baselines, e.g. " + "'Polynomial(degree=1)'. All parameters are free. " + "(Many POSIX shells attempt to interpret the " + "parentheses, and on these shells the option should " + "be surrounded by quotation marks.)", + ) + group.add_option( + "--bcrystal", + dest="bcrystal", + type="string", + metavar="rho0[c]", + help="Use linear baseline defined by crystal number " + "density rho0. Append 'c' to make parameter " + "constant. Equivalent to " + "'--bpoly1 -4*pi*rho0[c] 0c'.", + ) + group.add_option( + "--bsrmise", + dest="bsrmise", + type="string", + metavar="file", + help="Use baseline from specified .srmise file.", + ) + group.add_option( + "--bpoly0", + dest="bpoly0", + type="string", + metavar="a0[c]", + help="Use constant baseline given by y=a0. " + "Append 'c' to make parameter constant.", + ) + group.add_option( + "--bpoly1", + dest="bpoly1", + type="string", + nargs=2, + metavar="a1[c] a0[c]", + help="Use baseline given by y=a1*x + a0. Append 'c' to " + "make parameter constant.", + ) + group.add_option( + "--bpoly2", + dest="bpoly2", + type="string", + nargs=3, + metavar="a2[c] a1[c] a0[c]", + help="Use baseline given by y=a2*x^2+a1*x + a0. Append " + "'c' to make parameter constant.", + ) + group.add_option( + "--bseq", + dest="bseq", + type="string", + metavar="FILE", + help="Use baseline interpolated from x,y values in FILE. " + "This baseline has no free parameters.", + ) + group.add_option( + "--bspherical", + dest="bspherical", + type="string", + nargs=2, + metavar="s[c] r[c]", + help="Use spherical nanoparticle baseline with scale s " + "and radius r. Append 'c' to make parameter " + "constant.", + ) parser.add_option_group(group) - - group = OptionGroup(parser, "Uncertainty Options", - "Ideally a PDF reports the accurate experimentally " - "determined uncertainty. In practice, many PDFs " - "report none, while for others the reported values " - "are not necessarily reliable. (If in doubt, ask your " - "friendly neighborhood diffraction expert!) Even when " - "uncertainties are accurate, it can be " - "pragmatically useful to see how the results of " - "peak extraction change when assuming a different " - "value. Nevertheless, the primary determinant of " - "model complexity in SrMise is the uncertainty, so an " - "ad hoc uncertainty yields ad hoc model complexity. " - "See the SrMise documentation for further discussion, " - "including methods to mitigate this issue with " - "multimodel selection.") - group.add_option("--dg-mode", dest="dg_mode", type="choice", - choices=['absolute', 'data', 'max-fraction', - 'ptp-fraction', 'dG-fraction'], - help="Define how values passed to '--dg' are treated. " - "Possible values are: \n" - "'absolute' - The actual uncertainty in the PDF.\n" - "'max-fraction' - Fraction of max value in PDF.\n" - "'ptp-fraction' - Fraction of max minus min value " - "in the PDF.\n" - "'dG-fraction' - Fraction of dG reported by PDF.\n" - "If '--dg' is specified but mode is not, then mode " - "ia absolute. Otherwise, 'dG-fraction' is default " - "if the PDF reports uncertaintes, and 'max-fraction' " - "ia default if it does not.") - group.add_option("--dg", dest="dg", type="float", - help="Perform extraction assuming uncertainty dg. " - "Defaults depend on --dg-mode as follows:\n" - "'absolute'=%s\n" - "'max-fraction'=%s\n" - "'ptp-fraction'=%s\n" - "'dG-fraction'=%s" %(dg_defaults['absolute'], - dg_defaults['max-fraction'], - dg_defaults['ptp-fraction'], - dg_defaults['dG-fraction'])) -# group.add_option("--multimodel", nargs=3, dest="multimodel", type="float", -# metavar="dg_min dg_max n", -# help="Generate n models from dg_min to dg_max (given by " -# "--dg-mode) and perform multimodel analysis. " -# "This overrides any value given for --dg") + group = OptionGroup( + parser, + "Uncertainty Options", + "Ideally a PDF reports the accurate experimentally " + "determined uncertainty. In practice, many PDFs " + "report none, while for others the reported values " + "are not necessarily reliable. (If in doubt, ask your " + "friendly neighborhood diffraction expert!) Even when " + "uncertainties are accurate, it can be " + "pragmatically useful to see how the results of " + "peak extraction change when assuming a different " + "value. Nevertheless, the primary determinant of " + "model complexity in SrMise is the uncertainty, so an " + "ad hoc uncertainty yields ad hoc model complexity. " + "See the SrMise documentation for further discussion, " + "including methods to mitigate this issue with " + "multimodel selection.", + ) + group.add_option( + "--dg-mode", + dest="dg_mode", + type="choice", + choices=["absolute", "data", "max-fraction", "ptp-fraction", "dG-fraction"], + help="Define how values passed to '--dg' are treated. " + "Possible values are: \n" + "'absolute' - The actual uncertainty in the PDF.\n" + "'max-fraction' - Fraction of max value in PDF.\n" + "'ptp-fraction' - Fraction of max minus min value " + "in the PDF.\n" + "'dG-fraction' - Fraction of dG reported by PDF.\n" + "If '--dg' is specified but mode is not, then mode " + "ia absolute. Otherwise, 'dG-fraction' is default " + "if the PDF reports uncertaintes, and 'max-fraction' " + "ia default if it does not.", + ) + group.add_option( + "--dg", + dest="dg", + type="float", + help="Perform extraction assuming uncertainty dg. " + "Defaults depend on --dg-mode as follows:\n" + "'absolute'=%s\n" + "'max-fraction'=%s\n" + "'ptp-fraction'=%s\n" + "'dG-fraction'=%s" + % ( + dg_defaults["absolute"], + dg_defaults["max-fraction"], + dg_defaults["ptp-fraction"], + dg_defaults["dG-fraction"], + ), + ) + # group.add_option("--multimodel", nargs=3, dest="multimodel", type="float", + # metavar="dg_min dg_max n", + # help="Generate n models from dg_min to dg_max (given by " + # "--dg-mode) and perform multimodel analysis. " + # "This overrides any value given for --dg") parser.add_option_group(group) - - group = OptionGroup(parser, "Saving and Plotting Options", - "") - group.add_option("--pwa", dest="pwafile", metavar="FILE", - help="Save summary of result to FILE (.pwa format).") - group.add_option("--save", dest="savefile", metavar="FILE", - help="Save result of extraction to FILE (.srmise " - "format).") - group.add_option("--plot", "-p", action="store_true", dest="plot", - help="Plot extracted peaks.") - group.add_option("--liveplot", "-l", action="store_true", dest="liveplot", - help="(Experimental) Plot extracted peaks when fitting.") - group.add_option("--wait", "-w", action="store_true", dest="wait", - help="(Experimental) When using liveplot wait for user " - "after plotting.") + group = OptionGroup(parser, "Saving and Plotting Options", "") + group.add_option( + "--pwa", + dest="pwafile", + metavar="FILE", + help="Save summary of result to FILE (.pwa format).", + ) + group.add_option( + "--save", + dest="savefile", + metavar="FILE", + help="Save result of extraction to FILE (.srmise " "format).", + ) + group.add_option( + "--plot", "-p", action="store_true", dest="plot", help="Plot extracted peaks." + ) + group.add_option( + "--liveplot", + "-l", + action="store_true", + dest="liveplot", + help="(Experimental) Plot extracted peaks when fitting.", + ) + group.add_option( + "--wait", + "-w", + action="store_true", + dest="wait", + help="(Experimental) When using liveplot wait for user " "after plotting.", + ) parser.add_option_group(group) - - group = OptionGroup(parser, "Verbosity Options", - "Control detail printed to console.") - group.add_option("--informative", "-i", action="store_const", const="info", - dest="verbosity", - help="Summary of progress.") - group.add_option("--quiet", "-q", action="store_const", const="warning", - dest="verbosity", - help="[Default] Show minimal summary.") - group.add_option("--silent", "-s", action="store_const", const="critical", - dest="verbosity", - help="No non-critical output.") - group.add_option("--verbose", "-v", action="store_const", const="debug", - dest="verbosity", - help="Show verbose output.") + group = OptionGroup( + parser, "Verbosity Options", "Control detail printed to console." + ) + group.add_option( + "--informative", + "-i", + action="store_const", + const="info", + dest="verbosity", + help="Summary of progress.", + ) + group.add_option( + "--quiet", + "-q", + action="store_const", + const="warning", + dest="verbosity", + help="[Default] Show minimal summary.", + ) + group.add_option( + "--silent", + "-s", + action="store_const", + const="critical", + dest="verbosity", + help="No non-critical output.", + ) + group.add_option( + "--verbose", + "-v", + action="store_const", + const="debug", + dest="verbosity", + help="Show verbose output.", + ) parser.add_option_group(group) - group = OptionGroup(parser, "Deprecated Options", - "Not for general use.") - group.add_option("--scale", action="store_true", dest="scale", - help="(Deprecated) Scale supersampled uncertainties by " - "sqrt(oversampling) in intermediate steps when " - "Nyquist sampling.") - group.add_option("--no-scale", action="store_false", dest="scale", - help="(Deprecated) Never rescale uncertainties.") + group = OptionGroup(parser, "Deprecated Options", "Not for general use.") + group.add_option( + "--scale", + action="store_true", + dest="scale", + help="(Deprecated) Scale supersampled uncertainties by " + "sqrt(oversampling) in intermediate steps when " + "Nyquist sampling.", + ) + group.add_option( + "--no-scale", + action="store_false", + dest="scale", + help="(Deprecated) Never rescale uncertainties.", + ) parser.add_option_group(group) - (options, args) = parser.parse_args() if len(args) != 1: - parser.error("Exactly one argument required. \n"+usage) - + parser.error("Exactly one argument required. \n" + usage) from diffpy.srmise import srmiselog + srmiselog.setlevel(options.verbosity) from diffpy.srmise.pdfpeakextraction import PDFPeakExtraction @@ -275,30 +430,34 @@ def main(): if options.peakfunction is not None: from diffpy.srmise import peaks + try: - options.peakfunction = eval("peaks."+options.peakfunction) + options.peakfunction = eval("peaks." + options.peakfunction) except Exception as err: print(err) - print("Could not create peak function '%s'. Exiting." \ - %options.peakfunction) + print( + "Could not create peak function '%s'. Exiting." % options.peakfunction + ) return if options.modelevaluator is not None: from diffpy.srmise import modelevaluators + try: - options.modelevaluator = \ - eval("modelevaluators."+options.modelevaluator) + options.modelevaluator = eval("modelevaluators." + options.modelevaluator) except Exception as err: print(err) - print("Could not find ModelEvaluator '%s'. Exiting." \ - %options.modelevaluator) + print( + "Could not find ModelEvaluator '%s'. Exiting." % options.modelevaluator + ) return if options.bcrystal is not None: from diffpy.srmise.baselines import Polynomial + bl = Polynomial(degree=1) - options.baseline = parsepars(bl, [options.bcrystal, '0c']) - options.baseline.pars[0] = -4*np.pi*options.baseline.pars[0] + options.baseline = parsepars(bl, [options.bcrystal, "0c"]) + options.baseline.pars[0] = -4 * np.pi * options.baseline.pars[0] elif options.bsrmise is not None: # use baseline from existing file blext = PDFPeakExtraction() @@ -306,31 +465,37 @@ def main(): options.baseline = blext.extracted.baseline elif options.bpoly0 is not None: from diffpy.srmise.baselines import Polynomial + bl = Polynomial(degree=0) options.baseline = parsepars(bl, [options.bpoly0]) elif options.bpoly1 is not None: from diffpy.srmise.baselines import Polynomial + bl = Polynomial(degree=1) options.baseline = parsepars(bl, options.bpoly1) elif options.bpoly2 is not None: from diffpy.srmise.baselines import Polynomial + bl = Polynomial(degree=2) options.baseline = parsepars(bl, options.bpoly2) elif options.bseq is not None: from diffpy.srmise.baselines import FromSequence + bl = FromSequence(options.bseq) options.baseline = bl.actualize([], "internal") elif options.bspherical is not None: from diffpy.srmise.baselines import NanoSpherical + bl = NanoSpherical() options.baseline = parsepars(bl, options.bspherical) elif options.baseline is not None: from diffpy.srmise import baselines + try: - options.baseline = eval("baselines."+options.baseline) + options.baseline = eval("baselines." + options.baseline) except Exception as err: print(err) - print("Could not create baseline '%s'. Exiting." %options.baseline) + print("Could not create baseline '%s'. Exiting." % options.baseline) return filename = args[0] @@ -359,17 +524,19 @@ def main(): if options.dg is None: options.dg = dg_defaults[options.dg_mode] if options.dg_mode == "absolute": - pdict["effective_dy"] = options.dg*np.ones(len(ext.x)) + pdict["effective_dy"] = options.dg * np.ones(len(ext.x)) elif options.dg_mode == "max-fraction": - pdict["effective_dy"] = options.dg*ext.y.max()*np.ones(len(ext.x)) + pdict["effective_dy"] = options.dg * ext.y.max() * np.ones(len(ext.x)) elif options.dg_mode == "ptp-fraction": - pdict["effective_dy"] = options.dg*ext.y.ptp()*np.ones(len(ext.y)) + pdict["effective_dy"] = options.dg * ext.y.ptp() * np.ones(len(ext.y)) elif options.dg_mode == "dG-fraction": - pdict["effective_dy"] = options.dg*ext.dy + pdict["effective_dy"] = options.dg * ext.dy if options.rng is not None: pdict["rng"] = list(options.rng) if options.qmax is not None: - pdict["qmax"] = options.qmax if options.qmax == "automatic" else float(options.qmax) + pdict["qmax"] = ( + options.qmax if options.qmax == "automatic" else float(options.qmax) + ) if options.nyquist is not None: pdict["nyquist"] = options.nyquist if options.supersample is not None: @@ -381,6 +548,7 @@ def main(): if options.liveplot: from diffpy.srmise import srmiselog + srmiselog.liveplotting(True, options.wait) ext.setvars(**pdict) @@ -394,16 +562,14 @@ def main(): ext.write(options.savefile) except SrMiseFileError as err: print(err) - print("Could not save result to '%s'." %options.savefile) - + print("Could not save result to '%s'." % options.savefile) if options.pwafile is not None: try: ext.writepwa(options.pwafile) except SrMiseFileError as err: print(err) - print("Could not save pwa summary to '%s'." %options.pwafile) - + print("Could not save pwa summary to '%s'." % options.pwafile) print(ext) if cov is not None: @@ -411,11 +577,13 @@ def main(): if options.plot: from diffpy.srmise.applications.plot import makeplot + makeplot(ext) plt.show() elif options.liveplot: plt.show() + def parsepars(mp, parseq): """Return actualized model from sequence of strings. @@ -430,7 +598,7 @@ def parsepars(mp, parseq): pars = [] free = [] for p in parseq: - if p[-1] == 'c': + if p[-1] == "c": pars.append(float(p[0:-1])) free.append(False) else: @@ -448,60 +616,63 @@ def parsepars(mp, parseq): class IndentedHelpFormatterWithNL(IndentedHelpFormatter): - def _format_text(self, text): - if not text: return "" - text_width = self.width - self.current_indent - indent = " "*self.current_indent -# the above is still the same - bits = text.split('\n') - formatted_bits = [ - textwrap.fill(bit, - text_width, - initial_indent=indent, - subsequent_indent=indent) - for bit in bits] - result = "\n".join(formatted_bits) + "\n" - return result - - def format_option(self, option): - # The help for each option consists of two parts: - # * the opt strings and metavars - # eg. ("-x", or "-fFILENAME, --file=FILENAME") - # * the user-supplied help string - # eg. ("turn on expert mode", "read data from FILENAME") - # - # If possible, we write both of these on the same line: - # -x turn on expert mode - # - # But if the opt string list is too long, we put the help - # string on a second line, indented to the same column it would - # start in if it fit on the first line. - # -fFILENAME, --file=FILENAME - # read data from FILENAME - result = [] - opts = self.option_strings[option] - opt_width = self.help_position - self.current_indent - 2 - if len(opts) > opt_width: - opts = "%*s%s\n" % (self.current_indent, "", opts) - indent_first = self.help_position - else: # start help on same line as opts - opts = "%*s%-*s " % (self.current_indent, "", opt_width, opts) - indent_first = 0 - result.append(opts) - if option.help: - help_text = self.expand_default(option) -# Everything is the same up through here - help_lines = [] - for para in help_text.split("\n"): - help_lines.extend(textwrap.wrap(para, self.help_width)) -# Everything is the same after here - result.append("%*s%s\n" % ( - indent_first, "", help_lines[0])) - result.extend(["%*s%s\n" % (self.help_position, "", line) - for line in help_lines[1:]]) - elif opts[-1] != "\n": - result.append("\n") - return "".join(result) + def _format_text(self, text): + if not text: + return "" + text_width = self.width - self.current_indent + indent = " " * self.current_indent + # the above is still the same + bits = text.split("\n") + formatted_bits = [ + textwrap.fill( + bit, text_width, initial_indent=indent, subsequent_indent=indent + ) + for bit in bits + ] + result = "\n".join(formatted_bits) + "\n" + return result + + def format_option(self, option): + # The help for each option consists of two parts: + # * the opt strings and metavars + # eg. ("-x", or "-fFILENAME, --file=FILENAME") + # * the user-supplied help string + # eg. ("turn on expert mode", "read data from FILENAME") + # + # If possible, we write both of these on the same line: + # -x turn on expert mode + # + # But if the opt string list is too long, we put the help + # string on a second line, indented to the same column it would + # start in if it fit on the first line. + # -fFILENAME, --file=FILENAME + # read data from FILENAME + result = [] + opts = self.option_strings[option] + opt_width = self.help_position - self.current_indent - 2 + if len(opts) > opt_width: + opts = "%*s%s\n" % (self.current_indent, "", opts) + indent_first = self.help_position + else: # start help on same line as opts + opts = "%*s%-*s " % (self.current_indent, "", opt_width, opts) + indent_first = 0 + result.append(opts) + if option.help: + help_text = self.expand_default(option) + # Everything is the same up through here + help_lines = [] + for para in help_text.split("\n"): + help_lines.extend(textwrap.wrap(para, self.help_width)) + # Everything is the same after here + result.append("%*s%s\n" % (indent_first, "", help_lines[0])) + result.extend( + ["%*s%s\n" % (self.help_position, "", line) for line in help_lines[1:]] + ) + elif opts[-1] != "\n": + result.append("\n") + return "".join(result) + + ### End class if __name__ == "__main__": diff --git a/diffpy/srmise/applications/plot.py b/diffpy/srmise/applications/plot.py index 9202dbd..14f167e 100755 --- a/diffpy/srmise/applications/plot.py +++ b/diffpy/srmise/applications/plot.py @@ -28,49 +28,63 @@ # For a given figure, returns a label of interest labeldict = {} -default_gobs_style = {'color' : 'b', 'linestyle' : '', - 'markeredgecolor' : 'b', 'marker' : 'o', - 'markerfacecolor' : 'none', 'markersize' : 4} - -default_gfit_style = {'color' : 'g'} -default_gind_style = {'facecolor' : 'green', 'alpha' : 0.2} +default_gobs_style = { + "color": "b", + "linestyle": "", + "markeredgecolor": "b", + "marker": "o", + "markerfacecolor": "none", + "markersize": 4, +} + +default_gfit_style = {"color": "g"} +default_gind_style = {"facecolor": "green", "alpha": 0.2} default_gres_style = {} default_ep_style = {} default_ip_style = {} -default_dg_style = {'linestyle' : 'none', 'color' : 'black', - 'marker' : 'o', 'markerfacecolor' : 'black', - 'markeredgecolor' : 'black', - 'markersize' : 1, 'antialiased': False} +default_dg_style = { + "linestyle": "none", + "color": "black", + "marker": "o", + "markerfacecolor": "black", + "markeredgecolor": "black", + "markersize": 1, + "antialiased": False, +} def setfigformat(figsize): from matplotlib import rc - rc('legend', numpoints=2) - rc('figure', figsize=figsize) - rc('axes', titlesize=12, labelsize=11) - rc('xtick', labelsize=10) - rc('ytick', labelsize=10) - rc('lines', linewidth=0.75, markeredgewidth=0.5) + + rc("legend", numpoints=2) + rc("figure", figsize=figsize) + rc("axes", titlesize=12, labelsize=11) + rc("xtick", labelsize=10) + rc("ytick", labelsize=10) + rc("lines", linewidth=0.75, markeredgewidth=0.5) return + def gr_formataxis(ax=None): - if ax is None: ax = plt.gca() + if ax is None: + ax = plt.gca() ax.xaxis.set_minor_locator(MultipleLocator(1)) - ax.yaxis.set_label_position('left') + ax.yaxis.set_label_position("left") ax.yaxis.tick_left() - ax.yaxis.set_ticks_position('both') + ax.yaxis.set_ticks_position("both") return + def comparepositions(ppe, ip=None, **kwds): ax = kwds.get("ax", plt.gca()) - base = kwds.get("base", 0.) - yideal = kwds.get("yideal", -1.) - yext = kwds.get("yext", 1.) + base = kwds.get("base", 0.0) + yideal = kwds.get("yideal", -1.0) + yext = kwds.get("yext", 1.0) ep_style = kwds.get("ep_style", default_ep_style) ip_style = kwds.get("ip_style", default_ip_style) - yideal_label = kwds.get("yideal_label", r'ideal') - yext_label = kwds.get("yext_label", r'found') + yideal_label = kwds.get("yideal_label", r"ideal") + yext_label = kwds.get("yext_label", r"found") pmin = kwds.get("pmin", -np.inf) pmax = kwds.get("pmax", np.inf) @@ -78,39 +92,39 @@ def comparepositions(ppe, ip=None, **kwds): ep = [p for p in ep if p >= pmin and p <= pmax] if ip is not None: - xi = np.NaN + np.zeros(3*len(ip)) + xi = np.NaN + np.zeros(3 * len(ip)) xi[0::3] = ip xi[1::3] = ip yi = np.zeros_like(xi) + base yi[1::3] += yideal - plt.plot(xi, yi, 'b', lw=1.5, **ip_style) + plt.plot(xi, yi, "b", lw=1.5, **ip_style) - xe = np.NaN + np.zeros(3*len(ep)) + xe = np.NaN + np.zeros(3 * len(ep)) xe[0::3] = ep xe[1::3] = ep ye = np.zeros_like(xe) + base ye[1::3] += yext - plt.plot(xe, ye, 'g', lw=1.5, **ep_style) + plt.plot(xe, ye, "g", lw=1.5, **ep_style) if ip is not None: yb = (base, base) - plt.axhline(base, linestyle=":", color="k" ) - ax.yaxis.set_ticks([base+.5*yideal, base+.5*yext]) + plt.axhline(base, linestyle=":", color="k") + ax.yaxis.set_ticks([base + 0.5 * yideal, base + 0.5 * yext]) ax.yaxis.set_ticklabels([yideal_label, yext_label]) else: - ax.yaxis.set_ticks([base+.5*yext]) + ax.yaxis.set_ticks([base + 0.5 * yext]) ax.yaxis.set_ticklabels([yext_label]) # Set ylim explicitly, for case where yext is empty. if ip is not None: - plt.ylim(base+yideal, base+yext) + plt.ylim(base + yideal, base + yext) else: - plt.ylim(base, base+yext) + plt.ylim(base, base + yext) for tick in ax.yaxis.get_major_ticks(): tick.tick1line.set_markersize(0) tick.tick2line.set_markersize(0) - tick.label1.set_verticalalignment('center') + tick.label1.set_verticalalignment("center") tick.label1.set_fontsize(8) ticks = ax.yaxis.get_major_ticks() ticks[-1].label1.set_color("green") @@ -118,37 +132,45 @@ def comparepositions(ppe, ip=None, **kwds): ticks[0].label1.set_color("blue") return + def dgseries(stability, **kwds): ax = kwds.get("ax", plt.gca()) dg_style = kwds.get("dg_style", default_dg_style) - scale = kwds.get("scale", 1.) + scale = kwds.get("scale", 1.0) - dgmin = kwds.get("dgmin", stability.results[0][0])*scale - dgmax = kwds.get("dgmax", stability.results[-1][0])*scale + dgmin = kwds.get("dgmin", stability.results[0][0]) * scale + dgmax = kwds.get("dgmax", stability.results[-1][0]) * scale - pmin = kwds.get("pmin", 0.) + pmin = kwds.get("pmin", 0.0) pmax = kwds.get("pmax", np.inf) x = [] y = [] for dg, peaks, bl, dr in stability.results: - if dg*scale < dgmin or dg*scale > dgmax: + if dg * scale < dgmin or dg * scale > dgmax: continue peakpos = [p["position"] for p in peaks] peakpos = [p for p in peakpos if p >= pmin and p <= pmax] x.extend(peakpos) - y.extend(np.zeros_like(peakpos) + dg*scale) + y.extend(np.zeros_like(peakpos) + dg * scale) plt.plot(x, y, **dg_style) + def labelallsubplots(): rv = [] - for i, c in enumerate('abcd'): + for i, c in enumerate("abcd"): plt.subplot(221 + i) s = "(%s)" % c - ht = plt.text(0.04, 0.95, s, - horizontalalignment='left', verticalalignment='top', - transform=plt.gca().transAxes, weight='bold') + ht = plt.text( + 0.04, + 0.95, + s, + horizontalalignment="left", + verticalalignment="top", + transform=plt.gca().transAxes, + weight="bold", + ) rv.append(ht) return rv @@ -165,14 +187,16 @@ def makeplot(ppe_or_stability, ip=None, **kwds): if ppe.extracted is None: # Makeplot requires a ModelCluster, so whip one up. from diffpy.srmise import ModelCluster - ppe.defaultvars() # Make sure everything has some setting. This - # shouldn't have harmful side effects. + + ppe.defaultvars() # Make sure everything has some setting. This + # shouldn't have harmful side effects. rangeslice = ppe.getrangeslice() x = ppe.x[rangeslice] y = ppe.y[rangeslice] dy = ppe.effective_dy[rangeslice] - mcluster = ModelCluster(ppe.initial_peaks, ppe.baseline, x, y, \ - dy, None, ppe.error_method, ppe.pf) + mcluster = ModelCluster( + ppe.initial_peaks, ppe.baseline, x, y, dy, None, ppe.error_method, ppe.pf + ) ext = mcluster else: ext = ppe.extracted @@ -190,14 +214,14 @@ def makeplot(ppe_or_stability, ip=None, **kwds): # Define heights and interstitial offsets # All values in percent of main axis. - top_offset = kwds.get("top_offset", 0.) - dg_height = kwds.get("dg_height", 15. if stability is not None else 0.) - cmp_height = kwds.get("cmp_height", 15. if ip is not None else 7.5) - datatop_offset = kwds.get("datatop_offset", 3.) + top_offset = kwds.get("top_offset", 0.0) + dg_height = kwds.get("dg_height", 15.0 if stability is not None else 0.0) + cmp_height = kwds.get("cmp_height", 15.0 if ip is not None else 7.5) + datatop_offset = kwds.get("datatop_offset", 3.0) # <- Data appears here -> - databottom_offset = kwds.get("databottom_offset", 3.) + databottom_offset = kwds.get("databottom_offset", 3.0) # <- Residual appears here -> - bottom_offset = kwds.get("bottom_offset", 3.) + bottom_offset = kwds.get("bottom_offset", 3.0) # Style options dg_style = kwds.get("dg_style", default_dg_style) @@ -209,83 +233,94 @@ def makeplot(ppe_or_stability, ip=None, **kwds): ip_style = kwds.get("ip_style", default_ip_style) # Label options - userxlabel = kwds.get("xlabel", r'r ($\mathrm{\AA}$)') - userylabel = kwds.get("ylabel", r'G ($\mathrm{\AA^{-2}}$)') - datalabelx = kwds.get("datalabelx", .04) - yideal_label = kwds.get("yideal_label", r'ideal') - yext_label = kwds.get("yext_label", r'found') + userxlabel = kwds.get("xlabel", r"r ($\mathrm{\AA}$)") + userylabel = kwds.get("ylabel", r"G ($\mathrm{\AA^{-2}}$)") + datalabelx = kwds.get("datalabelx", 0.04) + yideal_label = kwds.get("yideal_label", r"ideal") + yext_label = kwds.get("yext_label", r"found") # Other options datalabel = kwds.get("datalabel", None) - dgformatstr = kwds.get("dgformatstr", r'$\delta$g=%f') - dgformatpost = kwds.get("dgformatpost", None) #->userfunction(string) + dgformatstr = kwds.get("dgformatstr", r"$\delta$g=%f") + dgformatpost = kwds.get("dgformatpost", None) # ->userfunction(string) show_fit = kwds.get("show_fit", True) show_individual = kwds.get("show_individual", True) fill_individual = kwds.get("fill_individual", True) show_observed = kwds.get("show_observed", True) show_residual = kwds.get("show_residual", True) - mask_residual = kwds.get("mask_residual", False) #-> number + mask_residual = kwds.get("mask_residual", False) # -> number show_annotation = kwds.get("show_annotation", True) - scale = kwds.get("scale", 1.) # Apply a global scaling factor to the data - - + scale = kwds.get("scale", 1.0) # Apply a global scaling factor to the data # Define the various data which will be plotted r = ext.r_cluster - dr = (r[-1]-r[0])/len(r) - rexpand = np.concatenate((np.arange(r[0]-dr, xlo, -dr)[::-1], r, np.arange(r[-1]+dr, xhi+dr, dr))) - rfine = np.arange(r[0], r[-1], .1*dr) - gr_obs = np.array(resample(ppe.x, ppe.y, rexpand))*scale - #gr_fit = resample(r, ext.value(), rfine) - gr_fit = np.array(ext.value(rfine))*scale - gr_fit_baseline = np.array(ext.valuebl(rfine))*scale - gr_fit_ind = [gr_fit_baseline + np.array(p.value(rfine))*scale for p in ext.model] - gr_res = np.array(ext.residual())*scale + dr = (r[-1] - r[0]) / len(r) + rexpand = np.concatenate( + (np.arange(r[0] - dr, xlo, -dr)[::-1], r, np.arange(r[-1] + dr, xhi + dr, dr)) + ) + rfine = np.arange(r[0], r[-1], 0.1 * dr) + gr_obs = np.array(resample(ppe.x, ppe.y, rexpand)) * scale + # gr_fit = resample(r, ext.value(), rfine) + gr_fit = np.array(ext.value(rfine)) * scale + gr_fit_baseline = np.array(ext.valuebl(rfine)) * scale + gr_fit_ind = [gr_fit_baseline + np.array(p.value(rfine)) * scale for p in ext.model] + gr_res = np.array(ext.residual()) * scale if mask_residual: gr_res = np.ma.masked_outside(gr_res, -mask_residual, mask_residual) all_gr = [] - if show_fit: all_gr.append(gr_fit) - #if show_individual: all_gr.extend([gr_fit_baseline, gr_fit_ind]) + if show_fit: + all_gr.append(gr_fit) + # if show_individual: all_gr.extend([gr_fit_baseline, gr_fit_ind]) if show_individual: all_gr.append(gr_fit_baseline) if len(gr_fit_ind) > 0: all_gr.extend(gr_fit_ind) - if show_observed: all_gr.append(gr_obs) + if show_observed: + all_gr.append(gr_obs) # gr_fit_ind is a list of lists, so use np.min/max # The funky bit with scale makes sure that a user-specified value # has scale applied to it, without messing up the default values, # which are calculated from already scaled quantities. - min_gr = kwds.get("min_gr", np.min([np.min(gr) for gr in all_gr])/scale)*scale - max_gr = kwds.get("max_gr", np.max([np.max(gr) for gr in all_gr])/scale)*scale - + min_gr = kwds.get("min_gr", np.min([np.min(gr) for gr in all_gr]) / scale) * scale + max_gr = kwds.get("max_gr", np.max([np.max(gr) for gr in all_gr]) / scale) * scale if show_residual: min_res = np.min(gr_res) max_res = np.max(gr_res) else: - min_res = 0. - max_res = 0. + min_res = 0.0 + max_res = 0.0 # Derive various y limits based on all the offsets - rel_height = 100. - top_offset - dg_height - cmp_height - datatop_offset - databottom_offset - bottom_offset - abs_height = 100*((max_gr - min_gr) + (max_res - min_res))/rel_height - - yhi = max_gr + (top_offset + dg_height + cmp_height + datatop_offset)*abs_height/100 + rel_height = ( + 100.0 + - top_offset + - dg_height + - cmp_height + - datatop_offset + - databottom_offset + - bottom_offset + ) + abs_height = 100 * ((max_gr - min_gr) + (max_res - min_res)) / rel_height + + yhi = ( + max_gr + + (top_offset + dg_height + cmp_height + datatop_offset) * abs_height / 100 + ) ylo = yhi - abs_height yhi = kwds.get("yhi", yhi) ylo = kwds.get("ylo", ylo) - datatop = yhi - (yhi-ylo)*.01*(top_offset + dg_height + cmp_height) - datalabeltop = 1 - .01*(top_offset + dg_height + cmp_height + datatop_offset) - resbase = ylo + bottom_offset*abs_height/100 - min_res + datatop = yhi - (yhi - ylo) * 0.01 * (top_offset + dg_height + cmp_height) + datalabeltop = 1 - 0.01 * (top_offset + dg_height + cmp_height + datatop_offset) + resbase = ylo + bottom_offset * abs_height / 100 - min_res resbase = kwds.get("resbase", resbase) - fig = kwds.get("figure", plt.gcf()) fig.clf() ax_data = AA.Subplot(fig, 111) @@ -302,8 +337,8 @@ def makeplot(ppe_or_stability, ip=None, **kwds): for peak in gr_fit_ind: plt.fill_between(rfine, gr_fit_baseline, peak, **gind_style) if show_residual: - plt.plot(r, gr_res + resbase, 'r-', **gres_style) - plt.plot((xlo, xhi), 2*[resbase], 'k:') + plt.plot(r, gr_res + resbase, "r-", **gres_style) + plt.plot((xlo, xhi), 2 * [resbase], "k:") # Format ax_data plt.xlim(xlo, xhi) @@ -311,27 +346,41 @@ def makeplot(ppe_or_stability, ip=None, **kwds): plt.xlabel(userxlabel) plt.ylabel(userylabel) ax_data.xaxis.set_minor_locator(plt.MultipleLocator(1)) - #ax_data.yaxis.set_minor_locator(plt.MultipleLocator(np.max([1,int((yhi-ylo)/20)]))) - ax_data.yaxis.set_label_position('left') + # ax_data.yaxis.set_minor_locator(plt.MultipleLocator(np.max([1,int((yhi-ylo)/20)]))) + ax_data.yaxis.set_label_position("left") ax_data.yaxis.tick_left() - ax_data.yaxis.set_ticks_position('both') + ax_data.yaxis.set_ticks_position("both") # Remove labels above where insets begin - #ax_data.yaxis.set_ticklabels([str(int(loc)) for loc in ax_data.yaxis.get_majorticklocs() if loc < datatop]) - ax_data.yaxis.set_ticks([loc for loc in ax_data.yaxis.get_majorticklocs() if (loc < datatop and loc >= ylo)]) - + # ax_data.yaxis.set_ticklabels([str(int(loc)) for loc in ax_data.yaxis.get_majorticklocs() if loc < datatop]) + ax_data.yaxis.set_ticks( + [ + loc + for loc in ax_data.yaxis.get_majorticklocs() + if (loc < datatop and loc >= ylo) + ] + ) # Dataset label if datalabel is not None: - dl = plt.text(datalabelx, datalabeltop, datalabel, ha='left', va='top', - transform=ax_data.transAxes, weight='bold') + dl = plt.text( + datalabelx, + datalabeltop, + datalabel, + ha="left", + va="top", + transform=ax_data.transAxes, + weight="bold", + ) else: dl = None figdict["datalabel"] = dl # Create new x axis at bottom edge of compare inset ax_data.axis["top"].set_visible(False) - ax_data.axis["newtop"] = ax_data.new_floating_axis(0, datatop, axis_direction="bottom") # "top" bugged? + ax_data.axis["newtop"] = ax_data.new_floating_axis( + 0, datatop, axis_direction="bottom" + ) # "top" bugged? ax_data.axis["newtop"].toggle(all=False, ticks=True) ax_data.axis["newtop"].major_ticks.set_tick_out(True) ax_data.axis["newtop"].minor_ticks.set_tick_out(True) @@ -340,37 +389,57 @@ def makeplot(ppe_or_stability, ip=None, **kwds): # The original label is invisible, but we use its (dynamic) x position # to update the new label, which we define have the correct y position. # A bit of a tradeoff for the nice insets and ability to define new axes. - newylabel = plt.text(-.1, .5*(datatop-ylo)/(yhi-ylo), userylabel, - ha='center', va='center', rotation='vertical', transform=ax_data.transAxes) - labeldict[fig] = newylabel # so we can find the correct text object - fig.canvas.mpl_connect('draw_event', on_draw) # original label invisibility and updating + newylabel = plt.text( + -0.1, + 0.5 * (datatop - ylo) / (yhi - ylo), + userylabel, + ha="center", + va="center", + rotation="vertical", + transform=ax_data.transAxes, + ) + labeldict[fig] = newylabel # so we can find the correct text object + fig.canvas.mpl_connect( + "draw_event", on_draw + ) # original label invisibility and updating # Compare extracted (and ideal, if provided) peak positions clearly. if cmp_height > 0: - ax_cmp = inset_axes(ax_data, - width="100%", - height="%s%%" %cmp_height, - loc=2, - bbox_to_anchor=(0., -.01*(top_offset+dg_height), 1, 1), - bbox_transform=ax_data.transAxes, - borderpad=0) + ax_cmp = inset_axes( + ax_data, + width="100%", + height="%s%%" % cmp_height, + loc=2, + bbox_to_anchor=(0.0, -0.01 * (top_offset + dg_height), 1, 1), + bbox_transform=ax_data.transAxes, + borderpad=0, + ) figdict["cmp"] = ax_cmp plt.axes(ax_cmp) - comparepositions(ext, ip, ep_style=ep_style, ip_style=ip_style, yideal_label=yideal_label, yext_label=yext_label) + comparepositions( + ext, + ip, + ep_style=ep_style, + ip_style=ip_style, + yideal_label=yideal_label, + yext_label=yext_label, + ) plt.xlim(xlo, xhi) ax_cmp.set_xticks([]) # Show how extracted peak positions change as dg is changed if dg_height > 0: - ax_dg = inset_axes(ax_data, - width="100%", - height="%s%%" %dg_height, - loc=2, - bbox_to_anchor=(0, -.01*top_offset, 1, 1), - bbox_transform=ax_data.transAxes, - borderpad=0) + ax_dg = inset_axes( + ax_data, + width="100%", + height="%s%%" % dg_height, + loc=2, + bbox_to_anchor=(0, -0.01 * top_offset, 1, 1), + bbox_transform=ax_data.transAxes, + borderpad=0, + ) figdict["dg"] = ax_dg plt.axes(ax_dg) @@ -385,31 +454,42 @@ def makeplot(ppe_or_stability, ip=None, **kwds): plt.xlim(xlo, xhi) ax_dg.xaxis.set_major_locator(plt.NullLocator()) ax_dg.yaxis.set_major_locator(plt.MaxNLocator(3)) - plt.ylabel(r'$\delta$g') + plt.ylabel(r"$\delta$g") # Annotate the actual dg shown if show_annotation: - dg = np.mean(ext.error_cluster)*scale - dgstr = dgformatstr %dg - if "dgformatpost" in kwds: #post-processing on dg annotation + dg = np.mean(ext.error_cluster) * scale + dgstr = dgformatstr % dg + if "dgformatpost" in kwds: # post-processing on dg annotation dgstr = kwds["dgformatpost"](dgstr) if len(ext.model) > 0: - xpos = np.mean([xlo, ext.model[0]["position"]]) # OK for now. + xpos = np.mean([xlo, ext.model[0]["position"]]) # OK for now. else: - xpos = xlo + .1*(xhi-xlo) + xpos = xlo + 0.1 * (xhi - xlo) if dg_height > 0 and cmp_height > 0: # Arrow, text in compare distances line ylo2, yhi2 = ax_dg.get_ylim() if ip is not None: - ypos = ylo2 - .25*cmp_height/dg_height*(yhi2-ylo2) + ypos = ylo2 - 0.25 * cmp_height / dg_height * (yhi2 - ylo2) else: - ypos = ylo2 - .5*cmp_height/dg_height*(yhi2-ylo2) - plt.annotate(dgstr, xy=(xlo, dg), xycoords='data', va='center', ha='center', - xytext=(xpos,ypos), textcoords='data', size=8, color='green', - arrowprops=dict(arrowstyle="->", - connectionstyle="angle,angleA=90,angleB=0,rad=10", - color="green")) + ypos = ylo2 - 0.5 * cmp_height / dg_height * (yhi2 - ylo2) + plt.annotate( + dgstr, + xy=(xlo, dg), + xycoords="data", + va="center", + ha="center", + xytext=(xpos, ypos), + textcoords="data", + size=8, + color="green", + arrowprops=dict( + arrowstyle="->", + connectionstyle="angle,angleA=90,angleB=0,rad=10", + color="green", + ), + ) elif dg_height > 0: # Arrow, and text located somewhere in main plot region @@ -420,8 +500,8 @@ def makeplot(ppe_or_stability, ip=None, **kwds): # Must change axes plt.axes(ax_cmp) ylo2, yhi2 = ax_cmp.get_ylim() - ypos = yhi2/2. - plt.text(xpos, ypos, dgstr, va='center', ha='center', size=8, color='green') + ypos = yhi2 / 2.0 + plt.text(xpos, ypos, dgstr, va="center", ha="center", size=8, color="green") else: # Text only in main plot region # Must change axes @@ -440,6 +520,8 @@ def makeplot(ppe_or_stability, ip=None, **kwds): # invisiblelabel must be temporarily made visible to update # its values. _lastxpos = {} + + def on_draw(event): global _lastxpos fig = event.canvas.figure @@ -459,7 +541,7 @@ def on_draw(event): # If it is kept visible the whole time this problem doesn't occur. # This problem doesn't occur onscreen (TkAgg) or printing PDFs, and # didn't occur in matplotlib 1.0.0. - if abs(xpos - _lastxpos.get(fig, 0)) > .001: + if abs(xpos - _lastxpos.get(fig, 0)) > 0.001: _lastxpos[fig] = xpos plt.draw() else: @@ -467,25 +549,27 @@ def on_draw(event): invisiblelabel.set_visible(False) xpos_old = visiblelabel.get_position()[0] - if abs(xpos - xpos_old) > .001: + if abs(xpos - xpos_old) > 0.001: labeldict[fig].set_x(xpos) plt.draw() return + def readcompare(filename): """Returns a list of distances read from filename, otherwise None.""" from diffpy.srmise.srmiseerrors import SrMiseDataFormatError, SrMiseFileError # TODO: Make this safer try: - datastring = open(filename,'rb').read() + datastring = open(filename, "rb").read() except Exception as err: raise err import re - res = re.search(r'^[^#]', datastring, re.M) + + res = re.search(r"^[^#]", datastring, re.M) if res: - datastring = datastring[res.end():].strip() + datastring = datastring[res.end() :].strip() distances = [] @@ -493,7 +577,7 @@ def readcompare(filename): for line in datastring.split("\n"): distances.append(float(line)) except (ValueError, IndexError) as err: - print("Could not read distances from '%s'. Ignoring file." %filename) + print("Could not read distances from '%s'. Ignoring file." % filename) if len(distances) == 0: return None @@ -503,31 +587,43 @@ def readcompare(filename): def main(): # configure options parsing - usage = ("%prog srmise_file [options]\n" - "srmise_file can be an extraction file saved by SrMise, " - "or a data file saved by PeakStability.") - descr = ("A very basic tool for somewhat prettier plotting than provided by " - "the basic SrMise classes. Can be used to compare peak positions " - "with those from a list.\n" - "NOTE: At this time the utility only works with peaks extracted using diffpy.srmise.PDFPeakExtraction.") + usage = ( + "%prog srmise_file [options]\n" + "srmise_file can be an extraction file saved by SrMise, " + "or a data file saved by PeakStability." + ) + descr = ( + "A very basic tool for somewhat prettier plotting than provided by " + "the basic SrMise classes. Can be used to compare peak positions " + "with those from a list.\n" + "NOTE: At this time the utility only works with peaks extracted using diffpy.srmise.PDFPeakExtraction." + ) parser = optparse.OptionParser(usage=usage, description=descr) - parser.add_option("--compare", type="string", - help="Compare extracted distances to distances listed (1/line) in this file.") - parser.add_option("--model", type="int", - help="Plot given model from set. Ignored if srmise_file is not a PeakStability file.") - parser.add_option("--show", action="store_true", - help="execute pylab.show() blocking call") - parser.add_option("-o", "--output", type="string", - help="save plot to the specified file") - parser.add_option("--format", type="string", default="eps", - help="output format for plot saving") + parser.add_option( + "--compare", + type="string", + help="Compare extracted distances to distances listed (1/line) in this file.", + ) + parser.add_option( + "--model", + type="int", + help="Plot given model from set. Ignored if srmise_file is not a PeakStability file.", + ) + parser.add_option( + "--show", action="store_true", help="execute pylab.show() blocking call" + ) + parser.add_option( + "-o", "--output", type="string", help="save plot to the specified file" + ) + parser.add_option( + "--format", type="string", default="eps", help="output format for plot saving" + ) parser.allow_interspersed_args = True opts, args = parser.parse_args(sys.argv[1:]) - if len(args) != 1: - parser.error("Exactly one argument required. \n"+usage) + parser.error("Exactly one argument required. \n" + usage) filename = args[0] @@ -535,26 +631,28 @@ def main(): toplot = PDFPeakExtraction() try: toplot.read(filename) - except (Exception): + except Exception: toplot = PeakStability() try: toplot.load(filename) except Exception: - print("File '%s' is not a .srmise or PeakStability data file." %filename) + print( + "File '%s' is not a .srmise or PeakStability data file." % filename + ) return if opts.model is not None: try: toplot.setcurrent(opts.model) - except (Exception): - print("Ignoring model, %s is not a PeakStability file." %filename) + except Exception: + print("Ignoring model, %s is not a PeakStability file." % filename) distances = None if opts.compare is not None: # use baseline from existing file distances = readcompare(opts.compare) - setfigformat(figsize=(6., 4.0)) + setfigformat(figsize=(6.0, 4.0)) figdict = makeplot(toplot, distances) if opts.output: plt.savefig(opts.output, format=opts.format, dpi=600) @@ -565,5 +663,5 @@ def main(): return -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/diffpy/srmise/baselines/arbitrary.py b/diffpy/srmise/baselines/arbitrary.py index 8658a41..b661944 100644 --- a/diffpy/srmise/baselines/arbitrary.py +++ b/diffpy/srmise/baselines/arbitrary.py @@ -23,7 +23,8 @@ logger = logging.getLogger("diffpy.srmise") -class Arbitrary (BaselineFunction): + +class Arbitrary(BaselineFunction): """Methods for evaluating a baseline from an arbitrary function. Supports baseline calculations with arbitrary functions. These functions, @@ -65,10 +66,10 @@ def __init__(self, npars, valuef, jacobianf=None, estimatef=None, Cache=None): # Define parameterdict # e.g. {"a_0":0, "a_1":1, "a_2":2, "a_3":3} if npars is 4. parameterdict = {} - for d in range(self.testnpars+1): - parameterdict["a_"+str(d)] = d - formats = ['internal'] - default_formats = {'default_input':'internal', 'default_output':'internal'} + for d in range(self.testnpars + 1): + parameterdict["a_" + str(d)] = d + formats = ["internal"] + default_formats = {"default_input": "internal", "default_output": "internal"} # Check that the provided functions are at least callable if valuef is None or callable(valuef): @@ -94,7 +95,9 @@ def __init__(self, npars, valuef, jacobianf=None, estimatef=None, Cache=None): metadict["valuef"] = (valuef, repr) metadict["jacobianf"] = (jacobianf, repr) metadict["estimatef"] = (estimatef, repr) - BaselineFunction.__init__(self, parameterdict, formats, default_formats, metadict, None, Cache) + BaselineFunction.__init__( + self, parameterdict, formats, default_formats, metadict, None, Cache + ) #### Methods required by BaselineFunction #### @@ -116,8 +119,7 @@ def estimate_parameters(self, r, y): try: return self.estimatef(r, y) except Exception as e: - emsg = "Error within estimation routine provided to Arbitrary:\n"+\ - str(e) + emsg = "Error within estimation routine provided to Arbitrary:\n" + str(e) raise SrMiseEstimationError(emsg) def _jacobianraw(self, pars, r, free): @@ -138,10 +140,10 @@ def _jacobianraw(self, pars, r, free): emsg = "No jacobian routine provided to Arbitrary." raise NotImplementedError(emsg) if len(pars) != self.npars: - emsg = "Argument pars must have "+str(self.npars)+" elements." + emsg = "Argument pars must have " + str(self.npars) + " elements." raise ValueError(emsg) if len(free) != self.npars: - emsg = "Argument free must have "+str(self.npars)+" elements." + emsg = "Argument free must have " + str(self.npars) + " elements." raise ValueError(emsg) # Allow an arbitrary function without a Jacobian provided act as @@ -171,15 +173,17 @@ def _transform_parametersraw(self, pars, in_format, out_format): if in_format == "internal": pass else: - raise ValueError("Argument 'in_format' must be one of %s." \ - % self.parformats) + raise ValueError( + "Argument 'in_format' must be one of %s." % self.parformats + ) # Convert to specified output format from "internal" format. if out_format == "internal": pass else: - raise ValueError("Argument 'out_format' must be one of %s." \ - % self.parformats) + raise ValueError( + "Argument 'out_format' must be one of %s." % self.parformats + ) return temp def _valueraw(self, pars, r): @@ -193,7 +197,7 @@ def _valueraw(self, pars, r): ... r: sequence or scalar over which pars is evaluated""" if len(pars) != self.npars: - emsg = "Argument pars must have "+str(self.npars)+" elements." + emsg = "Argument pars must have " + str(self.npars) + " elements." raise ValueError(emsg) # TODO: check that valuef returns something proper? @@ -202,19 +206,20 @@ def _valueraw(self, pars, r): def getmodule(self): return __name__ -#end of class Polynomial + +# end of class Polynomial # simple test code -if __name__ == '__main__': +if __name__ == "__main__": - f = Polynomial(degree = 3) + f = Polynomial(degree=3) r = np.arange(5) pars = np.array([3, 0, 1, 2]) free = np.array([True, False, True, True]) print(f._valueraw(pars, r)) print(f._jacobianraw(pars, r, free)) - f = Polynomial(degree = -1) + f = Polynomial(degree=-1) r = np.arange(5) pars = np.array([]) free = np.array([]) diff --git a/diffpy/srmise/baselines/fromsequence.py b/diffpy/srmise/baselines/fromsequence.py index 9085977..c75a8aa 100644 --- a/diffpy/srmise/baselines/fromsequence.py +++ b/diffpy/srmise/baselines/fromsequence.py @@ -22,7 +22,8 @@ logger = logging.getLogger("diffpy.srmise") -class FromSequence (BaselineFunction): + +class FromSequence(BaselineFunction): """Methods for evaluation of a baseline from discrete data via interpolation. FromSequence uses cubic spline interpolation (no smoothing) on discrete @@ -46,13 +47,15 @@ def __init__(self, *args, **kwds): or file: Name of file with column of x values and column of y values. """ - if len(args)==1 and len(kwds)==0: + if len(args) == 1 and len(kwds) == 0: # load from file x, y = self.readxy(args[0]) - elif len(args) == 0 and ("file" in kwds and "x" not in kwds and "y" not in kwds): + elif len(args) == 0 and ( + "file" in kwds and "x" not in kwds and "y" not in kwds + ): # load file x, y = self.readxy(kwds["file"]) - elif len(args)==2 and len(kwds)==0: + elif len(args) == 2 and len(kwds) == 0: # Load x, y directly from arguments x = args[0] y = args[1] @@ -69,15 +72,17 @@ def __init__(self, *args, **kwds): emsg = "Sequences x and y must have the same length." raise ValueError(emsg) parameterdict = {} - formats = ['internal'] - default_formats = {'default_input':'internal', 'default_output':'internal'} + formats = ["internal"] + default_formats = {"default_input": "internal", "default_output": "internal"} self.spline = spi.InterpolatedUnivariateSpline(x, y) self.minx = x[0] self.maxx = x[-1] metadict = {} metadict["x"] = (x, self.xyrepr) metadict["y"] = (y, self.xyrepr) - BaselineFunction.__init__(self, parameterdict, formats, default_formats, metadict, None, Cache=None) + BaselineFunction.__init__( + self, parameterdict, formats, default_formats, metadict, None, Cache=None + ) #### Methods required by BaselineFunction #### @@ -102,10 +107,10 @@ def _jacobianraw(self, pars, r, free): r: sequence or scalar over which pars is evaluated free: Empty sequence.""" if len(pars) != self.npars: - emsg = "Argument pars must have "+str(self.npars)+" elements." + emsg = "Argument pars must have " + str(self.npars) + " elements." raise ValueError(emsg) if len(free) != self.npars: - emsg = "Argument free must have "+str(self.npars)+" elements." + emsg = "Argument free must have " + str(self.npars) + " elements." raise ValueError(emsg) return [] @@ -125,15 +130,17 @@ def _transform_parametersraw(self, pars, in_format, out_format): if in_format == "internal": pass else: - raise ValueError("Argument 'in_format' must be one of %s." \ - % self.parformats) + raise ValueError( + "Argument 'in_format' must be one of %s." % self.parformats + ) # Convert to specified output format from "internal" format. if out_format == "internal": pass else: - raise ValueError("Argument 'out_format' must be one of %s." \ - % self.parformats) + raise ValueError( + "Argument 'out_format' must be one of %s." % self.parformats + ) return temp def _valueraw(self, pars, r): @@ -143,18 +150,22 @@ def _valueraw(self, pars, r): pars: Empty sequence r: sequence or scalar over which pars is evaluated""" if len(pars) != self.npars: - emsg = "Argument pars must have "+str(self.npars)+" elements." + emsg = "Argument pars must have " + str(self.npars) + " elements." raise ValueError(emsg) try: if r[0] < self.minx or r[-1] > self.maxx: - logger.warn("Warning: Evaluating interpolating function over %s, outside safe range of %s.", - [r[0], r[-1]], - [self.minx, self.maxx]) + logger.warn( + "Warning: Evaluating interpolating function over %s, outside safe range of %s.", + [r[0], r[-1]], + [self.minx, self.maxx], + ) except (IndexError, TypeError) as e: if r < self.minx or r > self.maxx: - logger.warn("Warning: Evaluating interpolating function at %s, outside safe range of %s.", - r, - [self.minx, self.maxx]) + logger.warn( + "Warning: Evaluating interpolating function at %s, outside safe range of %s.", + r, + [self.minx, self.maxx], + ) return self.spline(r) def getmodule(self): @@ -162,7 +173,7 @@ def getmodule(self): def xyrepr(self, var): """Safe string output of x and y, compatible with eval()""" - return "[%s]" %", ".join([repr(v) for v in var]) + return "[%s]" % ", ".join([repr(v) for v in var]) def readxy(self, filename): """ """ @@ -170,17 +181,18 @@ def readxy(self, filename): # TODO: Make this safer try: - datastring = open(filename,'rb').read() + datastring = open(filename, "rb").read() except Exception as err: raise err import re - res = re.search(r'^[^#]', datastring, re.M) + + res = re.search(r"^[^#]", datastring, re.M) if res: - datastring = datastring[res.end():].strip() + datastring = datastring[res.end() :].strip() - x=[] - y=[] + x = [] + y = [] try: for line in datastring.split("\n"): @@ -192,16 +204,17 @@ def readxy(self, filename): return (np.array(x), np.array(y)) -#end of class FromSequence + +# end of class FromSequence # simple test code -if __name__ == '__main__': +if __name__ == "__main__": - r = np.arange(0, 9.42413, .2) - b = -(np.tanh(.5*r) + np.sin(.5*r)) + r = np.arange(0, 9.42413, 0.2) + b = -(np.tanh(0.5 * r) + np.sin(0.5 * r)) f = FromSequence(r, b) pars = np.array([]) free = np.array([]) - r2 = np.arange(0, 9.42413, .5) + r2 = np.arange(0, 9.42413, 0.5) b2 = f._valueraw(pars, r2)