From f353243c19bc12f8eaf01d9ed5088deb05e9ebe7 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Fri, 27 Dec 2024 20:19:32 -0500 Subject: [PATCH 01/55] replace SCon with modern build tools, rewrite ... ... setup.py and add pyproject.toml --- SConstruct | 177 --------------------------- pyproject.toml | 80 +++++++++++++ requirements/build.txt | 2 + requirements/conda.txt | 3 + requirements/docs.txt | 4 + requirements/pip.txt | 0 requirements/test.txt | 6 + setup.py | 179 +++------------------------- src/extensions/SConscript | 69 ----------- src/extensions/SConscript.configure | 73 ------------ 10 files changed, 113 insertions(+), 480 deletions(-) delete mode 100644 SConstruct create mode 100644 pyproject.toml create mode 100644 requirements/build.txt create mode 100644 requirements/conda.txt create mode 100644 requirements/docs.txt create mode 100644 requirements/pip.txt create mode 100644 requirements/test.txt mode change 100755 => 100644 setup.py delete mode 100644 src/extensions/SConscript delete mode 100644 src/extensions/SConscript.configure diff --git a/SConstruct b/SConstruct deleted file mode 100644 index 23023b4e..00000000 --- a/SConstruct +++ /dev/null @@ -1,177 +0,0 @@ -# This SConstruct is for faster parallel builds. -# Use "setup.py" for normal installation. - -MY_SCONS_HELP = """\ -SCons rules for compiling and installing diffpy.srreal. -SCons build is much faster when run with parallel jobs (-j4). -Usage: scons [target] [var=value] - -Targets: - -module build Python extension module srreal_ext.so [default] -install install to default Python package location -develop copy extension module to src/diffpy/srreal/ directory -test execute unit tests - -Build configuration variables: -%s -Variables can be also assigned in a user script sconsvars.py. -SCons construction environment can be customized in sconscript.local script. -""" - -import os -import re -import subprocess -import platform - -def subdictionary(d, keyset): - return dict(kv for kv in d.items() if kv[0] in keyset) - -def getsyspaths(*names): - pall = sum((os.environ.get(n, '').split(os.pathsep) for n in names), []) - rv = [p for p in pall if os.path.exists(p)] - return rv - -def pyoutput(cmd): - proc = subprocess.Popen([env['python'], '-c', cmd], - stdout=subprocess.PIPE, - universal_newlines=True) - out = proc.communicate()[0] - return out.rstrip() - -def pyconfigvar(name): - cmd = ('from distutils.sysconfig import get_config_var\n' - 'print(get_config_var(%r))\n') % name - return pyoutput(cmd) - -# copy system environment variables related to compilation -DefaultEnvironment(ENV=subdictionary(os.environ, ''' - PATH PYTHONPATH GIT_DIR - CPATH CPLUS_INCLUDE_PATH LIBRARY_PATH LD_RUN_PATH - LD_LIBRARY_PATH DYLD_LIBRARY_PATH DYLD_FALLBACK_LIBRARY_PATH - MACOSX_DEPLOYMENT_TARGET LANG - _PYTHON_SYSCONFIGDATA_NAME - _CONDA_PYTHON_SYSCONFIGDATA_NAME - '''.split()) -) - -# Create construction environment -env = DefaultEnvironment().Clone() - -# Variables definitions below work only with 0.98 or later. -env.EnsureSConsVersion(0, 98) - -# Customizable compile variables -vars = Variables('sconsvars.py') - -vars.Add(PathVariable('prefix', - 'installation prefix directory', None)) -vars.Add(EnumVariable('build', - 'compiler settings', 'fast', - allowed_values=('debug', 'fast'))) -vars.Add(EnumVariable('tool', - 'C++ compiler toolkit to be used', 'default', - allowed_values=('default', 'intelc'))) -vars.Add(BoolVariable('profile', - 'build with profiling information', False)) -vars.Add('python', - 'Python executable to use for installation.', 'python') -vars.Update(env) -env.Help(MY_SCONS_HELP % vars.GenerateHelpText(env)) - -# Use Intel C++ compiler if requested by the user. -icpc = None -if env['tool'] == 'intelc': - icpc = env.WhereIs('icpc') - if not icpc: - print("Cannot find the Intel C/C++ compiler 'icpc'.") - Exit(1) - env.Tool('intelc', topdir=icpc[:icpc.rfind('/bin')]) - -# Figure out compilation switches, filter away C-related items. -good_python_flag = lambda n : ( - not isinstance(n, str) or - not re.match(r'(-g|-Wstrict-prototypes|-O\d|-fPIC)$', n)) -# Determine python-config script name. -pyversion = pyoutput('import sys; print("%i.%i" % sys.version_info[:2])') -pycfgname = 'python%s-config' % (pyversion if pyversion[0] == '3' else '') -pybindir = os.path.dirname(env.WhereIs(env['python'])) -pythonconfig = os.path.join(pybindir, pycfgname) -# Verify python-config comes from the same path as the target python. -xpython = env.WhereIs(env['python']) -xpythonconfig = env.WhereIs(pythonconfig) -if os.path.dirname(xpython) != os.path.dirname(xpythonconfig): - print("Inconsistent paths of %r and %r" % (xpython, xpythonconfig)) - Exit(1) -# Process the python-config flags here. -env.ParseConfig(pythonconfig + " --cflags") -env.Replace(CCFLAGS=[f for f in env['CCFLAGS'] if good_python_flag(f)]) -env.Replace(CPPDEFINES='') -# the CPPPATH directories are checked by scons dependency scanner -cpppath = getsyspaths('CPLUS_INCLUDE_PATH', 'CPATH') -env.AppendUnique(CPPPATH=cpppath) -# Insert LIBRARY_PATH explicitly because some compilers -# ignore it in the system environment. -env.PrependUnique(LIBPATH=getsyspaths('LIBRARY_PATH')) -# Add shared libraries. -# Note: libdiffpy and boost_python are added from SConscript.configure. - -fast_linkflags = ['-s'] -fast_shlinkflags = pyconfigvar('LDSHARED').split()[1:] - -# Specify minimum C++ standard. Allow later standard from sconscript.local. -# In case of multiple `-std` options the last option holds. -env.PrependUnique(CXXFLAGS='-std=c++11', delete_existing=1) - -# Platform specific intricacies. -if env['PLATFORM'] == 'darwin': - env.AppendUnique(CXXFLAGS='-ftemplate-depth-256') - darwin_shlinkflags = [n for n in env['SHLINKFLAGS'] - if n != '-dynamiclib'] - env.Replace(SHLINKFLAGS=darwin_shlinkflags) - env.AppendUnique(SHLINKFLAGS=['-bundle']) - env.AppendUnique(SHLINKFLAGS=['-undefined', 'dynamic_lookup']) - fast_linkflags[:] = [] - -# Compiler specific options -if icpc: - # options for Intel C++ compiler on hpc dev-intel07 - env.AppendUnique(CCFLAGS=['-w1', '-fp-model', 'precise']) - env.PrependUnique(LIBS=['imf']) - fast_optimflags = ['-fast', '-no-ipo'] -else: - # g++ options - env.AppendUnique(CCFLAGS=['-Wall']) - fast_optimflags = ['-ffast-math'] - -# Configure build variants -if env['build'] == 'debug': - env.AppendUnique(CCFLAGS='-g') -elif env['build'] == 'fast': - env.AppendUnique(CCFLAGS=['-O3'] + fast_optimflags) - env.AppendUnique(CPPDEFINES='NDEBUG') - env.AppendUnique(LINKFLAGS=fast_linkflags) - env.AppendUnique(SHLINKFLAGS=fast_shlinkflags) - -if env['profile']: - env.AppendUnique(CCFLAGS='-pg') - env.AppendUnique(LINKFLAGS='-pg') - -builddir = env.Dir('build/%s-%s' % (env['build'], platform.machine())) - -Export('env', 'pyconfigvar', 'pyoutput', 'pyversion') - -def GlobSources(pattern): - """Same as Glob but also require that source node is a valid file. - """ - rv = [f for f in Glob(pattern) if f.srcnode().isfile()] - return rv - -Export('GlobSources') - -if os.path.isfile('sconscript.local'): - env.SConscript('sconscript.local') - -env.SConscript('src/extensions/SConscript', variant_dir=builddir) - -# vim: ft=python diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..79c72f03 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,80 @@ +[build-system] +requires = ["setuptools>=62.0", "setuptools-git-versioning>=2.0", "numpy"] +build-backend = "setuptools.build_meta" + +[project] +name = "diffpy.srreal" +dynamic=['version', 'dependencies'] +authors = [ + { name="Simon J.L. Billinge group", email="simon.billinge@gmail.com" }, +] +maintainers = [ + { name="Simon J.L. Billinge group", email="simon.billinge@gmail.com" }, +] +description = "calculators for PDF, bond valence sum, and other quantities based on atom pair interaction" +keywords = ['PDF BVS atom overlap calculator real-space'] +readme = "README.rst" +requires-python = ">=3.11, <3.14" +classifiers = [ + 'Development Status :: 5 - Production/Stable', + 'Environment :: Console', + 'Intended Audience :: Developers', + 'Intended Audience :: Science/Research', + 'License :: OSI Approved :: BSD License', + 'Operating System :: MacOS :: MacOS X', + 'Operating System :: Microsoft :: Windows', + 'Operating System :: POSIX', + 'Operating System :: Unix', + 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', + 'Programming Language :: Python :: 3.13', + 'Topic :: Scientific/Engineering :: Physics', + 'Topic :: Scientific/Engineering :: Chemistry', +] + +[project.urls] +Homepage = "https://github.com/diffpy/diffpy.srreal/" +Issues = "https://github.com/diffpy/diffpy.srreal/issues/" + +[tool.setuptools-git-versioning] +enabled = true +template = "{tag}" +dev_template = "{tag}" +dirty_template = "{tag}" + +[tool.setuptools.packages.find] +where = ["src"] # list of folders that contain the packages (["."] by default) +include = ["*"] # package names should match these glob patterns (["*"] by default) +exclude = [] # exclude packages matching these glob patterns (empty by default) +namespaces = false # to disable scanning PEP 420 namespaces (true by default) + +[tool.setuptools.dynamic] +dependencies = {file = ["requirements/pip.txt"]} + +[tool.codespell] +exclude-file = ".codespell/ignore_lines.txt" +ignore-words = ".codespell/ignore_words.txt" +skip = "*.cif,*.dat" + +[tool.black] +line-length = 115 +include = '\.pyi?$' +exclude = ''' +/( + \.git + | \.hg + | \.mypy_cache + | \.tox + | \.venv + | \.rst + | \.txt + | _build + | buck-out + | build + | dist + + # The following are specific to Black, you probably don't want those. + | blib2to3 + | tests/data +)/ +''' diff --git a/requirements/build.txt b/requirements/build.txt new file mode 100644 index 00000000..f72d870d --- /dev/null +++ b/requirements/build.txt @@ -0,0 +1,2 @@ +python +setuptools diff --git a/requirements/conda.txt b/requirements/conda.txt new file mode 100644 index 00000000..5e7d3831 --- /dev/null +++ b/requirements/conda.txt @@ -0,0 +1,3 @@ +numpy +boost +diffpy.structure diff --git a/requirements/docs.txt b/requirements/docs.txt new file mode 100644 index 00000000..ab17b1c8 --- /dev/null +++ b/requirements/docs.txt @@ -0,0 +1,4 @@ +sphinx +sphinx_rtd_theme +doctr +m2r diff --git a/requirements/pip.txt b/requirements/pip.txt new file mode 100644 index 00000000..e69de29b diff --git a/requirements/test.txt b/requirements/test.txt new file mode 100644 index 00000000..a7277865 --- /dev/null +++ b/requirements/test.txt @@ -0,0 +1,6 @@ +flake8 +pytest +codecov +coverage +pytest-cov +pytest-env diff --git a/setup.py b/setup.py old mode 100755 new mode 100644 index 6256a9f5..6bb68e4e --- a/setup.py +++ b/setup.py @@ -1,195 +1,52 @@ #!/usr/bin/env python -# Installation script for diffpy.srreal - """diffpy.srreal - calculators for PDF, bond valence sum, and other quantities based on atom pair interaction. Packages: diffpy.srreal """ -import os -import re +import numpy import sys import glob -from setuptools import setup, find_packages -from setuptools import Extension -from numpy.distutils.misc_util import get_numpy_include_dirs +from setuptools import setup, Extension +from ctypes.util import find_library -# Use this version when git data are not available, like in git zip archive. -# Update when tagging a new release. -FALLBACK_VERSION = '1.3.0.post0' +def get_boost_libraries(): + base_lib = "boost_python" + major, minor = str(sys.version_info[0]), str(sys.version_info[1]) + tags = [f"{major}{minor}", major, ""] + mttags = ["", "-mt"] + candidates = [base_lib + tag for tag in tags for mt in mttags] + [base_lib] + for lib in candidates: + if find_library(lib): + return [lib] + raise RuntimeError("Cannot find a suitable Boost.Python library.") -# define extension arguments here ext_kws = { - 'libraries' : ['diffpy'], - 'extra_compile_args' : ['-std=c++11'], + 'libraries' : ["diffpy"] + get_boost_libraries(), + 'extra_compile_args' : ["-std=c++11"], 'extra_link_args' : [], - 'include_dirs' : get_numpy_include_dirs(), + 'include_dirs' : [numpy.get_include()], } -# determine if we run with Python 3. -PY3 = (sys.version_info[0] == 3) - -# Figure out the tagged name of boost_python library. -def get_boost_libraries(): - """Check for installed boost_python shared library. - - Returns list of required boost_python shared libraries that are installed - on the system. If required libraries are not found, an Exception will be - thrown. - """ - baselib = "boost_python" - major, minor = (str(x) for x in sys.version_info[:2]) - pytags = [major + minor, major, ''] - mttags = ['', '-mt'] - boostlibtags = [(pt + mt) for mt in mttags for pt in pytags] + [''] - from ctypes.util import find_library - for tag in boostlibtags: - lib = baselib + tag - found = find_library(lib) - if found: break - - # Show warning when library was not detected. - if not found: - import platform - import warnings - ldevname = 'LIBRARY_PATH' - if platform.system() == 'Darwin': - ldevname = 'DYLD_FALLBACK_LIBRARY_PATH' - wmsg = ("Cannot detect name suffix for the %r library. " - "Consider setting %s.") % (baselib, ldevname) - warnings.warn(wmsg) - - libs = [lib] - return libs - def create_extensions(): "Initialize Extension objects for the setup function." - blibs = [n for n in get_boost_libraries() - if not n in ext_kws['libraries']] - ext_kws['libraries'] += blibs ext = Extension('diffpy.srreal.srreal_ext', glob.glob('src/extensions/*.cpp'), **ext_kws) return [ext] -# versioncfgfile holds version data for git commit hash and date. -# It must reside in the same directory as version.py. -MYDIR = os.path.dirname(os.path.abspath(__file__)) -versioncfgfile = os.path.join(MYDIR, 'src/diffpy/srreal/version.cfg') -gitarchivecfgfile = os.path.join(MYDIR, '.gitarchive.cfg') - - -def gitinfo(): - from subprocess import Popen, PIPE - kw = dict(stdout=PIPE, cwd=MYDIR, universal_newlines=True) - proc = Popen(['git', 'describe', '--match=v[[:digit:]]*'], **kw) - desc = proc.stdout.read() - proc = Popen(['git', 'log', '-1', '--format=%H %ct %ci'], **kw) - glog = proc.stdout.read() - rv = {} - rv['version'] = '.post'.join(desc.strip().split('-')[:2]).lstrip('v') - rv['commit'], rv['timestamp'], rv['date'] = glog.strip().split(None, 2) - return rv - - -def getversioncfg(): - if PY3: - from configparser import RawConfigParser - else: - from ConfigParser import RawConfigParser - vd0 = dict(version=FALLBACK_VERSION, commit='', date='', timestamp=0) - # first fetch data from gitarchivecfgfile, ignore if it is unexpanded - g = vd0.copy() - cp0 = RawConfigParser(vd0) - cp0.read(gitarchivecfgfile) - if len(cp0.get('DEFAULT', 'commit')) > 20: - g = cp0.defaults() - mx = re.search(r'\btag: v(\d[^,]*)', g.pop('refnames')) - if mx: - g['version'] = mx.group(1) - # then try to obtain version data from git. - gitdir = os.path.join(MYDIR, '.git') - if os.path.exists(gitdir) or 'GIT_DIR' in os.environ: - try: - g = gitinfo() - except OSError: - pass - # finally, check and update the active version file - cp = RawConfigParser() - cp.read(versioncfgfile) - d = cp.defaults() - rewrite = not d or (g['commit'] and ( - g['version'] != d.get('version') or g['commit'] != d.get('commit'))) - if rewrite: - cp.set('DEFAULT', 'version', g['version']) - cp.set('DEFAULT', 'commit', g['commit']) - cp.set('DEFAULT', 'date', g['date']) - cp.set('DEFAULT', 'timestamp', g['timestamp']) - with open(versioncfgfile, 'w') as fp: - cp.write(fp) - return cp - -versiondata = getversioncfg() - -with open(os.path.join(MYDIR, 'README.rst')) as fp: - long_description = fp.read() - -# define distribution +# Extensions not included in pyproject.toml setup_args = dict( - name = "diffpy.srreal", - version = versiondata.get('DEFAULT', 'version'), - packages = find_packages(os.path.join(MYDIR, 'src')), - package_dir = {'' : 'src'}, - test_suite = 'diffpy.srreal.tests', - include_package_data = True, ext_modules = [], - install_requires = [ - 'diffpy.structure', - ], - zip_safe = False, - - author = "Simon J.L. Billinge group", - author_email = "sb2896@columbia.edu", - maintainer = "Pavol Juhas", - maintainer_email = "pavol.juhas@gmail.com", - description = ("calculators for PDF, bond valence sum, and other " - "quantities based on atom pair interaction."), - long_description = long_description, - long_description_content_type = 'text/x-rst', - license = 'BSD-style license', - url = "https://github.com/diffpy/diffpy.srreal/", - keywords = "PDF BVS atom overlap calculator real-space", - classifiers = [ - # List of possible values at - # http://pypi.python.org/pypi?:action=list_classifiers - 'Development Status :: 5 - Production/Stable', - 'Environment :: Console', - 'Intended Audience :: Developers', - 'Intended Audience :: Education', - 'Intended Audience :: Science/Research', - 'License :: OSI Approved :: BSD License', - 'Operating System :: MacOS :: MacOS X', - 'Operating System :: POSIX', - 'Operating System :: Unix', - 'Programming Language :: C++', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - 'Topic :: Scientific/Engineering :: Chemistry', - 'Topic :: Scientific/Engineering :: Physics', - 'Topic :: Software Development :: Libraries', - ], ) + if __name__ == '__main__': setup_args['ext_modules'] = create_extensions() setup(**setup_args) - -# End of file diff --git a/src/extensions/SConscript b/src/extensions/SConscript deleted file mode 100644 index 5f96f611..00000000 --- a/src/extensions/SConscript +++ /dev/null @@ -1,69 +0,0 @@ -import sys -import os - -Import('env', 'GlobSources', 'pyoutput') - -# make sure numpy headers are available -npdirs = pyoutput( - 'from numpy.distutils.misc_util import get_numpy_include_dirs\n' - 'print("\\n".join(get_numpy_include_dirs()))') -npdirs = [d.strip() for d in npdirs.split('\n')] -env.AppendUnique(CPPPATH=npdirs) - -# configure the boost_python library, which may have different extensions -if not (GetOption('clean') or env.GetOption('help')): - SConscript('SConscript.configure') - -# python extension module -module = env.SharedLibrary('srreal_ext', GlobSources('*.cpp'), - SHLIBPREFIX='', SHLIBSUFFIX='.so') -Alias('module', module) - -# update egg info when package version changes. -basedir = Dir('#').abspath -version = pyoutput( - 'import sys\n' - 'sys.path.insert(0, %r)\n' - 'from setup import versiondata\n' - 'print(versiondata.get("DEFAULT", "version"))\n' % basedir) -egginfo = env.Command(NoCache('#/src/diffpy.srreal.egg-info/PKG-INFO'), - env.Value(version), - '$python -Wignore setup.py egg_info') - -# install extension module in a development mode. -develop = Alias('develop', [egginfo, Install('#/src/diffpy/srreal', module)]) - -test = env.Alias('test', develop, - '$python -m diffpy.srreal.tests.run') -AlwaysBuild(test) - -def resolve_distutils_target(target, source, env): - tgt = pyoutput('\n'.join([ - "from setuptools import Distribution, Extension", - "ext = Extension('diffpy.srreal.srreal_ext', [])", - "attrs = dict(ext_modules=[ext])", - "dist = Distribution(attrs)", - "bcmd = dist.get_command_obj('build_ext')", - "bcmd.finalize_options()", - "print(bcmd.get_ext_fullpath(ext.name))", - ])) - env['distsofile'] = env.File(tgt) - return 0 - -c = '$python setup.py easy_install --no-deps {} .' -p = '--prefix=$prefix' if 'prefix' in env else '' -cmd_install = c.format(p) - -install = env.Alias('install', module, [ - resolve_distutils_target, - Mkdir('$distsofile.dir'), - Copy('$distsofile', '$SOURCE'), - Touch('$distsofile'), - cmd_install, - ]) -AlwaysBuild(install) - -# default targets: -Default(module) - -# vim: ft=python diff --git a/src/extensions/SConscript.configure b/src/extensions/SConscript.configure deleted file mode 100644 index 95851774..00000000 --- a/src/extensions/SConscript.configure +++ /dev/null @@ -1,73 +0,0 @@ -Import('env', 'pyconfigvar', 'pyversion') - -# Helper functions ----------------------------------------------------------- - -def CheckOptimizerFlag(context, flag): - ccflags_save = context.env['CCFLAGS'] - context.Message('Checking if compiler allows {!r}... '.format(flag)) - context.env.Replace(CCFLAGS=[flag]) - result = context.TryCompile('int a;\n', '.cpp') - context.Result(result) - if not result: - ccflags_save.remove(flag) - context.env.Replace(CCFLAGS=ccflags_save) - return result - - -def configure_boost_library(libname): - '''Add a boost library to the configured environment allowing for any - of the boostmttags name extensions. - - libname -- boost library name without any extension - - Note: CheckLib function automatically adds library to the environment. - ''' - mttags = ['', '-mt'] - boostlibtags = mttags - # check more tags for boost_python - if libname == 'boost_python': - major, minor = pyversion.split('.') - pytags = [major + minor, major, ''] - boostlibtags = [(pt + mt) for mt in mttags for pt in pytags] - # using global conf defined below - for t in boostlibtags: - libnamefull = libname + t - if conf.CheckLib(libnamefull, language='C++'): - return - # library not found here - print('This program requires %r library.' % libname) - Exit(1) - -# Start configuration -------------------------------------------------------- - -# Anaconda Python is compiled with super fancy gcc optimizer flags. -# Remove any flags that are not supported by the current compiler. - -custom_tests = {'CheckOptimizerFlag' : CheckOptimizerFlag} -conf = Configure(env, custom_tests=custom_tests) -optflags = [o for o in env['CCFLAGS'] - if o[:2] in ('-f', '-m')] -for o in optflags: - conf.CheckOptimizerFlag(o) -conf.Finish() - -# Create configuration environment that links with Python shared_library, so -# that the boost_python check does not fail due to unresolved Python symbols. -ecfg = env.Clone() -ecfg.Append(LIBS=[]) -ecfg.MergeFlags(pyconfigvar('BLDLIBRARY')) -# make sure there are no implicit dependency nodes in added LIBS -ecfg.Replace(LIBS=[str(n) for n in ecfg['LIBS']]) -newlibsindex = len(ecfg['LIBS']) - -conf = Configure(ecfg) -if not conf.CheckLib('diffpy', language='C++'): - print("This program requires 'libdiffpy' library.") - Exit(1) -configure_boost_library('boost_python') -conf.Finish() - -# Use libraries that were found in the configuration. -env.AppendUnique(LIBS=ecfg['LIBS'][newlibsindex:]) - -# vim: ft=python From 6198d352f84d9babfda3a0e77c93164b79e1dde5 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Fri, 27 Dec 2024 20:47:57 -0500 Subject: [PATCH 02/55] black autofix --- conda-recipe/run_test.py | 1 + devutils/tunePeakPrecision.py | 72 ++--- doc/manual/source/conf.py | 87 +++--- examples/compareC60PDFs.py | 9 +- examples/compareC60PDFs_objcryst.py | 13 +- examples/distanceprinter.py | 50 ++-- examples/lennardjones/ljcalculator.py | 15 +- examples/parallelPDF.py | 17 +- setup.py | 18 +- src/diffpy/__init__.py | 1 + src/diffpy/srreal/_cleanup.py | 6 +- src/diffpy/srreal/_docstrings.py | 28 +- src/diffpy/srreal/_final_imports.py | 30 +- src/diffpy/srreal/_version_data.py | 20 +- src/diffpy/srreal/atomradiitable.py | 26 +- src/diffpy/srreal/attributes.py | 15 +- src/diffpy/srreal/bondcalculator.py | 27 +- src/diffpy/srreal/bvparameterstable.py | 2 +- src/diffpy/srreal/bvscalculator.py | 47 ++-- src/diffpy/srreal/eventticker.py | 2 +- src/diffpy/srreal/overlapcalculator.py | 39 +-- src/diffpy/srreal/pairquantity.py | 2 +- src/diffpy/srreal/parallel.py | 95 ++++--- src/diffpy/srreal/pdfbaseline.py | 22 +- src/diffpy/srreal/pdfcalculator.py | 256 ++++++++++------- src/diffpy/srreal/pdfenvelope.py | 52 ++-- src/diffpy/srreal/peakprofile.py | 14 +- src/diffpy/srreal/peakwidthmodel.py | 46 +-- src/diffpy/srreal/scatteringfactortable.py | 4 +- src/diffpy/srreal/sfaverage.py | 10 +- src/diffpy/srreal/structureadapter.py | 34 ++- src/diffpy/srreal/structureconverters.py | 68 ++--- src/diffpy/srreal/tests/__init__.py | 21 +- src/diffpy/srreal/tests/debug.py | 5 +- src/diffpy/srreal/tests/run.py | 5 +- src/diffpy/srreal/tests/testatomradiitable.py | 164 +++++------ src/diffpy/srreal/tests/testattributes.py | 130 ++++----- src/diffpy/srreal/tests/testbondcalculator.py | 145 ++++------ src/diffpy/srreal/tests/testbvscalculator.py | 84 ++---- .../srreal/tests/testdebyepdfcalculator.py | 117 ++++---- .../srreal/tests/testoverlapcalculator.py | 196 ++++++------- src/diffpy/srreal/tests/testpairquantity.py | 102 +++---- src/diffpy/srreal/tests/testparallel.py | 48 ++-- src/diffpy/srreal/tests/testpdfbaseline.py | 144 ++++------ .../srreal/tests/testpdfcalcobjcryst.py | 60 ++-- src/diffpy/srreal/tests/testpdfcalculator.py | 136 ++++----- src/diffpy/srreal/tests/testpdfenvelope.py | 140 ++++----- src/diffpy/srreal/tests/testpeakprofile.py | 109 +++---- src/diffpy/srreal/tests/testpeakwidthmodel.py | 133 ++++----- .../srreal/tests/testscatteringfactortable.py | 138 ++++----- src/diffpy/srreal/tests/testsfaverage.py | 50 ++-- .../srreal/tests/teststructureadapter.py | 265 +++++++++--------- src/diffpy/srreal/tests/testutils.py | 39 +-- src/diffpy/srreal/version.py | 29 +- src/diffpy/srreal/wraputils.py | 42 +-- 55 files changed, 1673 insertions(+), 1757 deletions(-) diff --git a/conda-recipe/run_test.py b/conda-recipe/run_test.py index d39487ff..0edfe0c3 100644 --- a/conda-recipe/run_test.py +++ b/conda-recipe/run_test.py @@ -1,4 +1,5 @@ #!/usr/bin/env python import diffpy.srreal.tests + assert diffpy.srreal.tests.test().wasSuccessful() diff --git a/devutils/tunePeakPrecision.py b/devutils/tunePeakPrecision.py index 60c76f45..e46c9616 100755 --- a/devutils/tunePeakPrecision.py +++ b/devutils/tunePeakPrecision.py @@ -30,11 +30,12 @@ from diffpy.structure import Structure from diffpy.srreal.pdf_ext import PDFCalculator import diffpy.pdffit2 + # make PdfFit silent -diffpy.pdffit2.redirect_stdout(open('/dev/null', 'w')) +diffpy.pdffit2.redirect_stdout(open("/dev/null", "w")) # define nickel structure data -nickel_discus_data = ''' +nickel_discus_data = """ title Ni spcgr P1 cell 3.523870, 3.523870, 3.523870, 90.000000, 90.000000, 90.000000 @@ -44,10 +45,10 @@ NI 0.00000000 0.50000000 0.50000000 0.1000 NI 0.50000000 0.00000000 0.50000000 0.1000 NI 0.50000000 0.50000000 0.00000000 0.1000 -''' +""" nickel = Structure() -nickel.readStr(nickel_discus_data, format='discus') +nickel.readStr(nickel_discus_data, format="discus") def Gpdffit2(qmax): @@ -59,7 +60,7 @@ def Gpdffit2(qmax): """ # calculate reference data using pdffit2 pf2 = diffpy.pdffit2.PdfFit() - pf2.alloc('X', qmax, 0.0, rmin, rmax, int((rmax - rmin) / rstep + 1)) + pf2.alloc("X", qmax, 0.0, rmin, rmax, int((rmax - rmin) / rstep + 1)) pf2.add_structure(nickel) pf2.calc() rg = numpy.array((pf2.getR(), pf2.getpdf_fit())) @@ -81,7 +82,7 @@ def Gsrreal(qmax, peakprecision=None): pdfcalc._setDoubleAttr("rmax", rmax + rstep * 1e-4) pdfcalc._setDoubleAttr("rstep", rstep) if peakprecision is not None: - pdfcalc._setDoubleAttr('peakprecision', peakprecision) + pdfcalc._setDoubleAttr("peakprecision", peakprecision) pdfcalc.eval(nickel) rg = numpy.array([pdfcalc.rgrid, pdfcalc.pdf]) return rg @@ -105,30 +106,31 @@ def comparePDFCalculators(qmax, peakprecision=None): t0, t1 -- CPU times used by pdffit2 and PDFCalculator calls """ rv = {} - rv['qmax'] = qmax - rv['peakprecision'] = (peakprecision is None and - PDFCalculator()._getDoubleAttr('peakprecision') or peakprecision) + rv["qmax"] = qmax + rv["peakprecision"] = ( + peakprecision is None and PDFCalculator()._getDoubleAttr("peakprecision") or peakprecision + ) ttic = time.clock() rg0 = Gpdffit2(qmax) ttoc = time.clock() - rv['r'] = rg0[0] - rv['g0'] = rg0[1] - rv['t0'] = ttoc - ttic + rv["r"] = rg0[0] + rv["g0"] = rg0[1] + rv["t0"] = ttoc - ttic ttic = time.clock() rg1 = Gsrreal(qmax, peakprecision) ttoc = time.clock() - assert numpy.all(rv['r'] == rg1[0]) - rv['g1'] = rg1[1] - rv['t1'] = ttoc - ttic - rv['gdiff'] = rv['g0'] - rv['g1'] - rv['grmsd'] = numpy.sqrt(numpy.mean(rv['gdiff']**2)) + assert numpy.all(rv["r"] == rg1[0]) + rv["g1"] = rg1[1] + rv["t1"] = ttoc - ttic + rv["gdiff"] = rv["g0"] - rv["g1"] + rv["grmsd"] = numpy.sqrt(numpy.mean(rv["gdiff"] ** 2)) return rv def processCommandLineArguments(): global qmax, peakprecision, createplot argc = len(sys.argv) - if set(['-h', '--help']).intersection(sys.argv): + if set(["-h", "--help"]).intersection(sys.argv): print(__doc__) sys.exit() if argc > 1: @@ -136,7 +138,7 @@ def processCommandLineArguments(): if argc > 2: peakprecision = float(sys.argv[2]) if argc > 3: - createplot = sys.argv[3].lower() in ('y', 'yes', '1', 'true') + createplot = sys.argv[3].lower() in ("y", "yes", "1", "true") return @@ -148,22 +150,23 @@ def plotComparison(cmpdata): No return value. """ import pylab + pylab.clf() pylab.subplot(211) - pylab.title('qmax=%(qmax)g peakprecision=%(peakprecision)g' % cmpdata) - pylab.ylabel('G') - r = cmpdata['r'] - g0 = cmpdata['g0'] - g1 = cmpdata['g1'] - gdiff = cmpdata['gdiff'] + pylab.title("qmax=%(qmax)g peakprecision=%(peakprecision)g" % cmpdata) + pylab.ylabel("G") + r = cmpdata["r"] + g0 = cmpdata["g0"] + g1 = cmpdata["g1"] + gdiff = cmpdata["gdiff"] pylab.plot(r, g0, r, g1) pylab.subplot(212) - pylab.plot(r, gdiff, 'r') + pylab.plot(r, gdiff, "r") slope = numpy.sum(r * gdiff) / numpy.sum(r**2) - pylab.plot(r, slope * r, '--') - pylab.xlabel('r') - pylab.ylabel('Gdiff') - pylab.title('slope = %g' % slope) + pylab.plot(r, slope * r, "--") + pylab.xlabel("r") + pylab.ylabel("Gdiff") + pylab.title("slope = %g" % slope) pylab.draw() return @@ -171,14 +174,17 @@ def plotComparison(cmpdata): def main(): processCommandLineArguments() cmpdata = comparePDFCalculators(qmax, peakprecision) - print(("qmax = %(qmax)g pkprec = %(peakprecision)g " + - "grmsd = %(grmsd)g t0 = %(t0).3f t1 = %(t1).3f") % cmpdata) + print( + ("qmax = %(qmax)g pkprec = %(peakprecision)g " + "grmsd = %(grmsd)g t0 = %(t0).3f t1 = %(t1).3f") + % cmpdata + ) if createplot: plotComparison(cmpdata) import pylab + pylab.show() return -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/doc/manual/source/conf.py b/doc/manual/source/conf.py index 5d2c4878..307ec098 100644 --- a/doc/manual/source/conf.py +++ b/doc/manual/source/conf.py @@ -19,11 +19,11 @@ # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) -sys.path.insert(0, os.path.abspath('../../..')) +# sys.path.insert(0, os.path.abspath('.')) +sys.path.insert(0, os.path.abspath("../../..")) # abbreviations -ab_authors = u'Pavol Juhás, Christopher L. Farrow, Simon J.L. Billinge group' +ab_authors = "Pavol Juhás, Christopher L. Farrow, Simon J.L. Billinge group" # -- General configuration ----------------------------------------------------- @@ -33,38 +33,39 @@ # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [ - 'sphinx.ext.autodoc', - 'sphinx.ext.coverage', - 'sphinx.ext.napoleon', - 'sphinx.ext.intersphinx', - 'm2r', + "sphinx.ext.autodoc", + "sphinx.ext.coverage", + "sphinx.ext.napoleon", + "sphinx.ext.intersphinx", + "m2r", ] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # -source_suffix = ['.rst', '.md'] +source_suffix = [".rst", ".md"] # The encoding of source files. # source_encoding = 'utf-8-sig' # The master toctree document. -master_doc = 'index' +master_doc = "index" # General information about the project. -project = 'diffpy.srreal' -copyright = '%Y, Brookhaven National Laboratory' +project = "diffpy.srreal" +copyright = "%Y, Brookhaven National Laboratory" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. from setup import versiondata -fullversion = versiondata.get('DEFAULT', 'version') + +fullversion = versiondata.get("DEFAULT", "version") # The short X.Y version. -version = ''.join(fullversion.split('.post')[:1]) +version = "".join(fullversion.split(".post")[:1]) # The full version, including alpha/beta/rc tags. release = fullversion @@ -75,13 +76,13 @@ # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: # today = '' -today_seconds = versiondata.getint('DEFAULT', 'timestamp') -today = time.strftime('%B %d, %Y', time.localtime(today_seconds)) +today_seconds = versiondata.getint("DEFAULT", "timestamp") +today = time.strftime("%B %d, %Y", time.localtime(today_seconds)) year = today.split()[-1] # Else, today_fmt is used as the format for a strftime call. # today_fmt = '%B %d, %Y' # substitute YEAR in the copyright string -copyright = copyright.replace('%Y', year) +copyright = copyright.replace("%Y", year) # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. @@ -102,10 +103,10 @@ # show_authors = False # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = "sphinx" # A list of ignored prefixes for module index sorting. -modindex_common_prefix = ['diffpy.srreal'] +modindex_common_prefix = ["diffpy.srreal"] # Display all warnings for missing links. nitpicky = True @@ -114,14 +115,14 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'sphinx_py3doc_enhanced_theme' +html_theme = "sphinx_py3doc_enhanced_theme" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. html_theme_options = { - 'collapsiblesidebar' : 'true', - 'navigation_with_keys' : 'true', + "collapsiblesidebar": "true", + "navigation_with_keys": "true", } # Add any paths that contain custom themes here, relative to this directory. @@ -190,27 +191,24 @@ # html_file_suffix = None # Output file base name for HTML help builder. -htmlhelp_basename = 'srrealdoc' +htmlhelp_basename = "srrealdoc" # -- Options for LaTeX output -------------------------------------------------- latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -# 'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -# 'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -# 'preamble': '', + # The paper size ('letterpaper' or 'a4paper'). + # 'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + # 'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + # 'preamble': '', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('index', 'diffpy.srreal.tex', 'diffpy.srreal Documentation', - ab_authors, 'manual'), + ("index", "diffpy.srreal.tex", "diffpy.srreal Documentation", ab_authors, "manual"), ] # The name of an image file (relative to this directory) to place at the top of @@ -238,10 +236,7 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'diffpy.srreal', 'diffpy.srreal Documentation', - ab_authors, 1) -] +man_pages = [("index", "diffpy.srreal", "diffpy.srreal Documentation", ab_authors, 1)] # If true, show URL addresses after external links. # man_show_urls = False @@ -253,9 +248,15 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', 'diffpy.srreal', 'diffpy.srreal Documentation', - ab_authors, 'diffpy.srreal', 'One line description of project.', - 'Miscellaneous'), + ( + "index", + "diffpy.srreal", + "diffpy.srreal Documentation", + ab_authors, + "diffpy.srreal", + "One line description of project.", + "Miscellaneous", + ), ] # Documents to append as an appendix to all manuals. @@ -270,6 +271,6 @@ # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = { - 'numpy': ('https://docs.scipy.org/doc/numpy', None), - 'python' : ('https://docs.python.org/3.7', None), + "numpy": ("https://docs.scipy.org/doc/numpy", None), + "python": ("https://docs.python.org/3.7", None), } diff --git a/examples/compareC60PDFs.py b/examples/compareC60PDFs.py index 622c350c..03311ec1 100755 --- a/examples/compareC60PDFs.py +++ b/examples/compareC60PDFs.py @@ -11,13 +11,14 @@ from diffpy.srreal.pdfcalculator import PDFCalculator, DebyePDFCalculator mydir = os.path.dirname(os.path.abspath(sys.argv[0])) -buckyfile = os.path.join(mydir, 'datafiles', 'C60bucky.stru') +buckyfile = os.path.join(mydir, "datafiles", "C60bucky.stru") # load C60 molecule as a diffpy.structure object bucky = Structure(filename=buckyfile) -cfg = { 'qmax' : 25, - 'rmin' : 0, - 'rmax' : 10.001, +cfg = { + "qmax": 25, + "rmin": 0, + "rmax": 10.001, } # calculate PDF by real-space summation diff --git a/examples/compareC60PDFs_objcryst.py b/examples/compareC60PDFs_objcryst.py index 35f3a293..69c9143a 100755 --- a/examples/compareC60PDFs_objcryst.py +++ b/examples/compareC60PDFs_objcryst.py @@ -12,10 +12,10 @@ from diffpy.srreal.pdfcalculator import PDFCalculator, DebyePDFCalculator # load C60 molecule as a diffpy.structure object -bucky_diffpy = Structure(filename='datafiles/C60bucky.stru') +bucky_diffpy = Structure(filename="datafiles/C60bucky.stru") # convert to an ObjCryst molecule -c60 = Crystal(1, 1, 1, 'P1') +c60 = Crystal(1, 1, 1, "P1") mc60 = Molecule(c60, "C60") c60.AddScatterer(mc60) # Create the scattering power object for the carbon atoms @@ -26,10 +26,11 @@ mc60.AddAtom(a.xyz_cartn[0], a.xyz_cartn[1], a.xyz_cartn[2], sp, cname) # PDF configuration -cfg = { 'qmax' : 25, - 'rmin' : 0, - 'rmax' : 10.001, - 'rstep' : 0.05, +cfg = { + "qmax": 25, + "rmin": 0, + "rmax": 10.001, + "rstep": 0.05, } # calculate PDF by real-space summation diff --git a/examples/distanceprinter.py b/examples/distanceprinter.py index 45ae0e65..c28409b0 100755 --- a/examples/distanceprinter.py +++ b/examples/distanceprinter.py @@ -7,25 +7,25 @@ from diffpy.srreal.pairquantity import PairQuantity from diffpy.structure import Structure -class DistancePrinter(PairQuantity): - '''This PairQuantity class simply prints the visited pair distances +class DistancePrinter(PairQuantity): + """This PairQuantity class simply prints the visited pair distances and the indices of the contributing atoms. - ''' + """ def _resetValue(self): self.count = 0 def _addPairContribution(self, bnds, sumscale): self.count += bnds.multiplicity() * sumscale / 2.0 - print("%i %g %i %i" % ( - self.count, bnds.distance(), bnds.site0(), bnds.site1())) + print("%i %g %i %i" % (self.count, bnds.distance(), bnds.site0(), bnds.site1())) return + # class DistancePrinter # define nickel structure data -nickel_discus_data = ''' +nickel_discus_data = """ title Ni spcgr P1 cell 3.523870, 3.523870, 3.523870, 90.000000, 90.000000, 90.000000 @@ -35,47 +35,53 @@ def _addPairContribution(self, bnds, sumscale): NI 0.00000000 0.50000000 0.50000000 0.1000 NI 0.50000000 0.00000000 0.50000000 0.1000 NI 0.50000000 0.50000000 0.00000000 0.1000 -''' +""" nickel = Structure() -nickel.readStr(nickel_discus_data, format='discus') +nickel.readStr(nickel_discus_data, format="discus") -bucky = Structure(filename='datafiles/C60bucky.stru', format='discus') +bucky = Structure(filename="datafiles/C60bucky.stru", format="discus") distprint = DistancePrinter() -distprint._setDoubleAttr('rmax', 10) +distprint._setDoubleAttr("rmax", 10) + def get_pyobjcryst_sphalerite(): from pyobjcryst import loadCrystal - crst = loadCrystal('datafiles/sphalerite.cif') + + crst = loadCrystal("datafiles/sphalerite.cif") return crst + def main(): - s = input('Enter rmin: ') - if s.strip(): distprint.rmin = float(s) + s = input("Enter rmin: ") + if s.strip(): + distprint.rmin = float(s) print("rmin = %g" % distprint.rmin) - s = input('Enter rmax: ') - if s.strip(): distprint.rmax = float(s) + s = input("Enter rmax: ") + if s.strip(): + distprint.rmax = float(s) print("rmax = %g" % distprint.rmax) print() - linesep = 78 * '-' + linesep = 78 * "-" # C60bucky print(linesep) - input('Press enter for distances in C60 molecule.') + input("Press enter for distances in C60 molecule.") distprint.eval(bucky) # nickel print(linesep) - input('Press enter for distances in a nickel crystal.') + input("Press enter for distances in a nickel crystal.") distprint.eval(nickel) # objcryst sphalerite print(linesep) - input('Press enter for distances in objcryst loaded sphalerite.cif.') + input("Press enter for distances in objcryst loaded sphalerite.cif.") crst = get_pyobjcryst_sphalerite() distprint.eval(crst) print(linesep) - input('Press enter for distances in diffpy.structure sphalerite.cif.') - crst = Structure(filename='datafiles/sphalerite.cif') + input("Press enter for distances in diffpy.structure sphalerite.cif.") + crst = Structure(filename="datafiles/sphalerite.cif") distprint.eval(crst) return -if __name__ == '__main__': + +if __name__ == "__main__": main() diff --git a/examples/lennardjones/ljcalculator.py b/examples/lennardjones/ljcalculator.py index eebd7740..e4a43f29 100755 --- a/examples/lennardjones/ljcalculator.py +++ b/examples/lennardjones/ljcalculator.py @@ -10,6 +10,7 @@ from diffpy.srreal.pairquantity import PairQuantity from diffpy.structure import Structure + class LennardJonesCalculator(PairQuantity): # Initialization. The size of the result array is always 1. @@ -18,16 +19,13 @@ def __init__(self): self._resizeValue(1) return - def __call__(self, structure): - '''Return LJ potential for a specified structure - ''' + """Return LJ potential for a specified structure""" values = self.eval(structure) return values[0] - def _addPairContribution(self, bnds, sumscale): - '''Add Lennard-Jones contribution from a single pair of atoms. + """Add Lennard-Jones contribution from a single pair of atoms. bnds -- a BaseBondGenerator instance that contains information about the current pair of atom sites. @@ -35,12 +33,13 @@ def _addPairContribution(self, bnds, sumscale): be negative in case of fast value updates. No return value. Updates _value, the internal results array. - ''' + """ rij = bnds.distance() - ljij = 4 * (rij ** -12 - rij ** -6) + ljij = 4 * (rij**-12 - rij**-6) self._value[0] += sumscale * ljij / 2.0 return + # class LennardJonesCalculator @@ -55,5 +54,5 @@ def main(): print("LJ potential of %s is %g" % (filename, ljcalc(stru))) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/examples/parallelPDF.py b/examples/parallelPDF.py index 9040b28d..89a62f37 100755 --- a/examples/parallelPDF.py +++ b/examples/parallelPDF.py @@ -16,14 +16,12 @@ from diffpy.srreal.parallel import createParallelCalculator mydir = os.path.dirname(os.path.abspath(__file__)) -mentholcif = os.path.join(mydir, 'datafiles', 'menthol.cif') +mentholcif = os.path.join(mydir, "datafiles", "menthol.cif") Uisodefault = 0.005 # configure options parsing -parser = optparse.OptionParser("%prog [options]\n" + - __doc__) -parser.add_option("--pyobjcryst", action="store_true", - help="Use pyobjcryst to load the CIF file.") +parser = optparse.OptionParser("%prog [options]\n" + __doc__) +parser.add_option("--pyobjcryst", action="store_true", help="Use pyobjcryst to load the CIF file.") parser.allow_interspersed_args = True opts, args = parser.parse_args(sys.argv[1:]) @@ -32,6 +30,7 @@ # use pyobjcryst if requested by the user from pyobjcryst import loadCrystal from numpy import pi + menthol = loadCrystal(mentholcif) for sc in menthol.GetScatteringComponentList(): sp = sc.mpScattPow @@ -43,9 +42,10 @@ a.Uisoequiv = a.Uisoequiv or Uisodefault # configuration of a PDF calculator -cfg = { 'qmax' : 25, - 'rmin' : 0, - 'rmax' : 30, +cfg = { + "qmax": 25, + "rmin": 0, + "rmax": 30, } # number of CPUs for parallel calculation @@ -72,6 +72,7 @@ # plot both results and the difference curve from matplotlib.pyplot import plot, show, clf + clf() gd = g0 - g1 plot(r0, g0, r1, g1, r0, gd - 3) diff --git a/setup.py b/setup.py index 6bb68e4e..5611ed7f 100644 --- a/setup.py +++ b/setup.py @@ -26,27 +26,25 @@ def get_boost_libraries(): ext_kws = { - 'libraries' : ["diffpy"] + get_boost_libraries(), - 'extra_compile_args' : ["-std=c++11"], - 'extra_link_args' : [], - 'include_dirs' : [numpy.get_include()], + "libraries": ["diffpy"] + get_boost_libraries(), + "extra_compile_args": ["-std=c++11"], + "extra_link_args": [], + "include_dirs": [numpy.get_include()], } def create_extensions(): "Initialize Extension objects for the setup function." - ext = Extension('diffpy.srreal.srreal_ext', - glob.glob('src/extensions/*.cpp'), - **ext_kws) + ext = Extension("diffpy.srreal.srreal_ext", glob.glob("src/extensions/*.cpp"), **ext_kws) return [ext] # Extensions not included in pyproject.toml setup_args = dict( - ext_modules = [], + ext_modules=[], ) -if __name__ == '__main__': - setup_args['ext_modules'] = create_extensions() +if __name__ == "__main__": + setup_args["ext_modules"] = create_extensions() setup(**setup_args) diff --git a/src/diffpy/__init__.py b/src/diffpy/__init__.py index 93b57f65..bb399140 100644 --- a/src/diffpy/__init__.py +++ b/src/diffpy/__init__.py @@ -20,6 +20,7 @@ from pkgutil import extend_path + __path__ = extend_path(__path__, __name__) diff --git a/src/diffpy/srreal/_cleanup.py b/src/diffpy/srreal/_cleanup.py index dbb41b13..1e7cc517 100644 --- a/src/diffpy/srreal/_cleanup.py +++ b/src/diffpy/srreal/_cleanup.py @@ -33,6 +33,7 @@ class prototypes is implemented in libdiffpy. Any Python-extended classes # Routine to be used from srreal_ext module ---------------------------------- + def registerForCleanUp(obj): """Remember to clean up the specified prototype at Python exit. @@ -48,21 +49,21 @@ def registerForCleanUp(obj): _cleanup_handler.add(obj) return + # ---------------------------------------------------------------------------- + class _DerivedClassesCleanUpHandler(object): def __init__(self): self._references = set() return - def add(self, obj): wr = weakref.ref(obj) self._references.add(wr) return - def clean(self): while self._references: wr = self._references.pop() @@ -71,6 +72,7 @@ def clean(self): obj._deregisterType(obj.type()) return + # end of class _DerivedClassesCleanUpHandler diff --git a/src/diffpy/srreal/_docstrings.py b/src/diffpy/srreal/_docstrings.py index cbb1a6d6..fee8ab07 100644 --- a/src/diffpy/srreal/_docstrings.py +++ b/src/diffpy/srreal/_docstrings.py @@ -19,6 +19,7 @@ # Shared docstrings for classes derived from HasClassRegistry ---------------- + def get_registry_docstrings(cls): """Build a dictionary of docstrings per each HasClassRegistry method. @@ -31,18 +32,21 @@ def get_registry_docstrings(cls): Returns a dictionary mapping Python method names to their docstrins. """ n = cls.__name__ - rv = {k : v.replace('@NAME@', n) for k, v in ( - ("create", doc_HasClassRegistry_create), - ("clone", doc_HasClassRegistry_clone), - ("type", doc_HasClassRegistry_type), - ("_registerThisType", doc_HasClassRegistry__registerThisType), - ("_aliasType", doc_HasClassRegistry__aliasType), - ("_deregisterType", doc_HasClassRegistry__deregisterType), - ("createByType", doc_HasClassRegistry_createByType), - ("isRegisteredType", doc_HasClassRegistry_isRegisteredType), - ("getAliasedTypes", doc_HasClassRegistry_getAliasedTypes), - ("getRegisteredTypes", doc_HasClassRegistry_getRegisteredTypes), - )} + rv = { + k: v.replace("@NAME@", n) + for k, v in ( + ("create", doc_HasClassRegistry_create), + ("clone", doc_HasClassRegistry_clone), + ("type", doc_HasClassRegistry_type), + ("_registerThisType", doc_HasClassRegistry__registerThisType), + ("_aliasType", doc_HasClassRegistry__aliasType), + ("_deregisterType", doc_HasClassRegistry__deregisterType), + ("createByType", doc_HasClassRegistry_createByType), + ("isRegisteredType", doc_HasClassRegistry_isRegisteredType), + ("getAliasedTypes", doc_HasClassRegistry_getAliasedTypes), + ("getRegisteredTypes", doc_HasClassRegistry_getRegisteredTypes), + ) + } return rv diff --git a/src/diffpy/srreal/_final_imports.py b/src/diffpy/srreal/_final_imports.py index 9e75dfae..236eaf57 100644 --- a/src/diffpy/srreal/_final_imports.py +++ b/src/diffpy/srreal/_final_imports.py @@ -27,26 +27,28 @@ def import_now(): - ''' + """ Import all Python modules that tweak extension-defined classes. - ''' + """ global _import_now_called if _import_now_called: return _import_now_called = True from importlib import import_module - import_module('diffpy.srreal.attributes') - import_module('diffpy.srreal.atomradiitable') - import_module('diffpy.srreal.bondcalculator') - import_module('diffpy.srreal.bvscalculator') - import_module('diffpy.srreal.overlapcalculator') - import_module('diffpy.srreal.pdfbaseline') - import_module('diffpy.srreal.pdfenvelope') - import_module('diffpy.srreal.peakprofile') - import_module('diffpy.srreal.peakwidthmodel') - import_module('diffpy.srreal.scatteringfactortable') - import_module('diffpy.srreal.pdfcalculator') - import_module('diffpy.srreal.structureconverters') + + import_module("diffpy.srreal.attributes") + import_module("diffpy.srreal.atomradiitable") + import_module("diffpy.srreal.bondcalculator") + import_module("diffpy.srreal.bvscalculator") + import_module("diffpy.srreal.overlapcalculator") + import_module("diffpy.srreal.pdfbaseline") + import_module("diffpy.srreal.pdfenvelope") + import_module("diffpy.srreal.peakprofile") + import_module("diffpy.srreal.peakwidthmodel") + import_module("diffpy.srreal.scatteringfactortable") + import_module("diffpy.srreal.pdfcalculator") + import_module("diffpy.srreal.structureconverters") return + _import_now_called = False diff --git a/src/diffpy/srreal/_version_data.py b/src/diffpy/srreal/_version_data.py index a0e532b6..8c1a4f46 100644 --- a/src/diffpy/srreal/_version_data.py +++ b/src/diffpy/srreal/_version_data.py @@ -19,7 +19,7 @@ Does not import any extension module unlike the `version` module. """ -__all__ = ['__date__', '__git_commit__', '__timestamp__', '__version__'] +__all__ = ["__date__", "__git_commit__", "__timestamp__", "__version__"] import os.path @@ -27,22 +27,22 @@ # obtain version information from the version.cfg file -cp = dict(version='', date='', commit='', timestamp='0') -fcfg = resource_filename(__name__, 'version.cfg') -if not os.path.isfile(fcfg): # pragma: no cover +cp = dict(version="", date="", commit="", timestamp="0") +fcfg = resource_filename(__name__, "version.cfg") +if not os.path.isfile(fcfg): # pragma: no cover from warnings import warn + warn('Package metadata not found, execute "./setup.py egg_info".') fcfg = os.devnull with open(fcfg) as fp: - kwords = [[w.strip() for w in line.split(' = ', 1)] - for line in fp if line[:1].isalpha() and ' = ' in line] + kwords = [[w.strip() for w in line.split(" = ", 1)] for line in fp if line[:1].isalpha() and " = " in line] assert all(w[0] in cp for w in kwords), "received unrecognized keyword" cp.update(kwords) -__version__ = cp['version'] -__date__ = cp['date'] -__git_commit__ = cp['commit'] -__timestamp__ = int(cp['timestamp']) +__version__ = cp["version"] +__date__ = cp["date"] +__git_commit__ = cp["commit"] +__timestamp__ = int(cp["timestamp"]) # TODO remove deprecated __gitsha__ in version 1.4. __gitsha__ = __git_commit__ diff --git a/src/diffpy/srreal/atomradiitable.py b/src/diffpy/srreal/atomradiitable.py index 4a141961..fe5016aa 100644 --- a/src/diffpy/srreal/atomradiitable.py +++ b/src/diffpy/srreal/atomradiitable.py @@ -18,29 +18,31 @@ # exported items, these also makes them show in pydoc. -__all__ = ['AtomRadiiTable', 'ConstantRadiiTable', 'CovalentRadiiTable'] +__all__ = ["AtomRadiiTable", "ConstantRadiiTable", "CovalentRadiiTable"] from diffpy.srreal.srreal_ext import AtomRadiiTable, ConstantRadiiTable # class CovalentRadiiTable --------------------------------------------------- + class CovalentRadiiTable(AtomRadiiTable): - '''Covalent radii from Cordero et al., 2008, doi:10.1039/b801115j. + """Covalent radii from Cordero et al., 2008, doi:10.1039/b801115j. Instantiation of this class requires the periodictable module. - ''' + """ # class variable that holds the periodictable.elements object _elements = None def _standardLookup(self, smbl): - '''Return covalent atom radius in Angstroms. + """Return covalent atom radius in Angstroms. smbl -- string symbol of an element Return float. Raise ValueError for unknown element symbol. - ''' + """ if CovalentRadiiTable._elements is None: from periodictable import elements + CovalentRadiiTable._elements = elements e = self._elements.isotope(smbl) rv = e.covalent_radius @@ -52,27 +54,25 @@ def _standardLookup(self, smbl): # HasClassRegistry overloads: def create(self): - '''Create new instance of the CovalentRadiiTable. - ''' + """Create new instance of the CovalentRadiiTable.""" return CovalentRadiiTable() - def clone(self): - '''Return a new duplicate instance of self. - ''' + """Return a new duplicate instance of self.""" import copy - return copy.copy(self) + return copy.copy(self) def type(self): - '''Unique string identifier of the CovalentRadiiTable type. + """Unique string identifier of the CovalentRadiiTable type. This is used for class registration and as an argument for the createByType function. Return string. - ''' + """ return "covalent" + # End of class CovalentRadiiTable CovalentRadiiTable()._registerThisType() diff --git a/src/diffpy/srreal/attributes.py b/src/diffpy/srreal/attributes.py index cb843738..ad0452d6 100644 --- a/src/diffpy/srreal/attributes.py +++ b/src/diffpy/srreal/attributes.py @@ -17,26 +17,27 @@ A base to PairQuantity and quite a few other classes. """ -__all__ = ['Attributes'] +__all__ = ["Attributes"] from diffpy.srreal.srreal_ext import Attributes # Inject the __getattr__ and __setattr__ methods to the Attributes class + def _getattr(self, name): - '''Lookup a C++ double attribute if standard Python lookup fails. + """Lookup a C++ double attribute if standard Python lookup fails. Raise AttributeError if C++ double attribute does not exist. - ''' + """ rv = self._getDoubleAttr(name) return rv + Attributes.__getattr__ = _getattr def _setattr(self, name, value): - '''Assign to C++ double attribute if Python attribute does not exist. - ''' + """Assign to C++ double attribute if Python attribute does not exist.""" try: object.__getattribute__(self, name) except AttributeError: @@ -46,16 +47,20 @@ def _setattr(self, name, value): object.__setattr__(self, name, value) return + Attributes.__setattr__ = _setattr # Helper accessor functions used by the _registerDoubleAttribute method + def _pyattrgetter(name): f = lambda obj: object.__getattribute__(obj, name) return f + def _pyattrsetter(name): f = lambda obj, value: object.__setattr__(obj, name, value) return f + # End of file diff --git a/src/diffpy/srreal/bondcalculator.py b/src/diffpy/srreal/bondcalculator.py index ac89ebee..d7f410cd 100644 --- a/src/diffpy/srreal/bondcalculator.py +++ b/src/diffpy/srreal/bondcalculator.py @@ -18,7 +18,7 @@ # exported items, these also makes them show in pydoc. -__all__ = ['BondCalculator'] +__all__ = ["BondCalculator"] from diffpy.srreal.wraputils import propertyFromExtDoubleAttr from diffpy.srreal.wraputils import setattrFromKeywordArguments @@ -26,40 +26,45 @@ # property wrappers to C++ double attributes -BondCalculator.rmin = propertyFromExtDoubleAttr('rmin', - '''Lower bound for the bond distances. - [0 A]''') +BondCalculator.rmin = propertyFromExtDoubleAttr( + "rmin", + """Lower bound for the bond distances. + [0 A]""", +) -BondCalculator.rmax = propertyFromExtDoubleAttr('rmax', - '''Upper bound for the bond distances. - [5 A]''') +BondCalculator.rmax = propertyFromExtDoubleAttr( + "rmax", + """Upper bound for the bond distances. + [5 A]""", +) # method overrides that support keyword arguments + def _init_kwargs(self, **kwargs): - '''Create a new instance of BondCalculator. + """Create a new instance of BondCalculator. Keyword arguments can be used to configure calculator properties, for example: bdc = BondCalculator(rmin=1.5, rmax=2.5) Raise ValueError for invalid keyword argument. - ''' + """ BondCalculator.__boostpython__init(self) setattrFromKeywordArguments(self, **kwargs) return def _call_kwargs(self, structure=None, **kwargs): - '''Return sorted bond distances in the specified structure. + """Return sorted bond distances in the specified structure. structure -- structure to be evaluated, an instance of diffpy Structure or pyobjcryst Crystal. Reuse the last structure when None. kwargs -- optional parameter settings for this calculator Return a sorted numpy array. - ''' + """ setattrFromKeywordArguments(self, **kwargs) self.eval(structure) return self.distances diff --git a/src/diffpy/srreal/bvparameterstable.py b/src/diffpy/srreal/bvparameterstable.py index 1363226e..9d963fca 100644 --- a/src/diffpy/srreal/bvparameterstable.py +++ b/src/diffpy/srreal/bvparameterstable.py @@ -19,7 +19,7 @@ class BVParam -- bond valence data associated with specific cation-anion pair # exported items, these also makes them show in pydoc. -__all__ = ['BVParam', 'BVParametersTable'] +__all__ = ["BVParam", "BVParametersTable"] from diffpy.srreal.srreal_ext import BVParam, BVParametersTable diff --git a/src/diffpy/srreal/bvscalculator.py b/src/diffpy/srreal/bvscalculator.py index 47cb2cef..2e1cb1c1 100644 --- a/src/diffpy/srreal/bvscalculator.py +++ b/src/diffpy/srreal/bvscalculator.py @@ -18,7 +18,7 @@ # exported items -__all__ = ['BVSCalculator'] +__all__ = ["BVSCalculator"] from diffpy.srreal.srreal_ext import BVSCalculator from diffpy.srreal.wraputils import propertyFromExtDoubleAttr @@ -26,45 +26,54 @@ # Property wrappers to C++ double attributes -BVSCalculator.valenceprecision = propertyFromExtDoubleAttr('valenceprecision', - '''Cutoff value for valence contributions at long distances. - [1e-5]''') +BVSCalculator.valenceprecision = propertyFromExtDoubleAttr( + "valenceprecision", + """Cutoff value for valence contributions at long distances. + [1e-5]""", +) -BVSCalculator.rmaxused = propertyFromExtDoubleAttr('rmaxused', - '''Effective bound for bond lengths, where valence contributions +BVSCalculator.rmaxused = propertyFromExtDoubleAttr( + "rmaxused", + """Effective bound for bond lengths, where valence contributions become smaller than valenceprecission, read-only. Always smaller or equal to rmax. The value depends on ions present in the structure. - ''') - -BVSCalculator.rmin = propertyFromExtDoubleAttr('rmin', - '''Lower bound for the summed bond lengths. - [0 A]''') - -BVSCalculator.rmax = propertyFromExtDoubleAttr('rmax', - '''Upper bound for the summed bond lengths. The calculation is + """, +) + +BVSCalculator.rmin = propertyFromExtDoubleAttr( + "rmin", + """Lower bound for the summed bond lengths. + [0 A]""", +) + +BVSCalculator.rmax = propertyFromExtDoubleAttr( + "rmax", + """Upper bound for the summed bond lengths. The calculation is actually cut off much earlier when valence contributions get below valenceprecission. See also rmaxused and valenceprecission. - [1e6 A]''') + [1e6 A]""", +) # method overrides that support keyword arguments + def _init_kwargs(self, **kwargs): - '''Create a new instance of BVSCalculator. + """Create a new instance of BVSCalculator. Keyword arguments can be used to configure the calculator properties, for example: bvscalc = BVSCalculator(valenceprecision=0.001) Raise ValueError for invalid keyword argument. - ''' + """ BVSCalculator.__boostpython__init(self) setattrFromKeywordArguments(self, **kwargs) return def _call_kwargs(self, structure=None, **kwargs): - '''Return bond valence sums at each atom site in the structure. + """Return bond valence sums at each atom site in the structure. structure -- structure to be evaluated, an instance of diffpy Structure or pyobjcryst Crystal. Reuse the last structure when None. @@ -72,7 +81,7 @@ def _call_kwargs(self, structure=None, **kwargs): Return an array of calculated valence sums. See valences for the expected values. - ''' + """ setattrFromKeywordArguments(self, **kwargs) rv = self.eval(structure) return rv diff --git a/src/diffpy/srreal/eventticker.py b/src/diffpy/srreal/eventticker.py index 3a3d5795..ecec69ac 100644 --- a/src/diffpy/srreal/eventticker.py +++ b/src/diffpy/srreal/eventticker.py @@ -19,7 +19,7 @@ class EventTicker -- storage of modification times of dependent objects # exported items -__all__ = ['EventTicker'] +__all__ = ["EventTicker"] from diffpy.srreal.srreal_ext import EventTicker diff --git a/src/diffpy/srreal/overlapcalculator.py b/src/diffpy/srreal/overlapcalculator.py index e0813597..c99aed61 100644 --- a/src/diffpy/srreal/overlapcalculator.py +++ b/src/diffpy/srreal/overlapcalculator.py @@ -18,7 +18,7 @@ # exported items, these also makes them show in pydoc. -__all__ = ['OverlapCalculator'] +__all__ = ["OverlapCalculator"] from diffpy.srreal.wraputils import propertyFromExtDoubleAttr from diffpy.srreal.wraputils import setattrFromKeywordArguments @@ -26,45 +26,52 @@ # property wrappers to C++ double attributes -OverlapCalculator.rmin = propertyFromExtDoubleAttr('rmin', - '''Lower bound for the bond distances. - [0 A]''') - -OverlapCalculator.rmax = propertyFromExtDoubleAttr('rmax', - '''Upper bound for the bond distances. - [5 A]''') - -OverlapCalculator.rmaxused = propertyFromExtDoubleAttr('rmaxused', - '''Effective upper bound for the bond distances. +OverlapCalculator.rmin = propertyFromExtDoubleAttr( + "rmin", + """Lower bound for the bond distances. + [0 A]""", +) + +OverlapCalculator.rmax = propertyFromExtDoubleAttr( + "rmax", + """Upper bound for the bond distances. + [5 A]""", +) + +OverlapCalculator.rmaxused = propertyFromExtDoubleAttr( + "rmaxused", + """Effective upper bound for the bond distances. rmaxused equals either a double of the maximum atom radius in the structure or rmax. - ''') + """, +) # method overrides that support keyword arguments + def _init_kwargs(self, **kwargs): - '''Create a new instance of OverlapCalculator. + """Create a new instance of OverlapCalculator. Keyword arguments can be used to configure calculator properties, for example: olc = OverlapCalculator(rmax=2.5) Raise ValueError for invalid keyword argument. - ''' + """ OverlapCalculator.__boostpython__init(self) setattrFromKeywordArguments(self, **kwargs) return def _call_kwargs(self, structure=None, **kwargs): - '''Return siteSquareOverlaps per each site of the structure. + """Return siteSquareOverlaps per each site of the structure. structure -- structure to be evaluated, an instance of diffpy Structure or pyobjcryst Crystal. Reuse the last structure when None. kwargs -- optional parameter settings for this calculator Return a numpy array. - ''' + """ setattrFromKeywordArguments(self, **kwargs) self.eval(structure) return self.sitesquareoverlaps diff --git a/src/diffpy/srreal/pairquantity.py b/src/diffpy/srreal/pairquantity.py index f6a537b9..bba56c6b 100644 --- a/src/diffpy/srreal/pairquantity.py +++ b/src/diffpy/srreal/pairquantity.py @@ -19,7 +19,7 @@ class PairQuantity -- base class for Python defined calculators. # exported items -__all__ = ['PairQuantity'] +__all__ = ["PairQuantity"] from diffpy.srreal.srreal_ext import PairQuantity diff --git a/src/diffpy/srreal/parallel.py b/src/diffpy/srreal/parallel.py index c5a3d75b..413836a0 100644 --- a/src/diffpy/srreal/parallel.py +++ b/src/diffpy/srreal/parallel.py @@ -19,7 +19,7 @@ # exported items -__all__ = ['createParallelCalculator'] +__all__ = ["createParallelCalculator"] import copy import inspect @@ -27,8 +27,9 @@ # ---------------------------------------------------------------------------- + def createParallelCalculator(pqobj, ncpu, pmap): - '''Create a proxy parallel calculator to a PairQuantity instance. + """Create a proxy parallel calculator to a PairQuantity instance. pqobj -- instance of PairQuantity calculator to be run in parallel ncpu -- number of parallel jobs @@ -39,11 +40,10 @@ def createParallelCalculator(pqobj, ncpu, pmap): Return a proxy calculator instance that has the same interface, but executes the calculation in parallel split among ncpu jobs. - ''' + """ class ParallelPairQuantity(Attributes): - - '''Class for running parallel calculations. This is a proxy class + """Class for running parallel calculations. This is a proxy class to the wrapper PairQuantity type with the same interface. Instance data: @@ -51,68 +51,71 @@ class ParallelPairQuantity(Attributes): pqobj -- the master PairQuantity object to be evaluated in parallel ncpu -- number of parallel jobs pmap -- a parallel map function used to submit job to workers - ''' + """ def __init__(self, pqobj, ncpu, pmap): - '''Initialize a parallel proxy to the PairQuantity instance. + """Initialize a parallel proxy to the PairQuantity instance. pqobj -- instance of PairQuantity calculator to be run in parallel ncpu -- number of parallel jobs pmap -- a parallel map function used to submit job to workers - ''' + """ # use explicit assignment to avoid setattr forwarding to the pqobj - object.__setattr__(self, 'pqobj', pqobj) - object.__setattr__(self, 'ncpu', ncpu) - object.__setattr__(self, 'pmap', pmap) + object.__setattr__(self, "pqobj", pqobj) + object.__setattr__(self, "ncpu", ncpu) + object.__setattr__(self, "pmap", pmap) # parallel calculations support only the BASIC evaluation - self.pqobj.evaluatortype = 'BASIC' + self.pqobj.evaluatortype = "BASIC" return - def eval(self, stru=None): - '''Perform parallel calculation and return internal value array. + """Perform parallel calculation and return internal value array. stru -- object that can be converted to StructureAdapter, e.g., example diffpy Structure or pyobjcryst Crystal. Use the last structure when None. Return numpy array. - ''' + """ # use StructureAdapter for faster pickles from diffpy.srreal.structureadapter import createStructureAdapter + if stru is None: struadpt = self.pqobj.getStructure() else: struadpt = createStructureAdapter(stru) self.pqobj.setStructure(struadpt) - kwd = { 'cpuindex' : None, - 'ncpu' : self.ncpu, - 'pqobj' : copy.copy(self.pqobj), - } + kwd = { + "cpuindex": None, + "ncpu": self.ncpu, + "pqobj": copy.copy(self.pqobj), + } # shallow copies of kwd dictionary each with a unique cpuindex - arglist = [kwd.copy() for kwd['cpuindex'] in range(self.ncpu)] + arglist = [kwd.copy() for kwd["cpuindex"] in range(self.ncpu)] for pdata in self.pmap(_parallelData, arglist): self.pqobj._mergeParallelData(pdata, self.ncpu) return self.pqobj.value - def __call__(self, *args, **kwargs): - '''Call the wrapped calculator using parallel evaluation. + """Call the wrapped calculator using parallel evaluation. The arguments and return value are the same as for the wrapped PairQuantity calculator. - ''' - savedeval = self.pqobj.__dict__.get('eval') + """ + savedeval = self.pqobj.__dict__.get("eval") + def restore_eval(): if savedeval: self.pqobj.eval = savedeval else: - self.pqobj.__dict__.pop('eval', None) + self.pqobj.__dict__.pop("eval", None) + def parallel_eval(stru): assert self.pqobj.eval is parallel_eval restore_eval() return self.eval(stru) + self.pqobj.eval = parallel_eval try: rv = self.pqobj(*args, **kwargs) @@ -120,7 +123,6 @@ def parallel_eval(stru): restore_eval() return rv - @property def evaluatortype(self): """str : Type of evaluation procedure. @@ -145,22 +147,25 @@ def evaluatortype(self, value): # create proxy methods to all public methods and some protected methods - proxy_forced = set('''_getDoubleAttr _setDoubleAttr _hasDoubleAttr + proxy_forced = set( + """_getDoubleAttr _setDoubleAttr _hasDoubleAttr _namesOfDoubleAttributes _namesOfWritableDoubleAttributes - '''.split()) + """.split() + ) def _make_proxymethod(name, f): def proxymethod(self, *args, **kwargs): - pqobj = object.__getattribute__(self, 'pqobj') + pqobj = object.__getattribute__(self, "pqobj") return f(pqobj, *args, **kwargs) + proxymethod.__name__ = name proxymethod.__doc__ = f.__doc__ return proxymethod for n, f in inspect.getmembers(pqtype, inspect.isroutine): - ignore = n not in proxy_forced and (n.startswith('_') or - hasattr(ParallelPairQuantity, n)) - if ignore: continue + ignore = n not in proxy_forced and (n.startswith("_") or hasattr(ParallelPairQuantity, n)) + if ignore: + continue setattr(ParallelPairQuantity, n, _make_proxymethod(n, f)) # create proxy properties to all properties that do not conflict with @@ -169,15 +174,25 @@ def proxymethod(self, *args, **kwargs): def _make_proxyproperty(prop): fget = fset = fdel = None if prop.fget: - def fget(self): return prop.fget(self.pqobj) + + def fget(self): + return prop.fget(self.pqobj) + if prop.fset: - def fset(self, value): return prop.fset(self.pqobj, value) + + def fset(self, value): + return prop.fset(self.pqobj, value) + if prop.fdel: - def fdel(self): return prop.fdel(self.pqobj) + + def fdel(self): + return prop.fdel(self.pqobj) + return property(fget, fset, fdel, prop.__doc__) for n, p in inspect.getmembers(pqtype, lambda x: type(x) is property): - if hasattr(ParallelPairQuantity, n): continue + if hasattr(ParallelPairQuantity, n): + continue setattr(ParallelPairQuantity, n, _make_proxyproperty(p)) # finally create an instance of this very custom class @@ -185,11 +200,11 @@ def fdel(self): return prop.fdel(self.pqobj) def _parallelData(kwd): - '''Helper for calculating and fetching raw results from a worker node. - ''' - pqobj = kwd['pqobj'] - pqobj._setupParallelRun(kwd['cpuindex'], kwd['ncpu']) + """Helper for calculating and fetching raw results from a worker node.""" + pqobj = kwd["pqobj"] + pqobj._setupParallelRun(kwd["cpuindex"], kwd["ncpu"]) pqobj.eval() return pqobj._getParallelData() + # End of file diff --git a/src/diffpy/srreal/pdfbaseline.py b/src/diffpy/srreal/pdfbaseline.py index 5f5af2ba..dc8581cc 100644 --- a/src/diffpy/srreal/pdfbaseline.py +++ b/src/diffpy/srreal/pdfbaseline.py @@ -20,11 +20,11 @@ # exported items -__all__ = ''' +__all__ = """ PDFBaseline makePDFBaseline ZeroBaseline LinearBaseline - '''.split() + """.split() from diffpy.srreal import _final_imports from diffpy.srreal.srreal_ext import PDFBaseline @@ -40,14 +40,17 @@ # attribute wrapper -LinearBaseline.slope = propertyFromExtDoubleAttr('slope', - '''Slope of an unscaled linear baseline. For crystal structures it - is preset to (-4 * pi * rho0).''') +LinearBaseline.slope = propertyFromExtDoubleAttr( + "slope", + """Slope of an unscaled linear baseline. For crystal structures it + is preset to (-4 * pi * rho0).""", +) # Python functions wrapper + def makePDFBaseline(name, fnc, replace=False, **dbattrs): - '''Helper function for registering Python function as a PDFBaseline. + """Helper function for registering Python function as a PDFBaseline. This is required for using Python function as PDFCalculator.baseline. name -- unique string name for registering Python function in the @@ -81,12 +84,13 @@ def fshiftedline(x, aline, bline): pdfc = PDFCalculator() pdfc.baseline = baseline # or pdfc.baseline = "shiftedline" - ''' + """ from diffpy.srreal.wraputils import _wrapAsRegisteredUnaryFunction - rv = _wrapAsRegisteredUnaryFunction(PDFBaseline, name, fnc, - replace=replace, **dbattrs) + + rv = _wrapAsRegisteredUnaryFunction(PDFBaseline, name, fnc, replace=replace, **dbattrs) return rv + # Import delayed tweaks of the extension classes. _final_imports.import_now() diff --git a/src/diffpy/srreal/pdfcalculator.py b/src/diffpy/srreal/pdfcalculator.py index f34b25d7..5c30cf16 100644 --- a/src/diffpy/srreal/pdfcalculator.py +++ b/src/diffpy/srreal/pdfcalculator.py @@ -21,10 +21,10 @@ # exported items -__all__ = ''' +__all__ = """ DebyePDFCalculator PDFCalculator fftftog fftgtof - '''.split() + """.split() from diffpy.srreal.srreal_ext import DebyePDFCalculator from diffpy.srreal.srreal_ext import PDFCalculator @@ -36,81 +36,119 @@ assert all((fftftog, fftgtof)) # imports for backward compatibility -from diffpy.srreal.pdfbaseline import (PDFBaseline, makePDFBaseline, - ZeroBaseline, LinearBaseline) -from diffpy.srreal.pdfenvelope import (PDFEnvelope, makePDFEnvelope, - QResolutionEnvelope, ScaleEnvelope, - SphericalShapeEnvelope, StepCutEnvelope) +from diffpy.srreal.pdfbaseline import PDFBaseline, makePDFBaseline, ZeroBaseline, LinearBaseline +from diffpy.srreal.pdfenvelope import ( + PDFEnvelope, + makePDFEnvelope, + QResolutionEnvelope, + ScaleEnvelope, + SphericalShapeEnvelope, + StepCutEnvelope, +) from diffpy.srreal.peakprofile import PeakProfile -from diffpy.srreal.peakwidthmodel import (PeakWidthModel, - ConstantPeakWidth, DebyeWallerPeakWidth, JeongPeakWidth) +from diffpy.srreal.peakwidthmodel import PeakWidthModel, ConstantPeakWidth, DebyeWallerPeakWidth, JeongPeakWidth # silence the pyflakes syntax checker -assert all((PDFBaseline, makePDFBaseline, ZeroBaseline, LinearBaseline, - PDFEnvelope, makePDFEnvelope, QResolutionEnvelope, ScaleEnvelope, - SphericalShapeEnvelope, StepCutEnvelope, PeakProfile, - PeakWidthModel, ConstantPeakWidth, DebyeWallerPeakWidth, - JeongPeakWidth)) +assert all( + ( + PDFBaseline, + makePDFBaseline, + ZeroBaseline, + LinearBaseline, + PDFEnvelope, + makePDFEnvelope, + QResolutionEnvelope, + ScaleEnvelope, + SphericalShapeEnvelope, + StepCutEnvelope, + PeakProfile, + PeakWidthModel, + ConstantPeakWidth, + DebyeWallerPeakWidth, + JeongPeakWidth, + ) +) # ---------------------------------------------------------------------------- -def _defineCommonInterface(cls): - '''This function defines shared properties of PDF calculator classes. - ''' +def _defineCommonInterface(cls): + """This function defines shared properties of PDF calculator classes.""" - cls.scale = propertyFromExtDoubleAttr('scale', - '''Scale factor of the calculated PDF. Active for ScaleEnvelope. - [1.0 unitless]''') + cls.scale = propertyFromExtDoubleAttr( + "scale", + """Scale factor of the calculated PDF. Active for ScaleEnvelope. + [1.0 unitless]""", + ) - cls.delta1 = propertyFromExtDoubleAttr('delta1', - '''Coefficient for (1/r) contribution to the peak sharpening. + cls.delta1 = propertyFromExtDoubleAttr( + "delta1", + """Coefficient for (1/r) contribution to the peak sharpening. Active for JeongPeakWidth model. - [0 A]''') + [0 A]""", + ) - cls.delta2 = propertyFromExtDoubleAttr('delta2', - '''Coefficient for (1/r**2) contribution to the peak sharpening. + cls.delta2 = propertyFromExtDoubleAttr( + "delta2", + """Coefficient for (1/r**2) contribution to the peak sharpening. Active for JeongPeakWidth model. - [0 A**2]''') + [0 A**2]""", + ) - cls.qdamp = propertyFromExtDoubleAttr('qdamp', - '''PDF Gaussian dampening factor due to limited Q-resolution. + cls.qdamp = propertyFromExtDoubleAttr( + "qdamp", + """PDF Gaussian dampening factor due to limited Q-resolution. Not applied when equal to zero. Active for QResolutionEnvelope. - [0 1/A]''') + [0 1/A]""", + ) - cls.qbroad = propertyFromExtDoubleAttr('qbroad', - '''PDF peak broadening from increased intensity noise at high Q. + cls.qbroad = propertyFromExtDoubleAttr( + "qbroad", + """PDF peak broadening from increased intensity noise at high Q. Not applied when equal zero. Active for JeongPeakWidth model. - [0 1/A]''') - - cls.extendedrmin = propertyFromExtDoubleAttr('extendedrmin', - '''Low boundary of the extended r-range, read-only. - [A]''') - - cls.extendedrmax = propertyFromExtDoubleAttr('extendedrmax', - '''Upper boundary of the extended r-range, read-only. - [A]''') - - cls.maxextension = propertyFromExtDoubleAttr('maxextension', - '''Maximum extension of the r-range that accounts for contributions + [0 1/A]""", + ) + + cls.extendedrmin = propertyFromExtDoubleAttr( + "extendedrmin", + """Low boundary of the extended r-range, read-only. + [A]""", + ) + + cls.extendedrmax = propertyFromExtDoubleAttr( + "extendedrmax", + """Upper boundary of the extended r-range, read-only. + [A]""", + ) + + cls.maxextension = propertyFromExtDoubleAttr( + "maxextension", + """Maximum extension of the r-range that accounts for contributions from the out of range peaks. - [10 A]''') - - cls.rmin = propertyFromExtDoubleAttr('rmin', - '''Lower bound of the r-grid for PDF calculation. - [0 A]''') - - cls.rmax = propertyFromExtDoubleAttr('rmax', - '''Upper bound of the r-grid for PDF calculation. - [10 A]''') - - cls.rstep = propertyFromExtDoubleAttr('rstep', - '''Spacing in the calculated r-grid. r-values are at the + [10 A]""", + ) + + cls.rmin = propertyFromExtDoubleAttr( + "rmin", + """Lower bound of the r-grid for PDF calculation. + [0 A]""", + ) + + cls.rmax = propertyFromExtDoubleAttr( + "rmax", + """Upper bound of the r-grid for PDF calculation. + [10 A]""", + ) + + cls.rstep = propertyFromExtDoubleAttr( + "rstep", + """Spacing in the calculated r-grid. r-values are at the multiples of rstep. - [0.01 A]''') + [0.01 A]""", + ) def _call_kwargs(self, structure=None, **kwargs): - '''Calculate PDF for the given structure as an (r, G) tuple. + """Calculate PDF for the given structure as an (r, G) tuple. Keyword arguments can be used to configure calculator attributes, these override any properties that may be passed from the structure, such as spdiameter. @@ -122,7 +160,7 @@ def _call_kwargs(self, structure=None, **kwargs): Example: pdfcalc(structure, qmax=20, spdiameter=15) Return a tuple of (r, G) numpy arrays. - ''' + """ setattrFromKeywordArguments(self, **kwargs) self.eval(structure) # apply kwargs again if structure contained any attribute @@ -130,8 +168,10 @@ def _call_kwargs(self, structure=None, **kwargs): setattrFromKeywordArguments(self, **kwargs) rv = (self.rgrid, self.pdf) return rv + cls.__call__ = _call_kwargs + # _defineCommonInterface # class DebyePDFCalculator --------------------------------------------------- @@ -142,42 +182,52 @@ def _call_kwargs(self, structure=None, **kwargs): # Property wrappers to double attributes of the C++ DebyePDFCalculator -DebyePDFCalculator.debyeprecision = propertyFromExtDoubleAttr('debyeprecision', - '''Cutoff amplitude for the sine contributions to the F(Q). - [1e-6 unitless]''') +DebyePDFCalculator.debyeprecision = propertyFromExtDoubleAttr( + "debyeprecision", + """Cutoff amplitude for the sine contributions to the F(Q). + [1e-6 unitless]""", +) -DebyePDFCalculator.qmin = propertyFromExtDoubleAttr('qmin', - '''Lower bound of the Q-grid for the calculated F(Q). +DebyePDFCalculator.qmin = propertyFromExtDoubleAttr( + "qmin", + """Lower bound of the Q-grid for the calculated F(Q). Affects the shape envelope. [0 1/A] - ''') + """, +) -DebyePDFCalculator.qmax = propertyFromExtDoubleAttr('qmax', - '''Upper bound of the Q-grid for the calculated F(Q). +DebyePDFCalculator.qmax = propertyFromExtDoubleAttr( + "qmax", + """Upper bound of the Q-grid for the calculated F(Q). Affects the termination ripples. [25 1/A] - ''') + """, +) -DebyePDFCalculator.qstep = propertyFromExtDoubleAttr('qstep', - '''Spacing in the Q-grid. Q-values are at the multiples of qstep. +DebyePDFCalculator.qstep = propertyFromExtDoubleAttr( + "qstep", + """Spacing in the Q-grid. Q-values are at the multiples of qstep. [PI/extendedrmax A] unless user overridden. - See also setOptimumQstep, isOptimumQstep.''') + See also setOptimumQstep, isOptimumQstep.""", +) # method overrides to support optional keyword arguments + def _init_kwargs0(self, **kwargs): - '''Create a new instance of the DebyePDFCalculator. + """Create a new instance of the DebyePDFCalculator. Keyword arguments can be used to configure the calculator properties, for example: dpc = DebyePDFCalculator(qmax=20, rmin=7, rmax=15) Raise ValueError for invalid keyword argument. - ''' + """ DebyePDFCalculator.__boostpython__init(self) setattrFromKeywordArguments(self, **kwargs) return + DebyePDFCalculator.__boostpython__init = DebyePDFCalculator.__init__ DebyePDFCalculator.__init__ = _init_kwargs0 @@ -191,58 +241,74 @@ def _init_kwargs0(self, **kwargs): # Property wrappers to double attributes of the C++ PDFCalculator -PDFCalculator.peakprecision = propertyFromExtDoubleAttr('peakprecision', - '''Cutoff amplitude of the peak tail relative to the peak maximum. - [3.33e-6 unitless]''') +PDFCalculator.peakprecision = propertyFromExtDoubleAttr( + "peakprecision", + """Cutoff amplitude of the peak tail relative to the peak maximum. + [3.33e-6 unitless]""", +) -PDFCalculator.qmin = propertyFromExtDoubleAttr('qmin', - '''Lower bound of the experimental Q-range used. +PDFCalculator.qmin = propertyFromExtDoubleAttr( + "qmin", + """Lower bound of the experimental Q-range used. Affects the shape envelope. - [0 1/A]''') + [0 1/A]""", +) -PDFCalculator.qmax = propertyFromExtDoubleAttr('qmax', - '''Upper bound of the experimental Q-range used. +PDFCalculator.qmax = propertyFromExtDoubleAttr( + "qmax", + """Upper bound of the experimental Q-range used. Affects the termination ripples. Not used when zero. - [0 1/A]''') + [0 1/A]""", +) -PDFCalculator.qstep = propertyFromExtDoubleAttr('qstep', - '''Spacing in the Q-grid. Q-values are at the multiples of qstep. +PDFCalculator.qstep = propertyFromExtDoubleAttr( + "qstep", + """Spacing in the Q-grid. Q-values are at the multiples of qstep. The value is padded by rsteps so that PI/qstep > extendedrmax and PI/(qstep * rstep) is a power of 2. Read-only. - [PI/(padded extendedrmax) A]''') + [PI/(padded extendedrmax) A]""", +) -PDFCalculator.slope = propertyFromExtDoubleAttr('slope', - '''Slope of the linear PDF background. Assigned according to +PDFCalculator.slope = propertyFromExtDoubleAttr( + "slope", + """Slope of the linear PDF background. Assigned according to number density of the evaluated structure at each PDF calculation. Active for LinearBaseline. - [-4*pi*numdensity unitless]''') + [-4*pi*numdensity unitless]""", +) -PDFCalculator.spdiameter = propertyFromExtDoubleAttr('spdiameter', - '''Spherical particle diameter for PDF shape damping correction. +PDFCalculator.spdiameter = propertyFromExtDoubleAttr( + "spdiameter", + """Spherical particle diameter for PDF shape damping correction. Not used when zero. Active for SphericalShapeEnvelope. - [0 A]''') + [0 A]""", +) -PDFCalculator.stepcut = propertyFromExtDoubleAttr('stepcut', - '''r-boundary for a step cutoff of the calculated PDF. +PDFCalculator.stepcut = propertyFromExtDoubleAttr( + "stepcut", + """r-boundary for a step cutoff of the calculated PDF. Not used when negative or zero. Active for StepCutEnvelope. Not used when zero. Active for StepCutEnvelope. - [0 A]''') + [0 A]""", +) # method overrides to support optional keyword arguments + def _init_kwargs1(self, **kwargs): - '''Create a new instance of PDFCalculator. + """Create a new instance of PDFCalculator. Keyword arguments can be used to configure the calculator properties, for example: pc = PDFCalculator(qmax=20, rmin=7, rmax=15) Raise ValueError for invalid keyword argument. - ''' + """ PDFCalculator.__boostpython__init(self) setattrFromKeywordArguments(self, **kwargs) return + PDFCalculator.__boostpython__init = PDFCalculator.__init__ PDFCalculator.__init__ = _init_kwargs1 diff --git a/src/diffpy/srreal/pdfenvelope.py b/src/diffpy/srreal/pdfenvelope.py index d4cb93d3..e43a345a 100644 --- a/src/diffpy/srreal/pdfenvelope.py +++ b/src/diffpy/srreal/pdfenvelope.py @@ -21,13 +21,13 @@ # exported items -__all__ = ''' +__all__ = """ PDFEnvelope makePDFEnvelope QResolutionEnvelope ScaleEnvelope SphericalShapeEnvelope StepCutEnvelope - '''.split() + """.split() from diffpy.srreal import _final_imports from diffpy.srreal.srreal_ext import PDFEnvelope @@ -46,26 +46,35 @@ # attribute wrappers -QResolutionEnvelope.qdamp = propertyFromExtDoubleAttr('qdamp', - '''Dampening parameter in the Gaussian envelope function. - ''') - -ScaleEnvelope.scale = propertyFromExtDoubleAttr('scale', - '''Overall scale for a uniform scaling envelope. - ''') - -SphericalShapeEnvelope.spdiameter = propertyFromExtDoubleAttr('spdiameter', - '''Particle diameter in Angstroms for a spherical shape damping. - ''') - -StepCutEnvelope.stepcut = propertyFromExtDoubleAttr('stepcut', - '''Cutoff for a step-function envelope. - ''') +QResolutionEnvelope.qdamp = propertyFromExtDoubleAttr( + "qdamp", + """Dampening parameter in the Gaussian envelope function. + """, +) + +ScaleEnvelope.scale = propertyFromExtDoubleAttr( + "scale", + """Overall scale for a uniform scaling envelope. + """, +) + +SphericalShapeEnvelope.spdiameter = propertyFromExtDoubleAttr( + "spdiameter", + """Particle diameter in Angstroms for a spherical shape damping. + """, +) + +StepCutEnvelope.stepcut = propertyFromExtDoubleAttr( + "stepcut", + """Cutoff for a step-function envelope. + """, +) # Python functions wrapper + def makePDFEnvelope(name, fnc, replace=False, **dbattrs): - '''Helper function for registering Python function as a PDFEnvelope. + """Helper function for registering Python function as a PDFEnvelope. This is required for using Python function as PDFCalculator envelope. name -- unique string name for registering Python function in the @@ -100,12 +109,13 @@ def fexpdecay(x, expscale, exptail): pdfc = PDFCalculator() pdfc.addEnvelope(envelope) # or pdfc.addEnvelope("expdecay") - ''' + """ from diffpy.srreal.wraputils import _wrapAsRegisteredUnaryFunction - rv = _wrapAsRegisteredUnaryFunction(PDFEnvelope, name, fnc, - replace=replace, **dbattrs) + + rv = _wrapAsRegisteredUnaryFunction(PDFEnvelope, name, fnc, replace=replace, **dbattrs) return rv + # Import delayed tweaks of the extension classes. _final_imports.import_now() diff --git a/src/diffpy/srreal/peakprofile.py b/src/diffpy/srreal/peakprofile.py index e3745fa7..d082ac89 100644 --- a/src/diffpy/srreal/peakprofile.py +++ b/src/diffpy/srreal/peakprofile.py @@ -21,11 +21,7 @@ # exported items -__all__ = [ - 'PeakProfile', - 'GaussianProfile', - 'CroppedGaussianProfile' -] +__all__ = ["PeakProfile", "GaussianProfile", "CroppedGaussianProfile"] from diffpy.srreal import _final_imports from diffpy.srreal.srreal_ext import PeakProfile @@ -41,10 +37,12 @@ # add attribute wrappers for PeakProfile and derived classes -PeakProfile.peakprecision = propertyFromExtDoubleAttr('peakprecision', - '''Profile amplitude relative to the peak maximum for evaluating peak +PeakProfile.peakprecision = propertyFromExtDoubleAttr( + "peakprecision", + """Profile amplitude relative to the peak maximum for evaluating peak bounds xboundlo and xboundhi. [3.33e-6 unitless] - ''') + """, +) # Import delayed tweaks of the extension classes. diff --git a/src/diffpy/srreal/peakwidthmodel.py b/src/diffpy/srreal/peakwidthmodel.py index 59274712..75610987 100644 --- a/src/diffpy/srreal/peakwidthmodel.py +++ b/src/diffpy/srreal/peakwidthmodel.py @@ -21,12 +21,7 @@ # exported items -__all__ = [ - 'PeakWidthModel', - 'ConstantPeakWidth', - 'DebyeWallerPeakWidth', - 'JeongPeakWidth' -] +__all__ = ["PeakWidthModel", "ConstantPeakWidth", "DebyeWallerPeakWidth", "JeongPeakWidth"] from diffpy.srreal import _final_imports from diffpy.srreal.srreal_ext import PeakWidthModel, ConstantPeakWidth @@ -37,26 +32,35 @@ # add attribute wrappers for the derived classes -ConstantPeakWidth.width = propertyFromExtDoubleAttr('width', - '''Constant FWHM value returned by this model. - ''') +ConstantPeakWidth.width = propertyFromExtDoubleAttr( + "width", + """Constant FWHM value returned by this model. + """, +) -ConstantPeakWidth.bisowidth = propertyFromExtDoubleAttr('bisowidth', - '''Equivalent uniform Biso for this constant `width`. - ''') +ConstantPeakWidth.bisowidth = propertyFromExtDoubleAttr( + "bisowidth", + """Equivalent uniform Biso for this constant `width`. + """, +) -ConstantPeakWidth.uisowidth = propertyFromExtDoubleAttr('uisowidth', - '''Equivalent uniform Uiso for this constant `width`. - ''') +ConstantPeakWidth.uisowidth = propertyFromExtDoubleAttr( + "uisowidth", + """Equivalent uniform Uiso for this constant `width`. + """, +) -JeongPeakWidth.delta1 = propertyFromExtDoubleAttr('delta1', - 'Coefficient for (1/r) contribution to the peak sharpening.') +JeongPeakWidth.delta1 = propertyFromExtDoubleAttr( + "delta1", "Coefficient for (1/r) contribution to the peak sharpening." +) -JeongPeakWidth.delta2 = propertyFromExtDoubleAttr('delta2', - 'Coefficient for (1/r**2) contribution to the peak sharpening.') +JeongPeakWidth.delta2 = propertyFromExtDoubleAttr( + "delta2", "Coefficient for (1/r**2) contribution to the peak sharpening." +) -JeongPeakWidth.qbroad = propertyFromExtDoubleAttr('qbroad', - 'PDF peak broadening from increased intensity noise at high Q.') +JeongPeakWidth.qbroad = propertyFromExtDoubleAttr( + "qbroad", "PDF peak broadening from increased intensity noise at high Q." +) # Import delayed tweaks of the extension classes. diff --git a/src/diffpy/srreal/scatteringfactortable.py b/src/diffpy/srreal/scatteringfactortable.py index 5e4e1d6f..26f2ed3e 100644 --- a/src/diffpy/srreal/scatteringfactortable.py +++ b/src/diffpy/srreal/scatteringfactortable.py @@ -19,9 +19,7 @@ class ScatteringFactorTable -- scattering factors for atoms, ions and isotopes. # exported items, these also makes them show in pydoc. -__all__ = ['ScatteringFactorTable', - 'SFTXray', 'SFTElectron', 'SFTNeutron', 'SFTElectronNumber', - 'SFAverage'] +__all__ = ["ScatteringFactorTable", "SFTXray", "SFTElectron", "SFTNeutron", "SFTElectronNumber", "SFAverage"] from diffpy.srreal.srreal_ext import ScatteringFactorTable from diffpy.srreal.srreal_ext import SFTXray diff --git a/src/diffpy/srreal/sfaverage.py b/src/diffpy/srreal/sfaverage.py index fd1795f3..46c61b12 100644 --- a/src/diffpy/srreal/sfaverage.py +++ b/src/diffpy/srreal/sfaverage.py @@ -39,6 +39,7 @@ # class SFAverage ------------------------------------------------------------ + class SFAverage(object): """\ Calculate compositional statistics of atom scattering factors. @@ -103,12 +104,13 @@ def fromStructure(cls, stru, sftb, q=0): The calculated scattering factor averages. """ # a bit of duck-typing for faster handling of diffpy.structure - if hasattr(type(stru), 'composition'): + if hasattr(type(stru), "composition"): composition = stru.composition if isinstance(composition, dict): return cls.fromComposition(composition, sftb, q) # otherwise let's convert to a known structure type from diffpy.srreal.structureadapter import createStructureAdapter + adpt = createStructureAdapter(stru) composition = {} for i in range(adpt.countSites()): @@ -117,7 +119,6 @@ def fromStructure(cls, stru, sftb, q=0): composition[smbl] = composition.get(smbl, 0) + cnt return cls.fromComposition(composition, sftb, q) - @classmethod def fromComposition(cls, composition, sftb, q=0): """\ @@ -142,6 +143,7 @@ def fromComposition(cls, composition, sftb, q=0): The calculated scattering factor averages. """ from diffpy.srreal.scatteringfactortable import ScatteringFactorTable + sfa = cls() sfa.composition = {} if isinstance(composition, dict): @@ -154,8 +156,7 @@ def fromComposition(cls, composition, sftb, q=0): sfa.f1sum = 0.0 * q sfa.f2sum = 0.0 * q # resolve the lookup table object `tb` - tb = (sftb if not isinstance(sftb, str) - else ScatteringFactorTable.createByType(sftb)) + tb = sftb if not isinstance(sftb, str) else ScatteringFactorTable.createByType(sftb) for smbl, cnt in sfa.composition.items(): sfq = tb.lookup(smbl, q) sfa.f1sum += cnt * sfq @@ -166,4 +167,5 @@ def fromComposition(cls, composition, sftb, q=0): sfa.f2avg = sfa.f2sum / denom return sfa + # End of class SFAverage diff --git a/src/diffpy/srreal/structureadapter.py b/src/diffpy/srreal/structureadapter.py index 4740977b..dc9fdc30 100644 --- a/src/diffpy/srreal/structureadapter.py +++ b/src/diffpy/srreal/structureadapter.py @@ -29,8 +29,9 @@ EMPTY -- singleton instance of an empty structure. """ + def createStructureAdapter(stru): - ''' + """ Create StructureAdapter from a Python object. stru -- an object that is convertible to StructureAdapter, i.e., it has @@ -39,14 +40,17 @@ def createStructureAdapter(stru): Return a StructureAdapter instance. Raise TypeError if stru cannot be converted to StructureAdapter. - ''' - if isinstance(stru, StructureAdapter): return stru + """ + if isinstance(stru, StructureAdapter): + return stru import inspect + # build fully-qualified names of Python types in method resolution order cls = type(stru) fqnames = [str(tp).split("'")[1] for tp in inspect.getmro(cls)] for fqn in fqnames: - if not fqn in _adapter_converters_registry: continue + if not fqn in _adapter_converters_registry: + continue factory = _adapter_converters_registry[fqn] return factory(stru) # none of the registered factories could convert the stru object @@ -55,7 +59,7 @@ def createStructureAdapter(stru): def RegisterStructureAdapter(fqname, fnc=None): - '''Function decorator that marks it as a converter of specified + """Function decorator that marks it as a converter of specified object type to StructureAdapter class in diffpy.srreal. The registered structure object types can be afterwards directly used with calculators in diffpy.srreal as they would be implicitly converted to the internal @@ -75,14 +79,17 @@ def convertMyStructure(stru): ... See diffpy.srreal.structureconverters module for usage example. - ''' + """ + def __wrapper(fnc): _adapter_converters_registry[fqname] = fnc return fnc + if fnc is None: return __wrapper return __wrapper(fnc) + _adapter_converters_registry = {} # import of srreal_ext calls RegisterStructureAdapter, therefore it has @@ -101,8 +108,17 @@ def __wrapper(fnc): del _emptyStructureAdapter # silence the pyflakes syntax checker -assert all((Atom, AtomicStructureAdapter, PeriodicStructureAdapter, - CrystalStructureAdapter, StructureDifference, - nometa, nosymmetry, BaseBondGenerator)) +assert all( + ( + Atom, + AtomicStructureAdapter, + PeriodicStructureAdapter, + CrystalStructureAdapter, + StructureDifference, + nometa, + nosymmetry, + BaseBondGenerator, + ) +) # End of file diff --git a/src/diffpy/srreal/structureconverters.py b/src/diffpy/srreal/structureconverters.py index e504587d..210a2bbb 100644 --- a/src/diffpy/srreal/structureconverters.py +++ b/src/diffpy/srreal/structureconverters.py @@ -24,12 +24,13 @@ # Converter for Structure class from diffpy.structure ------------------------ + # TODO prune in version 1.4. -@RegisterStructureAdapter('diffpy.Structure.structure.Structure') -@RegisterStructureAdapter('diffpy.structure.structure.Structure') +@RegisterStructureAdapter("diffpy.Structure.structure.Structure") +@RegisterStructureAdapter("diffpy.structure.structure.Structure") def convertDiffPyStructure(stru): - 'Adapt Structure class from diffpy.structure package.' - haslattice = ((1, 1, 1, 90, 90, 90) != stru.lattice.abcABG()) + "Adapt Structure class from diffpy.structure package." + haslattice = (1, 1, 1, 90, 90, 90) != stru.lattice.abcABG() isperiodic = haslattice hasmeta = _DiffPyStructureMetadata.hasMetadata(stru) if hasmeta: @@ -46,18 +47,20 @@ def convertDiffPyStructure(stru): _fetchDiffPyStructureData(adpt, stru) return adpt + # Converters for Molecule and Crystal from pyobjcryst ------------------------ from diffpy.srreal.srreal_ext import convertObjCrystMolecule -RegisterStructureAdapter( - 'pyobjcryst._pyobjcryst.Molecule', convertObjCrystMolecule) + +RegisterStructureAdapter("pyobjcryst._pyobjcryst.Molecule", convertObjCrystMolecule) from diffpy.srreal.srreal_ext import convertObjCrystCrystal -RegisterStructureAdapter( - 'pyobjcryst._pyobjcryst.Crystal', convertObjCrystCrystal) + +RegisterStructureAdapter("pyobjcryst._pyobjcryst.Crystal", convertObjCrystCrystal) # Adapter classes and helpers for diffpy.structure class --------------------- + class _DiffPyStructureMetadata(object): "Base class for handling metadata information in the pdffit attribute." @@ -66,40 +69,38 @@ class _DiffPyStructureMetadata(object): @staticmethod def hasMetadata(stru): - """True if Structure object carries data in its pdffit attribute. - """ - rv = hasattr(stru, 'pdffit') and bool(stru.pdffit) + """True if Structure object carries data in its pdffit attribute.""" + rv = hasattr(stru, "pdffit") and bool(stru.pdffit) return rv - def _customPQConfig(self, pqobj): - """Apply PDF-related metadata if defined in PDFFit structure format. - """ + """Apply PDF-related metadata if defined in PDFFit structure format.""" pqname = type(pqobj).__name__ - if not pqname in ('PDFCalculator', 'DebyePDFCalculator'): return - if not self.pdffit: return + if not pqname in ("PDFCalculator", "DebyePDFCalculator"): + return + if not self.pdffit: + return # scale envtps = pqobj.usedenvelopetypes - if 'scale' not in envtps: - pqobj.addEnvelope('scale') - pqobj.scale = self.pdffit['scale'] + if "scale" not in envtps: + pqobj.addEnvelope("scale") + pqobj.scale = self.pdffit["scale"] # spdiameter if "spdiameter" in self.pdffit: - if not 'sphericalshape' in envtps: - pqobj.addEnvelope('sphericalshape') - pqobj.spdiameter = self.pdffit['spdiameter'] + if not "sphericalshape" in envtps: + pqobj.addEnvelope("sphericalshape") + pqobj.spdiameter = self.pdffit["spdiameter"] # stepcut if "stepcut" in self.pdffit: - if not 'stepcut' in envtps: - pqobj.addEnvelope('stepcut') - pqobj.stepcut = self.pdffit['stepcut'] + if not "stepcut" in envtps: + pqobj.addEnvelope("stepcut") + pqobj.stepcut = self.pdffit["stepcut"] # delta1, delta2 - set these only when using JeongPeakWidth model if pqobj.peakwidthmodel.type() == "jeong": - pqobj.delta1 = self.pdffit['delta1'] - pqobj.delta2 = self.pdffit['delta2'] + pqobj.delta1 = self.pdffit["delta1"] + pqobj.delta2 = self.pdffit["delta2"] return - def _fetchMetadata(self, stru): """Copy data from the pdffit attribute of diffpy Structure object @@ -114,16 +115,15 @@ def _fetchMetadata(self, stru): self.pdffit.update(stru.pdffit) return + # end of class _DiffPyStructureMetadata -class DiffPyStructureAtomicAdapter( - _DiffPyStructureMetadata, AtomicStructureAdapter): +class DiffPyStructureAtomicAdapter(_DiffPyStructureMetadata, AtomicStructureAdapter): pass -class DiffPyStructurePeriodicAdapter( - _DiffPyStructureMetadata, PeriodicStructureAdapter): +class DiffPyStructurePeriodicAdapter(_DiffPyStructureMetadata, PeriodicStructureAdapter): pass @@ -136,6 +136,7 @@ def _fetchDiffPyStructureData(adpt, stru): No return value. """ from diffpy.srreal.srreal_ext import Atom as AdapterAtom + # copy atoms del adpt[:] adpt.reserve(len(stru)) @@ -148,10 +149,11 @@ def _fetchDiffPyStructureData(adpt, stru): aa.xyz_cartn = a0.xyz aa.uij_cartn = a0.U adpt.append(aa) - if hasattr(adpt, 'setLatPar'): + if hasattr(adpt, "setLatPar"): adpt.setLatPar(*stru.lattice.abcABG()) for aa in adpt: adpt.toCartesian(aa) return + # End of file diff --git a/src/diffpy/srreal/tests/__init__.py b/src/diffpy/srreal/tests/__init__.py index f1b64d71..8f9447cf 100644 --- a/src/diffpy/srreal/tests/__init__.py +++ b/src/diffpy/srreal/tests/__init__.py @@ -25,8 +25,8 @@ del logging -def testsuite(pattern=''): - '''Create a unit tests suite for diffpy.srreal package. +def testsuite(pattern=""): + """Create a unit tests suite for diffpy.srreal package. Parameters ---------- @@ -39,14 +39,15 @@ def testsuite(pattern=''): ------- suite : `unittest.TestSuite` The TestSuite object containing the matching tests. - ''' + """ import re from os.path import dirname from itertools import chain from pkg_resources import resource_filename + loader = unittest.defaultTestLoader - thisdir = resource_filename(__name__, '') - depth = __name__.count('.') + 1 + thisdir = resource_filename(__name__, "") + depth = __name__.count(".") + 1 topdir = thisdir for i in range(depth): topdir = dirname(topdir) @@ -56,12 +57,12 @@ def testsuite(pattern=''): rx = re.compile(pattern) tsuites = list(chain.from_iterable(suite_all)) tsok = all(isinstance(ts, unittest.TestSuite) for ts in tsuites) - if not tsok: # pragma: no cover + if not tsok: # pragma: no cover return suite_all tcases = chain.from_iterable(tsuites) for tc in tcases: - tcwords = tc.id().split('.') - shortname = '.'.join(tcwords[-3:]) + tcwords = tc.id().split(".") + shortname = ".".join(tcwords[-3:]) if rx.search(shortname): suite.addTest(tc) # verify all tests are found for an empty pattern. @@ -70,12 +71,12 @@ def testsuite(pattern=''): def test(): - '''Execute all unit tests for the diffpy.srreal package. + """Execute all unit tests for the diffpy.srreal package. Returns ------- result : `unittest.TestResult` - ''' + """ suite = testsuite() runner = unittest.TextTestRunner() result = runner.run(suite) diff --git a/src/diffpy/srreal/tests/debug.py b/src/diffpy/srreal/tests/debug.py index be3127be..eb48ae31 100644 --- a/src/diffpy/srreal/tests/debug.py +++ b/src/diffpy/srreal/tests/debug.py @@ -22,10 +22,11 @@ """ -if __name__ == '__main__': +if __name__ == "__main__": import sys from diffpy.srreal.tests import testsuite - pattern = sys.argv[1] if len(sys.argv) > 1 else '' + + pattern = sys.argv[1] if len(sys.argv) > 1 else "" suite = testsuite(pattern) suite.debug() diff --git a/src/diffpy/srreal/tests/run.py b/src/diffpy/srreal/tests/run.py index 6f88d607..efbe2456 100644 --- a/src/diffpy/srreal/tests/run.py +++ b/src/diffpy/srreal/tests/run.py @@ -19,15 +19,18 @@ """ -if __name__ == '__main__': +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.srreal.tests import test + # produce zero exit code for a successful test sys.exit(not test().wasSuccessful()) diff --git a/src/diffpy/srreal/tests/testatomradiitable.py b/src/diffpy/srreal/tests/testatomradiitable.py index c96a6fb8..d9e7ee98 100644 --- a/src/diffpy/srreal/tests/testatomradiitable.py +++ b/src/diffpy/srreal/tests/testatomradiitable.py @@ -12,6 +12,7 @@ # ---------------------------------------------------------------------------- + class TestAtomRadiiTable(unittest.TestCase): def setUp(self): @@ -23,94 +24,86 @@ def tearDown(self): return def test_pickling(self): - '''check pickling and unpickling of AtomRadiiTable. - ''' + """check pickling and unpickling of AtomRadiiTable.""" ctb1 = pickle.loads(pickle.dumps(self.ctb)) self.assertTrue(type(ctb1) is ConstantRadiiTable) self.assertEqual({}, ctb1.getAllCustom()) - self.ctb.setCustom('Na', 1.3) - self.ctb.foobar = 'foo' + self.ctb.setCustom("Na", 1.3) + self.ctb.foobar = "foo" self.ctb.setDefault(3.7) ctb2 = pickle.loads(pickle.dumps(self.ctb)) - self.assertEqual({'Na' : 1.3}, ctb2.getAllCustom()) - self.assertFalse(hasattr(ctb2, 'foobar')) + self.assertEqual({"Na": 1.3}, ctb2.getAllCustom()) + self.assertFalse(hasattr(ctb2, "foobar")) self.assertEqual(3.7, ctb2.getDefault()) return def test__standardLookup(self): - """check AtomRadiiTable._standardLookup() - """ - self.assertRaises(RuntimeError, self.rtb._standardLookup, - 'anything') - self.assertEqual(0.0, self.ctb._standardLookup('anything')) + """check AtomRadiiTable._standardLookup()""" + self.assertRaises(RuntimeError, self.rtb._standardLookup, "anything") + self.assertEqual(0.0, self.ctb._standardLookup("anything")) self.ctb.setDefault(7.3) - self.assertEqual(7.3, self.ctb._standardLookup('anything')) + self.assertEqual(7.3, self.ctb._standardLookup("anything")) return def test_fromString(self): - """check AtomRadiiTable.fromString() - """ - self.rtb.fromString('H:0.33, B:0.42') - self.assertEqual({'H' : 0.33, 'B' : 0.42}, self.rtb.getAllCustom()) - self.assertRaises(ValueError, self.rtb.fromString, - 'C:2.3, U:asdf') - self.assertEqual({'H' : 0.33, 'B' : 0.42}, self.rtb.getAllCustom()) - self.rtb.fromString('C:2.3,,,') + """check AtomRadiiTable.fromString()""" + self.rtb.fromString("H:0.33, B:0.42") + self.assertEqual({"H": 0.33, "B": 0.42}, self.rtb.getAllCustom()) + self.assertRaises(ValueError, self.rtb.fromString, "C:2.3, U:asdf") + self.assertEqual({"H": 0.33, "B": 0.42}, self.rtb.getAllCustom()) + self.rtb.fromString("C:2.3,,,") self.assertEqual(3, len(self.rtb.getAllCustom())) - self.assertEqual(2.3, self.rtb.lookup('C')) - self.rtb.fromString('H:3.3') + self.assertEqual(2.3, self.rtb.lookup("C")) + self.rtb.fromString("H:3.3") self.assertEqual(3, len(self.rtb.getAllCustom())) - self.assertEqual(3.3, self.rtb.lookup('H')) + self.assertEqual(3.3, self.rtb.lookup("H")) return def test_getAllCustom(self): - """check AtomRadiiTable.getAllCustom() - """ + """check AtomRadiiTable.getAllCustom()""" self.assertEqual({}, self.rtb.getAllCustom()) return def test_lookup(self): - """check AtomRadiiTable.lookup() - """ - self.assertRaises(RuntimeError, self.rtb.lookup, 'C') - self.assertEqual(0.0, self.ctb.lookup('C')) - self.rtb.setCustom('C', 1.23) - self.assertEqual(1.23, self.rtb.lookup('C')) + """check AtomRadiiTable.lookup()""" + self.assertRaises(RuntimeError, self.rtb.lookup, "C") + self.assertEqual(0.0, self.ctb.lookup("C")) + self.rtb.setCustom("C", 1.23) + self.assertEqual(1.23, self.rtb.lookup("C")) return def test_resetCustom(self): - """check AtomRadiiTable.resetCustom() - """ - self.rtb.setCustom('C', 1.23) + """check AtomRadiiTable.resetCustom()""" + self.rtb.setCustom("C", 1.23) self.assertTrue(self.rtb.getAllCustom()) self.rtb.resetAll() self.assertFalse(self.rtb.getAllCustom()) return def test_setCustom(self): - """check AtomRadiiTable.setCustom() - """ - self.rtb.setCustom('C', 1.23) - self.assertEqual(1.23, self.rtb.lookup('C')) - self.rtb.setCustom('C', 3.3) - self.assertEqual(3.3, self.rtb.lookup('C')) + """check AtomRadiiTable.setCustom()""" + self.rtb.setCustom("C", 1.23) + self.assertEqual(1.23, self.rtb.lookup("C")) + self.rtb.setCustom("C", 3.3) + self.assertEqual(3.3, self.rtb.lookup("C")) return def test_toString(self): - """check AtomRadiiTable.toString() - """ + """check AtomRadiiTable.toString()""" rtb = self.rtb - self.assertEqual('', rtb.toString()) - self.assertEqual('', rtb.toString('; ')) - rtb.fromString('C : 1.5, B:2.0') - self.assertEqual('B:2,C:1.5', rtb.toString()) - self.assertEqual('B:2; C:1.5', rtb.toString('; ')) + self.assertEqual("", rtb.toString()) + self.assertEqual("", rtb.toString("; ")) + rtb.fromString("C : 1.5, B:2.0") + self.assertEqual("B:2,C:1.5", rtb.toString()) + self.assertEqual("B:2; C:1.5", rtb.toString("; ")) return + # End of class TestAtomRadiiTable # ---------------------------------------------------------------------------- + @unittest.skipUnless(has_periodictable, _msg_noperiodictable) class TestCovalentRadiiTable(unittest.TestCase): @@ -122,28 +115,25 @@ def tearDown(self): return def test_pickling(self): - '''check pickling and unpickling of CovalentRadiiTable. - ''' + """check pickling and unpickling of CovalentRadiiTable.""" rtb1 = pickle.loads(pickle.dumps(self.rtb)) self.assertTrue(type(rtb1) is CovalentRadiiTable) self.assertEqual({}, rtb1.getAllCustom()) - self.rtb.setCustom('Na', 1.3) - self.rtb.foobar = 'foo' + self.rtb.setCustom("Na", 1.3) + self.rtb.foobar = "foo" rtb2 = pickle.loads(pickle.dumps(self.rtb)) - self.assertEqual({'Na' : 1.3}, rtb2.getAllCustom()) - self.assertEqual('foo', rtb2.foobar) + self.assertEqual({"Na": 1.3}, rtb2.getAllCustom()) + self.assertEqual("foo", rtb2.foobar) return def test__standardLookup(self): - """check CovalentRadiiTable._standardLookup() - """ - self.assertEqual(1.22, self.rtb._standardLookup('Ga')) + """check CovalentRadiiTable._standardLookup()""" + self.assertEqual(1.22, self.rtb._standardLookup("Ga")) return def test_create(self): - """check CovalentRadiiTable.create() - """ - self.rtb.setCustom('Na', 1.3) + """check CovalentRadiiTable.create()""" + self.rtb.setCustom("Na", 1.3) rtb2 = self.rtb.create() self.assertTrue(isinstance(rtb2, CovalentRadiiTable)) self.assertEqual(1, len(self.rtb.getAllCustom())) @@ -151,66 +141,60 @@ def test_create(self): return def test_clone(self): - """check CovalentRadiiTable.clone() - """ - self.rtb.setCustom('Na', 1.3) + """check CovalentRadiiTable.clone()""" + self.rtb.setCustom("Na", 1.3) rtb2 = self.rtb.clone() self.assertTrue(isinstance(rtb2, CovalentRadiiTable)) self.assertEqual(1, len(rtb2.getAllCustom())) - self.assertEqual(1.3, rtb2.lookup('Na')) + self.assertEqual(1.3, rtb2.lookup("Na")) return def test_fromString(self): - """check CovalentRadiiTable.fromString() - """ - self.rtb.fromString('Ga:2.22') - self.assertEqual(2.22, self.rtb.lookup('Ga')) + """check CovalentRadiiTable.fromString()""" + self.rtb.fromString("Ga:2.22") + self.assertEqual(2.22, self.rtb.lookup("Ga")) return def test_getAllCustom(self): - """check CovalentRadiiTable.getAllCustom() - """ + """check CovalentRadiiTable.getAllCustom()""" self.assertEqual({}, self.rtb.getAllCustom()) return def test_lookup(self): - """check CovalentRadiiTable.lookup() - """ - self.assertEqual(1.22, self.rtb.lookup('Ga')) - self.rtb.fromString('Ga:2.22') - self.assertEqual(2.22, self.rtb.lookup('Ga')) + """check CovalentRadiiTable.lookup()""" + self.assertEqual(1.22, self.rtb.lookup("Ga")) + self.rtb.fromString("Ga:2.22") + self.assertEqual(2.22, self.rtb.lookup("Ga")) return def test_resetCustom(self): - """check CovalentRadiiTable.resetCustom() - """ - self.rtb.fromString('B:2.33, Ga:2.22') - self.rtb.resetCustom('B') - self.rtb.resetCustom('nada') + """check CovalentRadiiTable.resetCustom()""" + self.rtb.fromString("B:2.33, Ga:2.22") + self.rtb.resetCustom("B") + self.rtb.resetCustom("nada") self.assertEqual(1, len(self.rtb.getAllCustom())) - self.assertEqual(0.84, self.rtb.lookup('B')) - self.assertEqual(2.22, self.rtb.lookup('Ga')) + self.assertEqual(0.84, self.rtb.lookup("B")) + self.assertEqual(2.22, self.rtb.lookup("Ga")) return def test_setCustom(self): - """check CovalentRadiiTable.setCustom() - """ - self.assertEqual(0.84, self.rtb.lookup('B')) - self.rtb.setCustom('B', 0.9) - self.assertEqual(0.9, self.rtb.lookup('B')) + """check CovalentRadiiTable.setCustom()""" + self.assertEqual(0.84, self.rtb.lookup("B")) + self.rtb.setCustom("B", 0.9) + self.assertEqual(0.9, self.rtb.lookup("B")) return def test_toString(self): - """check CovalentRadiiTable.toString() - """ - self.assertEqual('', self.rtb.toString(';---')) + """check CovalentRadiiTable.toString()""" + self.assertEqual("", self.rtb.toString(";---")) return + # End of class TestCovalentRadiiTable # ---------------------------------------------------------------------------- -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() # End of file diff --git a/src/diffpy/srreal/tests/testattributes.py b/src/diffpy/srreal/tests/testattributes.py index 7c7e2f0d..cb4f2243 100644 --- a/src/diffpy/srreal/tests/testattributes.py +++ b/src/diffpy/srreal/tests/testattributes.py @@ -12,20 +12,18 @@ from diffpy.srreal.pairquantity import PairQuantity from diffpy.srreal.pdfcalculator import PDFCalculator + ############################################################################## class TestAttributes(unittest.TestCase): def setUp(self): return - def tearDown(self): return - def test___setattr__(self): - """check Attributes.__setattr__() - """ + """check Attributes.__setattr__()""" # normal attribute a = Attributes() a.x = 45 @@ -40,123 +38,112 @@ def test___setattr__(self): self.assertEqual(27, a._getDoubleAttr("x")) return - def test___getattr__(self): - """check Attributes.__getattr__() - """ + """check Attributes.__getattr__()""" a = Attributes() - self.assertRaises(AttributeError, getattr, a, 'invalid') + self.assertRaises(AttributeError, getattr, a, "invalid") a.x = 11 self.assertEqual(11, a.x) pdfc = PDFCalculator() - pdfc._setDoubleAttr('rmax', 12.34) + pdfc._setDoubleAttr("rmax", 12.34) self.assertEqual(12.34, pdfc.rmax) return - def test_garbage_collection(self): - """check garbage collection for Python defined Attributes - """ + """check garbage collection for Python defined Attributes""" # check if attributes are garbage collected pq = PairQuantity() wpq = weakref.ref(pq) self.assertFalse(wpq() is None) - pq._registerDoubleAttribute('foo') + pq._registerDoubleAttribute("foo") pq.foo = 45 - self.assertEqual(45, pq._getDoubleAttr('foo')) + self.assertEqual(45, pq._getDoubleAttr("foo")) del pq self.assertTrue(wpq() is None) return - def test__getDoubleAttr(self): - """check Attributes._getDoubleAttr() - """ + """check Attributes._getDoubleAttr()""" pdfc = PDFCalculator() pdfc.foo = 11 - self.assertRaises(AttributeError, pdfc._getDoubleAttr, 'foo') - pdfc._registerDoubleAttribute('foo') - self.assertEqual(11, pdfc._getDoubleAttr('foo')) + self.assertRaises(AttributeError, pdfc._getDoubleAttr, "foo") + pdfc._registerDoubleAttribute("foo") + self.assertEqual(11, pdfc._getDoubleAttr("foo")) pdfc.rmax = 22 - self.assertEqual(22, pdfc._getDoubleAttr('rmax')) - setattr(pdfc, 'rmax', 23) - self.assertEqual(23, pdfc._getDoubleAttr('rmax')) - self.assertRaises(Exception, setattr, pdfc, 'rmax', 'xxx') + self.assertEqual(22, pdfc._getDoubleAttr("rmax")) + setattr(pdfc, "rmax", 23) + self.assertEqual(23, pdfc._getDoubleAttr("rmax")) + self.assertRaises(Exception, setattr, pdfc, "rmax", "xxx") return - def test__hasDoubleAttr(self): - """check Attributes._hasDoubleAttr() - """ + """check Attributes._hasDoubleAttr()""" a = Attributes() a.foo = 45 - self.assertFalse(a._hasDoubleAttr('foo')) - a._registerDoubleAttribute('foo') - self.assertTrue(a._hasDoubleAttr('foo')) + self.assertFalse(a._hasDoubleAttr("foo")) + a._registerDoubleAttribute("foo") + self.assertTrue(a._hasDoubleAttr("foo")) return - def test__namesOfDoubleAttributes(self): - """check Attributes._namesOfDoubleAttributes() - """ + """check Attributes._namesOfDoubleAttributes()""" a = Attributes() self.assertEqual(0, len(a._namesOfDoubleAttributes())) pq = PairQuantity() self.assertNotEqual(0, len(pq._namesOfDoubleAttributes())) - self.assertFalse('bar' in pq._namesOfDoubleAttributes()) - pq._registerDoubleAttribute('bar') - self.assertTrue('bar' in pq._namesOfDoubleAttributes()) + self.assertFalse("bar" in pq._namesOfDoubleAttributes()) + pq._registerDoubleAttribute("bar") + self.assertTrue("bar" in pq._namesOfDoubleAttributes()) return - def test__namesOfWritableDoubleAttributes(self): - """check Attributes._namesOfDoubleAttributes() - """ + """check Attributes._namesOfDoubleAttributes()""" a = Attributes() self.assertEqual(0, len(a._namesOfDoubleAttributes())) - a._registerDoubleAttribute('bar', lambda obj: 13) - self.assertEqual(13, a._getDoubleAttr('bar')) + a._registerDoubleAttribute("bar", lambda obj: 13) + self.assertEqual(13, a._getDoubleAttr("bar")) self.assertEqual(13, a.bar) self.assertEqual(1, len(a._namesOfDoubleAttributes())) self.assertEqual(0, len(a._namesOfWritableDoubleAttributes())) pdfc = PDFCalculator() - self.assertTrue('extendedrmin' in pdfc._namesOfDoubleAttributes()) - self.assertTrue('extendedrmax' in pdfc._namesOfDoubleAttributes()) + self.assertTrue("extendedrmin" in pdfc._namesOfDoubleAttributes()) + self.assertTrue("extendedrmax" in pdfc._namesOfDoubleAttributes()) nwda = pdfc._namesOfWritableDoubleAttributes() - self.assertFalse('extendedrmin' in nwda) - self.assertFalse('extendedrmax' in nwda) + self.assertFalse("extendedrmin" in nwda) + self.assertFalse("extendedrmax" in nwda) return - def test__registerDoubleAttribute(self): - """check Attributes._registerDoubleAttribute() - """ - d = {'g_called' : False, 's_called' : False, 'value' : 0} + """check Attributes._registerDoubleAttribute()""" + d = {"g_called": False, "s_called": False, "value": 0} + def g(obj): - d['g_called'] = True - return d['value'] + d["g_called"] = True + return d["value"] + def s(obj, value): - d['s_called'] = True - d['value'] = value + d["s_called"] = True + d["value"] = value return + a = Attributes() wa = weakref.ref(a) - a._registerDoubleAttribute('a1', g, s) - self.assertFalse('a1' in a.__dict__) - self.assertFalse(d['g_called']) - self.assertFalse(d['s_called']) + a._registerDoubleAttribute("a1", g, s) + self.assertFalse("a1" in a.__dict__) + self.assertFalse(d["g_called"]) + self.assertFalse(d["s_called"]) self.assertEqual(0, a.a1) - self.assertTrue(d['g_called']) - self.assertFalse(d['s_called']) + self.assertTrue(d["g_called"]) + self.assertFalse(d["s_called"]) a.a1 = 47 - self.assertTrue(d['s_called']) - self.assertEqual(47, d['value']) - self.assertTrue(hasattr(a, 'a1')) - a._registerDoubleAttribute('a1readonly', g) + self.assertTrue(d["s_called"]) + self.assertEqual(47, d["value"]) + self.assertTrue(hasattr(a, "a1")) + a._registerDoubleAttribute("a1readonly", g) self.assertEqual(47, a.a1readonly) - self.assertTrue(hasattr(a, 'a1readonly')) - self.assertRaises(AttributeError, a._setDoubleAttr, 'a1readonly', 7) - self.assertRaises(AttributeError, setattr, a, 'a1readonly', 5) + self.assertTrue(hasattr(a, "a1readonly")) + self.assertRaises(AttributeError, a._setDoubleAttr, "a1readonly", 7) + self.assertRaises(AttributeError, setattr, a, "a1readonly", 5) self.assertEqual(47, a.a1readonly) a.a1 = 9 self.assertEqual(9, a.a1readonly) @@ -166,19 +153,18 @@ def s(obj, value): self.assertTrue(wa() is None) return - def test__setDoubleAttr(self): - """check Attributes._setDoubleAttr() - """ + """check Attributes._setDoubleAttr()""" pdfc = PDFCalculator() - pdfc._setDoubleAttr('scale', 1.23) - self.assertFalse('scale' in pdfc.__dict__) + pdfc._setDoubleAttr("scale", 1.23) + self.assertFalse("scale" in pdfc.__dict__) self.assertEqual(1.23, pdfc.scale) return + # End of class TestAttributes -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() # End of file diff --git a/src/diffpy/srreal/tests/testbondcalculator.py b/src/diffpy/srreal/tests/testbondcalculator.py index fba47a37..76164a2a 100644 --- a/src/diffpy/srreal/tests/testbondcalculator.py +++ b/src/diffpy/srreal/tests/testbondcalculator.py @@ -16,26 +16,24 @@ # ---------------------------------------------------------------------------- + class TestBondCalculator(unittest.TestCase): def setUp(self): self.bdc = BondCalculator() - if not hasattr(self, 'rutile'): - type(self).rutile = loadDiffPyStructure('rutile.cif') - if not hasattr(self, 'nickel'): - type(self).nickel = loadDiffPyStructure('Ni.stru') - if not hasattr(self, 'niprim'): - type(self).niprim = loadDiffPyStructure('Ni_primitive.stru') + if not hasattr(self, "rutile"): + type(self).rutile = loadDiffPyStructure("rutile.cif") + if not hasattr(self, "nickel"): + type(self).nickel = loadDiffPyStructure("Ni.stru") + if not hasattr(self, "niprim"): + type(self).niprim = loadDiffPyStructure("Ni_primitive.stru") return - def tearDown(self): return - def test___init__(self): - """check BondCalculator.__init__() - """ + """check BondCalculator.__init__()""" self.assertEqual(0, self.bdc.rmin) self.assertEqual(5, self.bdc.rmax) self.assertEqual(0, len(self.bdc.distances)) @@ -45,10 +43,8 @@ def test___init__(self): self.assertRaises(TypeError, BondCalculator, invalid=55) return - def test___call__(self): - """check BondCalculator.__call__() - """ + """check BondCalculator.__call__()""" bdc = self.bdc bdc.rmax = 0 self.assertEqual(0, len(bdc(self.rutile))) @@ -62,10 +58,8 @@ def test___call__(self): self.assertEqual(2, bdc.rmax) return - def test_pickling(self): - '''check pickling and unpickling of BondCalculator. - ''' + """check pickling and unpickling of BondCalculator.""" bdc = self.bdc bdc.rmin = 0.1 bdc.rmax = 12.3 @@ -79,14 +73,13 @@ def test_pickling(self): self.assertFalse(bdc1.getPairMask(1, 2)) self.assertTrue(bdc1.getPairMask(0, 0)) self.assertTrue(numpy.array_equal(bdc.distances, bdc1.distances)) - self.assertRaises(RuntimeError, pickle_with_attr, bdc, foo='bar') + self.assertRaises(RuntimeError, pickle_with_attr, bdc, foo="bar") return - def test_pickling_derived_structure(self): - '''check pickling of BondCalculator with DerivedStructureAdapter. - ''' + """check pickling of BondCalculator with DerivedStructureAdapter.""" from diffpy.srreal.tests.testutils import DerivedStructureAdapter + bdc = self.bdc stru0 = DerivedStructureAdapter() bdc.setStructure(stru0) @@ -100,20 +93,17 @@ def test_pickling_derived_structure(self): self.assertEqual(1, stru1.cpqcount) return - def test_distances(self): - """check BondCalculator.distances - """ + """check BondCalculator.distances""" self.bdc.eval(self.nickel) dst = self.bdc.distances - self.assertTrue(numpy.array_equal(dst, - BondCalculator()(self.nickel))) + self.assertTrue(numpy.array_equal(dst, BondCalculator()(self.nickel))) self.assertTrue(numpy.array_equal(dst, numpy.sort(dst))) self.bdc.maskAllPairs(False) for i in range(4): self.bdc.setPairMask(0, i, True) dst0a = self.bdc(self.nickel) - idx0a = (self.bdc.sites0 == 0) + idx0a = self.bdc.sites0 == 0 self.bdc.maskAllPairs(False) for i in range(4): self.bdc.setPairMask(3, i, True) @@ -124,20 +114,16 @@ def test_distances(self): self.assertTrue(numpy.allclose(dst0a[idx0a], dstp)) return - def test_directions(self): - """check BondCalculator.directions - """ + """check BondCalculator.directions""" dst = self.bdc(self.rutile) drs = self.bdc.directions nms = numpy.sqrt(numpy.sum(numpy.power(drs, 2), axis=1)) self.assertTrue(numpy.allclose(dst, nms)) return - def test_sites(self): - """check BondCalculator.sites - """ + """check BondCalculator.sites""" bdc = self.bdc dst = bdc(self.rutile) self.assertEqual(len(dst), len(bdc.sites0)) @@ -146,8 +132,7 @@ def test_sites(self): self.assertEqual(5, numpy.max(bdc.sites0)) self.assertEqual(0, numpy.min(bdc.sites1)) self.assertEqual(5, numpy.max(bdc.sites1)) - dij = [(tuple(d) + (i0, i1)) for d, i0, i1 in zip( - bdc.directions, bdc.sites0, bdc.sites1)] + dij = [(tuple(d) + (i0, i1)) for d, i0, i1 in zip(bdc.directions, bdc.sites0, bdc.sites1)] self.assertEqual(len(dij), len(set(dij))) bdc.maskAllPairs(False) bdc(self.rutile) @@ -158,16 +143,14 @@ def test_sites(self): self.assertEqual(set([3]), set(bdc.sites0).union(bdc.sites1)) return - def test_types(self): - """check BondCalculator.types - """ + """check BondCalculator.types""" bdc = self.bdc dst = bdc(self.rutile) self.assertEqual(len(dst), len(bdc.types0)) self.assertEqual(len(dst), len(bdc.types1)) - self.assertEqual(set(('Ti', 'O')), set(bdc.types0)) - self.assertEqual(set(('Ti', 'O')), set(bdc.types1)) + self.assertEqual(set(("Ti", "O")), set(bdc.types0)) + self.assertEqual(set(("Ti", "O")), set(bdc.types1)) self.assertFalse((bdc.types0 == bdc.types1).all()) bdc.maskAllPairs(False) bdc(self.rutile) @@ -176,13 +159,11 @@ def test_types(self): bdc.setPairMask(3, 3, True) bdc(self.rutile) self.assertTrue(len(bdc.types0)) - self.assertEqual(set(['O']), set(bdc.types0).union(set(bdc.types1))) + self.assertEqual(set(["O"]), set(bdc.types0).union(set(bdc.types1))) return - def test_filterCone(self): - """check BondCalculator.filterCone() - """ + """check BondCalculator.filterCone()""" bdc = self.bdc bdc.rmax = 2.5 self.assertEqual(12, len(bdc(self.niprim))) @@ -199,10 +180,8 @@ def test_filterCone(self): self.assertEqual(12, len(bdc(self.niprim))) return - def test_filterOff(self): - """check BondCalculator.filterOff() - """ + """check BondCalculator.filterOff()""" bdc = self.bdc bdc.rmax = 2.5 bdc.filterCone([1, 2, 3], -1) @@ -211,10 +190,8 @@ def test_filterOff(self): self.assertEqual(12, len(bdc(self.niprim))) return - def test_setPairMask(self): - '''check different setPairMask arguments. - ''' + """check different setPairMask arguments.""" bdc = self.bdc dall = bdc(self.nickel) bdc.maskAllPairs(False) @@ -230,39 +207,37 @@ def test_setPairMask(self): dst0c = bdc(self.nickel) self.assertTrue(numpy.array_equal(dst0a, dst0c)) bdc.maskAllPairs(False) - bdc.setPairMask(0, 'all', True) + bdc.setPairMask(0, "all", True) dst0d = bdc(self.nickel) self.assertTrue(numpy.array_equal(dst0a, dst0d)) - bdc.setPairMask('all', 'all', False) + bdc.setPairMask("all", "all", False) self.assertEqual(0, len(bdc(self.nickel))) - bdc.setPairMask('all', range(4), True) + bdc.setPairMask("all", range(4), True) dall2 = bdc(self.nickel) self.assertTrue(numpy.array_equal(dall, dall2)) - self.assertRaises(ValueError, bdc.setPairMask, 'fooo', 2, True) - self.assertRaises(ValueError, bdc.setPairMask, 'aLL', 2, True) + self.assertRaises(ValueError, bdc.setPairMask, "fooo", 2, True) + self.assertRaises(ValueError, bdc.setPairMask, "aLL", 2, True) return - def test_setTypeMask(self): - '''check different setTypeMask arguments. - ''' + """check different setTypeMask arguments.""" bdc = self.bdc dall = bdc(self.rutile) - bdc.setTypeMask('all', 'All', False) + bdc.setTypeMask("all", "All", False) self.assertTrue(numpy.array_equal(dall, bdc(self.rutile))) - bdc.setTypeMask('all', 'ALL', False) + bdc.setTypeMask("all", "ALL", False) self.assertEqual(0, len(bdc(self.rutile))) bdc.maskAllPairs(True) - bdc.setTypeMask('Ti', ['O'], True, others=False) + bdc.setTypeMask("Ti", ["O"], True, others=False) bdc() tps = set(zip(bdc.types0, bdc.types1)) self.assertEqual(2, len(tps)) - self.assertTrue(('Ti', 'O') in tps) - self.assertTrue(('O', 'Ti') in tps) - bdc.setTypeMask(['Ti'], self.rutile.element, 0, others=1) + self.assertTrue(("Ti", "O") in tps) + self.assertTrue(("O", "Ti") in tps) + bdc.setTypeMask(["Ti"], self.rutile.element, 0, others=1) bdc() tps = set(zip(bdc.types0, bdc.types1)) - self.assertEqual(set([('O', 'O')]), tps) + self.assertEqual(set([("O", "O")]), tps) return @@ -270,25 +245,23 @@ def test_setTypeMask(self): # ---------------------------------------------------------------------------- + @unittest.skipUnless(has_pyobjcryst, _msg_nopyobjcryst) class TestBondCalculatorObjCryst(unittest.TestCase): def setUp(self): self.bdc = BondCalculator() - if not hasattr(self, 'rutile'): - type(self).rutile = loadObjCrystCrystal('rutile.cif') - if not hasattr(self, 'nickel'): - type(self).nickel = loadObjCrystCrystal('Ni.cif') + if not hasattr(self, "rutile"): + type(self).rutile = loadObjCrystCrystal("rutile.cif") + if not hasattr(self, "nickel"): + type(self).nickel = loadObjCrystCrystal("Ni.cif") return - def tearDown(self): return - def test___call__(self): - """check BondCalculator.__call__() - """ + """check BondCalculator.__call__()""" bdc = self.bdc bdc.rmax = 0 self.assertEqual(0, len(bdc(self.rutile).tolist())) @@ -298,10 +271,8 @@ def test___call__(self): self.assertEqual(12, len(bdc(self.nickel))) return - def test_sites(self): - """check BondCalculator.sites - """ + """check BondCalculator.sites""" bdc = self.bdc dst = bdc(self.rutile) self.assertEqual(len(dst), len(bdc.sites0)) @@ -310,8 +281,7 @@ def test_sites(self): self.assertEqual(1, numpy.max(bdc.sites0)) self.assertEqual(0, numpy.min(bdc.sites1)) self.assertEqual(1, numpy.max(bdc.sites1)) - dij = [(tuple(d) + (i0, i1)) for d, i0, i1 in zip( - bdc.directions, bdc.sites0, bdc.sites1)] + dij = [(tuple(d) + (i0, i1)) for d, i0, i1 in zip(bdc.directions, bdc.sites0, bdc.sites1)] self.assertEqual(len(dij), len(set(dij))) bdc.maskAllPairs(False) bdc(self.rutile) @@ -322,16 +292,14 @@ def test_sites(self): self.assertEqual(set([1]), set(bdc.sites0).union(bdc.sites1)) return - def test_types(self): - """check BondCalculator.types - """ + """check BondCalculator.types""" bdc = self.bdc dst = bdc(self.rutile) self.assertEqual(len(dst), len(bdc.types0)) self.assertEqual(len(dst), len(bdc.types1)) - self.assertEqual(set(('Ti', 'O')), set(bdc.types0)) - self.assertEqual(set(('Ti', 'O')), set(bdc.types1)) + self.assertEqual(set(("Ti", "O")), set(bdc.types0)) + self.assertEqual(set(("Ti", "O")), set(bdc.types1)) self.assertNotEqual(bdc.types0.tolist(), bdc.types1.tolist()) bdc.maskAllPairs(False) bdc(self.rutile) @@ -340,13 +308,11 @@ def test_types(self): bdc.setPairMask(1, 1, True) bdc(self.rutile) self.assertTrue(len(bdc.types0)) - self.assertEqual(set(['O']), set(bdc.types0).union(set(bdc.types1))) + self.assertEqual(set(["O"]), set(bdc.types0).union(set(bdc.types1))) return - def test_filterCone(self): - """check BondCalculator.filterCone() - """ + """check BondCalculator.filterCone()""" bdc = self.bdc bdc.rmax = 2.5 bdc.filterCone([+0.5, +0.5, 0], 1) @@ -362,10 +328,8 @@ def test_filterCone(self): self.assertEqual(12, len(bdc(self.nickel))) return - def test_filterOff(self): - """check BondCalculator.filterOff() - """ + """check BondCalculator.filterOff()""" bdc = self.bdc bdc.rmax = 2.5 bdc.filterCone([1, 2, 3], -1) @@ -374,11 +338,12 @@ def test_filterOff(self): self.assertEqual(12, len(bdc(self.nickel))) return + # End of class TestBondCalculatorObjCryst # ---------------------------------------------------------------------------- -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() # End of file diff --git a/src/diffpy/srreal/tests/testbvscalculator.py b/src/diffpy/srreal/tests/testbvscalculator.py index 488c6348..62efd7dd 100644 --- a/src/diffpy/srreal/tests/testbvscalculator.py +++ b/src/diffpy/srreal/tests/testbvscalculator.py @@ -11,35 +11,32 @@ from diffpy.srreal.tests.testutils import loadDiffPyStructure from diffpy.srreal.tests.testutils import pickle_with_attr + ############################################################################## class TestBVSCalculator(unittest.TestCase): def setUp(self): self.bvc = BVSCalculator() - if not hasattr(self, 'rutile'): - type(self).rutile = loadDiffPyStructure('rutile.cif') + if not hasattr(self, "rutile"): + type(self).rutile = loadDiffPyStructure("rutile.cif") # rutile.cif does not have charge data, we need to add them here - iondict = {'Ti' : 'Ti4+', 'O' : 'O2-'} - for a in self.rutile: a.element = iondict[a.element] + iondict = {"Ti": "Ti4+", "O": "O2-"} + for a in self.rutile: + a.element = iondict[a.element] return - def tearDown(self): return - def test___init__(self): - """check BVSCalculator.__init__() - """ + """check BVSCalculator.__init__()""" self.assertEqual(1e-5, self.bvc.valenceprecision) bvc1 = BVSCalculator(valenceprecision=1e-4) self.assertEqual(1e-4, bvc1.valenceprecision) return - def test___call__(self): - """check BVSCalculator.__call__() - """ + """check BVSCalculator.__call__()""" vcalc = self.bvc(self.rutile) self.assertEqual(len(self.rutile), len(vcalc)) self.assertEqual(tuple(self.bvc.value), tuple(vcalc)) @@ -51,10 +48,8 @@ def test___call__(self): self.assertTrue(abs((vo - vc) / vo) < 0.1) return - def test_bvdiff(self): - """check BVSCalculator.bvdiff - """ + """check BVSCalculator.bvdiff""" self.bvc(self.rutile) self.assertEqual(6, len(self.bvc.bvdiff)) # rutile is overbonded @@ -62,25 +57,21 @@ def test_bvdiff(self): self.assertTrue(bvd < 0) return - def test_bvmsdiff(self): - """check BVSCalculator.bvmsdiff - """ + """check BVSCalculator.bvmsdiff""" self.assertEqual(0, self.bvc.bvmsdiff) self.bvc(self.rutile) self.assertAlmostEqual(0.0158969, self.bvc.bvmsdiff, 6) return - def test_bvrmsdiff(self): - """check BVSCalculator.bvrmsdiff - """ + """check BVSCalculator.bvrmsdiff""" from math import sqrt + self.assertEqual(0, self.bvc.bvrmsdiff) self.bvc(self.rutile) self.assertTrue(self.bvc.bvrmsdiff > 0) - self.assertAlmostEqual(sqrt(self.bvc.bvmsdiff), - self.bvc.bvrmsdiff, 12) + self.assertAlmostEqual(sqrt(self.bvc.bvmsdiff), self.bvc.bvrmsdiff, 12) bvrmsd0 = self.bvc.bvrmsdiff # check mixed occupancy rutilemix = self.rutile.copy() @@ -93,34 +84,25 @@ def test_bvrmsdiff(self): self.assertAlmostEqual(bvrmsd0, self.bvc.bvrmsdiff, 12) return - def test_eval(self): - """check BVSCalculator.eval() - """ + """check BVSCalculator.eval()""" vcalc = self.bvc.eval(self.rutile) self.assertEqual(tuple(vcalc), tuple(self.bvc.value)) return - def test_valences(self): - """check BVSCalculator.valences - """ + """check BVSCalculator.valences""" self.bvc(self.rutile) - self.assertEqual((4, 4, -2, -2, -2, -2), - tuple(self.bvc.valences)) + self.assertEqual((4, 4, -2, -2, -2, -2), tuple(self.bvc.valences)) return - def test_value(self): - """check BVSCalculator.value - """ + """check BVSCalculator.value""" self.assertEqual(0, len(self.bvc.value)) return - def test_pickling(self): - '''check pickling and unpickling of BVSCalculator. - ''' + """check pickling and unpickling of BVSCalculator.""" bvsc = BVSCalculator() bvsc.rmin = 0.1 bvsc.rmax = 12.3 @@ -130,13 +112,11 @@ def test_pickling(self): self.assertFalse(bvsc is bvsc1) for a in bvsc._namesOfDoubleAttributes(): self.assertEqual(getattr(bvsc, a), getattr(bvsc1, a)) - self.assertRaises(RuntimeError, pickle_with_attr, bvsc, foo='bar') + self.assertRaises(RuntimeError, pickle_with_attr, bvsc, foo="bar") return - def test_mask_pickling(self): - '''Check if mask gets properly pickled and restored. - ''' + """Check if mask gets properly pickled and restored.""" self.bvc.maskAllPairs(False) self.bvc.setPairMask(0, 1, True) self.assertTrue(False is self.bvc.getPairMask(0, 0)) @@ -146,13 +126,11 @@ def test_mask_pickling(self): self.assertTrue(True is bvc1.getPairMask(0, 1)) return - def test_table_pickling(self): - '''Check if bvparamtable gets correctly pickled and restored. - ''' - self.bvc.bvparamtable.setCustom('A', 1, 'B', -2, 7, 8) + """Check if bvparamtable gets correctly pickled and restored.""" + self.bvc.bvparamtable.setCustom("A", 1, "B", -2, 7, 8) bvc1 = pickle.loads(pickle.dumps(self.bvc)) - bpab = bvc1.bvparamtable.lookup('A+', 'B2-') + bpab = bvc1.bvparamtable.lookup("A+", "B2-") self.assertEqual("A", bpab.atom0) self.assertEqual(1, bpab.valence0) self.assertEqual("B", bpab.atom1) @@ -161,11 +139,10 @@ def test_table_pickling(self): self.assertEqual(8, bpab.B) return - def test_pickling_derived_structure(self): - '''check pickling of BVSCalculator with DerivedStructureAdapter. - ''' + """check pickling of BVSCalculator with DerivedStructureAdapter.""" from diffpy.srreal.tests.testutils import DerivedStructureAdapter + bvc = self.bvc stru0 = DerivedStructureAdapter() bvc.setStructure(stru0) @@ -179,15 +156,13 @@ def test_pickling_derived_structure(self): self.assertEqual(1, stru1.cpqcount) return - def test_table_atom_valence(self): - '''check calculation with defined valences in bvparamtable - ''' + """check calculation with defined valences in bvparamtable""" bvc = self.bvc barerutile = self.rutile.copy() for a in barerutile: - a.element = a.element.rstrip('+-012345678') - self.assertEqual({"Ti" : 2, "O" : 4}, barerutile.composition) + a.element = a.element.rstrip("+-012345678") + self.assertEqual({"Ti": 2, "O": 4}, barerutile.composition) self.assertFalse(any(bvc(barerutile))) bptb = bvc.bvparamtable bptb.setAtomValence("Ti", +4) @@ -201,9 +176,10 @@ def test_table_atom_valence(self): self.assertFalse(any(bvc(barerutile))) return + # End of class TestBVSCalculator -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() # End of file diff --git a/src/diffpy/srreal/tests/testdebyepdfcalculator.py b/src/diffpy/srreal/tests/testdebyepdfcalculator.py index 78d8b0ef..9268613f 100644 --- a/src/diffpy/srreal/tests/testdebyepdfcalculator.py +++ b/src/diffpy/srreal/tests/testdebyepdfcalculator.py @@ -13,6 +13,7 @@ from diffpy.srreal.tests.testutils import pickle_with_attr from diffpy.srreal.tests.testpdfcalculator import _maxNormDiff + ############################################################################## class TestDebyePDFCalculator(unittest.TestCase): @@ -22,78 +23,69 @@ class TestDebyePDFCalculator(unittest.TestCase): def setUp(self): self.dpdfc = DebyePDFCalculator() if not TestDebyePDFCalculator.bucky: - TestDebyePDFCalculator.bucky = ( - loadDiffPyStructure('C60bucky.stru')) + TestDebyePDFCalculator.bucky = loadDiffPyStructure("C60bucky.stru") if not TestDebyePDFCalculator.tio2rutile: - TestDebyePDFCalculator.tio2rutile = ( - loadDiffPyStructure('TiO2_rutile-fit.stru')) + TestDebyePDFCalculator.tio2rutile = loadDiffPyStructure("TiO2_rutile-fit.stru") return -# def tearDown(self): -# return -# -# def test___call__(self): -# """check DebyePDFCalculator.__call__() -# """ -# return -# -# def test___init__(self): -# """check DebyePDFCalculator.__init__() -# """ -# return + # def tearDown(self): + # return + # + # def test___call__(self): + # """check DebyePDFCalculator.__call__() + # """ + # return + # + # def test___init__(self): + # """check DebyePDFCalculator.__init__() + # """ + # return def test___getattr__(self): - """check DebyePDFCalculator.__getattr__() - """ + """check DebyePDFCalculator.__getattr__()""" self.assertEqual(0.0, self.dpdfc.qmin) - self.dpdfc._setDoubleAttr('qmin', 1.23) + self.dpdfc._setDoubleAttr("qmin", 1.23) self.assertEqual(1.23, self.dpdfc.qmin) return def test___setattr__(self): - """check DebyePDFCalculator.__setattr__() - """ - self.assertNotEqual(1.23, self.dpdfc._getDoubleAttr('rmin')) + """check DebyePDFCalculator.__setattr__()""" + self.assertNotEqual(1.23, self.dpdfc._getDoubleAttr("rmin")) self.dpdfc.rmin = 1.23 - self.assertEqual(1.23, self.dpdfc._getDoubleAttr('rmin')) + self.assertEqual(1.23, self.dpdfc._getDoubleAttr("rmin")) return def test__getDoubleAttr(self): - """check DebyePDFCalculator._getDoubleAttr() - """ + """check DebyePDFCalculator._getDoubleAttr()""" gdba = self.dpdfc._getDoubleAttr - self.assertEqual(1.0, gdba('scale')) - self.assertEqual(0.0, gdba('qdamp')) - self.assertRaises(Exception, gdba, 'notanattribute') + self.assertEqual(1.0, gdba("scale")) + self.assertEqual(0.0, gdba("qdamp")) + self.assertRaises(Exception, gdba, "notanattribute") return def test__hasDoubleAttr(self): - """check DebyePDFCalculator._hasDoubleAttr() - """ - self.assertTrue(self.dpdfc._hasDoubleAttr('scale')) - self.assertFalse(self.dpdfc._hasDoubleAttr('notanattribute')) + """check DebyePDFCalculator._hasDoubleAttr()""" + self.assertTrue(self.dpdfc._hasDoubleAttr("scale")) + self.assertFalse(self.dpdfc._hasDoubleAttr("notanattribute")) return def test__namesOfDoubleAttributes(self): - """check DebyePDFCalculator._namesOfDoubleAttributes() - """ + """check DebyePDFCalculator._namesOfDoubleAttributes()""" self.assertTrue(type(self.dpdfc._namesOfDoubleAttributes()) is set) - self.assertTrue('qmax' in self.dpdfc._namesOfDoubleAttributes()) + self.assertTrue("qmax" in self.dpdfc._namesOfDoubleAttributes()) return def test__setDoubleAttr(self): - """check DebyePDFCalculator._setDoubleAttr() - """ + """check DebyePDFCalculator._setDoubleAttr()""" gdba = self.dpdfc._getDoubleAttr sdba = self.dpdfc._setDoubleAttr - self.assertEqual(0.0, gdba('rmin')) - sdba('rmin', 3.0) - self.assertEqual(3.0, gdba('rmin')) + self.assertEqual(0.0, gdba("rmin")) + sdba("rmin", 3.0) + self.assertEqual(3.0, gdba("rmin")) return def test_PDF_C60bucky(self): - """check DebyePDFCalculator.pdf for C60 Bucky ball. - """ + """check DebyePDFCalculator.pdf for C60 Bucky ball.""" qmax = self.dpdfc.qmax r0, g0 = PDFCalculator(qmax=qmax)(self.bucky) r1, g1 = self.dpdfc(self.bucky) @@ -102,8 +94,7 @@ def test_PDF_C60bucky(self): return def test_partial_pdfs(self): - """Check calculation of partial PDFs. - """ + """Check calculation of partial PDFs.""" dpdfc = self.dpdfc dpdfc.qmin = 1.0 rutile = self.tio2rutile @@ -119,9 +110,9 @@ def test_partial_pdfs(self): self.assertTrue(numpy.allclose(g0, g1 + g1i)) # Ti-O dpdfc.maskAllPairs(False) - dpdfc.setTypeMask('all', 'ALL', True) - dpdfc.setTypeMask('Ti', 'Ti', False) - dpdfc.setTypeMask('O', 'O', False) + dpdfc.setTypeMask("all", "ALL", True) + dpdfc.setTypeMask("Ti", "Ti", False) + dpdfc.setTypeMask("O", "O", False) r2, g2 = dpdfc(rutile) self.assertTrue(numpy.array_equal(r0, r2)) dpdfc.invertMask() @@ -139,7 +130,7 @@ def test_partial_pdfs(self): self.assertTrue(numpy.array_equal(g2i, g2ti)) # O-O dpdfc.maskAllPairs(False) - dpdfc.setTypeMask('O', 'O', True) + dpdfc.setTypeMask("O", "O", True) r3, g3 = dpdfc(rutile) dpdfc.invertMask() r3i, g3i = dpdfc(rutile) @@ -149,12 +140,11 @@ def test_partial_pdfs(self): return def test_pickling(self): - '''check pickling and unpickling of PDFCalculator. - ''' + """check pickling and unpickling of PDFCalculator.""" dpdfc = self.dpdfc - dpdfc.setScatteringFactorTableByType('N') - dpdfc.scatteringfactortable.setCustomAs('Na', 'Na', 7) - dpdfc.addEnvelope('sphericalshape') + dpdfc.setScatteringFactorTableByType("N") + dpdfc.scatteringfactortable.setCustomAs("Na", "Na", 7) + dpdfc.addEnvelope("sphericalshape") dpdfc.debyeprecision = 0.001 dpdfc.delta1 = 0.2 dpdfc.delta2 = 0.3 @@ -174,21 +164,17 @@ def test_pickling(self): sft = dpdfc.scatteringfactortable sft1 = dpdfc1.scatteringfactortable self.assertEqual(sft.type(), sft1.type()) - self.assertEqual(7.0, sft1.lookup('Na')) + self.assertEqual(7.0, sft1.lookup("Na")) for a in dpdfc._namesOfDoubleAttributes(): self.assertEqual(getattr(dpdfc, a), getattr(dpdfc1, a)) - self.assertEqual(13.3, - dpdfc1.getEnvelope('sphericalshape').spdiameter) - self.assertEqual(dpdfc._namesOfDoubleAttributes(), - dpdfc1._namesOfDoubleAttributes()) + self.assertEqual(13.3, dpdfc1.getEnvelope("sphericalshape").spdiameter) + self.assertEqual(dpdfc._namesOfDoubleAttributes(), dpdfc1._namesOfDoubleAttributes()) self.assertEqual(dpdfc.usedenvelopetypes, dpdfc1.usedenvelopetypes) - self.assertRaises(RuntimeError, pickle_with_attr, dpdfc, foo='bar') + self.assertRaises(RuntimeError, pickle_with_attr, dpdfc, foo="bar") return - def test_mask_pickling(self): - '''Check if mask gets properly pickled and restored. - ''' + """Check if mask gets properly pickled and restored.""" self.dpdfc.maskAllPairs(False) self.dpdfc.setPairMask(0, 1, True) self.dpdfc.setTypeMask("Na", "Cl", True) @@ -201,11 +187,10 @@ def test_mask_pickling(self): self.assertTrue(True is self.dpdfc.getTypeMask("Cl", "Na")) return - def test_pickling_derived_structure(self): - '''check pickling of DebyePDFCalculator with DerivedStructureAdapter. - ''' + """check pickling of DebyePDFCalculator with DerivedStructureAdapter.""" from diffpy.srreal.tests.testutils import DerivedStructureAdapter + dpdfc = self.dpdfc stru0 = DerivedStructureAdapter() dpdfc.setStructure(stru0) @@ -268,7 +253,7 @@ def test_pickling_derived_structure(self): # End of class TestDebyePDFCalculator -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() # End of file diff --git a/src/diffpy/srreal/tests/testoverlapcalculator.py b/src/diffpy/srreal/tests/testoverlapcalculator.py index 44d83312..09881233 100644 --- a/src/diffpy/srreal/tests/testoverlapcalculator.py +++ b/src/diffpy/srreal/tests/testoverlapcalculator.py @@ -18,18 +18,19 @@ # ---------------------------------------------------------------------------- + class TestOverlapCalculator(unittest.TestCase): pool = None def setUp(self): self.olc = OverlapCalculator() - if not hasattr(self, 'rutile'): - type(self).rutile = loadDiffPyStructure('rutile.cif') - if not hasattr(self, 'nickel'): - type(self).nickel = loadDiffPyStructure('Ni.stru') - if not hasattr(self, 'niprim'): - type(self).niprim = loadDiffPyStructure('Ni_primitive.stru') + if not hasattr(self, "rutile"): + type(self).rutile = loadDiffPyStructure("rutile.cif") + if not hasattr(self, "nickel"): + type(self).nickel = loadDiffPyStructure("Ni.stru") + if not hasattr(self, "niprim"): + type(self).niprim = loadDiffPyStructure("Ni_primitive.stru") return def tearDown(self): @@ -40,8 +41,7 @@ def tearDown(self): return def test___init__(self): - """check OverlapCalculator.__init__() - """ + """check OverlapCalculator.__init__()""" self.assertEqual(0, self.olc.rmin) self.assertTrue(100 <= self.olc.rmax) self.assertEqual(0, self.olc.rmaxused) @@ -49,15 +49,14 @@ def test___init__(self): return def test___call__(self): - """check OverlapCalculator.__call__() - """ + """check OverlapCalculator.__call__()""" olc = self.olc sso1 = olc(self.rutile) self.assertEqual(6, len(sso1)) self.assertFalse(numpy.any(sso1)) self.assertEqual(0.0, olc.rmaxused) rtb = olc.atomradiitable - rtb.fromString('Ti:1.6, O:0.66') + rtb.fromString("Ti:1.6, O:0.66") sso2 = olc(self.rutile) self.assertEqual(6, len(sso2[sso2 > 0])) self.assertEqual(3.2, olc.rmaxused) @@ -67,8 +66,7 @@ def test___call__(self): return def test___getstate__(self): - """check OverlapCalculator.__getstate__() - """ + """check OverlapCalculator.__getstate__()""" olc = self.olc self.assertIs(None, olc.__getstate__()[-1]) tb = CovalentRadiiTable() @@ -79,8 +77,7 @@ def test___getstate__(self): return def test_pickling(self): - '''check pickling and unpickling of OverlapCalculator. - ''' + """check pickling and unpickling of OverlapCalculator.""" olc = self.olc olc.rmin = 0.1 olc.rmax = 12.3 @@ -92,14 +89,12 @@ def test_pickling(self): self.assertEqual(getattr(olc, a), getattr(olc1, a)) self.assertFalse(olc1.getPairMask(1, 2)) self.assertTrue(olc1.getPairMask(0, 0)) - self.assertTrue(numpy.array_equal( - olc.sitesquareoverlaps, olc1.sitesquareoverlaps)) - self.assertRaises(RuntimeError, pickle_with_attr, olc, foo='bar') + self.assertTrue(numpy.array_equal(olc.sitesquareoverlaps, olc1.sitesquareoverlaps)) + self.assertRaises(RuntimeError, pickle_with_attr, olc, foo="bar") return def test_pickling_artb(self): - '''check pickling and unpickling of OverlapCalculator.atomradiitable. - ''' + """check pickling and unpickling of OverlapCalculator.atomradiitable.""" olc = self.olc olc.atomradiitable.setDefault(1.3) spkl = pickle.dumps(olc) @@ -107,19 +102,19 @@ def test_pickling_artb(self): self.assertFalse(olc is olc1) self.assertEqual(1.3, olc1.atomradiitable.getDefault()) olc.atomradiitable = CovalentRadiiTable() - olc.atomradiitable.setCustom('Na', 2) + olc.atomradiitable.setCustom("Na", 2) olc.atomradiitable.foo = 123 spkl2 = pickle.dumps(olc) olc2 = pickle.loads(spkl2) - self.assertEqual(2, olc2.atomradiitable.lookup('Na')) + self.assertEqual(2, olc2.atomradiitable.lookup("Na")) self.assertEqual(1, len(olc2.atomradiitable.getAllCustom())) self.assertEqual(123, olc2.atomradiitable.foo) return def test_pickling_derived_structure(self): - '''check pickling of OverlapCalculator with DerivedStructureAdapter. - ''' + """check pickling of OverlapCalculator with DerivedStructureAdapter.""" from diffpy.srreal.tests.testutils import DerivedStructureAdapter + olc = self.olc stru0 = DerivedStructureAdapter() olc.setStructure(stru0) @@ -134,52 +129,48 @@ def test_pickling_derived_structure(self): return def test_parallel(self): - """check parallel run of OverlapCalculator - """ + """check parallel run of OverlapCalculator""" import multiprocessing from diffpy.srreal.parallel import createParallelCalculator + ncpu = 4 self.pool = multiprocessing.Pool(processes=ncpu) olc = self.olc - polc = createParallelCalculator(OverlapCalculator(), - ncpu, self.pool.imap_unordered) - olc.atomradiitable.fromString('Ti:1.6, O:0.66') + polc = createParallelCalculator(OverlapCalculator(), ncpu, self.pool.imap_unordered) + olc.atomradiitable.fromString("Ti:1.6, O:0.66") polc.atomradiitable = olc.atomradiitable self.assertTrue(numpy.array_equal(olc(self.rutile), polc(self.rutile))) self.assertTrue(olc.totalsquareoverlap > 0.0) self.assertEqual(olc.totalsquareoverlap, polc.totalsquareoverlap) - self.assertEqual(sorted(zip(olc.sites0, olc.sites1)), - sorted(zip(polc.sites0, polc.sites1))) + self.assertEqual(sorted(zip(olc.sites0, olc.sites1)), sorted(zip(polc.sites0, polc.sites1))) olc.atomradiitable.resetAll() self.assertEqual(0.0, sum(olc(self.rutile))) self.assertEqual(0.0, sum(polc(self.rutile))) return def test_distances(self): - """check OverlapCalculator.distances - """ + """check OverlapCalculator.distances""" olc = self.olc olc(self.nickel) self.assertEqual(0, len(olc.distances)) - olc.atomradiitable.setCustom('Ni', 1.25) + olc.atomradiitable.setCustom("Ni", 1.25) olc(self.nickel) self.assertEqual(4 * 12, len(olc.distances)) dmin = numpy.sqrt(0.5) * self.nickel.lattice.a self.assertAlmostEqual(dmin, numpy.min(olc.distances)) self.assertAlmostEqual(dmin, numpy.max(olc.distances)) olc.maskAllPairs(False) - olc.setPairMask(0, 'all', True) + olc.setPairMask(0, "all", True) olc(self.nickel) self.assertEqual(12 + 12, len(olc.distances)) return def test_directions(self): - """check OverlapCalculator.directions - """ + """check OverlapCalculator.directions""" olc = self.olc olc(self.nickel) self.assertEqual([], olc.directions.tolist()) - olc.atomradiitable.setCustom('Ni', 1.25) + olc.atomradiitable.setCustom("Ni", 1.25) olc.eval(self.nickel) drs = self.olc.directions nms = numpy.sqrt(numpy.sum(numpy.power(drs, 2), axis=1)) @@ -188,10 +179,9 @@ def test_directions(self): return def test_gradients(self): - """check OverlapCalculator.gradients - """ + """check OverlapCalculator.gradients""" olc = self.olc - olc.atomradiitable.fromString('Ti:1.6, O:0.66') + olc.atomradiitable.fromString("Ti:1.6, O:0.66") olc(self.rutile) self.assertEqual((6, 3), olc.gradients.shape) self.assertTrue(numpy.allclose([0, 0, 0], numpy.sum(olc.gradients))) @@ -199,7 +189,7 @@ def test_gradients(self): self.assertTrue(abs(g2[0]) > 0.1) tso0 = olc.totalsquareoverlap dx = 1e-8 - rutile2 = loadDiffPyStructure('rutile.cif') + rutile2 = loadDiffPyStructure("rutile.cif") rutile2[2].xyz_cartn += [dx, 0.0, 0.0] olc.eval(rutile2) g2nx = (olc.totalsquareoverlap - tso0) / dx @@ -207,63 +197,59 @@ def test_gradients(self): return def test_sitesquareoverlaps(self): - """check OverlapCalculator.sitesquareoverlaps - """ + """check OverlapCalculator.sitesquareoverlaps""" olc = self.olc self.assertTrue(numpy.array_equal([], olc.sitesquareoverlaps)) olc(self.rutile) self.assertTrue(numpy.array_equal(6 * [0.0], olc.sitesquareoverlaps)) - olc.atomradiitable.fromString('Ti:1.6, O:0.66') + olc.atomradiitable.fromString("Ti:1.6, O:0.66") sso = olc(self.rutile) self.assertTrue(numpy.array_equal(sso, olc.sitesquareoverlaps)) self.assertTrue(numpy.all(sso)) return def test_totalsquareoverlap(self): - """check OverlapCalculator.totalsquareoverlap - """ + """check OverlapCalculator.totalsquareoverlap""" olc = self.olc self.assertEqual(0.0, olc.totalsquareoverlap) olc(self.rutile) self.assertEqual(0.0, olc.totalsquareoverlap) - olc.atomradiitable.fromString('Ti:1.6, O:0.66') + olc.atomradiitable.fromString("Ti:1.6, O:0.66") olc(self.rutile) self.assertTrue(1.20854162728, olc.totalsquareoverlap) return def test_meansquareoverlap(self): - """check OverlapCalculator.meansquareoverlap - """ + """check OverlapCalculator.meansquareoverlap""" olc = self.olc self.assertEqual(0.0, olc.meansquareoverlap) olc(self.nickel) self.assertEqual(0.0, olc.meansquareoverlap) - olc.atomradiitable.setCustom('Ni', 1.25) + olc.atomradiitable.setCustom("Ni", 1.25) olc(self.nickel) mso0 = olc.meansquareoverlap self.assertTrue(mso0 > 0.0) sso1 = olc(self.niprim) self.assertEqual(1, len(sso1)) self.assertAlmostEqual(mso0, olc.meansquareoverlap) - olc.atomradiitable.fromString('Ti:1.6, O:0.66') + olc.atomradiitable.fromString("Ti:1.6, O:0.66") olc(self.rutile) self.assertAlmostEqual(0.201423604547, olc.meansquareoverlap) return def test_flipDiffTotal(self): - """check OverlapCalculator.flipDiffTotal - """ + """check OverlapCalculator.flipDiffTotal""" olc = self.olc - olc.atomradiitable.fromString('Ti:1.6, O:0.66') + olc.atomradiitable.fromString("Ti:1.6, O:0.66") olc(self.rutile) self.assertEqual(0.0, olc.flipDiffTotal(0, 0)) self.assertEqual(0.0, olc.flipDiffTotal(0, 1)) self.assertEqual(0.0, olc.flipDiffTotal(2, 5)) tso0 = olc.totalsquareoverlap olc2 = copy.copy(olc) - rutile2 = loadDiffPyStructure('rutile.cif') - rutile2[0].element = 'O' - rutile2[2].element = 'Ti' + rutile2 = loadDiffPyStructure("rutile.cif") + rutile2[0].element = "O" + rutile2[2].element = "Ti" olc2(rutile2) fdt02 = olc2.totalsquareoverlap - tso0 self.assertTrue(fdt02 > 0.01) @@ -273,48 +259,44 @@ def test_flipDiffTotal(self): return def test_getNeighborSites(self): - """check OverlapCalculator.getNeighborSites - """ + """check OverlapCalculator.getNeighborSites""" olc = self.olc olc(self.rutile) self.assertEqual(set(), olc.getNeighborSites(0)) self.assertEqual(set(), olc.getNeighborSites(3)) - olc.atomradiitable.fromString('Ti:1.6, O:0.66') + olc.atomradiitable.fromString("Ti:1.6, O:0.66") olc(self.rutile) oxygens = list(range(2, 6)) self.assertEqual(set([0] + oxygens), olc.getNeighborSites(0)) self.assertEqual(set([1] + oxygens), olc.getNeighborSites(1)) self.assertEqual(set(range(2)), olc.getNeighborSites(2)) self.assertEqual(set(range(2)), olc.getNeighborSites(5)) - n5, = numpy.array([5], dtype=int) + (n5,) = numpy.array([5], dtype=int) self.assertEqual(set(range(2)), olc.getNeighborSites(n5)) return def test_coordinations(self): - """check OverlapCalculator.coordinations - """ + """check OverlapCalculator.coordinations""" olc = self.olc self.assertEqual(0, len(olc.coordinations)) olc(self.rutile) self.assertEqual(6, len(olc.coordinations)) self.assertFalse(numpy.any(olc.coordinations)) - olc.atomradiitable.fromString('Ti:1.6, O:0.66') + olc.atomradiitable.fromString("Ti:1.6, O:0.66") olc(self.rutile) - self.assertTrue(numpy.array_equal( - [8, 8, 3, 3, 3, 3], olc.coordinations)) + self.assertTrue(numpy.array_equal([8, 8, 3, 3, 3, 3], olc.coordinations)) return def test_coordinationByTypes(self): - """check OverlapCalculator.coordinationByTypes - """ + """check OverlapCalculator.coordinationByTypes""" olc = self.olc olc(self.rutile) self.assertEqual({}, olc.coordinationByTypes(0)) self.assertEqual({}, olc.coordinationByTypes(5)) - olc.atomradiitable.fromString('Ti:1.6, O:0.66') + olc.atomradiitable.fromString("Ti:1.6, O:0.66") olc(self.rutile) - cTi = {'Ti' : 2.0, 'O' : 6.0} - cO = {'Ti' : 3.0} + cTi = {"Ti": 2.0, "O": 6.0} + cO = {"Ti": 3.0} self.assertEqual(cTi, olc.coordinationByTypes(0)) self.assertEqual(cTi, olc.coordinationByTypes(1)) self.assertEqual(cO, olc.coordinationByTypes(2)) @@ -324,91 +306,88 @@ def test_coordinationByTypes(self): return def test_neighborhoods(self): - """check OverlapCalculator.neighborhoods - """ + """check OverlapCalculator.neighborhoods""" olc = self.olc self.assertEqual([], olc.neighborhoods) olc(self.rutile) self.assertEqual([set((i,)) for i in range(6)], olc.neighborhoods) - olc.atomradiitable.fromString('Ti:1.6, O:0.66') + olc.atomradiitable.fromString("Ti:1.6, O:0.66") olc(self.rutile) self.assertEqual([set(range(6))], olc.neighborhoods) - olc.atomradiitable.setCustom('Ti', 1.8) - olc.atomradiitable.setCustom('O', 0.1) + olc.atomradiitable.setCustom("Ti", 1.8) + olc.atomradiitable.setCustom("O", 0.1) olc(self.rutile) nghbs = [set((0, 1))] + [set((i,)) for i in range(2, 6)] self.assertEqual(nghbs, olc.neighborhoods) return + # End of class TestOverlapCalculator # ---------------------------------------------------------------------------- + @unittest.skipUnless(has_pyobjcryst, _msg_nopyobjcryst) class TestOverlapCalculatorObjCryst(unittest.TestCase): def setUp(self): self.olc = OverlapCalculator() - if not hasattr(self, 'rutile'): - type(self).rutile = loadObjCrystCrystal('rutile.cif') - if not hasattr(self, 'nickel'): - type(self).nickel = loadObjCrystCrystal('Ni.cif') + if not hasattr(self, "rutile"): + type(self).rutile = loadObjCrystCrystal("rutile.cif") + if not hasattr(self, "nickel"): + type(self).nickel = loadObjCrystCrystal("Ni.cif") return def tearDown(self): return def test_totalsquareoverlap(self): - """check OverlapCalculator.totalsquareoverlap for ObjCryst crystal - """ + """check OverlapCalculator.totalsquareoverlap for ObjCryst crystal""" olc = self.olc self.assertEqual(0.0, olc.totalsquareoverlap) olc(self.rutile) self.assertEqual(0.0, olc.totalsquareoverlap) - olc.atomradiitable.fromString('Ti:1.6, O:0.66') + olc.atomradiitable.fromString("Ti:1.6, O:0.66") olc(self.rutile) self.assertTrue(1.20854162728, olc.totalsquareoverlap) return def test_meansquareoverlap(self): - """check OverlapCalculator.meansquareoverlap for ObjCryst crystal - """ + """check OverlapCalculator.meansquareoverlap for ObjCryst crystal""" olc = self.olc self.assertEqual(0.0, olc.meansquareoverlap) olc(self.rutile) self.assertEqual(0.0, olc.meansquareoverlap) - olc.atomradiitable.fromString('Ti:1.6, O:0.66') + olc.atomradiitable.fromString("Ti:1.6, O:0.66") olc(self.rutile) self.assertAlmostEqual(0.201423604547, olc.meansquareoverlap) return def test_flipDiffTotal(self): - """check OverlapCalculator.flipDiffTotal for an ObjCryst crystal - """ + """check OverlapCalculator.flipDiffTotal for an ObjCryst crystal""" olc = self.olc olc(self.rutile) self.assertEqual(0.0, olc.flipDiffTotal(0, 1)) - olc.atomradiitable.fromString('Ti:1.6, O:0.66') + olc.atomradiitable.fromString("Ti:1.6, O:0.66") olc(self.rutile) tso0 = olc.totalsquareoverlap olc2 = copy.copy(olc) - olc2.atomradiitable.fromString('Ti:0.66, O:1.6') + olc2.atomradiitable.fromString("Ti:0.66, O:1.6") olc2(self.rutile) fdt01 = olc2.totalsquareoverlap - tso0 self.assertAlmostEqual(fdt01, olc.flipDiffTotal(0, 1)) return def test_flipDiffMean(self): - """check OverlapCalculator.flipDiffMean for an ObjCryst crystal - """ + """check OverlapCalculator.flipDiffMean for an ObjCryst crystal""" olc = self.olc olc(self.rutile) self.assertEqual(0.0, olc.flipDiffMean(0, 1)) - olc.atomradiitable.fromString('Ti:1.6, O:0.66') + olc.atomradiitable.fromString("Ti:1.6, O:0.66") olc(self.rutile) mso0 = olc.meansquareoverlap olc2 = copy.copy(olc) - olc2.atomradiitable.fromString('Ti:0.66, O:1.6') + olc2.atomradiitable.fromString("Ti:0.66, O:1.6") olc2(self.rutile) fdm01 = olc2.meansquareoverlap - mso0 self.assertAlmostEqual(fdm01, olc.flipDiffMean(0, 1)) @@ -418,63 +397,60 @@ def test_flipDiffMean(self): return def test_getNeighborSites(self): - """check OverlapCalculator.getNeighborSites for an ObjCryst crystal - """ + """check OverlapCalculator.getNeighborSites for an ObjCryst crystal""" olc = self.olc olc(self.rutile) self.assertEqual(set(), olc.getNeighborSites(0)) self.assertEqual(set(), olc.getNeighborSites(1)) - olc.atomradiitable.fromString('Ti:1.6, O:0.66') + olc.atomradiitable.fromString("Ti:1.6, O:0.66") olc(self.rutile) self.assertEqual(set([0, 1]), olc.getNeighborSites(0)) self.assertEqual(set([0]), olc.getNeighborSites(1)) return def test_coordinations(self): - """check OverlapCalculator.coordinations for an ObjCryst crystal - """ + """check OverlapCalculator.coordinations for an ObjCryst crystal""" olc = self.olc self.assertEqual(0, len(olc.coordinations)) olc(self.rutile) self.assertEqual(2, len(olc.coordinations)) self.assertFalse(numpy.any(olc.coordinations)) - olc.atomradiitable.fromString('Ti:1.6, O:0.66') + olc.atomradiitable.fromString("Ti:1.6, O:0.66") olc(self.rutile) self.assertTrue(numpy.array_equal([8, 3], olc.coordinations)) return def test_coordinationByTypes(self): - """check OverlapCalculator.coordinationByTypes for an ObjCryst crystal - """ + """check OverlapCalculator.coordinationByTypes for an ObjCryst crystal""" olc = self.olc olc(self.rutile) self.assertEqual({}, olc.coordinationByTypes(0)) self.assertEqual({}, olc.coordinationByTypes(1)) - olc.atomradiitable.fromString('Ti:1.6, O:0.66') + olc.atomradiitable.fromString("Ti:1.6, O:0.66") olc(self.rutile) - cTi = {'Ti' : 2.0, 'O' : 6.0} - cO = {'Ti' : 3.0} + cTi = {"Ti": 2.0, "O": 6.0} + cO = {"Ti": 3.0} self.assertEqual(cTi, olc.coordinationByTypes(0)) self.assertEqual(cO, olc.coordinationByTypes(1)) return def test_neighborhoods(self): - """check OverlapCalculator.neighborhoods for an ObjCryst crystal - """ + """check OverlapCalculator.neighborhoods for an ObjCryst crystal""" olc = self.olc self.assertEqual([], olc.neighborhoods) olc(self.rutile) self.assertEqual([set((i,)) for i in range(2)], olc.neighborhoods) - olc.atomradiitable.fromString('Ti:1.6, O:0.66') + olc.atomradiitable.fromString("Ti:1.6, O:0.66") olc(self.rutile) self.assertEqual([set((0, 1))], olc.neighborhoods) return + # End of class TestOverlapCalculatorObjCryst # ---------------------------------------------------------------------------- -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() # End of file diff --git a/src/diffpy/srreal/tests/testpairquantity.py b/src/diffpy/srreal/tests/testpairquantity.py index 2bf755ab..3fa96c80 100644 --- a/src/diffpy/srreal/tests/testpairquantity.py +++ b/src/diffpy/srreal/tests/testpairquantity.py @@ -15,57 +15,56 @@ # ---------------------------------------------------------------------------- + class TestBasePairQuantity(unittest.TestCase): def setUp(self): self.bpq = BasePairQuantity() return - def test_pickling(self): "verify pickling is disabled for the C++ base class." self.assertRaises(RuntimeError, pickle.dumps, self.bpq) return + # End of class TestBasePairQuantity # ---------------------------------------------------------------------------- + class TestPairQuantity(unittest.TestCase): def setUp(self): self.pq = PairQuantity() return - def test_evaluatortype(self): - """check PairQuantity.evaluatortype property. - """ + """check PairQuantity.evaluatortype property.""" pq = self.pq - self.assertTrue(pq.evaluatortype in ('BASIC', 'OPTIMIZED')) - pq.evaluatortype = 'BASIC' - self.assertEqual('BASIC', pq.evaluatortype) - self.assertRaises(ValueError, setattr, pq, 'evaluatortype', 'invalid') - self.assertRaises(ValueError, setattr, pq, 'evaluatortype', 'basic') - self.assertRaises(ValueError, setattr, pq, 'evaluatortype', 'BASic') + self.assertTrue(pq.evaluatortype in ("BASIC", "OPTIMIZED")) + pq.evaluatortype = "BASIC" + self.assertEqual("BASIC", pq.evaluatortype) + self.assertRaises(ValueError, setattr, pq, "evaluatortype", "invalid") + self.assertRaises(ValueError, setattr, pq, "evaluatortype", "basic") + self.assertRaises(ValueError, setattr, pq, "evaluatortype", "BASic") # check all supported evaluators in PDFCalculator pdfc = PDFCalculator() - self.assertEqual('OPTIMIZED', pdfc.evaluatortype) - pdfc.evaluatortype = 'BASIC' - self.assertEqual('BASIC', pdfc.evaluatortype) - pdfc.evaluatortype = 'CHECK' - self.assertEqual('CHECK', pdfc.evaluatortype) - pdfc.evaluatortype = 'OPTIMIZED' - self.assertEqual('OPTIMIZED', pdfc.evaluatortype) + self.assertEqual("OPTIMIZED", pdfc.evaluatortype) + pdfc.evaluatortype = "BASIC" + self.assertEqual("BASIC", pdfc.evaluatortype) + pdfc.evaluatortype = "CHECK" + self.assertEqual("CHECK", pdfc.evaluatortype) + pdfc.evaluatortype = "OPTIMIZED" + self.assertEqual("OPTIMIZED", pdfc.evaluatortype) return - def test_setStructure(self): - """check PairQuantity.setStructure() - """ + """check PairQuantity.setStructure()""" Structure = mod_structure.Structure Atom = mod_structure.Atom from diffpy.srreal.structureadapter import EMPTY + stru = Structure([Atom("Ar", [0.1, 0.2, 0.3])]) self.pq.setStructure(stru) adpt = self.pq.getStructure() @@ -76,10 +75,8 @@ def test_setStructure(self): self.assertEqual(0, adpt.countSites()) return - def test_setPairMask_args(self): - """check argument type handling in setPairMask - """ + """check argument type handling in setPairMask""" spm = self.pq.setPairMask gpm = self.pq.getPairMask self.assertRaises(TypeError, spm, 0.0, 0, False) @@ -92,19 +89,16 @@ def test_setPairMask_args(self): self.assertFalse(gpm(2, 7)) return - def test_getStructure(self): - """check PairQuantity.getStructure() - """ + """check PairQuantity.getStructure()""" adpt = self.pq.getStructure() self.assertEqual(0, adpt.countSites()) return - def test_ticker(self): - """check PairQuantity.ticker() - """ + """check PairQuantity.ticker()""" from diffpy.srreal.eventticker import EventTicker + et0 = EventTicker(self.pq.ticker()) self.pq.rmax = 3.77 et1 = self.pq.ticker() @@ -112,10 +106,8 @@ def test_ticker(self): self.assertTrue(et0 < et1) return - def test_ticker_override(self): - """check Python override of PairQuantity.ticker. - """ + """check Python override of PairQuantity.ticker.""" pqcnt = PQCounter() self.assertEqual(0, pqcnt.tcnt) et0 = pqcnt.ticker() @@ -130,16 +122,14 @@ def test_ticker_override(self): self.assertEqual(1, pqcnt.tcnt) # Check if ticker call from OPTIMIZED evaluator is handled # with our Python override. - pqcnt.evaluatortype = 'OPTIMIZED' + pqcnt.evaluatortype = "OPTIMIZED" self.assertEqual(1, pqcnt.tcnt) pqcnt.eval() self.assertEqual(2, pqcnt.tcnt) return - def test__addPairContribution(self): - """Check Python override of PairQuantity._addPairContribution. - """ + """Check Python override of PairQuantity._addPairContribution.""" pqcnt = PQCounter() self.assertEqual(0, pqcnt(carbonzchain(0))) self.assertEqual(0, pqcnt(carbonzchain(1))) @@ -147,42 +137,36 @@ def test__addPairContribution(self): self.assertEqual(10, pqcnt(carbonzchain(5))) return - def test_optimized_evaluation(self): - """Check OPTIMIZED evaluation in Python-defined calculator class. - """ + """Check OPTIMIZED evaluation in Python-defined calculator class.""" c8 = carbonzchain(8) c9 = carbonzchain(9) pqd = PQDerived() # wrapper for evaluation using specified evaluatortype. # Use pq.eval twice to trigger optimized evaluation. - eval_as = lambda evtp, pq, stru : ( - setattr(pq, 'evaluatortype', evtp), - pq.eval(stru), pq.eval())[-1] - eval_as('BASIC', pqd, c8) - self.assertEqual('BASIC', pqd.evaluatortype) + eval_as = lambda evtp, pq, stru: (setattr(pq, "evaluatortype", evtp), pq.eval(stru), pq.eval())[-1] + eval_as("BASIC", pqd, c8) + self.assertEqual("BASIC", pqd.evaluatortype) # pqd does not support OPTIMIZED evaluation. Its use will # raise ValueError or RuntimeError for older libdiffpy. # Here we check for StandardError that covers them both. - self.assertRaises(Exception, - eval_as, 'OPTIMIZED', pqd, c8) + self.assertRaises(Exception, eval_as, "OPTIMIZED", pqd, c8) # PQCounter supports OPTIMIZED evaluation mode. ocnt = PQCounter() - ocnt.evaluatortype = 'OPTIMIZED' + ocnt.evaluatortype = "OPTIMIZED" self.assertEqual(28, ocnt(c8)) self.assertEqual(28, ocnt(c8)) - self.assertEqual('OPTIMIZED', ocnt.evaluatortypeused) + self.assertEqual("OPTIMIZED", ocnt.evaluatortypeused) self.assertEqual(36, ocnt(c9)) - self.assertEqual('OPTIMIZED', ocnt.evaluatortypeused) + self.assertEqual("OPTIMIZED", ocnt.evaluatortypeused) self.assertEqual(28, ocnt(c8)) - self.assertEqual('OPTIMIZED', ocnt.evaluatortypeused) + self.assertEqual("OPTIMIZED", ocnt.evaluatortypeused) return - def test_pickling(self): - '''check pickling and unpickling of PairQuantity. - ''' + """check pickling and unpickling of PairQuantity.""" from diffpy.srreal.tests.testutils import DerivedStructureAdapter + stru0 = DerivedStructureAdapter() self.pq.setStructure(stru0) self.assertEqual(1, stru0.cpqcount) @@ -201,12 +185,14 @@ def test_pickling(self): self.assertEqual("asdf", pcnt2.foo) return + # End of class TestPairQuantity # ---------------------------------------------------------------------------- # helper for testing PairQuantity overrides + class PQDerived(PairQuantity): tcnt = 0 @@ -215,10 +201,12 @@ def ticker(self): self.tcnt += 1 return PairQuantity.ticker(self) + # End of class PQDerived # helper for testing support for optimized evaluation + class PQCounter(PQDerived): def __init__(self): @@ -228,7 +216,7 @@ def __init__(self): return def __call__(self, structure=None): - rv, = self.eval(structure) + (rv,) = self.eval(structure) return rv def _addPairContribution(self, bnds, sumscale): @@ -244,17 +232,19 @@ def _restorePartialValue(self): del self.__stashed_value return + # End of class PQCounter + def carbonzchain(n): "Helper function that returns a z-chain of Carbon atoms." Structure = mod_structure.Structure Atom = mod_structure.Atom - rv = Structure([Atom('C', [0, 0, z]) for z in range(n)]) + rv = Structure([Atom("C", [0, 0, z]) for z in range(n)]) return rv -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() # End of file diff --git a/src/diffpy/srreal/tests/testparallel.py b/src/diffpy/srreal/tests/testparallel.py index 9373dca6..6924ab8a 100644 --- a/src/diffpy/srreal/tests/testparallel.py +++ b/src/diffpy/srreal/tests/testparallel.py @@ -10,6 +10,7 @@ from diffpy.srreal.tests.testutils import loadDiffPyStructure from diffpy.srreal.parallel import createParallelCalculator + ############################################################################## class TestRoutines(unittest.TestCase): @@ -20,11 +21,13 @@ class TestRoutines(unittest.TestCase): def setUp(self): if self.cdse is None: - type(self).cdse = loadDiffPyStructure('CdSe_cadmoselite.cif') - for a in self.cdse: a.Uisoequiv = 0.003 + type(self).cdse = loadDiffPyStructure("CdSe_cadmoselite.cif") + for a in self.cdse: + a.Uisoequiv = 0.003 if self.nickel is None: - type(self).nickel = loadDiffPyStructure('Ni.cif') - for a in self.nickel: a.Uisoequiv = 0.003 + type(self).nickel = loadDiffPyStructure("Ni.cif") + for a in self.nickel: + a.Uisoequiv = 0.003 return def tearDown(self): @@ -40,34 +43,30 @@ def pool(self): self._pool = multiprocessing.Pool(processes=self.ncpu) return self._pool - def test_parallel_evaluatortype(self): - """check handling of the evaluatortype property - """ + """check handling of the evaluatortype property""" from diffpy.srreal.pdfcalculator import PDFCalculator + pdfc = PDFCalculator() - self.assertEqual('OPTIMIZED', pdfc.evaluatortype) + self.assertEqual("OPTIMIZED", pdfc.evaluatortype) ppdfc = createParallelCalculator(pdfc, 2, map) - self.assertEqual('BASIC', ppdfc.evaluatortype) - self.assertEqual('BASIC', pdfc.evaluatortype) - ppdfc.evaluatortype = 'BASIC' - self.assertRaises(ValueError, - setattr, ppdfc, 'evaluatortype', 'OPTIMIZED') + self.assertEqual("BASIC", ppdfc.evaluatortype) + self.assertEqual("BASIC", pdfc.evaluatortype) + ppdfc.evaluatortype = "BASIC" + self.assertRaises(ValueError, setattr, ppdfc, "evaluatortype", "OPTIMIZED") return - def test_parallel_pdf(self): - """check parallel PDFCalculator - """ + """check parallel PDFCalculator""" from diffpy.srreal.pdfcalculator import PDFCalculator + pdfc = PDFCalculator() r0, g0 = pdfc(self.cdse) ppdfc1 = createParallelCalculator(PDFCalculator(), 3, map) r1, g1 = ppdfc1(self.cdse) self.assertTrue(numpy.array_equal(r0, r1)) self.assertTrue(numpy.allclose(g0, g1)) - ppdfc2 = createParallelCalculator(PDFCalculator(), - self.ncpu, self.pool.imap_unordered) + ppdfc2 = createParallelCalculator(PDFCalculator(), self.ncpu, self.pool.imap_unordered) r2, g2 = ppdfc2(self.cdse) self.assertTrue(numpy.array_equal(r0, r2)) self.assertTrue(numpy.allclose(g0, g2)) @@ -84,25 +83,23 @@ def test_parallel_pdf(self): self.assertTrue(numpy.allclose(g0a, g2a)) return - def test_parallel_bonds(self): - """check parallel BondCalculator - """ + """check parallel BondCalculator""" from diffpy.srreal.bondcalculator import BondCalculator + nickel = self.nickel bc = BondCalculator() d0 = bc(nickel) pbc1 = createParallelCalculator(BondCalculator(), 3, map) d1 = pbc1(nickel) self.assertTrue(numpy.array_equal(d0, d1)) - pbc2 = createParallelCalculator(BondCalculator(), - self.ncpu, self.pool.imap_unordered) + pbc2 = createParallelCalculator(BondCalculator(), self.ncpu, self.pool.imap_unordered) d2 = pbc2(nickel) self.assertTrue(numpy.array_equal(d0, d2)) bc.rmax = pbc1.rmax = pbc2.rmax = 2.5 for bci in (bc, pbc1, pbc2): bci.maskAllPairs(False) - bci.setPairMask(0, 'all', True) + bci.setPairMask(0, "all", True) bci.filterCone([1, 0, 0], 48) d0a = bc(nickel) self.assertEqual(8, len(d0a)) @@ -112,9 +109,10 @@ def test_parallel_bonds(self): self.assertTrue(numpy.array_equal(d0a, d2a)) return + # End of class TestRoutines -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() # End of file diff --git a/src/diffpy/srreal/tests/testpdfbaseline.py b/src/diffpy/srreal/tests/testpdfbaseline.py index 327ffded..d3fd8277 100644 --- a/src/diffpy/srreal/tests/testpdfbaseline.py +++ b/src/diffpy/srreal/tests/testpdfbaseline.py @@ -15,14 +15,14 @@ # ---------------------------------------------------------------------------- + class TestPDFBaseline(unittest.TestCase): def setUp(self): - self.linear = PDFBaseline.createByType('linear') - self.zero = PDFBaseline.createByType('zero') + self.linear = PDFBaseline.createByType("linear") + self.zero = PDFBaseline.createByType("zero") return - def tearDown(self): for tp in PDFBaseline.getRegisteredTypes(): PDFBaseline._deregisterType(tp) @@ -30,19 +30,15 @@ def tearDown(self): self.zero._registerThisType() return - def test___init__(self): - """check PDFBaseline.__init__() - """ + """check PDFBaseline.__init__()""" self.assertEqual(0.0, self.linear.slope) - self.linear._setDoubleAttr('slope', 2.0) + self.linear._setDoubleAttr("slope", 2.0) self.assertEqual(2.0, self.linear.slope) return - def test___call__(self): - """check PDFBaseline.__call__() - """ + """check PDFBaseline.__call__()""" # this is a virtual method in the base class self.assertRaises(RuntimeError, PDFBaseline().__call__, 37) self.assertEqual(0.0, self.zero(10)) @@ -51,7 +47,7 @@ def test___call__(self): self.assertEqual(0.0, self.linear(345)) self.linear.slope = -2 self.assertEqual(-7.0, self.linear(3.5)) - self.assertEqual(-2.0, self.linear._getDoubleAttr('slope')) + self.assertEqual(-2.0, self.linear._getDoubleAttr("slope")) x = numpy.arange(0, 10.001, 0.1) xb = numpy.array([(0.0, xi) for xi in x])[:, 1] self.assertTrue(xb.strides > x.strides) @@ -59,52 +55,42 @@ def test___call__(self): self.assertTrue(numpy.array_equal(-2 * x, self.linear(xb))) return - def test_clone(self): - """check PDFBaseline.clone - """ + """check PDFBaseline.clone""" # this is a virtual method in the base class self.assertRaises(RuntimeError, PDFBaseline().clone) self.linear.slope = 17 bl2 = self.linear.clone() - self.assertEqual('linear', bl2.type()) + self.assertEqual("linear", bl2.type()) self.assertEqual(17.0, bl2.slope) - self.assertEqual(17.0, bl2._getDoubleAttr('slope')) + self.assertEqual(17.0, bl2._getDoubleAttr("slope")) return - def test_create(self): - """check PDFBaseline.create - """ + """check PDFBaseline.create""" # this is a virtual method in the base class self.assertRaises(RuntimeError, PDFBaseline().create) - self.assertEqual('zero', self.zero.create().type()) - self.assertEqual('linear', self.linear.create().type()) + self.assertEqual("zero", self.zero.create().type()) + self.assertEqual("linear", self.linear.create().type()) self.linear.slope = 17 self.assertEqual(0.0, self.linear.create().slope) return - def test_type(self): - """check PDFBaseline.type - """ + """check PDFBaseline.type""" # this is a virtual method in the base class self.assertRaises(RuntimeError, PDFBaseline().type) - self.assertEqual('linear', self.linear.type()) - self.assertEqual('zero', self.zero.type()) + self.assertEqual("linear", self.linear.type()) + self.assertEqual("zero", self.zero.type()) self.assertTrue(type(self.linear) is LinearBaseline) self.assertTrue(type(self.zero) is ZeroBaseline) return - def test__aliasType(self): - """check PDFBaseline._aliasType. - """ + """check PDFBaseline._aliasType.""" self.assertRaises(ValueError, PDFBaseline.createByType, "alias") - self.assertRaises(RuntimeError, PDFBaseline._aliasType, - "invalid", "alias") - self.assertRaises(RuntimeError, PDFBaseline._aliasType, - "linear", "zero") + self.assertRaises(RuntimeError, PDFBaseline._aliasType, "invalid", "alias") + self.assertRaises(RuntimeError, PDFBaseline._aliasType, "linear", "zero") PDFBaseline._aliasType("linear", "alias") bl = PDFBaseline.createByType("alias") self.assertEqual("linear", bl.type()) @@ -114,81 +100,64 @@ def test__aliasType(self): bl1 = PDFBaseline.createByType("alias") self.assertTrue(isinstance(bl1, LinearBaseline)) # no other type can be aliased to the existing name. - self.assertRaises(RuntimeError, PDFBaseline._aliasType, - "zero", "alias") + self.assertRaises(RuntimeError, PDFBaseline._aliasType, "zero", "alias") return - def test__deregisterType(self): - """check PDFBaseline._deregisterType. - """ + """check PDFBaseline._deregisterType.""" self.assertEqual(0, PDFBaseline._deregisterType("nonexistent")) PDFBaseline._aliasType("linear", "alias") self.assertEqual(2, PDFBaseline._deregisterType("alias")) - self.assertFalse('linear' in PDFBaseline.getRegisteredTypes()) + self.assertFalse("linear" in PDFBaseline.getRegisteredTypes()) self.assertEqual(0, PDFBaseline._deregisterType("alias")) return - def test_createByType(self): - """check PDFBaseline.createByType() - """ - self.assertRaises(ValueError, PDFBaseline.createByType, 'notregistered') + """check PDFBaseline.createByType()""" + self.assertRaises(ValueError, PDFBaseline.createByType, "notregistered") return - def test_isRegisteredType(self): - """check PDFBaseline.isRegisteredType() - """ + """check PDFBaseline.isRegisteredType()""" self.assertTrue(PDFBaseline.isRegisteredType("linear")) self.assertFalse(PDFBaseline.isRegisteredType("nonexistent")) PDFBaseline._deregisterType("linear") self.assertFalse(PDFBaseline.isRegisteredType("linear")) return - def test_getAliasedTypes(self): - """check PDFBaseline.getAliasedTypes() - """ + """check PDFBaseline.getAliasedTypes()""" self.assertEqual({}, PDFBaseline.getAliasedTypes()) PDFBaseline._aliasType("linear", "foo") PDFBaseline._aliasType("linear", "bar") PDFBaseline._aliasType("linear", "linear") PDFBaseline._aliasType("bar", "foo") - self.assertEqual({'bar' : 'linear', 'foo' : 'linear'}, - PDFBaseline.getAliasedTypes()) + self.assertEqual({"bar": "linear", "foo": "linear"}, PDFBaseline.getAliasedTypes()) return - def test_getRegisteredTypes(self): - """check PDFBaseline.getRegisteredTypes - """ + """check PDFBaseline.getRegisteredTypes""" regtypes = PDFBaseline.getRegisteredTypes() self.assertTrue(2 <= len(regtypes)) - self.assertTrue('linear' in regtypes) - self.assertTrue('zero' in regtypes) + self.assertTrue("linear" in regtypes) + self.assertTrue("zero" in regtypes) return - def test_pickling(self): - '''check pickling and unpickling of PDFBaseline. - ''' + """check pickling and unpickling of PDFBaseline.""" linear = self.linear linear.slope = 11 linear2 = pickle.loads(pickle.dumps(linear)) - self.assertEqual('linear', linear2.type()) + self.assertEqual("linear", linear2.type()) self.assertEqual(11, linear2.slope) - self.assertEqual(11, linear2._getDoubleAttr('slope')) - self.assertRaises(RuntimeError, pickle_with_attr, linear, foo='bar') - self.assertRaises(RuntimeError, pickle_with_attr, self.zero, foo='bar') + self.assertEqual(11, linear2._getDoubleAttr("slope")) + self.assertRaises(RuntimeError, pickle_with_attr, linear, foo="bar") + self.assertRaises(RuntimeError, pickle_with_attr, self.zero, foo="bar") return - def test_makePDFBaseline(self): - '''check the makePDFBaseline wrapper. - ''' - pbl = makePDFBaseline('parabolabaseline', - parabola_baseline, a=1, b=2, c=3) + """check the makePDFBaseline wrapper.""" + pbl = makePDFBaseline("parabolabaseline", parabola_baseline, a=1, b=2, c=3) self.assertEqual(3, pbl(0)) self.assertEqual(6, pbl(1)) self.assertEqual(11, pbl(2)) @@ -199,59 +168,56 @@ def test_makePDFBaseline(self): self.assertEqual(0, pbl2.b) self.assertEqual(3, pbl2.c) self.assertEqual([7, 3, 28], [pbl2(x) for x in [-2, 0, 5]]) - pbl3 = PDFBaseline.createByType('parabolabaseline') + pbl3 = PDFBaseline.createByType("parabolabaseline") self.assertEqual(1, pbl3.a) self.assertEqual(2, pbl3.b) self.assertEqual(3, pbl3.c) - pbl.foo = 'bar' + pbl.foo = "bar" pbl4 = pickle.loads(pickle.dumps(pbl)) self.assertEqual([7, 3, 28], [pbl4(x) for x in [-2, 0, 5]]) - self.assertEqual('bar', pbl4.foo) + self.assertEqual("bar", pbl4.foo) # fail if this baseline type already exists. - self.assertRaises(RuntimeError, makePDFBaseline, 'linear', - parabola_baseline, a=1, b=2, c=3) - self.assertRaises(RuntimeError, makePDFBaseline, 'parabolabaseline', - parabola_baseline, a=1, b=2, c=3) + self.assertRaises(RuntimeError, makePDFBaseline, "linear", parabola_baseline, a=1, b=2, c=3) + self.assertRaises(RuntimeError, makePDFBaseline, "parabolabaseline", parabola_baseline, a=1, b=2, c=3) # check replacement of an existing type. - makePDFBaseline('linear', parabola_baseline, replace=True, - a=1, b=2, c=4) - pbl4 = PDFBaseline.createByType('linear') - self.assertEqual(set(('a', 'b', 'c')), pbl4._namesOfDoubleAttributes()) + makePDFBaseline("linear", parabola_baseline, replace=True, a=1, b=2, c=4) + pbl4 = PDFBaseline.createByType("linear") + self.assertEqual(set(("a", "b", "c")), pbl4._namesOfDoubleAttributes()) self.assertEqual(4, pbl4.c) # check baseline with no attributes - pbl5 = makePDFBaseline('myzero', lambda x: 0.0) + pbl5 = makePDFBaseline("myzero", lambda x: 0.0) self.assertEqual(0, pbl5(33)) self.assertEqual(set(), pbl5._namesOfDoubleAttributes()) return - def test_picking_owned(self): - '''verify pickling of PDFBaseline owned by PDF calculators. - ''' - pbl = makePDFBaseline('parabolabaseline', - parabola_baseline, a=1, b=2, c=3) + """verify pickling of PDFBaseline owned by PDF calculators.""" + pbl = makePDFBaseline("parabolabaseline", parabola_baseline, a=1, b=2, c=3) pbl.a = 7 - pbl.foobar = 'asdf' + pbl.foobar = "asdf" pc = PDFCalculator() pc.baseline = pbl self.assertIs(pbl, pc.baseline) pc2 = pickle.loads(pickle.dumps(pc)) pbl2 = pc2.baseline self.assertEqual(7, pbl2.a) - self.assertEqual('asdf', pbl2.foobar) - self.assertEqual('parabolabaseline', pbl2.type()) + self.assertEqual("asdf", pbl2.foobar) + self.assertEqual("parabolabaseline", pbl2.type()) return + # End of class TestPDFBaseline # ---------------------------------------------------------------------------- # function for wrapping by makePDFBaseline + def parabola_baseline(x, a, b, c): return a * x**2 + b * x + c -if __name__ == '__main__': + +if __name__ == "__main__": unittest.main() # End of file diff --git a/src/diffpy/srreal/tests/testpdfcalcobjcryst.py b/src/diffpy/srreal/tests/testpdfcalcobjcryst.py index 2193888d..4f5960a7 100644 --- a/src/diffpy/srreal/tests/testpdfcalcobjcryst.py +++ b/src/diffpy/srreal/tests/testpdfcalcobjcryst.py @@ -17,20 +17,23 @@ # helper functions + def _loadExpectedPDF(basefilename): - '''Read expected result and return a tuple of (r, g, cfgdict). - ''' - rxf = re.compile(r'[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?') + """Read expected result and return a tuple of (r, g, cfgdict).""" + rxf = re.compile(r"[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?") fullpath = datafile(basefilename) cfgdict = {} fp = open(fullpath) for line in fp: - if line[:1] != '#': break + if line[:1] != "#": + break w = line.split() - has_cfgdata = (len(w) == 4 and w[2] == '=') - if not has_cfgdata: continue + has_cfgdata = len(w) == 4 and w[2] == "=" + if not has_cfgdata: + continue cfgdict[w[1]] = w[3] - if rxf.match(w[3]): cfgdict[w[1]] = float(w[3]) + if rxf.match(w[3]): + cfgdict[w[1]] = float(w[3]) fp.close() r, g = numpy.loadtxt(fullpath, usecols=(0, 1), unpack=True) rv = (r, g, cfgdict) @@ -38,34 +41,35 @@ def _loadExpectedPDF(basefilename): def _makePDFCalculator(crst, cfgdict): - '''Return a PDFCalculator object evaluated for a pyobjcryst.Crystal crst. - ''' - pdfcargs = {k : v for k, v in cfgdict.items() - if k not in ('biso', 'type')} + """Return a PDFCalculator object evaluated for a pyobjcryst.Crystal crst.""" + pdfcargs = {k: v for k, v in cfgdict.items() if k not in ("biso", "type")} pdfc = PDFCalculator(**pdfcargs) - if 'biso' in cfgdict: + if "biso" in cfgdict: reg = crst.GetScatteringPowerRegistry() for i in range(reg.GetNb()): sp = reg.GetObj(i) - sp.SetBiso(cfgdict['biso']) - if 'type' in cfgdict: - pdfc.scatteringfactortable = cfgdict['type'] + sp.SetBiso(cfgdict["biso"]) + if "type" in cfgdict: + pdfc.scatteringfactortable = cfgdict["type"] pdfc.eval(crst) # avoid metadata override by PDFFitStructure for k, v in pdfcargs.items(): setattr(pdfc, k, v) return pdfc + # ---------------------------------------------------------------------------- + @unittest.skipUnless(has_pyobjcryst, _msg_nopyobjcryst) class TestPDFCalcObjcryst(unittest.TestCase): def _comparePDFs(self, nickname, pdfbasename, cifbasename): def setself(**kwtoset): for n, v in kwtoset.items(): - setattr(self, nickname + '_' + n, v) + setattr(self, nickname + "_" + n, v) return + r, gobs, cfg = _loadExpectedPDF(pdfbasename) setself(r=r, gobs=gobs, cfg=cfg) crst = loadObjCrystCrystal(cifbasename) @@ -76,38 +80,30 @@ def setself(**kwtoset): setself(gcalc=gcalc, mxnd=mxnd) return - def test_CdSeN(self): - '''check PDFCalculator on ObjCryst loaded CIF, neutrons - ''' - self._comparePDFs('cdsen', - 'CdSe_cadmoselite_N.fgr', 'CdSe_cadmoselite.cif') + """check PDFCalculator on ObjCryst loaded CIF, neutrons""" + self._comparePDFs("cdsen", "CdSe_cadmoselite_N.fgr", "CdSe_cadmoselite.cif") self.assertTrue(self.cdsen_mxnd < 0.01) return - def test_CdSeX(self): - '''check PDFCalculator on ObjCryst loaded CIF, xrays - ''' - self._comparePDFs('cdsex', - 'CdSe_cadmoselite_X.fgr', 'CdSe_cadmoselite.cif') + """check PDFCalculator on ObjCryst loaded CIF, xrays""" + self._comparePDFs("cdsex", "CdSe_cadmoselite_X.fgr", "CdSe_cadmoselite.cif") self.assertTrue(self.cdsex_mxnd < 0.01) return - def test_rutileaniso(self): - '''check PDFCalculator on ObjCryst loaded anisotropic rutile - ''' - self._comparePDFs('rutileaniso', - 'TiO2_rutile-fit.fgr', 'TiO2_rutile-fit.cif') + """check PDFCalculator on ObjCryst loaded anisotropic rutile""" + self._comparePDFs("rutileaniso", "TiO2_rutile-fit.fgr", "TiO2_rutile-fit.cif") self.assertTrue(self.rutileaniso_mxnd < 0.057) return + # End of class TestPDFCalcObjcryst # ---------------------------------------------------------------------------- -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() # End of file diff --git a/src/diffpy/srreal/tests/testpdfcalculator.py b/src/diffpy/srreal/tests/testpdfcalculator.py index e018d325..7c1e2645 100644 --- a/src/diffpy/srreal/tests/testpdfcalculator.py +++ b/src/diffpy/srreal/tests/testpdfcalculator.py @@ -16,17 +16,19 @@ # helper functions + def _maxNormDiff(yobs, ycalc): - '''Returned maximum difference normalized by RMS of the yobs - ''' + """Returned maximum difference normalized by RMS of the yobs""" yobsa = numpy.array(yobs) obsmax = numpy.max(numpy.fabs(yobsa)) or 1 ynmdiff = (yobsa - ycalc) / obsmax rv = max(numpy.fabs(ynmdiff)) return rv + # ---------------------------------------------------------------------------- + class TestPDFCalculator(unittest.TestCase): nickel = None @@ -35,28 +37,25 @@ class TestPDFCalculator(unittest.TestCase): def setUp(self): self.pdfcalc = PDFCalculator() if not self.nickel: - type(self).nickel = loadDiffPyStructure('Ni.stru') + type(self).nickel = loadDiffPyStructure("Ni.stru") if not self.tio2rutile: - type(self).tio2rutile = ( - loadDiffPyStructure('TiO2_rutile-fit.stru')) + type(self).tio2rutile = loadDiffPyStructure("TiO2_rutile-fit.stru") return def tearDown(self): return def test___init__(self): - """check PDFCalculator.__init__() - """ + """check PDFCalculator.__init__()""" pdfc = PDFCalculator(qmin=13, rmin=4, rmax=99) self.assertEqual(13, pdfc.qmin) self.assertEqual(4, pdfc.rmin) self.assertEqual(99, pdfc.rmax) - self.assertEqual(99, pdfc._getDoubleAttr('rmax')) + self.assertEqual(99, pdfc._getDoubleAttr("rmax")) return def test___call__(self): - """Check PDFCalculator.__call__() - """ + """Check PDFCalculator.__call__()""" r0, g0 = self.pdfcalc(self.tio2rutile, rmin=2) self.assertEqual(2.0, r0[0]) r1, g1 = self.pdfcalc(self.tio2rutile, scale=7) @@ -65,7 +64,7 @@ def test___call__(self): rutile2 = self.tio2rutile.copy() # work around Structure bug of shared pdffit dictionary rutile2.pdffit = dict(self.tio2rutile.pdffit) - rutile2.pdffit['spdiameter'] = 5.0 + rutile2.pdffit["spdiameter"] = 5.0 r3, g3 = self.pdfcalc(rutile2) self.assertEqual(0.0, sum(g3[r3 >= 5] ** 2)) r4, g4 = self.pdfcalc(rutile2, scale=1, spdiameter=0) @@ -74,53 +73,47 @@ def test___call__(self): return def test__getDoubleAttr(self): - """check PDFCalculator._getDoubleAttr() - """ + """check PDFCalculator._getDoubleAttr()""" gdba = self.pdfcalc._getDoubleAttr - self.assertEqual(1.0, gdba('scale')) - self.assertEqual(0.0, gdba('qdamp')) - self.assertRaises(Exception, gdba, 'notanattribute') + self.assertEqual(1.0, gdba("scale")) + self.assertEqual(0.0, gdba("qdamp")) + self.assertRaises(Exception, gdba, "notanattribute") return def test__hasDoubleAttr(self): - """check PDFCalculator._hasDoubleAttr() - """ - self.assertTrue(self.pdfcalc._hasDoubleAttr('scale')) - self.assertFalse(self.pdfcalc._hasDoubleAttr('notanattribute')) + """check PDFCalculator._hasDoubleAttr()""" + self.assertTrue(self.pdfcalc._hasDoubleAttr("scale")) + self.assertFalse(self.pdfcalc._hasDoubleAttr("notanattribute")) return def test__namesOfDoubleAttributes(self): - """check PDFCalculator._namesOfDoubleAttributes() - """ + """check PDFCalculator._namesOfDoubleAttributes()""" self.assertTrue(type(self.pdfcalc._namesOfDoubleAttributes()) is set) - self.assertTrue('qmax' in self.pdfcalc._namesOfDoubleAttributes()) + self.assertTrue("qmax" in self.pdfcalc._namesOfDoubleAttributes()) return def test__setDoubleAttr(self): - """check PDFCalculator._setDoubleAttr() - """ + """check PDFCalculator._setDoubleAttr()""" gdba = self.pdfcalc._getDoubleAttr sdba = self.pdfcalc._setDoubleAttr - self.assertEqual(0.0, gdba('rmin')) - sdba('rmin', 3.0) - self.assertEqual(3.0, gdba('rmin')) + self.assertEqual(0.0, gdba("rmin")) + sdba("rmin", 3.0) + self.assertEqual(3.0, gdba("rmin")) return def test_eval_nickel(self): - """check PDFCalculator.eval() on simple Nickel data - """ - fnipf2 = datafile('Ni-fit.fgr') + """check PDFCalculator.eval() on simple Nickel data""" + fnipf2 = datafile("Ni-fit.fgr") gpf2 = numpy.loadtxt(fnipf2, usecols=(1,)) - self.pdfcalc._setDoubleAttr('rmax', 10.0001) + self.pdfcalc._setDoubleAttr("rmax", 10.0001) self.pdfcalc.eval(self.nickel) gcalc = self.pdfcalc.pdf self.assertTrue(_maxNormDiff(gpf2, gcalc) < 0.0091) return def test_eval_rutile(self): - """check PDFCalculator.eval() on anisotropic rutile data - """ - frutile = datafile('TiO2_rutile-fit.fgr') + """check PDFCalculator.eval() on anisotropic rutile data""" + frutile = datafile("TiO2_rutile-fit.fgr") gpf2 = numpy.loadtxt(frutile, usecols=(1,)) # configure calculator according to testdata/TiO2_ruitile-fit.fgr self.pdfcalc.qmax = 26 @@ -143,8 +136,7 @@ def test_eval_rutile(self): return def test_partial_pdfs(self): - """Check calculation of partial PDFs. - """ + """Check calculation of partial PDFs.""" pdfc = self.pdfcalc pdfc.rstep = 0.1 rutile = self.tio2rutile @@ -208,8 +200,7 @@ def test_partial_pdfs(self): return def test_full_mask(self): - '''Test PDFCalculator for a fully masked structure. - ''' + """Test PDFCalculator for a fully masked structure.""" pdfc = self.pdfcalc pdfc.rstep = 0.1 rutile = self.tio2rutile @@ -225,8 +216,7 @@ def test_full_mask(self): return def test_zero_mask(self): - '''Test PDFCalculator with a totally masked out structure. - ''' + """Test PDFCalculator with a totally masked out structure.""" pdfc = self.pdfcalc pdfc.rstep = 0.1 rutile = self.tio2rutile @@ -241,12 +231,11 @@ def test_zero_mask(self): return def test_pickling(self): - '''check pickling and unpickling of PDFCalculator. - ''' + """check pickling and unpickling of PDFCalculator.""" pdfc = self.pdfcalc - pdfc.scatteringfactortable = 'N' - pdfc.scatteringfactortable.setCustomAs('Na', 'Na', 7) - pdfc.addEnvelope('sphericalshape') + pdfc.scatteringfactortable = "N" + pdfc.scatteringfactortable.setCustomAs("Na", "Na", 7) + pdfc.addEnvelope("sphericalshape") pdfc.delta1 = 0.2 pdfc.delta2 = 0.3 pdfc.maxextension = 10.1 @@ -266,20 +255,17 @@ def test_pickling(self): sft = pdfc.scatteringfactortable sft1 = pdfc1.scatteringfactortable self.assertEqual(sft.type(), sft1.type()) - self.assertEqual(7.0, sft1.lookup('Na')) + self.assertEqual(7.0, sft1.lookup("Na")) for a in pdfc._namesOfDoubleAttributes(): self.assertEqual(getattr(pdfc, a), getattr(pdfc1, a)) - self.assertEqual(13.3, - pdfc1.getEnvelope('sphericalshape').spdiameter) - self.assertEqual(pdfc._namesOfDoubleAttributes(), - pdfc1._namesOfDoubleAttributes()) + self.assertEqual(13.3, pdfc1.getEnvelope("sphericalshape").spdiameter) + self.assertEqual(pdfc._namesOfDoubleAttributes(), pdfc1._namesOfDoubleAttributes()) self.assertEqual(pdfc.usedenvelopetypes, pdfc1.usedenvelopetypes) - self.assertRaises(RuntimeError, pickle_with_attr, pdfc, foo='bar') + self.assertRaises(RuntimeError, pickle_with_attr, pdfc, foo="bar") return def test_mask_pickling(self): - '''Check if mask gets properly pickled and restored. - ''' + """Check if mask gets properly pickled and restored.""" self.pdfcalc.maskAllPairs(False) self.pdfcalc.setPairMask(0, 1, True) self.assertTrue(False is self.pdfcalc.getPairMask(0, 0)) @@ -290,9 +276,9 @@ def test_mask_pickling(self): return def test_pickling_derived_structure(self): - '''check pickling of PDFCalculator with DerivedStructureAdapter. - ''' + """check pickling of PDFCalculator with DerivedStructureAdapter.""" from diffpy.srreal.tests.testutils import DerivedStructureAdapter + pdfc = self.pdfcalc stru0 = DerivedStructureAdapter() pdfc.setStructure(stru0) @@ -307,20 +293,19 @@ def test_pickling_derived_structure(self): return def test_envelopes(self): - '''Check the envelopes property. - ''' + """Check the envelopes property.""" from diffpy.srreal.pdfenvelope import PDFEnvelope + pc = self.pdfcalc self.assertTrue(len(pc.envelopes) > 0) pc.clearEnvelopes() self.assertEqual(0, len(pc.envelopes)) - pc.addEnvelope(PDFEnvelope.createByType('scale')) + pc.addEnvelope(PDFEnvelope.createByType("scale")) self.assertEqual(1, len(pc.envelopes)) - self.assertEqual('scale', pc.envelopes[0].type()) - pc.envelopes += ('qresolution',) - self.assertEqual(('qresolution', 'scale'), pc.usedenvelopetypes) - self.assertTrue(all([isinstance(e, PDFEnvelope) - for e in pc.envelopes])) + self.assertEqual("scale", pc.envelopes[0].type()) + pc.envelopes += ("qresolution",) + self.assertEqual(("qresolution", "scale"), pc.usedenvelopetypes) + self.assertTrue(all([isinstance(e, PDFEnvelope) for e in pc.envelopes])) return @@ -353,41 +338,40 @@ def test_envelopes(self): # ---------------------------------------------------------------------------- + class TestFFTRoutines(unittest.TestCase): def test_fft_conversions(self): - """Verify conversions of arguments in fftgtof function. - """ - fnipf2 = datafile('Ni-fit.fgr') + """Verify conversions of arguments in fftgtof function.""" + fnipf2 = datafile("Ni-fit.fgr") data = numpy.loadtxt(fnipf2) dr = 0.01 - fq0, dq0 = fftgtof(data[:,1], dr) - fq1, dq1 = fftgtof(data[:,1].copy(), dr) - fq2, dq2 = fftgtof(list(data[:,1]), dr) + fq0, dq0 = fftgtof(data[:, 1], dr) + fq1, dq1 = fftgtof(data[:, 1].copy(), dr) + fq2, dq2 = fftgtof(list(data[:, 1]), dr) self.assertTrue(numpy.array_equal(fq0, fq1)) self.assertTrue(numpy.array_equal(fq0, fq2)) self.assertEqual(dq0, dq1) self.assertEqual(dq0, dq2) return - def test_fft_roundtrip(self): - """Check if forward and inverse transformation recover the input. - """ - fnipf2 = datafile('Ni-fit.fgr') + """Check if forward and inverse transformation recover the input.""" + fnipf2 = datafile("Ni-fit.fgr") g0 = numpy.loadtxt(fnipf2, usecols=(1,)) dr0 = 0.01 fq, dq = fftgtof(g0, dr0) g1, dr1 = fftftog(fq, dq) self.assertAlmostEqual(dr0, dr1, 12) - self.assertTrue(numpy.allclose(g0, g1[:g0.size])) + self.assertTrue(numpy.allclose(g0, g1[: g0.size])) return + # End of class TestFFTRoutines # ---------------------------------------------------------------------------- -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() # End of file diff --git a/src/diffpy/srreal/tests/testpdfenvelope.py b/src/diffpy/srreal/tests/testpdfenvelope.py index 48751290..7adb1060 100644 --- a/src/diffpy/srreal/tests/testpdfenvelope.py +++ b/src/diffpy/srreal/tests/testpdfenvelope.py @@ -16,32 +16,28 @@ # ---------------------------------------------------------------------------- + class TestPDFEnvelope(unittest.TestCase): def setUp(self): - self.fstepcut = PDFEnvelope.createByType('stepcut') + self.fstepcut = PDFEnvelope.createByType("stepcut") self.fstepcut.stepcut = 5 - self.fscale = PDFEnvelope.createByType('scale') + self.fscale = PDFEnvelope.createByType("scale") return - def tearDown(self): - PDFEnvelope._deregisterType('parabolaenvelope') + PDFEnvelope._deregisterType("parabolaenvelope") return - def test___init__(self): - """check PDFEnvelope.__init__() - """ + """check PDFEnvelope.__init__()""" self.assertEqual(1.0, self.fscale.scale) - self.fscale._setDoubleAttr('scale', 2.0) + self.fscale._setDoubleAttr("scale", 2.0) self.assertEqual(2.0, self.fscale.scale) return - def test___call__(self): - """check PDFEnvelope.__call__() - """ + """check PDFEnvelope.__call__()""" x = numpy.arange(0, 9.1, 0.3) xb = numpy.array([(0.0, xi) for xi in x])[:, 1] self.assertTrue(xb.strides > x.strides) @@ -59,76 +55,61 @@ def test___call__(self): self.assertEqual(-2.0, self.fscale(3.5)) return - def test_clone(self): - """check PDFEnvelope.clone - """ + """check PDFEnvelope.clone""" # this is a virtual method in the base class self.assertRaises(RuntimeError, PDFEnvelope().clone) self.fstepcut.stepcut = 17 e2 = self.fstepcut.clone() - self.assertEqual('stepcut', e2.type()) + self.assertEqual("stepcut", e2.type()) self.assertEqual(17.0, e2.stepcut) - self.assertEqual(17.0, e2._getDoubleAttr('stepcut')) + self.assertEqual(17.0, e2._getDoubleAttr("stepcut")) return - def test_create(self): - """check PDFEnvelope.create - """ + """check PDFEnvelope.create""" # this is a virtual method in the base class self.assertRaises(RuntimeError, PDFEnvelope().create) - self.assertEqual('stepcut', self.fstepcut.create().type()) - self.assertEqual('scale', self.fscale.create().type()) + self.assertEqual("stepcut", self.fstepcut.create().type()) + self.assertEqual("scale", self.fscale.create().type()) self.fstepcut.stepcut = 17 self.assertEqual(0.0, self.fstepcut.create().stepcut) return - def test_type(self): - """check PDFEnvelope.type - """ + """check PDFEnvelope.type""" # this is a virtual method in the base class self.assertRaises(RuntimeError, PDFEnvelope().type) - self.assertEqual('stepcut', self.fstepcut.type()) - self.assertEqual('scale', self.fscale.type()) + self.assertEqual("stepcut", self.fstepcut.type()) + self.assertEqual("scale", self.fscale.type()) return - def test_createByType(self): - """check PDFEnvelope.createByType() - """ - self.assertRaises(ValueError, PDFEnvelope.createByType, 'notregistered') + """check PDFEnvelope.createByType()""" + self.assertRaises(ValueError, PDFEnvelope.createByType, "notregistered") return - def test_getRegisteredTypes(self): - """check PDFEnvelope.getRegisteredTypes - """ + """check PDFEnvelope.getRegisteredTypes""" regtypes = PDFEnvelope.getRegisteredTypes() self.assertTrue(2 <= len(regtypes)) - self.assertTrue('stepcut' in regtypes) - self.assertTrue('scale' in regtypes) + self.assertTrue("stepcut" in regtypes) + self.assertTrue("scale" in regtypes) return - def test_pickling(self): - '''check pickling and unpickling of PDFEnvelope. - ''' + """check pickling and unpickling of PDFEnvelope.""" stp = self.fstepcut stp.stepcut = 11 stp2 = pickle.loads(pickle.dumps(stp)) - self.assertEqual('stepcut', stp2.type()) + self.assertEqual("stepcut", stp2.type()) self.assertEqual(11, stp2.stepcut) - self.assertEqual(11, stp2._getDoubleAttr('stepcut')) + self.assertEqual(11, stp2._getDoubleAttr("stepcut")) return - def test_makePDFEnvelope(self): - '''check the makePDFEnvelope wrapper. - ''' - pbl = makePDFEnvelope('parabolaenvelope', - parabola_envelope, a=1, b=2, c=3) + """check the makePDFEnvelope wrapper.""" + pbl = makePDFEnvelope("parabolaenvelope", parabola_envelope, a=1, b=2, c=3) self.assertEqual(3, pbl(0)) self.assertEqual(6, pbl(1)) self.assertEqual(11, pbl(2)) @@ -139,25 +120,22 @@ def test_makePDFEnvelope(self): self.assertEqual(0, pbl2.b) self.assertEqual(3, pbl2.c) self.assertEqual([7, 3, 28], [pbl2(x) for x in [-2, 0, 5]]) - pbl3 = PDFEnvelope.createByType('parabolaenvelope') + pbl3 = PDFEnvelope.createByType("parabolaenvelope") self.assertEqual(1, pbl3.a) self.assertEqual(2, pbl3.b) self.assertEqual(3, pbl3.c) pbl3.a = 0 - pbl3.foo = 'asdf' + pbl3.foo = "asdf" pbl3cp = pickle.loads(pickle.dumps(pbl3)) self.assertEqual(0, pbl3cp.a) - self.assertEqual('asdf', pbl3cp.foo) + self.assertEqual("asdf", pbl3cp.foo) return - def test_picking_owned(self): - '''verify pickling of envelopes owned by PDF calculators. - ''' - pbl = makePDFEnvelope('parabolaenvelope', - parabola_envelope, a=1, b=2, c=3) + """verify pickling of envelopes owned by PDF calculators.""" + pbl = makePDFEnvelope("parabolaenvelope", parabola_envelope, a=1, b=2, c=3) pbl.a = 7 - pbl.foobar = 'asdf' + pbl.foobar = "asdf" pc = PDFCalculator() pc.envelopes = (pbl,) dbpc = DebyePDFCalculator() @@ -173,117 +151,119 @@ def test_picking_owned(self): dbpc2 = pickle.loads(pickle.dumps(dbpc)) self.assertEqual(3.5, pc2.scale) self.assertEqual(3.5, dbpc2.scale) - pblcopies = [pc2.getEnvelope("parabolaenvelope"), - dbpc2.getEnvelope("parabolaenvelope")] + pblcopies = [pc2.getEnvelope("parabolaenvelope"), dbpc2.getEnvelope("parabolaenvelope")] for pbl2 in pblcopies: self.assertEqual(7, pbl2.a) - self.assertEqual('asdf', pbl2.foobar) - self.assertEqual('parabolaenvelope', pbl2.type()) + self.assertEqual("asdf", pbl2.foobar) + self.assertEqual("parabolaenvelope", pbl2.type()) return + # ---------------------------------------------------------------------------- + class TestQResolutionEnvelope(unittest.TestCase): def setUp(self): self.evlp = QResolutionEnvelope() return - def test_type(self): - self.assertEqual('qresolution', self.evlp.type()) - self.assertTrue(hasattr(self.evlp, 'qdamp')) + self.assertEqual("qresolution", self.evlp.type()) + self.assertTrue(hasattr(self.evlp, "qdamp")) return - def test_pickling(self): evlp = self.evlp evlp.qdamp = 3 evlp2 = pickle.loads(pickle.dumps(evlp)) self.assertEqual(QResolutionEnvelope, type(evlp2)) self.assertEqual(3, evlp2.qdamp) - self.assertRaises(RuntimeError, pickle_with_attr, evlp, foo='bar') + self.assertRaises(RuntimeError, pickle_with_attr, evlp, foo="bar") return + # ---------------------------------------------------------------------------- + class TestScaleEnvelope(unittest.TestCase): def setUp(self): self.evlp = ScaleEnvelope() return - def test_type(self): - self.assertEqual('scale', self.evlp.type()) - self.assertTrue(hasattr(self.evlp, 'scale')) + self.assertEqual("scale", self.evlp.type()) + self.assertTrue(hasattr(self.evlp, "scale")) return - def test_pickling(self): evlp = self.evlp evlp.scale = 3 evlp2 = pickle.loads(pickle.dumps(evlp)) self.assertEqual(ScaleEnvelope, type(evlp2)) self.assertEqual(3, evlp2.scale) - self.assertRaises(RuntimeError, pickle_with_attr, evlp, foo='bar') + self.assertRaises(RuntimeError, pickle_with_attr, evlp, foo="bar") return + # ---------------------------------------------------------------------------- + class TestSphericalShapeEnvelope(unittest.TestCase): def setUp(self): self.evlp = SphericalShapeEnvelope() return - def test_type(self): - self.assertEqual('sphericalshape', self.evlp.type()) - self.assertTrue(hasattr(self.evlp, 'spdiameter')) + self.assertEqual("sphericalshape", self.evlp.type()) + self.assertTrue(hasattr(self.evlp, "spdiameter")) return - def test_pickling(self): evlp = self.evlp evlp.spdiameter = 3 evlp2 = pickle.loads(pickle.dumps(evlp)) self.assertEqual(SphericalShapeEnvelope, type(evlp2)) self.assertEqual(3, evlp2.spdiameter) - self.assertRaises(RuntimeError, pickle_with_attr, evlp, foo='bar') + self.assertRaises(RuntimeError, pickle_with_attr, evlp, foo="bar") return + # ---------------------------------------------------------------------------- + class TestStepCutEnvelope(unittest.TestCase): def setUp(self): self.evlp = StepCutEnvelope() return - def test_type(self): - self.assertEqual('stepcut', self.evlp.type()) - self.assertTrue(hasattr(self.evlp, 'stepcut')) + self.assertEqual("stepcut", self.evlp.type()) + self.assertTrue(hasattr(self.evlp, "stepcut")) return - def test_pickling(self): evlp = self.evlp evlp.stepcut = 3 evlp2 = pickle.loads(pickle.dumps(evlp)) self.assertEqual(StepCutEnvelope, type(evlp2)) self.assertEqual(3, evlp2.stepcut) - self.assertRaises(RuntimeError, pickle_with_attr, evlp, foo='bar') + self.assertRaises(RuntimeError, pickle_with_attr, evlp, foo="bar") return + # ---------------------------------------------------------------------------- + def parabola_envelope(x, a, b, c): - 'parabola function for wrapping by makePDFEnvelope' + "parabola function for wrapping by makePDFEnvelope" return a * x**2 + b * x + c -if __name__ == '__main__': + +if __name__ == "__main__": unittest.main() # End of file diff --git a/src/diffpy/srreal/tests/testpeakprofile.py b/src/diffpy/srreal/tests/testpeakprofile.py index 50f86ae3..d187e969 100644 --- a/src/diffpy/srreal/tests/testpeakprofile.py +++ b/src/diffpy/srreal/tests/testpeakprofile.py @@ -15,65 +15,54 @@ # ---------------------------------------------------------------------------- + class TestPeakProfile(unittest.TestCase): def setUp(self): - self.pkgauss = PeakProfile.createByType('gaussian') - self.pkcropped = PeakProfile.createByType('croppedgaussian') + self.pkgauss = PeakProfile.createByType("gaussian") + self.pkcropped = PeakProfile.createByType("croppedgaussian") return - def tearDown(self): return - def test___init__(self): - """check PeakProfile.__init__() - """ + """check PeakProfile.__init__()""" self.assertNotEqual(0.0, self.pkgauss.peakprecision) - self.assertEqual(self.pkgauss.peakprecision, - self.pkcropped.peakprecision) - self.pkgauss._setDoubleAttr('peakprecision', 0.01) + self.assertEqual(self.pkgauss.peakprecision, self.pkcropped.peakprecision) + self.pkgauss._setDoubleAttr("peakprecision", 0.01) self.assertEqual(0.01, self.pkgauss.peakprecision) return - def test_create(self): - """check PeakProfile.create - """ + """check PeakProfile.create""" # this is a virtual method in the base class self.assertRaises(RuntimeError, PeakProfile().create) - self.assertEqual('gaussian', self.pkgauss.create().type()) + self.assertEqual("gaussian", self.pkgauss.create().type()) self.pkgauss.peakprecision = 0.007 self.assertNotEqual(0.007, self.pkgauss.create().peakprecision) return - def test_clone(self): - """check PeakProfile.clone - """ + """check PeakProfile.clone""" # this is a virtual method in the base class self.assertRaises(RuntimeError, PeakProfile().clone) self.pkgauss.peakprecision = 0.0003 pkg2 = self.pkgauss.clone() - self.assertEqual('gaussian', pkg2.type()) + self.assertEqual("gaussian", pkg2.type()) self.assertEqual(0.0003, pkg2.peakprecision) - self.assertEqual(0.0003, pkg2._getDoubleAttr('peakprecision')) + self.assertEqual(0.0003, pkg2._getDoubleAttr("peakprecision")) return - def test_type(self): - """check PeakProfile.type - """ + """check PeakProfile.type""" # this is a virtual method in the base class self.assertRaises(RuntimeError, PeakProfile().type) - self.assertEqual('croppedgaussian', self.pkcropped.type()) + self.assertEqual("croppedgaussian", self.pkcropped.type()) return - def test___call__(self): - """check PeakProfile.__call__() - """ + """check PeakProfile.__call__()""" ymx = self.pkgauss(0.0, 1) yhalflo = self.pkgauss(-0.5, 1) yhalfhi = self.pkgauss(-0.5, 1) @@ -83,11 +72,10 @@ def test___call__(self): self.assertNotEqual(0, self.pkgauss(10, 1)) return - def test_ticker(self): - """check PeakProfile.ticker() - """ + """check PeakProfile.ticker()""" from diffpy.srreal.eventticker import EventTicker + et0 = EventTicker(self.pkgauss.ticker()) self.pkgauss.peakprecision = 0.003 et1 = self.pkgauss.ticker() @@ -95,10 +83,8 @@ def test_ticker(self): self.assertTrue(et0 < et1) return - def test_ticker_override(self): - """check method override for PeakProfile.ticker in a derived class. - """ + """check method override for PeakProfile.ticker in a derived class.""" pkf = MySawTooth() self.assertEqual(0, pkf.tcnt) et0 = pkf.ticker() @@ -116,33 +102,30 @@ def test_ticker_override(self): self.assertEqual(2, pkf.tcnt) return - def test_getRegisteredTypes(self): - """check PeakProfile.getRegisteredTypes - """ + """check PeakProfile.getRegisteredTypes""" regtypes = PeakProfile.getRegisteredTypes() self.assertTrue(2 <= len(regtypes)) - self.assertTrue(regtypes.issuperset( - ['gaussian', 'croppedgaussian'])) + self.assertTrue(regtypes.issuperset(["gaussian", "croppedgaussian"])) return - def test_pickling(self): - '''check pickling and unpickling of PeakProfile. - ''' + """check pickling and unpickling of PeakProfile.""" pkg = self.pkgauss pkg.peakprecision = 0.0011 pkg2 = pickle.loads(pickle.dumps(pkg)) - self.assertEqual('gaussian', pkg2.type()) + self.assertEqual("gaussian", pkg2.type()) self.assertEqual(0.0011, pkg2.peakprecision) - self.assertEqual(0.0011, pkg2._getDoubleAttr('peakprecision')) - self.assertRaises(RuntimeError, pickle_with_attr, pkg, foo='bar') + self.assertEqual(0.0011, pkg2._getDoubleAttr("peakprecision")) + self.assertRaises(RuntimeError, pickle_with_attr, pkg, foo="bar") pkc = self.pkcropped - self.assertRaises(RuntimeError, pickle_with_attr, pkc, foo='bar') + self.assertRaises(RuntimeError, pickle_with_attr, pkc, foo="bar") return + # ---------------------------------------------------------------------------- + class MySawTooth(PeakProfile): "Helper class for testing PeakProfile." @@ -154,9 +137,11 @@ def create(self): def clone(self): import copy + return copy.copy(self) tcnt = 0 + def ticker(self): self.tcnt += 1 return PeakProfile.ticker(self) @@ -164,7 +149,8 @@ def ticker(self): def __call__(self, x, fwhm): w = 1.0 * fwhm rv = (1 - abs(x) / w) / (1.0 * w) - if rv < 0: rv = 0 + if rv < 0: + rv = 0 return rv def xboundlo(self, fwhm): @@ -173,67 +159,64 @@ def xboundlo(self, fwhm): def xboundhi(self, fwhm): return +fwhm + # End of class MySawTooth + class TestPeakProfileOwner(unittest.TestCase): def setUp(self): MySawTooth()._registerThisType() self.pc = PDFCalculator() - self.pc.peakprofile = 'mysawtooth' + self.pc.peakprofile = "mysawtooth" self.pkf = self.pc.peakprofile self.pkf.peakprecision = 0.0017 return - def tearDown(self): PeakProfile._deregisterType(self.pkf.type()) return - def test_pkftype(self): - '''Check type of the owned PeakProfile instance. - ''' - self.assertEqual('mysawtooth', self.pc.peakprofile.type()) + """Check type of the owned PeakProfile instance.""" + self.assertEqual("mysawtooth", self.pc.peakprofile.type()) return - def test_custom_peakprofile(self): "Check if our MySawTooth is indeed applied." - c2 = mod_structure.Structure(2 * [mod_structure.Atom('C')]) + c2 = mod_structure.Structure(2 * [mod_structure.Atom("C")]) c2.z = [0, 1] c2.Uisoequiv = 0.01 r, g = self.pc(c2) k = g.argmax() self.assertEqual(1, r[k]) - self.assertTrue(numpy.allclose(numpy.diff(g[k - 5:k], 2), 0)) - self.assertTrue(numpy.allclose(numpy.diff(g[k:k + 5], 2), 0)) + self.assertTrue(numpy.allclose(numpy.diff(g[k - 5 : k], 2), 0)) + self.assertTrue(numpy.allclose(numpy.diff(g[k : k + 5], 2), 0)) pkf2 = self.pc.peakprofile.clone() self.assertTrue(isinstance(pkf2, MySawTooth)) self.assertEqual(0.0017, pkf2.peakprecision) return - def test_pickling(self): - '''Check pickling of an owned PeakProfile instance. - ''' + """Check pickling of an owned PeakProfile instance.""" pc1 = pickle.loads(pickle.dumps(self.pc)) self.pkf.peakprecision = 0.0003 - self.pkf.foo = 'bar' + self.pkf.foo = "bar" pc2 = pickle.loads(pickle.dumps(self.pc)) - self.assertEqual('mysawtooth', pc1.peakprofile.type()) + self.assertEqual("mysawtooth", pc1.peakprofile.type()) self.assertEqual(0.0017, pc1.peakprofile.peakprecision) self.assertEqual(0.0017, pc1.peakprecision) - self.assertFalse(hasattr(pc1.peakprofile, 'foo')) - self.assertEqual('mysawtooth', pc2.peakprofile.type()) + self.assertFalse(hasattr(pc1.peakprofile, "foo")) + self.assertEqual("mysawtooth", pc2.peakprofile.type()) self.assertEqual(0.0003, pc2.peakprofile.peakprecision) self.assertEqual(0.0003, pc2.peakprecision) - self.assertEqual('bar', pc2.peakprofile.foo) + self.assertEqual("bar", pc2.peakprofile.foo) return + # ---------------------------------------------------------------------------- -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() # End of file diff --git a/src/diffpy/srreal/tests/testpeakwidthmodel.py b/src/diffpy/srreal/tests/testpeakwidthmodel.py index 830b3bdb..18a00465 100644 --- a/src/diffpy/srreal/tests/testpeakwidthmodel.py +++ b/src/diffpy/srreal/tests/testpeakwidthmodel.py @@ -15,24 +15,23 @@ # ---------------------------------------------------------------------------- + class TestPeakWidthModel(unittest.TestCase): tio2stru = None tio2adpt = None def setUp(self): - self.pwconst = PeakWidthModel.createByType('constant') + self.pwconst = PeakWidthModel.createByType("constant") self.pwconst.width = 2 if self.tio2stru is None: - self.tio2stru = loadDiffPyStructure('rutile.cif') + self.tio2stru = loadDiffPyStructure("rutile.cif") self.tio2adpt = createStructureAdapter(self.tio2stru) return - def tearDown(self): return - def _genbonds(self, rmin, rmax): "Return ready-to-use BondGenerator for rutile." bnds = self.tio2adpt.createBondGenerator() @@ -41,63 +40,52 @@ def _genbonds(self, rmin, rmax): bnds.rewind() return bnds - def test___init__(self): - """check PeakWidthModel.__init__() - """ + """check PeakWidthModel.__init__()""" self.assertEqual(2.0, self.pwconst.width) - self.pwconst._setDoubleAttr('width', 3.0) + self.pwconst._setDoubleAttr("width", 3.0) self.assertEqual(3.0, self.pwconst.width) return - def test_create(self): - """check PeakWidthModel.create - """ + """check PeakWidthModel.create""" # this is a virtual method in the base class self.assertRaises(RuntimeError, PeakWidthModel().create) - self.assertEqual('constant', self.pwconst.create().type()) + self.assertEqual("constant", self.pwconst.create().type()) self.pwconst.width = 17 self.assertEqual(0.0, self.pwconst.create().width) return - def test_clone(self): - """check PeakWidthModel.clone - """ + """check PeakWidthModel.clone""" # this is a virtual method in the base class self.assertRaises(RuntimeError, PeakWidthModel().clone) self.pwconst.width = 17 pwc2 = self.pwconst.clone() - self.assertEqual('constant', pwc2.type()) + self.assertEqual("constant", pwc2.type()) self.assertEqual(17.0, pwc2.width) - self.assertEqual(17.0, pwc2._getDoubleAttr('width')) + self.assertEqual(17.0, pwc2._getDoubleAttr("width")) return - def test_type(self): - """check PeakWidthModel.type - """ + """check PeakWidthModel.type""" # this is a virtual method in the base class self.assertRaises(RuntimeError, PeakWidthModel().type) - self.assertEqual('constant', self.pwconst.type()) + self.assertEqual("constant", self.pwconst.type()) return - def test_calculate(self): - """check PeakWidthModel.calculate() - """ + """check PeakWidthModel.calculate()""" pwm = PeakWidthModel() bnds = self._genbonds(1, 2) self.assertRaises(RuntimeError, pwm.calculate, bnds) self.assertEqual(2.0, self.pwconst.calculate(bnds)) return - def test_isowidths(self): - """check ConstantPeakWidth properties bisowidth, uisowidth. - """ + """check ConstantPeakWidth properties bisowidth, uisowidth.""" from numpy import pi + cnpw = self.pwconst dwpw = DebyeWallerPeakWidth() bnds = self._genbonds(1, 2) @@ -107,21 +95,17 @@ def test_isowidths(self): self.assertAlmostEqual(cnpw.bisowidth, 8 * pi**2 * cnpw.uisowidth, 12) return - def test_maxWidth(self): - """check PeakWidthModel.maxWidth() - """ - self.assertRaises(RuntimeError, PeakWidthModel().maxWidth, - self.tio2adpt, 0, 10) + """check PeakWidthModel.maxWidth()""" + self.assertRaises(RuntimeError, PeakWidthModel().maxWidth, self.tio2adpt, 0, 10) self.assertEqual(2.0, self.pwconst.maxWidth(self.tio2adpt, 0, 10)) self.assertEqual(2.0, self.pwconst.maxWidth(self.tio2stru, 0, 10)) return - def test_ticker(self): - """check PeakWidthModel.ticker() - """ + """check PeakWidthModel.ticker()""" from diffpy.srreal.eventticker import EventTicker + et0 = EventTicker(self.pwconst.ticker()) self.pwconst.width = 3 et1 = self.pwconst.ticker() @@ -129,10 +113,8 @@ def test_ticker(self): self.assertTrue(et0 < et1) return - def test_ticker_override(self): - """check PeakWidthModel.ticker override in a Python-derived class. - """ + """check PeakWidthModel.ticker override in a Python-derived class.""" pwm = MyPWM() self.assertEqual(0, pwm.tcnt) et0 = pwm.ticker() @@ -150,76 +132,67 @@ def test_ticker_override(self): self.assertEqual(2, pwm.tcnt) return - def test_getRegisteredTypes(self): - """check PeakWidthModel.getRegisteredTypes - """ + """check PeakWidthModel.getRegisteredTypes""" regtypes = PeakWidthModel.getRegisteredTypes() self.assertTrue(3 <= len(regtypes)) - self.assertTrue(regtypes.issuperset( - ['constant', 'debye-waller', 'jeong'])) + self.assertTrue(regtypes.issuperset(["constant", "debye-waller", "jeong"])) return - def test_pickling(self): - '''check pickling and unpickling of PeakWidthModel. - ''' + """check pickling and unpickling of PeakWidthModel.""" pwc = self.pwconst pwc.width = 11 pwc2 = pickle.loads(pickle.dumps(pwc)) - self.assertEqual('constant', pwc2.type()) + self.assertEqual("constant", pwc2.type()) self.assertEqual(11, pwc2.width) - self.assertEqual(11, pwc2._getDoubleAttr('width')) + self.assertEqual(11, pwc2._getDoubleAttr("width")) return + # ---------------------------------------------------------------------------- + class TestDebyeWallerPeakWidth(unittest.TestCase): def setUp(self): self.pwm = DebyeWallerPeakWidth() return - def test_type(self): - """check DebyeWallerPeakWidth.type - """ - self.assertEqual('debye-waller', self.pwm.type()) + """check DebyeWallerPeakWidth.type""" + self.assertEqual("debye-waller", self.pwm.type()) self.assertEqual(0, len(self.pwm._namesOfDoubleAttributes())) return - def test_pickling(self): - """check pickling of DebyeWallerPeakWidth class. - """ - self.assertEqual('debye-waller', self.pwm.type()) + """check pickling of DebyeWallerPeakWidth class.""" + self.assertEqual("debye-waller", self.pwm.type()) pwm = self.pwm pwm2 = pickle.loads(pickle.dumps(pwm)) self.assertEqual(DebyeWallerPeakWidth, type(pwm2)) return + # ---------------------------------------------------------------------------- + class TestJeongPeakWidth(unittest.TestCase): def setUp(self): self.pwm = JeongPeakWidth() return - def test_type(self): - """check JeongPeakWidth.type - """ - self.assertEqual('jeong', self.pwm.type()) - self.assertTrue(hasattr(self.pwm, 'delta1')) - self.assertTrue(hasattr(self.pwm, 'delta2')) - self.assertTrue(hasattr(self.pwm, 'qbroad')) + """check JeongPeakWidth.type""" + self.assertEqual("jeong", self.pwm.type()) + self.assertTrue(hasattr(self.pwm, "delta1")) + self.assertTrue(hasattr(self.pwm, "delta2")) + self.assertTrue(hasattr(self.pwm, "qbroad")) return - def test_pickling(self): - """check pickling of the DebyeWallerPeakWidth class - """ + """check pickling of the DebyeWallerPeakWidth class""" pwm = self.pwm pwm.delta1 = 1 pwm.delta2 = 2 @@ -231,8 +204,10 @@ def test_pickling(self): self.assertEqual(3, pwm2.qbroad) return + # ---------------------------------------------------------------------------- + class MyPWM(PeakWidthModel): "Helper class for testing PeakWidthModelOwner." @@ -240,7 +215,7 @@ class MyPWM(PeakWidthModel): def __init__(self): PeakWidthModel.__init__(self) - self._registerDoubleAttribute('pwmscale') + self._registerDoubleAttribute("pwmscale") return def type(self): @@ -251,18 +226,22 @@ def create(self): def clone(self): import copy + return copy.copy(self) def calculate(self, bnds): return self.pwmscale * bnds.msd() tcnt = 0 + def ticker(self): self.tcnt += 1 return PeakWidthModel.ticker(self) + # End of class MyPWM + class TestPeakWidthOwner(unittest.TestCase): @classmethod @@ -270,7 +249,6 @@ def tearDownClass(cls): assert "mypwm" not in PeakWidthModel.getRegisteredTypes() return - def setUp(self): self.pc = PDFCalculator() self.dbpc = DebyePDFCalculator() @@ -279,25 +257,21 @@ def setUp(self): self.dbpc.peakwidthmodel = self.pwm return - def test_pwmtype(self): - '''Check type of the owned PeakWidthModel instance. - ''' - self.assertEqual('mypwm', self.pc.peakwidthmodel.type()) - self.assertEqual('mypwm', self.dbpc.peakwidthmodel.type()) + """Check type of the owned PeakWidthModel instance.""" + self.assertEqual("mypwm", self.pc.peakwidthmodel.type()) + self.assertEqual("mypwm", self.dbpc.peakwidthmodel.type()) return - def test_pickling(self): - '''Check pickling of an owned PeakWidthModel instance. - ''' + """Check pickling of an owned PeakWidthModel instance.""" pc1 = pickle.loads(pickle.dumps(self.pc)) self.pwm.pwmscale = 3 pc2 = pickle.loads(pickle.dumps(self.pc)) - self.assertEqual('mypwm', pc1.peakwidthmodel.type()) + self.assertEqual("mypwm", pc1.peakwidthmodel.type()) self.assertEqual(1.5, pc1.peakwidthmodel.pwmscale) self.assertEqual(1.5, pc1.pwmscale) - self.assertEqual('mypwm', pc2.peakwidthmodel.type()) + self.assertEqual("mypwm", pc2.peakwidthmodel.type()) self.assertEqual(3, pc2.peakwidthmodel.pwmscale) self.assertEqual(3, pc2.pwmscale) dbpc2 = pickle.loads(pickle.dumps(self.dbpc)) @@ -305,9 +279,10 @@ def test_pickling(self): self.assertEqual(3, dbpc2.pwmscale) return + # ---------------------------------------------------------------------------- -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() # End of file diff --git a/src/diffpy/srreal/tests/testscatteringfactortable.py b/src/diffpy/srreal/tests/testscatteringfactortable.py index 4edd6023..ba4dbebc 100644 --- a/src/diffpy/srreal/tests/testscatteringfactortable.py +++ b/src/diffpy/srreal/tests/testscatteringfactortable.py @@ -16,57 +16,70 @@ # ---------------------------------------------------------------------------- + class LocalTable(ScatteringFactorTable): def clone(self): import copy + return copy.copy(self) - def create(self): return LocalTable() - def _standardLookup(self, smbl, q): return q + 1 - def radiationType(self): return "LTB" - def type(self): return "localtable" + + def create(self): + return LocalTable() + + def _standardLookup(self, smbl, q): + return q + 1 + + def radiationType(self): + return "LTB" + + def type(self): + return "localtable" + def ticker(self): self.tcnt += 1 return ScatteringFactorTable.ticker(self) + tcnt = 0 + # ---------------------------------------------------------------------------- + class TestScatteringFactorTable(unittest.TestCase): def setUp(self): - self.sftx = ScatteringFactorTable.createByType('X') - self.sftn = ScatteringFactorTable.createByType('N') + self.sftx = ScatteringFactorTable.createByType("X") + self.sftn = ScatteringFactorTable.createByType("N") LocalTable()._registerThisType() return def tearDown(self): - ScatteringFactorTable._deregisterType('localtable') + ScatteringFactorTable._deregisterType("localtable") return def test_class_registry(self): - """check if instances are aliased by radiationType(). - """ - ltb = ScatteringFactorTable.createByType('LTB') + """check if instances are aliased by radiationType().""" + ltb = ScatteringFactorTable.createByType("LTB") self.assertTrue(type(ltb) is LocalTable) - ltb2 = ScatteringFactorTable.createByType('localtable') + ltb2 = ScatteringFactorTable.createByType("localtable") self.assertTrue(type(ltb2) is LocalTable) return def test_ticker(self): - """check ScatteringFactorTable.ticker() - """ + """check ScatteringFactorTable.ticker()""" from diffpy.srreal.eventticker import EventTicker + et0 = EventTicker(self.sftx.ticker()) - self.sftx.setCustomAs('D', 'H') + self.sftx.setCustomAs("D", "H") et1 = self.sftx.ticker() self.assertNotEqual(et0, et1) self.assertTrue(et0 < et1) return def test_ticker_override(self): - """check Python override of ScatteringFactorTable.ticker. - """ + """check Python override of ScatteringFactorTable.ticker.""" from diffpy.srreal.pdfcalculator import PDFCalculator + lsft = LocalTable() self.assertEqual(0, lsft.tcnt) et0 = lsft.ticker() @@ -85,108 +98,101 @@ def test_ticker_override(self): return def test_pickling(self): - """check pickling of ScatteringFactorTable instances. - """ + """check pickling of ScatteringFactorTable instances.""" self.assertEqual(0, len(self.sftx.getCustomSymbols())) - self.sftx.setCustomAs('Na', 'Na', 123) - self.sftx.setCustomAs('Calias', 'C') + self.sftx.setCustomAs("Na", "Na", 123) + self.sftx.setCustomAs("Calias", "C") self.assertEqual(2, len(self.sftx.getCustomSymbols())) sftx1 = pickle.loads(pickle.dumps(self.sftx)) self.assertEqual(2, len(sftx1.getCustomSymbols())) - self.assertAlmostEqual(123, sftx1.lookup('Na'), 12) - self.assertEqual(self.sftx.lookup('C'), sftx1.lookup('Calias')) + self.assertAlmostEqual(123, sftx1.lookup("Na"), 12) + self.assertEqual(self.sftx.lookup("C"), sftx1.lookup("Calias")) self.assertEqual(self.sftx.type(), sftx1.type()) pwa = pickle_with_attr - self.assertRaises(RuntimeError, pwa, SFTXray(), foo='bar') - self.assertRaises(RuntimeError, pwa, SFTElectron(), foo='bar') - self.assertRaises(RuntimeError, pwa, SFTNeutron(), foo='bar') - self.assertRaises(RuntimeError, pwa, SFTElectronNumber(), foo='bar') + self.assertRaises(RuntimeError, pwa, SFTXray(), foo="bar") + self.assertRaises(RuntimeError, pwa, SFTElectron(), foo="bar") + self.assertRaises(RuntimeError, pwa, SFTNeutron(), foo="bar") + self.assertRaises(RuntimeError, pwa, SFTElectronNumber(), foo="bar") return def test_picking_owned(self): - '''verify pickling of envelopes owned by PDF calculators. - ''' + """verify pickling of envelopes owned by PDF calculators.""" pc = PDFCalculator() dbpc = DebyePDFCalculator() ltb = LocalTable() - ltb.setCustomAs('Na', 'Na', 37) - ltb.foo = 'bar' + ltb.setCustomAs("Na", "Na", 37) + ltb.foo = "bar" pc.scatteringfactortable = ltb dbpc.scatteringfactortable = ltb self.assertIs(ltb, pc.scatteringfactortable) self.assertIs(ltb, dbpc.scatteringfactortable) pc2 = pickle.loads(pickle.dumps(pc)) dbpc2 = pickle.loads(pickle.dumps(dbpc)) - self.assertEqual('localtable', pc2.scatteringfactortable.type()) - self.assertEqual('localtable', dbpc2.scatteringfactortable.type()) - self.assertEqual(37, pc2.scatteringfactortable.lookup('Na')) - self.assertEqual(37, dbpc2.scatteringfactortable.lookup('Na')) - self.assertEqual('bar', pc2.scatteringfactortable.foo) - self.assertEqual('bar', dbpc2.scatteringfactortable.foo) + self.assertEqual("localtable", pc2.scatteringfactortable.type()) + self.assertEqual("localtable", dbpc2.scatteringfactortable.type()) + self.assertEqual(37, pc2.scatteringfactortable.lookup("Na")) + self.assertEqual(37, dbpc2.scatteringfactortable.lookup("Na")) + self.assertEqual("bar", pc2.scatteringfactortable.foo) + self.assertEqual("bar", dbpc2.scatteringfactortable.foo) return def test_pickling_derived(self): - """check pickling of a derived classes. - """ + """check pickling of a derived classes.""" lsft = LocalTable() - self.assertEqual(3, lsft._standardLookup('Na', 2)) + self.assertEqual(3, lsft._standardLookup("Na", 2)) self.assertEqual(set(), lsft.getCustomSymbols()) - lsft.foobar = 'asdf' - lsft.setCustomAs('Na', 'Na', 123) + lsft.foobar = "asdf" + lsft.setCustomAs("Na", "Na", 123) self.assertEqual(1, len(lsft.getCustomSymbols())) lsft1 = pickle.loads(pickle.dumps(lsft)) self.assertEqual(1, len(lsft1.getCustomSymbols())) - self.assertAlmostEqual(123, lsft1.lookup('Na'), 12) - self.assertEqual('asdf', lsft1.foobar) + self.assertAlmostEqual(123, lsft1.lookup("Na"), 12) + self.assertEqual("asdf", lsft1.foobar) self.assertEqual(lsft.type(), lsft1.type()) - self.assertEqual(3, lsft1._standardLookup('Cl', 2)) - self.assertEqual(1, lsft1.lookup('H')) + self.assertEqual(3, lsft1._standardLookup("Cl", 2)) + self.assertEqual(1, lsft1.lookup("H")) return def test_derived_create(self): - """Check override of ScatteringFactorTable.create in Python class. - """ + """Check override of ScatteringFactorTable.create in Python class.""" lsft = LocalTable() - lsft.setCustomAs('Xy', 'Na') + lsft.setCustomAs("Xy", "Na") lsft2 = lsft.create() self.assertTrue(isinstance(lsft2, LocalTable)) self.assertEqual(set(), lsft2.getCustomSymbols()) return def test_derived_clone(self): - """Check override of ScatteringFactorTable.clone in Python class. - """ + """Check override of ScatteringFactorTable.clone in Python class.""" lsft = LocalTable() - lsft.setCustomAs('Xy', 'Na') + lsft.setCustomAs("Xy", "Na") lsft2 = lsft.clone() self.assertTrue(isinstance(lsft2, LocalTable)) - self.assertEqual(set(['Xy']), lsft2.getCustomSymbols()) + self.assertEqual(set(["Xy"]), lsft2.getCustomSymbols()) return def test_lookup(self): - """Check ScatteringFactorTable.lookup handling of array arguments. - """ + """Check ScatteringFactorTable.lookup handling of array arguments.""" qa = numpy.linspace(0, 50) - qb = numpy.array([(x, 0.0) for x in qa])[:,0] + qb = numpy.array([(x, 0.0) for x in qa])[:, 0] self.assertTrue(qb.strides > qa.strides) sftx = self.sftx - fmn0 = numpy.array([sftx.lookup('Mn', x) for x in qa]) - self.assertTrue(numpy.array_equal(fmn0, sftx.lookup('Mn', qa))) - self.assertTrue(numpy.array_equal(fmn0, sftx.lookup('Mn', qb))) - self.assertTrue(numpy.array_equal( - fmn0.reshape(5, 10), sftx.lookup('Mn', qa.reshape(5, 10)))) - self.assertTrue(numpy.array_equal( - fmn0.reshape(5, 2, 5), sftx.lookup('Mn', qa.reshape(5, 2, 5)))) - self.assertTrue(numpy.array_equal(fmn0, sftx.lookup('Mn', list(qa)))) - self.assertRaises(TypeError, sftx.lookup, 'Na', 'asdf') - self.assertRaises(TypeError, sftx.lookup, 'Na', {}) + fmn0 = numpy.array([sftx.lookup("Mn", x) for x in qa]) + self.assertTrue(numpy.array_equal(fmn0, sftx.lookup("Mn", qa))) + self.assertTrue(numpy.array_equal(fmn0, sftx.lookup("Mn", qb))) + self.assertTrue(numpy.array_equal(fmn0.reshape(5, 10), sftx.lookup("Mn", qa.reshape(5, 10)))) + self.assertTrue(numpy.array_equal(fmn0.reshape(5, 2, 5), sftx.lookup("Mn", qa.reshape(5, 2, 5)))) + self.assertTrue(numpy.array_equal(fmn0, sftx.lookup("Mn", list(qa)))) + self.assertRaises(TypeError, sftx.lookup, "Na", "asdf") + self.assertRaises(TypeError, sftx.lookup, "Na", {}) return + # End of class TestScatteringFactorTable # ---------------------------------------------------------------------------- -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() # End of file diff --git a/src/diffpy/srreal/tests/testsfaverage.py b/src/diffpy/srreal/tests/testsfaverage.py index f7838405..b23cb8a6 100644 --- a/src/diffpy/srreal/tests/testsfaverage.py +++ b/src/diffpy/srreal/tests/testsfaverage.py @@ -15,24 +15,23 @@ # ---------------------------------------------------------------------------- + class TestSFAverage(unittest.TestCase): def setUp(self): - self.sftx = ScatteringFactorTable.createByType('X') - self.sftn = ScatteringFactorTable.createByType('N') + self.sftx = ScatteringFactorTable.createByType("X") + self.sftn = ScatteringFactorTable.createByType("N") return def tearDown(self): return - def test_fromStructure_CdSe(self): - """check SFAverage.fromStructure() for CdSe - """ - cdse = loadDiffPyStructure('CdSe_cadmoselite.cif') + """check SFAverage.fromStructure() for CdSe""" + cdse = loadDiffPyStructure("CdSe_cadmoselite.cif") sfavg = SFAverage.fromStructure(cdse, self.sftx) - fcd = self.sftx.lookup('Cd') - fse = self.sftx.lookup('Se') + fcd = self.sftx.lookup("Cd") + fse = self.sftx.lookup("Se") self.assertTrue(isinstance(sfavg.f1sum, float)) self.assertAlmostEqual(0.5 * (fcd + fse), sfavg.f1avg) self.assertAlmostEqual(0.5 * (fcd**2 + fse**2), sfavg.f2avg) @@ -46,23 +45,19 @@ def test_fromStructure_CdSe(self): self.assertEqual(sfavg.f2sum, sfavg2.f2sum[0]) sfavg3 = SFAverage.fromStructure(cdse, self.sftn, qa) self.assertEqual(sfavg3.f1sum[0], sfavg3.f1sum[-1]) - sfavg4 = SFAverage.fromStructure(cdse, 'N', qa) + sfavg4 = SFAverage.fromStructure(cdse, "N", qa) self.assertTrue(numpy.array_equal(sfavg3.f1sum, sfavg4.f1sum)) self.assertTrue(numpy.array_equal(sfavg3.f2sum, sfavg4.f2sum)) - sfavg5 = SFAverage.fromStructure(cdse, 'EN', qa) + sfavg5 = SFAverage.fromStructure(cdse, "EN", qa) self.assertFalse(numpy.array_equal(sfavg3.f1sum, sfavg5.f1sum)) - self.assertRaises(TypeError, SFAverage.fromStructure, - 'notastructure', self.sftx) - self.assertRaises(ValueError, SFAverage.fromStructure, - cdse, 'invalid') + self.assertRaises(TypeError, SFAverage.fromStructure, "notastructure", self.sftx) + self.assertRaises(ValueError, SFAverage.fromStructure, cdse, "invalid") return - def test_fromComposition(self): - """check SFAverage.fromComposition() - """ - sfavg1 = SFAverage.fromComposition({'Na' : 1, 'Cl' : 1}, self.sftx) - fm = ['Na', 0.25, 'Cl', 0.75, 'Cl', 0.25, 'Na', 0.5, 'Na', 0.25] + """check SFAverage.fromComposition()""" + sfavg1 = SFAverage.fromComposition({"Na": 1, "Cl": 1}, self.sftx) + fm = ["Na", 0.25, "Cl", 0.75, "Cl", 0.25, "Na", 0.5, "Na", 0.25] smblcnts = zip(fm[0::2], fm[1::2]) sfavg2 = SFAverage.fromComposition(smblcnts, self.sftx) self.assertEqual(sfavg1.f1sum, sfavg2.f1sum) @@ -74,39 +69,40 @@ def test_fromComposition(self): self.assertEqual(0, sfempty.count) return + # End of class TestSFAverage # ---------------------------------------------------------------------------- + @unittest.skipUnless(has_pyobjcryst, _msg_nopyobjcryst) class TestSFAverageObjCryst(unittest.TestCase): def setUp(self): - self.sftx = ScatteringFactorTable.createByType('X') + self.sftx = ScatteringFactorTable.createByType("X") return def tearDown(self): return - def test_from_rutile(self): - """check SFAverage.fromStructure for pyobjcryst Crystal of rutile. - """ - rutile = loadObjCrystCrystal('rutile.cif') + """check SFAverage.fromStructure for pyobjcryst Crystal of rutile.""" + rutile = loadObjCrystCrystal("rutile.cif") qa = numpy.arange(0, 25, 0.1) sfavg = SFAverage.fromStructure(rutile, self.sftx, qa) - fti = self.sftx.lookup('Ti', qa) - fo = self.sftx.lookup('O', qa) + fti = self.sftx.lookup("Ti", qa) + fo = self.sftx.lookup("O", qa) self.assertTrue(numpy.allclose((fti + 2 * fo) / 3.0, sfavg.f1avg)) fti2, fo2 = fti**2, fo**2 self.assertTrue(numpy.allclose((fti2 + 2 * fo2) / 3.0, sfavg.f2avg)) self.assertEqual(6, sfavg.count) + # End of class TestSFAverageObjCryst # ---------------------------------------------------------------------------- -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() # End of file diff --git a/src/diffpy/srreal/tests/teststructureadapter.py b/src/diffpy/srreal/tests/teststructureadapter.py index 9224ace9..932a4ddc 100644 --- a/src/diffpy/srreal/tests/teststructureadapter.py +++ b/src/diffpy/srreal/tests/teststructureadapter.py @@ -13,22 +13,28 @@ from diffpy.srreal.tests.testutils import loadDiffPyStructure from diffpy.srreal.tests.testutils import loadCrystalStructureAdapter from diffpy.srreal.structureadapter import ( - createStructureAdapter, nometa, nosymmetry, StructureAdapter, - AtomicStructureAdapter, Atom, PeriodicStructureAdapter, - CrystalStructureAdapter) + createStructureAdapter, + nometa, + nosymmetry, + StructureAdapter, + AtomicStructureAdapter, + Atom, + PeriodicStructureAdapter, + CrystalStructureAdapter, +) import diffpy.srreal.tests.testutils as testutils # ---------------------------------------------------------------------------- + class TestRoutines(unittest.TestCase): def setUp(self): - self.nickel = loadDiffPyStructure('Ni.stru') + self.nickel = loadDiffPyStructure("Ni.stru") return def test_createStructureAdapter(self): - """check createStructureAdapter() routine. - """ + """check createStructureAdapter() routine.""" adpt = createStructureAdapter(self.nickel) self.assertEqual(4, adpt.countSites()) self.assertTrue(False is adpt.siteAnisotropy(0)) @@ -42,11 +48,9 @@ def test_createStructureAdapter(self): return def test_createStructureAdapterTypes(self): - '''Check types returned by conversion from diffpy.structure. - ''' - from diffpy.srreal.structureconverters import ( - DiffPyStructureAtomicAdapter, - DiffPyStructurePeriodicAdapter) + """Check types returned by conversion from diffpy.structure.""" + from diffpy.srreal.structureconverters import DiffPyStructureAtomicAdapter, DiffPyStructurePeriodicAdapter + adpt = createStructureAdapter(self.nickel) self.assertTrue(type(adpt) is DiffPyStructurePeriodicAdapter) self.nickel.pdffit = None @@ -61,8 +65,7 @@ def test_createStructureAdapterTypes(self): return def test_createStructureAdapter_int64_occupancy(self): - """Check Structure conversion when occupany is of numpy.int64 type. - """ + """Check Structure conversion when occupany is of numpy.int64 type.""" self.nickel[0].occupancy = numpy.int64(0) self.nickel[1].occupancy = numpy.int64(1) adpt = createStructureAdapter(self.nickel) @@ -71,38 +74,37 @@ def test_createStructureAdapter_int64_occupancy(self): return def test_pickling(self): - '''check pickling of StructureAdapter instances. - ''' + """check pickling of StructureAdapter instances.""" adpt = createStructureAdapter(self.nickel) adpt1 = pickle.loads(pickle.dumps(adpt)) self.assertFalse(adpt is adpt1) self.assertEqual(adpt.countSites(), adpt1.countSites()) self.assertEqual(adpt.totalOccupancy(), adpt1.totalOccupancy()) self.assertEqual(adpt.siteAtomType(1), adpt1.siteAtomType(1)) - self.assertTrue(numpy.array_equal( - adpt.siteCartesianPosition(1), adpt1.siteCartesianPosition(1))) + self.assertTrue(numpy.array_equal(adpt.siteCartesianPosition(1), adpt1.siteCartesianPosition(1))) self.assertEqual(adpt.siteMultiplicity(1), adpt1.siteMultiplicity(1)) self.assertEqual(adpt.siteOccupancy(1), adpt1.siteOccupancy(1)) self.assertTrue(adpt.siteAnisotropy(1) is adpt1.siteAnisotropy(1)) - self.assertTrue(numpy.array_equal( - adpt.siteCartesianUij(1), adpt1.siteCartesianUij(1))) + self.assertTrue(numpy.array_equal(adpt.siteCartesianUij(1), adpt1.siteCartesianUij(1))) return def test_pickle_nonwrapped(self): - '''Check if pickling works for non-wrapped C++ object. - ''' + """Check if pickling works for non-wrapped C++ object.""" from diffpy.srreal.structureadapter import EMPTY as e0 + spkl = pickle.dumps(e0) e1 = pickle.loads(spkl) self.assertEqual(0, e1.countSites()) return + # End of class TestStructureAdapter # ---------------------------------------------------------------------------- + class TestDerivedAdapter(unittest.TestCase): - 'Check functionality in a Python-derived StructureAdapter class.' + "Check functionality in a Python-derived StructureAdapter class." DerivedCls = testutils.DerivedStructureAdapter @@ -111,8 +113,7 @@ def setUp(self): return def test__customPQConfig(self): - """check if DerivedCls._customPQConfig gets called. - """ + """check if DerivedCls._customPQConfig gets called.""" self.assertEqual(0, self.adpt.cpqcount) pc = PDFCalculator() pc.setStructure(self.adpt) @@ -122,8 +123,7 @@ def test__customPQConfig(self): return def test_pickling(self): - '''check pickling of DerivedCls instances. - ''' + """check pickling of DerivedCls instances.""" self.adpt.cpqcount = 1 adpt1 = pickle.loads(pickle.dumps(self.adpt)) self.assertTrue(self.DerivedCls is type(adpt1)) @@ -136,31 +136,36 @@ def test_pickling(self): self.assertEqual(3, adpt1.cpqcount) return + # End of class TestDerivedAdapter + class TestDerivedAtomicAdapter(TestDerivedAdapter): DerivedCls = testutils.DerivedAtomicStructureAdapter + class TestDerivedPeriodicAdapter(TestDerivedAdapter): DerivedCls = testutils.DerivedPeriodicStructureAdapter + class TestDerivedCrystalAdapter(TestDerivedAdapter): DerivedCls = testutils.DerivedCrystalStructureAdapter + # ---------------------------------------------------------------------------- + class TestNoMeta(unittest.TestCase): def setUp(self): - self.nickel = loadDiffPyStructure('Ni.stru') + self.nickel = loadDiffPyStructure("Ni.stru") return def test_nometa(self): - '''check NoMetaStructureAdapter. - ''' + """check NoMetaStructureAdapter.""" r0, g0 = PDFCalculator()(self.nickel) ni1 = self.nickel.copy() - ni1.pdffit['scale'] = 2.0 + ni1.pdffit["scale"] = 2.0 r1, g1 = PDFCalculator()(ni1) self.assertTrue(numpy.array_equal(r0, r1)) self.assertTrue(numpy.allclose(2 * g0, g1)) @@ -170,7 +175,7 @@ def test_nometa(self): self.assertTrue(numpy.array_equal(r0, r1nm)) self.assertTrue(numpy.allclose(g0, g1nm)) ni2 = self.nickel.copy() - ni2.pdffit['delta2'] = 4 + ni2.pdffit["delta2"] = 4 r2, g2 = PDFCalculator()(ni2) r2, g2nm = PDFCalculator()(nometa(ni2)) self.assertFalse(numpy.allclose(g0, g2)) @@ -183,11 +188,10 @@ def test_nometa(self): return def test_nometa_pickling(self): - '''check pickling of the NoMetaStructureAdapter wrapper. - ''' + """check pickling of the NoMetaStructureAdapter wrapper.""" r0, g0 = PDFCalculator()(self.nickel) ni1 = self.nickel.copy() - ni1.pdffit['scale'] = 2.0 + ni1.pdffit["scale"] = 2.0 ni1nm = pickle.loads(pickle.dumps(nometa(ni1))) self.assertFalse(ni1nm is ni1) r1nm, g1nm = PDFCalculator()(ni1nm) @@ -196,25 +200,25 @@ def test_nometa_pickling(self): return def test_nometa_twice(self): - '''check that second call of nometa returns the same object. - ''' + """check that second call of nometa returns the same object.""" adpt1 = nometa(self.nickel) adpt2 = nometa(adpt1) self.assertTrue(adpt1 is adpt2) + # End of class TestNoMeta # ---------------------------------------------------------------------------- + class TestNoSymmetry(unittest.TestCase): def setUp(self): - self.nickel = loadDiffPyStructure('Ni.stru') + self.nickel = loadDiffPyStructure("Ni.stru") return def test_nosymmetry(self): - '''check NoSymmetryStructureAdapter. - ''' + """check NoSymmetryStructureAdapter.""" pdfc0 = PDFCalculator() r0, g0 = pdfc0(self.nickel) rdf0 = pdfc0.rdf @@ -224,7 +228,7 @@ def test_nosymmetry(self): r1, g1 = pdfc1(niuc) self.assertTrue(numpy.array_equal(r0, r1)) self.assertFalse(numpy.allclose(g0, g1)) - tail = (r0 > 5.0) + tail = r0 > 5.0 self.assertTrue(numpy.allclose(0.0 * g1[tail], g1[tail])) rdf0 = pdfc0.rdf rdf1 = pdfc1.rdf @@ -238,15 +242,13 @@ def test_nosymmetry(self): return def test_nosymmetry_twice(self): - '''check that second call of nosymmetry returns the same object. - ''' + """check that second call of nosymmetry returns the same object.""" adpt1 = nosymmetry(self.nickel) adpt2 = nosymmetry(adpt1) self.assertTrue(adpt1 is adpt2) def test_nosymmetry_pickling(self): - '''check pickling of the NoSymmetryStructureAdapter wrapper. - ''' + """check pickling of the NoSymmetryStructureAdapter wrapper.""" ni1ns = nosymmetry(self.nickel) r1, g1 = PDFCalculator()(ni1ns) ni2ns = pickle.loads(pickle.dumps(ni1ns)) @@ -256,38 +258,38 @@ def test_nosymmetry_pickling(self): self.assertTrue(numpy.array_equal(g1, g2)) return + # End of class TestNoSymmetry # ---------------------------------------------------------------------------- + @unittest.skipUnless(has_pyobjcryst, _msg_nopyobjcryst) class TestPyObjCrystAdapter(unittest.TestCase): def setUp(self): - rutile_crystal = loadObjCrystCrystal('TiO2_rutile-fit.cif') + rutile_crystal = loadObjCrystCrystal("TiO2_rutile-fit.cif") self.rutile = createStructureAdapter(rutile_crystal) return def test_objcryst_adapter(self): - '''check ObjCrystStructureAdapter for rutile. - ''' + """check ObjCrystStructureAdapter for rutile.""" self.assertEqual(2, self.rutile.countSites()) self.assertEqual(6, self.rutile.totalOccupancy()) self.assertEqual("Ti", self.rutile.siteAtomType(0)) self.assertEqual("O", self.rutile.siteAtomType(1)) self.assertTrue(True is self.rutile.siteAnisotropy(0)) self.assertTrue(True is self.rutile.siteAnisotropy(1)) - self.assertTrue(numpy.allclose( - numpy.diag([0.008698, 0.008698, 0.005492]), - self.rutile.siteCartesianUij(0))) - self.assertTrue(numpy.allclose( - numpy.diag([0.021733, 0.021733, 0.007707]), - self.rutile.siteCartesianUij(1))) + self.assertTrue( + numpy.allclose(numpy.diag([0.008698, 0.008698, 0.005492]), self.rutile.siteCartesianUij(0)) + ) + self.assertTrue( + numpy.allclose(numpy.diag([0.021733, 0.021733, 0.007707]), self.rutile.siteCartesianUij(1)) + ) return def test_objcryst_pickling(self): - '''check pickling of the NoSymmetryStructureAdapter wrapper. - ''' + """check pickling of the NoSymmetryStructureAdapter wrapper.""" r0, g0 = PDFCalculator()(self.rutile) rutile1 = pickle.loads(pickle.dumps(self.rutile)) self.assertFalse(self.rutile is rutile1) @@ -296,12 +298,14 @@ def test_objcryst_pickling(self): self.assertTrue(numpy.array_equal(g0, g1)) return + # End of class TestPyObjCrystAdapter # ---------------------------------------------------------------------------- + class IndexRangeTests(object): - 'Check error handling for site index arguments.' + "Check error handling for site index arguments." AdptClass = None @@ -310,73 +314,71 @@ def setUp(self): return def test_siteAtomTypeIndex(self): - """Check out-of-range arguments in AdptClass.siteAtomType. - """ + """Check out-of-range arguments in AdptClass.siteAtomType.""" cnt = self.adpt.countSites() self.assertRaises(IndexError, self.adpt.siteAtomType, cnt) self.assertRaises(IndexError, self.adpt.siteAtomType, -1) return def test_siteCartesianPositionIndex(self): - """Check out-of-range arguments in AdptClass.siteCartesianPosition. - """ + """Check out-of-range arguments in AdptClass.siteCartesianPosition.""" cnt = self.adpt.countSites() self.assertRaises(IndexError, self.adpt.siteCartesianPosition, cnt) self.assertRaises(IndexError, self.adpt.siteCartesianPosition, -1) return def test_siteMultiplicityIndex(self): - """Check out-of-range arguments in AdptClass.siteMultiplicity. - """ + """Check out-of-range arguments in AdptClass.siteMultiplicity.""" cnt = self.adpt.countSites() self.assertRaises(IndexError, self.adpt.siteMultiplicity, cnt) self.assertRaises(IndexError, self.adpt.siteMultiplicity, -1) return def test_siteOccupancyIndex(self): - """Check out-of-range arguments in AdptClass.siteOccupancy. - """ + """Check out-of-range arguments in AdptClass.siteOccupancy.""" cnt = self.adpt.countSites() self.assertRaises(IndexError, self.adpt.siteOccupancy, cnt) self.assertRaises(IndexError, self.adpt.siteOccupancy, -1) return def test_siteAnisotropyIndex(self): - """Check out-of-range arguments in AdptClass.siteAnisotropy. - """ + """Check out-of-range arguments in AdptClass.siteAnisotropy.""" cnt = self.adpt.countSites() self.assertRaises(IndexError, self.adpt.siteAnisotropy, cnt) self.assertRaises(IndexError, self.adpt.siteAnisotropy, -1) return def test_siteCartesianUijIndex(self): - """Check out-of-range arguments in AdptClass.siteCartesianUij. - """ + """Check out-of-range arguments in AdptClass.siteCartesianUij.""" cnt = self.adpt.countSites() self.assertRaises(IndexError, self.adpt.siteCartesianUij, cnt) self.assertRaises(IndexError, self.adpt.siteCartesianUij, -1) return + # End of class IndexRangeTests TestCase = unittest.TestCase # test index bounds for C++ classes + class TestAtomicAdapterIndexRange(IndexRangeTests, TestCase): AdptClass = AtomicStructureAdapter + # No need to do index tests for PeriodicStructureAdapter as it does not # override any of AtomicStructureAdapter site-access methods. # CrystalStructureAdapter overrides siteMultiplicity so we'll # test it here as well. + class TestCrystalAdapter(IndexRangeTests, TestCase): AdptClass = CrystalStructureAdapter def test_expandLatticeAtom(self): """Check CrystalStructureAdapter.expandLatticeAtom.""" - cdse = loadCrystalStructureAdapter('CdSe_cadmoselite.cif') + cdse = loadCrystalStructureAdapter("CdSe_cadmoselite.cif") a = Atom() a.xyz_cartn = (0.1, 0.13, 0.17) asymsites = cdse.expandLatticeAtom(a) @@ -387,18 +389,20 @@ def test_expandLatticeAtom(self): def test_getEquivalentAtoms(self): """Check CrystalStructureAdapter.getEquivalentAtoms.""" - cdse = loadCrystalStructureAdapter('CdSe_cadmoselite.cif') + cdse = loadCrystalStructureAdapter("CdSe_cadmoselite.cif") eqatoms0 = cdse.getEquivalentAtoms(0) eqatoms1 = cdse.getEquivalentAtoms(1) self.assertTrue(type(eqatoms1) is list) self.assertEqual(2, len(eqatoms0)) self.assertEqual(2, len(eqatoms1)) - self.assertTrue(all(a.atomtype == "Cd" for a in eqatoms0)) - self.assertTrue(all(a.atomtype == "Se" for a in eqatoms1)) + self.assertTrue(all(a.atomtype == "Cd" for a in eqatoms0)) + self.assertTrue(all(a.atomtype == "Se" for a in eqatoms1)) return + # ---------------------------------------------------------------------------- + class TestDerivedStructureAdapter(IndexRangeTests, TestCase): AdptClass = testutils.DerivedStructureAdapter @@ -409,121 +413,112 @@ def setUp(self): return def test_siteAtomType_valid(self): - """Check DerivedStructureAdapter.siteAtomType. - """ + """Check DerivedStructureAdapter.siteAtomType.""" adpt1 = self.adpt1 self.assertEqual("Cu", adpt1.siteAtomType(0)) self.assertEqual("", StructureAdapter.siteAtomType(adpt1, 0)) return def test_siteCartesianPosition_valid(self): - """Check DerivedStructureAdapter.siteCartesianPosition. - """ + """Check DerivedStructureAdapter.siteCartesianPosition.""" adpt1 = self.adpt1 xyz0 = adpt1.siteCartesianPosition(0) self.assertTrue(numpy.array_equal([1, 2, 3], xyz0)) return def test_siteMultiplicity_valid(self): - """Check DerivedStructureAdapter.siteMultiplicity. - """ + """Check DerivedStructureAdapter.siteMultiplicity.""" adpt1 = self.adpt1 self.assertEqual(2, adpt1.siteMultiplicity(0)) self.assertEqual(1, StructureAdapter.siteMultiplicity(adpt1, 0)) return def test_siteOccupancy_valid(self): - """Check DerivedStructureAdapter.siteOccupancy. - """ + """Check DerivedStructureAdapter.siteOccupancy.""" adpt1 = self.adpt1 self.assertEqual(0.5, adpt1.siteOccupancy(0)) self.assertEqual(1.0, StructureAdapter.siteOccupancy(adpt1, 0)) return def test_siteAnisotropy_valid(self): - """Check DerivedStructureAdapter.siteAnisotropy. - """ + """Check DerivedStructureAdapter.siteAnisotropy.""" adpt1 = self.adpt1 self.assertFalse(adpt1.siteAnisotropy(0)) return def test_siteCartesianUij_valid(self): - """Check DerivedStructureAdapter.siteCartesianUij. - """ + """Check DerivedStructureAdapter.siteCartesianUij.""" adpt1 = self.adpt1 uiso = 0.005 * numpy.identity(3) self.assertTrue(numpy.array_equal(uiso, adpt1.siteCartesianUij(0))) self.assertRaises(IndexError, adpt1.siteCartesianUij, 1) return + # End of class TestDerivedStructureAdapter # ---------------------------------------------------------------------------- + class TestStructureAdapter(unittest.TestCase): def setUp(self): self.adpt = StructureAdapter() return -# def test__customPQConfig(self): -# """check StructureAdapter._customPQConfig() -# """ -# return -# -# def test_countSites(self): -# """check StructureAdapter.countSites() -# """ -# return -# -# def test_createBondGenerator(self): -# """check StructureAdapter.createBondGenerator() -# """ -# return -# -# def test_numberDensity(self): -# """check StructureAdapter.numberDensity() -# """ -# return + # def test__customPQConfig(self): + # """check StructureAdapter._customPQConfig() + # """ + # return + # + # def test_countSites(self): + # """check StructureAdapter.countSites() + # """ + # return + # + # def test_createBondGenerator(self): + # """check StructureAdapter.createBondGenerator() + # """ + # return + # + # def test_numberDensity(self): + # """check StructureAdapter.numberDensity() + # """ + # return def test_siteAtomType(self): - """check StructureAdapter.siteAtomType() - """ + """check StructureAdapter.siteAtomType()""" self.assertEqual("", self.adpt.siteAtomType(0)) return def test_siteCartesianPosition(self): - """check StructureAdapter.siteCartesianPosition() - """ + """check StructureAdapter.siteCartesianPosition()""" self.assertRaises(RuntimeError, self.adpt.siteAnisotropy, 0) return def test_siteMultiplicity(self): - """check StructureAdapter.siteMultiplicity() - """ + """check StructureAdapter.siteMultiplicity()""" self.assertEqual(1, self.adpt.siteMultiplicity(0)) return def test_siteOccupancy(self): - """check StructureAdapter.siteOccupancy() - """ + """check StructureAdapter.siteOccupancy()""" # check if we use the C++ method that alwasy return 1. self.assertEqual(1.0, self.adpt.siteOccupancy(0)) self.assertEqual(1.0, self.adpt.siteOccupancy(99)) return def test_siteAnisotropy(self): - """check StructureAdapter.siteAnisotropy() - """ + """check StructureAdapter.siteAnisotropy()""" self.assertRaises(RuntimeError, self.adpt.siteAnisotropy, 0) return def test_siteCartesianUij(self): - """check StructureAdapter.siteCartesianUij() - """ + """check StructureAdapter.siteCartesianUij()""" self.assertRaises(RuntimeError, self.adpt.siteCartesianUij, 0) return + # def test_totalOccupancy(self): # """check StructureAdapter.totalOccupancy() # """ @@ -533,6 +528,7 @@ def test_siteCartesianUij(self): # ---------------------------------------------------------------------------- + class TestAtom(unittest.TestCase): def setUp(self): @@ -540,8 +536,7 @@ def setUp(self): return def test___init__copy(self): - '''check Atom copy constructor. - ''' + """check Atom copy constructor.""" self.a.xyz_cartn = (1, 2, 3) a1 = Atom(self.a) self.assertEqual(self.a, a1) @@ -549,18 +544,16 @@ def test___init__copy(self): return def test_equality(self): - '''check Atom equal and not equal operators. - ''' + """check Atom equal and not equal operators.""" self.assertEqual(self.a, Atom()) self.assertFalse(self.a != Atom()) a1 = Atom() - a1.atomtype = 'Na' + a1.atomtype = "Na" self.assertNotEqual(self.a, a1) return def test_pickling(self): - '''check pickling of Atom instances. - ''' + """check pickling of Atom instances.""" self.a.atomtype = "Na" a1 = pickle.loads(pickle.dumps(self.a)) self.assertEqual("Na", a1.atomtype) @@ -569,8 +562,7 @@ def test_pickling(self): return def test_xyz_cartn(self): - '''check Atom.xyz_cartn. - ''' + """check Atom.xyz_cartn.""" a = self.a a.xyz_cartn = 4, 5, 6 self.assertTrue(numpy.array_equal([4, 5, 6], a.xyz_cartn)) @@ -580,17 +572,15 @@ def test_xyz_cartn(self): return def test_uij_cartn(self): - '''check Atom.uij_cartn - ''' + """check Atom.uij_cartn""" a = self.a a.uij_cartn = numpy.identity(3) * 0.01 a.uc12 = 0.012 a.uc13 = 0.013 a.uc23 = 0.023 - self.assertTrue(numpy.array_equal(a.uij_cartn, [ - [0.01, 0.012, 0.013], - [0.012, 0.01, 0.023], - [0.013, 0.023, 0.01]])) + self.assertTrue( + numpy.array_equal(a.uij_cartn, [[0.01, 0.012, 0.013], [0.012, 0.01, 0.023], [0.013, 0.023, 0.01]]) + ) self.assertEqual(0.01, a.uc11) self.assertEqual(0.01, a.uc22) self.assertEqual(0.01, a.uc33) @@ -600,7 +590,7 @@ def test_uij_cartn(self): return def test_xc_yc_zc(self): - 'check Atom properties xc, yc, zc.' + "check Atom properties xc, yc, zc." a = self.a a.xc, a.yc, a.zc = numpy.arange(1, 4) self.assertEqual(1.0, a.xc) @@ -609,18 +599,18 @@ def test_xc_yc_zc(self): return def test_occupancy(self): - 'check Atom.occupancy' + "check Atom.occupancy" a = self.a - a.occupancy, = numpy.arange(1) + (a.occupancy,) = numpy.arange(1) self.assertEqual(0.0, a.occupancy) a.occupancy = numpy.float32(0.5) self.assertEqual(0.5, a.occupancy) return def test_anisotropy(self): - 'check Atom.anisotropy' + "check Atom.anisotropy" a = self.a - nptrue, npfalse = (numpy.arange(2) < 1) + nptrue, npfalse = numpy.arange(2) < 1 a.anisotropy = nptrue self.assertTrue(a.anisotropy) a.anisotropy = npfalse @@ -628,18 +618,19 @@ def test_anisotropy(self): return def test_ucij(self): - 'check Atom attributes u11, u22, etc.' + "check Atom attributes u11, u22, etc." a = self.a a.uc11, a.uc22, a.uc33, a.uc12, a.uc13, a.uc23 = numpy.arange(1, 7) uijexp = [[1, 4, 5], [4, 2, 6], [5, 6, 3]] self.assertTrue(numpy.array_equal(uijexp, a.uij_cartn)) return + # End of class TestAtom # ---------------------------------------------------------------------------- -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() # End of file diff --git a/src/diffpy/srreal/tests/testutils.py b/src/diffpy/srreal/tests/testutils.py index 0cead96d..c16ae8dd 100644 --- a/src/diffpy/srreal/tests/testutils.py +++ b/src/diffpy/srreal/tests/testutils.py @@ -32,37 +32,42 @@ _msg_nopyobjcryst = "No module named 'pyobjcryst'" try: import pyobjcryst.crystal + convertObjCrystCrystal(pyobjcryst.crystal.Crystal()) has_pyobjcryst = True except ImportError: has_pyobjcryst = False - logger.warning('Cannot import pyobjcryst, pyobjcryst tests skipped.') + logger.warning("Cannot import pyobjcryst, pyobjcryst tests skipped.") except TypeError: has_pyobjcryst = False - logger.warning('Compiled without ObjCryst, pyobjcryst tests skipped.') + logger.warning("Compiled without ObjCryst, pyobjcryst tests skipped.") # periodictable _msg_noperiodictable = "No module named 'periodictable'" try: import periodictable + has_periodictable = True # silence the pyflakes syntax checker del periodictable except ImportError: has_periodictable = False - logger.warning('Cannot import periodictable, periodictable tests skipped.') + logger.warning("Cannot import periodictable, periodictable tests skipped.") # helper functions + def datafile(filename): from pkg_resources import resource_filename + rv = resource_filename(__name__, "testdata/" + filename) return rv def loadObjCrystCrystal(filename): from pyobjcryst import loadCrystal + fullpath = datafile(filename) crst = loadCrystal(fullpath) return crst @@ -76,8 +81,9 @@ def loadDiffPyStructure(filename): def loadCrystalStructureAdapter(filename): from diffpy.srreal.structureconverters import _fetchDiffPyStructureData + fullpath = datafile(filename) - pcif = getParser('cif') + pcif = getParser("cif") stru = pcif.parseFile(fullpath) asu = stru[:0] + pcif.asymmetric_unit adpt = CrystalStructureAdapter() @@ -95,6 +101,7 @@ def pickle_with_attr(obj, **attr): rv = pickle.dumps(obj) return rv + # helper class for testing overloading of StructureAdapter from diffpy.srreal.structureadapter import StructureAdapter @@ -102,6 +109,7 @@ def pickle_with_attr(obj, **attr): from diffpy.srreal.structureadapter import PeriodicStructureAdapter from diffpy.srreal.structureadapter import CrystalStructureAdapter + class HasCustomPQConfig(object): cpqcount = 0 @@ -117,17 +125,15 @@ def __init__(self): StructureAdapter.__init__(self) self.positions = [] - def clone(self): rv = DerivedStructureAdapter() rv.positions[:] = copy.deepcopy(self.positions) return rv - def createBondGenerator(self): from diffpy.srreal.structureadapter import BaseBondGenerator - return BaseBondGenerator(self) + return BaseBondGenerator(self) def countSites(self): return len(self.positions) @@ -139,16 +145,13 @@ def siteAtomType(self, idx): self._checkindex(idx) return "Cu" - def siteCartesianPosition(self, idx): return self.positions[idx] - def siteMultiplicity(self, idx): self._checkindex(idx) return 2 * StructureAdapter.siteMultiplicity(self, idx) - def siteOccupancy(self, idx): self._checkindex(idx) return 0.5 * StructureAdapter.siteOccupancy(self, idx) @@ -157,28 +160,28 @@ def siteAnisotropy(self, idx): self._checkindex(idx) return False - def siteCartesianUij(self, idx): self._checkindex(idx) return numpy.identity(3, dtype=float) * 0.005 - def _checkindex(self, idx): self.positions[idx] return + # End of class DerivedStructureAdapter -class DerivedAtomicStructureAdapter( - HasCustomPQConfig, AtomicStructureAdapter): + +class DerivedAtomicStructureAdapter(HasCustomPQConfig, AtomicStructureAdapter): pass -class DerivedPeriodicStructureAdapter( - HasCustomPQConfig, PeriodicStructureAdapter): + +class DerivedPeriodicStructureAdapter(HasCustomPQConfig, PeriodicStructureAdapter): pass -class DerivedCrystalStructureAdapter( - HasCustomPQConfig, CrystalStructureAdapter): + +class DerivedCrystalStructureAdapter(HasCustomPQConfig, CrystalStructureAdapter): pass + # End of file diff --git a/src/diffpy/srreal/version.py b/src/diffpy/srreal/version.py index 8d8feeba..a078d249 100644 --- a/src/diffpy/srreal/version.py +++ b/src/diffpy/srreal/version.py @@ -25,8 +25,7 @@ Use `libdiffpy_version_info.git_commit` instead. """ -__all__ = ['__date__', '__git_commit__', '__timestamp__', '__version__', - 'libdiffpy_version_info'] +__all__ = ["__date__", "__git_commit__", "__timestamp__", "__version__", "libdiffpy_version_info"] from diffpy.srreal._version_data import __version__ @@ -43,22 +42,24 @@ from diffpy.srreal.srreal_ext import _get_libdiffpy_version_info_dict libdiffpy_version_info = namedtuple( - 'libdiffpy_version_info', + "libdiffpy_version_info", "major minor micro patch version_number version date git_commit " + # TODO remove git_sha in version 1.4. - "git_sha") + "git_sha", +) vd = _get_libdiffpy_version_info_dict() libdiffpy_version_info = libdiffpy_version_info( - version = vd['version_str'], - version_number = vd['version'], - major = vd['major'], - minor = vd['minor'], - micro = vd['micro'], - patch = vd['patch'], - date = vd['date'], - git_commit = vd['git_commit'], - # TODO remove git_sha in version 1.4. - git_sha = vd['git_commit']) + version=vd["version_str"], + version_number=vd["version"], + major=vd["major"], + minor=vd["minor"], + micro=vd["micro"], + patch=vd["patch"], + date=vd["date"], + git_commit=vd["git_commit"], + # TODO remove git_sha in version 1.4. + git_sha=vd["git_commit"], +) del vd # End of file diff --git a/src/diffpy/srreal/wraputils.py b/src/diffpy/srreal/wraputils.py index 79261ec3..e9eb19e1 100644 --- a/src/diffpy/srreal/wraputils.py +++ b/src/diffpy/srreal/wraputils.py @@ -21,25 +21,29 @@ # Routines ------------------------------------------------------------------- + def propertyFromExtDoubleAttr(attrname, doc): - '''Create property wrapper to a DoubleAttr in C++ extension object. + """Create property wrapper to a DoubleAttr in C++ extension object. attrname -- string name of the double attribute doc -- docstring for the Python class property Return a property object. - ''' + """ + def fget(self): return self._getDoubleAttr(attrname) + def fset(self, value): self._setDoubleAttr(attrname, value) return + rv = property(fget, fset, doc=doc) return rv def setattrFromKeywordArguments(obj, **kwargs): - '''Set attributes of the obj according to keyword arguments. + """Set attributes of the obj according to keyword arguments. For example: setattrFromKeywordArguments(obj, qmax=24, scale=2) This is a shared helper function used by __init__ and __call__. @@ -47,7 +51,7 @@ def setattrFromKeywordArguments(obj, **kwargs): No return value. Raise TypeError for invalid keyword argument. - ''' + """ for n in kwargs: if not hasattr(obj, n): emsg = "Invalid keyword argument %r" % n @@ -58,7 +62,7 @@ def setattrFromKeywordArguments(obj, **kwargs): def _wrapAsRegisteredUnaryFunction(cls, regname, fnc, replace=False, **dbattrs): - '''Helper function for wrapping Python function as PDFBaseline or + """Helper function for wrapping Python function as PDFBaseline or PDFEnvelope functor. Not intended for direct usage, this function is rather called from makePDFBaseline or makePDFEnvelope wrappers. @@ -79,33 +83,31 @@ def _wrapAsRegisteredUnaryFunction(cls, regname, fnc, replace=False, **dbattrs): fnc(x, **dbattrs). Return an instance of the functor class. - ''' + """ + class RegisteredUnaryFunction(cls): def create(self): - '''Create new instance of the same type as self. - ''' + """Create new instance of the same type as self.""" return RegisteredUnaryFunction() def clone(self): - '''Return a new duplicate instance of self. - ''' + """Return a new duplicate instance of self.""" return copy.copy(self) def type(self): - '''Unique string identifier of this functor type. The string + """Unique string identifier of this functor type. The string is used for class registration and as an argument for the createByType function. Return string identifier. - ''' + """ return regname def __call__(self, x): - '''Evaluate this functor at x. - ''' + """Evaluate this functor at x.""" if dbattrs: - kw = {n : getattr(self, n) for n in dbattrs} + kw = {n: getattr(self, n) for n in dbattrs} rv = fnc(x, **kw) else: rv = fnc(x) @@ -126,7 +128,7 @@ def __reduce__(self): if replace: RegisteredUnaryFunction._deregisterType(regname) - RegisteredUnaryFunction.__name__ = 'User' + cls.__name__ + '_' + regname + RegisteredUnaryFunction.__name__ = "User" + cls.__name__ + "_" + regname RegisteredUnaryFunction.__getstate__ = _pickle_getstate RegisteredUnaryFunction.__setstate__ = _pickle_setstate RegisteredUnaryFunction()._registerThisType() @@ -134,21 +136,25 @@ def __reduce__(self): assert type(rv) is RegisteredUnaryFunction return rv + # pickling support functions + def _regunary_create(cls, tp): return cls.createByType(tp) + def _pickle_getstate(self): state = (self.__dict__,) return state + def _pickle_setstate(self, state): if len(state) != 1: - emsg = ("expected 1-item tuple in call to __setstate__, got " + - repr(state)) + emsg = "expected 1-item tuple in call to __setstate__, got " + repr(state) raise ValueError(emsg) self.__dict__.update(state[0]) return + # End of file From 5df5dfbff1e5ccf3d30beae5e0f28a7032bbfb8f Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Wed, 1 Jan 2025 18:00:21 -0500 Subject: [PATCH 03/55] add precommit and fix related checks --- .codespell/ignore_lines.txt | 2 + .codespell/ignore_words.txt | 29 ++++ .flake8 | 13 ++ .isort.cfg | 5 + .pre-commit-config.yaml | 67 +++++++++ .prettierignore | 1 + .travis.yml | 130 ------------------ README.rst | 2 +- devutils/makesdist | 40 +++--- devutils/tunePeakPrecision.py | 28 ++-- doc/manual/source/conf.py | 5 +- examples/compareC60PDFs.py | 9 +- examples/compareC60PDFs_objcryst.py | 8 +- examples/datafiles/menthol.cif | 24 ++-- examples/distanceprinter.py | 10 +- examples/lennardjones/ljcalculator.py | 7 +- examples/parallelPDF.py | 25 ++-- requirements/build.txt | 3 +- requirements/conda.txt | 4 +- setup.py | 7 +- src/diffpy/__init__.py | 1 - src/diffpy/srreal/__init__.py | 4 +- src/diffpy/srreal/_cleanup.py | 5 +- src/diffpy/srreal/_docstrings.py | 5 +- src/diffpy/srreal/_final_imports.py | 8 +- src/diffpy/srreal/_version_data.py | 5 +- src/diffpy/srreal/atomradiitable.py | 11 +- src/diffpy/srreal/attributes.py | 9 +- src/diffpy/srreal/bondcalculator.py | 12 +- src/diffpy/srreal/bvparameterstable.py | 6 +- src/diffpy/srreal/bvscalculator.py | 7 +- src/diffpy/srreal/eventticker.py | 5 +- src/diffpy/srreal/overlapcalculator.py | 12 +- src/diffpy/srreal/pairquantity.py | 5 +- src/diffpy/srreal/parallel.py | 22 +-- src/diffpy/srreal/pdfbaseline.py | 8 +- src/diffpy/srreal/pdfcalculator.py | 29 ++-- src/diffpy/srreal/pdfenvelope.py | 15 +- src/diffpy/srreal/peakprofile.py | 4 +- src/diffpy/srreal/peakwidthmodel.py | 4 +- src/diffpy/srreal/scatteringfactortable.py | 12 +- src/diffpy/srreal/sfaverage.py | 18 +-- src/diffpy/srreal/structureadapter.py | 46 ++++--- src/diffpy/srreal/structureconverters.py | 40 +++--- src/diffpy/srreal/tests/__init__.py | 9 +- src/diffpy/srreal/tests/debug.py | 5 +- src/diffpy/srreal/tests/run.py | 6 +- src/diffpy/srreal/tests/testatomradiitable.py | 47 ++++--- src/diffpy/srreal/tests/testattributes.py | 20 +-- src/diffpy/srreal/tests/testbondcalculator.py | 51 +++---- src/diffpy/srreal/tests/testbvscalculator.py | 30 ++-- src/diffpy/srreal/tests/testdata/Ni.stru | 4 +- .../srreal/tests/testdebyepdfcalculator.py | 28 ++-- .../srreal/tests/testoverlapcalculator.py | 76 +++++----- src/diffpy/srreal/tests/testpairquantity.py | 30 ++-- src/diffpy/srreal/tests/testparallel.py | 15 +- src/diffpy/srreal/tests/testpdfbaseline.py | 39 +++--- .../srreal/tests/testpdfcalcobjcryst.py | 18 ++- src/diffpy/srreal/tests/testpdfcalculator.py | 33 ++--- src/diffpy/srreal/tests/testpdfenvelope.py | 39 +++--- src/diffpy/srreal/tests/testpeakprofile.py | 29 ++-- src/diffpy/srreal/tests/testpeakwidthmodel.py | 39 +++--- .../srreal/tests/testscatteringfactortable.py | 30 ++-- src/diffpy/srreal/tests/testsfaverage.py | 21 +-- .../srreal/tests/teststructureadapter.py | 78 ++++++----- src/diffpy/srreal/tests/testutils.py | 17 +-- src/diffpy/srreal/version.py | 10 +- src/diffpy/srreal/wraputils.py | 14 +- 68 files changed, 683 insertions(+), 717 deletions(-) create mode 100644 .codespell/ignore_lines.txt create mode 100644 .codespell/ignore_words.txt create mode 100644 .flake8 create mode 100644 .isort.cfg create mode 100644 .pre-commit-config.yaml create mode 100644 .prettierignore delete mode 100644 .travis.yml diff --git a/.codespell/ignore_lines.txt b/.codespell/ignore_lines.txt new file mode 100644 index 00000000..07fa7c8c --- /dev/null +++ b/.codespell/ignore_lines.txt @@ -0,0 +1,2 @@ +;; Please include filenames and explanations for each ignored line. +;; See https://docs.openverse.org/meta/codespell.html for docs. diff --git a/.codespell/ignore_words.txt b/.codespell/ignore_words.txt new file mode 100644 index 00000000..3b490070 --- /dev/null +++ b/.codespell/ignore_words.txt @@ -0,0 +1,29 @@ +;; Please include explanations for each ignored word (lowercase). +;; See https://docs.openverse.org/meta/codespell.html for docs. + +;; abbreviation for "materials" often used in a journal title +mater + +;; alternative use of socioeconomic +socio-economic + +;; Frobenius norm used in np.linalg.norm +fro + +;; abbreviation for "structure" +struc + +;; method name within JournalPanel class +onText + +;; a method name within JournalPanel class +delt + +;; structure file format +discus + +;; variable name within pdfbaseline module +aline + +;; variable name within TestSFAverageObjCryst class +fo diff --git a/.flake8 b/.flake8 new file mode 100644 index 00000000..04d2d0b0 --- /dev/null +++ b/.flake8 @@ -0,0 +1,13 @@ +# As of now, flake8 does not natively support configuration via pyproject.toml +# https://github.com/microsoft/vscode-flake8/issues/135 +[flake8] +exclude = + .git, + __pycache__, + build, + dist, + doc/source/conf.py +max-line-length = 115 +# Ignore some style 'errors' produced while formatting by 'black' +# https://black.readthedocs.io/en/stable/guides/using_black_with_other_tools.html#labels-why-pycodestyle-warnings +extend-ignore = E203 diff --git a/.isort.cfg b/.isort.cfg new file mode 100644 index 00000000..7ce0fb1f --- /dev/null +++ b/.isort.cfg @@ -0,0 +1,5 @@ +[settings] +# Keep import statement below line_length character limit +line_length = 115 +multi_line_output = 3 +include_trailing_comma = True diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000..754e5329 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,67 @@ +default_language_version: + python: python3 +ci: + autofix_commit_msg: | + [pre-commit.ci] auto fixes from pre-commit hooks + autofix_prs: true + autoupdate_branch: "pre-commit-autoupdate" + autoupdate_commit_msg: "[pre-commit.ci] pre-commit autoupdate" + autoupdate_schedule: monthly + skip: [no-commit-to-branch] + submodules: false +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.6.0 + hooks: + - id: check-yaml + exclude: ^conda-recipe/meta\.yaml$ + - id: end-of-file-fixer + - id: trailing-whitespace + - id: check-case-conflict + - id: check-merge-conflict + - id: check-toml + - id: check-added-large-files + - repo: https://github.com/psf/black + rev: 24.4.2 + hooks: + - id: black + - repo: https://github.com/pycqa/flake8 + rev: 7.0.0 + hooks: + - id: flake8 + - repo: https://github.com/pycqa/isort + rev: 5.13.2 + hooks: + - id: isort + args: ["--profile", "black"] + - repo: https://github.com/kynan/nbstripout + rev: 0.7.1 + hooks: + - id: nbstripout + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.4.0 + hooks: + - id: no-commit-to-branch + name: Prevent Commit to Main Branch + args: ["--branch", "main"] + stages: [pre-commit] + - repo: https://github.com/codespell-project/codespell + rev: v2.3.0 + hooks: + - id: codespell + additional_dependencies: + - tomli + # prettier - multi formatter for .json, .yml, and .md files + - repo: https://github.com/pre-commit/mirrors-prettier + rev: f12edd9c7be1c20cfa42420fd0e6df71e42b51ea # frozen: v4.0.0-alpha.8 + hooks: + - id: prettier + additional_dependencies: + - "prettier@^3.2.4" + # docformatter - PEP 257 compliant docstring formatter + - repo: https://github.com/s-weigand/docformatter + rev: 5757c5190d95e5449f102ace83df92e7d3b06c6c + hooks: + - id: docformatter + additional_dependencies: [tomli] + args: [--in-place, --config, ./pyproject.toml] diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..7f39adde --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +/conda-recipe/* diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index de49f467..00000000 --- a/.travis.yml +++ /dev/null @@ -1,130 +0,0 @@ -dist: xenial -language: generic - -os: - - linux - - osx - -env: - - MYUSEMC=true MYPYTHON_VERSION=2.7 - - MYUSEMC=true MYPYTHON_VERSION=3.5 - - MYUSEMC=true MYPYTHON_VERSION=3.6 - - MYUSEMC=true MYPYTHON_VERSION=3.7 - - MYUSEMC=false - -git: - depth: 999999 - -branches: - except: - - /^v[0-9]/ - - -before_install: - - MYNAME=diffpy.srreal - - MYCOMMIT="$(git rev-parse HEAD)" - - umask 022 - - git fetch origin --tags - - MYPYTHON=python; MYPIP=pip - - NOSYS=true; NOAPT=true; NOBREW=true; NOMC=true - - if ${MYUSEMC}; then - NOMC=false; - elif [[ ${TRAVIS_OS_NAME} == linux ]]; then - NOAPT=false; NOSYS=false; - MYPIPFLAGS="--user"; - elif [[ ${TRAVIS_OS_NAME} == osx ]]; then - NOBREW=false; NOSYS=false; - MYPYTHON=python3; - MYPIP=pip3; - MYPIPFLAGS="--user"; - fi - - MYMCREPO=https://repo.anaconda.com/miniconda - - case ${TRAVIS_OS_NAME} in - linux) - MYMCBUNDLE=Miniconda3-latest-Linux-x86_64.sh ;; - osx) - MYMCBUNDLE=Miniconda3-latest-MacOSX-x86_64.sh ;; - *) - echo "Unsupported operating system." >&2; - exit 2 ;; - esac - - MYRUNDIR=${PWD}/build/rundir - - - mkdir -p ~/pkgs - - mkdir -p ${MYRUNDIR} - - cp .coveragerc ${MYRUNDIR}/ - - - $NOMC || pushd ~/pkgs - - $NOMC || wget --timestamping ${MYMCREPO}/${MYMCBUNDLE} - - $NOMC || test -x ~/mc/bin/conda || bash ${MYMCBUNDLE} -b -f -p ~/mc - - $NOMC || popd - - $NOMC || source ~/mc/bin/activate base - - $NOMC || conda update --yes conda - - $NOMC || conda install --yes conda-build conda-verify jinja2 numpy - - $NOMC || conda create --name=testenv --yes python=${MYPYTHON_VERSION} coverage - - $NOMC || conda config --add channels diffpy - - - $NOAPT || test "${TRAVIS_OS_NAME}" = "linux" || exit $? - - $NOAPT || PATH="$(echo "$PATH" | sed 's,:/opt/pyenv/[^:]*,,g')" - - $NOAPT || test "$(which python)" = "/usr/bin/python" || ( - which python; exit 1) - - $NOAPT || sudo apt-get update -qq - - $NOAPT || sudo apt-get install -y - libgsl0-dev libboost-all-dev python-dev - python-setuptools python-numpy python-pyparsing - python-lxml python-pip build-essential scons - - - $NOBREW || test "${TRAVIS_OS_NAME}" = "osx" || exit $? - - $NOBREW || brew update - - $NOBREW || brew install gcc || brew link --overwrite gcc - - $NOBREW || brew install boost-python3 - - $NOBREW || brew install gsl - - $NOBREW || brew install scons - - - $NOSYS || devutils/makesdist - - $NOSYS || MYTARBUNDLE="$(ls -t "${PWD}"/dist/*.tar.gz | head -1)" - - $NOSYS || pushd ~/pkgs - - $NOSYS || git clone https://github.com/diffpy/libobjcryst.git - - $NOSYS || git clone https://github.com/diffpy/libdiffpy.git - - $NOSYS || popd - - -install: - - $NOMC || conda build --python=${MYPYTHON_VERSION} conda-recipe - - $NOMC || conda render --python=${MYPYTHON_VERSION} --output conda-recipe | - sed 's,.*/,,; s/[.]tar[.]bz2$//; s/-/=/g' > /tmp/mypackage.txt - - $NOMC || source activate testenv - - $NOMC || conda install --yes --use-local --file=/tmp/mypackage.txt - - - MYSUDO= - - $NOAPT || MYSUDO=sudo - - $NOSYS || $MYPIP install $MYPIPFLAGS coverage - - $NOSYS || $MYPIP install $MYPIPFLAGS periodictable - - $NOSYS || $MYPIP install $MYPIPFLAGS pycifrw - - $NOSYS || $MYPIP install $MYPIPFLAGS diffpy.structure - - - $NOSYS || $MYSUDO scons -C ~/pkgs/libobjcryst install - - $NOSYS || $MYPIP install $MYPIPFLAGS pyobjcryst - - $NOSYS || $MYSUDO scons -C ~/pkgs/libdiffpy install - - $NOSYS || $MYPIP install $MYPIPFLAGS "${MYTARBUNDLE}" - - - cd ${MYRUNDIR} - - MYGIT_REV=$($MYPYTHON -c "import ${MYNAME}.version as v; print(v.__git_commit__)") - - if [[ "${MYCOMMIT}" != "${MYGIT_REV}" ]]; then - echo "Version mismatch ${MYCOMMIT} vs ${MYGIT_REV}."; - exit 1; - fi - - -before_script: - - $NOBREW || USER_BASE="$(python3 -c 'import site; print(site.USER_BASE)')" - - $NOBREW || PATH="${USER_BASE}/bin:${PATH}" - - -script: - - coverage run --source ${MYNAME} -m ${MYNAME}.tests.run - - -after_success: - - $MYPIP install $MYPIPFLAGS codecov - - codecov diff --git a/README.rst b/README.rst index 3a87d0a5..f6388b27 100644 --- a/README.rst +++ b/README.rst @@ -114,7 +114,7 @@ parallel jobs (-j4) :: sudo scons -j4 install -See ``scons -h`` for decription of build targets and options. +See ``scons -h`` for description of build targets and options. DEVELOPMENT diff --git a/devutils/makesdist b/devutils/makesdist index 06e07d7c..10bba1ff 100755 --- a/devutils/makesdist +++ b/devutils/makesdist @@ -1,52 +1,56 @@ #!/usr/bin/env python -'''Create source distribution tar.gz archive, where each file belongs -to a root user and modification time is set to the git commit time. -''' +"""Create source distribution tar.gz archive, where each file belongs to a root +user and modification time is set to the git commit time.""" -import sys +import glob +import gzip import os import subprocess -import glob +import sys import tarfile -import gzip + +from setup import FALLBACK_VERSION, versiondata BASEDIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) sys.path.insert(0, BASEDIR) -from setup import versiondata, FALLBACK_VERSION -timestamp = versiondata.getint('DEFAULT', 'timestamp') +timestamp = versiondata.getint("DEFAULT", "timestamp") -vfb = versiondata.get('DEFAULT', 'version').split('.post')[0] + '.post0' +vfb = versiondata.get("DEFAULT", "version").split(".post")[0] + ".post0" emsg = "Invalid FALLBACK_VERSION. Expected %r got %r." assert vfb == FALLBACK_VERSION, emsg % (vfb, FALLBACK_VERSION) + def inform(s): sys.stdout.write(s) sys.stdout.flush() return + inform('Run "setup.py sdist --formats=tar" ') -cmd_sdist = ([sys.executable, '-Wignore:Cannot detect name suffix'] + - 'setup.py sdist --formats=tar'.split()) -ec = subprocess.call(cmd_sdist, cwd=BASEDIR, stdout=open(os.devnull, 'w')) -if ec: sys.exit(ec) +cmd_sdist = [sys.executable, "-Wignore:Cannot detect name suffix"] + "setup.py sdist --formats=tar".split() +ec = subprocess.call(cmd_sdist, cwd=BASEDIR, stdout=open(os.devnull, "w")) +if ec: + sys.exit(ec) inform("[done]\n") -tarname = max(glob.glob(BASEDIR + '/dist/*.tar'), key=os.path.getmtime) +tarname = max(glob.glob(BASEDIR + "/dist/*.tar"), key=os.path.getmtime) tfin = tarfile.open(tarname) -fpout = gzip.GzipFile(tarname + '.gz', 'w', mtime=0) -tfout = tarfile.open(fileobj=fpout, mode='w') +fpout = gzip.GzipFile(tarname + ".gz", "w", mtime=0) +tfout = tarfile.open(fileobj=fpout, mode="w") + def fixtarinfo(tinfo): tinfo.uid = tinfo.gid = 0 - tinfo.uname = tinfo.gname = 'root' + tinfo.uname = tinfo.gname = "root" tinfo.mtime = timestamp tinfo.mode &= ~0o022 return tinfo -inform('Filter %s --> %s.gz ' % (2 * (os.path.basename(tarname),))) + +inform("Filter %s --> %s.gz " % (2 * (os.path.basename(tarname),))) for ti in tfin: tfout.addfile(fixtarinfo(ti), tfin.extractfile(ti)) diff --git a/devutils/tunePeakPrecision.py b/devutils/tunePeakPrecision.py index e46c9616..c6f3cc94 100755 --- a/devutils/tunePeakPrecision.py +++ b/devutils/tunePeakPrecision.py @@ -1,11 +1,21 @@ #!/usr/bin/env python -"""Tune the peak precision parameter so that PDFCalculator -gives equivalent results to diffpy.pdffit2. +"""Tune the peak precision parameter so that PDFCalculator gives equivalent +results to diffpy.pdffit2. Usage: tunePeakPrecision.py [qmax] [peakprecision] [createplot] """ +# global imports +import sys +import time + +import numpy + +import diffpy.pdffit2 +from diffpy.srreal.pdf_ext import PDFCalculator +from diffpy.structure import Structure + # Results: # Qmax peakprecision CPU Notes # 15 3.2e-6 clear minimum @@ -21,16 +31,6 @@ peakprecision = None createplot = False -# global imports -import sys -import time - -import numpy - -from diffpy.structure import Structure -from diffpy.srreal.pdf_ext import PDFCalculator -import diffpy.pdffit2 - # make PdfFit silent diffpy.pdffit2.redirect_stdout(open("/dev/null", "w")) @@ -52,7 +52,7 @@ def Gpdffit2(qmax): - """Calculate reference nickel PDF using diffpy.pdffit2 + """Calculate reference nickel PDF using diffpy.pdffit2. qmax -- vawevector cutoff value in 1/A @@ -68,7 +68,7 @@ def Gpdffit2(qmax): def Gsrreal(qmax, peakprecision=None): - """Calculate nickel PDF using PDFCalculator from diffpy.srreal + """Calculate nickel PDF using PDFCalculator from diffpy.srreal. qmax -- vawevector cutoff value in 1/A peakprecision -- precision factor affecting peak cutoff, diff --git a/doc/manual/source/conf.py b/doc/manual/source/conf.py index 307ec098..326acdd8 100644 --- a/doc/manual/source/conf.py +++ b/doc/manual/source/conf.py @@ -12,10 +12,12 @@ # All configuration values have a default; values that are commented out # serve to show the default. -import sys import os +import sys import time +from setup import versiondata + # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. @@ -61,7 +63,6 @@ # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. -from setup import versiondata fullversion = versiondata.get("DEFAULT", "version") # The short X.Y version. diff --git a/examples/compareC60PDFs.py b/examples/compareC60PDFs.py index 03311ec1..844cd7a6 100755 --- a/examples/compareC60PDFs.py +++ b/examples/compareC60PDFs.py @@ -1,14 +1,17 @@ #!/usr/bin/env python """Plot C60 PDFs calculated with PDFCalculator and DebyePDFCalculator. + The C60 molecule is held in a diffpy Structure object. """ -import sys import os -from matplotlib.pyplot import plot, show, clf +import sys + +from matplotlib.pyplot import clf, plot, show + +from diffpy.srreal.pdfcalculator import DebyePDFCalculator, PDFCalculator from diffpy.structure import Structure -from diffpy.srreal.pdfcalculator import PDFCalculator, DebyePDFCalculator mydir = os.path.dirname(os.path.abspath(sys.argv[0])) buckyfile = os.path.join(mydir, "datafiles", "C60bucky.stru") diff --git a/examples/compareC60PDFs_objcryst.py b/examples/compareC60PDFs_objcryst.py index 69c9143a..62e705d0 100755 --- a/examples/compareC60PDFs_objcryst.py +++ b/examples/compareC60PDFs_objcryst.py @@ -1,15 +1,17 @@ #!/usr/bin/env python """Plot C60 PDFs calculated with PDFCalculator and DebyePDFCalculator. + The C60 molecule are stored in a pyobjcryst object. """ -from matplotlib.pyplot import plot, show, clf -from diffpy.structure import Structure +from matplotlib.pyplot import clf, plot, show from pyobjcryst.crystal import Crystal from pyobjcryst.molecule import Molecule from pyobjcryst.scatteringpower import ScatteringPowerAtom -from diffpy.srreal.pdfcalculator import PDFCalculator, DebyePDFCalculator + +from diffpy.srreal.pdfcalculator import DebyePDFCalculator, PDFCalculator +from diffpy.structure import Structure # load C60 molecule as a diffpy.structure object bucky_diffpy = Structure(filename="datafiles/C60bucky.stru") diff --git a/examples/datafiles/menthol.cif b/examples/datafiles/menthol.cif index c8c7e6e2..1ff0ca8b 100644 --- a/examples/datafiles/menthol.cif +++ b/examples/datafiles/menthol.cif @@ -2,26 +2,26 @@ ########################################################################### # # Cambridge Crystallographic Data Centre -# CCDC -# +# CCDC +# ########################################################################### # # This CIF contains data generated directly from one or more entries in -# the Cambridge Structural Database and will include bibliographic, +# the Cambridge Structural Database and will include bibliographic, # chemical, crystal, experimental, refinement, and atomic coordinate data, # as available. -# +# # Copyright 2008 The Cambridge Crystallographic Data Centre -# -# This CIF is provided on the understanding that it is used for bona fide +# +# This CIF is provided on the understanding that it is used for bona fide # research purposes only. It may contain copyright material of the CCDC -# or of third parties, and may not be copied or further disseminated in -# any form, whether machine-readable or not, except for the purpose of +# or of third parties, and may not be copied or further disseminated in +# any form, whether machine-readable or not, except for the purpose of # generating routine backup copies on your local computer system. -# -# For further information about the CCDC, data deposition and data -# retrieval see . Bona fide researchers may freely -# download Mercury and enCIFer from this site to visualise CIF-encoded +# +# For further information about the CCDC, data deposition and data +# retrieval see . Bona fide researchers may freely +# download Mercury and enCIFer from this site to visualise CIF-encoded # structures and to carry out CIF format checking respectively. # ########################################################################### diff --git a/examples/distanceprinter.py b/examples/distanceprinter.py index c28409b0..a4b95984 100755 --- a/examples/distanceprinter.py +++ b/examples/distanceprinter.py @@ -1,17 +1,15 @@ #!/usr/bin/env python -"""Demonstration of using PairQuantity class for a printout -of pair distances in periodic and non-periodic structures. -""" +"""Demonstration of using PairQuantity class for a printout of pair distances +in periodic and non-periodic structures.""" from diffpy.srreal.pairquantity import PairQuantity from diffpy.structure import Structure class DistancePrinter(PairQuantity): - """This PairQuantity class simply prints the visited pair distances - and the indices of the contributing atoms. - """ + """This PairQuantity class simply prints the visited pair distances and the + indices of the contributing atoms.""" def _resetValue(self): self.count = 0 diff --git a/examples/lennardjones/ljcalculator.py b/examples/lennardjones/ljcalculator.py index e4a43f29..5dc5d852 100755 --- a/examples/lennardjones/ljcalculator.py +++ b/examples/lennardjones/ljcalculator.py @@ -1,12 +1,13 @@ #!/usr/bin/env python -"""Demonstration of using PairQuantity class for calculation -of Lennard Jones potential. +"""Demonstration of using PairQuantity class for calculation of Lennard Jones +potential. Vij = 4 * ( rij ** -12 - rij ** -6 ) """ import sys + from diffpy.srreal.pairquantity import PairQuantity from diffpy.structure import Structure @@ -20,7 +21,7 @@ def __init__(self): return def __call__(self, structure): - """Return LJ potential for a specified structure""" + """Return LJ potential for a specified structure.""" values = self.eval(structure) return values[0] diff --git a/examples/parallelPDF.py b/examples/parallelPDF.py index 89a62f37..30516398 100755 --- a/examples/parallelPDF.py +++ b/examples/parallelPDF.py @@ -1,19 +1,23 @@ #!/usr/bin/env python -"""Demonstration of parallel PDF calculation using the multiprocessing -package. A PDF of menthol structure is first calculated on a single core -and then on all computer CPUs. The script then compares both results -and prints elapsed time per each calculation. +"""Demonstration of parallel PDF calculation using the multiprocessing package. + +A PDF of menthol structure is first calculated on a single core and then +on all computer CPUs. The script then compares both results and prints +elapsed time per each calculation. """ +import multiprocessing +import optparse import os import sys -import optparse import time -import multiprocessing -from diffpy.structure import Structure -from diffpy.srreal.pdfcalculator import PDFCalculator + +from matplotlib.pyplot import clf, plot, show + from diffpy.srreal.parallel import createParallelCalculator +from diffpy.srreal.pdfcalculator import PDFCalculator +from diffpy.structure import Structure mydir = os.path.dirname(os.path.abspath(__file__)) mentholcif = os.path.join(mydir, "datafiles", "menthol.cif") @@ -28,8 +32,8 @@ # load menthol structure and make sure Uiso values are non-zero if opts.pyobjcryst: # use pyobjcryst if requested by the user - from pyobjcryst import loadCrystal from numpy import pi + from pyobjcryst import loadCrystal menthol = loadCrystal(mentholcif) for sc in menthol.GetScatteringComponentList(): @@ -62,7 +66,7 @@ pool = multiprocessing.Pool(processes=ncpu) t1 = time.time() -# create a proxy parrallel calculator to PDFCalculator pc0, +# create a proxy parallel calculator to PDFCalculator pc0, # that uses ncpu parallel jobs submitted via pool.imap_unordered pc1 = createParallelCalculator(pc0, ncpu, pool.imap_unordered) r1, g1 = pc1(menthol) @@ -71,7 +75,6 @@ print("Time ratio: %g" % (t0 / t1)) # plot both results and the difference curve -from matplotlib.pyplot import plot, show, clf clf() gd = g0 - g1 diff --git a/requirements/build.txt b/requirements/build.txt index f72d870d..b050e013 100644 --- a/requirements/build.txt +++ b/requirements/build.txt @@ -1,2 +1,3 @@ python -setuptools +boost +numpy diff --git a/requirements/conda.txt b/requirements/conda.txt index 5e7d3831..af3f87d8 100644 --- a/requirements/conda.txt +++ b/requirements/conda.txt @@ -1,3 +1,5 @@ -numpy boost +numpy +setuptools diffpy.structure +periodictable diff --git a/setup.py b/setup.py index 5611ed7f..ea931a64 100644 --- a/setup.py +++ b/setup.py @@ -6,12 +6,13 @@ Packages: diffpy.srreal """ -import numpy -import sys import glob -from setuptools import setup, Extension +import sys from ctypes.util import find_library +import numpy +from setuptools import Extension, setup + def get_boost_libraries(): base_lib = "boost_python" diff --git a/src/diffpy/__init__.py b/src/diffpy/__init__.py index bb399140..e8b7ec78 100644 --- a/src/diffpy/__init__.py +++ b/src/diffpy/__init__.py @@ -12,7 +12,6 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - """diffpy - tools for structure analysis by diffraction. Blank namespace package. diff --git a/src/diffpy/srreal/__init__.py b/src/diffpy/srreal/__init__.py index 1d3d7206..7c62d5f3 100644 --- a/src/diffpy/srreal/__init__.py +++ b/src/diffpy/srreal/__init__.py @@ -12,9 +12,7 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - -"""Tools for real space structure analysis. -""" +"""Tools for real space structure analysis.""" # package version from diffpy.srreal._version_data import __version__ diff --git a/src/diffpy/srreal/_cleanup.py b/src/diffpy/srreal/_cleanup.py index 1e7cc517..19fdffd2 100644 --- a/src/diffpy/srreal/_cleanup.py +++ b/src/diffpy/srreal/_cleanup.py @@ -12,9 +12,7 @@ # See LICENSE.txt for license information. # ############################################################################## - -""" -Cancel registration of Python-extended C++ classes when Python exits. +"""Cancel registration of Python-extended C++ classes when Python exits. Note ---- @@ -30,7 +28,6 @@ class prototypes is implemented in libdiffpy. Any Python-extended classes import atexit import weakref - # Routine to be used from srreal_ext module ---------------------------------- diff --git a/src/diffpy/srreal/_docstrings.py b/src/diffpy/srreal/_docstrings.py index fee8ab07..ab2cb889 100644 --- a/src/diffpy/srreal/_docstrings.py +++ b/src/diffpy/srreal/_docstrings.py @@ -12,10 +12,7 @@ # See LICENSE.txt for license information. # ############################################################################## - -""" -Docstrings for classes and functions in srreal_ext module. -""" +"""Docstrings for classes and functions in srreal_ext module.""" # Shared docstrings for classes derived from HasClassRegistry ---------------- diff --git a/src/diffpy/srreal/_final_imports.py b/src/diffpy/srreal/_final_imports.py index 236eaf57..273f106f 100644 --- a/src/diffpy/srreal/_final_imports.py +++ b/src/diffpy/srreal/_final_imports.py @@ -12,9 +12,7 @@ # See LICENSE.txt for license information. # ############################################################################## - -""" -Finalize tweak of classes from the extension module srreal_ext. +"""Finalize tweak of classes from the extension module srreal_ext. This private module handles loading of Python-level tweaks of the extension-defined classes. Any client that imports this module @@ -27,9 +25,7 @@ def import_now(): - """ - Import all Python modules that tweak extension-defined classes. - """ + """Import all Python modules that tweak extension-defined classes.""" global _import_now_called if _import_now_called: return diff --git a/src/diffpy/srreal/_version_data.py b/src/diffpy/srreal/_version_data.py index 8c1a4f46..b3828e8d 100644 --- a/src/diffpy/srreal/_version_data.py +++ b/src/diffpy/srreal/_version_data.py @@ -12,9 +12,7 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - -""" -Extraction of version data for diffpy.srreal package +"""Extraction of version data for diffpy.srreal package. Does not import any extension module unlike the `version` module. """ @@ -25,7 +23,6 @@ from pkg_resources import resource_filename - # obtain version information from the version.cfg file cp = dict(version="", date="", commit="", timestamp="0") fcfg = resource_filename(__name__, "version.cfg") diff --git a/src/diffpy/srreal/atomradiitable.py b/src/diffpy/srreal/atomradiitable.py index fe5016aa..9d1f03fa 100644 --- a/src/diffpy/srreal/atomradiitable.py +++ b/src/diffpy/srreal/atomradiitable.py @@ -12,9 +12,7 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - -"""class AtomRadiiTable -- storage of empirical atom radii. -""" +"""Class AtomRadiiTable -- storage of empirical atom radii.""" # exported items, these also makes them show in pydoc. @@ -27,6 +25,7 @@ class CovalentRadiiTable(AtomRadiiTable): """Covalent radii from Cordero et al., 2008, doi:10.1039/b801115j. + Instantiation of this class requires the periodictable module. """ @@ -64,9 +63,9 @@ def clone(self): return copy.copy(self) def type(self): - """Unique string identifier of the CovalentRadiiTable type. - This is used for class registration and as an argument for the - createByType function. + """Unique string identifier of the CovalentRadiiTable type. This is + used for class registration and as an argument for the createByType + function. Return string. """ diff --git a/src/diffpy/srreal/attributes.py b/src/diffpy/srreal/attributes.py index ad0452d6..e0326a92 100644 --- a/src/diffpy/srreal/attributes.py +++ b/src/diffpy/srreal/attributes.py @@ -12,7 +12,6 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - """class Attributes -- wrapper to C++ class diffpy::Attributes A base to PairQuantity and quite a few other classes. """ @@ -54,12 +53,16 @@ def _setattr(self, name, value): def _pyattrgetter(name): - f = lambda obj: object.__getattribute__(obj, name) + def f(obj): + return object.__getattribute__(obj, name) + return f def _pyattrsetter(name): - f = lambda obj, value: object.__setattr__(obj, name, value) + def f(obj, value): + object.__setattr__(obj, name, value) + return f diff --git a/src/diffpy/srreal/bondcalculator.py b/src/diffpy/srreal/bondcalculator.py index d7f410cd..2d9a68de 100644 --- a/src/diffpy/srreal/bondcalculator.py +++ b/src/diffpy/srreal/bondcalculator.py @@ -12,17 +12,14 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - -"""class BondCalculator -- distances between atoms in the structure. -""" +"""Class BondCalculator -- distances between atoms in the structure.""" # exported items, these also makes them show in pydoc. __all__ = ["BondCalculator"] -from diffpy.srreal.wraputils import propertyFromExtDoubleAttr -from diffpy.srreal.wraputils import setattrFromKeywordArguments from diffpy.srreal.srreal_ext import BondCalculator +from diffpy.srreal.wraputils import propertyFromExtDoubleAttr, setattrFromKeywordArguments # property wrappers to C++ double attributes @@ -43,9 +40,8 @@ def _init_kwargs(self, **kwargs): - """Create a new instance of BondCalculator. - Keyword arguments can be used to configure - calculator properties, for example: + """Create a new instance of BondCalculator. Keyword arguments can be used + to configure calculator properties, for example: bdc = BondCalculator(rmin=1.5, rmax=2.5) diff --git a/src/diffpy/srreal/bvparameterstable.py b/src/diffpy/srreal/bvparameterstable.py index 9d963fca..6d6d9242 100644 --- a/src/diffpy/srreal/bvparameterstable.py +++ b/src/diffpy/srreal/bvparameterstable.py @@ -12,10 +12,8 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - -"""class BVParametersTable -- storage of bond valence parameters -class BVParam -- bond valence data associated with specific cation-anion pair -""" +"""Class BVParametersTable -- storage of bond valence parameters class BVParam +-- bond valence data associated with specific cation-anion pair.""" # exported items, these also makes them show in pydoc. diff --git a/src/diffpy/srreal/bvscalculator.py b/src/diffpy/srreal/bvscalculator.py index 2e1cb1c1..7cc1bced 100644 --- a/src/diffpy/srreal/bvscalculator.py +++ b/src/diffpy/srreal/bvscalculator.py @@ -12,17 +12,14 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - -"""class BVSCalculator -- bond valence sums calculator -""" +"""Class BVSCalculator -- bond valence sums calculator.""" # exported items __all__ = ["BVSCalculator"] from diffpy.srreal.srreal_ext import BVSCalculator -from diffpy.srreal.wraputils import propertyFromExtDoubleAttr -from diffpy.srreal.wraputils import setattrFromKeywordArguments +from diffpy.srreal.wraputils import propertyFromExtDoubleAttr, setattrFromKeywordArguments # Property wrappers to C++ double attributes diff --git a/src/diffpy/srreal/eventticker.py b/src/diffpy/srreal/eventticker.py index ecec69ac..35b74877 100644 --- a/src/diffpy/srreal/eventticker.py +++ b/src/diffpy/srreal/eventticker.py @@ -12,10 +12,7 @@ # See LICENSE.txt for license information. # ############################################################################## - -""" -class EventTicker -- storage of modification times of dependent objects -""" +"""Class EventTicker -- storage of modification times of dependent objects.""" # exported items diff --git a/src/diffpy/srreal/overlapcalculator.py b/src/diffpy/srreal/overlapcalculator.py index c99aed61..9747a221 100644 --- a/src/diffpy/srreal/overlapcalculator.py +++ b/src/diffpy/srreal/overlapcalculator.py @@ -12,17 +12,14 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - -"""class OverlapCalculator -- calculator of atom overlaps in a structure. -""" +"""Class OverlapCalculator -- calculator of atom overlaps in a structure.""" # exported items, these also makes them show in pydoc. __all__ = ["OverlapCalculator"] -from diffpy.srreal.wraputils import propertyFromExtDoubleAttr -from diffpy.srreal.wraputils import setattrFromKeywordArguments from diffpy.srreal.srreal_ext import OverlapCalculator +from diffpy.srreal.wraputils import propertyFromExtDoubleAttr, setattrFromKeywordArguments # property wrappers to C++ double attributes @@ -50,9 +47,8 @@ def _init_kwargs(self, **kwargs): - """Create a new instance of OverlapCalculator. - Keyword arguments can be used to configure - calculator properties, for example: + """Create a new instance of OverlapCalculator. Keyword arguments can be + used to configure calculator properties, for example: olc = OverlapCalculator(rmax=2.5) diff --git a/src/diffpy/srreal/pairquantity.py b/src/diffpy/srreal/pairquantity.py index bba56c6b..a8eaa058 100644 --- a/src/diffpy/srreal/pairquantity.py +++ b/src/diffpy/srreal/pairquantity.py @@ -12,10 +12,7 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - -""" -class PairQuantity -- base class for Python defined calculators. -""" +"""Class PairQuantity -- base class for Python defined calculators.""" # exported items diff --git a/src/diffpy/srreal/parallel.py b/src/diffpy/srreal/parallel.py index 413836a0..5ab113ee 100644 --- a/src/diffpy/srreal/parallel.py +++ b/src/diffpy/srreal/parallel.py @@ -12,7 +12,6 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - """ParallelPairQuantity -- proxy class for converting PairQuantity types into parallel calculators. """ @@ -23,6 +22,7 @@ import copy import inspect + from diffpy.srreal.attributes import Attributes # ---------------------------------------------------------------------------- @@ -43,8 +43,8 @@ def createParallelCalculator(pqobj, ncpu, pmap): """ class ParallelPairQuantity(Attributes): - """Class for running parallel calculations. This is a proxy class - to the wrapper PairQuantity type with the same interface. + """Class for running parallel calculations. This is a proxy class to + the wrapper PairQuantity type with the same interface. Instance data: @@ -100,8 +100,8 @@ def eval(self, stru=None): def __call__(self, *args, **kwargs): """Call the wrapped calculator using parallel evaluation. - The arguments and return value are the same as for the wrapped - PairQuantity calculator. + The arguments and return value are the same as for the + wrapped PairQuantity calculator. """ savedeval = self.pqobj.__dict__.get("eval") @@ -175,19 +175,25 @@ def _make_proxyproperty(prop): fget = fset = fdel = None if prop.fget: - def fget(self): + def _fget(self): return prop.fget(self.pqobj) + fget = _fget + if prop.fset: - def fset(self, value): + def _fset(self, value): return prop.fset(self.pqobj, value) + fset = _fset + if prop.fdel: - def fdel(self): + def _fdel(self): return prop.fdel(self.pqobj) + fdel = _fdel + return property(fget, fset, fdel, prop.__doc__) for n, p in inspect.getmembers(pqtype, lambda x: type(x) is property): diff --git a/src/diffpy/srreal/pdfbaseline.py b/src/diffpy/srreal/pdfbaseline.py index dc8581cc..22ced38b 100644 --- a/src/diffpy/srreal/pdfbaseline.py +++ b/src/diffpy/srreal/pdfbaseline.py @@ -12,7 +12,6 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - """ Classes for configuring PDF baseline: PDFBaseline, ZeroBaseline, LinearBaseline @@ -27,8 +26,7 @@ """.split() from diffpy.srreal import _final_imports -from diffpy.srreal.srreal_ext import PDFBaseline -from diffpy.srreal.srreal_ext import ZeroBaseline, LinearBaseline +from diffpy.srreal.srreal_ext import LinearBaseline, PDFBaseline, ZeroBaseline from diffpy.srreal.wraputils import propertyFromExtDoubleAttr # class PDFBaseline ---------------------------------------------------------- @@ -50,8 +48,8 @@ def makePDFBaseline(name, fnc, replace=False, **dbattrs): - """Helper function for registering Python function as a PDFBaseline. - This is required for using Python function as PDFCalculator.baseline. + """Helper function for registering Python function as a PDFBaseline. This + is required for using Python function as PDFCalculator.baseline. name -- unique string name for registering Python function in the global registry of PDFBaseline types. This will be the diff --git a/src/diffpy/srreal/pdfcalculator.py b/src/diffpy/srreal/pdfcalculator.py index 5c30cf16..b1c9d125 100644 --- a/src/diffpy/srreal/pdfcalculator.py +++ b/src/diffpy/srreal/pdfcalculator.py @@ -12,13 +12,14 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - """ Top-level classes for PDF calculation: DebyePDFCalculator -- simulate PDF by evaluating Debye sum in Q-space PDFCalculator -- calculate PDF by peak summation in real space """ +from diffpy.srreal.srreal_ext import DebyePDFCalculator, PDFCalculator, fftftog, fftgtof +from diffpy.srreal.wraputils import propertyFromExtDoubleAttr, setattrFromKeywordArguments # exported items __all__ = """ @@ -26,27 +27,21 @@ fftftog fftgtof """.split() -from diffpy.srreal.srreal_ext import DebyePDFCalculator -from diffpy.srreal.srreal_ext import PDFCalculator -from diffpy.srreal.srreal_ext import fftftog, fftgtof -from diffpy.srreal.wraputils import propertyFromExtDoubleAttr -from diffpy.srreal.wraputils import setattrFromKeywordArguments - -# silence the pyflakes syntax checker -assert all((fftftog, fftgtof)) - # imports for backward compatibility -from diffpy.srreal.pdfbaseline import PDFBaseline, makePDFBaseline, ZeroBaseline, LinearBaseline +from diffpy.srreal.pdfbaseline import LinearBaseline, PDFBaseline, ZeroBaseline, makePDFBaseline from diffpy.srreal.pdfenvelope import ( PDFEnvelope, - makePDFEnvelope, QResolutionEnvelope, ScaleEnvelope, SphericalShapeEnvelope, StepCutEnvelope, + makePDFEnvelope, ) from diffpy.srreal.peakprofile import PeakProfile -from diffpy.srreal.peakwidthmodel import PeakWidthModel, ConstantPeakWidth, DebyeWallerPeakWidth, JeongPeakWidth +from diffpy.srreal.peakwidthmodel import ConstantPeakWidth, DebyeWallerPeakWidth, JeongPeakWidth, PeakWidthModel + +# silence the pyflakes syntax checker +assert all((fftftog, fftgtof)) # silence the pyflakes syntax checker assert all( @@ -148,10 +143,10 @@ def _defineCommonInterface(cls): ) def _call_kwargs(self, structure=None, **kwargs): - """Calculate PDF for the given structure as an (r, G) tuple. - Keyword arguments can be used to configure calculator attributes, - these override any properties that may be passed from the structure, - such as spdiameter. + """Calculate PDF for the given structure as an (r, G) tuple. Keyword + arguments can be used to configure calculator attributes, these + override any properties that may be passed from the structure, such as + spdiameter. structure -- a structure object to be evaluated. Reuse the last structure when None. diff --git a/src/diffpy/srreal/pdfenvelope.py b/src/diffpy/srreal/pdfenvelope.py index e43a345a..594e80d9 100644 --- a/src/diffpy/srreal/pdfenvelope.py +++ b/src/diffpy/srreal/pdfenvelope.py @@ -12,7 +12,6 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - """ Classes for configuring PDF scaling envelope: PDFEnvelope, ScaleEnvelope, QResolutionEnvelope, @@ -30,9 +29,13 @@ """.split() from diffpy.srreal import _final_imports -from diffpy.srreal.srreal_ext import PDFEnvelope -from diffpy.srreal.srreal_ext import ScaleEnvelope, QResolutionEnvelope -from diffpy.srreal.srreal_ext import SphericalShapeEnvelope, StepCutEnvelope +from diffpy.srreal.srreal_ext import ( + PDFEnvelope, + QResolutionEnvelope, + ScaleEnvelope, + SphericalShapeEnvelope, + StepCutEnvelope, +) from diffpy.srreal.wraputils import propertyFromExtDoubleAttr # class PDFEnvelope ---------------------------------------------------------- @@ -74,8 +77,8 @@ def makePDFEnvelope(name, fnc, replace=False, **dbattrs): - """Helper function for registering Python function as a PDFEnvelope. - This is required for using Python function as PDFCalculator envelope. + """Helper function for registering Python function as a PDFEnvelope. This + is required for using Python function as PDFCalculator envelope. name -- unique string name for registering Python function in the global registry of PDFEnvelope types. This will be the diff --git a/src/diffpy/srreal/peakprofile.py b/src/diffpy/srreal/peakprofile.py index d082ac89..ff1044f7 100644 --- a/src/diffpy/srreal/peakprofile.py +++ b/src/diffpy/srreal/peakprofile.py @@ -12,7 +12,6 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - """ Class for configuring PDF profile function: PeakProfile @@ -24,8 +23,7 @@ __all__ = ["PeakProfile", "GaussianProfile", "CroppedGaussianProfile"] from diffpy.srreal import _final_imports -from diffpy.srreal.srreal_ext import PeakProfile -from diffpy.srreal.srreal_ext import GaussianProfile, CroppedGaussianProfile +from diffpy.srreal.srreal_ext import CroppedGaussianProfile, GaussianProfile, PeakProfile from diffpy.srreal.wraputils import propertyFromExtDoubleAttr # class PeakProfile ---------------------------------------------------------- diff --git a/src/diffpy/srreal/peakwidthmodel.py b/src/diffpy/srreal/peakwidthmodel.py index 75610987..cb0acb9b 100644 --- a/src/diffpy/srreal/peakwidthmodel.py +++ b/src/diffpy/srreal/peakwidthmodel.py @@ -12,7 +12,6 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - """ Classes for configuring peak width evaluation in PDF calculations: PeakWidthModel, @@ -24,8 +23,7 @@ __all__ = ["PeakWidthModel", "ConstantPeakWidth", "DebyeWallerPeakWidth", "JeongPeakWidth"] from diffpy.srreal import _final_imports -from diffpy.srreal.srreal_ext import PeakWidthModel, ConstantPeakWidth -from diffpy.srreal.srreal_ext import DebyeWallerPeakWidth, JeongPeakWidth +from diffpy.srreal.srreal_ext import ConstantPeakWidth, DebyeWallerPeakWidth, JeongPeakWidth, PeakWidthModel from diffpy.srreal.wraputils import propertyFromExtDoubleAttr # class PeakWidthModel ------------------------------------------------------- diff --git a/src/diffpy/srreal/scatteringfactortable.py b/src/diffpy/srreal/scatteringfactortable.py index 26f2ed3e..a53ce546 100644 --- a/src/diffpy/srreal/scatteringfactortable.py +++ b/src/diffpy/srreal/scatteringfactortable.py @@ -12,21 +12,15 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - -""" -class ScatteringFactorTable -- scattering factors for atoms, ions and isotopes. -""" +"""Class ScatteringFactorTable -- scattering factors for atoms, ions and +isotopes.""" # exported items, these also makes them show in pydoc. __all__ = ["ScatteringFactorTable", "SFTXray", "SFTElectron", "SFTNeutron", "SFTElectronNumber", "SFAverage"] -from diffpy.srreal.srreal_ext import ScatteringFactorTable -from diffpy.srreal.srreal_ext import SFTXray -from diffpy.srreal.srreal_ext import SFTElectron -from diffpy.srreal.srreal_ext import SFTNeutron -from diffpy.srreal.srreal_ext import SFTElectronNumber from diffpy.srreal.sfaverage import SFAverage +from diffpy.srreal.srreal_ext import ScatteringFactorTable, SFTElectron, SFTElectronNumber, SFTNeutron, SFTXray # Pickling Support ----------------------------------------------------------- diff --git a/src/diffpy/srreal/sfaverage.py b/src/diffpy/srreal/sfaverage.py index 46c61b12..5a1dde4d 100644 --- a/src/diffpy/srreal/sfaverage.py +++ b/src/diffpy/srreal/sfaverage.py @@ -12,10 +12,7 @@ # See LICENSE.txt for license information. # ############################################################################## - -""" -Compositional averaging of atom scattering factors. - +"""Compositional averaging of atom scattering factors. Examples -------- @@ -41,8 +38,7 @@ class SFAverage(object): - """\ - Calculate compositional statistics of atom scattering factors. + """Calculate compositional statistics of atom scattering factors. Compositional averages can be calculated for an array of Q-values. Results are stored in the class attributes. @@ -65,7 +61,7 @@ class SFAverage(object): Compositional average of squared scattering factors. Float or NumPy array. composition : - Dictionary of atom symbols and their total abundancies. + Dictionary of atom symbols and their total abundance. """ f1sum = 0 @@ -77,8 +73,7 @@ class SFAverage(object): @classmethod def fromStructure(cls, stru, sftb, q=0): - """\ - Calculate average scattering factors from a structure object. + """Calculate average scattering factors from a structure object. Parameters ---------- @@ -121,8 +116,7 @@ def fromStructure(cls, stru, sftb, q=0): @classmethod def fromComposition(cls, composition, sftb, q=0): - """\ - Calculate average scattering factors from atom concentrations. + """Calculate average scattering factors from atom concentrations. Parameters ---------- @@ -150,7 +144,7 @@ def fromComposition(cls, composition, sftb, q=0): sfa.composition.update(composition) else: for smbl, cnt in composition: - if not smbl in sfa.composition: + if smbl not in sfa.composition: sfa.composition[smbl] = 0 sfa.composition[smbl] += cnt sfa.f1sum = 0.0 * q diff --git a/src/diffpy/srreal/structureadapter.py b/src/diffpy/srreal/structureadapter.py index dc9fdc30..3abd19a0 100644 --- a/src/diffpy/srreal/structureadapter.py +++ b/src/diffpy/srreal/structureadapter.py @@ -12,9 +12,8 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - -"""class StructureAdapter -- adapter of any structure object to the interface - expected by srreal PairQuantity calculators +"""Class StructureAdapter -- adapter of any structure object to the interface +expected by srreal PairQuantity calculators. Routines: @@ -29,10 +28,25 @@ EMPTY -- singleton instance of an empty structure. """ +# import of srreal_ext calls RegisterStructureAdapter, therefore it has +# to be at the end of this module. + +from diffpy.srreal.srreal_ext import ( + Atom, + AtomicStructureAdapter, + BaseBondGenerator, + CrystalStructureAdapter, + PeriodicStructureAdapter, + StructureAdapter, + StructureDifference, + _emptyStructureAdapter, + nometa, + nosymmetry, +) + def createStructureAdapter(stru): - """ - Create StructureAdapter from a Python object. + """Create StructureAdapter from a Python object. stru -- an object that is convertible to StructureAdapter, i.e., it has a registered factory that converts Python structure object to @@ -49,7 +63,7 @@ def createStructureAdapter(stru): cls = type(stru) fqnames = [str(tp).split("'")[1] for tp in inspect.getmro(cls)] for fqn in fqnames: - if not fqn in _adapter_converters_registry: + if fqn not in _adapter_converters_registry: continue factory = _adapter_converters_registry[fqn] return factory(stru) @@ -59,10 +73,10 @@ def createStructureAdapter(stru): def RegisterStructureAdapter(fqname, fnc=None): - """Function decorator that marks it as a converter of specified - object type to StructureAdapter class in diffpy.srreal. The registered - structure object types can be afterwards directly used with calculators - in diffpy.srreal as they would be implicitly converted to the internal + """Function decorator that marks it as a converter of specified object type + to StructureAdapter class in diffpy.srreal. The registered structure + object types can be afterwards directly used with calculators in + diffpy.srreal as they would be implicitly converted to the internal diffpy.srreal structure type. fqname -- fully qualified class name for the convertible objects. @@ -92,18 +106,6 @@ def __wrapper(fnc): _adapter_converters_registry = {} -# import of srreal_ext calls RegisterStructureAdapter, therefore it has -# to be at the end of this module. - -from diffpy.srreal.srreal_ext import StructureAdapter -from diffpy.srreal.srreal_ext import Atom, AtomicStructureAdapter -from diffpy.srreal.srreal_ext import PeriodicStructureAdapter -from diffpy.srreal.srreal_ext import CrystalStructureAdapter -from diffpy.srreal.srreal_ext import StructureDifference -from diffpy.srreal.srreal_ext import nometa, nosymmetry -from diffpy.srreal.srreal_ext import _emptyStructureAdapter -from diffpy.srreal.srreal_ext import BaseBondGenerator - EMPTY = _emptyStructureAdapter() del _emptyStructureAdapter diff --git a/src/diffpy/srreal/structureconverters.py b/src/diffpy/srreal/structureconverters.py index 210a2bbb..c9b844d8 100644 --- a/src/diffpy/srreal/structureconverters.py +++ b/src/diffpy/srreal/structureconverters.py @@ -12,15 +12,22 @@ # See LICENSE.txt for license information. # ############################################################################## +"""Converters from other structure representations in Python to diffpy.srreal +StructureAdapter classes.""" + +from diffpy.srreal.srreal_ext import ( + AtomicStructureAdapter, + PeriodicStructureAdapter, + convertObjCrystCrystal, + convertObjCrystMolecule, +) +from diffpy.srreal.structureadapter import RegisterStructureAdapter + +# Converters for Molecule and Crystal from pyobjcryst ------------------------ -""" -Converters from other structure representations in Python to diffpy.srreal -StructureAdapter classes. -""" -from diffpy.srreal.structureadapter import RegisterStructureAdapter -from diffpy.srreal.srreal_ext import AtomicStructureAdapter -from diffpy.srreal.srreal_ext import PeriodicStructureAdapter +RegisterStructureAdapter("pyobjcryst._pyobjcryst.Molecule", convertObjCrystMolecule) +RegisterStructureAdapter("pyobjcryst._pyobjcryst.Crystal", convertObjCrystCrystal) # Converter for Structure class from diffpy.structure ------------------------ @@ -48,21 +55,10 @@ def convertDiffPyStructure(stru): return adpt -# Converters for Molecule and Crystal from pyobjcryst ------------------------ - -from diffpy.srreal.srreal_ext import convertObjCrystMolecule - -RegisterStructureAdapter("pyobjcryst._pyobjcryst.Molecule", convertObjCrystMolecule) - -from diffpy.srreal.srreal_ext import convertObjCrystCrystal - -RegisterStructureAdapter("pyobjcryst._pyobjcryst.Crystal", convertObjCrystCrystal) - # Adapter classes and helpers for diffpy.structure class --------------------- class _DiffPyStructureMetadata(object): - "Base class for handling metadata information in the pdffit attribute." pdffit = None @@ -76,7 +72,7 @@ def hasMetadata(stru): def _customPQConfig(self, pqobj): """Apply PDF-related metadata if defined in PDFFit structure format.""" pqname = type(pqobj).__name__ - if not pqname in ("PDFCalculator", "DebyePDFCalculator"): + if pqname not in ("PDFCalculator", "DebyePDFCalculator"): return if not self.pdffit: return @@ -87,12 +83,12 @@ def _customPQConfig(self, pqobj): pqobj.scale = self.pdffit["scale"] # spdiameter if "spdiameter" in self.pdffit: - if not "sphericalshape" in envtps: + if "sphericalshape" not in envtps: pqobj.addEnvelope("sphericalshape") pqobj.spdiameter = self.pdffit["spdiameter"] # stepcut if "stepcut" in self.pdffit: - if not "stepcut" in envtps: + if "stepcut" not in envtps: pqobj.addEnvelope("stepcut") pqobj.stepcut = self.pdffit["stepcut"] # delta1, delta2 - set these only when using JeongPeakWidth model @@ -102,7 +98,7 @@ def _customPQConfig(self, pqobj): return def _fetchMetadata(self, stru): - """Copy data from the pdffit attribute of diffpy Structure object + """Copy data from the pdffit attribute of diffpy Structure object. stru -- instance of Structure class from diffpy.structure diff --git a/src/diffpy/srreal/tests/__init__.py b/src/diffpy/srreal/tests/__init__.py index 8f9447cf..c4e942b5 100644 --- a/src/diffpy/srreal/tests/__init__.py +++ b/src/diffpy/srreal/tests/__init__.py @@ -12,12 +12,10 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## +"""Unit tests for diffpy.srreal.""" -"""Unit tests for diffpy.srreal. -""" - -import unittest import logging +import unittest # create logger instance for the tests subpackage logging.basicConfig() @@ -41,8 +39,9 @@ def testsuite(pattern=""): The TestSuite object containing the matching tests. """ import re - from os.path import dirname from itertools import chain + from os.path import dirname + from pkg_resources import resource_filename loader = unittest.defaultTestLoader diff --git a/src/diffpy/srreal/tests/debug.py b/src/diffpy/srreal/tests/debug.py index eb48ae31..47197f9c 100644 --- a/src/diffpy/srreal/tests/debug.py +++ b/src/diffpy/srreal/tests/debug.py @@ -12,9 +12,7 @@ # See LICENSE.txt for license information. # ############################################################################## - -""" -Convenience module for debugging the unit tests using +"""Convenience module for debugging the unit tests using. python -m diffpy.srreal.tests.debug @@ -24,6 +22,7 @@ if __name__ == "__main__": import sys + from diffpy.srreal.tests import testsuite pattern = sys.argv[1] if len(sys.argv) > 1 else "" diff --git a/src/diffpy/srreal/tests/run.py b/src/diffpy/srreal/tests/run.py index efbe2456..9d107059 100644 --- a/src/diffpy/srreal/tests/run.py +++ b/src/diffpy/srreal/tests/run.py @@ -12,8 +12,7 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - -"""Convenience module for executing all unit tests with +"""Convenience module for executing all unit tests with. python -m diffpy.srreal.tests.run """ @@ -24,7 +23,8 @@ # show warnings by default if not sys.warnoptions: - import os, warnings + import os + import warnings warnings.simplefilter("default") # also affect subprocesses diff --git a/src/diffpy/srreal/tests/testatomradiitable.py b/src/diffpy/srreal/tests/testatomradiitable.py index d9e7ee98..f5c2265e 100644 --- a/src/diffpy/srreal/tests/testatomradiitable.py +++ b/src/diffpy/srreal/tests/testatomradiitable.py @@ -1,14 +1,13 @@ #!/usr/bin/env python -"""Unit tests for the AtomRadiiTable class. -""" +"""Unit tests for the AtomRadiiTable class.""" -import unittest import pickle -from diffpy.srreal.tests.testutils import has_periodictable, _msg_noperiodictable -from diffpy.srreal.atomradiitable import AtomRadiiTable, CovalentRadiiTable -from diffpy.srreal.atomradiitable import ConstantRadiiTable +import unittest + +from diffpy.srreal.atomradiitable import AtomRadiiTable, ConstantRadiiTable, CovalentRadiiTable +from diffpy.srreal.tests.testutils import _msg_noperiodictable, has_periodictable # ---------------------------------------------------------------------------- @@ -24,7 +23,7 @@ def tearDown(self): return def test_pickling(self): - """check pickling and unpickling of AtomRadiiTable.""" + """Check pickling and unpickling of AtomRadiiTable.""" ctb1 = pickle.loads(pickle.dumps(self.ctb)) self.assertTrue(type(ctb1) is ConstantRadiiTable) self.assertEqual({}, ctb1.getAllCustom()) @@ -38,7 +37,7 @@ def test_pickling(self): return def test__standardLookup(self): - """check AtomRadiiTable._standardLookup()""" + """Check AtomRadiiTable._standardLookup()""" self.assertRaises(RuntimeError, self.rtb._standardLookup, "anything") self.assertEqual(0.0, self.ctb._standardLookup("anything")) self.ctb.setDefault(7.3) @@ -46,7 +45,7 @@ def test__standardLookup(self): return def test_fromString(self): - """check AtomRadiiTable.fromString()""" + """Check AtomRadiiTable.fromString()""" self.rtb.fromString("H:0.33, B:0.42") self.assertEqual({"H": 0.33, "B": 0.42}, self.rtb.getAllCustom()) self.assertRaises(ValueError, self.rtb.fromString, "C:2.3, U:asdf") @@ -60,12 +59,12 @@ def test_fromString(self): return def test_getAllCustom(self): - """check AtomRadiiTable.getAllCustom()""" + """Check AtomRadiiTable.getAllCustom()""" self.assertEqual({}, self.rtb.getAllCustom()) return def test_lookup(self): - """check AtomRadiiTable.lookup()""" + """Check AtomRadiiTable.lookup()""" self.assertRaises(RuntimeError, self.rtb.lookup, "C") self.assertEqual(0.0, self.ctb.lookup("C")) self.rtb.setCustom("C", 1.23) @@ -73,7 +72,7 @@ def test_lookup(self): return def test_resetCustom(self): - """check AtomRadiiTable.resetCustom()""" + """Check AtomRadiiTable.resetCustom()""" self.rtb.setCustom("C", 1.23) self.assertTrue(self.rtb.getAllCustom()) self.rtb.resetAll() @@ -81,7 +80,7 @@ def test_resetCustom(self): return def test_setCustom(self): - """check AtomRadiiTable.setCustom()""" + """Check AtomRadiiTable.setCustom()""" self.rtb.setCustom("C", 1.23) self.assertEqual(1.23, self.rtb.lookup("C")) self.rtb.setCustom("C", 3.3) @@ -89,7 +88,7 @@ def test_setCustom(self): return def test_toString(self): - """check AtomRadiiTable.toString()""" + """Check AtomRadiiTable.toString()""" rtb = self.rtb self.assertEqual("", rtb.toString()) self.assertEqual("", rtb.toString("; ")) @@ -115,7 +114,7 @@ def tearDown(self): return def test_pickling(self): - """check pickling and unpickling of CovalentRadiiTable.""" + """Check pickling and unpickling of CovalentRadiiTable.""" rtb1 = pickle.loads(pickle.dumps(self.rtb)) self.assertTrue(type(rtb1) is CovalentRadiiTable) self.assertEqual({}, rtb1.getAllCustom()) @@ -127,12 +126,12 @@ def test_pickling(self): return def test__standardLookup(self): - """check CovalentRadiiTable._standardLookup()""" + """Check CovalentRadiiTable._standardLookup()""" self.assertEqual(1.22, self.rtb._standardLookup("Ga")) return def test_create(self): - """check CovalentRadiiTable.create()""" + """Check CovalentRadiiTable.create()""" self.rtb.setCustom("Na", 1.3) rtb2 = self.rtb.create() self.assertTrue(isinstance(rtb2, CovalentRadiiTable)) @@ -141,7 +140,7 @@ def test_create(self): return def test_clone(self): - """check CovalentRadiiTable.clone()""" + """Check CovalentRadiiTable.clone()""" self.rtb.setCustom("Na", 1.3) rtb2 = self.rtb.clone() self.assertTrue(isinstance(rtb2, CovalentRadiiTable)) @@ -150,25 +149,25 @@ def test_clone(self): return def test_fromString(self): - """check CovalentRadiiTable.fromString()""" + """Check CovalentRadiiTable.fromString()""" self.rtb.fromString("Ga:2.22") self.assertEqual(2.22, self.rtb.lookup("Ga")) return def test_getAllCustom(self): - """check CovalentRadiiTable.getAllCustom()""" + """Check CovalentRadiiTable.getAllCustom()""" self.assertEqual({}, self.rtb.getAllCustom()) return def test_lookup(self): - """check CovalentRadiiTable.lookup()""" + """Check CovalentRadiiTable.lookup()""" self.assertEqual(1.22, self.rtb.lookup("Ga")) self.rtb.fromString("Ga:2.22") self.assertEqual(2.22, self.rtb.lookup("Ga")) return def test_resetCustom(self): - """check CovalentRadiiTable.resetCustom()""" + """Check CovalentRadiiTable.resetCustom()""" self.rtb.fromString("B:2.33, Ga:2.22") self.rtb.resetCustom("B") self.rtb.resetCustom("nada") @@ -178,14 +177,14 @@ def test_resetCustom(self): return def test_setCustom(self): - """check CovalentRadiiTable.setCustom()""" + """Check CovalentRadiiTable.setCustom()""" self.assertEqual(0.84, self.rtb.lookup("B")) self.rtb.setCustom("B", 0.9) self.assertEqual(0.9, self.rtb.lookup("B")) return def test_toString(self): - """check CovalentRadiiTable.toString()""" + """Check CovalentRadiiTable.toString()""" self.assertEqual("", self.rtb.toString(";---")) return diff --git a/src/diffpy/srreal/tests/testattributes.py b/src/diffpy/srreal/tests/testattributes.py index cb4f2243..573ccf8d 100644 --- a/src/diffpy/srreal/tests/testattributes.py +++ b/src/diffpy/srreal/tests/testattributes.py @@ -4,9 +4,9 @@ """ +import gc import unittest import weakref -import gc from diffpy.srreal.attributes import Attributes from diffpy.srreal.pairquantity import PairQuantity @@ -23,7 +23,7 @@ def tearDown(self): return def test___setattr__(self): - """check Attributes.__setattr__()""" + """Check Attributes.__setattr__()""" # normal attribute a = Attributes() a.x = 45 @@ -39,7 +39,7 @@ def test___setattr__(self): return def test___getattr__(self): - """check Attributes.__getattr__()""" + """Check Attributes.__getattr__()""" a = Attributes() self.assertRaises(AttributeError, getattr, a, "invalid") a.x = 11 @@ -50,7 +50,7 @@ def test___getattr__(self): return def test_garbage_collection(self): - """check garbage collection for Python defined Attributes""" + """Check garbage collection for Python defined Attributes.""" # check if attributes are garbage collected pq = PairQuantity() wpq = weakref.ref(pq) @@ -63,7 +63,7 @@ def test_garbage_collection(self): return def test__getDoubleAttr(self): - """check Attributes._getDoubleAttr()""" + """Check Attributes._getDoubleAttr()""" pdfc = PDFCalculator() pdfc.foo = 11 self.assertRaises(AttributeError, pdfc._getDoubleAttr, "foo") @@ -77,7 +77,7 @@ def test__getDoubleAttr(self): return def test__hasDoubleAttr(self): - """check Attributes._hasDoubleAttr()""" + """Check Attributes._hasDoubleAttr()""" a = Attributes() a.foo = 45 self.assertFalse(a._hasDoubleAttr("foo")) @@ -86,7 +86,7 @@ def test__hasDoubleAttr(self): return def test__namesOfDoubleAttributes(self): - """check Attributes._namesOfDoubleAttributes()""" + """Check Attributes._namesOfDoubleAttributes()""" a = Attributes() self.assertEqual(0, len(a._namesOfDoubleAttributes())) pq = PairQuantity() @@ -97,7 +97,7 @@ def test__namesOfDoubleAttributes(self): return def test__namesOfWritableDoubleAttributes(self): - """check Attributes._namesOfDoubleAttributes()""" + """Check Attributes._namesOfDoubleAttributes()""" a = Attributes() self.assertEqual(0, len(a._namesOfDoubleAttributes())) a._registerDoubleAttribute("bar", lambda obj: 13) @@ -114,7 +114,7 @@ def test__namesOfWritableDoubleAttributes(self): return def test__registerDoubleAttribute(self): - """check Attributes._registerDoubleAttribute()""" + """Check Attributes._registerDoubleAttribute()""" d = {"g_called": False, "s_called": False, "value": 0} def g(obj): @@ -154,7 +154,7 @@ def s(obj, value): return def test__setDoubleAttr(self): - """check Attributes._setDoubleAttr()""" + """Check Attributes._setDoubleAttr()""" pdfc = PDFCalculator() pdfc._setDoubleAttr("scale", 1.23) self.assertFalse("scale" in pdfc.__dict__) diff --git a/src/diffpy/srreal/tests/testbondcalculator.py b/src/diffpy/srreal/tests/testbondcalculator.py index 76164a2a..cbbe6090 100644 --- a/src/diffpy/srreal/tests/testbondcalculator.py +++ b/src/diffpy/srreal/tests/testbondcalculator.py @@ -1,18 +1,21 @@ #!/usr/bin/env python -"""Unit tests for diffpy.srreal.bondcalculator -""" +"""Unit tests for diffpy.srreal.bondcalculator.""" -import unittest import pickle +import unittest + import numpy -from diffpy.srreal.tests.testutils import has_pyobjcryst, _msg_nopyobjcryst -from diffpy.srreal.tests.testutils import loadDiffPyStructure -from diffpy.srreal.tests.testutils import loadObjCrystCrystal -from diffpy.srreal.tests.testutils import pickle_with_attr from diffpy.srreal.bondcalculator import BondCalculator +from diffpy.srreal.tests.testutils import ( + _msg_nopyobjcryst, + has_pyobjcryst, + loadDiffPyStructure, + loadObjCrystCrystal, + pickle_with_attr, +) # ---------------------------------------------------------------------------- @@ -33,7 +36,7 @@ def tearDown(self): return def test___init__(self): - """check BondCalculator.__init__()""" + """Check BondCalculator.__init__()""" self.assertEqual(0, self.bdc.rmin) self.assertEqual(5, self.bdc.rmax) self.assertEqual(0, len(self.bdc.distances)) @@ -44,7 +47,7 @@ def test___init__(self): return def test___call__(self): - """check BondCalculator.__call__()""" + """Check BondCalculator.__call__()""" bdc = self.bdc bdc.rmax = 0 self.assertEqual(0, len(bdc(self.rutile))) @@ -59,7 +62,7 @@ def test___call__(self): return def test_pickling(self): - """check pickling and unpickling of BondCalculator.""" + """Check pickling and unpickling of BondCalculator.""" bdc = self.bdc bdc.rmin = 0.1 bdc.rmax = 12.3 @@ -77,7 +80,7 @@ def test_pickling(self): return def test_pickling_derived_structure(self): - """check pickling of BondCalculator with DerivedStructureAdapter.""" + """Check pickling of BondCalculator with DerivedStructureAdapter.""" from diffpy.srreal.tests.testutils import DerivedStructureAdapter bdc = self.bdc @@ -94,7 +97,7 @@ def test_pickling_derived_structure(self): return def test_distances(self): - """check BondCalculator.distances""" + """Check BondCalculator.distances.""" self.bdc.eval(self.nickel) dst = self.bdc.distances self.assertTrue(numpy.array_equal(dst, BondCalculator()(self.nickel))) @@ -115,7 +118,7 @@ def test_distances(self): return def test_directions(self): - """check BondCalculator.directions""" + """Check BondCalculator.directions.""" dst = self.bdc(self.rutile) drs = self.bdc.directions nms = numpy.sqrt(numpy.sum(numpy.power(drs, 2), axis=1)) @@ -123,7 +126,7 @@ def test_directions(self): return def test_sites(self): - """check BondCalculator.sites""" + """Check BondCalculator.sites.""" bdc = self.bdc dst = bdc(self.rutile) self.assertEqual(len(dst), len(bdc.sites0)) @@ -144,7 +147,7 @@ def test_sites(self): return def test_types(self): - """check BondCalculator.types""" + """Check BondCalculator.types.""" bdc = self.bdc dst = bdc(self.rutile) self.assertEqual(len(dst), len(bdc.types0)) @@ -163,7 +166,7 @@ def test_types(self): return def test_filterCone(self): - """check BondCalculator.filterCone()""" + """Check BondCalculator.filterCone()""" bdc = self.bdc bdc.rmax = 2.5 self.assertEqual(12, len(bdc(self.niprim))) @@ -181,7 +184,7 @@ def test_filterCone(self): return def test_filterOff(self): - """check BondCalculator.filterOff()""" + """Check BondCalculator.filterOff()""" bdc = self.bdc bdc.rmax = 2.5 bdc.filterCone([1, 2, 3], -1) @@ -191,7 +194,7 @@ def test_filterOff(self): return def test_setPairMask(self): - """check different setPairMask arguments.""" + """Check different setPairMask arguments.""" bdc = self.bdc dall = bdc(self.nickel) bdc.maskAllPairs(False) @@ -220,7 +223,7 @@ def test_setPairMask(self): return def test_setTypeMask(self): - """check different setTypeMask arguments.""" + """Check different setTypeMask arguments.""" bdc = self.bdc dall = bdc(self.rutile) bdc.setTypeMask("all", "All", False) @@ -261,7 +264,7 @@ def tearDown(self): return def test___call__(self): - """check BondCalculator.__call__()""" + """Check BondCalculator.__call__()""" bdc = self.bdc bdc.rmax = 0 self.assertEqual(0, len(bdc(self.rutile).tolist())) @@ -272,7 +275,7 @@ def test___call__(self): return def test_sites(self): - """check BondCalculator.sites""" + """Check BondCalculator.sites.""" bdc = self.bdc dst = bdc(self.rutile) self.assertEqual(len(dst), len(bdc.sites0)) @@ -293,7 +296,7 @@ def test_sites(self): return def test_types(self): - """check BondCalculator.types""" + """Check BondCalculator.types.""" bdc = self.bdc dst = bdc(self.rutile) self.assertEqual(len(dst), len(bdc.types0)) @@ -312,7 +315,7 @@ def test_types(self): return def test_filterCone(self): - """check BondCalculator.filterCone()""" + """Check BondCalculator.filterCone()""" bdc = self.bdc bdc.rmax = 2.5 bdc.filterCone([+0.5, +0.5, 0], 1) @@ -329,7 +332,7 @@ def test_filterCone(self): return def test_filterOff(self): - """check BondCalculator.filterOff()""" + """Check BondCalculator.filterOff()""" bdc = self.bdc bdc.rmax = 2.5 bdc.filterCone([1, 2, 3], -1) diff --git a/src/diffpy/srreal/tests/testbvscalculator.py b/src/diffpy/srreal/tests/testbvscalculator.py index 62efd7dd..aceac210 100644 --- a/src/diffpy/srreal/tests/testbvscalculator.py +++ b/src/diffpy/srreal/tests/testbvscalculator.py @@ -1,15 +1,13 @@ #!/usr/bin/env python -"""Unit tests for diffpy.srreal.bvscalculator -""" +"""Unit tests for diffpy.srreal.bvscalculator.""" -import unittest import pickle +import unittest from diffpy.srreal.bvscalculator import BVSCalculator -from diffpy.srreal.tests.testutils import loadDiffPyStructure -from diffpy.srreal.tests.testutils import pickle_with_attr +from diffpy.srreal.tests.testutils import loadDiffPyStructure, pickle_with_attr ############################################################################## @@ -29,14 +27,14 @@ def tearDown(self): return def test___init__(self): - """check BVSCalculator.__init__()""" + """Check BVSCalculator.__init__()""" self.assertEqual(1e-5, self.bvc.valenceprecision) bvc1 = BVSCalculator(valenceprecision=1e-4) self.assertEqual(1e-4, bvc1.valenceprecision) return def test___call__(self): - """check BVSCalculator.__call__()""" + """Check BVSCalculator.__call__()""" vcalc = self.bvc(self.rutile) self.assertEqual(len(self.rutile), len(vcalc)) self.assertEqual(tuple(self.bvc.value), tuple(vcalc)) @@ -49,7 +47,7 @@ def test___call__(self): return def test_bvdiff(self): - """check BVSCalculator.bvdiff""" + """Check BVSCalculator.bvdiff.""" self.bvc(self.rutile) self.assertEqual(6, len(self.bvc.bvdiff)) # rutile is overbonded @@ -58,14 +56,14 @@ def test_bvdiff(self): return def test_bvmsdiff(self): - """check BVSCalculator.bvmsdiff""" + """Check BVSCalculator.bvmsdiff.""" self.assertEqual(0, self.bvc.bvmsdiff) self.bvc(self.rutile) self.assertAlmostEqual(0.0158969, self.bvc.bvmsdiff, 6) return def test_bvrmsdiff(self): - """check BVSCalculator.bvrmsdiff""" + """Check BVSCalculator.bvrmsdiff.""" from math import sqrt self.assertEqual(0, self.bvc.bvrmsdiff) @@ -85,24 +83,24 @@ def test_bvrmsdiff(self): return def test_eval(self): - """check BVSCalculator.eval()""" + """Check BVSCalculator.eval()""" vcalc = self.bvc.eval(self.rutile) self.assertEqual(tuple(vcalc), tuple(self.bvc.value)) return def test_valences(self): - """check BVSCalculator.valences""" + """Check BVSCalculator.valences.""" self.bvc(self.rutile) self.assertEqual((4, 4, -2, -2, -2, -2), tuple(self.bvc.valences)) return def test_value(self): - """check BVSCalculator.value""" + """Check BVSCalculator.value.""" self.assertEqual(0, len(self.bvc.value)) return def test_pickling(self): - """check pickling and unpickling of BVSCalculator.""" + """Check pickling and unpickling of BVSCalculator.""" bvsc = BVSCalculator() bvsc.rmin = 0.1 bvsc.rmax = 12.3 @@ -140,7 +138,7 @@ def test_table_pickling(self): return def test_pickling_derived_structure(self): - """check pickling of BVSCalculator with DerivedStructureAdapter.""" + """Check pickling of BVSCalculator with DerivedStructureAdapter.""" from diffpy.srreal.tests.testutils import DerivedStructureAdapter bvc = self.bvc @@ -157,7 +155,7 @@ def test_pickling_derived_structure(self): return def test_table_atom_valence(self): - """check calculation with defined valences in bvparamtable""" + """Check calculation with defined valences in bvparamtable.""" bvc = self.bvc barerutile = self.rutile.copy() for a in barerutile: diff --git a/src/diffpy/srreal/tests/testdata/Ni.stru b/src/diffpy/srreal/tests/testdata/Ni.stru index 5d39b959..e13f2693 100644 --- a/src/diffpy/srreal/tests/testdata/Ni.stru +++ b/src/diffpy/srreal/tests/testdata/Ni.stru @@ -2,11 +2,11 @@ title structure Ni FCC format pdffit scale 1.000000 sharp 0.000000, 0.000000, 1.000000, 0.000000 -spcgr Fm-3m +spcgr Fm-3m cell 3.520000, 3.520000, 3.520000, 90.000000, 90.000000, 90.000000 dcell 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000 ncell 1, 1, 1, 4 -atoms +atoms NI 0.00000000 0.00000000 0.00000000 1.0000 0.00000000 0.00000000 0.00000000 0.0000 0.00126651 0.00126651 0.00126651 diff --git a/src/diffpy/srreal/tests/testdebyepdfcalculator.py b/src/diffpy/srreal/tests/testdebyepdfcalculator.py index 9268613f..fd8c07d4 100644 --- a/src/diffpy/srreal/tests/testdebyepdfcalculator.py +++ b/src/diffpy/srreal/tests/testdebyepdfcalculator.py @@ -1,17 +1,16 @@ #!/usr/bin/env python -"""Unit tests for pdfcalculator.py -""" +"""Unit tests for pdfcalculator.py.""" -import unittest import pickle +import unittest + import numpy from diffpy.srreal.pdfcalculator import DebyePDFCalculator, PDFCalculator -from diffpy.srreal.tests.testutils import loadDiffPyStructure -from diffpy.srreal.tests.testutils import pickle_with_attr from diffpy.srreal.tests.testpdfcalculator import _maxNormDiff +from diffpy.srreal.tests.testutils import loadDiffPyStructure, pickle_with_attr ############################################################################## @@ -42,21 +41,21 @@ def setUp(self): # return def test___getattr__(self): - """check DebyePDFCalculator.__getattr__()""" + """Check DebyePDFCalculator.__getattr__()""" self.assertEqual(0.0, self.dpdfc.qmin) self.dpdfc._setDoubleAttr("qmin", 1.23) self.assertEqual(1.23, self.dpdfc.qmin) return def test___setattr__(self): - """check DebyePDFCalculator.__setattr__()""" + """Check DebyePDFCalculator.__setattr__()""" self.assertNotEqual(1.23, self.dpdfc._getDoubleAttr("rmin")) self.dpdfc.rmin = 1.23 self.assertEqual(1.23, self.dpdfc._getDoubleAttr("rmin")) return def test__getDoubleAttr(self): - """check DebyePDFCalculator._getDoubleAttr()""" + """Check DebyePDFCalculator._getDoubleAttr()""" gdba = self.dpdfc._getDoubleAttr self.assertEqual(1.0, gdba("scale")) self.assertEqual(0.0, gdba("qdamp")) @@ -64,19 +63,19 @@ def test__getDoubleAttr(self): return def test__hasDoubleAttr(self): - """check DebyePDFCalculator._hasDoubleAttr()""" + """Check DebyePDFCalculator._hasDoubleAttr()""" self.assertTrue(self.dpdfc._hasDoubleAttr("scale")) self.assertFalse(self.dpdfc._hasDoubleAttr("notanattribute")) return def test__namesOfDoubleAttributes(self): - """check DebyePDFCalculator._namesOfDoubleAttributes()""" + """Check DebyePDFCalculator._namesOfDoubleAttributes()""" self.assertTrue(type(self.dpdfc._namesOfDoubleAttributes()) is set) self.assertTrue("qmax" in self.dpdfc._namesOfDoubleAttributes()) return def test__setDoubleAttr(self): - """check DebyePDFCalculator._setDoubleAttr()""" + """Check DebyePDFCalculator._setDoubleAttr()""" gdba = self.dpdfc._getDoubleAttr sdba = self.dpdfc._setDoubleAttr self.assertEqual(0.0, gdba("rmin")) @@ -85,7 +84,7 @@ def test__setDoubleAttr(self): return def test_PDF_C60bucky(self): - """check DebyePDFCalculator.pdf for C60 Bucky ball.""" + """Check DebyePDFCalculator.pdf for C60 Bucky ball.""" qmax = self.dpdfc.qmax r0, g0 = PDFCalculator(qmax=qmax)(self.bucky) r1, g1 = self.dpdfc(self.bucky) @@ -140,7 +139,7 @@ def test_partial_pdfs(self): return def test_pickling(self): - """check pickling and unpickling of PDFCalculator.""" + """Check pickling and unpickling of PDFCalculator.""" dpdfc = self.dpdfc dpdfc.setScatteringFactorTableByType("N") dpdfc.scatteringfactortable.setCustomAs("Na", "Na", 7) @@ -188,7 +187,8 @@ def test_mask_pickling(self): return def test_pickling_derived_structure(self): - """check pickling of DebyePDFCalculator with DerivedStructureAdapter.""" + """Check pickling of DebyePDFCalculator with + DerivedStructureAdapter.""" from diffpy.srreal.tests.testutils import DerivedStructureAdapter dpdfc = self.dpdfc diff --git a/src/diffpy/srreal/tests/testoverlapcalculator.py b/src/diffpy/srreal/tests/testoverlapcalculator.py index 09881233..aabda0e6 100644 --- a/src/diffpy/srreal/tests/testoverlapcalculator.py +++ b/src/diffpy/srreal/tests/testoverlapcalculator.py @@ -1,20 +1,23 @@ #!/usr/bin/env python -"""Unit tests for diffpy.srreal.overlapcalculator -""" +"""Unit tests for diffpy.srreal.overlapcalculator.""" -import unittest -import pickle import copy +import pickle +import unittest + import numpy -from diffpy.srreal.tests.testutils import has_pyobjcryst, _msg_nopyobjcryst -from diffpy.srreal.tests.testutils import loadDiffPyStructure -from diffpy.srreal.tests.testutils import loadObjCrystCrystal -from diffpy.srreal.tests.testutils import pickle_with_attr -from diffpy.srreal.overlapcalculator import OverlapCalculator from diffpy.srreal.atomradiitable import CovalentRadiiTable +from diffpy.srreal.overlapcalculator import OverlapCalculator +from diffpy.srreal.tests.testutils import ( + _msg_nopyobjcryst, + has_pyobjcryst, + loadDiffPyStructure, + loadObjCrystCrystal, + pickle_with_attr, +) # ---------------------------------------------------------------------------- @@ -41,7 +44,7 @@ def tearDown(self): return def test___init__(self): - """check OverlapCalculator.__init__()""" + """Check OverlapCalculator.__init__()""" self.assertEqual(0, self.olc.rmin) self.assertTrue(100 <= self.olc.rmax) self.assertEqual(0, self.olc.rmaxused) @@ -49,7 +52,7 @@ def test___init__(self): return def test___call__(self): - """check OverlapCalculator.__call__()""" + """Check OverlapCalculator.__call__()""" olc = self.olc sso1 = olc(self.rutile) self.assertEqual(6, len(sso1)) @@ -66,7 +69,7 @@ def test___call__(self): return def test___getstate__(self): - """check OverlapCalculator.__getstate__()""" + """Check OverlapCalculator.__getstate__()""" olc = self.olc self.assertIs(None, olc.__getstate__()[-1]) tb = CovalentRadiiTable() @@ -77,7 +80,7 @@ def test___getstate__(self): return def test_pickling(self): - """check pickling and unpickling of OverlapCalculator.""" + """Check pickling and unpickling of OverlapCalculator.""" olc = self.olc olc.rmin = 0.1 olc.rmax = 12.3 @@ -94,7 +97,8 @@ def test_pickling(self): return def test_pickling_artb(self): - """check pickling and unpickling of OverlapCalculator.atomradiitable.""" + """Check pickling and unpickling of + OverlapCalculator.atomradiitable.""" olc = self.olc olc.atomradiitable.setDefault(1.3) spkl = pickle.dumps(olc) @@ -112,7 +116,7 @@ def test_pickling_artb(self): return def test_pickling_derived_structure(self): - """check pickling of OverlapCalculator with DerivedStructureAdapter.""" + """Check pickling of OverlapCalculator with DerivedStructureAdapter.""" from diffpy.srreal.tests.testutils import DerivedStructureAdapter olc = self.olc @@ -129,8 +133,9 @@ def test_pickling_derived_structure(self): return def test_parallel(self): - """check parallel run of OverlapCalculator""" + """Check parallel run of OverlapCalculator.""" import multiprocessing + from diffpy.srreal.parallel import createParallelCalculator ncpu = 4 @@ -149,7 +154,7 @@ def test_parallel(self): return def test_distances(self): - """check OverlapCalculator.distances""" + """Check OverlapCalculator.distances.""" olc = self.olc olc(self.nickel) self.assertEqual(0, len(olc.distances)) @@ -166,7 +171,7 @@ def test_distances(self): return def test_directions(self): - """check OverlapCalculator.directions""" + """Check OverlapCalculator.directions.""" olc = self.olc olc(self.nickel) self.assertEqual([], olc.directions.tolist()) @@ -179,7 +184,7 @@ def test_directions(self): return def test_gradients(self): - """check OverlapCalculator.gradients""" + """Check OverlapCalculator.gradients.""" olc = self.olc olc.atomradiitable.fromString("Ti:1.6, O:0.66") olc(self.rutile) @@ -197,7 +202,7 @@ def test_gradients(self): return def test_sitesquareoverlaps(self): - """check OverlapCalculator.sitesquareoverlaps""" + """Check OverlapCalculator.sitesquareoverlaps.""" olc = self.olc self.assertTrue(numpy.array_equal([], olc.sitesquareoverlaps)) olc(self.rutile) @@ -209,7 +214,7 @@ def test_sitesquareoverlaps(self): return def test_totalsquareoverlap(self): - """check OverlapCalculator.totalsquareoverlap""" + """Check OverlapCalculator.totalsquareoverlap.""" olc = self.olc self.assertEqual(0.0, olc.totalsquareoverlap) olc(self.rutile) @@ -220,7 +225,7 @@ def test_totalsquareoverlap(self): return def test_meansquareoverlap(self): - """check OverlapCalculator.meansquareoverlap""" + """Check OverlapCalculator.meansquareoverlap.""" olc = self.olc self.assertEqual(0.0, olc.meansquareoverlap) olc(self.nickel) @@ -238,7 +243,7 @@ def test_meansquareoverlap(self): return def test_flipDiffTotal(self): - """check OverlapCalculator.flipDiffTotal""" + """Check OverlapCalculator.flipDiffTotal.""" olc = self.olc olc.atomradiitable.fromString("Ti:1.6, O:0.66") olc(self.rutile) @@ -259,7 +264,7 @@ def test_flipDiffTotal(self): return def test_getNeighborSites(self): - """check OverlapCalculator.getNeighborSites""" + """Check OverlapCalculator.getNeighborSites.""" olc = self.olc olc(self.rutile) self.assertEqual(set(), olc.getNeighborSites(0)) @@ -276,7 +281,7 @@ def test_getNeighborSites(self): return def test_coordinations(self): - """check OverlapCalculator.coordinations""" + """Check OverlapCalculator.coordinations.""" olc = self.olc self.assertEqual(0, len(olc.coordinations)) olc(self.rutile) @@ -288,7 +293,7 @@ def test_coordinations(self): return def test_coordinationByTypes(self): - """check OverlapCalculator.coordinationByTypes""" + """Check OverlapCalculator.coordinationByTypes.""" olc = self.olc olc(self.rutile) self.assertEqual({}, olc.coordinationByTypes(0)) @@ -306,7 +311,7 @@ def test_coordinationByTypes(self): return def test_neighborhoods(self): - """check OverlapCalculator.neighborhoods""" + """Check OverlapCalculator.neighborhoods.""" olc = self.olc self.assertEqual([], olc.neighborhoods) olc(self.rutile) @@ -342,7 +347,7 @@ def tearDown(self): return def test_totalsquareoverlap(self): - """check OverlapCalculator.totalsquareoverlap for ObjCryst crystal""" + """Check OverlapCalculator.totalsquareoverlap for ObjCryst crystal.""" olc = self.olc self.assertEqual(0.0, olc.totalsquareoverlap) olc(self.rutile) @@ -353,7 +358,7 @@ def test_totalsquareoverlap(self): return def test_meansquareoverlap(self): - """check OverlapCalculator.meansquareoverlap for ObjCryst crystal""" + """Check OverlapCalculator.meansquareoverlap for ObjCryst crystal.""" olc = self.olc self.assertEqual(0.0, olc.meansquareoverlap) olc(self.rutile) @@ -364,7 +369,7 @@ def test_meansquareoverlap(self): return def test_flipDiffTotal(self): - """check OverlapCalculator.flipDiffTotal for an ObjCryst crystal""" + """Check OverlapCalculator.flipDiffTotal for an ObjCryst crystal.""" olc = self.olc olc(self.rutile) self.assertEqual(0.0, olc.flipDiffTotal(0, 1)) @@ -379,7 +384,7 @@ def test_flipDiffTotal(self): return def test_flipDiffMean(self): - """check OverlapCalculator.flipDiffMean for an ObjCryst crystal""" + """Check OverlapCalculator.flipDiffMean for an ObjCryst crystal.""" olc = self.olc olc(self.rutile) self.assertEqual(0.0, olc.flipDiffMean(0, 1)) @@ -397,7 +402,7 @@ def test_flipDiffMean(self): return def test_getNeighborSites(self): - """check OverlapCalculator.getNeighborSites for an ObjCryst crystal""" + """Check OverlapCalculator.getNeighborSites for an ObjCryst crystal.""" olc = self.olc olc(self.rutile) self.assertEqual(set(), olc.getNeighborSites(0)) @@ -409,7 +414,7 @@ def test_getNeighborSites(self): return def test_coordinations(self): - """check OverlapCalculator.coordinations for an ObjCryst crystal""" + """Check OverlapCalculator.coordinations for an ObjCryst crystal.""" olc = self.olc self.assertEqual(0, len(olc.coordinations)) olc(self.rutile) @@ -421,7 +426,8 @@ def test_coordinations(self): return def test_coordinationByTypes(self): - """check OverlapCalculator.coordinationByTypes for an ObjCryst crystal""" + """Check OverlapCalculator.coordinationByTypes for an ObjCryst + crystal.""" olc = self.olc olc(self.rutile) self.assertEqual({}, olc.coordinationByTypes(0)) @@ -435,7 +441,7 @@ def test_coordinationByTypes(self): return def test_neighborhoods(self): - """check OverlapCalculator.neighborhoods for an ObjCryst crystal""" + """Check OverlapCalculator.neighborhoods for an ObjCryst crystal.""" olc = self.olc self.assertEqual([], olc.neighborhoods) olc(self.rutile) diff --git a/src/diffpy/srreal/tests/testpairquantity.py b/src/diffpy/srreal/tests/testpairquantity.py index 3fa96c80..c07da95c 100644 --- a/src/diffpy/srreal/tests/testpairquantity.py +++ b/src/diffpy/srreal/tests/testpairquantity.py @@ -1,18 +1,17 @@ #!/usr/bin/env python -"""Unit tests for diffpy.srreal.pairquantity -""" +"""Unit tests for diffpy.srreal.pairquantity.""" -import unittest import pickle +import unittest + import numpy from diffpy.srreal.pairquantity import PairQuantity -from diffpy.srreal.srreal_ext import BasePairQuantity from diffpy.srreal.pdfcalculator import PDFCalculator +from diffpy.srreal.srreal_ext import BasePairQuantity from diffpy.srreal.tests.testutils import mod_structure - # ---------------------------------------------------------------------------- @@ -40,7 +39,7 @@ def setUp(self): return def test_evaluatortype(self): - """check PairQuantity.evaluatortype property.""" + """Check PairQuantity.evaluatortype property.""" pq = self.pq self.assertTrue(pq.evaluatortype in ("BASIC", "OPTIMIZED")) pq.evaluatortype = "BASIC" @@ -60,7 +59,7 @@ def test_evaluatortype(self): return def test_setStructure(self): - """check PairQuantity.setStructure()""" + """Check PairQuantity.setStructure()""" Structure = mod_structure.Structure Atom = mod_structure.Atom from diffpy.srreal.structureadapter import EMPTY @@ -76,7 +75,7 @@ def test_setStructure(self): return def test_setPairMask_args(self): - """check argument type handling in setPairMask""" + """Check argument type handling in setPairMask.""" spm = self.pq.setPairMask gpm = self.pq.getPairMask self.assertRaises(TypeError, spm, 0.0, 0, False) @@ -90,13 +89,13 @@ def test_setPairMask_args(self): return def test_getStructure(self): - """check PairQuantity.getStructure()""" + """Check PairQuantity.getStructure()""" adpt = self.pq.getStructure() self.assertEqual(0, adpt.countSites()) return def test_ticker(self): - """check PairQuantity.ticker()""" + """Check PairQuantity.ticker()""" from diffpy.srreal.eventticker import EventTicker et0 = EventTicker(self.pq.ticker()) @@ -107,7 +106,7 @@ def test_ticker(self): return def test_ticker_override(self): - """check Python override of PairQuantity.ticker.""" + """Check Python override of PairQuantity.ticker.""" pqcnt = PQCounter() self.assertEqual(0, pqcnt.tcnt) et0 = pqcnt.ticker() @@ -142,9 +141,14 @@ def test_optimized_evaluation(self): c8 = carbonzchain(8) c9 = carbonzchain(9) pqd = PQDerived() + # wrapper for evaluation using specified evaluatortype. # Use pq.eval twice to trigger optimized evaluation. - eval_as = lambda evtp, pq, stru: (setattr(pq, "evaluatortype", evtp), pq.eval(stru), pq.eval())[-1] + def eval_as(evtp, pq, stru): + setattr(pq, "evaluatortype", evtp) + pq.eval(stru) + return pq.eval() + eval_as("BASIC", pqd, c8) self.assertEqual("BASIC", pqd.evaluatortype) # pqd does not support OPTIMIZED evaluation. Its use will @@ -164,7 +168,7 @@ def test_optimized_evaluation(self): return def test_pickling(self): - """check pickling and unpickling of PairQuantity.""" + """Check pickling and unpickling of PairQuantity.""" from diffpy.srreal.tests.testutils import DerivedStructureAdapter stru0 = DerivedStructureAdapter() diff --git a/src/diffpy/srreal/tests/testparallel.py b/src/diffpy/srreal/tests/testparallel.py index 6924ab8a..e6ae9c12 100644 --- a/src/diffpy/srreal/tests/testparallel.py +++ b/src/diffpy/srreal/tests/testparallel.py @@ -1,14 +1,15 @@ #!/usr/bin/env python -"""Unit tests for diffpy.srreal.parallel -""" +"""Unit tests for diffpy.srreal.parallel.""" -import unittest import multiprocessing +import unittest + import numpy -from diffpy.srreal.tests.testutils import loadDiffPyStructure + from diffpy.srreal.parallel import createParallelCalculator +from diffpy.srreal.tests.testutils import loadDiffPyStructure ############################################################################## @@ -44,7 +45,7 @@ def pool(self): return self._pool def test_parallel_evaluatortype(self): - """check handling of the evaluatortype property""" + """Check handling of the evaluatortype property.""" from diffpy.srreal.pdfcalculator import PDFCalculator pdfc = PDFCalculator() @@ -57,7 +58,7 @@ def test_parallel_evaluatortype(self): return def test_parallel_pdf(self): - """check parallel PDFCalculator""" + """Check parallel PDFCalculator.""" from diffpy.srreal.pdfcalculator import PDFCalculator pdfc = PDFCalculator() @@ -84,7 +85,7 @@ def test_parallel_pdf(self): return def test_parallel_bonds(self): - """check parallel BondCalculator""" + """Check parallel BondCalculator.""" from diffpy.srreal.bondcalculator import BondCalculator nickel = self.nickel diff --git a/src/diffpy/srreal/tests/testpdfbaseline.py b/src/diffpy/srreal/tests/testpdfbaseline.py index d3fd8277..152119e7 100644 --- a/src/diffpy/srreal/tests/testpdfbaseline.py +++ b/src/diffpy/srreal/tests/testpdfbaseline.py @@ -1,17 +1,16 @@ #!/usr/bin/env python -"""Unit tests for the PDFBaseline class from diffpy.srreal.pdfcalculator -""" +"""Unit tests for the PDFBaseline class from diffpy.srreal.pdfcalculator.""" -import unittest import pickle +import unittest + import numpy -from diffpy.srreal.tests.testutils import pickle_with_attr -from diffpy.srreal.pdfbaseline import PDFBaseline, makePDFBaseline -from diffpy.srreal.pdfbaseline import ZeroBaseline, LinearBaseline +from diffpy.srreal.pdfbaseline import LinearBaseline, PDFBaseline, ZeroBaseline, makePDFBaseline from diffpy.srreal.pdfcalculator import PDFCalculator +from diffpy.srreal.tests.testutils import pickle_with_attr # ---------------------------------------------------------------------------- @@ -31,14 +30,14 @@ def tearDown(self): return def test___init__(self): - """check PDFBaseline.__init__()""" + """Check PDFBaseline.__init__()""" self.assertEqual(0.0, self.linear.slope) self.linear._setDoubleAttr("slope", 2.0) self.assertEqual(2.0, self.linear.slope) return def test___call__(self): - """check PDFBaseline.__call__()""" + """Check PDFBaseline.__call__()""" # this is a virtual method in the base class self.assertRaises(RuntimeError, PDFBaseline().__call__, 37) self.assertEqual(0.0, self.zero(10)) @@ -56,7 +55,7 @@ def test___call__(self): return def test_clone(self): - """check PDFBaseline.clone""" + """Check PDFBaseline.clone.""" # this is a virtual method in the base class self.assertRaises(RuntimeError, PDFBaseline().clone) self.linear.slope = 17 @@ -67,7 +66,7 @@ def test_clone(self): return def test_create(self): - """check PDFBaseline.create""" + """Check PDFBaseline.create.""" # this is a virtual method in the base class self.assertRaises(RuntimeError, PDFBaseline().create) self.assertEqual("zero", self.zero.create().type()) @@ -77,7 +76,7 @@ def test_create(self): return def test_type(self): - """check PDFBaseline.type""" + """Check PDFBaseline.type.""" # this is a virtual method in the base class self.assertRaises(RuntimeError, PDFBaseline().type) self.assertEqual("linear", self.linear.type()) @@ -87,7 +86,7 @@ def test_type(self): return def test__aliasType(self): - """check PDFBaseline._aliasType.""" + """Check PDFBaseline._aliasType.""" self.assertRaises(ValueError, PDFBaseline.createByType, "alias") self.assertRaises(RuntimeError, PDFBaseline._aliasType, "invalid", "alias") self.assertRaises(RuntimeError, PDFBaseline._aliasType, "linear", "zero") @@ -104,7 +103,7 @@ def test__aliasType(self): return def test__deregisterType(self): - """check PDFBaseline._deregisterType.""" + """Check PDFBaseline._deregisterType.""" self.assertEqual(0, PDFBaseline._deregisterType("nonexistent")) PDFBaseline._aliasType("linear", "alias") self.assertEqual(2, PDFBaseline._deregisterType("alias")) @@ -113,12 +112,12 @@ def test__deregisterType(self): return def test_createByType(self): - """check PDFBaseline.createByType()""" + """Check PDFBaseline.createByType()""" self.assertRaises(ValueError, PDFBaseline.createByType, "notregistered") return def test_isRegisteredType(self): - """check PDFBaseline.isRegisteredType()""" + """Check PDFBaseline.isRegisteredType()""" self.assertTrue(PDFBaseline.isRegisteredType("linear")) self.assertFalse(PDFBaseline.isRegisteredType("nonexistent")) PDFBaseline._deregisterType("linear") @@ -126,7 +125,7 @@ def test_isRegisteredType(self): return def test_getAliasedTypes(self): - """check PDFBaseline.getAliasedTypes()""" + """Check PDFBaseline.getAliasedTypes()""" self.assertEqual({}, PDFBaseline.getAliasedTypes()) PDFBaseline._aliasType("linear", "foo") PDFBaseline._aliasType("linear", "bar") @@ -136,7 +135,7 @@ def test_getAliasedTypes(self): return def test_getRegisteredTypes(self): - """check PDFBaseline.getRegisteredTypes""" + """Check PDFBaseline.getRegisteredTypes.""" regtypes = PDFBaseline.getRegisteredTypes() self.assertTrue(2 <= len(regtypes)) self.assertTrue("linear" in regtypes) @@ -144,7 +143,7 @@ def test_getRegisteredTypes(self): return def test_pickling(self): - """check pickling and unpickling of PDFBaseline.""" + """Check pickling and unpickling of PDFBaseline.""" linear = self.linear linear.slope = 11 linear2 = pickle.loads(pickle.dumps(linear)) @@ -156,7 +155,7 @@ def test_pickling(self): return def test_makePDFBaseline(self): - """check the makePDFBaseline wrapper.""" + """Check the makePDFBaseline wrapper.""" pbl = makePDFBaseline("parabolabaseline", parabola_baseline, a=1, b=2, c=3) self.assertEqual(3, pbl(0)) self.assertEqual(6, pbl(1)) @@ -191,7 +190,7 @@ def test_makePDFBaseline(self): return def test_picking_owned(self): - """verify pickling of PDFBaseline owned by PDF calculators.""" + """Verify pickling of PDFBaseline owned by PDF calculators.""" pbl = makePDFBaseline("parabolabaseline", parabola_baseline, a=1, b=2, c=3) pbl.a = 7 pbl.foobar = "asdf" diff --git a/src/diffpy/srreal/tests/testpdfcalcobjcryst.py b/src/diffpy/srreal/tests/testpdfcalcobjcryst.py index 4f5960a7..01ef21b8 100644 --- a/src/diffpy/srreal/tests/testpdfcalcobjcryst.py +++ b/src/diffpy/srreal/tests/testpdfcalcobjcryst.py @@ -1,19 +1,16 @@ #!/usr/bin/env python -"""Unit tests for pdfcalculator.py on ObjCryst crystal structures -""" +"""Unit tests for pdfcalculator.py on ObjCryst crystal structures.""" import re import unittest import numpy -from diffpy.srreal.pdfcalculator import PDFCalculator -from diffpy.srreal.tests.testutils import has_pyobjcryst, _msg_nopyobjcryst -from diffpy.srreal.tests.testutils import loadObjCrystCrystal -from diffpy.srreal.tests.testutils import datafile +from diffpy.srreal.pdfcalculator import PDFCalculator from diffpy.srreal.tests.testpdfcalculator import _maxNormDiff +from diffpy.srreal.tests.testutils import _msg_nopyobjcryst, datafile, has_pyobjcryst, loadObjCrystCrystal # helper functions @@ -41,7 +38,8 @@ def _loadExpectedPDF(basefilename): def _makePDFCalculator(crst, cfgdict): - """Return a PDFCalculator object evaluated for a pyobjcryst.Crystal crst.""" + """Return a PDFCalculator object evaluated for a pyobjcryst.Crystal + crst.""" pdfcargs = {k: v for k, v in cfgdict.items() if k not in ("biso", "type")} pdfc = PDFCalculator(**pdfcargs) if "biso" in cfgdict: @@ -81,19 +79,19 @@ def setself(**kwtoset): return def test_CdSeN(self): - """check PDFCalculator on ObjCryst loaded CIF, neutrons""" + """Check PDFCalculator on ObjCryst loaded CIF, neutrons.""" self._comparePDFs("cdsen", "CdSe_cadmoselite_N.fgr", "CdSe_cadmoselite.cif") self.assertTrue(self.cdsen_mxnd < 0.01) return def test_CdSeX(self): - """check PDFCalculator on ObjCryst loaded CIF, xrays""" + """Check PDFCalculator on ObjCryst loaded CIF, xrays.""" self._comparePDFs("cdsex", "CdSe_cadmoselite_X.fgr", "CdSe_cadmoselite.cif") self.assertTrue(self.cdsex_mxnd < 0.01) return def test_rutileaniso(self): - """check PDFCalculator on ObjCryst loaded anisotropic rutile""" + """Check PDFCalculator on ObjCryst loaded anisotropic rutile.""" self._comparePDFs("rutileaniso", "TiO2_rutile-fit.fgr", "TiO2_rutile-fit.cif") self.assertTrue(self.rutileaniso_mxnd < 0.057) return diff --git a/src/diffpy/srreal/tests/testpdfcalculator.py b/src/diffpy/srreal/tests/testpdfcalculator.py index 7c1e2645..5b790032 100644 --- a/src/diffpy/srreal/tests/testpdfcalculator.py +++ b/src/diffpy/srreal/tests/testpdfcalculator.py @@ -1,24 +1,21 @@ #!/usr/bin/env python -"""Unit tests for diffpy.srreal.pdfcalculator -""" +"""Unit tests for diffpy.srreal.pdfcalculator.""" -import unittest import pickle +import unittest import numpy -from diffpy.srreal.tests.testutils import loadDiffPyStructure -from diffpy.srreal.tests.testutils import datafile -from diffpy.srreal.tests.testutils import pickle_with_attr -from diffpy.srreal.pdfcalculator import PDFCalculator -from diffpy.srreal.pdfcalculator import fftgtof, fftftog + +from diffpy.srreal.pdfcalculator import PDFCalculator, fftftog, fftgtof +from diffpy.srreal.tests.testutils import datafile, loadDiffPyStructure, pickle_with_attr # helper functions def _maxNormDiff(yobs, ycalc): - """Returned maximum difference normalized by RMS of the yobs""" + """Returned maximum difference normalized by RMS of the yobs.""" yobsa = numpy.array(yobs) obsmax = numpy.max(numpy.fabs(yobsa)) or 1 ynmdiff = (yobsa - ycalc) / obsmax @@ -46,7 +43,7 @@ def tearDown(self): return def test___init__(self): - """check PDFCalculator.__init__()""" + """Check PDFCalculator.__init__()""" pdfc = PDFCalculator(qmin=13, rmin=4, rmax=99) self.assertEqual(13, pdfc.qmin) self.assertEqual(4, pdfc.rmin) @@ -73,7 +70,7 @@ def test___call__(self): return def test__getDoubleAttr(self): - """check PDFCalculator._getDoubleAttr()""" + """Check PDFCalculator._getDoubleAttr()""" gdba = self.pdfcalc._getDoubleAttr self.assertEqual(1.0, gdba("scale")) self.assertEqual(0.0, gdba("qdamp")) @@ -81,19 +78,19 @@ def test__getDoubleAttr(self): return def test__hasDoubleAttr(self): - """check PDFCalculator._hasDoubleAttr()""" + """Check PDFCalculator._hasDoubleAttr()""" self.assertTrue(self.pdfcalc._hasDoubleAttr("scale")) self.assertFalse(self.pdfcalc._hasDoubleAttr("notanattribute")) return def test__namesOfDoubleAttributes(self): - """check PDFCalculator._namesOfDoubleAttributes()""" + """Check PDFCalculator._namesOfDoubleAttributes()""" self.assertTrue(type(self.pdfcalc._namesOfDoubleAttributes()) is set) self.assertTrue("qmax" in self.pdfcalc._namesOfDoubleAttributes()) return def test__setDoubleAttr(self): - """check PDFCalculator._setDoubleAttr()""" + """Check PDFCalculator._setDoubleAttr()""" gdba = self.pdfcalc._getDoubleAttr sdba = self.pdfcalc._setDoubleAttr self.assertEqual(0.0, gdba("rmin")) @@ -102,7 +99,7 @@ def test__setDoubleAttr(self): return def test_eval_nickel(self): - """check PDFCalculator.eval() on simple Nickel data""" + """Check PDFCalculator.eval() on simple Nickel data.""" fnipf2 = datafile("Ni-fit.fgr") gpf2 = numpy.loadtxt(fnipf2, usecols=(1,)) self.pdfcalc._setDoubleAttr("rmax", 10.0001) @@ -112,7 +109,7 @@ def test_eval_nickel(self): return def test_eval_rutile(self): - """check PDFCalculator.eval() on anisotropic rutile data""" + """Check PDFCalculator.eval() on anisotropic rutile data.""" frutile = datafile("TiO2_rutile-fit.fgr") gpf2 = numpy.loadtxt(frutile, usecols=(1,)) # configure calculator according to testdata/TiO2_ruitile-fit.fgr @@ -231,7 +228,7 @@ def test_zero_mask(self): return def test_pickling(self): - """check pickling and unpickling of PDFCalculator.""" + """Check pickling and unpickling of PDFCalculator.""" pdfc = self.pdfcalc pdfc.scatteringfactortable = "N" pdfc.scatteringfactortable.setCustomAs("Na", "Na", 7) @@ -276,7 +273,7 @@ def test_mask_pickling(self): return def test_pickling_derived_structure(self): - """check pickling of PDFCalculator with DerivedStructureAdapter.""" + """Check pickling of PDFCalculator with DerivedStructureAdapter.""" from diffpy.srreal.tests.testutils import DerivedStructureAdapter pdfc = self.pdfcalc diff --git a/src/diffpy/srreal/tests/testpdfenvelope.py b/src/diffpy/srreal/tests/testpdfenvelope.py index 7adb1060..cf840554 100644 --- a/src/diffpy/srreal/tests/testpdfenvelope.py +++ b/src/diffpy/srreal/tests/testpdfenvelope.py @@ -1,18 +1,23 @@ #!/usr/bin/env python -"""Unit tests for the PDFEnvelope class from diffpy.srreal.pdfcalculator -""" +"""Unit tests for the PDFEnvelope class from diffpy.srreal.pdfcalculator.""" -import unittest import pickle +import unittest + import numpy +from diffpy.srreal.pdfcalculator import DebyePDFCalculator, PDFCalculator +from diffpy.srreal.pdfenvelope import ( + PDFEnvelope, + QResolutionEnvelope, + ScaleEnvelope, + SphericalShapeEnvelope, + StepCutEnvelope, + makePDFEnvelope, +) from diffpy.srreal.tests.testutils import pickle_with_attr -from diffpy.srreal.pdfenvelope import PDFEnvelope, makePDFEnvelope -from diffpy.srreal.pdfenvelope import QResolutionEnvelope, ScaleEnvelope -from diffpy.srreal.pdfenvelope import SphericalShapeEnvelope, StepCutEnvelope -from diffpy.srreal.pdfcalculator import PDFCalculator, DebyePDFCalculator # ---------------------------------------------------------------------------- @@ -30,14 +35,14 @@ def tearDown(self): return def test___init__(self): - """check PDFEnvelope.__init__()""" + """Check PDFEnvelope.__init__()""" self.assertEqual(1.0, self.fscale.scale) self.fscale._setDoubleAttr("scale", 2.0) self.assertEqual(2.0, self.fscale.scale) return def test___call__(self): - """check PDFEnvelope.__call__()""" + """Check PDFEnvelope.__call__()""" x = numpy.arange(0, 9.1, 0.3) xb = numpy.array([(0.0, xi) for xi in x])[:, 1] self.assertTrue(xb.strides > x.strides) @@ -56,7 +61,7 @@ def test___call__(self): return def test_clone(self): - """check PDFEnvelope.clone""" + """Check PDFEnvelope.clone.""" # this is a virtual method in the base class self.assertRaises(RuntimeError, PDFEnvelope().clone) self.fstepcut.stepcut = 17 @@ -67,7 +72,7 @@ def test_clone(self): return def test_create(self): - """check PDFEnvelope.create""" + """Check PDFEnvelope.create.""" # this is a virtual method in the base class self.assertRaises(RuntimeError, PDFEnvelope().create) self.assertEqual("stepcut", self.fstepcut.create().type()) @@ -77,7 +82,7 @@ def test_create(self): return def test_type(self): - """check PDFEnvelope.type""" + """Check PDFEnvelope.type.""" # this is a virtual method in the base class self.assertRaises(RuntimeError, PDFEnvelope().type) self.assertEqual("stepcut", self.fstepcut.type()) @@ -85,12 +90,12 @@ def test_type(self): return def test_createByType(self): - """check PDFEnvelope.createByType()""" + """Check PDFEnvelope.createByType()""" self.assertRaises(ValueError, PDFEnvelope.createByType, "notregistered") return def test_getRegisteredTypes(self): - """check PDFEnvelope.getRegisteredTypes""" + """Check PDFEnvelope.getRegisteredTypes.""" regtypes = PDFEnvelope.getRegisteredTypes() self.assertTrue(2 <= len(regtypes)) self.assertTrue("stepcut" in regtypes) @@ -98,7 +103,7 @@ def test_getRegisteredTypes(self): return def test_pickling(self): - """check pickling and unpickling of PDFEnvelope.""" + """Check pickling and unpickling of PDFEnvelope.""" stp = self.fstepcut stp.stepcut = 11 stp2 = pickle.loads(pickle.dumps(stp)) @@ -108,7 +113,7 @@ def test_pickling(self): return def test_makePDFEnvelope(self): - """check the makePDFEnvelope wrapper.""" + """Check the makePDFEnvelope wrapper.""" pbl = makePDFEnvelope("parabolaenvelope", parabola_envelope, a=1, b=2, c=3) self.assertEqual(3, pbl(0)) self.assertEqual(6, pbl(1)) @@ -132,7 +137,7 @@ def test_makePDFEnvelope(self): return def test_picking_owned(self): - """verify pickling of envelopes owned by PDF calculators.""" + """Verify pickling of envelopes owned by PDF calculators.""" pbl = makePDFEnvelope("parabolaenvelope", parabola_envelope, a=1, b=2, c=3) pbl.a = 7 pbl.foobar = "asdf" diff --git a/src/diffpy/srreal/tests/testpeakprofile.py b/src/diffpy/srreal/tests/testpeakprofile.py index d187e969..56e3943e 100644 --- a/src/diffpy/srreal/tests/testpeakprofile.py +++ b/src/diffpy/srreal/tests/testpeakprofile.py @@ -1,17 +1,16 @@ #!/usr/bin/env python -"""Unit tests for the PeakProfile classes from diffpy.srreal.peakprofile -""" +"""Unit tests for the PeakProfile classes from diffpy.srreal.peakprofile.""" -import unittest import pickle +import unittest + import numpy -from diffpy.srreal.tests.testutils import pickle_with_attr -from diffpy.srreal.tests.testutils import mod_structure -from diffpy.srreal.peakprofile import PeakProfile from diffpy.srreal.pdfcalculator import PDFCalculator +from diffpy.srreal.peakprofile import PeakProfile +from diffpy.srreal.tests.testutils import mod_structure, pickle_with_attr # ---------------------------------------------------------------------------- @@ -27,7 +26,7 @@ def tearDown(self): return def test___init__(self): - """check PeakProfile.__init__()""" + """Check PeakProfile.__init__()""" self.assertNotEqual(0.0, self.pkgauss.peakprecision) self.assertEqual(self.pkgauss.peakprecision, self.pkcropped.peakprecision) self.pkgauss._setDoubleAttr("peakprecision", 0.01) @@ -35,7 +34,7 @@ def test___init__(self): return def test_create(self): - """check PeakProfile.create""" + """Check PeakProfile.create.""" # this is a virtual method in the base class self.assertRaises(RuntimeError, PeakProfile().create) self.assertEqual("gaussian", self.pkgauss.create().type()) @@ -44,7 +43,7 @@ def test_create(self): return def test_clone(self): - """check PeakProfile.clone""" + """Check PeakProfile.clone.""" # this is a virtual method in the base class self.assertRaises(RuntimeError, PeakProfile().clone) self.pkgauss.peakprecision = 0.0003 @@ -55,14 +54,14 @@ def test_clone(self): return def test_type(self): - """check PeakProfile.type""" + """Check PeakProfile.type.""" # this is a virtual method in the base class self.assertRaises(RuntimeError, PeakProfile().type) self.assertEqual("croppedgaussian", self.pkcropped.type()) return def test___call__(self): - """check PeakProfile.__call__()""" + """Check PeakProfile.__call__()""" ymx = self.pkgauss(0.0, 1) yhalflo = self.pkgauss(-0.5, 1) yhalfhi = self.pkgauss(-0.5, 1) @@ -73,7 +72,7 @@ def test___call__(self): return def test_ticker(self): - """check PeakProfile.ticker()""" + """Check PeakProfile.ticker()""" from diffpy.srreal.eventticker import EventTicker et0 = EventTicker(self.pkgauss.ticker()) @@ -84,7 +83,7 @@ def test_ticker(self): return def test_ticker_override(self): - """check method override for PeakProfile.ticker in a derived class.""" + """Check method override for PeakProfile.ticker in a derived class.""" pkf = MySawTooth() self.assertEqual(0, pkf.tcnt) et0 = pkf.ticker() @@ -103,14 +102,14 @@ def test_ticker_override(self): return def test_getRegisteredTypes(self): - """check PeakProfile.getRegisteredTypes""" + """Check PeakProfile.getRegisteredTypes.""" regtypes = PeakProfile.getRegisteredTypes() self.assertTrue(2 <= len(regtypes)) self.assertTrue(regtypes.issuperset(["gaussian", "croppedgaussian"])) return def test_pickling(self): - """check pickling and unpickling of PeakProfile.""" + """Check pickling and unpickling of PeakProfile.""" pkg = self.pkgauss pkg.peakprecision = 0.0011 pkg2 = pickle.loads(pickle.dumps(pkg)) diff --git a/src/diffpy/srreal/tests/testpeakwidthmodel.py b/src/diffpy/srreal/tests/testpeakwidthmodel.py index 18a00465..0ba053f7 100644 --- a/src/diffpy/srreal/tests/testpeakwidthmodel.py +++ b/src/diffpy/srreal/tests/testpeakwidthmodel.py @@ -1,15 +1,14 @@ #!/usr/bin/env python -"""Unit tests for the PeakWidthModel classes from diffpy.srreal.peakwidthmodel -""" +"""Unit tests for the PeakWidthModel classes from +diffpy.srreal.peakwidthmodel.""" -import unittest import pickle +import unittest -from diffpy.srreal.peakwidthmodel import PeakWidthModel -from diffpy.srreal.peakwidthmodel import DebyeWallerPeakWidth, JeongPeakWidth from diffpy.srreal.pdfcalculator import DebyePDFCalculator, PDFCalculator +from diffpy.srreal.peakwidthmodel import DebyeWallerPeakWidth, JeongPeakWidth, PeakWidthModel from diffpy.srreal.structureadapter import createStructureAdapter from diffpy.srreal.tests.testutils import loadDiffPyStructure @@ -41,14 +40,14 @@ def _genbonds(self, rmin, rmax): return bnds def test___init__(self): - """check PeakWidthModel.__init__()""" + """Check PeakWidthModel.__init__()""" self.assertEqual(2.0, self.pwconst.width) self.pwconst._setDoubleAttr("width", 3.0) self.assertEqual(3.0, self.pwconst.width) return def test_create(self): - """check PeakWidthModel.create""" + """Check PeakWidthModel.create.""" # this is a virtual method in the base class self.assertRaises(RuntimeError, PeakWidthModel().create) self.assertEqual("constant", self.pwconst.create().type()) @@ -57,7 +56,7 @@ def test_create(self): return def test_clone(self): - """check PeakWidthModel.clone""" + """Check PeakWidthModel.clone.""" # this is a virtual method in the base class self.assertRaises(RuntimeError, PeakWidthModel().clone) self.pwconst.width = 17 @@ -68,14 +67,14 @@ def test_clone(self): return def test_type(self): - """check PeakWidthModel.type""" + """Check PeakWidthModel.type.""" # this is a virtual method in the base class self.assertRaises(RuntimeError, PeakWidthModel().type) self.assertEqual("constant", self.pwconst.type()) return def test_calculate(self): - """check PeakWidthModel.calculate()""" + """Check PeakWidthModel.calculate()""" pwm = PeakWidthModel() bnds = self._genbonds(1, 2) self.assertRaises(RuntimeError, pwm.calculate, bnds) @@ -83,7 +82,7 @@ def test_calculate(self): return def test_isowidths(self): - """check ConstantPeakWidth properties bisowidth, uisowidth.""" + """Check ConstantPeakWidth properties bisowidth, uisowidth.""" from numpy import pi cnpw = self.pwconst @@ -96,14 +95,14 @@ def test_isowidths(self): return def test_maxWidth(self): - """check PeakWidthModel.maxWidth()""" + """Check PeakWidthModel.maxWidth()""" self.assertRaises(RuntimeError, PeakWidthModel().maxWidth, self.tio2adpt, 0, 10) self.assertEqual(2.0, self.pwconst.maxWidth(self.tio2adpt, 0, 10)) self.assertEqual(2.0, self.pwconst.maxWidth(self.tio2stru, 0, 10)) return def test_ticker(self): - """check PeakWidthModel.ticker()""" + """Check PeakWidthModel.ticker()""" from diffpy.srreal.eventticker import EventTicker et0 = EventTicker(self.pwconst.ticker()) @@ -114,7 +113,7 @@ def test_ticker(self): return def test_ticker_override(self): - """check PeakWidthModel.ticker override in a Python-derived class.""" + """Check PeakWidthModel.ticker override in a Python-derived class.""" pwm = MyPWM() self.assertEqual(0, pwm.tcnt) et0 = pwm.ticker() @@ -133,14 +132,14 @@ def test_ticker_override(self): return def test_getRegisteredTypes(self): - """check PeakWidthModel.getRegisteredTypes""" + """Check PeakWidthModel.getRegisteredTypes.""" regtypes = PeakWidthModel.getRegisteredTypes() self.assertTrue(3 <= len(regtypes)) self.assertTrue(regtypes.issuperset(["constant", "debye-waller", "jeong"])) return def test_pickling(self): - """check pickling and unpickling of PeakWidthModel.""" + """Check pickling and unpickling of PeakWidthModel.""" pwc = self.pwconst pwc.width = 11 pwc2 = pickle.loads(pickle.dumps(pwc)) @@ -160,13 +159,13 @@ def setUp(self): return def test_type(self): - """check DebyeWallerPeakWidth.type""" + """Check DebyeWallerPeakWidth.type.""" self.assertEqual("debye-waller", self.pwm.type()) self.assertEqual(0, len(self.pwm._namesOfDoubleAttributes())) return def test_pickling(self): - """check pickling of DebyeWallerPeakWidth class.""" + """Check pickling of DebyeWallerPeakWidth class.""" self.assertEqual("debye-waller", self.pwm.type()) pwm = self.pwm pwm2 = pickle.loads(pickle.dumps(pwm)) @@ -184,7 +183,7 @@ def setUp(self): return def test_type(self): - """check JeongPeakWidth.type""" + """Check JeongPeakWidth.type.""" self.assertEqual("jeong", self.pwm.type()) self.assertTrue(hasattr(self.pwm, "delta1")) self.assertTrue(hasattr(self.pwm, "delta2")) @@ -192,7 +191,7 @@ def test_type(self): return def test_pickling(self): - """check pickling of the DebyeWallerPeakWidth class""" + """Check pickling of the DebyeWallerPeakWidth class.""" pwm = self.pwm pwm.delta1 = 1 pwm.delta2 = 2 diff --git a/src/diffpy/srreal/tests/testscatteringfactortable.py b/src/diffpy/srreal/tests/testscatteringfactortable.py index ba4dbebc..e4c95be6 100644 --- a/src/diffpy/srreal/tests/testscatteringfactortable.py +++ b/src/diffpy/srreal/tests/testscatteringfactortable.py @@ -1,18 +1,22 @@ #!/usr/bin/env python -"""Unit tests for diffpy.srreal.scatteringfactortable -""" +"""Unit tests for diffpy.srreal.scatteringfactortable.""" -import unittest import pickle +import unittest + import numpy +from diffpy.srreal.pdfcalculator import DebyePDFCalculator, PDFCalculator +from diffpy.srreal.scatteringfactortable import ( + ScatteringFactorTable, + SFTElectron, + SFTElectronNumber, + SFTNeutron, + SFTXray, +) from diffpy.srreal.tests.testutils import pickle_with_attr -from diffpy.srreal.scatteringfactortable import ScatteringFactorTable -from diffpy.srreal.scatteringfactortable import SFTXray, SFTElectron -from diffpy.srreal.scatteringfactortable import SFTNeutron, SFTElectronNumber -from diffpy.srreal.pdfcalculator import PDFCalculator, DebyePDFCalculator # ---------------------------------------------------------------------------- @@ -58,7 +62,7 @@ def tearDown(self): return def test_class_registry(self): - """check if instances are aliased by radiationType().""" + """Check if instances are aliased by radiationType().""" ltb = ScatteringFactorTable.createByType("LTB") self.assertTrue(type(ltb) is LocalTable) ltb2 = ScatteringFactorTable.createByType("localtable") @@ -66,7 +70,7 @@ def test_class_registry(self): return def test_ticker(self): - """check ScatteringFactorTable.ticker()""" + """Check ScatteringFactorTable.ticker()""" from diffpy.srreal.eventticker import EventTicker et0 = EventTicker(self.sftx.ticker()) @@ -77,7 +81,7 @@ def test_ticker(self): return def test_ticker_override(self): - """check Python override of ScatteringFactorTable.ticker.""" + """Check Python override of ScatteringFactorTable.ticker.""" from diffpy.srreal.pdfcalculator import PDFCalculator lsft = LocalTable() @@ -98,7 +102,7 @@ def test_ticker_override(self): return def test_pickling(self): - """check pickling of ScatteringFactorTable instances.""" + """Check pickling of ScatteringFactorTable instances.""" self.assertEqual(0, len(self.sftx.getCustomSymbols())) self.sftx.setCustomAs("Na", "Na", 123) self.sftx.setCustomAs("Calias", "C") @@ -116,7 +120,7 @@ def test_pickling(self): return def test_picking_owned(self): - """verify pickling of envelopes owned by PDF calculators.""" + """Verify pickling of envelopes owned by PDF calculators.""" pc = PDFCalculator() dbpc = DebyePDFCalculator() ltb = LocalTable() @@ -137,7 +141,7 @@ def test_picking_owned(self): return def test_pickling_derived(self): - """check pickling of a derived classes.""" + """Check pickling of a derived classes.""" lsft = LocalTable() self.assertEqual(3, lsft._standardLookup("Na", 2)) self.assertEqual(set(), lsft.getCustomSymbols()) diff --git a/src/diffpy/srreal/tests/testsfaverage.py b/src/diffpy/srreal/tests/testsfaverage.py index b23cb8a6..6efaa981 100644 --- a/src/diffpy/srreal/tests/testsfaverage.py +++ b/src/diffpy/srreal/tests/testsfaverage.py @@ -1,17 +1,20 @@ #!/usr/bin/env python -"""Unit tests for diffpy.srreal.sfaverage -""" +"""Unit tests for diffpy.srreal.sfaverage.""" import unittest + import numpy -from diffpy.srreal.sfaverage import SFAverage from diffpy.srreal.scatteringfactortable import ScatteringFactorTable -from diffpy.srreal.tests.testutils import loadDiffPyStructure -from diffpy.srreal.tests.testutils import has_pyobjcryst, _msg_nopyobjcryst -from diffpy.srreal.tests.testutils import loadObjCrystCrystal +from diffpy.srreal.sfaverage import SFAverage +from diffpy.srreal.tests.testutils import ( + _msg_nopyobjcryst, + has_pyobjcryst, + loadDiffPyStructure, + loadObjCrystCrystal, +) # ---------------------------------------------------------------------------- @@ -27,7 +30,7 @@ def tearDown(self): return def test_fromStructure_CdSe(self): - """check SFAverage.fromStructure() for CdSe""" + """Check SFAverage.fromStructure() for CdSe.""" cdse = loadDiffPyStructure("CdSe_cadmoselite.cif") sfavg = SFAverage.fromStructure(cdse, self.sftx) fcd = self.sftx.lookup("Cd") @@ -55,7 +58,7 @@ def test_fromStructure_CdSe(self): return def test_fromComposition(self): - """check SFAverage.fromComposition()""" + """Check SFAverage.fromComposition()""" sfavg1 = SFAverage.fromComposition({"Na": 1, "Cl": 1}, self.sftx) fm = ["Na", 0.25, "Cl", 0.75, "Cl", 0.25, "Na", 0.5, "Na", 0.25] smblcnts = zip(fm[0::2], fm[1::2]) @@ -86,7 +89,7 @@ def tearDown(self): return def test_from_rutile(self): - """check SFAverage.fromStructure for pyobjcryst Crystal of rutile.""" + """Check SFAverage.fromStructure for pyobjcryst Crystal of rutile.""" rutile = loadObjCrystCrystal("rutile.cif") qa = numpy.arange(0, 25, 0.1) sfavg = SFAverage.fromStructure(rutile, self.sftx, qa) diff --git a/src/diffpy/srreal/tests/teststructureadapter.py b/src/diffpy/srreal/tests/teststructureadapter.py index 932a4ddc..55a3604c 100644 --- a/src/diffpy/srreal/tests/teststructureadapter.py +++ b/src/diffpy/srreal/tests/teststructureadapter.py @@ -1,28 +1,32 @@ #!/usr/bin/env python -"""Unit tests for diffpy.srreal.structureadapter -""" +"""Unit tests for diffpy.srreal.structureadapter.""" -import unittest import pickle +import unittest + import numpy + +import diffpy.srreal.tests.testutils as testutils from diffpy.srreal.pdfcalculator import PDFCalculator -from diffpy.srreal.tests.testutils import has_pyobjcryst, _msg_nopyobjcryst -from diffpy.srreal.tests.testutils import loadObjCrystCrystal -from diffpy.srreal.tests.testutils import loadDiffPyStructure -from diffpy.srreal.tests.testutils import loadCrystalStructureAdapter from diffpy.srreal.structureadapter import ( + Atom, + AtomicStructureAdapter, + CrystalStructureAdapter, + PeriodicStructureAdapter, + StructureAdapter, createStructureAdapter, nometa, nosymmetry, - StructureAdapter, - AtomicStructureAdapter, - Atom, - PeriodicStructureAdapter, - CrystalStructureAdapter, ) -import diffpy.srreal.tests.testutils as testutils +from diffpy.srreal.tests.testutils import ( + _msg_nopyobjcryst, + has_pyobjcryst, + loadCrystalStructureAdapter, + loadDiffPyStructure, + loadObjCrystCrystal, +) # ---------------------------------------------------------------------------- @@ -34,7 +38,7 @@ def setUp(self): return def test_createStructureAdapter(self): - """check createStructureAdapter() routine.""" + """Check createStructureAdapter() routine.""" adpt = createStructureAdapter(self.nickel) self.assertEqual(4, adpt.countSites()) self.assertTrue(False is adpt.siteAnisotropy(0)) @@ -74,7 +78,7 @@ def test_createStructureAdapter_int64_occupancy(self): return def test_pickling(self): - """check pickling of StructureAdapter instances.""" + """Check pickling of StructureAdapter instances.""" adpt = createStructureAdapter(self.nickel) adpt1 = pickle.loads(pickle.dumps(adpt)) self.assertFalse(adpt is adpt1) @@ -113,7 +117,7 @@ def setUp(self): return def test__customPQConfig(self): - """check if DerivedCls._customPQConfig gets called.""" + """Check if DerivedCls._customPQConfig gets called.""" self.assertEqual(0, self.adpt.cpqcount) pc = PDFCalculator() pc.setStructure(self.adpt) @@ -123,7 +127,7 @@ def test__customPQConfig(self): return def test_pickling(self): - """check pickling of DerivedCls instances.""" + """Check pickling of DerivedCls instances.""" self.adpt.cpqcount = 1 adpt1 = pickle.loads(pickle.dumps(self.adpt)) self.assertTrue(self.DerivedCls is type(adpt1)) @@ -162,7 +166,7 @@ def setUp(self): return def test_nometa(self): - """check NoMetaStructureAdapter.""" + """Check NoMetaStructureAdapter.""" r0, g0 = PDFCalculator()(self.nickel) ni1 = self.nickel.copy() ni1.pdffit["scale"] = 2.0 @@ -188,7 +192,7 @@ def test_nometa(self): return def test_nometa_pickling(self): - """check pickling of the NoMetaStructureAdapter wrapper.""" + """Check pickling of the NoMetaStructureAdapter wrapper.""" r0, g0 = PDFCalculator()(self.nickel) ni1 = self.nickel.copy() ni1.pdffit["scale"] = 2.0 @@ -200,7 +204,7 @@ def test_nometa_pickling(self): return def test_nometa_twice(self): - """check that second call of nometa returns the same object.""" + """Check that second call of nometa returns the same object.""" adpt1 = nometa(self.nickel) adpt2 = nometa(adpt1) self.assertTrue(adpt1 is adpt2) @@ -218,7 +222,7 @@ def setUp(self): return def test_nosymmetry(self): - """check NoSymmetryStructureAdapter.""" + """Check NoSymmetryStructureAdapter.""" pdfc0 = PDFCalculator() r0, g0 = pdfc0(self.nickel) rdf0 = pdfc0.rdf @@ -242,13 +246,13 @@ def test_nosymmetry(self): return def test_nosymmetry_twice(self): - """check that second call of nosymmetry returns the same object.""" + """Check that second call of nosymmetry returns the same object.""" adpt1 = nosymmetry(self.nickel) adpt2 = nosymmetry(adpt1) self.assertTrue(adpt1 is adpt2) def test_nosymmetry_pickling(self): - """check pickling of the NoSymmetryStructureAdapter wrapper.""" + """Check pickling of the NoSymmetryStructureAdapter wrapper.""" ni1ns = nosymmetry(self.nickel) r1, g1 = PDFCalculator()(ni1ns) ni2ns = pickle.loads(pickle.dumps(ni1ns)) @@ -273,7 +277,7 @@ def setUp(self): return def test_objcryst_adapter(self): - """check ObjCrystStructureAdapter for rutile.""" + """Check ObjCrystStructureAdapter for rutile.""" self.assertEqual(2, self.rutile.countSites()) self.assertEqual(6, self.rutile.totalOccupancy()) self.assertEqual("Ti", self.rutile.siteAtomType(0)) @@ -289,7 +293,7 @@ def test_objcryst_adapter(self): return def test_objcryst_pickling(self): - """check pickling of the NoSymmetryStructureAdapter wrapper.""" + """Check pickling of the NoSymmetryStructureAdapter wrapper.""" r0, g0 = PDFCalculator()(self.rutile) rutile1 = pickle.loads(pickle.dumps(self.rutile)) self.assertFalse(self.rutile is rutile1) @@ -487,34 +491,34 @@ def setUp(self): # return def test_siteAtomType(self): - """check StructureAdapter.siteAtomType()""" + """Check StructureAdapter.siteAtomType()""" self.assertEqual("", self.adpt.siteAtomType(0)) return def test_siteCartesianPosition(self): - """check StructureAdapter.siteCartesianPosition()""" + """Check StructureAdapter.siteCartesianPosition()""" self.assertRaises(RuntimeError, self.adpt.siteAnisotropy, 0) return def test_siteMultiplicity(self): - """check StructureAdapter.siteMultiplicity()""" + """Check StructureAdapter.siteMultiplicity()""" self.assertEqual(1, self.adpt.siteMultiplicity(0)) return def test_siteOccupancy(self): - """check StructureAdapter.siteOccupancy()""" - # check if we use the C++ method that alwasy return 1. + """Check StructureAdapter.siteOccupancy()""" + # check if we use the C++ method that always return 1. self.assertEqual(1.0, self.adpt.siteOccupancy(0)) self.assertEqual(1.0, self.adpt.siteOccupancy(99)) return def test_siteAnisotropy(self): - """check StructureAdapter.siteAnisotropy()""" + """Check StructureAdapter.siteAnisotropy()""" self.assertRaises(RuntimeError, self.adpt.siteAnisotropy, 0) return def test_siteCartesianUij(self): - """check StructureAdapter.siteCartesianUij()""" + """Check StructureAdapter.siteCartesianUij()""" self.assertRaises(RuntimeError, self.adpt.siteCartesianUij, 0) return @@ -536,7 +540,7 @@ def setUp(self): return def test___init__copy(self): - """check Atom copy constructor.""" + """Check Atom copy constructor.""" self.a.xyz_cartn = (1, 2, 3) a1 = Atom(self.a) self.assertEqual(self.a, a1) @@ -544,7 +548,7 @@ def test___init__copy(self): return def test_equality(self): - """check Atom equal and not equal operators.""" + """Check Atom equal and not equal operators.""" self.assertEqual(self.a, Atom()) self.assertFalse(self.a != Atom()) a1 = Atom() @@ -553,7 +557,7 @@ def test_equality(self): return def test_pickling(self): - """check pickling of Atom instances.""" + """Check pickling of Atom instances.""" self.a.atomtype = "Na" a1 = pickle.loads(pickle.dumps(self.a)) self.assertEqual("Na", a1.atomtype) @@ -562,7 +566,7 @@ def test_pickling(self): return def test_xyz_cartn(self): - """check Atom.xyz_cartn.""" + """Check Atom.xyz_cartn.""" a = self.a a.xyz_cartn = 4, 5, 6 self.assertTrue(numpy.array_equal([4, 5, 6], a.xyz_cartn)) @@ -572,7 +576,7 @@ def test_xyz_cartn(self): return def test_uij_cartn(self): - """check Atom.uij_cartn""" + """Check Atom.uij_cartn.""" a = self.a a.uij_cartn = numpy.identity(3) * 0.01 a.uc12 = 0.012 diff --git a/src/diffpy/srreal/tests/testutils.py b/src/diffpy/srreal/tests/testutils.py index c16ae8dd..8cbb3ecc 100644 --- a/src/diffpy/srreal/tests/testutils.py +++ b/src/diffpy/srreal/tests/testutils.py @@ -1,13 +1,19 @@ #!/usr/bin/env python -"""Helper routines for running other unit tests. -""" +"""Helper routines for running other unit tests.""" import copy -import numpy import pickle +import numpy + +from diffpy.srreal.structureadapter import ( + AtomicStructureAdapter, + CrystalStructureAdapter, + PeriodicStructureAdapter, + StructureAdapter, +) from diffpy.srreal.structureconverters import convertObjCrystCrystal from diffpy.srreal.tests import logger @@ -104,11 +110,6 @@ def pickle_with_attr(obj, **attr): # helper class for testing overloading of StructureAdapter -from diffpy.srreal.structureadapter import StructureAdapter -from diffpy.srreal.structureadapter import AtomicStructureAdapter -from diffpy.srreal.structureadapter import PeriodicStructureAdapter -from diffpy.srreal.structureadapter import CrystalStructureAdapter - class HasCustomPQConfig(object): diff --git a/src/diffpy/srreal/version.py b/src/diffpy/srreal/version.py index a078d249..67596f6b 100644 --- a/src/diffpy/srreal/version.py +++ b/src/diffpy/srreal/version.py @@ -12,9 +12,7 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - -""" -Definitions of version-related constants and of libdiffpy_version_info. +"""Definitions of version-related constants and of libdiffpy_version_info. Notes ----- @@ -28,10 +26,7 @@ __all__ = ["__date__", "__git_commit__", "__timestamp__", "__version__", "libdiffpy_version_info"] -from diffpy.srreal._version_data import __version__ -from diffpy.srreal._version_data import __date__ -from diffpy.srreal._version_data import __git_commit__ -from diffpy.srreal._version_data import __timestamp__ +from diffpy.srreal._version_data import __date__, __git_commit__, __timestamp__, __version__ # TODO remove deprecated __gitsha__ in version 1.4. __gitsha__ = __git_commit__ @@ -39,6 +34,7 @@ # version information on the active libdiffpy shared library ----------------- from collections import namedtuple + from diffpy.srreal.srreal_ext import _get_libdiffpy_version_info_dict libdiffpy_version_info = namedtuple( diff --git a/src/diffpy/srreal/wraputils.py b/src/diffpy/srreal/wraputils.py index e9eb19e1..a026edd3 100644 --- a/src/diffpy/srreal/wraputils.py +++ b/src/diffpy/srreal/wraputils.py @@ -12,9 +12,7 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - -"""Local utilities helpful for tweaking interfaces to boost python classes. -""" +"""Local utilities helpful for tweaking interfaces to boost python classes.""" import copy @@ -63,8 +61,8 @@ def setattrFromKeywordArguments(obj, **kwargs): def _wrapAsRegisteredUnaryFunction(cls, regname, fnc, replace=False, **dbattrs): """Helper function for wrapping Python function as PDFBaseline or - PDFEnvelope functor. Not intended for direct usage, this function - is rather called from makePDFBaseline or makePDFEnvelope wrappers. + PDFEnvelope functor. Not intended for direct usage, this function is + rather called from makePDFBaseline or makePDFEnvelope wrappers. cls -- the functor class for wrapping the Python function regname -- string name for registering the function in the global @@ -96,9 +94,9 @@ def clone(self): return copy.copy(self) def type(self): - """Unique string identifier of this functor type. The string - is used for class registration and as an argument for the - createByType function. + """Unique string identifier of this functor type. The string is + used for class registration and as an argument for the createByType + function. Return string identifier. """ From d14bb52e331738c911c97ce3bac2b1c2569c5491 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Wed, 1 Jan 2025 18:43:35 -0500 Subject: [PATCH 04/55] add PR test workflow and issue templates --- .github/ISSUE_TEMPLATE/bug_feature.md | 16 +++++++ .github/ISSUE_TEMPLATE/release_checklist.md | 46 +++++++++++++++++++++ .github/workflows/tests-on-pr.yml | 43 +++++++++++++++++++ environment.yml | 6 +++ requirements/conda.txt | 1 + 5 files changed, 112 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_feature.md create mode 100644 .github/ISSUE_TEMPLATE/release_checklist.md create mode 100644 .github/workflows/tests-on-pr.yml create mode 100644 environment.yml diff --git a/.github/ISSUE_TEMPLATE/bug_feature.md b/.github/ISSUE_TEMPLATE/bug_feature.md new file mode 100644 index 00000000..b3454deb --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_feature.md @@ -0,0 +1,16 @@ +--- +name: Bug Report or Feature Request +about: Report a bug or suggest a new feature! +title: "" +labels: "" +assignees: "" +--- + +### Problem + + + +### Proposed solution diff --git a/.github/ISSUE_TEMPLATE/release_checklist.md b/.github/ISSUE_TEMPLATE/release_checklist.md new file mode 100644 index 00000000..11df804d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/release_checklist.md @@ -0,0 +1,46 @@ +--- +name: Release +about: Checklist and communication channel for PyPI and GitHub release +title: "Ready for PyPI/GitHub release" +labels: "release" +assignees: "" +--- + +### PyPI/GitHub rc-release preparation checklist: + +- [ ] All PRs/issues attached to the release are merged. +- [ ] All the badges on the README are passing. +- [ ] License information is verified as correct. If you are unsure, please comment below. +- [ ] Locally rendered documentation contains all appropriate pages, including API references (check no modules are + missing), tutorials, and other human-written text is up-to-date with any changes in the code. +- [ ] Installation instructions in the README, documentation, and the website (e.g., diffpy.org) are updated. +- [ ] Successfully run any tutorial examples or do functional testing with the latest Python version. +- [ ] Grammar and writing quality are checked (no typos). +- [ ] Install `pip install build twine`, run `python -m build` and `twine check dist/*` to ensure that the package can be built and is correctly formatted for PyPI release. + +Please mention @sbillinge here when you are ready for PyPI/GitHub release. Include any additional comments necessary, such as version information and details about the pre-release here: + +### PyPI/GitHub full-release preparation checklist: + +- [ ] Create a new conda environment and install the rc from PyPI (`pip install ==??`) +- [ ] License information on PyPI is correct. +- [ ] Docs are deployed successfully to `https://www.diffpy.org/`. +- [ ] Successfully run all tests, tutorial examples or do functional testing. + +Please let @sbillinge know that all checks are done and the package is ready for full release. + +### conda-forge release preparation checklist: + + + +- [ ] Ensure that the full release has appeared on PyPI successfully. +- [ ] New package dependencies listed in `conda.txt` and `test.txt` are added to `meta.yaml` in the feedstock. +- [ ] Close any open issues on the feedstock. Reach out to @bobleesj if you have questions. +- [ ] Tag @sbillinge and @bobleesj for conda-forge release. + +### Post-release checklist + + + +- [ ] Run tutorial examples and conduct functional testing using the installation guide in the README. Attach screenshots/results as comments. +- [ ] Documentation (README, tutorials, API references, and websites) is deployed without broken links or missing figures. diff --git a/.github/workflows/tests-on-pr.yml b/.github/workflows/tests-on-pr.yml new file mode 100644 index 00000000..2c1ffad5 --- /dev/null +++ b/.github/workflows/tests-on-pr.yml @@ -0,0 +1,43 @@ +name: Tests on PR + +on: + push: + branches: + - main + pull_request: + workflow_dispatch: + +jobs: + validate: + defaults: + run: + shell: bash -l {0} + + runs-on: ubuntu-latest + steps: + - name: Check out diffpy.srreal + uses: actions/checkout@v4 + + - name: Initialize miniconda + uses: conda-incubator/setup-miniconda@v3 + with: + activate-environment: test + auto-update-conda: true + environment-file: environment.yml + auto-activate-base: false + python-version: 3.12 + + - name: Conda config + run: >- + conda config --set always_yes yes + --set changeps1 no + + - name: Install diffpy.srreal and requirements + run: | + conda install --file requirements/test.txt + conda install --file requirements/conda.txt + python -m pip install . --no-deps + + - name: Validate diffpy.pdfgui + run: + python -m diffpy.srreal.tests.run diff --git a/environment.yml b/environment.yml new file mode 100644 index 00000000..a3904941 --- /dev/null +++ b/environment.yml @@ -0,0 +1,6 @@ +name: diffpy.pdfgui +channels: + - conda-forge +dependencies: + - python=3 + - pip diff --git a/requirements/conda.txt b/requirements/conda.txt index af3f87d8..a2ce8f05 100644 --- a/requirements/conda.txt +++ b/requirements/conda.txt @@ -1,5 +1,6 @@ boost numpy +libdiffpy setuptools diffpy.structure periodictable From c0fd7d60a6364a691e6337ff4f56c70636f21d93 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Wed, 1 Jan 2025 18:54:49 -0500 Subject: [PATCH 05/55] pcmt --- .github/ISSUE_TEMPLATE/release_checklist.md | 8 ++++---- .github/workflows/tests-on-pr.yml | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/release_checklist.md b/.github/ISSUE_TEMPLATE/release_checklist.md index 11df804d..fa94779e 100644 --- a/.github/ISSUE_TEMPLATE/release_checklist.md +++ b/.github/ISSUE_TEMPLATE/release_checklist.md @@ -12,11 +12,11 @@ assignees: "" - [ ] All the badges on the README are passing. - [ ] License information is verified as correct. If you are unsure, please comment below. - [ ] Locally rendered documentation contains all appropriate pages, including API references (check no modules are - missing), tutorials, and other human-written text is up-to-date with any changes in the code. + missing), tutorials, and other human-written text is up-to-date with any changes in the code. - [ ] Installation instructions in the README, documentation, and the website (e.g., diffpy.org) are updated. - [ ] Successfully run any tutorial examples or do functional testing with the latest Python version. - [ ] Grammar and writing quality are checked (no typos). -- [ ] Install `pip install build twine`, run `python -m build` and `twine check dist/*` to ensure that the package can be built and is correctly formatted for PyPI release. +- [ ] Install `pip install build twine`, run `python -m build` and `twine check dist/*` to ensure that the package can be built and is correctly formatted for PyPI release. Please mention @sbillinge here when you are ready for PyPI/GitHub release. Include any additional comments necessary, such as version information and details about the pre-release here: @@ -42,5 +42,5 @@ Please let @sbillinge know that all checks are done and the package is ready for -- [ ] Run tutorial examples and conduct functional testing using the installation guide in the README. Attach screenshots/results as comments. -- [ ] Documentation (README, tutorials, API references, and websites) is deployed without broken links or missing figures. +- [ ] Run tutorial examples and conduct functional testing using the installation guide in the README. Attach screenshots/results as comments. +- [ ] Documentation (README, tutorials, API references, and websites) is deployed without broken links or missing figures. diff --git a/.github/workflows/tests-on-pr.yml b/.github/workflows/tests-on-pr.yml index 2c1ffad5..bb5d9098 100644 --- a/.github/workflows/tests-on-pr.yml +++ b/.github/workflows/tests-on-pr.yml @@ -39,5 +39,4 @@ jobs: python -m pip install . --no-deps - name: Validate diffpy.pdfgui - run: - python -m diffpy.srreal.tests.run + run: python -m diffpy.srreal.tests.run From 1bd44475f827c88fd5fc8a81a9a1a8f4715824fb Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Wed, 1 Jan 2025 21:17:38 -0500 Subject: [PATCH 06/55] add cookie --- .github/workflows/tests-on-pr.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/tests-on-pr.yml b/.github/workflows/tests-on-pr.yml index bb5d9098..f9b4d90b 100644 --- a/.github/workflows/tests-on-pr.yml +++ b/.github/workflows/tests-on-pr.yml @@ -4,6 +4,7 @@ on: push: branches: - main + - cookie pull_request: workflow_dispatch: From ea77121c6e202bb9ea6e6aa56b8b700ca0451e6e Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Sat, 11 Jan 2025 00:06:43 -0500 Subject: [PATCH 07/55] move tests --- {src/diffpy/srreal/tests => tests}/__init__.py | 0 {src/diffpy/srreal/tests => tests}/debug.py | 0 {src/diffpy/srreal/tests => tests}/run.py | 0 {src/diffpy/srreal/tests => tests}/testatomradiitable.py | 0 {src/diffpy/srreal/tests => tests}/testattributes.py | 0 {src/diffpy/srreal/tests => tests}/testbondcalculator.py | 0 {src/diffpy/srreal/tests => tests}/testbvscalculator.py | 0 {src/diffpy/srreal/tests => tests}/testdata/C60bucky.stru | 0 {src/diffpy/srreal/tests => tests}/testdata/CdSe_cadmoselite.cif | 0 .../diffpy/srreal/tests => tests}/testdata/CdSe_cadmoselite_N.fgr | 0 .../diffpy/srreal/tests => tests}/testdata/CdSe_cadmoselite_X.fgr | 0 {src/diffpy/srreal/tests => tests}/testdata/Ni-fit.fgr | 0 {src/diffpy/srreal/tests => tests}/testdata/Ni.cif | 0 {src/diffpy/srreal/tests => tests}/testdata/Ni.stru | 0 {src/diffpy/srreal/tests => tests}/testdata/Ni_primitive.stru | 0 {src/diffpy/srreal/tests => tests}/testdata/TiO2_rutile-fit.cif | 0 {src/diffpy/srreal/tests => tests}/testdata/TiO2_rutile-fit.fgr | 0 {src/diffpy/srreal/tests => tests}/testdata/TiO2_rutile-fit.stru | 0 {src/diffpy/srreal/tests => tests}/testdata/rutile.cif | 0 {src/diffpy/srreal/tests => tests}/testdata/silicon.cif | 0 {src/diffpy/srreal/tests => tests}/testdata/sphalerite.cif | 0 {src/diffpy/srreal/tests => tests}/testdebyepdfcalculator.py | 0 {src/diffpy/srreal/tests => tests}/testoverlapcalculator.py | 0 {src/diffpy/srreal/tests => tests}/testpairquantity.py | 0 {src/diffpy/srreal/tests => tests}/testparallel.py | 0 {src/diffpy/srreal/tests => tests}/testpdfbaseline.py | 0 {src/diffpy/srreal/tests => tests}/testpdfcalcobjcryst.py | 0 {src/diffpy/srreal/tests => tests}/testpdfcalculator.py | 0 {src/diffpy/srreal/tests => tests}/testpdfenvelope.py | 0 {src/diffpy/srreal/tests => tests}/testpeakprofile.py | 0 {src/diffpy/srreal/tests => tests}/testpeakwidthmodel.py | 0 {src/diffpy/srreal/tests => tests}/testscatteringfactortable.py | 0 {src/diffpy/srreal/tests => tests}/testsfaverage.py | 0 {src/diffpy/srreal/tests => tests}/teststructureadapter.py | 0 {src/diffpy/srreal/tests => tests}/testutils.py | 0 35 files changed, 0 insertions(+), 0 deletions(-) rename {src/diffpy/srreal/tests => tests}/__init__.py (100%) rename {src/diffpy/srreal/tests => tests}/debug.py (100%) rename {src/diffpy/srreal/tests => tests}/run.py (100%) rename {src/diffpy/srreal/tests => tests}/testatomradiitable.py (100%) rename {src/diffpy/srreal/tests => tests}/testattributes.py (100%) rename {src/diffpy/srreal/tests => tests}/testbondcalculator.py (100%) rename {src/diffpy/srreal/tests => tests}/testbvscalculator.py (100%) rename {src/diffpy/srreal/tests => tests}/testdata/C60bucky.stru (100%) rename {src/diffpy/srreal/tests => tests}/testdata/CdSe_cadmoselite.cif (100%) rename {src/diffpy/srreal/tests => tests}/testdata/CdSe_cadmoselite_N.fgr (100%) rename {src/diffpy/srreal/tests => tests}/testdata/CdSe_cadmoselite_X.fgr (100%) rename {src/diffpy/srreal/tests => tests}/testdata/Ni-fit.fgr (100%) rename {src/diffpy/srreal/tests => tests}/testdata/Ni.cif (100%) rename {src/diffpy/srreal/tests => tests}/testdata/Ni.stru (100%) rename {src/diffpy/srreal/tests => tests}/testdata/Ni_primitive.stru (100%) rename {src/diffpy/srreal/tests => tests}/testdata/TiO2_rutile-fit.cif (100%) rename {src/diffpy/srreal/tests => tests}/testdata/TiO2_rutile-fit.fgr (100%) rename {src/diffpy/srreal/tests => tests}/testdata/TiO2_rutile-fit.stru (100%) rename {src/diffpy/srreal/tests => tests}/testdata/rutile.cif (100%) rename {src/diffpy/srreal/tests => tests}/testdata/silicon.cif (100%) rename {src/diffpy/srreal/tests => tests}/testdata/sphalerite.cif (100%) rename {src/diffpy/srreal/tests => tests}/testdebyepdfcalculator.py (100%) rename {src/diffpy/srreal/tests => tests}/testoverlapcalculator.py (100%) rename {src/diffpy/srreal/tests => tests}/testpairquantity.py (100%) rename {src/diffpy/srreal/tests => tests}/testparallel.py (100%) rename {src/diffpy/srreal/tests => tests}/testpdfbaseline.py (100%) rename {src/diffpy/srreal/tests => tests}/testpdfcalcobjcryst.py (100%) rename {src/diffpy/srreal/tests => tests}/testpdfcalculator.py (100%) rename {src/diffpy/srreal/tests => tests}/testpdfenvelope.py (100%) rename {src/diffpy/srreal/tests => tests}/testpeakprofile.py (100%) rename {src/diffpy/srreal/tests => tests}/testpeakwidthmodel.py (100%) rename {src/diffpy/srreal/tests => tests}/testscatteringfactortable.py (100%) rename {src/diffpy/srreal/tests => tests}/testsfaverage.py (100%) rename {src/diffpy/srreal/tests => tests}/teststructureadapter.py (100%) rename {src/diffpy/srreal/tests => tests}/testutils.py (100%) diff --git a/src/diffpy/srreal/tests/__init__.py b/tests/__init__.py similarity index 100% rename from src/diffpy/srreal/tests/__init__.py rename to tests/__init__.py diff --git a/src/diffpy/srreal/tests/debug.py b/tests/debug.py similarity index 100% rename from src/diffpy/srreal/tests/debug.py rename to tests/debug.py diff --git a/src/diffpy/srreal/tests/run.py b/tests/run.py similarity index 100% rename from src/diffpy/srreal/tests/run.py rename to tests/run.py diff --git a/src/diffpy/srreal/tests/testatomradiitable.py b/tests/testatomradiitable.py similarity index 100% rename from src/diffpy/srreal/tests/testatomradiitable.py rename to tests/testatomradiitable.py diff --git a/src/diffpy/srreal/tests/testattributes.py b/tests/testattributes.py similarity index 100% rename from src/diffpy/srreal/tests/testattributes.py rename to tests/testattributes.py diff --git a/src/diffpy/srreal/tests/testbondcalculator.py b/tests/testbondcalculator.py similarity index 100% rename from src/diffpy/srreal/tests/testbondcalculator.py rename to tests/testbondcalculator.py diff --git a/src/diffpy/srreal/tests/testbvscalculator.py b/tests/testbvscalculator.py similarity index 100% rename from src/diffpy/srreal/tests/testbvscalculator.py rename to tests/testbvscalculator.py diff --git a/src/diffpy/srreal/tests/testdata/C60bucky.stru b/tests/testdata/C60bucky.stru similarity index 100% rename from src/diffpy/srreal/tests/testdata/C60bucky.stru rename to tests/testdata/C60bucky.stru diff --git a/src/diffpy/srreal/tests/testdata/CdSe_cadmoselite.cif b/tests/testdata/CdSe_cadmoselite.cif similarity index 100% rename from src/diffpy/srreal/tests/testdata/CdSe_cadmoselite.cif rename to tests/testdata/CdSe_cadmoselite.cif diff --git a/src/diffpy/srreal/tests/testdata/CdSe_cadmoselite_N.fgr b/tests/testdata/CdSe_cadmoselite_N.fgr similarity index 100% rename from src/diffpy/srreal/tests/testdata/CdSe_cadmoselite_N.fgr rename to tests/testdata/CdSe_cadmoselite_N.fgr diff --git a/src/diffpy/srreal/tests/testdata/CdSe_cadmoselite_X.fgr b/tests/testdata/CdSe_cadmoselite_X.fgr similarity index 100% rename from src/diffpy/srreal/tests/testdata/CdSe_cadmoselite_X.fgr rename to tests/testdata/CdSe_cadmoselite_X.fgr diff --git a/src/diffpy/srreal/tests/testdata/Ni-fit.fgr b/tests/testdata/Ni-fit.fgr similarity index 100% rename from src/diffpy/srreal/tests/testdata/Ni-fit.fgr rename to tests/testdata/Ni-fit.fgr diff --git a/src/diffpy/srreal/tests/testdata/Ni.cif b/tests/testdata/Ni.cif similarity index 100% rename from src/diffpy/srreal/tests/testdata/Ni.cif rename to tests/testdata/Ni.cif diff --git a/src/diffpy/srreal/tests/testdata/Ni.stru b/tests/testdata/Ni.stru similarity index 100% rename from src/diffpy/srreal/tests/testdata/Ni.stru rename to tests/testdata/Ni.stru diff --git a/src/diffpy/srreal/tests/testdata/Ni_primitive.stru b/tests/testdata/Ni_primitive.stru similarity index 100% rename from src/diffpy/srreal/tests/testdata/Ni_primitive.stru rename to tests/testdata/Ni_primitive.stru diff --git a/src/diffpy/srreal/tests/testdata/TiO2_rutile-fit.cif b/tests/testdata/TiO2_rutile-fit.cif similarity index 100% rename from src/diffpy/srreal/tests/testdata/TiO2_rutile-fit.cif rename to tests/testdata/TiO2_rutile-fit.cif diff --git a/src/diffpy/srreal/tests/testdata/TiO2_rutile-fit.fgr b/tests/testdata/TiO2_rutile-fit.fgr similarity index 100% rename from src/diffpy/srreal/tests/testdata/TiO2_rutile-fit.fgr rename to tests/testdata/TiO2_rutile-fit.fgr diff --git a/src/diffpy/srreal/tests/testdata/TiO2_rutile-fit.stru b/tests/testdata/TiO2_rutile-fit.stru similarity index 100% rename from src/diffpy/srreal/tests/testdata/TiO2_rutile-fit.stru rename to tests/testdata/TiO2_rutile-fit.stru diff --git a/src/diffpy/srreal/tests/testdata/rutile.cif b/tests/testdata/rutile.cif similarity index 100% rename from src/diffpy/srreal/tests/testdata/rutile.cif rename to tests/testdata/rutile.cif diff --git a/src/diffpy/srreal/tests/testdata/silicon.cif b/tests/testdata/silicon.cif similarity index 100% rename from src/diffpy/srreal/tests/testdata/silicon.cif rename to tests/testdata/silicon.cif diff --git a/src/diffpy/srreal/tests/testdata/sphalerite.cif b/tests/testdata/sphalerite.cif similarity index 100% rename from src/diffpy/srreal/tests/testdata/sphalerite.cif rename to tests/testdata/sphalerite.cif diff --git a/src/diffpy/srreal/tests/testdebyepdfcalculator.py b/tests/testdebyepdfcalculator.py similarity index 100% rename from src/diffpy/srreal/tests/testdebyepdfcalculator.py rename to tests/testdebyepdfcalculator.py diff --git a/src/diffpy/srreal/tests/testoverlapcalculator.py b/tests/testoverlapcalculator.py similarity index 100% rename from src/diffpy/srreal/tests/testoverlapcalculator.py rename to tests/testoverlapcalculator.py diff --git a/src/diffpy/srreal/tests/testpairquantity.py b/tests/testpairquantity.py similarity index 100% rename from src/diffpy/srreal/tests/testpairquantity.py rename to tests/testpairquantity.py diff --git a/src/diffpy/srreal/tests/testparallel.py b/tests/testparallel.py similarity index 100% rename from src/diffpy/srreal/tests/testparallel.py rename to tests/testparallel.py diff --git a/src/diffpy/srreal/tests/testpdfbaseline.py b/tests/testpdfbaseline.py similarity index 100% rename from src/diffpy/srreal/tests/testpdfbaseline.py rename to tests/testpdfbaseline.py diff --git a/src/diffpy/srreal/tests/testpdfcalcobjcryst.py b/tests/testpdfcalcobjcryst.py similarity index 100% rename from src/diffpy/srreal/tests/testpdfcalcobjcryst.py rename to tests/testpdfcalcobjcryst.py diff --git a/src/diffpy/srreal/tests/testpdfcalculator.py b/tests/testpdfcalculator.py similarity index 100% rename from src/diffpy/srreal/tests/testpdfcalculator.py rename to tests/testpdfcalculator.py diff --git a/src/diffpy/srreal/tests/testpdfenvelope.py b/tests/testpdfenvelope.py similarity index 100% rename from src/diffpy/srreal/tests/testpdfenvelope.py rename to tests/testpdfenvelope.py diff --git a/src/diffpy/srreal/tests/testpeakprofile.py b/tests/testpeakprofile.py similarity index 100% rename from src/diffpy/srreal/tests/testpeakprofile.py rename to tests/testpeakprofile.py diff --git a/src/diffpy/srreal/tests/testpeakwidthmodel.py b/tests/testpeakwidthmodel.py similarity index 100% rename from src/diffpy/srreal/tests/testpeakwidthmodel.py rename to tests/testpeakwidthmodel.py diff --git a/src/diffpy/srreal/tests/testscatteringfactortable.py b/tests/testscatteringfactortable.py similarity index 100% rename from src/diffpy/srreal/tests/testscatteringfactortable.py rename to tests/testscatteringfactortable.py diff --git a/src/diffpy/srreal/tests/testsfaverage.py b/tests/testsfaverage.py similarity index 100% rename from src/diffpy/srreal/tests/testsfaverage.py rename to tests/testsfaverage.py diff --git a/src/diffpy/srreal/tests/teststructureadapter.py b/tests/teststructureadapter.py similarity index 100% rename from src/diffpy/srreal/tests/teststructureadapter.py rename to tests/teststructureadapter.py diff --git a/src/diffpy/srreal/tests/testutils.py b/tests/testutils.py similarity index 100% rename from src/diffpy/srreal/tests/testutils.py rename to tests/testutils.py From abc8a9c988d91858e38829bd12941e21680e91e8 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Sat, 11 Jan 2025 00:10:24 -0500 Subject: [PATCH 08/55] remove unnecessary files, add conftest --- tests/__init__.py | 85 ------------------------------------------- tests/conftest.py | 19 ++++++++++ tests/debug.py | 33 ----------------- tests/run.py | 37 ------------------- tests/test_version.py | 10 +++++ 5 files changed, 29 insertions(+), 155 deletions(-) delete mode 100644 tests/__init__.py create mode 100644 tests/conftest.py delete mode 100644 tests/debug.py delete mode 100644 tests/run.py create mode 100644 tests/test_version.py diff --git a/tests/__init__.py b/tests/__init__.py deleted file mode 100644 index c4e942b5..00000000 --- a/tests/__init__.py +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env python -############################################################################## -# -# diffpy.srreal by DANSE Diffraction group -# Simon J. L. Billinge -# (c) 2012 The Trustees of Columbia University -# in the City of New York. All rights reserved. -# -# File coded by: Pavol Juhas -# -# See AUTHORS.txt for a list of people who contributed. -# See LICENSE_DANSE.txt for license information. -# -############################################################################## -"""Unit tests for diffpy.srreal.""" - -import logging -import unittest - -# create logger instance for the tests subpackage -logging.basicConfig() -logger = logging.getLogger(__name__) -del logging - - -def testsuite(pattern=""): - """Create a unit tests suite for diffpy.srreal package. - - Parameters - ---------- - pattern : str, optional - Regular expression pattern for selecting test cases. - Select all tests when empty. Ignore the pattern when - any of unit test modules fails to import. - - Returns - ------- - suite : `unittest.TestSuite` - The TestSuite object containing the matching tests. - """ - import re - from itertools import chain - from os.path import dirname - - from pkg_resources import resource_filename - - loader = unittest.defaultTestLoader - thisdir = resource_filename(__name__, "") - depth = __name__.count(".") + 1 - topdir = thisdir - for i in range(depth): - topdir = dirname(topdir) - suite_all = loader.discover(thisdir, top_level_dir=topdir) - # always filter the suite by pattern to test-cover the selection code. - suite = unittest.TestSuite() - rx = re.compile(pattern) - tsuites = list(chain.from_iterable(suite_all)) - tsok = all(isinstance(ts, unittest.TestSuite) for ts in tsuites) - if not tsok: # pragma: no cover - return suite_all - tcases = chain.from_iterable(tsuites) - for tc in tcases: - tcwords = tc.id().split(".") - shortname = ".".join(tcwords[-3:]) - if rx.search(shortname): - suite.addTest(tc) - # verify all tests are found for an empty pattern. - assert pattern or suite_all.countTestCases() == suite.countTestCases() - return suite - - -def test(): - """Execute all unit tests for the diffpy.srreal package. - - Returns - ------- - result : `unittest.TestResult` - """ - suite = testsuite() - runner = unittest.TextTestRunner() - result = runner.run(suite) - return result - - -# End of file diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 00000000..e3b63139 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,19 @@ +import json +from pathlib import Path + +import pytest + + +@pytest.fixture +def user_filesystem(tmp_path): + base_dir = Path(tmp_path) + home_dir = base_dir / "home_dir" + home_dir.mkdir(parents=True, exist_ok=True) + cwd_dir = base_dir / "cwd_dir" + cwd_dir.mkdir(parents=True, exist_ok=True) + + home_config_data = {"username": "home_username", "email": "home@email.com"} + with open(home_dir / "diffpyconfig.json", "w") as f: + json.dump(home_config_data, f) + + yield tmp_path diff --git a/tests/debug.py b/tests/debug.py deleted file mode 100644 index 47197f9c..00000000 --- a/tests/debug.py +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env python -############################################################################## -# -# diffpy.srreal Complex Modeling Initiative -# (c) 2016 Brookhaven Science Associates, -# Brookhaven National Laboratory. -# All rights reserved. -# -# File coded by: Pavol Juhas -# -# See AUTHORS.txt for a list of people who contributed. -# See LICENSE.txt for license information. -# -############################################################################## -"""Convenience module for debugging the unit tests using. - -python -m diffpy.srreal.tests.debug - -Exceptions raised by failed tests or other errors are not caught. -""" - - -if __name__ == "__main__": - import sys - - from diffpy.srreal.tests import testsuite - - pattern = sys.argv[1] if len(sys.argv) > 1 else "" - suite = testsuite(pattern) - suite.debug() - - -# End of file diff --git a/tests/run.py b/tests/run.py deleted file mode 100644 index 9d107059..00000000 --- a/tests/run.py +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env python -############################################################################## -# -# diffpy.srreal by DANSE Diffraction group -# Simon J. L. Billinge -# (c) 2010 The Trustees of Columbia University -# in the City of New York. All rights reserved. -# -# File coded by: Pavol Juhas -# -# See AUTHORS.txt for a list of people who contributed. -# See LICENSE_DANSE.txt for license information. -# -############################################################################## -"""Convenience module for executing all unit tests with. - -python -m diffpy.srreal.tests.run -""" - - -if __name__ == "__main__": - import sys - - # show warnings by default - if not sys.warnoptions: - import os - import warnings - - warnings.simplefilter("default") - # also affect subprocesses - os.environ["PYTHONWARNINGS"] = "default" - from diffpy.srreal.tests import test - - # produce zero exit code for a successful test - sys.exit(not test().wasSuccessful()) - -# End of file diff --git a/tests/test_version.py b/tests/test_version.py new file mode 100644 index 00000000..d50b30db --- /dev/null +++ b/tests/test_version.py @@ -0,0 +1,10 @@ +"""Unit tests for __version__.py.""" + +import diffpy.srreal + + +def test_package_version(): + """Ensure the package version is defined and not set to the initial + placeholder.""" + assert hasattr(diffpy.srreal, "__version__") + assert diffpy.srreal.__version__ != "0.0.0" From f01987ab40d920f060a4f76f1341899834b332cc Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Sat, 11 Jan 2025 00:14:52 -0500 Subject: [PATCH 09/55] easy tests --- tests/{testattributes.py => test_attributes.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/{testattributes.py => test_attributes.py} (100%) diff --git a/tests/testattributes.py b/tests/test_attributes.py similarity index 100% rename from tests/testattributes.py rename to tests/test_attributes.py From 70e88e4eb30232392242bb9ddcd83ac42dbf8ca1 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Sat, 11 Jan 2025 04:29:26 -0500 Subject: [PATCH 10/55] fix pytest --- tests/conftest.py | 56 +++++++++++++++++ ...omradiitable.py => test_atomradiitable.py} | 11 ++-- ...ndcalculator.py => test_bondcalculator.py} | 14 +++-- ...bvscalculator.py => test_bvscalculator.py} | 4 +- ...lculator.py => test_debyepdfcalculator.py} | 5 +- ...alculator.py => test_overlapcalculator.py} | 14 +++-- ...stpairquantity.py => test_pairquantity.py} | 4 +- tests/{testparallel.py => test_parallel.py} | 2 +- ...testpdfbaseline.py => test_pdfbaseline.py} | 2 +- ...alcobjcryst.py => test_pdfcalcobjcryst.py} | 11 ++-- ...pdfcalculator.py => test_pdfcalculator.py} | 13 +--- ...testpdfenvelope.py => test_pdfenvelope.py} | 2 +- ...testpeakprofile.py => test_peakprofile.py} | 2 +- ...akwidthmodel.py => test_peakwidthmodel.py} | 2 +- ...table.py => test_scatteringfactortable.py} | 2 +- tests/{testsfaverage.py => test_sfaverage.py} | 12 ++-- ...ureadapter.py => test_structureadapter.py} | 27 ++++---- tests/testutils.py | 63 +++++-------------- 18 files changed, 136 insertions(+), 110 deletions(-) rename tests/{testatomradiitable.py => test_atomradiitable.py} (96%) rename tests/{testbondcalculator.py => test_bondcalculator.py} (97%) rename tests/{testbvscalculator.py => test_bvscalculator.py} (97%) rename tests/{testdebyepdfcalculator.py => test_debyepdfcalculator.py} (97%) rename tests/{testoverlapcalculator.py => test_overlapcalculator.py} (98%) rename tests/{testpairquantity.py => test_pairquantity.py} (98%) rename tests/{testparallel.py => test_parallel.py} (98%) rename tests/{testpdfbaseline.py => test_pdfbaseline.py} (99%) rename tests/{testpdfcalcobjcryst.py => test_pdfcalcobjcryst.py} (92%) rename tests/{testpdfcalculator.py => test_pdfcalculator.py} (96%) rename tests/{testpdfenvelope.py => test_pdfenvelope.py} (99%) rename tests/{testpeakprofile.py => test_peakprofile.py} (98%) rename tests/{testpeakwidthmodel.py => test_peakwidthmodel.py} (99%) rename tests/{testscatteringfactortable.py => test_scatteringfactortable.py} (99%) rename tests/{testsfaverage.py => test_sfaverage.py} (94%) rename tests/{teststructureadapter.py => test_structureadapter.py} (97%) diff --git a/tests/conftest.py b/tests/conftest.py index e3b63139..81a85fc5 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,8 +1,12 @@ import json +import logging from pathlib import Path import pytest +from diffpy.srreal.structureconverters import convertObjCrystCrystal +import diffpy.structure as mod_structure + @pytest.fixture def user_filesystem(tmp_path): @@ -17,3 +21,55 @@ def user_filesystem(tmp_path): json.dump(home_config_data, f) yield tmp_path + + +# Resolve availability of optional packages. + +# pyobjcryst + + +@pytest.fixture(scope="session") +def _msg_nopyobjcryst(): + return "No module named 'pyobjcryst'" + + +@pytest.fixture(scope="session") +def has_pyobjcryst(): + try: + import pyobjcryst.crystal + convertObjCrystCrystal(pyobjcryst.crystal.Crystal()) + has_pyobjcryst = True + except ImportError: + has_pyobjcryst = False + logging.warning("Cannot import pyobjcryst, pyobjcryst tests skipped.") + print("Cannot import pyobjcryst, pyobjcryst tests skipped.") + except TypeError: + has_pyobjcryst = False + logging.warning("Compiled without ObjCryst, pyobjcryst tests skipped.") + print("Compiled without ObjCryst, pyobjcryst tests skipped.") + + return has_pyobjcryst + + +# periodictable + + +@pytest.fixture(scope="session") +def _msg_noperiodictable(): + return "No module named 'periodictable'" + + +@pytest.fixture(scope="session") +def has_periodictable(): + try: + import periodictable + + has_periodictable = True + + # silence the pyflakes syntax checker + del periodictable + except ImportError: + has_periodictable = False + logging.warning("Cannot import periodictable, periodictable tests skipped.") + + return has_periodictable diff --git a/tests/testatomradiitable.py b/tests/test_atomradiitable.py similarity index 96% rename from tests/testatomradiitable.py rename to tests/test_atomradiitable.py index f5c2265e..fc4ead69 100644 --- a/tests/testatomradiitable.py +++ b/tests/test_atomradiitable.py @@ -5,15 +5,13 @@ import pickle import unittest +import pytest from diffpy.srreal.atomradiitable import AtomRadiiTable, ConstantRadiiTable, CovalentRadiiTable -from diffpy.srreal.tests.testutils import _msg_noperiodictable, has_periodictable # ---------------------------------------------------------------------------- - class TestAtomRadiiTable(unittest.TestCase): - def setUp(self): self.rtb = AtomRadiiTable() self.ctb = ConstantRadiiTable() @@ -102,10 +100,13 @@ def test_toString(self): # ---------------------------------------------------------------------------- - -@unittest.skipUnless(has_periodictable, _msg_noperiodictable) class TestCovalentRadiiTable(unittest.TestCase): + @pytest.fixture(autouse=True) + def _check_periodictable(self, has_periodictable, _msg_noperiodictable): + if not has_periodictable: + pytest.skip(_msg_noperiodictable) + def setUp(self): self.rtb = CovalentRadiiTable() return diff --git a/tests/testbondcalculator.py b/tests/test_bondcalculator.py similarity index 97% rename from tests/testbondcalculator.py rename to tests/test_bondcalculator.py index cbbe6090..47fcc286 100644 --- a/tests/testbondcalculator.py +++ b/tests/test_bondcalculator.py @@ -5,13 +5,12 @@ import pickle import unittest +import pytest import numpy from diffpy.srreal.bondcalculator import BondCalculator -from diffpy.srreal.tests.testutils import ( - _msg_nopyobjcryst, - has_pyobjcryst, +from testutils import ( loadDiffPyStructure, loadObjCrystCrystal, pickle_with_attr, @@ -81,7 +80,7 @@ def test_pickling(self): def test_pickling_derived_structure(self): """Check pickling of BondCalculator with DerivedStructureAdapter.""" - from diffpy.srreal.tests.testutils import DerivedStructureAdapter + from testutils import DerivedStructureAdapter bdc = self.bdc stru0 = DerivedStructureAdapter() @@ -248,10 +247,13 @@ def test_setTypeMask(self): # ---------------------------------------------------------------------------- - -@unittest.skipUnless(has_pyobjcryst, _msg_nopyobjcryst) class TestBondCalculatorObjCryst(unittest.TestCase): + @pytest.fixture(autouse=True) + def _check_periodictable(self, has_pyobjcryst, _msg_nopyobjcryst): + if not has_pyobjcryst: + pytest.skip(_msg_nopyobjcryst) + def setUp(self): self.bdc = BondCalculator() if not hasattr(self, "rutile"): diff --git a/tests/testbvscalculator.py b/tests/test_bvscalculator.py similarity index 97% rename from tests/testbvscalculator.py rename to tests/test_bvscalculator.py index aceac210..3e936017 100644 --- a/tests/testbvscalculator.py +++ b/tests/test_bvscalculator.py @@ -7,7 +7,7 @@ import unittest from diffpy.srreal.bvscalculator import BVSCalculator -from diffpy.srreal.tests.testutils import loadDiffPyStructure, pickle_with_attr +from testutils import loadDiffPyStructure, pickle_with_attr ############################################################################## @@ -139,7 +139,7 @@ def test_table_pickling(self): def test_pickling_derived_structure(self): """Check pickling of BVSCalculator with DerivedStructureAdapter.""" - from diffpy.srreal.tests.testutils import DerivedStructureAdapter + from testutils import DerivedStructureAdapter bvc = self.bvc stru0 = DerivedStructureAdapter() diff --git a/tests/testdebyepdfcalculator.py b/tests/test_debyepdfcalculator.py similarity index 97% rename from tests/testdebyepdfcalculator.py rename to tests/test_debyepdfcalculator.py index fd8c07d4..65e04a0c 100644 --- a/tests/testdebyepdfcalculator.py +++ b/tests/test_debyepdfcalculator.py @@ -9,8 +9,7 @@ import numpy from diffpy.srreal.pdfcalculator import DebyePDFCalculator, PDFCalculator -from diffpy.srreal.tests.testpdfcalculator import _maxNormDiff -from diffpy.srreal.tests.testutils import loadDiffPyStructure, pickle_with_attr +from testutils import loadDiffPyStructure, pickle_with_attr, _maxNormDiff ############################################################################## @@ -189,7 +188,7 @@ def test_mask_pickling(self): def test_pickling_derived_structure(self): """Check pickling of DebyePDFCalculator with DerivedStructureAdapter.""" - from diffpy.srreal.tests.testutils import DerivedStructureAdapter + from testutils import DerivedStructureAdapter dpdfc = self.dpdfc stru0 = DerivedStructureAdapter() diff --git a/tests/testoverlapcalculator.py b/tests/test_overlapcalculator.py similarity index 98% rename from tests/testoverlapcalculator.py rename to tests/test_overlapcalculator.py index aabda0e6..6b410c9e 100644 --- a/tests/testoverlapcalculator.py +++ b/tests/test_overlapcalculator.py @@ -6,14 +6,13 @@ import copy import pickle import unittest +import pytest import numpy from diffpy.srreal.atomradiitable import CovalentRadiiTable from diffpy.srreal.overlapcalculator import OverlapCalculator -from diffpy.srreal.tests.testutils import ( - _msg_nopyobjcryst, - has_pyobjcryst, +from testutils import ( loadDiffPyStructure, loadObjCrystCrystal, pickle_with_attr, @@ -117,7 +116,7 @@ def test_pickling_artb(self): def test_pickling_derived_structure(self): """Check pickling of OverlapCalculator with DerivedStructureAdapter.""" - from diffpy.srreal.tests.testutils import DerivedStructureAdapter + from testutils import DerivedStructureAdapter olc = self.olc stru0 = DerivedStructureAdapter() @@ -331,10 +330,13 @@ def test_neighborhoods(self): # ---------------------------------------------------------------------------- - -@unittest.skipUnless(has_pyobjcryst, _msg_nopyobjcryst) class TestOverlapCalculatorObjCryst(unittest.TestCase): + @pytest.fixture(autouse=True) + def _check_periodictable(self, has_pyobjcryst, _msg_nopyobjcryst): + if not has_pyobjcryst: + pytest.skip(_msg_nopyobjcryst) + def setUp(self): self.olc = OverlapCalculator() if not hasattr(self, "rutile"): diff --git a/tests/testpairquantity.py b/tests/test_pairquantity.py similarity index 98% rename from tests/testpairquantity.py rename to tests/test_pairquantity.py index c07da95c..689883aa 100644 --- a/tests/testpairquantity.py +++ b/tests/test_pairquantity.py @@ -10,7 +10,7 @@ from diffpy.srreal.pairquantity import PairQuantity from diffpy.srreal.pdfcalculator import PDFCalculator from diffpy.srreal.srreal_ext import BasePairQuantity -from diffpy.srreal.tests.testutils import mod_structure +from testutils import mod_structure # ---------------------------------------------------------------------------- @@ -169,7 +169,7 @@ def eval_as(evtp, pq, stru): def test_pickling(self): """Check pickling and unpickling of PairQuantity.""" - from diffpy.srreal.tests.testutils import DerivedStructureAdapter + from testutils import DerivedStructureAdapter stru0 = DerivedStructureAdapter() self.pq.setStructure(stru0) diff --git a/tests/testparallel.py b/tests/test_parallel.py similarity index 98% rename from tests/testparallel.py rename to tests/test_parallel.py index e6ae9c12..050cd222 100644 --- a/tests/testparallel.py +++ b/tests/test_parallel.py @@ -9,7 +9,7 @@ import numpy from diffpy.srreal.parallel import createParallelCalculator -from diffpy.srreal.tests.testutils import loadDiffPyStructure +from testutils import loadDiffPyStructure ############################################################################## diff --git a/tests/testpdfbaseline.py b/tests/test_pdfbaseline.py similarity index 99% rename from tests/testpdfbaseline.py rename to tests/test_pdfbaseline.py index 152119e7..8e07d78f 100644 --- a/tests/testpdfbaseline.py +++ b/tests/test_pdfbaseline.py @@ -10,7 +10,7 @@ from diffpy.srreal.pdfbaseline import LinearBaseline, PDFBaseline, ZeroBaseline, makePDFBaseline from diffpy.srreal.pdfcalculator import PDFCalculator -from diffpy.srreal.tests.testutils import pickle_with_attr +from testutils import pickle_with_attr # ---------------------------------------------------------------------------- diff --git a/tests/testpdfcalcobjcryst.py b/tests/test_pdfcalcobjcryst.py similarity index 92% rename from tests/testpdfcalcobjcryst.py rename to tests/test_pdfcalcobjcryst.py index 01ef21b8..980a71f0 100644 --- a/tests/testpdfcalcobjcryst.py +++ b/tests/test_pdfcalcobjcryst.py @@ -5,12 +5,12 @@ import re import unittest +import pytest import numpy from diffpy.srreal.pdfcalculator import PDFCalculator -from diffpy.srreal.tests.testpdfcalculator import _maxNormDiff -from diffpy.srreal.tests.testutils import _msg_nopyobjcryst, datafile, has_pyobjcryst, loadObjCrystCrystal +from testutils import datafile, loadObjCrystCrystal, _maxNormDiff # helper functions @@ -58,10 +58,13 @@ def _makePDFCalculator(crst, cfgdict): # ---------------------------------------------------------------------------- - -@unittest.skipUnless(has_pyobjcryst, _msg_nopyobjcryst) class TestPDFCalcObjcryst(unittest.TestCase): + @pytest.fixture(autouse=True) + def _check_periodictable(self, has_pyobjcryst, _msg_nopyobjcryst): + if not has_pyobjcryst: + pytest.skip(_msg_nopyobjcryst) + def _comparePDFs(self, nickname, pdfbasename, cifbasename): def setself(**kwtoset): for n, v in kwtoset.items(): diff --git a/tests/testpdfcalculator.py b/tests/test_pdfcalculator.py similarity index 96% rename from tests/testpdfcalculator.py rename to tests/test_pdfcalculator.py index 5b790032..a27e84d9 100644 --- a/tests/testpdfcalculator.py +++ b/tests/test_pdfcalculator.py @@ -9,20 +9,11 @@ import numpy from diffpy.srreal.pdfcalculator import PDFCalculator, fftftog, fftgtof -from diffpy.srreal.tests.testutils import datafile, loadDiffPyStructure, pickle_with_attr +from testutils import datafile, loadDiffPyStructure, pickle_with_attr, _maxNormDiff # helper functions -def _maxNormDiff(yobs, ycalc): - """Returned maximum difference normalized by RMS of the yobs.""" - yobsa = numpy.array(yobs) - obsmax = numpy.max(numpy.fabs(yobsa)) or 1 - ynmdiff = (yobsa - ycalc) / obsmax - rv = max(numpy.fabs(ynmdiff)) - return rv - - # ---------------------------------------------------------------------------- @@ -274,7 +265,7 @@ def test_mask_pickling(self): def test_pickling_derived_structure(self): """Check pickling of PDFCalculator with DerivedStructureAdapter.""" - from diffpy.srreal.tests.testutils import DerivedStructureAdapter + from testutils import DerivedStructureAdapter pdfc = self.pdfcalc stru0 = DerivedStructureAdapter() diff --git a/tests/testpdfenvelope.py b/tests/test_pdfenvelope.py similarity index 99% rename from tests/testpdfenvelope.py rename to tests/test_pdfenvelope.py index cf840554..f6493f2b 100644 --- a/tests/testpdfenvelope.py +++ b/tests/test_pdfenvelope.py @@ -17,7 +17,7 @@ StepCutEnvelope, makePDFEnvelope, ) -from diffpy.srreal.tests.testutils import pickle_with_attr +from testutils import pickle_with_attr # ---------------------------------------------------------------------------- diff --git a/tests/testpeakprofile.py b/tests/test_peakprofile.py similarity index 98% rename from tests/testpeakprofile.py rename to tests/test_peakprofile.py index 56e3943e..8676afdb 100644 --- a/tests/testpeakprofile.py +++ b/tests/test_peakprofile.py @@ -10,7 +10,7 @@ from diffpy.srreal.pdfcalculator import PDFCalculator from diffpy.srreal.peakprofile import PeakProfile -from diffpy.srreal.tests.testutils import mod_structure, pickle_with_attr +from testutils import mod_structure, pickle_with_attr # ---------------------------------------------------------------------------- diff --git a/tests/testpeakwidthmodel.py b/tests/test_peakwidthmodel.py similarity index 99% rename from tests/testpeakwidthmodel.py rename to tests/test_peakwidthmodel.py index 0ba053f7..6b8e25a0 100644 --- a/tests/testpeakwidthmodel.py +++ b/tests/test_peakwidthmodel.py @@ -10,7 +10,7 @@ from diffpy.srreal.pdfcalculator import DebyePDFCalculator, PDFCalculator from diffpy.srreal.peakwidthmodel import DebyeWallerPeakWidth, JeongPeakWidth, PeakWidthModel from diffpy.srreal.structureadapter import createStructureAdapter -from diffpy.srreal.tests.testutils import loadDiffPyStructure +from testutils import loadDiffPyStructure # ---------------------------------------------------------------------------- diff --git a/tests/testscatteringfactortable.py b/tests/test_scatteringfactortable.py similarity index 99% rename from tests/testscatteringfactortable.py rename to tests/test_scatteringfactortable.py index e4c95be6..48d1efe0 100644 --- a/tests/testscatteringfactortable.py +++ b/tests/test_scatteringfactortable.py @@ -16,7 +16,7 @@ SFTNeutron, SFTXray, ) -from diffpy.srreal.tests.testutils import pickle_with_attr +from testutils import pickle_with_attr # ---------------------------------------------------------------------------- diff --git a/tests/testsfaverage.py b/tests/test_sfaverage.py similarity index 94% rename from tests/testsfaverage.py rename to tests/test_sfaverage.py index 6efaa981..78d39fd2 100644 --- a/tests/testsfaverage.py +++ b/tests/test_sfaverage.py @@ -4,14 +4,13 @@ import unittest +import pytest import numpy from diffpy.srreal.scatteringfactortable import ScatteringFactorTable from diffpy.srreal.sfaverage import SFAverage -from diffpy.srreal.tests.testutils import ( - _msg_nopyobjcryst, - has_pyobjcryst, +from testutils import ( loadDiffPyStructure, loadObjCrystCrystal, ) @@ -77,10 +76,13 @@ def test_fromComposition(self): # ---------------------------------------------------------------------------- - -@unittest.skipUnless(has_pyobjcryst, _msg_nopyobjcryst) class TestSFAverageObjCryst(unittest.TestCase): + @pytest.fixture(autouse=True) + def _check_periodictable(self, has_pyobjcryst, _msg_nopyobjcryst): + if not has_pyobjcryst: + pytest.skip(_msg_nopyobjcryst) + def setUp(self): self.sftx = ScatteringFactorTable.createByType("X") return diff --git a/tests/teststructureadapter.py b/tests/test_structureadapter.py similarity index 97% rename from tests/teststructureadapter.py rename to tests/test_structureadapter.py index 55a3604c..6cd69a36 100644 --- a/tests/teststructureadapter.py +++ b/tests/test_structureadapter.py @@ -5,10 +5,10 @@ import pickle import unittest +import pytest import numpy -import diffpy.srreal.tests.testutils as testutils from diffpy.srreal.pdfcalculator import PDFCalculator from diffpy.srreal.structureadapter import ( Atom, @@ -20,12 +20,14 @@ nometa, nosymmetry, ) -from diffpy.srreal.tests.testutils import ( - _msg_nopyobjcryst, - has_pyobjcryst, +from testutils import ( loadCrystalStructureAdapter, loadDiffPyStructure, loadObjCrystCrystal, + DerivedStructureAdapter, + DerivedAtomicStructureAdapter, + DerivedPeriodicStructureAdapter, + DerivedCrystalStructureAdapter ) # ---------------------------------------------------------------------------- @@ -110,7 +112,7 @@ def test_pickle_nonwrapped(self): class TestDerivedAdapter(unittest.TestCase): "Check functionality in a Python-derived StructureAdapter class." - DerivedCls = testutils.DerivedStructureAdapter + DerivedCls = DerivedStructureAdapter def setUp(self): self.adpt = self.DerivedCls() @@ -145,15 +147,15 @@ def test_pickling(self): class TestDerivedAtomicAdapter(TestDerivedAdapter): - DerivedCls = testutils.DerivedAtomicStructureAdapter + DerivedCls = DerivedAtomicStructureAdapter class TestDerivedPeriodicAdapter(TestDerivedAdapter): - DerivedCls = testutils.DerivedPeriodicStructureAdapter + DerivedCls = DerivedPeriodicStructureAdapter class TestDerivedCrystalAdapter(TestDerivedAdapter): - DerivedCls = testutils.DerivedCrystalStructureAdapter + DerivedCls = DerivedCrystalStructureAdapter # ---------------------------------------------------------------------------- @@ -267,10 +269,13 @@ def test_nosymmetry_pickling(self): # ---------------------------------------------------------------------------- - -@unittest.skipUnless(has_pyobjcryst, _msg_nopyobjcryst) class TestPyObjCrystAdapter(unittest.TestCase): + @pytest.fixture(autouse=True) + def _check_periodictable(self, has_pyobjcryst, _msg_nopyobjcryst): + if not has_pyobjcryst: + pytest.skip(_msg_nopyobjcryst) + def setUp(self): rutile_crystal = loadObjCrystCrystal("TiO2_rutile-fit.cif") self.rutile = createStructureAdapter(rutile_crystal) @@ -408,7 +413,7 @@ def test_getEquivalentAtoms(self): class TestDerivedStructureAdapter(IndexRangeTests, TestCase): - AdptClass = testutils.DerivedStructureAdapter + AdptClass = DerivedStructureAdapter def setUp(self): IndexRangeTests.setUp(self) diff --git a/tests/testutils.py b/tests/testutils.py index 8cbb3ecc..d68dd99c 100644 --- a/tests/testutils.py +++ b/tests/testutils.py @@ -14,61 +14,18 @@ PeriodicStructureAdapter, StructureAdapter, ) -from diffpy.srreal.structureconverters import convertObjCrystCrystal -from diffpy.srreal.tests import logger - -# Deprecated in 1.3 - import of old camel-case diffpy.Structure names. -# TODO drop this in version 1.4. - -try: - import diffpy.structure as mod_structure - from diffpy.structure.parsers import getParser -except ImportError as e: - try: - import diffpy.Structure as mod_structure - from diffpy.Structure.Parsers import getParser - except ImportError: - raise e - del e - -# Resolve availability of optional packages. - -# pyobjcryst - -_msg_nopyobjcryst = "No module named 'pyobjcryst'" -try: - import pyobjcryst.crystal - - convertObjCrystCrystal(pyobjcryst.crystal.Crystal()) - has_pyobjcryst = True -except ImportError: - has_pyobjcryst = False - logger.warning("Cannot import pyobjcryst, pyobjcryst tests skipped.") -except TypeError: - has_pyobjcryst = False - logger.warning("Compiled without ObjCryst, pyobjcryst tests skipped.") - -# periodictable - -_msg_noperiodictable = "No module named 'periodictable'" -try: - import periodictable - - has_periodictable = True - # silence the pyflakes syntax checker - del periodictable -except ImportError: - has_periodictable = False - logger.warning("Cannot import periodictable, periodictable tests skipped.") +import diffpy.structure as mod_structure +from diffpy.structure.parsers import getParser + # helper functions def datafile(filename): - from pkg_resources import resource_filename + from pathlib import Path - rv = resource_filename(__name__, "testdata/" + filename) - return rv + rv = Path(__file__).parent / "testdata" / filename + return str(rv) def loadObjCrystCrystal(filename): @@ -108,6 +65,14 @@ def pickle_with_attr(obj, **attr): return rv +def _maxNormDiff(yobs, ycalc): + """Returned maximum difference normalized by RMS of the yobs.""" + yobsa = numpy.array(yobs) + obsmax = numpy.max(numpy.fabs(yobsa)) or 1 + ynmdiff = (yobsa - ycalc) / obsmax + rv = max(numpy.fabs(ynmdiff)) + return rv + # helper class for testing overloading of StructureAdapter From d0a96e83a87c7dabc0081db72879a216c8789646 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Sat, 11 Jan 2025 04:33:53 -0500 Subject: [PATCH 11/55] help py3.11 find boost --- setup.py | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index ea931a64..6c322f3e 100644 --- a/setup.py +++ b/setup.py @@ -7,8 +7,10 @@ """ import glob +import os import sys from ctypes.util import find_library +from pathlib import Path import numpy from setuptools import Extension, setup @@ -26,11 +28,33 @@ def get_boost_libraries(): raise RuntimeError("Cannot find a suitable Boost.Python library.") +def get_boost_config(): + boost_path = os.environ.get("BOOST_PATH", "") + if boost_path: + inc = Path(boost_path) / "include" + lib = Path(boost_path) / "lib" + else: + conda_prefix = os.environ.get("CONDA_PREFIX") + if not conda_prefix: + raise EnvironmentError( + "Neither BOOST_PATH nor CONDA_PREFIX are set. " "Please install Boost or set BOOST_PATH." + ) + if os.name == "nt": + inc = Path(conda_prefix) / "Library" / "include" + lib = Path(conda_prefix) / "Library" / "lib" + else: + inc = Path(conda_prefix) / "include" + lib = Path(conda_prefix) / "lib" + return {"include_dirs": [str(inc)], "library_dirs": [str(lib)]} + + +boost_cfg = get_boost_config() ext_kws = { "libraries": ["diffpy"] + get_boost_libraries(), "extra_compile_args": ["-std=c++11"], "extra_link_args": [], - "include_dirs": [numpy.get_include()], + "include_dirs": [numpy.get_include()] + boost_cfg["include_dirs"], + "library_dirs": boost_cfg["library_dirs"], } From 881517437700d2669f72c8927a159527c4349848 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Sat, 11 Jan 2025 04:41:24 -0500 Subject: [PATCH 12/55] add dependencies --- requirements/build.txt | 1 + requirements/conda.txt | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/requirements/build.txt b/requirements/build.txt index b050e013..dde224fc 100644 --- a/requirements/build.txt +++ b/requirements/build.txt @@ -1,3 +1,4 @@ python boost numpy +# libobjcryst (if libdiffpy built with objcryst) diff --git a/requirements/conda.txt b/requirements/conda.txt index a2ce8f05..f4e764df 100644 --- a/requirements/conda.txt +++ b/requirements/conda.txt @@ -3,4 +3,6 @@ numpy libdiffpy setuptools diffpy.structure -periodictable +gsl +# periodictable +# pyobjcryst (up to py3.11 for mac) From 95f2ef125df7a69395299aa23aaafa436628a872 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Sat, 11 Jan 2025 04:56:49 -0500 Subject: [PATCH 13/55] update CI --- .github/workflows/tests-on-pr.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests-on-pr.yml b/.github/workflows/tests-on-pr.yml index f9b4d90b..dfdbc776 100644 --- a/.github/workflows/tests-on-pr.yml +++ b/.github/workflows/tests-on-pr.yml @@ -36,8 +36,8 @@ jobs: - name: Install diffpy.srreal and requirements run: | conda install --file requirements/test.txt - conda install --file requirements/conda.txt + conda install boost numpy libdiffpy setuptools diffpy.structure periodictable gsl python -m pip install . --no-deps - name: Validate diffpy.pdfgui - run: python -m diffpy.srreal.tests.run + run: pytest tests From 59f94716f04be33b01b6a6e97a681b255e6a99cd Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 11 Jan 2025 09:58:02 +0000 Subject: [PATCH 14/55] [pre-commit.ci] auto fixes from pre-commit hooks --- tests/conftest.py | 3 ++- tests/test_atomradiitable.py | 3 +++ tests/test_bondcalculator.py | 9 +++------ tests/test_bvscalculator.py | 3 ++- tests/test_debyepdfcalculator.py | 2 +- tests/test_overlapcalculator.py | 9 +++------ tests/test_pairquantity.py | 2 +- tests/test_parallel.py | 2 +- tests/test_pdfbaseline.py | 2 +- tests/test_pdfcalcobjcryst.py | 5 +++-- tests/test_pdfcalculator.py | 2 +- tests/test_pdfenvelope.py | 2 +- tests/test_peakprofile.py | 2 +- tests/test_peakwidthmodel.py | 3 ++- tests/test_scatteringfactortable.py | 2 +- tests/test_sfaverage.py | 8 +++----- tests/test_structureadapter.py | 21 +++++++++++---------- tests/testutils.py | 4 ++-- 18 files changed, 42 insertions(+), 42 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 81a85fc5..273cc36f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -4,8 +4,8 @@ import pytest -from diffpy.srreal.structureconverters import convertObjCrystCrystal import diffpy.structure as mod_structure +from diffpy.srreal.structureconverters import convertObjCrystCrystal @pytest.fixture @@ -37,6 +37,7 @@ def _msg_nopyobjcryst(): def has_pyobjcryst(): try: import pyobjcryst.crystal + convertObjCrystCrystal(pyobjcryst.crystal.Crystal()) has_pyobjcryst = True except ImportError: diff --git a/tests/test_atomradiitable.py b/tests/test_atomradiitable.py index fc4ead69..158a6f4d 100644 --- a/tests/test_atomradiitable.py +++ b/tests/test_atomradiitable.py @@ -5,12 +5,14 @@ import pickle import unittest + import pytest from diffpy.srreal.atomradiitable import AtomRadiiTable, ConstantRadiiTable, CovalentRadiiTable # ---------------------------------------------------------------------------- + class TestAtomRadiiTable(unittest.TestCase): def setUp(self): self.rtb = AtomRadiiTable() @@ -100,6 +102,7 @@ def test_toString(self): # ---------------------------------------------------------------------------- + class TestCovalentRadiiTable(unittest.TestCase): @pytest.fixture(autouse=True) diff --git a/tests/test_bondcalculator.py b/tests/test_bondcalculator.py index 47fcc286..cd69fe55 100644 --- a/tests/test_bondcalculator.py +++ b/tests/test_bondcalculator.py @@ -5,16 +5,12 @@ import pickle import unittest -import pytest import numpy +import pytest +from testutils import loadDiffPyStructure, loadObjCrystCrystal, pickle_with_attr from diffpy.srreal.bondcalculator import BondCalculator -from testutils import ( - loadDiffPyStructure, - loadObjCrystCrystal, - pickle_with_attr, -) # ---------------------------------------------------------------------------- @@ -247,6 +243,7 @@ def test_setTypeMask(self): # ---------------------------------------------------------------------------- + class TestBondCalculatorObjCryst(unittest.TestCase): @pytest.fixture(autouse=True) diff --git a/tests/test_bvscalculator.py b/tests/test_bvscalculator.py index 3e936017..c2f3838a 100644 --- a/tests/test_bvscalculator.py +++ b/tests/test_bvscalculator.py @@ -6,9 +6,10 @@ import pickle import unittest -from diffpy.srreal.bvscalculator import BVSCalculator from testutils import loadDiffPyStructure, pickle_with_attr +from diffpy.srreal.bvscalculator import BVSCalculator + ############################################################################## class TestBVSCalculator(unittest.TestCase): diff --git a/tests/test_debyepdfcalculator.py b/tests/test_debyepdfcalculator.py index 65e04a0c..693a7ab5 100644 --- a/tests/test_debyepdfcalculator.py +++ b/tests/test_debyepdfcalculator.py @@ -7,9 +7,9 @@ import unittest import numpy +from testutils import _maxNormDiff, loadDiffPyStructure, pickle_with_attr from diffpy.srreal.pdfcalculator import DebyePDFCalculator, PDFCalculator -from testutils import loadDiffPyStructure, pickle_with_attr, _maxNormDiff ############################################################################## diff --git a/tests/test_overlapcalculator.py b/tests/test_overlapcalculator.py index 6b410c9e..5a7a2040 100644 --- a/tests/test_overlapcalculator.py +++ b/tests/test_overlapcalculator.py @@ -6,17 +6,13 @@ import copy import pickle import unittest -import pytest import numpy +import pytest +from testutils import loadDiffPyStructure, loadObjCrystCrystal, pickle_with_attr from diffpy.srreal.atomradiitable import CovalentRadiiTable from diffpy.srreal.overlapcalculator import OverlapCalculator -from testutils import ( - loadDiffPyStructure, - loadObjCrystCrystal, - pickle_with_attr, -) # ---------------------------------------------------------------------------- @@ -330,6 +326,7 @@ def test_neighborhoods(self): # ---------------------------------------------------------------------------- + class TestOverlapCalculatorObjCryst(unittest.TestCase): @pytest.fixture(autouse=True) diff --git a/tests/test_pairquantity.py b/tests/test_pairquantity.py index 689883aa..01e3bd94 100644 --- a/tests/test_pairquantity.py +++ b/tests/test_pairquantity.py @@ -6,11 +6,11 @@ import unittest import numpy +from testutils import mod_structure from diffpy.srreal.pairquantity import PairQuantity from diffpy.srreal.pdfcalculator import PDFCalculator from diffpy.srreal.srreal_ext import BasePairQuantity -from testutils import mod_structure # ---------------------------------------------------------------------------- diff --git a/tests/test_parallel.py b/tests/test_parallel.py index 050cd222..3bc524c6 100644 --- a/tests/test_parallel.py +++ b/tests/test_parallel.py @@ -7,9 +7,9 @@ import unittest import numpy +from testutils import loadDiffPyStructure from diffpy.srreal.parallel import createParallelCalculator -from testutils import loadDiffPyStructure ############################################################################## diff --git a/tests/test_pdfbaseline.py b/tests/test_pdfbaseline.py index 8e07d78f..20535ce5 100644 --- a/tests/test_pdfbaseline.py +++ b/tests/test_pdfbaseline.py @@ -7,10 +7,10 @@ import unittest import numpy +from testutils import pickle_with_attr from diffpy.srreal.pdfbaseline import LinearBaseline, PDFBaseline, ZeroBaseline, makePDFBaseline from diffpy.srreal.pdfcalculator import PDFCalculator -from testutils import pickle_with_attr # ---------------------------------------------------------------------------- diff --git a/tests/test_pdfcalcobjcryst.py b/tests/test_pdfcalcobjcryst.py index 980a71f0..3fd4d4ca 100644 --- a/tests/test_pdfcalcobjcryst.py +++ b/tests/test_pdfcalcobjcryst.py @@ -5,12 +5,12 @@ import re import unittest -import pytest import numpy +import pytest +from testutils import _maxNormDiff, datafile, loadObjCrystCrystal from diffpy.srreal.pdfcalculator import PDFCalculator -from testutils import datafile, loadObjCrystCrystal, _maxNormDiff # helper functions @@ -58,6 +58,7 @@ def _makePDFCalculator(crst, cfgdict): # ---------------------------------------------------------------------------- + class TestPDFCalcObjcryst(unittest.TestCase): @pytest.fixture(autouse=True) diff --git a/tests/test_pdfcalculator.py b/tests/test_pdfcalculator.py index a27e84d9..ef45a6ba 100644 --- a/tests/test_pdfcalculator.py +++ b/tests/test_pdfcalculator.py @@ -7,9 +7,9 @@ import unittest import numpy +from testutils import _maxNormDiff, datafile, loadDiffPyStructure, pickle_with_attr from diffpy.srreal.pdfcalculator import PDFCalculator, fftftog, fftgtof -from testutils import datafile, loadDiffPyStructure, pickle_with_attr, _maxNormDiff # helper functions diff --git a/tests/test_pdfenvelope.py b/tests/test_pdfenvelope.py index f6493f2b..7ea75f4c 100644 --- a/tests/test_pdfenvelope.py +++ b/tests/test_pdfenvelope.py @@ -7,6 +7,7 @@ import unittest import numpy +from testutils import pickle_with_attr from diffpy.srreal.pdfcalculator import DebyePDFCalculator, PDFCalculator from diffpy.srreal.pdfenvelope import ( @@ -17,7 +18,6 @@ StepCutEnvelope, makePDFEnvelope, ) -from testutils import pickle_with_attr # ---------------------------------------------------------------------------- diff --git a/tests/test_peakprofile.py b/tests/test_peakprofile.py index 8676afdb..9b739c19 100644 --- a/tests/test_peakprofile.py +++ b/tests/test_peakprofile.py @@ -7,10 +7,10 @@ import unittest import numpy +from testutils import mod_structure, pickle_with_attr from diffpy.srreal.pdfcalculator import PDFCalculator from diffpy.srreal.peakprofile import PeakProfile -from testutils import mod_structure, pickle_with_attr # ---------------------------------------------------------------------------- diff --git a/tests/test_peakwidthmodel.py b/tests/test_peakwidthmodel.py index 6b8e25a0..6c83cd15 100644 --- a/tests/test_peakwidthmodel.py +++ b/tests/test_peakwidthmodel.py @@ -7,10 +7,11 @@ import pickle import unittest +from testutils import loadDiffPyStructure + from diffpy.srreal.pdfcalculator import DebyePDFCalculator, PDFCalculator from diffpy.srreal.peakwidthmodel import DebyeWallerPeakWidth, JeongPeakWidth, PeakWidthModel from diffpy.srreal.structureadapter import createStructureAdapter -from testutils import loadDiffPyStructure # ---------------------------------------------------------------------------- diff --git a/tests/test_scatteringfactortable.py b/tests/test_scatteringfactortable.py index 48d1efe0..3d327ae8 100644 --- a/tests/test_scatteringfactortable.py +++ b/tests/test_scatteringfactortable.py @@ -7,6 +7,7 @@ import unittest import numpy +from testutils import pickle_with_attr from diffpy.srreal.pdfcalculator import DebyePDFCalculator, PDFCalculator from diffpy.srreal.scatteringfactortable import ( @@ -16,7 +17,6 @@ SFTNeutron, SFTXray, ) -from testutils import pickle_with_attr # ---------------------------------------------------------------------------- diff --git a/tests/test_sfaverage.py b/tests/test_sfaverage.py index 78d39fd2..87dd9a15 100644 --- a/tests/test_sfaverage.py +++ b/tests/test_sfaverage.py @@ -4,16 +4,13 @@ import unittest -import pytest import numpy +import pytest +from testutils import loadDiffPyStructure, loadObjCrystCrystal from diffpy.srreal.scatteringfactortable import ScatteringFactorTable from diffpy.srreal.sfaverage import SFAverage -from testutils import ( - loadDiffPyStructure, - loadObjCrystCrystal, -) # ---------------------------------------------------------------------------- @@ -76,6 +73,7 @@ def test_fromComposition(self): # ---------------------------------------------------------------------------- + class TestSFAverageObjCryst(unittest.TestCase): @pytest.fixture(autouse=True) diff --git a/tests/test_structureadapter.py b/tests/test_structureadapter.py index 6cd69a36..697c355c 100644 --- a/tests/test_structureadapter.py +++ b/tests/test_structureadapter.py @@ -5,9 +5,18 @@ import pickle import unittest -import pytest import numpy +import pytest +from testutils import ( + DerivedAtomicStructureAdapter, + DerivedCrystalStructureAdapter, + DerivedPeriodicStructureAdapter, + DerivedStructureAdapter, + loadCrystalStructureAdapter, + loadDiffPyStructure, + loadObjCrystCrystal, +) from diffpy.srreal.pdfcalculator import PDFCalculator from diffpy.srreal.structureadapter import ( @@ -20,15 +29,6 @@ nometa, nosymmetry, ) -from testutils import ( - loadCrystalStructureAdapter, - loadDiffPyStructure, - loadObjCrystCrystal, - DerivedStructureAdapter, - DerivedAtomicStructureAdapter, - DerivedPeriodicStructureAdapter, - DerivedCrystalStructureAdapter -) # ---------------------------------------------------------------------------- @@ -269,6 +269,7 @@ def test_nosymmetry_pickling(self): # ---------------------------------------------------------------------------- + class TestPyObjCrystAdapter(unittest.TestCase): @pytest.fixture(autouse=True) diff --git a/tests/testutils.py b/tests/testutils.py index d68dd99c..5f594af7 100644 --- a/tests/testutils.py +++ b/tests/testutils.py @@ -8,16 +8,15 @@ import numpy +import diffpy.structure as mod_structure from diffpy.srreal.structureadapter import ( AtomicStructureAdapter, CrystalStructureAdapter, PeriodicStructureAdapter, StructureAdapter, ) -import diffpy.structure as mod_structure from diffpy.structure.parsers import getParser - # helper functions @@ -73,6 +72,7 @@ def _maxNormDiff(yobs, ycalc): rv = max(numpy.fabs(ynmdiff)) return rv + # helper class for testing overloading of StructureAdapter From 0ce4864698f77bb77fa563e33c48dcfaa4bb5464 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Sat, 11 Jan 2025 05:00:17 -0500 Subject: [PATCH 15/55] pcmt --- tests/conftest.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index 273cc36f..ac3c2227 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -4,7 +4,6 @@ import pytest -import diffpy.structure as mod_structure from diffpy.srreal.structureconverters import convertObjCrystCrystal From 81b3c03dfd444953de01714dd6b5518f34dd82c4 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Sat, 11 Jan 2025 05:07:47 -0500 Subject: [PATCH 16/55] git, codecov, cfgs, news dir, MANIFEST --- .codecov.yml | 16 +++++- .codespell/ignore_words.txt | 9 ---- .coveragerc | 22 --------- .gitarchive.cfg | 5 -- .gitattributes | 7 --- .gitignore | 98 ++++++++++++++++++++++++++----------- MANIFEST.in | 25 ++++------ environment.yml | 2 +- news/TEMPLATE.rst | 23 +++++++++ 9 files changed, 117 insertions(+), 90 deletions(-) delete mode 100644 .coveragerc delete mode 100644 .gitarchive.cfg delete mode 100644 .gitattributes create mode 100644 news/TEMPLATE.rst diff --git a/.codecov.yml b/.codecov.yml index 86671410..4af5eb24 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -1,2 +1,14 @@ -fixes: - - ".*/site-packages/::src/" +coverage: + status: + project: # more options at https://docs.codecov.com/docs/commit-status + default: + target: auto # use the coverage from the base commit, fail if coverage is lower + threshold: 0% # allow the coverage to drop by + +comment: + layout: " diff, flags, files" + behavior: default + require_changes: false + require_base: false # [true :: must have a base report to post] + require_head: false # [true :: must have a head report to post] + hide_project_coverage: false # [true :: only show coverage on the git diff aka patch coverage] diff --git a/.codespell/ignore_words.txt b/.codespell/ignore_words.txt index 3b490070..63971de7 100644 --- a/.codespell/ignore_words.txt +++ b/.codespell/ignore_words.txt @@ -10,15 +10,6 @@ socio-economic ;; Frobenius norm used in np.linalg.norm fro -;; abbreviation for "structure" -struc - -;; method name within JournalPanel class -onText - -;; a method name within JournalPanel class -delt - ;; structure file format discus diff --git a/.coveragerc b/.coveragerc deleted file mode 100644 index d0a0d16d..00000000 --- a/.coveragerc +++ /dev/null @@ -1,22 +0,0 @@ -# Configuration of the coverage.py tool for reporting test coverage. - -[report] -# RE patterns for lines to be excluded from consideration. -exclude_lines = - ## Have to re-enable the standard pragma - pragma: no cover - ## Don't complain if tests don't hit defensive assertion code: - raise AssertionError - raise NotImplementedError - ^[ ]*assert False - - ## Don't complain if non-runnable code isn't run: - ^[ ]*@unittest.skip\b - ^[ ]{4}unittest.main() - if __name__ == .__main__.: - - -[run] -omit = - ## exclude debug.py from codecov report - */tests/debug.py diff --git a/.gitarchive.cfg b/.gitarchive.cfg deleted file mode 100644 index 95e1448c..00000000 --- a/.gitarchive.cfg +++ /dev/null @@ -1,5 +0,0 @@ -[DEFAULT] -commit = $Format:%H$ -date = $Format:%ci$ -timestamp = $Format:%ct$ -refnames = $Format:%D$ diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 2c3906b0..00000000 --- a/.gitattributes +++ /dev/null @@ -1,7 +0,0 @@ -/.gitattributes export-ignore -/.gitignore export-ignore -/.travis.yml export-ignore -/conda-recipe/ export-ignore -/devutils export-ignore -/doc export-ignore -.gitarchive.cfg export-subst diff --git a/.gitignore b/.gitignore index 120238d6..d418364a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,52 +1,92 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ *.py[cod] +*$py.class # C extensions *.so -# Packages -*.egg -*.egg-info -dist -build -eggs -parts -bin -var -sdist -temp -develop-eggs +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +venv/ +*.egg-info/ .installed.cfg -lib -lib64 -tags +*.egg +bin/ +temp/ +tags/ errors.err +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + # Installer logs pip-log.txt +pip-delete-this-directory.txt MANIFEST # Unit test / coverage reports +htmlcov/ +.tox/ .coverage -.tox +.coverage.* +.cache nosetests.xml +coverage.xml +*,cover +.hypothesis/ # Translations *.mo +*.pot # Mr Developer .mr.developer.cfg .project .pydevproject -.settings - -# SCons build files -.gdb_history -.sconf_temp/ -.sconsign.dblite -config.log -/sconscript.local -/sconsvars.py - -# version information -setup.cfg -/src/diffpy/*/version.cfg + +# Django stuff: +*.log + +# Sphinx documentation +docs/build/ +docs/source/generated/ + +# pytest +.pytest_cache/ + +# PyBuilder +target/ + +# Editor files +# mac +.DS_Store +*~ + +# vim +*.swp +*.swo + +# pycharm +.idea/ + +# VSCode +.vscode/ + +# Ipython Notebook +.ipynb_checkpoints diff --git a/MANIFEST.in b/MANIFEST.in index f27ccfbe..f1a78eec 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,17 +1,12 @@ -recursive-include src * -include SConstruct -include AUTHORS.txt LICENSE*.txt README.rst -recursive-exclude src *.pyc *.so -global-exclude .gitattributes .gitignore .gitarchive.cfg -global-exclude .DS_Store +graft src +graft tests +graft requirements -# Avoid user content in setup.cfg to make distribution reproducible. -exclude setup.cfg +include AUTHORS.rst LICENSE*.rst README.rst -# Exclude git-tracked files spuriously added by setuptools_scm -exclude .coveragerc -exclude .travis* -prune conda-recipe -prune devutils -prune doc -prune examples +# Exclude all bytecode files and __pycache__ directories +global-exclude *.py[cod] # Exclude all .pyc, .pyo, and .pyd files. +global-exclude .DS_Store # Exclude Mac filesystem artifacts. +global-exclude __pycache__ # Exclude Python cache directories. +global-exclude .git* # Exclude git files and directories. +global-exclude .idea # Exclude PyCharm project settings. diff --git a/environment.yml b/environment.yml index a3904941..680bfd94 100644 --- a/environment.yml +++ b/environment.yml @@ -1,4 +1,4 @@ -name: diffpy.pdfgui +name: diffpy.srreal channels: - conda-forge dependencies: diff --git a/news/TEMPLATE.rst b/news/TEMPLATE.rst new file mode 100644 index 00000000..790d30b1 --- /dev/null +++ b/news/TEMPLATE.rst @@ -0,0 +1,23 @@ +**Added:** + +* + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* From 4a8000a43ef20f24c54867d4177838dc4a2aa87f Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Sat, 11 Jan 2025 05:08:46 -0500 Subject: [PATCH 17/55] AUTHORS, CHANGELOG, COC, LICENSEs, README --- AUTHORS.rst | 12 ++ AUTHORS.txt | 9 -- CHANGELOG.md | 41 ------ CHANGELOG.rst | 47 +++++++ CODE_OF_CONDUCT.rst | 133 ++++++++++++++++++ LICENSE.rst | 142 +++++++++++++++++++ LICENSE.txt | 137 ------------------ LICENSE_DANSE.txt => LICENSE_DANSE.rst | 18 ++- README.rst | 186 ++++++++++++------------- 9 files changed, 434 insertions(+), 291 deletions(-) create mode 100644 AUTHORS.rst delete mode 100644 AUTHORS.txt delete mode 100644 CHANGELOG.md create mode 100644 CHANGELOG.rst create mode 100644 CODE_OF_CONDUCT.rst create mode 100644 LICENSE.rst delete mode 100644 LICENSE.txt rename LICENSE_DANSE.txt => LICENSE_DANSE.rst (78%) diff --git a/AUTHORS.rst b/AUTHORS.rst new file mode 100644 index 00000000..84a4bac1 --- /dev/null +++ b/AUTHORS.rst @@ -0,0 +1,12 @@ +Authors +======= + +Pavol Juhas, +Chris Farrow, +Simon J.L. Billinge + +Contributors +------------ + +For a list of contributors, visit +https://github.com/diffpy/diffpy.srreal/graphs/contributors diff --git a/AUTHORS.txt b/AUTHORS.txt deleted file mode 100644 index 00374f30..00000000 --- a/AUTHORS.txt +++ /dev/null @@ -1,9 +0,0 @@ -Authors: - -Pavol Juhas -Chris Farrow -Simon J.L. Billinge - -Contributors: - -https://github.com/diffpy/diffpy.srreal/graphs/contributors diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 8c521cc6..00000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,41 +0,0 @@ -# Release notes - -## Version 1.3.0 – 2019-03-13 - -Main differences from version 1.2. - -### Added - -- Support for Python 3.7, 3.6, 3.5 in addition to 2.7. -- Validation of compiler options from `python-config`. -- Make scons scripts compatible with Python 3 and Python 2. -- `ConstantPeakWidth` attributes `uisowidth`, `bisowidth` to ease - PDF simulation with uniform isotropic atom displacements. - -### Changed - -- Require libdiffpy 1.4 or later. -- Build Anaconda package with Anaconda C++ compiler. -- Allow language standard c++11. -- Pickle format for `PDFCalculator`, `DebyePDFCalculator`, - `OverlapCalculator`, `PeakWidthModel`, `PeakProfile`, `PDFEnvelope`, - `PDFBaseline`, and `ScatteringFactorTable` objects. - -### Deprecated - -- Variable `__gitsha__` in the `version` module renamed to `__git_commit__`. -- `libdiffpy_version_info` attribute `git_sha` renamed to `git_commit`. - -### Removed - -- Unused method `BVParam.__hash__`. -- Disable pickling of `BasePairQuantity` as it is in effect abstract. -- Pickling of Python-added attributes to exported C++ classes. -- Function `get_libdiffpy_version_info` from the `version` module. - -### Fixed - -- Return value conversion of `CrystalStructureAdapter` methods - `expandLatticeAtom` and `getEquivalentAtoms` methods. - Make them return a `list` of `Atom` objects. -- Name suffix resolution of `boost_python` shared library. diff --git a/CHANGELOG.rst b/CHANGELOG.rst new file mode 100644 index 00000000..6f96d258 --- /dev/null +++ b/CHANGELOG.rst @@ -0,0 +1,47 @@ +============= +Release Notes +============= + +.. current developments + + +Version 1.3.0 2019-03-13 +========================= + +Main differences from version 1.2. + +**Added:** + +* Support for Python 3.7, 3.6, 3.5 in addition to 2.7. +* Validation of compiler options from `python-config`. +* Make scons scripts compatible with Python 3 and Python 2. +* `ConstantPeakWidth` attributes `uisowidth`, `bisowidth` to ease + PDF simulation with uniform isotropic atom displacements. + +**Changed:** + +* Require libdiffpy 1.4 or later. +* Build Anaconda package with Anaconda C++ compiler. +* Allow language standard c++11. +* Pickle format for `PDFCalculator`, `DebyePDFCalculator`, + `OverlapCalculator`, `PeakWidthModel`, `PeakProfile`, `PDFEnvelope`, + `PDFBaseline`, and `ScatteringFactorTable` objects. + +**Deprecated:** + +* Variable `__gitsha__` in the `version` module renamed to `__git_commit__`. +* `libdiffpy_version_info` attribute `git_sha` renamed to `git_commit`. + +**Removed** + +* Unused method `BVParam.__hash__`. +* Disable pickling of `BasePairQuantity` as it is in effect abstract. +* Pickling of Python-added attributes to exported C++ classes. +* Function `get_libdiffpy_version_info` from the `version` module. + +**Fixed** + +* Return value conversion of `CrystalStructureAdapter` methods + `expandLatticeAtom` and `getEquivalentAtoms` methods. + Make them return a `list` of `Atom` objects. +* Name suffix resolution of `boost_python` shared library. diff --git a/CODE_OF_CONDUCT.rst b/CODE_OF_CONDUCT.rst new file mode 100644 index 00000000..ff9c3561 --- /dev/null +++ b/CODE_OF_CONDUCT.rst @@ -0,0 +1,133 @@ +===================================== + Contributor Covenant Code of Conduct +===================================== + +Our Pledge +---------- + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual +identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +Our Standards +------------- + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the overall + community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or advances of + any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email address, + without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +Enforcement Responsibilities +---------------------------- + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +Scope +----- + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official email address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +Enforcement +----------- + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +sb2896@columbia.edu. All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +Enforcement Guidelines +---------------------- + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +1. Correction +**************** + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +2. Warning +************* + +**Community Impact**: A violation through a single incident or series of +actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +3. Temporary Ban +****************** + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +4. Permanent Ban +****************** + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the +community. + +Attribution +----------- + +This Code of Conduct is adapted from the `Contributor Covenant `_. + +Community Impact Guidelines were inspired by `Mozilla's code of conduct enforcement ladder `_. + +For answers to common questions about this code of conduct, see the `FAQ `_. `Translations are available `_ diff --git a/LICENSE.rst b/LICENSE.rst new file mode 100644 index 00000000..c983d73f --- /dev/null +++ b/LICENSE.rst @@ -0,0 +1,142 @@ +OPEN SOURCE LICENSE AGREEMENT +============================= + +Copyright (c) 2009-2011, University of Tennessee + +Copyright (c) 1989, 1991 Free Software Foundation, Inc. + +Copyright (c) 2006, The Regents of the University of California through Lawrence Berkeley National Laboratory + +Copyright (c) 2014, Australian Synchrotron Research Program Inc., ("ASRP") + +Copyright (c) 2006-2007, Board of Trustees of Michigan State University + +Copyright (c) 2008-2012, The Trustees of Columbia University in the City of New York + +Copyright (c) 2014-2019, Brookhaven Science Associates, Brookhaven National Laboratory + +Copyright (c) 2024, The Trustees of Columbia University in the City of New York. +All rights reserved. + +The "DiffPy-CMI" is distributed subject to the following license conditions: + +.. code-block:: text + + SOFTWARE LICENSE AGREEMENT + + Software: DiffPy-CMI + + + (1) The "Software", below, refers to the aforementioned DiffPy-CMI (in either + source code, or binary form and accompanying documentation). + + Part of the software was derived from the DANSE, ObjCryst++ (with permission), + PyCifRW, Python periodictable, CCTBX, and SasView open source projects, of + which the original Copyrights are contained in each individual file. + + Each licensee is addressed as "you" or "Licensee." + + + (2) The copyright holders shown above and their third-party Licensors hereby + grant licensee a royalty-free nonexclusive license, subject to the limitations + stated herein and U.S. Government license rights. + + + (3) You may modify and make a copy or copies of the software for use within + your organization, if you meet the following conditions: + + (a) Copies in source code must include the copyright notice and this + software license agreement. + + (b) Copies in binary form must include the copyright notice and this + Software License Agreement in the documentation and/or other materials + provided with the copy. + + + (4) You may modify a copy or copies of the Software or any portion of it, thus + forming a work based on the Software, and distribute copies of such work + outside your organization, if you meet all of the following conditions: + + (a) Copies in source code must include the copyright notice and this + Software License Agreement; + + (b) Copies in binary form must include the copyright notice and this + Software License Agreement in the documentation and/or other materials + provided with the copy; + + (c) Modified copies and works based on the Software must carry prominent + notices stating that you changed specified portions of the Software. + + (d) Neither the name of Brookhaven Science Associates or Brookhaven + National Laboratory nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + written permission. + + + (5) Portions of the Software resulted from work developed under a U.S. + Government contract and are subject to the following license: + The Government is granted for itself and others acting on its behalf a + paid-up, nonexclusive, irrevocable worldwide license in this computer software + to reproduce, prepare derivative works, and perform publicly and display + publicly. + + + (6) WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" WITHOUT + WARRANTY OF ANY KIND. THE COPYRIGHT HOLDERS, THEIR THIRD PARTY + LICENSORS, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND + THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + PARTICULAR PURPOSE, TITLE OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL + LIABILITY OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR USEFULNESS OF + THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF THE SOFTWARE WOULD NOT INFRINGE + PRIVATELY OWNED RIGHTS, (4) DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION + UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL BE CORRECTED. + + + (7) LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT HOLDERS, THEIR + THIRD PARTY LICENSORS, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF + ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, INCIDENTAL, + CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF ANY KIND OR NATURE, INCLUDING + BUT NOT LIMITED TO LOSS OF PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, + WHETHER SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT (INCLUDING + NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, EVEN IF ANY OF SAID PARTIES HAS + BEEN WARNED OF THE POSSIBILITY OF SUCH LOSS OR DAMAGES. + + +Brookhaven National Laboratory Notice +===================================== + +Acknowledgment of sponsorship +----------------------------- + +This software was produced by the Brookhaven National Laboratory, under +Contract DE-AC02-98CH10886 with the Department of Energy. + + +Government disclaimer of liability +---------------------------------- + +Neither the United States nor the United States Department of Energy, nor +any of their employees, makes any warranty, express or implied, or assumes +any legal liability or responsibility for the accuracy, completeness, or +usefulness of any data, apparatus, product, or process disclosed, or +represents that its use would not infringe privately owned rights. + + +Brookhaven disclaimer of liability +---------------------------------- + +Brookhaven National Laboratory makes no representations or warranties, +express or implied, nor assumes any liability for the use of this software. + + +Maintenance of notice +--------------------- + +In the interest of clarity regarding the origin and status of this +software, Brookhaven National Laboratory requests that any recipient of it +maintain this notice affixed to any distribution by the recipient that +contains a copy or derivative of this software. + + +END OF LICENSE diff --git a/LICENSE.txt b/LICENSE.txt deleted file mode 100644 index f6d92af7..00000000 --- a/LICENSE.txt +++ /dev/null @@ -1,137 +0,0 @@ -OPEN SOURCE LICENSE AGREEMENT -============================= - -Copyright (c) 2009-2011, University of Tennessee -Copyright (c) 1989, 1991 Free Software Foundation, Inc. -Copyright (c) 2006, The Regents of the University of California through - Lawrence Berkeley National Laboratory -Copyright (c) 2014, Australian Synchrotron Research Program Inc., ("ASRP") -Copyright (c) 2006-2007, Board of Trustees of Michigan State University -Copyright (c) 2008-2012, The Trustees of Columbia University in the City - of New York - -Copyright (c) 2014-2019, Brookhaven Science Associates, Brookhaven National - Laboratory - - -The "DiffPy-CMI" is distributed subject to the following license conditions: - - -SOFTWARE LICENSE AGREEMENT - - Software: DiffPy-CMI - - -(1) The "Software", below, refers to the aforementioned DiffPy-CMI (in either -source code, or binary form and accompanying documentation). - -Part of the software was derived from the DANSE, ObjCryst++ (with permission), -PyCifRW, Python periodictable, CCTBX, and SasView open source projects, of -which the original Copyrights are contained in each individual file. - -Each licensee is addressed as "you" or "Licensee." - - -(2) The copyright holders shown above and their third-party Licensors hereby -grant licensee a royalty-free nonexclusive license, subject to the limitations -stated herein and U.S. Government license rights. - - -(3) You may modify and make a copy or copies of the software for use within -your organization, if you meet the following conditions: - - (a) Copies in source code must include the copyright notice and this - software license agreement. - - (b) Copies in binary form must include the copyright notice and this - Software License Agreement in the documentation and/or other materials - provided with the copy. - - -(4) You may modify a copy or copies of the Software or any portion of it, thus -forming a work based on the Software, and distribute copies of such work -outside your organization, if you meet all of the following conditions: - - (a) Copies in source code must include the copyright notice and this - Software License Agreement; - - (b) Copies in binary form must include the copyright notice and this - Software License Agreement in the documentation and/or other materials - provided with the copy; - - (c) Modified copies and works based on the Software must carry prominent - notices stating that you changed specified portions of the Software. - - (d) Neither the name of Brookhaven Science Associates or Brookhaven - National Laboratory nor the names of its contributors may be used to - endorse or promote products derived from this software without specific - written permission. - - -(5) Portions of the Software resulted from work developed under a U.S. -Government contract and are subject to the following license: -The Government is granted for itself and others acting on its behalf a -paid-up, nonexclusive, irrevocable worldwide license in this computer software -to reproduce, prepare derivative works, and perform publicly and display -publicly. - - -(6) WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" WITHOUT -WARRANTY OF ANY KIND. THE COPYRIGHT HOLDERS, THEIR THIRD PARTY -LICENSORS, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND -THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR IMPLIED, INCLUDING -BUT NOT LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE, TITLE OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL -LIABILITY OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR USEFULNESS OF -THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF THE SOFTWARE WOULD NOT INFRINGE -PRIVATELY OWNED RIGHTS, (4) DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION -UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL BE CORRECTED. - - -(7) LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT HOLDERS, THEIR -THIRD PARTY LICENSORS, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF -ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, INCIDENTAL, -CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF ANY KIND OR NATURE, INCLUDING -BUT NOT LIMITED TO LOSS OF PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, -WHETHER SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT (INCLUDING -NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, EVEN IF ANY OF SAID PARTIES HAS -BEEN WARNED OF THE POSSIBILITY OF SUCH LOSS OR DAMAGES. - - -Brookhaven National Laboratory Notice -===================================== - -Acknowledgment of sponsorship ------------------------------ - -This software was produced by the Brookhaven National Laboratory, under -Contract DE-AC02-98CH10886 with the Department of Energy. - - -Government disclaimer of liability ----------------------------------- - -Neither the United States nor the United States Department of Energy, nor -any of their employees, makes any warranty, express or implied, or assumes -any legal liability or responsibility for the accuracy, completeness, or -usefulness of any data, apparatus, product, or process disclosed, or -represents that its use would not infringe privately owned rights. - - -Brookhaven disclaimer of liability ----------------------------------- - -Brookhaven National Laboratory makes no representations or warranties, -express or implied, nor assumes any liability for the use of this software. - - -Maintenance of notice ---------------------- - -In the interest of clarity regarding the origin and status of this -software, Brookhaven National Laboratory requests that any recipient of it -maintain this notice affixed to any distribution by the recipient that -contains a copy or derivative of this software. - - -END OF LICENSE diff --git a/LICENSE_DANSE.txt b/LICENSE_DANSE.rst similarity index 78% rename from LICENSE_DANSE.txt rename to LICENSE_DANSE.rst index f5f9f3ea..1c0ab5db 100644 --- a/LICENSE_DANSE.txt +++ b/LICENSE_DANSE.rst @@ -1,24 +1,32 @@ +LICENSE +======= + This program is part of the DiffPy and DANSE open-source projects and is available subject to the conditions and terms laid out below. -Copyright (c) 2008-2012, The Trustees of Columbia University in -the City of New York. All rights reserved. +Copyright (c) 2008-2012, The Trustees of Columbia University in the City of New York. +All rights reserved. + +Copyright (c) 2024, The Trustees of Columbia University in the City of New York. +All rights reserved. For more information please visit the project web-page at + http://www.diffpy.org + or email Prof. Simon Billinge at sb2896@columbia.edu. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright +- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright +- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of the copyright holder nor the names of its +- Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. diff --git a/README.rst b/README.rst index f6388b27..a6d2ff81 100644 --- a/README.rst +++ b/README.rst @@ -1,13 +1,41 @@ -.. image:: https://travis-ci.org/diffpy/diffpy.srreal.svg?branch=master - :target: https://travis-ci.org/diffpy/diffpy.srreal +|Icon| |title|_ +=============== -.. image:: https://codecov.io/gh/diffpy/diffpy.srreal/branch/master/graph/badge.svg - :target: https://codecov.io/gh/diffpy/diffpy.srreal +.. |title| replace:: diffpy.srreal +.. _title: https://diffpy.github.io/diffpy.srreal -diffpy.srreal -======================================================================== +.. |Icon| image:: https://avatars.githubusercontent.com/diffpy + :target: https://diffpy.github.io/diffpy.srreal + :height: 100px -Calculators for PDF, bond valence sum and other pair quantities +|PyPi| |Forge| |PythonVersion| |PR| + +|CI| |Codecov| |Black| |Tracking| + +.. |Black| image:: https://img.shields.io/badge/code_style-black-black + :target: https://github.com/psf/black + +.. |CI| image:: https://github.com/diffpy/diffpy.srreal/actions/workflows/matrix-and-codecov-on-merge-to-main.yml/badge.svg + :target: https://github.com/diffpy/diffpy.srreal/actions/workflows/matrix-and-codecov-on-merge-to-main.yml + +.. |Codecov| image:: https://codecov.io/gh/diffpy/diffpy.srreal/branch/main/graph/badge.svg + :target: https://codecov.io/gh/diffpy/diffpy.srreal + +.. |Forge| image:: https://img.shields.io/conda/vn/conda-forge/diffpy.srreal + :target: https://anaconda.org/conda-forge/diffpy.srreal + +.. |PR| image:: https://img.shields.io/badge/PR-Welcome-29ab47ff + +.. |PyPi| image:: https://img.shields.io/pypi/v/diffpy.srreal + :target: https://pypi.org/project/diffpy.srreal/ + +.. |PythonVersion| image:: https://img.shields.io/pypi/pyversions/diffpy.srreal + :target: https://pypi.org/project/diffpy.srreal/ + +.. |Tracking| image:: https://img.shields.io/badge/issue_tracking-github-blue + :target: https://github.com/diffpy/diffpy.srreal/issues + +Calculators for PDF, bond valence sum, and other quantities based on atom pair interaction. The diffpy.srreal package provides calculators for atomic pair distribution function (PDF), bond valence sums (BVS), atom overlaps for a hard-sphere @@ -39,126 +67,86 @@ calculate PDF with a user-defined profile function. A new calculator class can be also defined for any quantity that is obtained by iteration over atom pairs, by defining only the function that processes atom-pair contributions. -For more information about the diffpy.srreal library, see users manual at -http://diffpy.github.io/diffpy.srreal. - - -REQUIREMENTS ------------------------------------------------------------------------- - -The diffpy.srreal package requires Python 3.7, 3.6, 3.5 or 2.7, -C++ compiler and the following software: - -* ``setuptools`` - tools for installing Python packages -* ``NumPy`` - library for scientific computing with Python -* ``python-dev`` - header files for interfacing Python with C -* ``libboost-all-dev`` - Boost C++ libraries and development files -* ``libdiffpy`` - C++ library for PDF, bond valence sum and other pair - quantity calculators https://github.com/diffpy/libdiffpy -* ``diffpy.structure`` - simple storage and manipulation of atomic structures - https://github.com/diffpy/diffpy.structure -* ``scons`` - software construction tool (optional) - -Optional software: - -* ``periodictable`` - periodic table of elements in Python - http://www.reflectometry.org/danse/elements.html -* ``pyobjcryst`` - Python bindings to ObjCryst++, the Object Oriented - Crystallographic library for C++, https://github.com/diffpy/pyobjcryst. +For more information about the diffpy.srreal library, please consult our `online documentation `_. -We recommend to use `Anaconda Python `_ -as it allows to install all software dependencies together with -diffpy.srreal. For other Python distributions it is necessary to -install the required software separately. As an example, on Ubuntu -Linux some of the required software can be installed using :: +Citation +-------- - sudo apt-get install \ - python-setuptools python-numpy scons \ - build-essential python-dev libboost-all-dev +If you use diffpy.srreal in a scientific publication, we would like you to cite this package as -To install the remaining packages see the installation instructions -at their respective web pages. + diffpy.srreal Package, https://github.com/diffpy/diffpy.srreal +Installation +------------ -INSTALLATION ------------------------------------------------------------------------- +The preferred method is to use `Miniconda Python +`_ +and install from the "conda-forge" channel of Conda packages. -The preferred method is to use Anaconda Python and install from the -"diffpy" channel of Anaconda packages :: +To add "conda-forge" to the conda channels, run the following in a terminal. :: - conda config --add channels diffpy - conda install diffpy.srreal + conda config --add channels conda-forge -diffpy.srreal is also included in the "diffpy-cmi" collection -of packages for structure analysis :: +We want to install our packages in a suitable conda environment. +The following creates and activates a new environment named ``diffpy.srreal_env`` :: - conda install diffpy-cmi + conda create -n diffpy.srreal_env diffpy.srreal + conda activate diffpy.srreal_env -If you prefer to install from sources, make sure all required software -packages are in place and then run :: +To confirm that the installation was successful, type :: - python setup.py install + python -c "import diffpy.srreal; print(diffpy.srreal.__version__)" -You may need to use ``sudo`` with system Python so the process is -allowed to copy files to the system directories. If administrator (root) -access is not available, see the output from -``python setup.py install --help`` for options to install to -a user-writable location. The installation integrity can be -verified by executing the included tests with :: +The output should print the latest version displayed on the badges above. - python -m diffpy.srreal.tests.run +If the above does not work, you can use ``pip`` to download and install the latest release from +`Python Package Index `_. +To install using ``pip`` into your ``diffpy.srreal_env`` environment, type :: -An alternative way of installing diffpy.srreal is to use the SCons tool, -which can speed up the process by compiling C++ files in several -parallel jobs (-j4) :: + pip install diffpy.srreal - sudo scons -j4 install +If you prefer to install from sources, after installing the dependencies, obtain the source archive from +`GitHub `_. Once installed, ``cd`` into your ``diffpy.srreal`` directory +and run the following :: -See ``scons -h`` for description of build targets and options. + pip install . +Getting Started +--------------- -DEVELOPMENT ------------------------------------------------------------------------- +You may consult our `online documentation `_ for tutorials and API references. -diffpy.srreal is an open-source software developed as a part of the -DiffPy-CMI complex modeling initiative at the Brookhaven National -Laboratory. The diffpy.srreal sources are hosted at -https://github.com/diffpy/diffpy.srreal. +Support and Contribute +---------------------- -Feel free to fork the project and contribute. To install diffpy.srreal -in a development mode, where the sources are directly used by Python -rather than copied to a system directory, use :: +`Diffpy user group `_ is the discussion forum for general questions and discussions about the use of diffpy.srreal. Please join the diffpy.srreal users community by joining the Google group. The diffpy.srreal project welcomes your expertise and enthusiasm! - python setup.py develop --user +If you see a bug or want to request a feature, please `report it as an issue `_ and/or `submit a fix as a PR `_. You can also post it to the `Diffpy user group `_. -To rebuild the C++ extension module and then optionally test the code -integrity, use :: +Feel free to fork the project and contribute. To install diffpy.srreal +in a development mode, with its sources being directly used by Python +rather than copied to a package directory, use the following in the root +directory :: - scons -j4 build=debug develop [test] + pip install -e . -When developing with Anaconda Python it is essential to specify -header path, library path and runtime library path for the active -Anaconda environment. This can be achieved by setting the ``CPATH``, -``LIBRARY_PATH`` and ``LDFLAGS`` environment variables as follows:: +To ensure code quality and to prevent accidental commits into the default branch, please set up the use of our pre-commit +hooks. - # resolve the prefix directory P of the active Anaconda environment - P="$(conda info --json | grep default_prefix | cut -d\" -f4)" - export CPATH=$P/include - export LIBRARY_PATH=$P/lib - export LDFLAGS=-Wl,-rpath,$P/lib - # compile and re-install diffpy.srreal - scons -j4 build=debug develop +1. Install pre-commit in your working environment by running ``conda install pre-commit``. -Note the Anaconda package for the required libdiffpy library is built -with a C++ compiler provided by Anaconda. This may cause incompatibility -with system C++. In such case use Anaconda C++ to build diffpy.srreal. +2. Initialize pre-commit (one time only) ``pre-commit install``. +Thereafter your code will be linted by black and isort and checked against flake8 before you can commit. +If it fails by black or isort, just rerun and it should pass (black and isort will modify the files so should +pass after they are modified). If the flake8 test fails please see the error messages and fix them manually before +trying to commit again. -CONTACTS ------------------------------------------------------------------------- +Improvements and fixes are always appreciated. -For more information on diffpy.srreal please visit the project web-page +Before contributing, please read our `Code of Conduct `_. -http://www.diffpy.org +Contact +------- -or email Prof. Simon Billinge at sb2896@columbia.edu. +For more information on diffpy.srreal please visit the project `web-page `_ or email Prof. Simon Billinge at sb2896@columbia.edu. From 74ccfe19c97ce0445c1a9384f1649cae1f576393 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Sat, 11 Jan 2025 05:10:39 -0500 Subject: [PATCH 18/55] gh workflows, conda-recipe, devutils --- .../workflows/build-wheel-release-upload.yml | 18 ++++ .github/workflows/check-news-item.yml | 12 +++ .../matrix-and-codecov-on-merge-to-main.yml | 21 +++++ .github/workflows/publish-docs-on-release.yml | 12 +++ conda-recipe/build.sh | 9 -- conda-recipe/conda_build_config.yaml | 17 ---- conda-recipe/meta.yaml | 83 ------------------- conda-recipe/run_test.py | 5 -- conda-recipe/sconscript.local | 18 ---- devutils/makesdist | 59 ------------- .../srreal/devutils}/tunePeakPrecision.py | 0 11 files changed, 63 insertions(+), 191 deletions(-) create mode 100644 .github/workflows/build-wheel-release-upload.yml create mode 100644 .github/workflows/check-news-item.yml create mode 100644 .github/workflows/matrix-and-codecov-on-merge-to-main.yml create mode 100644 .github/workflows/publish-docs-on-release.yml delete mode 100644 conda-recipe/build.sh delete mode 100644 conda-recipe/conda_build_config.yaml delete mode 100644 conda-recipe/meta.yaml delete mode 100644 conda-recipe/run_test.py delete mode 100644 conda-recipe/sconscript.local delete mode 100755 devutils/makesdist rename {devutils => src/diffpy/srreal/devutils}/tunePeakPrecision.py (100%) diff --git a/.github/workflows/build-wheel-release-upload.yml b/.github/workflows/build-wheel-release-upload.yml new file mode 100644 index 00000000..f6486717 --- /dev/null +++ b/.github/workflows/build-wheel-release-upload.yml @@ -0,0 +1,18 @@ +name: Release (GitHub/PyPI) and Deploy Docs + +on: + workflow_dispatch: + push: + tags: + - '*' # Trigger on all tags initially, but tag and release privilege are verified in _build-wheel-release-upload.yml + +jobs: + release: + uses: Billingegroup/release-scripts/.github/workflows/_build-wheel-release-upload.yml@v0 + with: + project: diffpy.srreal + c_extension: true + github_admin_username: sbillinge + secrets: + PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} + PAT_TOKEN: ${{ secrets.PAT_TOKEN }} diff --git a/.github/workflows/check-news-item.yml b/.github/workflows/check-news-item.yml new file mode 100644 index 00000000..3f68c3b4 --- /dev/null +++ b/.github/workflows/check-news-item.yml @@ -0,0 +1,12 @@ +name: Check for News + +on: + pull_request_target: + branches: + - main + +jobs: + check-news-item: + uses: Billingegroup/release-scripts/.github/workflows/_check-news-item.yml@v0 + with: + project: diffpy.srreal diff --git a/.github/workflows/matrix-and-codecov-on-merge-to-main.yml b/.github/workflows/matrix-and-codecov-on-merge-to-main.yml new file mode 100644 index 00000000..ea2983bd --- /dev/null +++ b/.github/workflows/matrix-and-codecov-on-merge-to-main.yml @@ -0,0 +1,21 @@ +name: CI + +on: + push: + branches: + - main + release: + types: + - prereleased + - published + workflow_dispatch: + +jobs: + matrix-coverage: + uses: Billingegroup/release-scripts/.github/workflows/_matrix-and-codecov-on-merge-to-main.yml@v0 + with: + project: diffpy.srreal + c_extension: true + headless: false + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/publish-docs-on-release.yml b/.github/workflows/publish-docs-on-release.yml new file mode 100644 index 00000000..8daf1623 --- /dev/null +++ b/.github/workflows/publish-docs-on-release.yml @@ -0,0 +1,12 @@ +name: Deploy Documentation on Release + +on: + workflow_dispatch: + +jobs: + docs: + uses: Billingegroup/release-scripts/.github/workflows/_publish-docs-on-release.yml@v0 + with: + project: diffpy.srreal + c_extension: true + headless: false diff --git a/conda-recipe/build.sh b/conda-recipe/build.sh deleted file mode 100644 index 16f60848..00000000 --- a/conda-recipe/build.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -MYNCPU=$(( (CPU_COUNT > 4) ? 4 : CPU_COUNT )) - -# Apply sconscript.local customizations. -cp ${RECIPE_DIR}/sconscript.local ./ - -# Install srreal with scons to utilize multiple CPUs. -scons -j $MYNCPU install prefix=$PREFIX diff --git a/conda-recipe/conda_build_config.yaml b/conda-recipe/conda_build_config.yaml deleted file mode 100644 index 4c9fb940..00000000 --- a/conda-recipe/conda_build_config.yaml +++ /dev/null @@ -1,17 +0,0 @@ -python: - - 3.7 - - 3.6 - - 3.5 - - 2.7 - -numpy: - - 1.11 - -libdiffpy: - - 1.4.* - -boost: - - 1.67 - -pin_run_as_build: - boost: x.x diff --git a/conda-recipe/meta.yaml b/conda-recipe/meta.yaml deleted file mode 100644 index b3d23d70..00000000 --- a/conda-recipe/meta.yaml +++ /dev/null @@ -1,83 +0,0 @@ -{% set setupdata = load_setup_py_data() %} - -package: - name: diffpy.srreal - version: {{ setupdata['version'] }} - -source: - # git_url: https://github.com/diffpy/diffpy.srreal - git_url: .. - -build: - preserve_egg_dir: True # [py2k] - - # If this is a new build for the same version, increment the build - # number. If you do not include this key, it defaults to 0. - # number: 0 - -requirements: - build: - - {{ compiler('cxx') }} - host: - - python {{ python }} - - setuptools - - scons - - numpy {{ numpy }} - - libdiffpy {{ libdiffpy }} - - boost {{ boost }} - - run: - # NOTE libdiffpy is added implicitly from libdiffpy run_exports - - python - - setuptools - - {{ pin_compatible('numpy', min_pin='x.x', max_pin='x') }} - - boost - - diffpy.structure - - pyobjcryst 2.1.* - - periodictable - -test: - # Python imports - imports: - - diffpy - - diffpy.srreal - - diffpy.srreal.tests - - commands: - # Test if any module can be imported as the first one. - - python -s -c "import diffpy.srreal.atomradiitable" - - python -s -c "import diffpy.srreal.attributes" - - python -s -c "import diffpy.srreal.bondcalculator" - - python -s -c "import diffpy.srreal.bvparameterstable" - - python -s -c "import diffpy.srreal.bvscalculator" - - python -s -c "import diffpy.srreal.eventticker" - - python -s -c "import diffpy.srreal.overlapcalculator" - - python -s -c "import diffpy.srreal.pairquantity" - - python -s -c "import diffpy.srreal.pdfbaseline" - - python -s -c "import diffpy.srreal.pdfcalculator" - - python -s -c "import diffpy.srreal.pdfenvelope" - - python -s -c "import diffpy.srreal.peakprofile" - - python -s -c "import diffpy.srreal.peakwidthmodel" - - python -s -c "import diffpy.srreal.scatteringfactortable" - - python -s -c "import diffpy.srreal.srreal_ext" - - python -s -c "import diffpy.srreal.structureadapter" - - python -s -c "import diffpy.srreal.structureconverters" - - python -s -c "import diffpy.srreal.version" - - - # You can also put a file called run_test.py in the recipe that will be run - # at test time. - - # requires: - # Put any additional test requirements here. For example - # - nose - -about: - home: https://github.com/diffpy/diffpy.srreal - summary: Calculators for PDF, bond valence sum and other - pair-interaction quantities. - license: Modified BSD License - license_file: LICENSE.txt - -# See http://docs.continuum.io/conda/build.html -# for more information about meta.yaml. diff --git a/conda-recipe/run_test.py b/conda-recipe/run_test.py deleted file mode 100644 index 0edfe0c3..00000000 --- a/conda-recipe/run_test.py +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env python - -import diffpy.srreal.tests - -assert diffpy.srreal.tests.test().wasSuccessful() diff --git a/conda-recipe/sconscript.local b/conda-recipe/sconscript.local deleted file mode 100644 index f8740395..00000000 --- a/conda-recipe/sconscript.local +++ /dev/null @@ -1,18 +0,0 @@ -# Customize scons build environment. - -Import('env') - -import os - -# Apply environment settings for Anaconda compilers -env.Replace(CXX=os.environ['CXX']) -env.MergeFlags(os.environ['CFLAGS']) -env.MergeFlags(os.environ['CPPFLAGS']) -env.MergeFlags(os.environ['CXXFLAGS']) -env.MergeFlags(os.environ['LDFLAGS']) - -# Silence copious warnings from the boost headers. -P = os.environ['PREFIX'] -env.Prepend(CCFLAGS=['-isystem{}/include'.format(P)]) - -# vim: ft=python diff --git a/devutils/makesdist b/devutils/makesdist deleted file mode 100755 index 10bba1ff..00000000 --- a/devutils/makesdist +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env python - -"""Create source distribution tar.gz archive, where each file belongs to a root -user and modification time is set to the git commit time.""" - -import glob -import gzip -import os -import subprocess -import sys -import tarfile - -from setup import FALLBACK_VERSION, versiondata - -BASEDIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) -sys.path.insert(0, BASEDIR) - -timestamp = versiondata.getint("DEFAULT", "timestamp") - -vfb = versiondata.get("DEFAULT", "version").split(".post")[0] + ".post0" -emsg = "Invalid FALLBACK_VERSION. Expected %r got %r." -assert vfb == FALLBACK_VERSION, emsg % (vfb, FALLBACK_VERSION) - - -def inform(s): - sys.stdout.write(s) - sys.stdout.flush() - return - - -inform('Run "setup.py sdist --formats=tar" ') -cmd_sdist = [sys.executable, "-Wignore:Cannot detect name suffix"] + "setup.py sdist --formats=tar".split() -ec = subprocess.call(cmd_sdist, cwd=BASEDIR, stdout=open(os.devnull, "w")) -if ec: - sys.exit(ec) -inform("[done]\n") - -tarname = max(glob.glob(BASEDIR + "/dist/*.tar"), key=os.path.getmtime) - -tfin = tarfile.open(tarname) -fpout = gzip.GzipFile(tarname + ".gz", "w", mtime=0) -tfout = tarfile.open(fileobj=fpout, mode="w") - - -def fixtarinfo(tinfo): - tinfo.uid = tinfo.gid = 0 - tinfo.uname = tinfo.gname = "root" - tinfo.mtime = timestamp - tinfo.mode &= ~0o022 - return tinfo - - -inform("Filter %s --> %s.gz " % (2 * (os.path.basename(tarname),))) -for ti in tfin: - tfout.addfile(fixtarinfo(ti), tfin.extractfile(ti)) - -tfin.close() -os.remove(tarname) -inform("[done]\n") diff --git a/devutils/tunePeakPrecision.py b/src/diffpy/srreal/devutils/tunePeakPrecision.py similarity index 100% rename from devutils/tunePeakPrecision.py rename to src/diffpy/srreal/devutils/tunePeakPrecision.py From 39eeb08a54dd1c6a3e0ee967dbacce4fc755d751 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Sat, 11 Jan 2025 05:11:36 -0500 Subject: [PATCH 19/55] doc --- doc/{manual => }/Makefile | 27 ++- doc/make.bat | 36 ++++ doc/manual/source/api/diffpy.srreal.rst | 163 ------------------ doc/manual/source/license.rst | 142 --------------- doc/manual/source/release.rst | 3 - doc/source/_static/.placeholder | 0 .../api/diffpy.srreal.example_package.rst | 31 ++++ doc/source/api/diffpy.srreal.rst | 30 ++++ doc/{manual => }/source/conf.py | 89 ++++++---- doc/source/examples.rst | 4 + .../source/examples}/compareC60PDFs.py | 0 .../examples}/compareC60PDFs_objcryst.py | 0 .../source/examples}/datafiles/C60bucky.stru | 0 .../source/examples}/datafiles/menthol.cif | 0 .../source/examples}/datafiles/sphalerite.cif | 0 .../source/examples}/distanceprinter.py | 0 .../source/examples}/lennardjones/Makefile | 0 .../source/examples}/lennardjones/README.txt | 0 .../source/examples}/lennardjones/lj50.xyz | 0 .../examples}/lennardjones/ljcalculator.cpp | 0 .../examples}/lennardjones/ljcalculator.py | 0 .../source/examples}/parallelPDF.py | 0 doc/{manual => }/source/index.rst | 40 +++-- doc/source/license.rst | 149 ++++++++++++++++ doc/source/release.rst | 5 + 25 files changed, 360 insertions(+), 359 deletions(-) rename doc/{manual => }/Makefile (83%) create mode 100644 doc/make.bat delete mode 100644 doc/manual/source/api/diffpy.srreal.rst delete mode 100644 doc/manual/source/license.rst delete mode 100644 doc/manual/source/release.rst create mode 100644 doc/source/_static/.placeholder create mode 100644 doc/source/api/diffpy.srreal.example_package.rst create mode 100644 doc/source/api/diffpy.srreal.rst rename doc/{manual => }/source/conf.py (81%) create mode 100644 doc/source/examples.rst rename {examples => doc/source/examples}/compareC60PDFs.py (100%) rename {examples => doc/source/examples}/compareC60PDFs_objcryst.py (100%) rename {examples => doc/source/examples}/datafiles/C60bucky.stru (100%) rename {examples => doc/source/examples}/datafiles/menthol.cif (100%) rename {examples => doc/source/examples}/datafiles/sphalerite.cif (100%) rename {examples => doc/source/examples}/distanceprinter.py (100%) rename {examples => doc/source/examples}/lennardjones/Makefile (100%) rename {examples => doc/source/examples}/lennardjones/README.txt (100%) rename {examples => doc/source/examples}/lennardjones/lj50.xyz (100%) rename {examples => doc/source/examples}/lennardjones/ljcalculator.cpp (100%) rename {examples => doc/source/examples}/lennardjones/ljcalculator.py (100%) rename {examples => doc/source/examples}/parallelPDF.py (100%) rename doc/{manual => }/source/index.rst (80%) create mode 100644 doc/source/license.rst create mode 100644 doc/source/release.rst diff --git a/doc/manual/Makefile b/doc/Makefile similarity index 83% rename from doc/manual/Makefile rename to doc/Makefile index a21894cf..0c241efa 100644 --- a/doc/manual/Makefile +++ b/doc/Makefile @@ -6,6 +6,12 @@ SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = build +BASENAME = $(subst .,,$(subst $() $(),,diffpy.srreal)) + +# User-friendly check for sphinx-build +ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) +$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) +endif # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 @@ -14,7 +20,7 @@ ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) sou # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext publish +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext help: @echo "Please use \`make ' where is one of" @@ -29,17 +35,20 @@ help: @echo " epub to make an epub" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" @echo " text to make text files" @echo " man to make manual pages" @echo " texinfo to make Texinfo files" @echo " info to make Texinfo files and run them through makeinfo" @echo " gettext to make PO message catalogs" @echo " changes to make an overview of all changed/added/deprecated items" + @echo " xml to make Docutils-native XML files" + @echo " pseudoxml to make pseudoxml-XML files for display purposes" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" clean: - -rm -rf $(BUILDDIR)/* + rm -rf $(BUILDDIR)/* html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @@ -77,17 +86,17 @@ qthelp: @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/SrReal.qhcp" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/$(BASENAME).qhcp" @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/SrReal.qhc" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/$(BASENAME).qhc" devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/SrReal" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/SrReal" + @echo "# mkdir -p $$HOME/.local/share/devhelp/$(BASENAME)" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/$(BASENAME)" @echo "# devhelp" epub: @@ -108,6 +117,12 @@ latexpdf: $(MAKE) -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." +latexpdfja: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through platex and dvipdfmx..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + text: $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo diff --git a/doc/make.bat b/doc/make.bat new file mode 100644 index 00000000..ac53d5bd --- /dev/null +++ b/doc/make.bat @@ -0,0 +1,36 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build +set SPHINXPROJ=PackagingScientificPython + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% + +:end +popd diff --git a/doc/manual/source/api/diffpy.srreal.rst b/doc/manual/source/api/diffpy.srreal.rst deleted file mode 100644 index 24629776..00000000 --- a/doc/manual/source/api/diffpy.srreal.rst +++ /dev/null @@ -1,163 +0,0 @@ -:tocdepth: 2 - -.. default-role:: py:obj - -diffpy.srreal package -===================== - -.. automodule:: diffpy.srreal - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -diffpy.srreal.atomradiitable module ------------------------------------ - -.. automodule:: diffpy.srreal.atomradiitable - :members: - :undoc-members: - :show-inheritance: - -diffpy.srreal.attributes module -------------------------------- - -.. automodule:: diffpy.srreal.attributes - :members: - :undoc-members: - :show-inheritance: - -diffpy.srreal.bondcalculator module ------------------------------------ - -.. automodule:: diffpy.srreal.bondcalculator - :members: - :undoc-members: - :show-inheritance: - -diffpy.srreal.bvparameterstable module --------------------------------------- - -.. automodule:: diffpy.srreal.bvparameterstable - :members: - :undoc-members: - :show-inheritance: - -diffpy.srreal.bvscalculator module ----------------------------------- - -.. automodule:: diffpy.srreal.bvscalculator - :members: - :undoc-members: - :show-inheritance: - -diffpy.srreal.eventticker module --------------------------------- - -.. automodule:: diffpy.srreal.eventticker - :members: - :undoc-members: - :show-inheritance: - -diffpy.srreal.overlapcalculator module --------------------------------------- - -.. automodule:: diffpy.srreal.overlapcalculator - :members: - :undoc-members: - :show-inheritance: - -diffpy.srreal.pairquantity module ---------------------------------- - -.. automodule:: diffpy.srreal.pairquantity - :members: - :undoc-members: - :show-inheritance: - -diffpy.srreal.parallel module ------------------------------ - -.. automodule:: diffpy.srreal.parallel - :members: - :undoc-members: - :show-inheritance: - -diffpy.srreal.pdfbaseline module --------------------------------- - -.. automodule:: diffpy.srreal.pdfbaseline - :members: - :undoc-members: - :show-inheritance: - -diffpy.srreal.pdfcalculator module ----------------------------------- - -.. automodule:: diffpy.srreal.pdfcalculator - :members: - :undoc-members: - :show-inheritance: - -diffpy.srreal.pdfenvelope module --------------------------------- - -.. automodule:: diffpy.srreal.pdfenvelope - :members: - :undoc-members: - :show-inheritance: - -diffpy.srreal.peakprofile module --------------------------------- - -.. automodule:: diffpy.srreal.peakprofile - :members: - :undoc-members: - :show-inheritance: - -diffpy.srreal.peakwidthmodel module ------------------------------------ - -.. automodule:: diffpy.srreal.peakwidthmodel - :members: - :undoc-members: - :show-inheritance: - -diffpy.srreal.scatteringfactortable module ------------------------------------------- - -.. automodule:: diffpy.srreal.scatteringfactortable - :members: ScatteringFactorTable, SFTXray, - SFTElectron, SFTNeutron, SFTElectronNumber - :undoc-members: - :show-inheritance: - -diffpy.srreal.sfaverage module ------------------------------- - -.. automodule:: diffpy.srreal.sfaverage - :members: - :undoc-members: - :no-show-inheritance: - -diffpy.srreal.structureadapter module -------------------------------------- - -.. automodule:: diffpy.srreal.structureadapter - :members: - :undoc-members: - :show-inheritance: - -.. skip internal module diffpy.srreal.structureconverters - -diffpy.srreal.version module ----------------------------- - -.. automodule:: diffpy.srreal.version - :members: - :undoc-members: - :show-inheritance: - -.. skip internal module diffpy.srreal.wraputils diff --git a/doc/manual/source/license.rst b/doc/manual/source/license.rst deleted file mode 100644 index 7d78e94f..00000000 --- a/doc/manual/source/license.rst +++ /dev/null @@ -1,142 +0,0 @@ -.. index:: license - -License -####### - -OPEN SOURCE LICENSE AGREEMENT -============================= - -| Copyright (c) 2009-2011, University of Tennessee -| Copyright (c) 1989, 1991 Free Software Foundation, Inc. -| Copyright (c) 2006, The Regents of the University of California through - Lawrence Berkeley National Laboratory -| Copyright (c) 2014, Australian Synchrotron Research Program Inc., ("ASRP") -| Copyright (c) 2006-2007, Board of Trustees of Michigan State University -| Copyright (c) 2008-2012, The Trustees of Columbia University in - the City of New York -| Copyright (c) 2014-2019, Brookhaven Science Associates, - Brookhaven National Laboratory - - -The "DiffPy-CMI" is distributed subject to the following license conditions: - - -SOFTWARE LICENSE AGREEMENT -========================== - -Software: **DiffPy-CMI** - - -(1) The "Software", below, refers to the aforementioned DiffPy-CMI (in either -source code, or binary form and accompanying documentation). - -Part of the software was derived from the DANSE, ObjCryst++ (with permission), -PyCifRW, Python periodictable, CCTBX, and SasView open source projects, of -which the original Copyrights are contained in each individual file. - -Each licensee is addressed as "you" or "Licensee." - - -(2) The copyright holders shown above and their third-party Licensors hereby -grant licensee a royalty-free nonexclusive license, subject to the limitations -stated herein and U.S. Government license rights. - - -(3) You may modify and make a copy or copies of the software for use within -your organization, if you meet the following conditions: - - (a) Copies in source code must include the copyright notice and this - software license agreement. - - (b) Copies in binary form must include the copyright notice and this - Software License Agreement in the documentation and/or other materials - provided with the copy. - - -(4) You may modify a copy or copies of the Software or any portion of it, thus -forming a work based on the Software, and distribute copies of such work -outside your organization, if you meet all of the following conditions: - - (a) Copies in source code must include the copyright notice and this - Software License Agreement; - - (b) Copies in binary form must include the copyright notice and this - Software License Agreement in the documentation and/or other materials - provided with the copy; - - (c) Modified copies and works based on the Software must carry prominent - notices stating that you changed specified portions of the Software. - - (d) Neither the name of Brookhaven Science Associates or Brookhaven - National Laboratory nor the names of its contributors may be used to - endorse or promote products derived from this software without specific - written permission. - - -(5) Portions of the Software resulted from work developed under a U.S. -Government contract and are subject to the following license: -The Government is granted for itself and others acting on its behalf a -paid-up, nonexclusive, irrevocable worldwide license in this computer software -to reproduce, prepare derivative works, and perform publicly and display -publicly. - - -(6) WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" WITHOUT -WARRANTY OF ANY KIND. THE COPYRIGHT HOLDERS, THEIR THIRD PARTY -LICENSORS, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND -THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR IMPLIED, INCLUDING -BUT NOT LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE, TITLE OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL -LIABILITY OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR USEFULNESS OF -THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF THE SOFTWARE WOULD NOT INFRINGE -PRIVATELY OWNED RIGHTS, (4) DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION -UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL BE CORRECTED. - - -(7) LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT HOLDERS, THEIR -THIRD PARTY LICENSORS, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF -ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, INCIDENTAL, -CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF ANY KIND OR NATURE, INCLUDING -BUT NOT LIMITED TO LOSS OF PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, -WHETHER SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT (INCLUDING -NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, EVEN IF ANY OF SAID PARTIES HAS -BEEN WARNED OF THE POSSIBILITY OF SUCH LOSS OR DAMAGES. - - -Brookhaven National Laboratory Notice -===================================== - -Acknowledgment of sponsorship ------------------------------ - -This software was produced by the Brookhaven National Laboratory, under -Contract DE-AC02-98CH10886 with the Department of Energy. - - -Government disclaimer of liability ----------------------------------- - -Neither the United States nor the United States Department of Energy, nor -any of their employees, makes any warranty, express or implied, or assumes -any legal liability or responsibility for the accuracy, completeness, or -usefulness of any data, apparatus, product, or process disclosed, or -represents that its use would not infringe privately owned rights. - - -Brookhaven disclaimer of liability ----------------------------------- - -Brookhaven National Laboratory makes no representations or warranties, -express or implied, nor assumes any liability for the use of this software. - - -Maintenance of notice ---------------------- - -In the interest of clarity regarding the origin and status of this -software, Brookhaven National Laboratory requests that any recipient of it -maintain this notice affixed to any distribution by the recipient that -contains a copy or derivative of this software. - - -.. rubric:: END OF LICENSE diff --git a/doc/manual/source/release.rst b/doc/manual/source/release.rst deleted file mode 100644 index 7ec4f81d..00000000 --- a/doc/manual/source/release.rst +++ /dev/null @@ -1,3 +0,0 @@ -.. index:: release notes - -.. mdinclude:: ../../../CHANGELOG.md diff --git a/doc/source/_static/.placeholder b/doc/source/_static/.placeholder new file mode 100644 index 00000000..e69de29b diff --git a/doc/source/api/diffpy.srreal.example_package.rst b/doc/source/api/diffpy.srreal.example_package.rst new file mode 100644 index 00000000..439a6b4f --- /dev/null +++ b/doc/source/api/diffpy.srreal.example_package.rst @@ -0,0 +1,31 @@ +.. _example_package documentation: + +|title| +======= + +.. |title| replace:: diffpy.srreal.example_package package + +.. automodule:: diffpy.srreal.example_package + :members: + :undoc-members: + :show-inheritance: + +|foo| +----- + +.. |foo| replace:: diffpy.srreal.example_package.foo module + +.. automodule:: diffpy.srreal.example_package.foo + :members: + :undoc-members: + :show-inheritance: + +|bar| +----- + +.. |bar| replace:: diffpy.srreal.example_package.bar module + +.. automodule:: diffpy.srreal.example_package.foo + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/api/diffpy.srreal.rst b/doc/source/api/diffpy.srreal.rst new file mode 100644 index 00000000..0f1bb4b7 --- /dev/null +++ b/doc/source/api/diffpy.srreal.rst @@ -0,0 +1,30 @@ +:tocdepth: -1 + +|title| +======= + +.. |title| replace:: diffpy.srreal package + +.. automodule:: diffpy.srreal + :members: + :undoc-members: + :show-inheritance: + +Subpackages +----------- + +.. toctree:: + diffpy.srreal.example_package + +Submodules +---------- + +|module| +-------- + +.. |module| replace:: diffpy.srreal.example_submodule module + +.. automodule:: diffpy.srreal.example_submodule + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/manual/source/conf.py b/doc/source/conf.py similarity index 81% rename from doc/manual/source/conf.py rename to doc/source/conf.py index 326acdd8..f885a7b1 100644 --- a/doc/manual/source/conf.py +++ b/doc/source/conf.py @@ -2,9 +2,10 @@ # -*- coding: utf-8 -*- # # diffpy.srreal documentation build configuration file, created by -# sphinx-quickstart on Tue Oct 22 12:02:48 2013. +# sphinx-quickstart on Thu Jan 30 15:49:41 2014. # -# This file is execfile()d with the current directory set to its containing dir. +# This file is execfile()d with the current directory set to its +# containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. @@ -12,33 +13,36 @@ # All configuration values have a default; values that are commented out # serve to show the default. -import os import sys import time - -from setup import versiondata +from importlib.metadata import version +from pathlib import Path # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# sys.path.insert(0, os.path.abspath('.')) -sys.path.insert(0, os.path.abspath("../../..")) +# documentation root, use Path().resolve() to make it absolute, like shown here. +# sys.path.insert(0, str(Path(".").resolve())) +sys.path.insert(0, str(Path("../..").resolve())) +sys.path.insert(0, str(Path("../../src").resolve())) # abbreviations ab_authors = "Pavol Juhás, Christopher L. Farrow, Simon J.L. Billinge group" -# -- General configuration ----------------------------------------------------- +# -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. # needs_sphinx = '1.0' -# Add any Sphinx extension module names here, as strings. They can be extensions -# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. extensions = [ "sphinx.ext.autodoc", - "sphinx.ext.coverage", "sphinx.ext.napoleon", + "sphinx.ext.todo", + "sphinx.ext.viewcode", "sphinx.ext.intersphinx", + "sphinx_rtd_theme", "m2r", ] @@ -58,13 +62,13 @@ # General information about the project. project = "diffpy.srreal" -copyright = "%Y, Brookhaven National Laboratory" +copyright = "%Y, The Trustees of Columbia University in the City of New York" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. -fullversion = versiondata.get("DEFAULT", "version") +fullversion = version(project) # The short X.Y version. version = "".join(fullversion.split(".post")[:1]) # The full version, including alpha/beta/rc tags. @@ -77,8 +81,7 @@ # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: # today = '' -today_seconds = versiondata.getint("DEFAULT", "timestamp") -today = time.strftime("%B %d, %Y", time.localtime(today_seconds)) +today = time.strftime("%B %d, %Y", time.localtime()) year = today.split()[-1] # Else, today_fmt is used as the format for a strftime call. # today_fmt = '%B %d, %Y' @@ -87,9 +90,10 @@ # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. -exclude_patterns = [] +exclude_patterns = ["build"] -# The reST default role (used for this markup: `text`) to use for all documents. +# The reST default role (used for this markup: `text`) to use for all +# documents. # default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. @@ -112,17 +116,18 @@ # Display all warnings for missing links. nitpicky = True -# -- Options for HTML output --------------------------------------------------- +# -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = "sphinx_py3doc_enhanced_theme" +# +html_theme = "sphinx_rtd_theme" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. +# html_theme_options = { - "collapsiblesidebar": "true", "navigation_with_keys": "true", } @@ -150,6 +155,11 @@ # so a file named "default.css" will overwrite the builtin "default.css". # html_static_path = ['_static'] +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +# html_extra_path = [] + # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. # html_last_updated_fmt = '%b %d, %Y' @@ -192,10 +202,11 @@ # html_file_suffix = None # Output file base name for HTML help builder. -htmlhelp_basename = "srrealdoc" +basename = "diffpy.srreal".replace(" ", "").replace(".", "") +htmlhelp_basename = basename + "doc" -# -- Options for LaTeX output -------------------------------------------------- +# -- Options for LaTeX output --------------------------------------------- latex_elements = { # The paper size ('letterpaper' or 'a4paper'). @@ -207,9 +218,16 @@ } # Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass [howto/manual]). +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). latex_documents = [ - ("index", "diffpy.srreal.tex", "diffpy.srreal Documentation", ab_authors, "manual"), + ( + "index", + "diffpy.srreal.tex", + "diffpy.srreal Documentation", + ab_authors, + "manual", + ), ] # The name of an image file (relative to this directory) to place at the top of @@ -233,17 +251,25 @@ # latex_domain_indices = True -# -- Options for manual page output -------------------------------------------- +# -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [("index", "diffpy.srreal", "diffpy.srreal Documentation", ab_authors, 1)] +man_pages = [ + ( + "index", + "diffpy.srreal", + "diffpy.srreal Documentation", + ab_authors, + 1, + ) +] # If true, show URL addresses after external links. # man_show_urls = False -# -- Options for Texinfo output ------------------------------------------------ +# -- Options for Texinfo output ------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, @@ -269,9 +295,12 @@ # How to display URL addresses: 'footnote', 'no', or 'inline'. # texinfo_show_urls = 'footnote' +# If true, do not generate a @detailmenu in the "Top" node's menu. +# texinfo_no_detailmenu = False + # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = { - "numpy": ("https://docs.scipy.org/doc/numpy", None), - "python": ("https://docs.python.org/3.7", None), + "numpy": ("https://numpy.org/doc/stable/", None), + "python": ("https://docs.python.org/3", None), } diff --git a/doc/source/examples.rst b/doc/source/examples.rst new file mode 100644 index 00000000..ef8715f5 --- /dev/null +++ b/doc/source/examples.rst @@ -0,0 +1,4 @@ +.. _examples: + +Examples +######## diff --git a/examples/compareC60PDFs.py b/doc/source/examples/compareC60PDFs.py similarity index 100% rename from examples/compareC60PDFs.py rename to doc/source/examples/compareC60PDFs.py diff --git a/examples/compareC60PDFs_objcryst.py b/doc/source/examples/compareC60PDFs_objcryst.py similarity index 100% rename from examples/compareC60PDFs_objcryst.py rename to doc/source/examples/compareC60PDFs_objcryst.py diff --git a/examples/datafiles/C60bucky.stru b/doc/source/examples/datafiles/C60bucky.stru similarity index 100% rename from examples/datafiles/C60bucky.stru rename to doc/source/examples/datafiles/C60bucky.stru diff --git a/examples/datafiles/menthol.cif b/doc/source/examples/datafiles/menthol.cif similarity index 100% rename from examples/datafiles/menthol.cif rename to doc/source/examples/datafiles/menthol.cif diff --git a/examples/datafiles/sphalerite.cif b/doc/source/examples/datafiles/sphalerite.cif similarity index 100% rename from examples/datafiles/sphalerite.cif rename to doc/source/examples/datafiles/sphalerite.cif diff --git a/examples/distanceprinter.py b/doc/source/examples/distanceprinter.py similarity index 100% rename from examples/distanceprinter.py rename to doc/source/examples/distanceprinter.py diff --git a/examples/lennardjones/Makefile b/doc/source/examples/lennardjones/Makefile similarity index 100% rename from examples/lennardjones/Makefile rename to doc/source/examples/lennardjones/Makefile diff --git a/examples/lennardjones/README.txt b/doc/source/examples/lennardjones/README.txt similarity index 100% rename from examples/lennardjones/README.txt rename to doc/source/examples/lennardjones/README.txt diff --git a/examples/lennardjones/lj50.xyz b/doc/source/examples/lennardjones/lj50.xyz similarity index 100% rename from examples/lennardjones/lj50.xyz rename to doc/source/examples/lennardjones/lj50.xyz diff --git a/examples/lennardjones/ljcalculator.cpp b/doc/source/examples/lennardjones/ljcalculator.cpp similarity index 100% rename from examples/lennardjones/ljcalculator.cpp rename to doc/source/examples/lennardjones/ljcalculator.cpp diff --git a/examples/lennardjones/ljcalculator.py b/doc/source/examples/lennardjones/ljcalculator.py similarity index 100% rename from examples/lennardjones/ljcalculator.py rename to doc/source/examples/lennardjones/ljcalculator.py diff --git a/examples/parallelPDF.py b/doc/source/examples/parallelPDF.py similarity index 100% rename from examples/parallelPDF.py rename to doc/source/examples/parallelPDF.py diff --git a/doc/manual/source/index.rst b/doc/source/index.rst similarity index 80% rename from doc/manual/source/index.rst rename to doc/source/index.rst index 4dab5ec8..2c063dfc 100644 --- a/doc/manual/source/index.rst +++ b/doc/source/index.rst @@ -1,8 +1,10 @@ -#################################################### -diffpy.srreal documentation -#################################################### +####### +|title| +####### -diffpy.srreal - calculators for PDF, bond valence sum and other pair quantities. +.. |title| replace:: diffpy.srreal documentation + +diffpy.srreal - Calculators for PDF, bond valence sum, and other quantities based on atom pair interaction. | Software version |release|. | Last updated |today|. @@ -37,9 +39,9 @@ calculate PDF with a user-defined profile function. A new calculator class can be also defined for any quantity that is obtained by iteration over atom pairs, by defining only the function that processes atom-pair contributions. -======================================== +======= Authors -======================================== +======= diffpy.srreal is developed by members of the Billinge Group at Columbia University and at Brookhaven National Laboratory including @@ -48,28 +50,36 @@ Pavol Juhás, Christopher L. Farrow, Simon J.L. Billinge. For a detailed list of contributors see https://github.com/diffpy/diffpy.srreal/graphs/contributors. -====================================== +Reference +========= + +If you use this program for a scientific research that leads +to publication, we ask that you acknowledge use of the program +by citing the following paper in your publication: + + diffpy.srreal Package, https://github.com/diffpy/diffpy.srreal + +============ Installation -====================================== +============ -See the `README `_ +See the `README `_ file included with the distribution. -====================================== +================= Table of contents -====================================== - +================= .. toctree:: :titlesonly: license release + examples Package API -====================================== +======= Indices -====================================== +======= * :ref:`genindex` -* :ref:`modindex` * :ref:`search` diff --git a/doc/source/license.rst b/doc/source/license.rst new file mode 100644 index 00000000..dfdea740 --- /dev/null +++ b/doc/source/license.rst @@ -0,0 +1,149 @@ +:tocdepth: -1 + +.. index:: license + +License +####### + +OPEN SOURCE LICENSE AGREEMENT +============================= + +Copyright (c) 2009-2011, University of Tennessee + +Copyright (c) 1989, 1991 Free Software Foundation, Inc. + +Copyright (c) 2006, The Regents of the University of California through Lawrence Berkeley National Laboratory + +Copyright (c) 2014, Australian Synchrotron Research Program Inc., ("ASRP") + +Copyright (c) 2006-2007, Board of Trustees of Michigan State University + +Copyright (c) 2008-2012, The Trustees of Columbia University in the City of New York + +Copyright (c) 2014-2019, Brookhaven Science Associates, Brookhaven National Laboratory + +Copyright (c) 2024, The Trustees of Columbia University in the City of New York. +All rights reserved. + +The "DiffPy-CMI" is distributed subject to the following license conditions: + +.. code-block:: text + + SOFTWARE LICENSE AGREEMENT + + Software: DiffPy-CMI + + + (1) The "Software", below, refers to the aforementioned DiffPy-CMI (in either + source code, or binary form and accompanying documentation). + + Part of the software was derived from the DANSE, ObjCryst++ (with permission), + PyCifRW, Python periodictable, CCTBX, and SasView open source projects, of + which the original Copyrights are contained in each individual file. + + Each licensee is addressed as "you" or "Licensee." + + + (2) The copyright holders shown above and their third-party Licensors hereby + grant licensee a royalty-free nonexclusive license, subject to the limitations + stated herein and U.S. Government license rights. + + + (3) You may modify and make a copy or copies of the software for use within + your organization, if you meet the following conditions: + + (a) Copies in source code must include the copyright notice and this + software license agreement. + + (b) Copies in binary form must include the copyright notice and this + Software License Agreement in the documentation and/or other materials + provided with the copy. + + + (4) You may modify a copy or copies of the Software or any portion of it, thus + forming a work based on the Software, and distribute copies of such work + outside your organization, if you meet all of the following conditions: + + (a) Copies in source code must include the copyright notice and this + Software License Agreement; + + (b) Copies in binary form must include the copyright notice and this + Software License Agreement in the documentation and/or other materials + provided with the copy; + + (c) Modified copies and works based on the Software must carry prominent + notices stating that you changed specified portions of the Software. + + (d) Neither the name of Brookhaven Science Associates or Brookhaven + National Laboratory nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + written permission. + + + (5) Portions of the Software resulted from work developed under a U.S. + Government contract and are subject to the following license: + The Government is granted for itself and others acting on its behalf a + paid-up, nonexclusive, irrevocable worldwide license in this computer software + to reproduce, prepare derivative works, and perform publicly and display + publicly. + + + (6) WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" WITHOUT + WARRANTY OF ANY KIND. THE COPYRIGHT HOLDERS, THEIR THIRD PARTY + LICENSORS, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND + THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + PARTICULAR PURPOSE, TITLE OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL + LIABILITY OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR USEFULNESS OF + THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF THE SOFTWARE WOULD NOT INFRINGE + PRIVATELY OWNED RIGHTS, (4) DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION + UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL BE CORRECTED. + + + (7) LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT HOLDERS, THEIR + THIRD PARTY LICENSORS, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF + ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, INCIDENTAL, + CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF ANY KIND OR NATURE, INCLUDING + BUT NOT LIMITED TO LOSS OF PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, + WHETHER SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT (INCLUDING + NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, EVEN IF ANY OF SAID PARTIES HAS + BEEN WARNED OF THE POSSIBILITY OF SUCH LOSS OR DAMAGES. + + +Brookhaven National Laboratory Notice +===================================== + +Acknowledgment of sponsorship +----------------------------- + +This software was produced by the Brookhaven National Laboratory, under +Contract DE-AC02-98CH10886 with the Department of Energy. + + +Government disclaimer of liability +---------------------------------- + +Neither the United States nor the United States Department of Energy, nor +any of their employees, makes any warranty, express or implied, or assumes +any legal liability or responsibility for the accuracy, completeness, or +usefulness of any data, apparatus, product, or process disclosed, or +represents that its use would not infringe privately owned rights. + + +Brookhaven disclaimer of liability +---------------------------------- + +Brookhaven National Laboratory makes no representations or warranties, +express or implied, nor assumes any liability for the use of this software. + + +Maintenance of notice +--------------------- + +In the interest of clarity regarding the origin and status of this +software, Brookhaven National Laboratory requests that any recipient of it +maintain this notice affixed to any distribution by the recipient that +contains a copy or derivative of this software. + + +END OF LICENSE diff --git a/doc/source/release.rst b/doc/source/release.rst new file mode 100644 index 00000000..27cd0cc9 --- /dev/null +++ b/doc/source/release.rst @@ -0,0 +1,5 @@ +:tocdepth: -1 + +.. index:: release notes + +.. include:: ../../CHANGELOG.rst From b05530cbd63716aaa12d41d0c45b3433229cdcda Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Sat, 11 Jan 2025 05:12:23 -0500 Subject: [PATCH 20/55] src --- src/diffpy/__init__.py | 20 ++++------ src/diffpy/srreal/__init__.py | 16 ++++---- src/diffpy/srreal/_version_data.py | 49 ----------------------- src/diffpy/srreal/version.py | 62 +++++++----------------------- 4 files changed, 29 insertions(+), 118 deletions(-) delete mode 100644 src/diffpy/srreal/_version_data.py diff --git a/src/diffpy/__init__.py b/src/diffpy/__init__.py index e8b7ec78..67de5256 100644 --- a/src/diffpy/__init__.py +++ b/src/diffpy/__init__.py @@ -1,26 +1,22 @@ #!/usr/bin/env python ############################################################################## # -# diffpy by DANSE Diffraction group -# Simon J. L. Billinge -# (c) 2008 The Trustees of Columbia University -# in the City of New York. All rights reserved. +# (c) 2025 The Trustees of Columbia University in the City of New York. +# All rights reserved. # -# File coded by: Pavol Juhas +# File coded by: Billinge Group members and community contributors. # -# See AUTHORS.txt for a list of people who contributed. -# See LICENSE_DANSE.txt for license information. +# See GitHub contributions for a more detailed list of contributors. +# https://github.com/diffpy/diffpy.srreal/graphs/contributors +# +# See LICENSE.rst for license information. # ############################################################################## -"""diffpy - tools for structure analysis by diffraction. - -Blank namespace package. -""" +"""Blank namespace package for module diffpy.""" from pkgutil import extend_path __path__ = extend_path(__path__, __name__) - # End of file diff --git a/src/diffpy/srreal/__init__.py b/src/diffpy/srreal/__init__.py index 7c62d5f3..2beff97f 100644 --- a/src/diffpy/srreal/__init__.py +++ b/src/diffpy/srreal/__init__.py @@ -1,21 +1,21 @@ #!/usr/bin/env python ############################################################################## # -# diffpy.srreal by DANSE Diffraction group -# Simon J. L. Billinge -# (c) 2008 The Trustees of Columbia University -# in the City of New York. All rights reserved. +# (c) 2025 The Trustees of Columbia University in the City of New York. +# All rights reserved. # -# File coded by: Pavol Juhas +# File coded by: Billinge Group members and community contributors. # -# See AUTHORS.txt for a list of people who contributed. -# See LICENSE_DANSE.txt for license information. +# See GitHub contributions for a more detailed list of contributors. +# https://github.com/diffpy/diffpy.srreal/graphs/contributors +# +# See LICENSE.rst for license information. # ############################################################################## """Tools for real space structure analysis.""" # package version -from diffpy.srreal._version_data import __version__ +from diffpy.srreal.version import __version__ # silence the pyflakes syntax checker assert __version__ or True diff --git a/src/diffpy/srreal/_version_data.py b/src/diffpy/srreal/_version_data.py deleted file mode 100644 index b3828e8d..00000000 --- a/src/diffpy/srreal/_version_data.py +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env python -############################################################################## -# -# diffpy.srreal by DANSE Diffraction group -# Simon J. L. Billinge -# (c) 2008 The Trustees of Columbia University -# in the City of New York. All rights reserved. -# -# File coded by: Pavol Juhas -# -# See AUTHORS.txt for a list of people who contributed. -# See LICENSE_DANSE.txt for license information. -# -############################################################################## -"""Extraction of version data for diffpy.srreal package. - -Does not import any extension module unlike the `version` module. -""" - -__all__ = ["__date__", "__git_commit__", "__timestamp__", "__version__"] - -import os.path - -from pkg_resources import resource_filename - -# obtain version information from the version.cfg file -cp = dict(version="", date="", commit="", timestamp="0") -fcfg = resource_filename(__name__, "version.cfg") -if not os.path.isfile(fcfg): # pragma: no cover - from warnings import warn - - warn('Package metadata not found, execute "./setup.py egg_info".') - fcfg = os.devnull -with open(fcfg) as fp: - kwords = [[w.strip() for w in line.split(" = ", 1)] for line in fp if line[:1].isalpha() and " = " in line] -assert all(w[0] in cp for w in kwords), "received unrecognized keyword" -cp.update(kwords) - -__version__ = cp["version"] -__date__ = cp["date"] -__git_commit__ = cp["commit"] -__timestamp__ = int(cp["timestamp"]) - -# TODO remove deprecated __gitsha__ in version 1.4. -__gitsha__ = __git_commit__ - -del cp, fcfg, fp, kwords - -# End of file diff --git a/src/diffpy/srreal/version.py b/src/diffpy/srreal/version.py index 67596f6b..54d1c6b3 100644 --- a/src/diffpy/srreal/version.py +++ b/src/diffpy/srreal/version.py @@ -1,61 +1,25 @@ #!/usr/bin/env python ############################################################################## # -# diffpy.srreal by DANSE Diffraction group -# Simon J. L. Billinge -# (c) 2008 The Trustees of Columbia University -# in the City of New York. All rights reserved. +# (c) 2025 The Trustees of Columbia University in the City of New York. +# All rights reserved. # -# File coded by: Pavol Juhas +# File coded by: Billinge Group members and community contributors. # -# See AUTHORS.txt for a list of people who contributed. -# See LICENSE_DANSE.txt for license information. +# See GitHub contributions for a more detailed list of contributors. +# https://github.com/diffpy/diffpy.srreal/graphs/contributors +# +# See LICENSE.rst for license information. # ############################################################################## -"""Definitions of version-related constants and of libdiffpy_version_info. - -Notes ------ -Variable `__gitsha__` is deprecated as of version 1.3. -Use `__git_commit__` instead. - -Variable `libdiffpy_version_info.git_sha` is deprecated as of version 1.4.0. -Use `libdiffpy_version_info.git_commit` instead. -""" - -__all__ = ["__date__", "__git_commit__", "__timestamp__", "__version__", "libdiffpy_version_info"] - - -from diffpy.srreal._version_data import __date__, __git_commit__, __timestamp__, __version__ - -# TODO remove deprecated __gitsha__ in version 1.4. -__gitsha__ = __git_commit__ - -# version information on the active libdiffpy shared library ----------------- +"""Definition of __version__.""" -from collections import namedtuple +# We do not use the other three variables, but can be added back if needed. +# __all__ = ["__date__", "__git_commit__", "__timestamp__", "__version__"] -from diffpy.srreal.srreal_ext import _get_libdiffpy_version_info_dict +# obtain version information +from importlib.metadata import version -libdiffpy_version_info = namedtuple( - "libdiffpy_version_info", - "major minor micro patch version_number version date git_commit " + - # TODO remove git_sha in version 1.4. - "git_sha", -) -vd = _get_libdiffpy_version_info_dict() -libdiffpy_version_info = libdiffpy_version_info( - version=vd["version_str"], - version_number=vd["version"], - major=vd["major"], - minor=vd["minor"], - micro=vd["micro"], - patch=vd["patch"], - date=vd["date"], - git_commit=vd["git_commit"], - # TODO remove git_sha in version 1.4. - git_sha=vd["git_commit"], -) -del vd +__version__ = version("diffpy.srreal") # End of file From d2354a46a40972867b2d19ad6d6fce58345e8c07 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Sat, 11 Jan 2025 05:12:30 -0500 Subject: [PATCH 21/55] pyproject.toml --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 79c72f03..26eafc62 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,8 +11,8 @@ authors = [ maintainers = [ { name="Simon J.L. Billinge group", email="simon.billinge@gmail.com" }, ] -description = "calculators for PDF, bond valence sum, and other quantities based on atom pair interaction" -keywords = ['PDF BVS atom overlap calculator real-space'] +description = "Calculators for PDF, bond valence sum, and other quantities based on atom pair interaction." +keywords = ['PDF', 'BVS', 'atom', 'overlap', 'calculator', 'real-space'] readme = "README.rst" requires-python = ">=3.11, <3.14" classifiers = [ From 178507aad25b9502879f30cfc3ff1d70321747ce Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Sat, 11 Jan 2025 05:16:58 -0500 Subject: [PATCH 22/55] pcmt --- .github/workflows/build-wheel-release-upload.yml | 2 +- .github/workflows/check-news-item.yml | 2 +- AUTHORS.rst | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-wheel-release-upload.yml b/.github/workflows/build-wheel-release-upload.yml index f6486717..f751e848 100644 --- a/.github/workflows/build-wheel-release-upload.yml +++ b/.github/workflows/build-wheel-release-upload.yml @@ -4,7 +4,7 @@ on: workflow_dispatch: push: tags: - - '*' # Trigger on all tags initially, but tag and release privilege are verified in _build-wheel-release-upload.yml + - "*" # Trigger on all tags initially, but tag and release privilege are verified in _build-wheel-release-upload.yml jobs: release: diff --git a/.github/workflows/check-news-item.yml b/.github/workflows/check-news-item.yml index 3f68c3b4..26108723 100644 --- a/.github/workflows/check-news-item.yml +++ b/.github/workflows/check-news-item.yml @@ -3,7 +3,7 @@ name: Check for News on: pull_request_target: branches: - - main + - main jobs: check-news-item: diff --git a/AUTHORS.rst b/AUTHORS.rst index 84a4bac1..ad15dbc7 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -1,8 +1,8 @@ Authors ======= -Pavol Juhas, -Chris Farrow, +Pavol Juhas, +Chris Farrow, Simon J.L. Billinge Contributors From 50e6e8120fbd1d3019c46faa67b5de6e28bd5488 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Sat, 1 Feb 2025 19:31:12 -0500 Subject: [PATCH 23/55] srreal windows support --- requirements/conda.txt | 1 + setup.py | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/requirements/conda.txt b/requirements/conda.txt index f4e764df..dbaae37e 100644 --- a/requirements/conda.txt +++ b/requirements/conda.txt @@ -6,3 +6,4 @@ diffpy.structure gsl # periodictable # pyobjcryst (up to py3.11 for mac) +# dlfcn-win32 (for windows) diff --git a/setup.py b/setup.py index 6c322f3e..784b57c6 100644 --- a/setup.py +++ b/setup.py @@ -47,14 +47,21 @@ def get_boost_config(): lib = Path(conda_prefix) / "lib" return {"include_dirs": [str(inc)], "library_dirs": [str(lib)]} +if os.name == "nt": + compile_args = ["/std:c++14"] + macros = [("_USE_MATH_DEFINES", None)] +else: + compile_args = ["-std=c++11"] + macros = [] boost_cfg = get_boost_config() ext_kws = { "libraries": ["diffpy"] + get_boost_libraries(), - "extra_compile_args": ["-std=c++11"], + "extra_compile_args": compile_args, "extra_link_args": [], "include_dirs": [numpy.get_include()] + boost_cfg["include_dirs"], "library_dirs": boost_cfg["library_dirs"], + "define_macros": macros, } From b83ee8fa121043b94d2e3f3900bd1cb540eddd26 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 2 Feb 2025 00:35:19 +0000 Subject: [PATCH 24/55] [pre-commit.ci] auto fixes from pre-commit hooks --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 784b57c6..f5b929f2 100644 --- a/setup.py +++ b/setup.py @@ -47,6 +47,7 @@ def get_boost_config(): lib = Path(conda_prefix) / "lib" return {"include_dirs": [str(inc)], "library_dirs": [str(lib)]} + if os.name == "nt": compile_args = ["/std:c++14"] macros = [("_USE_MATH_DEFINES", None)] From d863058ed3089b281aeb8f5576eb4e8bf95395b2 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 18 Jun 2025 10:54:29 -0400 Subject: [PATCH 25/55] skpkg: pc autofixes with updated config files --- .flake8 | 2 +- .isort.cfg | 2 +- .pre-commit-config.yaml | 1 - src/diffpy/srreal/bondcalculator.py | 5 ++++- src/diffpy/srreal/bvscalculator.py | 5 ++++- src/diffpy/srreal/overlapcalculator.py | 5 ++++- src/diffpy/srreal/pdfcalculator.py | 26 ++++++++++++++++++---- src/diffpy/srreal/peakprofile.py | 6 ++++- src/diffpy/srreal/peakwidthmodel.py | 7 +++++- src/diffpy/srreal/scatteringfactortable.py | 8 ++++++- tests/test_atomradiitable.py | 6 ++++- tests/test_bondcalculator.py | 6 ++++- tests/test_overlapcalculator.py | 6 ++++- tests/test_pdfbaseline.py | 7 +++++- tests/test_pdfcalculator.py | 7 +++++- tests/test_peakwidthmodel.py | 6 ++++- tests/test_structureadapter.py | 5 ++++- 17 files changed, 90 insertions(+), 20 deletions(-) diff --git a/.flake8 b/.flake8 index 04d2d0b0..7b2865c1 100644 --- a/.flake8 +++ b/.flake8 @@ -7,7 +7,7 @@ exclude = build, dist, doc/source/conf.py -max-line-length = 115 +max-line-length = 79 # Ignore some style 'errors' produced while formatting by 'black' # https://black.readthedocs.io/en/stable/guides/using_black_with_other_tools.html#labels-why-pycodestyle-warnings extend-ignore = E203 diff --git a/.isort.cfg b/.isort.cfg index 7ce0fb1f..86f162b8 100644 --- a/.isort.cfg +++ b/.isort.cfg @@ -1,5 +1,5 @@ [settings] # Keep import statement below line_length character limit -line_length = 115 +line_length = 79 multi_line_output = 3 include_trailing_comma = True diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 754e5329..0e4a84d1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,7 +14,6 @@ repos: rev: v4.6.0 hooks: - id: check-yaml - exclude: ^conda-recipe/meta\.yaml$ - id: end-of-file-fixer - id: trailing-whitespace - id: check-case-conflict diff --git a/src/diffpy/srreal/bondcalculator.py b/src/diffpy/srreal/bondcalculator.py index 2d9a68de..281ea7d5 100644 --- a/src/diffpy/srreal/bondcalculator.py +++ b/src/diffpy/srreal/bondcalculator.py @@ -19,7 +19,10 @@ __all__ = ["BondCalculator"] from diffpy.srreal.srreal_ext import BondCalculator -from diffpy.srreal.wraputils import propertyFromExtDoubleAttr, setattrFromKeywordArguments +from diffpy.srreal.wraputils import ( + propertyFromExtDoubleAttr, + setattrFromKeywordArguments, +) # property wrappers to C++ double attributes diff --git a/src/diffpy/srreal/bvscalculator.py b/src/diffpy/srreal/bvscalculator.py index 7cc1bced..82ff5a3c 100644 --- a/src/diffpy/srreal/bvscalculator.py +++ b/src/diffpy/srreal/bvscalculator.py @@ -19,7 +19,10 @@ __all__ = ["BVSCalculator"] from diffpy.srreal.srreal_ext import BVSCalculator -from diffpy.srreal.wraputils import propertyFromExtDoubleAttr, setattrFromKeywordArguments +from diffpy.srreal.wraputils import ( + propertyFromExtDoubleAttr, + setattrFromKeywordArguments, +) # Property wrappers to C++ double attributes diff --git a/src/diffpy/srreal/overlapcalculator.py b/src/diffpy/srreal/overlapcalculator.py index 9747a221..ab41037a 100644 --- a/src/diffpy/srreal/overlapcalculator.py +++ b/src/diffpy/srreal/overlapcalculator.py @@ -19,7 +19,10 @@ __all__ = ["OverlapCalculator"] from diffpy.srreal.srreal_ext import OverlapCalculator -from diffpy.srreal.wraputils import propertyFromExtDoubleAttr, setattrFromKeywordArguments +from diffpy.srreal.wraputils import ( + propertyFromExtDoubleAttr, + setattrFromKeywordArguments, +) # property wrappers to C++ double attributes diff --git a/src/diffpy/srreal/pdfcalculator.py b/src/diffpy/srreal/pdfcalculator.py index b1c9d125..e24b3e5b 100644 --- a/src/diffpy/srreal/pdfcalculator.py +++ b/src/diffpy/srreal/pdfcalculator.py @@ -18,8 +18,16 @@ PDFCalculator -- calculate PDF by peak summation in real space """ -from diffpy.srreal.srreal_ext import DebyePDFCalculator, PDFCalculator, fftftog, fftgtof -from diffpy.srreal.wraputils import propertyFromExtDoubleAttr, setattrFromKeywordArguments +from diffpy.srreal.srreal_ext import ( + DebyePDFCalculator, + PDFCalculator, + fftftog, + fftgtof, +) +from diffpy.srreal.wraputils import ( + propertyFromExtDoubleAttr, + setattrFromKeywordArguments, +) # exported items __all__ = """ @@ -28,7 +36,12 @@ """.split() # imports for backward compatibility -from diffpy.srreal.pdfbaseline import LinearBaseline, PDFBaseline, ZeroBaseline, makePDFBaseline +from diffpy.srreal.pdfbaseline import ( + LinearBaseline, + PDFBaseline, + ZeroBaseline, + makePDFBaseline, +) from diffpy.srreal.pdfenvelope import ( PDFEnvelope, QResolutionEnvelope, @@ -38,7 +51,12 @@ makePDFEnvelope, ) from diffpy.srreal.peakprofile import PeakProfile -from diffpy.srreal.peakwidthmodel import ConstantPeakWidth, DebyeWallerPeakWidth, JeongPeakWidth, PeakWidthModel +from diffpy.srreal.peakwidthmodel import ( + ConstantPeakWidth, + DebyeWallerPeakWidth, + JeongPeakWidth, + PeakWidthModel, +) # silence the pyflakes syntax checker assert all((fftftog, fftgtof)) diff --git a/src/diffpy/srreal/peakprofile.py b/src/diffpy/srreal/peakprofile.py index ff1044f7..7692e1d7 100644 --- a/src/diffpy/srreal/peakprofile.py +++ b/src/diffpy/srreal/peakprofile.py @@ -23,7 +23,11 @@ __all__ = ["PeakProfile", "GaussianProfile", "CroppedGaussianProfile"] from diffpy.srreal import _final_imports -from diffpy.srreal.srreal_ext import CroppedGaussianProfile, GaussianProfile, PeakProfile +from diffpy.srreal.srreal_ext import ( + CroppedGaussianProfile, + GaussianProfile, + PeakProfile, +) from diffpy.srreal.wraputils import propertyFromExtDoubleAttr # class PeakProfile ---------------------------------------------------------- diff --git a/src/diffpy/srreal/peakwidthmodel.py b/src/diffpy/srreal/peakwidthmodel.py index cb0acb9b..c5884979 100644 --- a/src/diffpy/srreal/peakwidthmodel.py +++ b/src/diffpy/srreal/peakwidthmodel.py @@ -23,7 +23,12 @@ __all__ = ["PeakWidthModel", "ConstantPeakWidth", "DebyeWallerPeakWidth", "JeongPeakWidth"] from diffpy.srreal import _final_imports -from diffpy.srreal.srreal_ext import ConstantPeakWidth, DebyeWallerPeakWidth, JeongPeakWidth, PeakWidthModel +from diffpy.srreal.srreal_ext import ( + ConstantPeakWidth, + DebyeWallerPeakWidth, + JeongPeakWidth, + PeakWidthModel, +) from diffpy.srreal.wraputils import propertyFromExtDoubleAttr # class PeakWidthModel ------------------------------------------------------- diff --git a/src/diffpy/srreal/scatteringfactortable.py b/src/diffpy/srreal/scatteringfactortable.py index a53ce546..b98fcb39 100644 --- a/src/diffpy/srreal/scatteringfactortable.py +++ b/src/diffpy/srreal/scatteringfactortable.py @@ -20,7 +20,13 @@ __all__ = ["ScatteringFactorTable", "SFTXray", "SFTElectron", "SFTNeutron", "SFTElectronNumber", "SFAverage"] from diffpy.srreal.sfaverage import SFAverage -from diffpy.srreal.srreal_ext import ScatteringFactorTable, SFTElectron, SFTElectronNumber, SFTNeutron, SFTXray +from diffpy.srreal.srreal_ext import ( + ScatteringFactorTable, + SFTElectron, + SFTElectronNumber, + SFTNeutron, + SFTXray, +) # Pickling Support ----------------------------------------------------------- diff --git a/tests/test_atomradiitable.py b/tests/test_atomradiitable.py index 158a6f4d..c69b6ed3 100644 --- a/tests/test_atomradiitable.py +++ b/tests/test_atomradiitable.py @@ -8,7 +8,11 @@ import pytest -from diffpy.srreal.atomradiitable import AtomRadiiTable, ConstantRadiiTable, CovalentRadiiTable +from diffpy.srreal.atomradiitable import ( + AtomRadiiTable, + ConstantRadiiTable, + CovalentRadiiTable, +) # ---------------------------------------------------------------------------- diff --git a/tests/test_bondcalculator.py b/tests/test_bondcalculator.py index cd69fe55..808b6390 100644 --- a/tests/test_bondcalculator.py +++ b/tests/test_bondcalculator.py @@ -8,7 +8,11 @@ import numpy import pytest -from testutils import loadDiffPyStructure, loadObjCrystCrystal, pickle_with_attr +from testutils import ( + loadDiffPyStructure, + loadObjCrystCrystal, + pickle_with_attr, +) from diffpy.srreal.bondcalculator import BondCalculator diff --git a/tests/test_overlapcalculator.py b/tests/test_overlapcalculator.py index 5a7a2040..07c0bd91 100644 --- a/tests/test_overlapcalculator.py +++ b/tests/test_overlapcalculator.py @@ -9,7 +9,11 @@ import numpy import pytest -from testutils import loadDiffPyStructure, loadObjCrystCrystal, pickle_with_attr +from testutils import ( + loadDiffPyStructure, + loadObjCrystCrystal, + pickle_with_attr, +) from diffpy.srreal.atomradiitable import CovalentRadiiTable from diffpy.srreal.overlapcalculator import OverlapCalculator diff --git a/tests/test_pdfbaseline.py b/tests/test_pdfbaseline.py index 20535ce5..d07f6880 100644 --- a/tests/test_pdfbaseline.py +++ b/tests/test_pdfbaseline.py @@ -9,7 +9,12 @@ import numpy from testutils import pickle_with_attr -from diffpy.srreal.pdfbaseline import LinearBaseline, PDFBaseline, ZeroBaseline, makePDFBaseline +from diffpy.srreal.pdfbaseline import ( + LinearBaseline, + PDFBaseline, + ZeroBaseline, + makePDFBaseline, +) from diffpy.srreal.pdfcalculator import PDFCalculator # ---------------------------------------------------------------------------- diff --git a/tests/test_pdfcalculator.py b/tests/test_pdfcalculator.py index ef45a6ba..f1c9c383 100644 --- a/tests/test_pdfcalculator.py +++ b/tests/test_pdfcalculator.py @@ -7,7 +7,12 @@ import unittest import numpy -from testutils import _maxNormDiff, datafile, loadDiffPyStructure, pickle_with_attr +from testutils import ( + _maxNormDiff, + datafile, + loadDiffPyStructure, + pickle_with_attr, +) from diffpy.srreal.pdfcalculator import PDFCalculator, fftftog, fftgtof diff --git a/tests/test_peakwidthmodel.py b/tests/test_peakwidthmodel.py index 6c83cd15..e6566e99 100644 --- a/tests/test_peakwidthmodel.py +++ b/tests/test_peakwidthmodel.py @@ -10,7 +10,11 @@ from testutils import loadDiffPyStructure from diffpy.srreal.pdfcalculator import DebyePDFCalculator, PDFCalculator -from diffpy.srreal.peakwidthmodel import DebyeWallerPeakWidth, JeongPeakWidth, PeakWidthModel +from diffpy.srreal.peakwidthmodel import ( + DebyeWallerPeakWidth, + JeongPeakWidth, + PeakWidthModel, +) from diffpy.srreal.structureadapter import createStructureAdapter # ---------------------------------------------------------------------------- diff --git a/tests/test_structureadapter.py b/tests/test_structureadapter.py index 697c355c..384421f7 100644 --- a/tests/test_structureadapter.py +++ b/tests/test_structureadapter.py @@ -55,7 +55,10 @@ def test_createStructureAdapter(self): def test_createStructureAdapterTypes(self): """Check types returned by conversion from diffpy.structure.""" - from diffpy.srreal.structureconverters import DiffPyStructureAtomicAdapter, DiffPyStructurePeriodicAdapter + from diffpy.srreal.structureconverters import ( + DiffPyStructureAtomicAdapter, + DiffPyStructurePeriodicAdapter, + ) adpt = createStructureAdapter(self.nickel) self.assertTrue(type(adpt) is DiffPyStructurePeriodicAdapter) From 7a64d9d9acb91c43fcd4b2296382ed59c447b39f Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 18 Jun 2025 10:56:07 -0400 Subject: [PATCH 26/55] chore: news --- news/pre-commit-auto.rst | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 news/pre-commit-auto.rst diff --git a/news/pre-commit-auto.rst b/news/pre-commit-auto.rst new file mode 100644 index 00000000..e720e3b2 --- /dev/null +++ b/news/pre-commit-auto.rst @@ -0,0 +1,23 @@ +**Added:** + +* Update linelength to sk-package standard of 79 characters. + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* From 2ef09a4567f659c8392c78d3a4b536bd2480a470 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 18 Jun 2025 16:21:08 -0400 Subject: [PATCH 27/55] chore: change to run on macos instead of ubuntu --- .github/workflows/tests-on-pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests-on-pr.yml b/.github/workflows/tests-on-pr.yml index dfdbc776..6e49d1f1 100644 --- a/.github/workflows/tests-on-pr.yml +++ b/.github/workflows/tests-on-pr.yml @@ -14,7 +14,7 @@ jobs: run: shell: bash -l {0} - runs-on: ubuntu-latest + runs-on: macos-14 steps: - name: Check out diffpy.srreal uses: actions/checkout@v4 From 2c7bf1f28d422d02ecd84c3f14eb58d38dda0ff2 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Fri, 20 Jun 2025 15:37:31 -0500 Subject: [PATCH 28/55] find objcryst --- setup.py | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index f5b929f2..5cdbbb1d 100644 --- a/setup.py +++ b/setup.py @@ -48,20 +48,46 @@ def get_boost_config(): return {"include_dirs": [str(inc)], "library_dirs": [str(lib)]} +def get_objcryst_libraries(): + conda_prefix = os.environ.get("CONDA_PREFIX") + if not conda_prefix: + raise EnvironmentError( + "CONDA_PREFIX is not set. Please install ObjCryst using conda and activate the environment." + ) + if os.name == "nt": + libdir = Path(conda_prefix) / "Library" / "lib" + else: + libdir = Path(conda_prefix) / "lib" + + libs = [] + for fn in os.listdir(libdir): + low = fn.lower() + if "objcryst" in low: + libs.append(os.path.splitext(fn)[0]) + if not libs: + raise RuntimeError(f"No ObjCryst libraries found in {libdir}") + return libs + + if os.name == "nt": compile_args = ["/std:c++14"] macros = [("_USE_MATH_DEFINES", None)] + extra_link_args = ["/FORCE:MULTIPLE"] else: compile_args = ["-std=c++11"] macros = [] + extra_link_args = [] boost_cfg = get_boost_config() +objcryst_libs = get_objcryst_libraries() + ext_kws = { - "libraries": ["diffpy"] + get_boost_libraries(), + "libraries": ["diffpy"] + get_boost_libraries() + objcryst_libs, "extra_compile_args": compile_args, - "extra_link_args": [], + "extra_link_args": extra_link_args, "include_dirs": [numpy.get_include()] + boost_cfg["include_dirs"], "library_dirs": boost_cfg["library_dirs"], + "runtime_library_dirs": boost_cfg["library_dirs"], "define_macros": macros, } From 99cd3d382b769190b190f7d3286efdcaa9b18fef Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 20 Jun 2025 20:38:59 +0000 Subject: [PATCH 29/55] [pre-commit.ci] auto fixes from pre-commit hooks --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 5cdbbb1d..d25ba1d7 100644 --- a/setup.py +++ b/setup.py @@ -72,7 +72,7 @@ def get_objcryst_libraries(): if os.name == "nt": compile_args = ["/std:c++14"] macros = [("_USE_MATH_DEFINES", None)] - extra_link_args = ["/FORCE:MULTIPLE"] + extra_link_args = ["/FORCE:MULTIPLE"] else: compile_args = ["-std=c++11"] macros = [] From 12481e9ac78d9cf27a54beedd4769d6e40afeafd Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Sun, 22 Jun 2025 14:56:48 -0500 Subject: [PATCH 30/55] update conda requirements, correct objcryst flag --- requirements/conda.txt | 11 ++++------- setup.py | 11 ++++++++--- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/requirements/conda.txt b/requirements/conda.txt index dbaae37e..0f11dbec 100644 --- a/requirements/conda.txt +++ b/requirements/conda.txt @@ -1,9 +1,6 @@ -boost -numpy libdiffpy -setuptools +libboost-devel +libobjcryst +pyobjcryst diffpy.structure -gsl -# periodictable -# pyobjcryst (up to py3.11 for mac) -# dlfcn-win32 (for windows) +periodictable diff --git a/setup.py b/setup.py index d25ba1d7..c16945fe 100644 --- a/setup.py +++ b/setup.py @@ -61,9 +61,14 @@ def get_objcryst_libraries(): libs = [] for fn in os.listdir(libdir): - low = fn.lower() - if "objcryst" in low: - libs.append(os.path.splitext(fn)[0]) + stem = Path(fn).stem + if "objcryst" not in stem.lower(): + continue + # strip a leading "lib" so that setuptools does -lObjCryst, not -llibObjCryst + if stem.startswith("lib"): + stem = stem[3:] + libs.append(stem) + if not libs: raise RuntimeError(f"No ObjCryst libraries found in {libdir}") return libs From cabdcc705aa7ae3ee7f2a69b0ea166f14ad7ddc0 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Sun, 22 Jun 2025 15:00:18 -0500 Subject: [PATCH 31/55] force libdiffpy rc version --- requirements/conda.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/conda.txt b/requirements/conda.txt index 0f11dbec..a9b021c0 100644 --- a/requirements/conda.txt +++ b/requirements/conda.txt @@ -1,4 +1,4 @@ -libdiffpy +libdiffpy=1.4.1rc1 libboost-devel libobjcryst pyobjcryst From fa597f8403e5ba5874fe8164c33ec36731313671 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Sun, 22 Jun 2025 15:10:08 -0500 Subject: [PATCH 32/55] update tests --- .github/workflows/tests-on-pr.yml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tests-on-pr.yml b/.github/workflows/tests-on-pr.yml index 6e49d1f1..ed07dd15 100644 --- a/.github/workflows/tests-on-pr.yml +++ b/.github/workflows/tests-on-pr.yml @@ -14,7 +14,13 @@ jobs: run: shell: bash -l {0} - runs-on: macos-14 + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macos-13, macos-14] + python-version: [3.11, 3.12, 3.13] + steps: - name: Check out diffpy.srreal uses: actions/checkout@v4 @@ -26,7 +32,7 @@ jobs: auto-update-conda: true environment-file: environment.yml auto-activate-base: false - python-version: 3.12 + python-version: ${{ matrix.python-version }} - name: Conda config run: >- @@ -35,8 +41,8 @@ jobs: - name: Install diffpy.srreal and requirements run: | + conda install --file requirements/conda.txt conda install --file requirements/test.txt - conda install boost numpy libdiffpy setuptools diffpy.structure periodictable gsl python -m pip install . --no-deps - name: Validate diffpy.pdfgui From 170f9c9aaf98f6d853ef48957d183a1a458932cb Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Sun, 22 Jun 2025 15:18:04 -0500 Subject: [PATCH 33/55] try removing extra insurance --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index c16945fe..dd48ed93 100644 --- a/setup.py +++ b/setup.py @@ -92,7 +92,7 @@ def get_objcryst_libraries(): "extra_link_args": extra_link_args, "include_dirs": [numpy.get_include()] + boost_cfg["include_dirs"], "library_dirs": boost_cfg["library_dirs"], - "runtime_library_dirs": boost_cfg["library_dirs"], + # "runtime_library_dirs": boost_cfg["library_dirs"], "define_macros": macros, } From a86ab582eebaac9ac2e474208def563b89daa703 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Sun, 22 Jun 2025 15:26:05 -0500 Subject: [PATCH 34/55] make MSVC linker happy --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index dd48ed93..fb542c23 100644 --- a/setup.py +++ b/setup.py @@ -65,7 +65,7 @@ def get_objcryst_libraries(): if "objcryst" not in stem.lower(): continue # strip a leading "lib" so that setuptools does -lObjCryst, not -llibObjCryst - if stem.startswith("lib"): + if os.name != "nt" and stem.startswith("lib"): stem = stem[3:] libs.append(stem) From d3ecb25e99f5ffd6370df9c1d449e0b9677eaf05 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Mon, 23 Jun 2025 11:56:46 -0400 Subject: [PATCH 35/55] skpkg: change black line length requirements to 79 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 26eafc62..4aecbc54 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -57,7 +57,7 @@ ignore-words = ".codespell/ignore_words.txt" skip = "*.cif,*.dat" [tool.black] -line-length = 115 +line-length = 79 include = '\.pyi?$' exclude = ''' /( From 703588bac78cb83601582585b00889e09531f1a6 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Mon, 23 Jun 2025 11:57:46 -0400 Subject: [PATCH 36/55] skpkg: autofixes with linelength 79 --- doc/source/examples/distanceprinter.py | 5 +- doc/source/examples/parallelPDF.py | 6 ++- setup.py | 9 +++- .../srreal/devutils/tunePeakPrecision.py | 9 +++- src/diffpy/srreal/parallel.py | 4 +- src/diffpy/srreal/pdfbaseline.py | 4 +- src/diffpy/srreal/pdfenvelope.py | 4 +- src/diffpy/srreal/peakwidthmodel.py | 7 ++- src/diffpy/srreal/scatteringfactortable.py | 9 +++- src/diffpy/srreal/sfaverage.py | 6 ++- src/diffpy/srreal/structureconverters.py | 16 ++++-- src/diffpy/srreal/wraputils.py | 8 ++- tests/conftest.py | 4 +- tests/test_bondcalculator.py | 10 +++- tests/test_debyepdfcalculator.py | 8 ++- tests/test_overlapcalculator.py | 17 ++++-- tests/test_parallel.py | 12 +++-- tests/test_pdfbaseline.py | 52 +++++++++++++++---- tests/test_pdfcalcobjcryst.py | 12 +++-- tests/test_pdfcalculator.py | 8 ++- tests/test_pdfenvelope.py | 17 ++++-- tests/test_peakprofile.py | 4 +- tests/test_peakwidthmodel.py | 8 ++- tests/test_scatteringfactortable.py | 12 ++++- tests/test_sfaverage.py | 4 +- tests/test_structureadapter.py | 31 +++++++++-- tests/testutils.py | 8 ++- 27 files changed, 232 insertions(+), 62 deletions(-) diff --git a/doc/source/examples/distanceprinter.py b/doc/source/examples/distanceprinter.py index a4b95984..374cf25e 100755 --- a/doc/source/examples/distanceprinter.py +++ b/doc/source/examples/distanceprinter.py @@ -16,7 +16,10 @@ def _resetValue(self): def _addPairContribution(self, bnds, sumscale): self.count += bnds.multiplicity() * sumscale / 2.0 - print("%i %g %i %i" % (self.count, bnds.distance(), bnds.site0(), bnds.site1())) + print( + "%i %g %i %i" + % (self.count, bnds.distance(), bnds.site0(), bnds.site1()) + ) return diff --git a/doc/source/examples/parallelPDF.py b/doc/source/examples/parallelPDF.py index 30516398..ebf26b01 100755 --- a/doc/source/examples/parallelPDF.py +++ b/doc/source/examples/parallelPDF.py @@ -25,7 +25,11 @@ # configure options parsing parser = optparse.OptionParser("%prog [options]\n" + __doc__) -parser.add_option("--pyobjcryst", action="store_true", help="Use pyobjcryst to load the CIF file.") +parser.add_option( + "--pyobjcryst", + action="store_true", + help="Use pyobjcryst to load the CIF file.", +) parser.allow_interspersed_args = True opts, args = parser.parse_args(sys.argv[1:]) diff --git a/setup.py b/setup.py index fb542c23..fe548047 100644 --- a/setup.py +++ b/setup.py @@ -37,7 +37,8 @@ def get_boost_config(): conda_prefix = os.environ.get("CONDA_PREFIX") if not conda_prefix: raise EnvironmentError( - "Neither BOOST_PATH nor CONDA_PREFIX are set. " "Please install Boost or set BOOST_PATH." + "Neither BOOST_PATH nor CONDA_PREFIX are set. " + "Please install Boost or set BOOST_PATH." ) if os.name == "nt": inc = Path(conda_prefix) / "Library" / "include" @@ -99,7 +100,11 @@ def get_objcryst_libraries(): def create_extensions(): "Initialize Extension objects for the setup function." - ext = Extension("diffpy.srreal.srreal_ext", glob.glob("src/extensions/*.cpp"), **ext_kws) + ext = Extension( + "diffpy.srreal.srreal_ext", + glob.glob("src/extensions/*.cpp"), + **ext_kws, + ) return [ext] diff --git a/src/diffpy/srreal/devutils/tunePeakPrecision.py b/src/diffpy/srreal/devutils/tunePeakPrecision.py index c6f3cc94..247d7018 100755 --- a/src/diffpy/srreal/devutils/tunePeakPrecision.py +++ b/src/diffpy/srreal/devutils/tunePeakPrecision.py @@ -108,7 +108,9 @@ def comparePDFCalculators(qmax, peakprecision=None): rv = {} rv["qmax"] = qmax rv["peakprecision"] = ( - peakprecision is None and PDFCalculator()._getDoubleAttr("peakprecision") or peakprecision + peakprecision is None + and PDFCalculator()._getDoubleAttr("peakprecision") + or peakprecision ) ttic = time.clock() rg0 = Gpdffit2(qmax) @@ -175,7 +177,10 @@ def main(): processCommandLineArguments() cmpdata = comparePDFCalculators(qmax, peakprecision) print( - ("qmax = %(qmax)g pkprec = %(peakprecision)g " + "grmsd = %(grmsd)g t0 = %(t0).3f t1 = %(t1).3f") + ( + "qmax = %(qmax)g pkprec = %(peakprecision)g " + + "grmsd = %(grmsd)g t0 = %(t0).3f t1 = %(t1).3f" + ) % cmpdata ) if createplot: diff --git a/src/diffpy/srreal/parallel.py b/src/diffpy/srreal/parallel.py index 5ab113ee..87b8a76e 100644 --- a/src/diffpy/srreal/parallel.py +++ b/src/diffpy/srreal/parallel.py @@ -163,7 +163,9 @@ def proxymethod(self, *args, **kwargs): return proxymethod for n, f in inspect.getmembers(pqtype, inspect.isroutine): - ignore = n not in proxy_forced and (n.startswith("_") or hasattr(ParallelPairQuantity, n)) + ignore = n not in proxy_forced and ( + n.startswith("_") or hasattr(ParallelPairQuantity, n) + ) if ignore: continue setattr(ParallelPairQuantity, n, _make_proxymethod(n, f)) diff --git a/src/diffpy/srreal/pdfbaseline.py b/src/diffpy/srreal/pdfbaseline.py index 22ced38b..0769c2d2 100644 --- a/src/diffpy/srreal/pdfbaseline.py +++ b/src/diffpy/srreal/pdfbaseline.py @@ -85,7 +85,9 @@ def fshiftedline(x, aline, bline): """ from diffpy.srreal.wraputils import _wrapAsRegisteredUnaryFunction - rv = _wrapAsRegisteredUnaryFunction(PDFBaseline, name, fnc, replace=replace, **dbattrs) + rv = _wrapAsRegisteredUnaryFunction( + PDFBaseline, name, fnc, replace=replace, **dbattrs + ) return rv diff --git a/src/diffpy/srreal/pdfenvelope.py b/src/diffpy/srreal/pdfenvelope.py index 594e80d9..76582dfa 100644 --- a/src/diffpy/srreal/pdfenvelope.py +++ b/src/diffpy/srreal/pdfenvelope.py @@ -115,7 +115,9 @@ def fexpdecay(x, expscale, exptail): """ from diffpy.srreal.wraputils import _wrapAsRegisteredUnaryFunction - rv = _wrapAsRegisteredUnaryFunction(PDFEnvelope, name, fnc, replace=replace, **dbattrs) + rv = _wrapAsRegisteredUnaryFunction( + PDFEnvelope, name, fnc, replace=replace, **dbattrs + ) return rv diff --git a/src/diffpy/srreal/peakwidthmodel.py b/src/diffpy/srreal/peakwidthmodel.py index c5884979..7c73e8e8 100644 --- a/src/diffpy/srreal/peakwidthmodel.py +++ b/src/diffpy/srreal/peakwidthmodel.py @@ -20,7 +20,12 @@ # exported items -__all__ = ["PeakWidthModel", "ConstantPeakWidth", "DebyeWallerPeakWidth", "JeongPeakWidth"] +__all__ = [ + "PeakWidthModel", + "ConstantPeakWidth", + "DebyeWallerPeakWidth", + "JeongPeakWidth", +] from diffpy.srreal import _final_imports from diffpy.srreal.srreal_ext import ( diff --git a/src/diffpy/srreal/scatteringfactortable.py b/src/diffpy/srreal/scatteringfactortable.py index b98fcb39..9fa232ac 100644 --- a/src/diffpy/srreal/scatteringfactortable.py +++ b/src/diffpy/srreal/scatteringfactortable.py @@ -17,7 +17,14 @@ # exported items, these also makes them show in pydoc. -__all__ = ["ScatteringFactorTable", "SFTXray", "SFTElectron", "SFTNeutron", "SFTElectronNumber", "SFAverage"] +__all__ = [ + "ScatteringFactorTable", + "SFTXray", + "SFTElectron", + "SFTNeutron", + "SFTElectronNumber", + "SFAverage", +] from diffpy.srreal.sfaverage import SFAverage from diffpy.srreal.srreal_ext import ( diff --git a/src/diffpy/srreal/sfaverage.py b/src/diffpy/srreal/sfaverage.py index 5a1dde4d..636dc974 100644 --- a/src/diffpy/srreal/sfaverage.py +++ b/src/diffpy/srreal/sfaverage.py @@ -150,7 +150,11 @@ def fromComposition(cls, composition, sftb, q=0): sfa.f1sum = 0.0 * q sfa.f2sum = 0.0 * q # resolve the lookup table object `tb` - tb = sftb if not isinstance(sftb, str) else ScatteringFactorTable.createByType(sftb) + tb = ( + sftb + if not isinstance(sftb, str) + else ScatteringFactorTable.createByType(sftb) + ) for smbl, cnt in sfa.composition.items(): sfq = tb.lookup(smbl, q) sfa.f1sum += cnt * sfq diff --git a/src/diffpy/srreal/structureconverters.py b/src/diffpy/srreal/structureconverters.py index c9b844d8..e3e22e1f 100644 --- a/src/diffpy/srreal/structureconverters.py +++ b/src/diffpy/srreal/structureconverters.py @@ -26,8 +26,12 @@ # Converters for Molecule and Crystal from pyobjcryst ------------------------ -RegisterStructureAdapter("pyobjcryst._pyobjcryst.Molecule", convertObjCrystMolecule) -RegisterStructureAdapter("pyobjcryst._pyobjcryst.Crystal", convertObjCrystCrystal) +RegisterStructureAdapter( + "pyobjcryst._pyobjcryst.Molecule", convertObjCrystMolecule +) +RegisterStructureAdapter( + "pyobjcryst._pyobjcryst.Crystal", convertObjCrystCrystal +) # Converter for Structure class from diffpy.structure ------------------------ @@ -115,11 +119,15 @@ def _fetchMetadata(self, stru): # end of class _DiffPyStructureMetadata -class DiffPyStructureAtomicAdapter(_DiffPyStructureMetadata, AtomicStructureAdapter): +class DiffPyStructureAtomicAdapter( + _DiffPyStructureMetadata, AtomicStructureAdapter +): pass -class DiffPyStructurePeriodicAdapter(_DiffPyStructureMetadata, PeriodicStructureAdapter): +class DiffPyStructurePeriodicAdapter( + _DiffPyStructureMetadata, PeriodicStructureAdapter +): pass diff --git a/src/diffpy/srreal/wraputils.py b/src/diffpy/srreal/wraputils.py index a026edd3..b44f76ea 100644 --- a/src/diffpy/srreal/wraputils.py +++ b/src/diffpy/srreal/wraputils.py @@ -59,7 +59,9 @@ def setattrFromKeywordArguments(obj, **kwargs): return -def _wrapAsRegisteredUnaryFunction(cls, regname, fnc, replace=False, **dbattrs): +def _wrapAsRegisteredUnaryFunction( + cls, regname, fnc, replace=False, **dbattrs +): """Helper function for wrapping Python function as PDFBaseline or PDFEnvelope functor. Not intended for direct usage, this function is rather called from makePDFBaseline or makePDFEnvelope wrappers. @@ -149,7 +151,9 @@ def _pickle_getstate(self): def _pickle_setstate(self, state): if len(state) != 1: - emsg = "expected 1-item tuple in call to __setstate__, got " + repr(state) + emsg = "expected 1-item tuple in call to __setstate__, got " + repr( + state + ) raise ValueError(emsg) self.__dict__.update(state[0]) return diff --git a/tests/conftest.py b/tests/conftest.py index ac3c2227..3e0ed938 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -70,6 +70,8 @@ def has_periodictable(): del periodictable except ImportError: has_periodictable = False - logging.warning("Cannot import periodictable, periodictable tests skipped.") + logging.warning( + "Cannot import periodictable, periodictable tests skipped." + ) return has_periodictable diff --git a/tests/test_bondcalculator.py b/tests/test_bondcalculator.py index 808b6390..89eb7f94 100644 --- a/tests/test_bondcalculator.py +++ b/tests/test_bondcalculator.py @@ -134,7 +134,10 @@ def test_sites(self): self.assertEqual(5, numpy.max(bdc.sites0)) self.assertEqual(0, numpy.min(bdc.sites1)) self.assertEqual(5, numpy.max(bdc.sites1)) - dij = [(tuple(d) + (i0, i1)) for d, i0, i1 in zip(bdc.directions, bdc.sites0, bdc.sites1)] + dij = [ + (tuple(d) + (i0, i1)) + for d, i0, i1 in zip(bdc.directions, bdc.sites0, bdc.sites1) + ] self.assertEqual(len(dij), len(set(dij))) bdc.maskAllPairs(False) bdc(self.rutile) @@ -287,7 +290,10 @@ def test_sites(self): self.assertEqual(1, numpy.max(bdc.sites0)) self.assertEqual(0, numpy.min(bdc.sites1)) self.assertEqual(1, numpy.max(bdc.sites1)) - dij = [(tuple(d) + (i0, i1)) for d, i0, i1 in zip(bdc.directions, bdc.sites0, bdc.sites1)] + dij = [ + (tuple(d) + (i0, i1)) + for d, i0, i1 in zip(bdc.directions, bdc.sites0, bdc.sites1) + ] self.assertEqual(len(dij), len(set(dij))) bdc.maskAllPairs(False) bdc(self.rutile) diff --git a/tests/test_debyepdfcalculator.py b/tests/test_debyepdfcalculator.py index 693a7ab5..ff160f88 100644 --- a/tests/test_debyepdfcalculator.py +++ b/tests/test_debyepdfcalculator.py @@ -23,7 +23,9 @@ def setUp(self): if not TestDebyePDFCalculator.bucky: TestDebyePDFCalculator.bucky = loadDiffPyStructure("C60bucky.stru") if not TestDebyePDFCalculator.tio2rutile: - TestDebyePDFCalculator.tio2rutile = loadDiffPyStructure("TiO2_rutile-fit.stru") + TestDebyePDFCalculator.tio2rutile = loadDiffPyStructure( + "TiO2_rutile-fit.stru" + ) return # def tearDown(self): @@ -166,7 +168,9 @@ def test_pickling(self): for a in dpdfc._namesOfDoubleAttributes(): self.assertEqual(getattr(dpdfc, a), getattr(dpdfc1, a)) self.assertEqual(13.3, dpdfc1.getEnvelope("sphericalshape").spdiameter) - self.assertEqual(dpdfc._namesOfDoubleAttributes(), dpdfc1._namesOfDoubleAttributes()) + self.assertEqual( + dpdfc._namesOfDoubleAttributes(), dpdfc1._namesOfDoubleAttributes() + ) self.assertEqual(dpdfc.usedenvelopetypes, dpdfc1.usedenvelopetypes) self.assertRaises(RuntimeError, pickle_with_attr, dpdfc, foo="bar") return diff --git a/tests/test_overlapcalculator.py b/tests/test_overlapcalculator.py index 07c0bd91..ee1de8e8 100644 --- a/tests/test_overlapcalculator.py +++ b/tests/test_overlapcalculator.py @@ -91,7 +91,9 @@ def test_pickling(self): self.assertEqual(getattr(olc, a), getattr(olc1, a)) self.assertFalse(olc1.getPairMask(1, 2)) self.assertTrue(olc1.getPairMask(0, 0)) - self.assertTrue(numpy.array_equal(olc.sitesquareoverlaps, olc1.sitesquareoverlaps)) + self.assertTrue( + numpy.array_equal(olc.sitesquareoverlaps, olc1.sitesquareoverlaps) + ) self.assertRaises(RuntimeError, pickle_with_attr, olc, foo="bar") return @@ -140,13 +142,18 @@ def test_parallel(self): ncpu = 4 self.pool = multiprocessing.Pool(processes=ncpu) olc = self.olc - polc = createParallelCalculator(OverlapCalculator(), ncpu, self.pool.imap_unordered) + polc = createParallelCalculator( + OverlapCalculator(), ncpu, self.pool.imap_unordered + ) olc.atomradiitable.fromString("Ti:1.6, O:0.66") polc.atomradiitable = olc.atomradiitable self.assertTrue(numpy.array_equal(olc(self.rutile), polc(self.rutile))) self.assertTrue(olc.totalsquareoverlap > 0.0) self.assertEqual(olc.totalsquareoverlap, polc.totalsquareoverlap) - self.assertEqual(sorted(zip(olc.sites0, olc.sites1)), sorted(zip(polc.sites0, polc.sites1))) + self.assertEqual( + sorted(zip(olc.sites0, olc.sites1)), + sorted(zip(polc.sites0, polc.sites1)), + ) olc.atomradiitable.resetAll() self.assertEqual(0.0, sum(olc(self.rutile))) self.assertEqual(0.0, sum(polc(self.rutile))) @@ -288,7 +295,9 @@ def test_coordinations(self): self.assertFalse(numpy.any(olc.coordinations)) olc.atomradiitable.fromString("Ti:1.6, O:0.66") olc(self.rutile) - self.assertTrue(numpy.array_equal([8, 8, 3, 3, 3, 3], olc.coordinations)) + self.assertTrue( + numpy.array_equal([8, 8, 3, 3, 3, 3], olc.coordinations) + ) return def test_coordinationByTypes(self): diff --git a/tests/test_parallel.py b/tests/test_parallel.py index 3bc524c6..b4b53b17 100644 --- a/tests/test_parallel.py +++ b/tests/test_parallel.py @@ -54,7 +54,9 @@ def test_parallel_evaluatortype(self): self.assertEqual("BASIC", ppdfc.evaluatortype) self.assertEqual("BASIC", pdfc.evaluatortype) ppdfc.evaluatortype = "BASIC" - self.assertRaises(ValueError, setattr, ppdfc, "evaluatortype", "OPTIMIZED") + self.assertRaises( + ValueError, setattr, ppdfc, "evaluatortype", "OPTIMIZED" + ) return def test_parallel_pdf(self): @@ -67,7 +69,9 @@ def test_parallel_pdf(self): r1, g1 = ppdfc1(self.cdse) self.assertTrue(numpy.array_equal(r0, r1)) self.assertTrue(numpy.allclose(g0, g1)) - ppdfc2 = createParallelCalculator(PDFCalculator(), self.ncpu, self.pool.imap_unordered) + ppdfc2 = createParallelCalculator( + PDFCalculator(), self.ncpu, self.pool.imap_unordered + ) r2, g2 = ppdfc2(self.cdse) self.assertTrue(numpy.array_equal(r0, r2)) self.assertTrue(numpy.allclose(g0, g2)) @@ -94,7 +98,9 @@ def test_parallel_bonds(self): pbc1 = createParallelCalculator(BondCalculator(), 3, map) d1 = pbc1(nickel) self.assertTrue(numpy.array_equal(d0, d1)) - pbc2 = createParallelCalculator(BondCalculator(), self.ncpu, self.pool.imap_unordered) + pbc2 = createParallelCalculator( + BondCalculator(), self.ncpu, self.pool.imap_unordered + ) d2 = pbc2(nickel) self.assertTrue(numpy.array_equal(d0, d2)) bc.rmax = pbc1.rmax = pbc2.rmax = 2.5 diff --git a/tests/test_pdfbaseline.py b/tests/test_pdfbaseline.py index d07f6880..ecf417c0 100644 --- a/tests/test_pdfbaseline.py +++ b/tests/test_pdfbaseline.py @@ -93,8 +93,12 @@ def test_type(self): def test__aliasType(self): """Check PDFBaseline._aliasType.""" self.assertRaises(ValueError, PDFBaseline.createByType, "alias") - self.assertRaises(RuntimeError, PDFBaseline._aliasType, "invalid", "alias") - self.assertRaises(RuntimeError, PDFBaseline._aliasType, "linear", "zero") + self.assertRaises( + RuntimeError, PDFBaseline._aliasType, "invalid", "alias" + ) + self.assertRaises( + RuntimeError, PDFBaseline._aliasType, "linear", "zero" + ) PDFBaseline._aliasType("linear", "alias") bl = PDFBaseline.createByType("alias") self.assertEqual("linear", bl.type()) @@ -104,7 +108,9 @@ def test__aliasType(self): bl1 = PDFBaseline.createByType("alias") self.assertTrue(isinstance(bl1, LinearBaseline)) # no other type can be aliased to the existing name. - self.assertRaises(RuntimeError, PDFBaseline._aliasType, "zero", "alias") + self.assertRaises( + RuntimeError, PDFBaseline._aliasType, "zero", "alias" + ) return def test__deregisterType(self): @@ -118,7 +124,9 @@ def test__deregisterType(self): def test_createByType(self): """Check PDFBaseline.createByType()""" - self.assertRaises(ValueError, PDFBaseline.createByType, "notregistered") + self.assertRaises( + ValueError, PDFBaseline.createByType, "notregistered" + ) return def test_isRegisteredType(self): @@ -136,7 +144,9 @@ def test_getAliasedTypes(self): PDFBaseline._aliasType("linear", "bar") PDFBaseline._aliasType("linear", "linear") PDFBaseline._aliasType("bar", "foo") - self.assertEqual({"bar": "linear", "foo": "linear"}, PDFBaseline.getAliasedTypes()) + self.assertEqual( + {"bar": "linear", "foo": "linear"}, PDFBaseline.getAliasedTypes() + ) return def test_getRegisteredTypes(self): @@ -161,7 +171,9 @@ def test_pickling(self): def test_makePDFBaseline(self): """Check the makePDFBaseline wrapper.""" - pbl = makePDFBaseline("parabolabaseline", parabola_baseline, a=1, b=2, c=3) + pbl = makePDFBaseline( + "parabolabaseline", parabola_baseline, a=1, b=2, c=3 + ) self.assertEqual(3, pbl(0)) self.assertEqual(6, pbl(1)) self.assertEqual(11, pbl(2)) @@ -181,10 +193,28 @@ def test_makePDFBaseline(self): self.assertEqual([7, 3, 28], [pbl4(x) for x in [-2, 0, 5]]) self.assertEqual("bar", pbl4.foo) # fail if this baseline type already exists. - self.assertRaises(RuntimeError, makePDFBaseline, "linear", parabola_baseline, a=1, b=2, c=3) - self.assertRaises(RuntimeError, makePDFBaseline, "parabolabaseline", parabola_baseline, a=1, b=2, c=3) + self.assertRaises( + RuntimeError, + makePDFBaseline, + "linear", + parabola_baseline, + a=1, + b=2, + c=3, + ) + self.assertRaises( + RuntimeError, + makePDFBaseline, + "parabolabaseline", + parabola_baseline, + a=1, + b=2, + c=3, + ) # check replacement of an existing type. - makePDFBaseline("linear", parabola_baseline, replace=True, a=1, b=2, c=4) + makePDFBaseline( + "linear", parabola_baseline, replace=True, a=1, b=2, c=4 + ) pbl4 = PDFBaseline.createByType("linear") self.assertEqual(set(("a", "b", "c")), pbl4._namesOfDoubleAttributes()) self.assertEqual(4, pbl4.c) @@ -196,7 +226,9 @@ def test_makePDFBaseline(self): def test_picking_owned(self): """Verify pickling of PDFBaseline owned by PDF calculators.""" - pbl = makePDFBaseline("parabolabaseline", parabola_baseline, a=1, b=2, c=3) + pbl = makePDFBaseline( + "parabolabaseline", parabola_baseline, a=1, b=2, c=3 + ) pbl.a = 7 pbl.foobar = "asdf" pc = PDFCalculator() diff --git a/tests/test_pdfcalcobjcryst.py b/tests/test_pdfcalcobjcryst.py index 3fd4d4ca..3780558f 100644 --- a/tests/test_pdfcalcobjcryst.py +++ b/tests/test_pdfcalcobjcryst.py @@ -84,19 +84,25 @@ def setself(**kwtoset): def test_CdSeN(self): """Check PDFCalculator on ObjCryst loaded CIF, neutrons.""" - self._comparePDFs("cdsen", "CdSe_cadmoselite_N.fgr", "CdSe_cadmoselite.cif") + self._comparePDFs( + "cdsen", "CdSe_cadmoselite_N.fgr", "CdSe_cadmoselite.cif" + ) self.assertTrue(self.cdsen_mxnd < 0.01) return def test_CdSeX(self): """Check PDFCalculator on ObjCryst loaded CIF, xrays.""" - self._comparePDFs("cdsex", "CdSe_cadmoselite_X.fgr", "CdSe_cadmoselite.cif") + self._comparePDFs( + "cdsex", "CdSe_cadmoselite_X.fgr", "CdSe_cadmoselite.cif" + ) self.assertTrue(self.cdsex_mxnd < 0.01) return def test_rutileaniso(self): """Check PDFCalculator on ObjCryst loaded anisotropic rutile.""" - self._comparePDFs("rutileaniso", "TiO2_rutile-fit.fgr", "TiO2_rutile-fit.cif") + self._comparePDFs( + "rutileaniso", "TiO2_rutile-fit.fgr", "TiO2_rutile-fit.cif" + ) self.assertTrue(self.rutileaniso_mxnd < 0.057) return diff --git a/tests/test_pdfcalculator.py b/tests/test_pdfcalculator.py index f1c9c383..2871acce 100644 --- a/tests/test_pdfcalculator.py +++ b/tests/test_pdfcalculator.py @@ -252,7 +252,9 @@ def test_pickling(self): for a in pdfc._namesOfDoubleAttributes(): self.assertEqual(getattr(pdfc, a), getattr(pdfc1, a)) self.assertEqual(13.3, pdfc1.getEnvelope("sphericalshape").spdiameter) - self.assertEqual(pdfc._namesOfDoubleAttributes(), pdfc1._namesOfDoubleAttributes()) + self.assertEqual( + pdfc._namesOfDoubleAttributes(), pdfc1._namesOfDoubleAttributes() + ) self.assertEqual(pdfc.usedenvelopetypes, pdfc1.usedenvelopetypes) self.assertRaises(RuntimeError, pickle_with_attr, pdfc, foo="bar") return @@ -298,7 +300,9 @@ def test_envelopes(self): self.assertEqual("scale", pc.envelopes[0].type()) pc.envelopes += ("qresolution",) self.assertEqual(("qresolution", "scale"), pc.usedenvelopetypes) - self.assertTrue(all([isinstance(e, PDFEnvelope) for e in pc.envelopes])) + self.assertTrue( + all([isinstance(e, PDFEnvelope) for e in pc.envelopes]) + ) return diff --git a/tests/test_pdfenvelope.py b/tests/test_pdfenvelope.py index 7ea75f4c..901ea01f 100644 --- a/tests/test_pdfenvelope.py +++ b/tests/test_pdfenvelope.py @@ -91,7 +91,9 @@ def test_type(self): def test_createByType(self): """Check PDFEnvelope.createByType()""" - self.assertRaises(ValueError, PDFEnvelope.createByType, "notregistered") + self.assertRaises( + ValueError, PDFEnvelope.createByType, "notregistered" + ) return def test_getRegisteredTypes(self): @@ -114,7 +116,9 @@ def test_pickling(self): def test_makePDFEnvelope(self): """Check the makePDFEnvelope wrapper.""" - pbl = makePDFEnvelope("parabolaenvelope", parabola_envelope, a=1, b=2, c=3) + pbl = makePDFEnvelope( + "parabolaenvelope", parabola_envelope, a=1, b=2, c=3 + ) self.assertEqual(3, pbl(0)) self.assertEqual(6, pbl(1)) self.assertEqual(11, pbl(2)) @@ -138,7 +142,9 @@ def test_makePDFEnvelope(self): def test_picking_owned(self): """Verify pickling of envelopes owned by PDF calculators.""" - pbl = makePDFEnvelope("parabolaenvelope", parabola_envelope, a=1, b=2, c=3) + pbl = makePDFEnvelope( + "parabolaenvelope", parabola_envelope, a=1, b=2, c=3 + ) pbl.a = 7 pbl.foobar = "asdf" pc = PDFCalculator() @@ -156,7 +162,10 @@ def test_picking_owned(self): dbpc2 = pickle.loads(pickle.dumps(dbpc)) self.assertEqual(3.5, pc2.scale) self.assertEqual(3.5, dbpc2.scale) - pblcopies = [pc2.getEnvelope("parabolaenvelope"), dbpc2.getEnvelope("parabolaenvelope")] + pblcopies = [ + pc2.getEnvelope("parabolaenvelope"), + dbpc2.getEnvelope("parabolaenvelope"), + ] for pbl2 in pblcopies: self.assertEqual(7, pbl2.a) self.assertEqual("asdf", pbl2.foobar) diff --git a/tests/test_peakprofile.py b/tests/test_peakprofile.py index 9b739c19..13347735 100644 --- a/tests/test_peakprofile.py +++ b/tests/test_peakprofile.py @@ -28,7 +28,9 @@ def tearDown(self): def test___init__(self): """Check PeakProfile.__init__()""" self.assertNotEqual(0.0, self.pkgauss.peakprecision) - self.assertEqual(self.pkgauss.peakprecision, self.pkcropped.peakprecision) + self.assertEqual( + self.pkgauss.peakprecision, self.pkcropped.peakprecision + ) self.pkgauss._setDoubleAttr("peakprecision", 0.01) self.assertEqual(0.01, self.pkgauss.peakprecision) return diff --git a/tests/test_peakwidthmodel.py b/tests/test_peakwidthmodel.py index e6566e99..3ea3b2e8 100644 --- a/tests/test_peakwidthmodel.py +++ b/tests/test_peakwidthmodel.py @@ -101,7 +101,9 @@ def test_isowidths(self): def test_maxWidth(self): """Check PeakWidthModel.maxWidth()""" - self.assertRaises(RuntimeError, PeakWidthModel().maxWidth, self.tio2adpt, 0, 10) + self.assertRaises( + RuntimeError, PeakWidthModel().maxWidth, self.tio2adpt, 0, 10 + ) self.assertEqual(2.0, self.pwconst.maxWidth(self.tio2adpt, 0, 10)) self.assertEqual(2.0, self.pwconst.maxWidth(self.tio2stru, 0, 10)) return @@ -140,7 +142,9 @@ def test_getRegisteredTypes(self): """Check PeakWidthModel.getRegisteredTypes.""" regtypes = PeakWidthModel.getRegisteredTypes() self.assertTrue(3 <= len(regtypes)) - self.assertTrue(regtypes.issuperset(["constant", "debye-waller", "jeong"])) + self.assertTrue( + regtypes.issuperset(["constant", "debye-waller", "jeong"]) + ) return def test_pickling(self): diff --git a/tests/test_scatteringfactortable.py b/tests/test_scatteringfactortable.py index 3d327ae8..c2ec9351 100644 --- a/tests/test_scatteringfactortable.py +++ b/tests/test_scatteringfactortable.py @@ -184,8 +184,16 @@ def test_lookup(self): fmn0 = numpy.array([sftx.lookup("Mn", x) for x in qa]) self.assertTrue(numpy.array_equal(fmn0, sftx.lookup("Mn", qa))) self.assertTrue(numpy.array_equal(fmn0, sftx.lookup("Mn", qb))) - self.assertTrue(numpy.array_equal(fmn0.reshape(5, 10), sftx.lookup("Mn", qa.reshape(5, 10)))) - self.assertTrue(numpy.array_equal(fmn0.reshape(5, 2, 5), sftx.lookup("Mn", qa.reshape(5, 2, 5)))) + self.assertTrue( + numpy.array_equal( + fmn0.reshape(5, 10), sftx.lookup("Mn", qa.reshape(5, 10)) + ) + ) + self.assertTrue( + numpy.array_equal( + fmn0.reshape(5, 2, 5), sftx.lookup("Mn", qa.reshape(5, 2, 5)) + ) + ) self.assertTrue(numpy.array_equal(fmn0, sftx.lookup("Mn", list(qa)))) self.assertRaises(TypeError, sftx.lookup, "Na", "asdf") self.assertRaises(TypeError, sftx.lookup, "Na", {}) diff --git a/tests/test_sfaverage.py b/tests/test_sfaverage.py index 87dd9a15..770ca15c 100644 --- a/tests/test_sfaverage.py +++ b/tests/test_sfaverage.py @@ -49,7 +49,9 @@ def test_fromStructure_CdSe(self): self.assertTrue(numpy.array_equal(sfavg3.f2sum, sfavg4.f2sum)) sfavg5 = SFAverage.fromStructure(cdse, "EN", qa) self.assertFalse(numpy.array_equal(sfavg3.f1sum, sfavg5.f1sum)) - self.assertRaises(TypeError, SFAverage.fromStructure, "notastructure", self.sftx) + self.assertRaises( + TypeError, SFAverage.fromStructure, "notastructure", self.sftx + ) self.assertRaises(ValueError, SFAverage.fromStructure, cdse, "invalid") return diff --git a/tests/test_structureadapter.py b/tests/test_structureadapter.py index 384421f7..73f7fd4d 100644 --- a/tests/test_structureadapter.py +++ b/tests/test_structureadapter.py @@ -90,11 +90,19 @@ def test_pickling(self): self.assertEqual(adpt.countSites(), adpt1.countSites()) self.assertEqual(adpt.totalOccupancy(), adpt1.totalOccupancy()) self.assertEqual(adpt.siteAtomType(1), adpt1.siteAtomType(1)) - self.assertTrue(numpy.array_equal(adpt.siteCartesianPosition(1), adpt1.siteCartesianPosition(1))) + self.assertTrue( + numpy.array_equal( + adpt.siteCartesianPosition(1), adpt1.siteCartesianPosition(1) + ) + ) self.assertEqual(adpt.siteMultiplicity(1), adpt1.siteMultiplicity(1)) self.assertEqual(adpt.siteOccupancy(1), adpt1.siteOccupancy(1)) self.assertTrue(adpt.siteAnisotropy(1) is adpt1.siteAnisotropy(1)) - self.assertTrue(numpy.array_equal(adpt.siteCartesianUij(1), adpt1.siteCartesianUij(1))) + self.assertTrue( + numpy.array_equal( + adpt.siteCartesianUij(1), adpt1.siteCartesianUij(1) + ) + ) return def test_pickle_nonwrapped(self): @@ -294,10 +302,16 @@ def test_objcryst_adapter(self): self.assertTrue(True is self.rutile.siteAnisotropy(0)) self.assertTrue(True is self.rutile.siteAnisotropy(1)) self.assertTrue( - numpy.allclose(numpy.diag([0.008698, 0.008698, 0.005492]), self.rutile.siteCartesianUij(0)) + numpy.allclose( + numpy.diag([0.008698, 0.008698, 0.005492]), + self.rutile.siteCartesianUij(0), + ) ) self.assertTrue( - numpy.allclose(numpy.diag([0.021733, 0.021733, 0.007707]), self.rutile.siteCartesianUij(1)) + numpy.allclose( + numpy.diag([0.021733, 0.021733, 0.007707]), + self.rutile.siteCartesianUij(1), + ) ) return @@ -592,7 +606,14 @@ def test_uij_cartn(self): a.uc13 = 0.013 a.uc23 = 0.023 self.assertTrue( - numpy.array_equal(a.uij_cartn, [[0.01, 0.012, 0.013], [0.012, 0.01, 0.023], [0.013, 0.023, 0.01]]) + numpy.array_equal( + a.uij_cartn, + [ + [0.01, 0.012, 0.013], + [0.012, 0.01, 0.023], + [0.013, 0.023, 0.01], + ], + ) ) self.assertEqual(0.01, a.uc11) self.assertEqual(0.01, a.uc22) diff --git a/tests/testutils.py b/tests/testutils.py index 5f594af7..c2991a33 100644 --- a/tests/testutils.py +++ b/tests/testutils.py @@ -142,11 +142,15 @@ class DerivedAtomicStructureAdapter(HasCustomPQConfig, AtomicStructureAdapter): pass -class DerivedPeriodicStructureAdapter(HasCustomPQConfig, PeriodicStructureAdapter): +class DerivedPeriodicStructureAdapter( + HasCustomPQConfig, PeriodicStructureAdapter +): pass -class DerivedCrystalStructureAdapter(HasCustomPQConfig, CrystalStructureAdapter): +class DerivedCrystalStructureAdapter( + HasCustomPQConfig, CrystalStructureAdapter +): pass From d0f61e86bea9a99f474e04c3b62dc1876c34ea1a Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Mon, 23 Jun 2025 11:58:40 -0400 Subject: [PATCH 37/55] chore: news --- news/pc-blackv2.rst | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 news/pc-blackv2.rst diff --git a/news/pc-blackv2.rst b/news/pc-blackv2.rst new file mode 100644 index 00000000..64feaf3d --- /dev/null +++ b/news/pc-blackv2.rst @@ -0,0 +1,23 @@ +**Added:** + +* + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* Configure ``black`` to have a linelength requirement of 79 characters. + +**Security:** + +* From 412bbf536a6142a461e80be6910e37e73ac2d2b3 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Mon, 23 Jun 2025 12:05:44 -0400 Subject: [PATCH 38/55] skpkg: flake8 fixes in setup.py --- setup.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index fe548047..d781a2a9 100644 --- a/setup.py +++ b/setup.py @@ -53,7 +53,8 @@ def get_objcryst_libraries(): conda_prefix = os.environ.get("CONDA_PREFIX") if not conda_prefix: raise EnvironmentError( - "CONDA_PREFIX is not set. Please install ObjCryst using conda and activate the environment." + "CONDA_PREFIX is not set. " + "Please install ObjCryst using conda and activate the environment." ) if os.name == "nt": libdir = Path(conda_prefix) / "Library" / "lib" @@ -65,7 +66,8 @@ def get_objcryst_libraries(): stem = Path(fn).stem if "objcryst" not in stem.lower(): continue - # strip a leading "lib" so that setuptools does -lObjCryst, not -llibObjCryst + # strip a leading "lib" + # so that setuptools does -lObjCryst, not -llibObjCryst if os.name != "nt" and stem.startswith("lib"): stem = stem[3:] libs.append(stem) From e3924859bb570a64c9d0b02dd92db8b4f11f3b67 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Mon, 23 Jun 2025 15:13:08 -0400 Subject: [PATCH 39/55] skpkg: doc formatting autofixes --- doc/source/examples/distanceprinter.py | 8 +++---- .../examples/lennardjones/ljcalculator.py | 4 ++-- doc/source/examples/parallelPDF.py | 3 ++- src/diffpy/srreal/_docstrings.py | 3 ++- src/diffpy/srreal/_final_imports.py | 3 ++- src/diffpy/srreal/atomradiitable.py | 6 ++--- src/diffpy/srreal/attributes.py | 3 ++- src/diffpy/srreal/bondcalculator.py | 4 ++-- .../srreal/devutils/tunePeakPrecision.py | 4 ++-- src/diffpy/srreal/eventticker.py | 3 ++- src/diffpy/srreal/overlapcalculator.py | 7 +++--- src/diffpy/srreal/pairquantity.py | 3 ++- src/diffpy/srreal/parallel.py | 10 ++++---- src/diffpy/srreal/pdfbaseline.py | 5 ++-- src/diffpy/srreal/pdfcalculator.py | 11 +++++---- src/diffpy/srreal/pdfenvelope.py | 5 ++-- src/diffpy/srreal/sfaverage.py | 3 ++- src/diffpy/srreal/structureadapter.py | 14 +++++------ src/diffpy/srreal/structureconverters.py | 13 ++++++---- src/diffpy/srreal/wraputils.py | 13 +++++----- tests/test_bondcalculator.py | 3 ++- tests/test_bvscalculator.py | 3 ++- tests/test_overlapcalculator.py | 24 ++++++++++++------- tests/test_pairquantity.py | 6 +++-- tests/test_pdfbaseline.py | 3 ++- tests/test_pdfcalculator.py | 6 +++-- tests/test_pdfenvelope.py | 3 ++- tests/test_peakprofile.py | 6 +++-- tests/test_peakwidthmodel.py | 3 ++- tests/test_scatteringfactortable.py | 9 ++++--- tests/test_sfaverage.py | 3 ++- tests/test_structureadapter.py | 15 ++++++++---- 32 files changed, 127 insertions(+), 82 deletions(-) diff --git a/doc/source/examples/distanceprinter.py b/doc/source/examples/distanceprinter.py index 374cf25e..870c7216 100755 --- a/doc/source/examples/distanceprinter.py +++ b/doc/source/examples/distanceprinter.py @@ -1,15 +1,15 @@ #!/usr/bin/env python -"""Demonstration of using PairQuantity class for a printout of pair distances -in periodic and non-periodic structures.""" +"""Demonstration of using PairQuantity class for a printout of pair +distances in periodic and non-periodic structures.""" from diffpy.srreal.pairquantity import PairQuantity from diffpy.structure import Structure class DistancePrinter(PairQuantity): - """This PairQuantity class simply prints the visited pair distances and the - indices of the contributing atoms.""" + """This PairQuantity class simply prints the visited pair distances + and the indices of the contributing atoms.""" def _resetValue(self): self.count = 0 diff --git a/doc/source/examples/lennardjones/ljcalculator.py b/doc/source/examples/lennardjones/ljcalculator.py index 5dc5d852..4e1e1511 100755 --- a/doc/source/examples/lennardjones/ljcalculator.py +++ b/doc/source/examples/lennardjones/ljcalculator.py @@ -1,7 +1,7 @@ #!/usr/bin/env python -"""Demonstration of using PairQuantity class for calculation of Lennard Jones -potential. +"""Demonstration of using PairQuantity class for calculation of Lennard +Jones potential. Vij = 4 * ( rij ** -12 - rij ** -6 ) """ diff --git a/doc/source/examples/parallelPDF.py b/doc/source/examples/parallelPDF.py index ebf26b01..199ebaa1 100755 --- a/doc/source/examples/parallelPDF.py +++ b/doc/source/examples/parallelPDF.py @@ -1,6 +1,7 @@ #!/usr/bin/env python -"""Demonstration of parallel PDF calculation using the multiprocessing package. +"""Demonstration of parallel PDF calculation using the multiprocessing +package. A PDF of menthol structure is first calculated on a single core and then on all computer CPUs. The script then compares both results and prints diff --git a/src/diffpy/srreal/_docstrings.py b/src/diffpy/srreal/_docstrings.py index ab2cb889..a743a985 100644 --- a/src/diffpy/srreal/_docstrings.py +++ b/src/diffpy/srreal/_docstrings.py @@ -18,7 +18,8 @@ def get_registry_docstrings(cls): - """Build a dictionary of docstrings per each HasClassRegistry method. + """Build a dictionary of docstrings per each HasClassRegistry + method. Parameters ---------- diff --git a/src/diffpy/srreal/_final_imports.py b/src/diffpy/srreal/_final_imports.py index 273f106f..b61e0dc1 100644 --- a/src/diffpy/srreal/_final_imports.py +++ b/src/diffpy/srreal/_final_imports.py @@ -25,7 +25,8 @@ def import_now(): - """Import all Python modules that tweak extension-defined classes.""" + """Import all Python modules that tweak extension-defined + classes.""" global _import_now_called if _import_now_called: return diff --git a/src/diffpy/srreal/atomradiitable.py b/src/diffpy/srreal/atomradiitable.py index 9d1f03fa..9bcf9bd2 100644 --- a/src/diffpy/srreal/atomradiitable.py +++ b/src/diffpy/srreal/atomradiitable.py @@ -63,9 +63,9 @@ def clone(self): return copy.copy(self) def type(self): - """Unique string identifier of the CovalentRadiiTable type. This is - used for class registration and as an argument for the createByType - function. + """Unique string identifier of the CovalentRadiiTable type. This + is used for class registration and as an argument for the + createByType function. Return string. """ diff --git a/src/diffpy/srreal/attributes.py b/src/diffpy/srreal/attributes.py index e0326a92..3e188caa 100644 --- a/src/diffpy/srreal/attributes.py +++ b/src/diffpy/srreal/attributes.py @@ -36,7 +36,8 @@ def _getattr(self, name): def _setattr(self, name, value): - """Assign to C++ double attribute if Python attribute does not exist.""" + """Assign to C++ double attribute if Python attribute does not + exist.""" try: object.__getattribute__(self, name) except AttributeError: diff --git a/src/diffpy/srreal/bondcalculator.py b/src/diffpy/srreal/bondcalculator.py index 281ea7d5..98d2fe89 100644 --- a/src/diffpy/srreal/bondcalculator.py +++ b/src/diffpy/srreal/bondcalculator.py @@ -43,8 +43,8 @@ def _init_kwargs(self, **kwargs): - """Create a new instance of BondCalculator. Keyword arguments can be used - to configure calculator properties, for example: + """Create a new instance of BondCalculator. Keyword arguments can be + used to configure calculator properties, for example: bdc = BondCalculator(rmin=1.5, rmax=2.5) diff --git a/src/diffpy/srreal/devutils/tunePeakPrecision.py b/src/diffpy/srreal/devutils/tunePeakPrecision.py index 247d7018..d899ea5c 100755 --- a/src/diffpy/srreal/devutils/tunePeakPrecision.py +++ b/src/diffpy/srreal/devutils/tunePeakPrecision.py @@ -1,7 +1,7 @@ #!/usr/bin/env python -"""Tune the peak precision parameter so that PDFCalculator gives equivalent -results to diffpy.pdffit2. +"""Tune the peak precision parameter so that PDFCalculator gives +equivalent results to diffpy.pdffit2. Usage: tunePeakPrecision.py [qmax] [peakprecision] [createplot] """ diff --git a/src/diffpy/srreal/eventticker.py b/src/diffpy/srreal/eventticker.py index 35b74877..58d95565 100644 --- a/src/diffpy/srreal/eventticker.py +++ b/src/diffpy/srreal/eventticker.py @@ -12,7 +12,8 @@ # See LICENSE.txt for license information. # ############################################################################## -"""Class EventTicker -- storage of modification times of dependent objects.""" +"""Class EventTicker -- storage of modification times of dependent +objects.""" # exported items diff --git a/src/diffpy/srreal/overlapcalculator.py b/src/diffpy/srreal/overlapcalculator.py index ab41037a..e0fcaa47 100644 --- a/src/diffpy/srreal/overlapcalculator.py +++ b/src/diffpy/srreal/overlapcalculator.py @@ -12,7 +12,8 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## -"""Class OverlapCalculator -- calculator of atom overlaps in a structure.""" +"""Class OverlapCalculator -- calculator of atom overlaps in a +structure.""" # exported items, these also makes them show in pydoc. @@ -50,8 +51,8 @@ def _init_kwargs(self, **kwargs): - """Create a new instance of OverlapCalculator. Keyword arguments can be - used to configure calculator properties, for example: + """Create a new instance of OverlapCalculator. Keyword arguments can + be used to configure calculator properties, for example: olc = OverlapCalculator(rmax=2.5) diff --git a/src/diffpy/srreal/pairquantity.py b/src/diffpy/srreal/pairquantity.py index a8eaa058..7097e7c8 100644 --- a/src/diffpy/srreal/pairquantity.py +++ b/src/diffpy/srreal/pairquantity.py @@ -12,7 +12,8 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## -"""Class PairQuantity -- base class for Python defined calculators.""" +"""Class PairQuantity -- base class for Python defined +calculators.""" # exported items diff --git a/src/diffpy/srreal/parallel.py b/src/diffpy/srreal/parallel.py index 87b8a76e..179f092b 100644 --- a/src/diffpy/srreal/parallel.py +++ b/src/diffpy/srreal/parallel.py @@ -43,8 +43,8 @@ def createParallelCalculator(pqobj, ncpu, pmap): """ class ParallelPairQuantity(Attributes): - """Class for running parallel calculations. This is a proxy class to - the wrapper PairQuantity type with the same interface. + """Class for running parallel calculations. This is a proxy + class to the wrapper PairQuantity type with the same interface. Instance data: @@ -70,7 +70,8 @@ def __init__(self, pqobj, ncpu, pmap): return def eval(self, stru=None): - """Perform parallel calculation and return internal value array. + """Perform parallel calculation and return internal value + array. stru -- object that can be converted to StructureAdapter, e.g., example diffpy Structure or pyobjcryst Crystal. @@ -208,7 +209,8 @@ def _fdel(self): def _parallelData(kwd): - """Helper for calculating and fetching raw results from a worker node.""" + """Helper for calculating and fetching raw results from a worker + node.""" pqobj = kwd["pqobj"] pqobj._setupParallelRun(kwd["cpuindex"], kwd["ncpu"]) pqobj.eval() diff --git a/src/diffpy/srreal/pdfbaseline.py b/src/diffpy/srreal/pdfbaseline.py index 0769c2d2..bb168467 100644 --- a/src/diffpy/srreal/pdfbaseline.py +++ b/src/diffpy/srreal/pdfbaseline.py @@ -48,8 +48,9 @@ def makePDFBaseline(name, fnc, replace=False, **dbattrs): - """Helper function for registering Python function as a PDFBaseline. This - is required for using Python function as PDFCalculator.baseline. + """Helper function for registering Python function as a PDFBaseline. + This is required for using Python function as + PDFCalculator.baseline. name -- unique string name for registering Python function in the global registry of PDFBaseline types. This will be the diff --git a/src/diffpy/srreal/pdfcalculator.py b/src/diffpy/srreal/pdfcalculator.py index e24b3e5b..0e7524b7 100644 --- a/src/diffpy/srreal/pdfcalculator.py +++ b/src/diffpy/srreal/pdfcalculator.py @@ -86,7 +86,8 @@ def _defineCommonInterface(cls): - """This function defines shared properties of PDF calculator classes.""" + """This function defines shared properties of PDF calculator + classes.""" cls.scale = propertyFromExtDoubleAttr( "scale", @@ -161,10 +162,10 @@ def _defineCommonInterface(cls): ) def _call_kwargs(self, structure=None, **kwargs): - """Calculate PDF for the given structure as an (r, G) tuple. Keyword - arguments can be used to configure calculator attributes, these - override any properties that may be passed from the structure, such as - spdiameter. + """Calculate PDF for the given structure as an (r, G) tuple. + Keyword arguments can be used to configure calculator + attributes, these override any properties that may be passed + from the structure, such as spdiameter. structure -- a structure object to be evaluated. Reuse the last structure when None. diff --git a/src/diffpy/srreal/pdfenvelope.py b/src/diffpy/srreal/pdfenvelope.py index 76582dfa..c7395175 100644 --- a/src/diffpy/srreal/pdfenvelope.py +++ b/src/diffpy/srreal/pdfenvelope.py @@ -77,8 +77,9 @@ def makePDFEnvelope(name, fnc, replace=False, **dbattrs): - """Helper function for registering Python function as a PDFEnvelope. This - is required for using Python function as PDFCalculator envelope. + """Helper function for registering Python function as a PDFEnvelope. + This is required for using Python function as PDFCalculator + envelope. name -- unique string name for registering Python function in the global registry of PDFEnvelope types. This will be the diff --git a/src/diffpy/srreal/sfaverage.py b/src/diffpy/srreal/sfaverage.py index 636dc974..d524b0c3 100644 --- a/src/diffpy/srreal/sfaverage.py +++ b/src/diffpy/srreal/sfaverage.py @@ -116,7 +116,8 @@ def fromStructure(cls, stru, sftb, q=0): @classmethod def fromComposition(cls, composition, sftb, q=0): - """Calculate average scattering factors from atom concentrations. + """Calculate average scattering factors from atom + concentrations. Parameters ---------- diff --git a/src/diffpy/srreal/structureadapter.py b/src/diffpy/srreal/structureadapter.py index 3abd19a0..a878ab97 100644 --- a/src/diffpy/srreal/structureadapter.py +++ b/src/diffpy/srreal/structureadapter.py @@ -12,8 +12,8 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## -"""Class StructureAdapter -- adapter of any structure object to the interface -expected by srreal PairQuantity calculators. +"""Class StructureAdapter -- adapter of any structure object to the +interface expected by srreal PairQuantity calculators. Routines: @@ -73,11 +73,11 @@ def createStructureAdapter(stru): def RegisterStructureAdapter(fqname, fnc=None): - """Function decorator that marks it as a converter of specified object type - to StructureAdapter class in diffpy.srreal. The registered structure - object types can be afterwards directly used with calculators in - diffpy.srreal as they would be implicitly converted to the internal - diffpy.srreal structure type. + """Function decorator that marks it as a converter of specified + object type to StructureAdapter class in diffpy.srreal. The + registered structure object types can be afterwards directly used + with calculators in diffpy.srreal as they would be implicitly + converted to the internal diffpy.srreal structure type. fqname -- fully qualified class name for the convertible objects. This is the quoted string included in "str(type(obj))". diff --git a/src/diffpy/srreal/structureconverters.py b/src/diffpy/srreal/structureconverters.py index e3e22e1f..5f9f6cb5 100644 --- a/src/diffpy/srreal/structureconverters.py +++ b/src/diffpy/srreal/structureconverters.py @@ -12,8 +12,8 @@ # See LICENSE.txt for license information. # ############################################################################## -"""Converters from other structure representations in Python to diffpy.srreal -StructureAdapter classes.""" +"""Converters from other structure representations in Python to +diffpy.srreal StructureAdapter classes.""" from diffpy.srreal.srreal_ext import ( AtomicStructureAdapter, @@ -69,12 +69,14 @@ class _DiffPyStructureMetadata(object): @staticmethod def hasMetadata(stru): - """True if Structure object carries data in its pdffit attribute.""" + """True if Structure object carries data in its pdffit + attribute.""" rv = hasattr(stru, "pdffit") and bool(stru.pdffit) return rv def _customPQConfig(self, pqobj): - """Apply PDF-related metadata if defined in PDFFit structure format.""" + """Apply PDF-related metadata if defined in PDFFit structure + format.""" pqname = type(pqobj).__name__ if pqname not in ("PDFCalculator", "DebyePDFCalculator"): return @@ -102,7 +104,8 @@ def _customPQConfig(self, pqobj): return def _fetchMetadata(self, stru): - """Copy data from the pdffit attribute of diffpy Structure object. + """Copy data from the pdffit attribute of diffpy Structure + object. stru -- instance of Structure class from diffpy.structure diff --git a/src/diffpy/srreal/wraputils.py b/src/diffpy/srreal/wraputils.py index b44f76ea..46322152 100644 --- a/src/diffpy/srreal/wraputils.py +++ b/src/diffpy/srreal/wraputils.py @@ -12,7 +12,8 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## -"""Local utilities helpful for tweaking interfaces to boost python classes.""" +"""Local utilities helpful for tweaking interfaces to boost python +classes.""" import copy @@ -63,8 +64,8 @@ def _wrapAsRegisteredUnaryFunction( cls, regname, fnc, replace=False, **dbattrs ): """Helper function for wrapping Python function as PDFBaseline or - PDFEnvelope functor. Not intended for direct usage, this function is - rather called from makePDFBaseline or makePDFEnvelope wrappers. + PDFEnvelope functor. Not intended for direct usage, this function + is rather called from makePDFBaseline or makePDFEnvelope wrappers. cls -- the functor class for wrapping the Python function regname -- string name for registering the function in the global @@ -96,9 +97,9 @@ def clone(self): return copy.copy(self) def type(self): - """Unique string identifier of this functor type. The string is - used for class registration and as an argument for the createByType - function. + """Unique string identifier of this functor type. The + string is used for class registration and as an argument for + the createByType function. Return string identifier. """ diff --git a/tests/test_bondcalculator.py b/tests/test_bondcalculator.py index 89eb7f94..4b280397 100644 --- a/tests/test_bondcalculator.py +++ b/tests/test_bondcalculator.py @@ -79,7 +79,8 @@ def test_pickling(self): return def test_pickling_derived_structure(self): - """Check pickling of BondCalculator with DerivedStructureAdapter.""" + """Check pickling of BondCalculator with + DerivedStructureAdapter.""" from testutils import DerivedStructureAdapter bdc = self.bdc diff --git a/tests/test_bvscalculator.py b/tests/test_bvscalculator.py index c2f3838a..f15172f9 100644 --- a/tests/test_bvscalculator.py +++ b/tests/test_bvscalculator.py @@ -139,7 +139,8 @@ def test_table_pickling(self): return def test_pickling_derived_structure(self): - """Check pickling of BVSCalculator with DerivedStructureAdapter.""" + """Check pickling of BVSCalculator with + DerivedStructureAdapter.""" from testutils import DerivedStructureAdapter bvc = self.bvc diff --git a/tests/test_overlapcalculator.py b/tests/test_overlapcalculator.py index ee1de8e8..ce27bd31 100644 --- a/tests/test_overlapcalculator.py +++ b/tests/test_overlapcalculator.py @@ -117,7 +117,8 @@ def test_pickling_artb(self): return def test_pickling_derived_structure(self): - """Check pickling of OverlapCalculator with DerivedStructureAdapter.""" + """Check pickling of OverlapCalculator with + DerivedStructureAdapter.""" from testutils import DerivedStructureAdapter olc = self.olc @@ -359,7 +360,8 @@ def tearDown(self): return def test_totalsquareoverlap(self): - """Check OverlapCalculator.totalsquareoverlap for ObjCryst crystal.""" + """Check OverlapCalculator.totalsquareoverlap for ObjCryst + crystal.""" olc = self.olc self.assertEqual(0.0, olc.totalsquareoverlap) olc(self.rutile) @@ -370,7 +372,8 @@ def test_totalsquareoverlap(self): return def test_meansquareoverlap(self): - """Check OverlapCalculator.meansquareoverlap for ObjCryst crystal.""" + """Check OverlapCalculator.meansquareoverlap for ObjCryst + crystal.""" olc = self.olc self.assertEqual(0.0, olc.meansquareoverlap) olc(self.rutile) @@ -381,7 +384,8 @@ def test_meansquareoverlap(self): return def test_flipDiffTotal(self): - """Check OverlapCalculator.flipDiffTotal for an ObjCryst crystal.""" + """Check OverlapCalculator.flipDiffTotal for an ObjCryst + crystal.""" olc = self.olc olc(self.rutile) self.assertEqual(0.0, olc.flipDiffTotal(0, 1)) @@ -396,7 +400,8 @@ def test_flipDiffTotal(self): return def test_flipDiffMean(self): - """Check OverlapCalculator.flipDiffMean for an ObjCryst crystal.""" + """Check OverlapCalculator.flipDiffMean for an ObjCryst + crystal.""" olc = self.olc olc(self.rutile) self.assertEqual(0.0, olc.flipDiffMean(0, 1)) @@ -414,7 +419,8 @@ def test_flipDiffMean(self): return def test_getNeighborSites(self): - """Check OverlapCalculator.getNeighborSites for an ObjCryst crystal.""" + """Check OverlapCalculator.getNeighborSites for an ObjCryst + crystal.""" olc = self.olc olc(self.rutile) self.assertEqual(set(), olc.getNeighborSites(0)) @@ -426,7 +432,8 @@ def test_getNeighborSites(self): return def test_coordinations(self): - """Check OverlapCalculator.coordinations for an ObjCryst crystal.""" + """Check OverlapCalculator.coordinations for an ObjCryst + crystal.""" olc = self.olc self.assertEqual(0, len(olc.coordinations)) olc(self.rutile) @@ -453,7 +460,8 @@ def test_coordinationByTypes(self): return def test_neighborhoods(self): - """Check OverlapCalculator.neighborhoods for an ObjCryst crystal.""" + """Check OverlapCalculator.neighborhoods for an ObjCryst + crystal.""" olc = self.olc self.assertEqual([], olc.neighborhoods) olc(self.rutile) diff --git a/tests/test_pairquantity.py b/tests/test_pairquantity.py index 01e3bd94..14335a9f 100644 --- a/tests/test_pairquantity.py +++ b/tests/test_pairquantity.py @@ -128,7 +128,8 @@ def test_ticker_override(self): return def test__addPairContribution(self): - """Check Python override of PairQuantity._addPairContribution.""" + """Check Python override of + PairQuantity._addPairContribution.""" pqcnt = PQCounter() self.assertEqual(0, pqcnt(carbonzchain(0))) self.assertEqual(0, pqcnt(carbonzchain(1))) @@ -137,7 +138,8 @@ def test__addPairContribution(self): return def test_optimized_evaluation(self): - """Check OPTIMIZED evaluation in Python-defined calculator class.""" + """Check OPTIMIZED evaluation in Python-defined calculator + class.""" c8 = carbonzchain(8) c9 = carbonzchain(9) pqd = PQDerived() diff --git a/tests/test_pdfbaseline.py b/tests/test_pdfbaseline.py index ecf417c0..e9aff06a 100644 --- a/tests/test_pdfbaseline.py +++ b/tests/test_pdfbaseline.py @@ -1,6 +1,7 @@ #!/usr/bin/env python -"""Unit tests for the PDFBaseline class from diffpy.srreal.pdfcalculator.""" +"""Unit tests for the PDFBaseline class from +diffpy.srreal.pdfcalculator.""" import pickle diff --git a/tests/test_pdfcalculator.py b/tests/test_pdfcalculator.py index 2871acce..28b31980 100644 --- a/tests/test_pdfcalculator.py +++ b/tests/test_pdfcalculator.py @@ -271,7 +271,8 @@ def test_mask_pickling(self): return def test_pickling_derived_structure(self): - """Check pickling of PDFCalculator with DerivedStructureAdapter.""" + """Check pickling of PDFCalculator with + DerivedStructureAdapter.""" from testutils import DerivedStructureAdapter pdfc = self.pdfcalc @@ -353,7 +354,8 @@ def test_fft_conversions(self): return def test_fft_roundtrip(self): - """Check if forward and inverse transformation recover the input.""" + """Check if forward and inverse transformation recover the + input.""" fnipf2 = datafile("Ni-fit.fgr") g0 = numpy.loadtxt(fnipf2, usecols=(1,)) dr0 = 0.01 diff --git a/tests/test_pdfenvelope.py b/tests/test_pdfenvelope.py index 901ea01f..ff8d95a6 100644 --- a/tests/test_pdfenvelope.py +++ b/tests/test_pdfenvelope.py @@ -1,6 +1,7 @@ #!/usr/bin/env python -"""Unit tests for the PDFEnvelope class from diffpy.srreal.pdfcalculator.""" +"""Unit tests for the PDFEnvelope class from +diffpy.srreal.pdfcalculator.""" import pickle diff --git a/tests/test_peakprofile.py b/tests/test_peakprofile.py index 13347735..dfc59ed2 100644 --- a/tests/test_peakprofile.py +++ b/tests/test_peakprofile.py @@ -1,6 +1,7 @@ #!/usr/bin/env python -"""Unit tests for the PeakProfile classes from diffpy.srreal.peakprofile.""" +"""Unit tests for the PeakProfile classes from +diffpy.srreal.peakprofile.""" import pickle @@ -85,7 +86,8 @@ def test_ticker(self): return def test_ticker_override(self): - """Check method override for PeakProfile.ticker in a derived class.""" + """Check method override for PeakProfile.ticker in a derived + class.""" pkf = MySawTooth() self.assertEqual(0, pkf.tcnt) et0 = pkf.ticker() diff --git a/tests/test_peakwidthmodel.py b/tests/test_peakwidthmodel.py index 3ea3b2e8..2b5bd853 100644 --- a/tests/test_peakwidthmodel.py +++ b/tests/test_peakwidthmodel.py @@ -120,7 +120,8 @@ def test_ticker(self): return def test_ticker_override(self): - """Check PeakWidthModel.ticker override in a Python-derived class.""" + """Check PeakWidthModel.ticker override in a Python-derived + class.""" pwm = MyPWM() self.assertEqual(0, pwm.tcnt) et0 = pwm.ticker() diff --git a/tests/test_scatteringfactortable.py b/tests/test_scatteringfactortable.py index c2ec9351..097d4129 100644 --- a/tests/test_scatteringfactortable.py +++ b/tests/test_scatteringfactortable.py @@ -158,7 +158,8 @@ def test_pickling_derived(self): return def test_derived_create(self): - """Check override of ScatteringFactorTable.create in Python class.""" + """Check override of ScatteringFactorTable.create in Python + class.""" lsft = LocalTable() lsft.setCustomAs("Xy", "Na") lsft2 = lsft.create() @@ -167,7 +168,8 @@ def test_derived_create(self): return def test_derived_clone(self): - """Check override of ScatteringFactorTable.clone in Python class.""" + """Check override of ScatteringFactorTable.clone in Python + class.""" lsft = LocalTable() lsft.setCustomAs("Xy", "Na") lsft2 = lsft.clone() @@ -176,7 +178,8 @@ def test_derived_clone(self): return def test_lookup(self): - """Check ScatteringFactorTable.lookup handling of array arguments.""" + """Check ScatteringFactorTable.lookup handling of array + arguments.""" qa = numpy.linspace(0, 50) qb = numpy.array([(x, 0.0) for x in qa])[:, 0] self.assertTrue(qb.strides > qa.strides) diff --git a/tests/test_sfaverage.py b/tests/test_sfaverage.py index 770ca15c..1171b590 100644 --- a/tests/test_sfaverage.py +++ b/tests/test_sfaverage.py @@ -91,7 +91,8 @@ def tearDown(self): return def test_from_rutile(self): - """Check SFAverage.fromStructure for pyobjcryst Crystal of rutile.""" + """Check SFAverage.fromStructure for pyobjcryst Crystal of + rutile.""" rutile = loadObjCrystCrystal("rutile.cif") qa = numpy.arange(0, 25, 0.1) sfavg = SFAverage.fromStructure(rutile, self.sftx, qa) diff --git a/tests/test_structureadapter.py b/tests/test_structureadapter.py index 73f7fd4d..186e2ba6 100644 --- a/tests/test_structureadapter.py +++ b/tests/test_structureadapter.py @@ -74,7 +74,8 @@ def test_createStructureAdapterTypes(self): return def test_createStructureAdapter_int64_occupancy(self): - """Check Structure conversion when occupany is of numpy.int64 type.""" + """Check Structure conversion when occupany is of numpy.int64 + type.""" self.nickel[0].occupancy = numpy.int64(0) self.nickel[1].occupancy = numpy.int64(1) adpt = createStructureAdapter(self.nickel) @@ -259,7 +260,8 @@ def test_nosymmetry(self): return def test_nosymmetry_twice(self): - """Check that second call of nosymmetry returns the same object.""" + """Check that second call of nosymmetry returns the same + object.""" adpt1 = nosymmetry(self.nickel) adpt2 = nosymmetry(adpt1) self.assertTrue(adpt1 is adpt2) @@ -348,14 +350,16 @@ def test_siteAtomTypeIndex(self): return def test_siteCartesianPositionIndex(self): - """Check out-of-range arguments in AdptClass.siteCartesianPosition.""" + """Check out-of-range arguments in + AdptClass.siteCartesianPosition.""" cnt = self.adpt.countSites() self.assertRaises(IndexError, self.adpt.siteCartesianPosition, cnt) self.assertRaises(IndexError, self.adpt.siteCartesianPosition, -1) return def test_siteMultiplicityIndex(self): - """Check out-of-range arguments in AdptClass.siteMultiplicity.""" + """Check out-of-range arguments in + AdptClass.siteMultiplicity.""" cnt = self.adpt.countSites() self.assertRaises(IndexError, self.adpt.siteMultiplicity, cnt) self.assertRaises(IndexError, self.adpt.siteMultiplicity, -1) @@ -376,7 +380,8 @@ def test_siteAnisotropyIndex(self): return def test_siteCartesianUijIndex(self): - """Check out-of-range arguments in AdptClass.siteCartesianUij.""" + """Check out-of-range arguments in + AdptClass.siteCartesianUij.""" cnt = self.adpt.countSites() self.assertRaises(IndexError, self.adpt.siteCartesianUij, cnt) self.assertRaises(IndexError, self.adpt.siteCartesianUij, -1) From 9b9f2a3de2097a312cd06807c4ce091da1633253 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Mon, 23 Jun 2025 15:13:27 -0400 Subject: [PATCH 40/55] skpkg: add docformatting config to pyproject.toml --- pyproject.toml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 4aecbc54..38694f27 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -78,3 +78,8 @@ exclude = ''' | tests/data )/ ''' + +[tool.docformatter] +recursive = true +wrap-summaries = 72 +wrap-descriptions = 72 From c1003ac5b508a01cb4af7737c53ff51032585c3b Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Tue, 24 Jun 2025 14:05:56 -0400 Subject: [PATCH 41/55] skpkg: gitignore, code of conduct updates, rm env.yml and prettierignore --- .gitignore | 1 + .prettierignore | 1 - CODE_OF_CONDUCT.rst | 2 +- environment.yml | 6 ------ 4 files changed, 2 insertions(+), 8 deletions(-) delete mode 100644 .prettierignore delete mode 100644 environment.yml diff --git a/.gitignore b/.gitignore index d418364a..099e2948 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ __pycache__/ .Python env/ build/ +_build/ develop-eggs/ dist/ downloads/ diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index 7f39adde..00000000 --- a/.prettierignore +++ /dev/null @@ -1 +0,0 @@ -/conda-recipe/* diff --git a/CODE_OF_CONDUCT.rst b/CODE_OF_CONDUCT.rst index ff9c3561..e8199ca5 100644 --- a/CODE_OF_CONDUCT.rst +++ b/CODE_OF_CONDUCT.rst @@ -8,7 +8,7 @@ Our Pledge We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender -identity and expression, level of experience, education, socio-economic status, +identity and expression, level of experience, education, socioeconomic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation. diff --git a/environment.yml b/environment.yml deleted file mode 100644 index 680bfd94..00000000 --- a/environment.yml +++ /dev/null @@ -1,6 +0,0 @@ -name: diffpy.srreal -channels: - - conda-forge -dependencies: - - python=3 - - pip From 63005979a5aa896e31e5763be93693176d0587d1 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Tue, 24 Jun 2025 14:08:27 -0400 Subject: [PATCH 42/55] skpkg: ignore_words.txt and pyproject.toml --- .codespell/ignore_words.txt | 3 --- pyproject.toml | 14 +++++++------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/.codespell/ignore_words.txt b/.codespell/ignore_words.txt index 63971de7..7ca2aeac 100644 --- a/.codespell/ignore_words.txt +++ b/.codespell/ignore_words.txt @@ -4,9 +4,6 @@ ;; abbreviation for "materials" often used in a journal title mater -;; alternative use of socioeconomic -socio-economic - ;; Frobenius norm used in np.linalg.norm fro diff --git a/pyproject.toml b/pyproject.toml index 38694f27..840710d8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,10 +6,10 @@ build-backend = "setuptools.build_meta" name = "diffpy.srreal" dynamic=['version', 'dependencies'] authors = [ - { name="Simon J.L. Billinge group", email="simon.billinge@gmail.com" }, + { name="Simon Billinge", email="sb2896@columbia.edu" }, ] maintainers = [ - { name="Simon J.L. Billinge group", email="simon.billinge@gmail.com" }, + { name="Simon Billinge", email="sb2896@columbia.edu" }, ] description = "Calculators for PDF, bond valence sum, and other quantities based on atom pair interaction." keywords = ['PDF', 'BVS', 'atom', 'overlap', 'calculator', 'real-space'] @@ -56,6 +56,11 @@ exclude-file = ".codespell/ignore_lines.txt" ignore-words = ".codespell/ignore_words.txt" skip = "*.cif,*.dat" +[tool.docformatter] +recursive = true +wrap-summaries = 72 +wrap-descriptions = 72 + [tool.black] line-length = 79 include = '\.pyi?$' @@ -78,8 +83,3 @@ exclude = ''' | tests/data )/ ''' - -[tool.docformatter] -recursive = true -wrap-summaries = 72 -wrap-descriptions = 72 From 462a18c09d2105087f9b19d11457789acead366a Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Tue, 24 Jun 2025 14:10:20 -0400 Subject: [PATCH 43/55] skpkg: github workflows dir --- .github/ISSUE_TEMPLATE/release_checklist.md | 14 +++--- .../pull_request_template.md | 15 ++++++ .../workflows/build-wheel-release-upload.yml | 4 +- .github/workflows/check-news-item.yml | 2 +- .../matrix-and-codecov-on-merge-to-main.yml | 2 +- .github/workflows/publish-docs-on-release.yml | 2 +- .github/workflows/tests-on-pr.yml | 50 +++---------------- 7 files changed, 35 insertions(+), 54 deletions(-) create mode 100644 .github/PULL_REQUEST_TEMPLATE/pull_request_template.md diff --git a/.github/ISSUE_TEMPLATE/release_checklist.md b/.github/ISSUE_TEMPLATE/release_checklist.md index fa94779e..6107962c 100644 --- a/.github/ISSUE_TEMPLATE/release_checklist.md +++ b/.github/ISSUE_TEMPLATE/release_checklist.md @@ -13,30 +13,30 @@ assignees: "" - [ ] License information is verified as correct. If you are unsure, please comment below. - [ ] Locally rendered documentation contains all appropriate pages, including API references (check no modules are missing), tutorials, and other human-written text is up-to-date with any changes in the code. -- [ ] Installation instructions in the README, documentation, and the website (e.g., diffpy.org) are updated. +- [ ] Installation instructions in the README, documentation, and the website are updated. - [ ] Successfully run any tutorial examples or do functional testing with the latest Python version. - [ ] Grammar and writing quality are checked (no typos). - [ ] Install `pip install build twine`, run `python -m build` and `twine check dist/*` to ensure that the package can be built and is correctly formatted for PyPI release. -Please mention @sbillinge here when you are ready for PyPI/GitHub release. Include any additional comments necessary, such as version information and details about the pre-release here: +Please tag the maintainer (e.g., @username) in the comment here when you are ready for the PyPI/GitHub release. Include any additional comments necessary, such as version information and details about the pre-release here: ### PyPI/GitHub full-release preparation checklist: - [ ] Create a new conda environment and install the rc from PyPI (`pip install ==??`) - [ ] License information on PyPI is correct. -- [ ] Docs are deployed successfully to `https://www.diffpy.org/`. +- [ ] Docs are deployed successfully to `https:///`. - [ ] Successfully run all tests, tutorial examples or do functional testing. -Please let @sbillinge know that all checks are done and the package is ready for full release. +Please let the maintainer know that all checks are done and the package is ready for full release. ### conda-forge release preparation checklist: - + - [ ] Ensure that the full release has appeared on PyPI successfully. - [ ] New package dependencies listed in `conda.txt` and `test.txt` are added to `meta.yaml` in the feedstock. -- [ ] Close any open issues on the feedstock. Reach out to @bobleesj if you have questions. -- [ ] Tag @sbillinge and @bobleesj for conda-forge release. +- [ ] Close any open issues on the feedstock. Reach out to the maintainer if you have questions. +- [ ] Tag the maintainer for conda-forge release. ### Post-release checklist diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md new file mode 100644 index 00000000..1099d862 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md @@ -0,0 +1,15 @@ +### What problem does this PR address? + + + +### What should the reviewer(s) do? + + + + diff --git a/.github/workflows/build-wheel-release-upload.yml b/.github/workflows/build-wheel-release-upload.yml index f751e848..caaf5a0a 100644 --- a/.github/workflows/build-wheel-release-upload.yml +++ b/.github/workflows/build-wheel-release-upload.yml @@ -8,11 +8,11 @@ on: jobs: release: - uses: Billingegroup/release-scripts/.github/workflows/_build-wheel-release-upload.yml@v0 + uses: scikit-package/release-scripts/.github/workflows/_build-wheel-release-upload.yml@v0 with: project: diffpy.srreal c_extension: true - github_admin_username: sbillinge + maintainer_GITHUB_username: sbillinge secrets: PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} PAT_TOKEN: ${{ secrets.PAT_TOKEN }} diff --git a/.github/workflows/check-news-item.yml b/.github/workflows/check-news-item.yml index 26108723..88908d6f 100644 --- a/.github/workflows/check-news-item.yml +++ b/.github/workflows/check-news-item.yml @@ -7,6 +7,6 @@ on: jobs: check-news-item: - uses: Billingegroup/release-scripts/.github/workflows/_check-news-item.yml@v0 + uses: scikit-package/release-scripts/.github/workflows/_check-news-item.yml@v0 with: project: diffpy.srreal diff --git a/.github/workflows/matrix-and-codecov-on-merge-to-main.yml b/.github/workflows/matrix-and-codecov-on-merge-to-main.yml index ea2983bd..9d2881b3 100644 --- a/.github/workflows/matrix-and-codecov-on-merge-to-main.yml +++ b/.github/workflows/matrix-and-codecov-on-merge-to-main.yml @@ -12,7 +12,7 @@ on: jobs: matrix-coverage: - uses: Billingegroup/release-scripts/.github/workflows/_matrix-and-codecov-on-merge-to-main.yml@v0 + uses: scikit-package/release-scripts/.github/workflows/_matrix-and-codecov-on-merge-to-main.yml@v0 with: project: diffpy.srreal c_extension: true diff --git a/.github/workflows/publish-docs-on-release.yml b/.github/workflows/publish-docs-on-release.yml index 8daf1623..108cc184 100644 --- a/.github/workflows/publish-docs-on-release.yml +++ b/.github/workflows/publish-docs-on-release.yml @@ -5,7 +5,7 @@ on: jobs: docs: - uses: Billingegroup/release-scripts/.github/workflows/_publish-docs-on-release.yml@v0 + uses: scikit-package/release-scripts/.github/workflows/_publish-docs-on-release.yml@v0 with: project: diffpy.srreal c_extension: true diff --git a/.github/workflows/tests-on-pr.yml b/.github/workflows/tests-on-pr.yml index ed07dd15..3deb95d2 100644 --- a/.github/workflows/tests-on-pr.yml +++ b/.github/workflows/tests-on-pr.yml @@ -1,49 +1,15 @@ name: Tests on PR on: - push: - branches: - - main - - cookie pull_request: workflow_dispatch: jobs: - validate: - defaults: - run: - shell: bash -l {0} - - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest, windows-latest, macos-13, macos-14] - python-version: [3.11, 3.12, 3.13] - - steps: - - name: Check out diffpy.srreal - uses: actions/checkout@v4 - - - name: Initialize miniconda - uses: conda-incubator/setup-miniconda@v3 - with: - activate-environment: test - auto-update-conda: true - environment-file: environment.yml - auto-activate-base: false - python-version: ${{ matrix.python-version }} - - - name: Conda config - run: >- - conda config --set always_yes yes - --set changeps1 no - - - name: Install diffpy.srreal and requirements - run: | - conda install --file requirements/conda.txt - conda install --file requirements/test.txt - python -m pip install . --no-deps - - - name: Validate diffpy.pdfgui - run: pytest tests + tests-on-pr: + uses: scikit-package/release-scripts/.github/workflows/_tests-on-pr.yml@v0 + with: + project: diffpy.srreal + c_extension: true + headless: false + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} From b24e60a709a0a2e25dd3d5dde8eb44f27d657f4c Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Tue, 24 Jun 2025 14:10:45 -0400 Subject: [PATCH 44/55] skpkg: change log header --- CHANGELOG.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 6f96d258..79c75d7d 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,5 +1,5 @@ ============= -Release Notes +Release notes ============= .. current developments From b84b8d87195adcef372293dabd3dff0bbaacd2b1 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Tue, 24 Jun 2025 14:11:23 -0400 Subject: [PATCH 45/55] skpkg: readme --- README.rst | 45 ++++++++++----------------------------------- 1 file changed, 10 insertions(+), 35 deletions(-) diff --git a/README.rst b/README.rst index a6d2ff81..116f2d1b 100644 --- a/README.rst +++ b/README.rst @@ -8,7 +8,7 @@ :target: https://diffpy.github.io/diffpy.srreal :height: 100px -|PyPi| |Forge| |PythonVersion| |PR| +|PyPI| |Forge| |PythonVersion| |PR| |CI| |Codecov| |Black| |Tracking| @@ -26,7 +26,7 @@ .. |PR| image:: https://img.shields.io/badge/PR-Welcome-29ab47ff -.. |PyPi| image:: https://img.shields.io/pypi/v/diffpy.srreal +.. |PyPI| image:: https://img.shields.io/pypi/v/diffpy.srreal :target: https://pypi.org/project/diffpy.srreal/ .. |PythonVersion| image:: https://img.shields.io/pypi/pyversions/diffpy.srreal @@ -37,35 +37,7 @@ Calculators for PDF, bond valence sum, and other quantities based on atom pair interaction. -The diffpy.srreal package provides calculators for atomic pair distribution -function (PDF), bond valence sums (BVS), atom overlaps for a hard-sphere -model, bond distances and directions up to specified maximum distance. The -atomic structure models are represented with internal classes as non-periodic, -periodic or structures with space group symmetries. The package provides -implicit adapters from diffpy.structure classes or from Crystal or Molecule -objects from pyobjcryst. Adapters can be easily defined for any other -structure representations in Python allowing their direct use with the -calculators. Calculators support two evaluation models - BASIC, which -performs a full pair-summation every time, and OPTIMIZED, which updates only -pair contributions that have changed since the last evaluation. Calculations -can be split among parallel jobs using Python multiprocessing package or any -other library that provides parallel map function. PDF calculations can -be done in two modes - either as a real-space summation of peak profiles -(PDFCalculator) or as a reciprocal-space Debye summation and Fourier -transform of the total scattering structure function (DebyePDFCalculator). - -The diffpy.srreal package is a Python binding to the C++ library libdiffpy -(https://github.com/diffpy/libdiffpy). Calculators are created as -objects of a given calculator type and so multiple instances of the same -calculator type can exist with different configurations. Calculators are -composed of other objects that perform lower-level tasks, such as calculating -peak profile or looking up atom scattering factors. These objects can be -re-assigned at runtime allowing to easily customize the calculation procedure. -New classes can be defined using object inheritance either in Python or in C++ -and used with the existing calculators; as an example, this allows to -calculate PDF with a user-defined profile function. A new calculator class -can be also defined for any quantity that is obtained by iteration over atom -pairs, by defining only the function that processes atom-pair contributions. +* LONGER DESCRIPTION HERE For more information about the diffpy.srreal library, please consult our `online documentation `_. @@ -119,9 +91,7 @@ You may consult our `online documentation `_ is the discussion forum for general questions and discussions about the use of diffpy.srreal. Please join the diffpy.srreal users community by joining the Google group. The diffpy.srreal project welcomes your expertise and enthusiasm! - -If you see a bug or want to request a feature, please `report it as an issue `_ and/or `submit a fix as a PR `_. You can also post it to the `Diffpy user group `_. +If you see a bug or want to request a feature, please `report it as an issue `_ and/or `submit a fix as a PR `_. Feel free to fork the project and contribute. To install diffpy.srreal in a development mode, with its sources being directly used by Python @@ -149,4 +119,9 @@ Before contributing, please read our `Code of Conduct `_ or email Prof. Simon Billinge at sb2896@columbia.edu. +For more information on diffpy.srreal please visit the project `web-page `_ or email Simon Billinge at sb2896@columbia.edu. + +Acknowledgements +---------------- + +``diffpy.srreal`` is built and maintained with `scikit-package `_. From 741046024f223f9e7e2e63e569ece67d0dc5795a Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Tue, 24 Jun 2025 15:25:06 -0400 Subject: [PATCH 46/55] skpkg: user facing files and requirements --- .readthedocs.yaml | 13 ++++ README.rst | 30 ++++++++- doc/source/api/diffpy.srreal.devutils.rst | 20 ++++++ doc/source/conf.py | 21 +++++- doc/source/getting-started.rst | 79 +++++++++++++++++++++++ doc/source/index.rst | 10 ++- doc/source/license.rst | 2 +- requirements/docs.txt | 1 + 8 files changed, 171 insertions(+), 5 deletions(-) create mode 100644 .readthedocs.yaml create mode 100644 doc/source/api/diffpy.srreal.devutils.rst create mode 100644 doc/source/getting-started.rst diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 00000000..47f7a017 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,13 @@ +version: 2 + +build: + os: "ubuntu-22.04" + tools: + python: "latest" + +python: + install: + - requirements: requirements/docs.txt + +sphinx: + configuration: doc/source/conf.py diff --git a/README.rst b/README.rst index 116f2d1b..d1343cb2 100644 --- a/README.rst +++ b/README.rst @@ -37,7 +37,35 @@ Calculators for PDF, bond valence sum, and other quantities based on atom pair interaction. -* LONGER DESCRIPTION HERE +The diffpy.srreal package provides calculators for atomic pair distribution +function (PDF), bond valence sums (BVS), atom overlaps for a hard-sphere +model, bond distances and directions up to specified maximum distance. The +atomic structure models are represented with internal classes as non-periodic, +periodic or structures with space group symmetries. The package provides +implicit adapters from diffpy.structure classes or from Crystal or Molecule +objects from pyobjcryst. Adapters can be easily defined for any other +structure representations in Python allowing their direct use with the +calculators. Calculators support two evaluation models - BASIC, which +performs a full pair-summation every time, and OPTIMIZED, which updates only +pair contributions that have changed since the last evaluation. Calculations +can be split among parallel jobs using Python multiprocessing package or any +other library that provides parallel map function. PDF calculations can +be done in two modes - either as a real-space summation of peak profiles +(PDFCalculator) or as a reciprocal-space Debye summation and Fourier +transform of the total scattering structure function (DebyePDFCalculator). + +The diffpy.srreal package is a Python binding to the C++ library libdiffpy +(https://github.com/diffpy/libdiffpy). Calculators are created as +objects of a given calculator type and so multiple instances of the same +calculator type can exist with different configurations. Calculators are +composed of other objects that perform lower-level tasks, such as calculating +peak profile or looking up atom scattering factors. These objects can be +re-assigned at runtime allowing to easily customize the calculation procedure. +New classes can be defined using object inheritance either in Python or in C++ +and used with the existing calculators; as an example, this allows to +calculate PDF with a user-defined profile function. A new calculator class +can be also defined for any quantity that is obtained by iteration over atom +pairs, by defining only the function that processes atom-pair contributions. For more information about the diffpy.srreal library, please consult our `online documentation `_. diff --git a/doc/source/api/diffpy.srreal.devutils.rst b/doc/source/api/diffpy.srreal.devutils.rst new file mode 100644 index 00000000..77bc0792 --- /dev/null +++ b/doc/source/api/diffpy.srreal.devutils.rst @@ -0,0 +1,20 @@ +:tocdepth: -1 + +diffpy.srreal.devutils package +============================== + +.. automodule:: diffpy.srreal.devutils + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +diffpy.srreal.devutils.tunePeakPrecision module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.srreal.devutils.tunePeakPrecision + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/conf.py b/doc/source/conf.py index f885a7b1..a05707e1 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -18,6 +18,12 @@ from importlib.metadata import version from pathlib import Path +# Attempt to import the version dynamically from GitHub tag. +try: + fullversion = version("diffpy.srreal") +except Exception: + fullversion = "No version found. The correct version will appear in the released version." # noqa: E501 + # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use Path().resolve() to make it absolute, like shown here. @@ -43,6 +49,7 @@ "sphinx.ext.viewcode", "sphinx.ext.intersphinx", "sphinx_rtd_theme", + "sphinx_copybutton", "m2r", ] @@ -68,7 +75,6 @@ # |version| and |release|, also used in various other places throughout the # built documents. -fullversion = version(project) # The short X.Y version. version = "".join(fullversion.split(".post")[:1]) # The full version, including alpha/beta/rc tags. @@ -88,6 +94,11 @@ # substitute YEAR in the copyright string copyright = copyright.replace("%Y", year) +# For sphinx_copybutton extension. +# Do not copy "$" for shell commands in code-blocks. +copybutton_prompt_text = r"^\$ " +copybutton_prompt_is_regexp = True + # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = ["build"] @@ -123,6 +134,14 @@ # html_theme = "sphinx_rtd_theme" +html_context = { + "display_github": True, + "github_user": "diffpy", + "github_repo": "diffpy.srreal", + "github_version": "main", + "conf_py_path": "/doc/source/", +} + # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. diff --git a/doc/source/getting-started.rst b/doc/source/getting-started.rst new file mode 100644 index 00000000..ac7d510e --- /dev/null +++ b/doc/source/getting-started.rst @@ -0,0 +1,79 @@ +:tocdepth: -1 + +.. index:: getting-started + +.. _getting-started: + +================ +Getting started +================ + +Here are some example templates provided to help you get started with writing your documentation. You can use these templates to create your own documentation. + +Reuse ``.rst`` files across multiple pages +------------------------------------------ + +Here is how you can reuse a reusable block of ``.rst`` files across multiple pages: + +.. include:: snippets/example-table.rst + +.. warning:: + + Ensure that the ``.rst`` file you are including is not too long. If it is too long, it may be better to split it into multiple files and include them separately. + +Refer to a specific section in the documentation +------------------------------------------------ + +You can use the ``ref`` tag to refer to a specific section in the documentation. For example, you can refer to the section below using the ``:ref:`` tag as shown :ref:`here `. + +.. note:: + + Please check the raw ``.rst`` file of this page to see the exact use of the ``:ref:`` tag. + +Embed your code snippets in the documentation +--------------------------------------------- + +Here is how you can write a block of code in the documentation. You can use the ``code-block`` directive to write a block of code in the documentation. For example, you can write a block of code as shown below: + +.. code-block:: bash + + # Create a new environment, without build dependencies (pure Python package) + conda create -n -env python=3.13 \ + --file requirements/test.txt \ + --file requirements/conda.txt + + # Create a new environment, with build dependencies (non-pure Python package) + conda create -n -env python=3.13 \ + --file requirements/test.txt \ + --file requirements/conda.txt \ + --file requirements/build.txt + + # Activate the environment + conda activate _env + + # Install your package locally + # `--no-deps` to NOT install packages again from `requirements.pip.txt` + pip install -e . --no-deps + + # Run pytest locally + pytest + + # ... run example tutorials + +.. _attach-image: + +Attach an image to the documentation +------------------------------------ + +Here is how you attach an image to the documentation. The ``/doc/source/img/scikit-package-logo-text.png`` example image is provided in the template. + +.. image:: ./img/scikit-package-logo-text.png + :alt: codecov-in-pr-comment + :width: 400px + :align: center + + +Other useful directives +----------------------- + +Here is how you can do menu selection :menuselection:`Admin --> Settings` and display labels for buttons like :guilabel:`Privacy level`. diff --git a/doc/source/index.rst b/doc/source/index.rst index 2c063dfc..1b845f1b 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -4,9 +4,9 @@ .. |title| replace:: diffpy.srreal documentation -diffpy.srreal - Calculators for PDF, bond valence sum, and other quantities based on atom pair interaction. +``diffpy.srreal`` - Calculators for PDF, bond valence sum, and other quantities based on atom pair interaction. -| Software version |release|. +| Software version |release| | Last updated |today|. The diffpy.srreal package provides calculators for atomic pair distribution @@ -66,6 +66,12 @@ Installation See the `README `_ file included with the distribution. +================ +Acknowledgements +================ + +``diffpy.srreal`` is built and maintained with `scikit-package `_. + ================= Table of contents ================= diff --git a/doc/source/license.rst b/doc/source/license.rst index dfdea740..03c1eae0 100644 --- a/doc/source/license.rst +++ b/doc/source/license.rst @@ -22,7 +22,7 @@ Copyright (c) 2008-2012, The Trustees of Columbia University in the City of New Copyright (c) 2014-2019, Brookhaven Science Associates, Brookhaven National Laboratory -Copyright (c) 2024, The Trustees of Columbia University in the City of New York. +Copyright (c) 2025, The Trustees of Columbia University in the City of New York. All rights reserved. The "DiffPy-CMI" is distributed subject to the following license conditions: diff --git a/requirements/docs.txt b/requirements/docs.txt index ab17b1c8..5f34c6ed 100644 --- a/requirements/docs.txt +++ b/requirements/docs.txt @@ -1,4 +1,5 @@ sphinx sphinx_rtd_theme +sphinx-copybutton doctr m2r From e2e5e0d888ac3ec786ccfb95c5d90fc2c8b8a6d4 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Tue, 24 Jun 2025 15:25:54 -0400 Subject: [PATCH 47/55] chore: news --- news/skpkg-migration.rst | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 news/skpkg-migration.rst diff --git a/news/skpkg-migration.rst b/news/skpkg-migration.rst new file mode 100644 index 00000000..b0ec659f --- /dev/null +++ b/news/skpkg-migration.rst @@ -0,0 +1,23 @@ +**Added:** + +* + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* Support ``scikit-package`` Level 5 standard (https://scikit-package.github.io/scikit-package/). + +**Security:** + +* From 830af7d0aaba334e47be516c5175410a0e25d2d5 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Tue, 24 Jun 2025 15:27:53 -0400 Subject: [PATCH 48/55] chore: add diffpy user group to readme --- README.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.rst b/README.rst index d1343cb2..280fa60c 100644 --- a/README.rst +++ b/README.rst @@ -119,6 +119,8 @@ You may consult our `online documentation `_ is the discussion forum for general questions and discussions about the use of diffpy.srreal. Please join the diffpy.srreal users community by joining the Google group. The diffpy.srreal project welcomes your expertise and enthusiasm! + If you see a bug or want to request a feature, please `report it as an issue `_ and/or `submit a fix as a PR `_. Feel free to fork the project and contribute. To install diffpy.srreal From f2e0ddcbb79eb38b67cde4c5be44257b2582022c Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Tue, 24 Jun 2025 15:28:57 -0400 Subject: [PATCH 49/55] chore: more diffpy user group in readme --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 280fa60c..502f3233 100644 --- a/README.rst +++ b/README.rst @@ -121,7 +121,7 @@ Support and Contribute `Diffpy user group `_ is the discussion forum for general questions and discussions about the use of diffpy.srreal. Please join the diffpy.srreal users community by joining the Google group. The diffpy.srreal project welcomes your expertise and enthusiasm! -If you see a bug or want to request a feature, please `report it as an issue `_ and/or `submit a fix as a PR `_. +If you see a bug or want to request a feature, please `report it as an issue `_ and/or `submit a fix as a PR `_. You can also post it to the `Diffpy user group `_. Feel free to fork the project and contribute. To install diffpy.srreal in a development mode, with its sources being directly used by Python From ad73cb4302f4c671dd121437c0af8921dcffcf28 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Tue, 24 Jun 2025 15:38:23 -0400 Subject: [PATCH 50/55] chore: fix typo --- doc/source/api/diffpy.srreal.devutils.rst | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 doc/source/api/diffpy.srreal.devutils.rst diff --git a/doc/source/api/diffpy.srreal.devutils.rst b/doc/source/api/diffpy.srreal.devutils.rst deleted file mode 100644 index 77bc0792..00000000 --- a/doc/source/api/diffpy.srreal.devutils.rst +++ /dev/null @@ -1,20 +0,0 @@ -:tocdepth: -1 - -diffpy.srreal.devutils package -============================== - -.. automodule:: diffpy.srreal.devutils - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -diffpy.srreal.devutils.tunePeakPrecision module -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. automodule:: diffpy.srreal.devutils.tunePeakPrecision - :members: - :undoc-members: - :show-inheritance: From ea1c8886a695ad3401e0e439b5793ddf96e5a4f8 Mon Sep 17 00:00:00 2001 From: Caden Myers <158210249+cadenmyers13@users.noreply.github.com> Date: Tue, 24 Jun 2025 16:32:33 -0400 Subject: [PATCH 51/55] chore: revert tests-on-pr.yml back to original --- .github/workflows/tests-on-pr.yml | 48 +++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/.github/workflows/tests-on-pr.yml b/.github/workflows/tests-on-pr.yml index 3deb95d2..b4d3a35c 100644 --- a/.github/workflows/tests-on-pr.yml +++ b/.github/workflows/tests-on-pr.yml @@ -1,15 +1,47 @@ name: Tests on PR on: + push: + branches: + - main + - cookie pull_request: workflow_dispatch: jobs: - tests-on-pr: - uses: scikit-package/release-scripts/.github/workflows/_tests-on-pr.yml@v0 - with: - project: diffpy.srreal - c_extension: true - headless: false - secrets: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + validate: + defaults: + run: + shell: bash -l {0} + + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macos-13, macos-14] + python-version: [3.11, 3.12, 3.13] + + steps: + - name: Check out diffpy.srreal + uses: actions/checkout@v4 + + - name: Initialize miniconda + uses: conda-incubator/setup-miniconda@v3 + with: + activate-environment: test + auto-update-conda: true + environment-file: environment.yml + auto-activate-base: false + python-version: ${{ matrix.python-version }} + + - name: Conda config + run: >- + conda config --set always_yes yes + --set changeps1 no + - name: Install diffpy.srreal and requirements + run: | + conda install --file requirements/conda.txt + conda install --file requirements/test.txt + python -m pip install . --no-deps + - name: Validate diffpy.pdfgui + run: pytest tests From ac8a64d93db06c5c39556c063a46c3a94e1428f5 Mon Sep 17 00:00:00 2001 From: Caden Myers <158210249+cadenmyers13@users.noreply.github.com> Date: Tue, 24 Jun 2025 16:33:42 -0400 Subject: [PATCH 52/55] chore: add blank lines --- .github/workflows/tests-on-pr.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/tests-on-pr.yml b/.github/workflows/tests-on-pr.yml index b4d3a35c..c877fd32 100644 --- a/.github/workflows/tests-on-pr.yml +++ b/.github/workflows/tests-on-pr.yml @@ -38,10 +38,12 @@ jobs: run: >- conda config --set always_yes yes --set changeps1 no + - name: Install diffpy.srreal and requirements run: | conda install --file requirements/conda.txt conda install --file requirements/test.txt python -m pip install . --no-deps + - name: Validate diffpy.pdfgui run: pytest tests From 62b83e558e788a565a687c335f524d8736e4b057 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 24 Jun 2025 20:33:57 +0000 Subject: [PATCH 53/55] [pre-commit.ci] auto fixes from pre-commit hooks --- .github/workflows/tests-on-pr.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests-on-pr.yml b/.github/workflows/tests-on-pr.yml index c877fd32..ed07dd15 100644 --- a/.github/workflows/tests-on-pr.yml +++ b/.github/workflows/tests-on-pr.yml @@ -38,12 +38,12 @@ jobs: run: >- conda config --set always_yes yes --set changeps1 no - + - name: Install diffpy.srreal and requirements run: | conda install --file requirements/conda.txt conda install --file requirements/test.txt python -m pip install . --no-deps - + - name: Validate diffpy.pdfgui run: pytest tests From 1488319ae8e95f2c6e4956593d49474b6918b86c Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 25 Jun 2025 11:02:35 -0400 Subject: [PATCH 54/55] ci: configure tests-on-pr.yml to run without environment.yml --- .github/workflows/tests-on-pr.yml | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/.github/workflows/tests-on-pr.yml b/.github/workflows/tests-on-pr.yml index ed07dd15..e5546783 100644 --- a/.github/workflows/tests-on-pr.yml +++ b/.github/workflows/tests-on-pr.yml @@ -28,22 +28,25 @@ jobs: - name: Initialize miniconda uses: conda-incubator/setup-miniconda@v3 with: - activate-environment: test auto-update-conda: true - environment-file: environment.yml auto-activate-base: false python-version: ${{ matrix.python-version }} - - name: Conda config - run: >- - conda config --set always_yes yes - --set changeps1 no - + run: | + conda config --add channels conda-forge - name: Install diffpy.srreal and requirements run: | - conda install --file requirements/conda.txt - conda install --file requirements/test.txt + conda create -n test python=${{ matrix.python-version }} -y + source $(conda info --base)/etc/profile.d/conda.sh + conda activate test + conda install pip -y + conda config --set always_yes yes --set changeps1 no + conda install --file requirements/conda.txt -y + conda install --file requirements/test.txt -y python -m pip install . --no-deps - name: Validate diffpy.pdfgui - run: pytest tests + run: | + source $(conda info --base)/etc/profile.d/conda.sh + conda activate test + pytest tests From e4a27007819d3799e2df00a90c569f55abaf795e Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 25 Jun 2025 12:38:59 -0400 Subject: [PATCH 55/55] skpkg: remove getting-started.rst --- doc/source/getting-started.rst | 79 ---------------------------------- 1 file changed, 79 deletions(-) delete mode 100644 doc/source/getting-started.rst diff --git a/doc/source/getting-started.rst b/doc/source/getting-started.rst deleted file mode 100644 index ac7d510e..00000000 --- a/doc/source/getting-started.rst +++ /dev/null @@ -1,79 +0,0 @@ -:tocdepth: -1 - -.. index:: getting-started - -.. _getting-started: - -================ -Getting started -================ - -Here are some example templates provided to help you get started with writing your documentation. You can use these templates to create your own documentation. - -Reuse ``.rst`` files across multiple pages ------------------------------------------- - -Here is how you can reuse a reusable block of ``.rst`` files across multiple pages: - -.. include:: snippets/example-table.rst - -.. warning:: - - Ensure that the ``.rst`` file you are including is not too long. If it is too long, it may be better to split it into multiple files and include them separately. - -Refer to a specific section in the documentation ------------------------------------------------- - -You can use the ``ref`` tag to refer to a specific section in the documentation. For example, you can refer to the section below using the ``:ref:`` tag as shown :ref:`here `. - -.. note:: - - Please check the raw ``.rst`` file of this page to see the exact use of the ``:ref:`` tag. - -Embed your code snippets in the documentation ---------------------------------------------- - -Here is how you can write a block of code in the documentation. You can use the ``code-block`` directive to write a block of code in the documentation. For example, you can write a block of code as shown below: - -.. code-block:: bash - - # Create a new environment, without build dependencies (pure Python package) - conda create -n -env python=3.13 \ - --file requirements/test.txt \ - --file requirements/conda.txt - - # Create a new environment, with build dependencies (non-pure Python package) - conda create -n -env python=3.13 \ - --file requirements/test.txt \ - --file requirements/conda.txt \ - --file requirements/build.txt - - # Activate the environment - conda activate _env - - # Install your package locally - # `--no-deps` to NOT install packages again from `requirements.pip.txt` - pip install -e . --no-deps - - # Run pytest locally - pytest - - # ... run example tutorials - -.. _attach-image: - -Attach an image to the documentation ------------------------------------- - -Here is how you attach an image to the documentation. The ``/doc/source/img/scikit-package-logo-text.png`` example image is provided in the template. - -.. image:: ./img/scikit-package-logo-text.png - :alt: codecov-in-pr-comment - :width: 400px - :align: center - - -Other useful directives ------------------------ - -Here is how you can do menu selection :menuselection:`Admin --> Settings` and display labels for buttons like :guilabel:`Privacy level`.