diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..0e711179 --- /dev/null +++ b/.clang-format @@ -0,0 +1,10 @@ +BasedOnStyle: Google + +IndentWidth: 2 +ContinuationIndentWidth: 2 +TabWidth: 2 +UseTab: Never + +ColumnLimit: 80 + +SortIncludes: false diff --git a/.codespell/ignore_words.txt b/.codespell/ignore_words.txt new file mode 100644 index 00000000..7825d133 --- /dev/null +++ b/.codespell/ignore_words.txt @@ -0,0 +1,10 @@ +# Please include explanations for each ignored word (lowercase). +# See https://docs.openverse.org/meta/codespell.html for docs. + +# src/diffpy/srreal/BaseDebyeSum.cpp:231,233 +# variable name +multipl + +# src/tests/TestScatteringFactorTable.hpp:73-80 +# Custom alias name of C in test +Ccustom diff --git a/.flake8 b/.flake8 new file mode 100644 index 00000000..1efa4c9d --- /dev/null +++ b/.flake8 @@ -0,0 +1,14 @@ +# 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, + docs/source/conf.py + site_scons/* # bring it back after updating scons tools +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/.gitattributes b/.gitattributes index 503fc76f..91a78d45 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2,5 +2,5 @@ /.gitignore export-ignore /.travis* export-ignore /conda-recipe/ export-ignore -/doc export-ignore +/docs export-ignore gitarchive.cfg export-subst diff --git a/.github/workflows/github-release.yml b/.github/workflows/github-release.yml new file mode 100644 index 00000000..ca55540d --- /dev/null +++ b/.github/workflows/github-release.yml @@ -0,0 +1,67 @@ +name: "Tag-based Release with SHA256" + +on: + push: + tags: + - '*' + +jobs: + release: + runs-on: ubuntu-latest + steps: + + - name: Checkout libdiffpy + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Check permission + id: perm + uses: actions/github-script@v6 + with: + result-encoding: string + script: | + const { data } = await github.rest.repos.getCollaboratorPermissionLevel({ + owner: context.repo.owner, + repo: context.repo.repo, + username: context.actor + }); + return data.permission + + - name: Fail if not maintainer/admin + if: ${{ steps.perm.outputs.result != 'maintain' && steps.perm.outputs.result != 'admin' }} + run: | + echo "${{ github.actor }} is not a maintainer or admin" + exit 1 + + - name: Download tarball + run: | + curl -L "https://codeload.github.com/${{ github.repository }}/tar.gz/${{ github.ref_name }}" \ + -o source.tar.gz + + - name: Compute SHA256 + id: sha + run: | + shasum=$(openssl sha256 source.tar.gz | awk '{print $2}') + echo "sha=$shasum" >> $GITHUB_OUTPUT + + - name: Get tag message + id: tagmsg + run: | + TAG=${GITHUB_REF##*/} + message=$(git tag -l --format='%(contents)' "$TAG") + echo "tag_message<> $GITHUB_OUTPUT + echo "$message" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + + - name: Create GitHub Release + uses: softprops/action-gh-release@v1 + with: + tag_name: ${{ github.ref_name }} + name: Release ${{ github.ref_name }} + body: | + ${{ steps.tagmsg.outputs.tag_message }} + + SHA256 (tar.gz): ${{ steps.sha.outputs.sha }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 496ca8a9..59993767 100644 --- a/.gitignore +++ b/.gitignore @@ -1,19 +1,26 @@ -# Compiled Object files -*.slo -*.lo -*.o +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class +.exp +.lib +.dll # Compiled Dynamic libraries *.so *.dylib +# Compiled Object files +*.slo +*.lo +*.o + # Compiled Static libraries *.lai *.la *.a.sconf_temp # SCons build files -*.pyc .gdb_history .sconf_temp/ .sconsign.dblite @@ -24,9 +31,98 @@ errors.err /sconsvars.py tags +# Distribution / packaging +.Python +env/ +build/ +_build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +venv/ +*.egg-info/ +.installed.cfg +*.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 +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover +.hypothesis/ + +# Translations +*.mo +*.pot + +# Mr Developer +.mr.developer.cfg +.project +.pydevproject + +# 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/ + +# Visual Studio +.vs/* + # eclipse .project .pydevproject +# Ipython Notebook +.ipynb_checkpoints + # source distribution tarball libdiffpy-*.tar.gz 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..1f9b90b9 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,84 @@ +default_language_version: + python: python3 + +exclude: (?x)^.*\.(cif|dat)$ + +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 + - 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 + files: \.py$ + + - repo: https://github.com/pycqa/isort + rev: 5.13.2 + hooks: + - id: isort + args: ["--profile", "black"] + files: \.py$ + + - repo: https://github.com/pycqa/flake8 + rev: 7.0.0 + hooks: + - id: flake8 + files: \.py$ + + - repo: https://github.com/pre-commit/mirrors-clang-format + rev: v20.1.6 + hooks: + - id: clang-format + name: clang-format (C/C++) + files: \.(c|cpp|cc|cxx|h|hpp|hh)$ + + # Add this back after maintainance + # - repo: https://github.com/cpplint/cpplint + # rev: 2.0.2 + # hooks: + # - id: cpplint + # name: cpplint (C/C++) + # files: \.(c|cc|cpp|cxx|h|hh|hpp|hxx)$ + # args: + # - --filter= + # -whitespace/line_length + # ,-legal/copyright + # ,-build/header_guard + # ,-build/include_order + # ,-build/include_what_you_use + + - repo: https://github.com/codespell-project/codespell + rev: v2.3.0 + hooks: + - id: codespell + additional_dependencies: + - tomli + args: + - "--ignore-words=./.codespell/ignore_words.txt" + + - 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] diff --git a/.travis-sconscript.local b/.travis-sconscript.local deleted file mode 100644 index c7fb22be..00000000 --- a/.travis-sconscript.local +++ /dev/null @@ -1,34 +0,0 @@ -# Customize scons build environment. - -Import('env') - -import os - -# Workaround: DEBUG_CPPFLAGS is defined on Linux, but not on Mac OS X. -# Make sure it is always sensibly defined. -os.environ.setdefault('DEBUG_CPPFLAGS', os.environ['CPPFLAGS']) - -# Apply environment settings for Anaconda compilers -env.Replace(CXX=os.environ['CXX']) -if env['build'] == 'fast': - env.MergeFlags(os.environ['CFLAGS']) - env.MergeFlags(os.environ['CPPFLAGS']) - env.MergeFlags(os.environ['CXXFLAGS']) -else: - env.MergeFlags(os.environ['DEBUG_CFLAGS']) - env.MergeFlags(os.environ['DEBUG_CPPFLAGS']) - env.MergeFlags(os.environ['DEBUG_CXXFLAGS']) -env.MergeFlags(os.environ['LDFLAGS']) - -# Silence copious warnings from the boost headers. -P = os.environ['MYPREFIX'] -env.Prepend(CCFLAGS=['-isystem{}/include'.format(P)]) - -# Define path to the shared libraries from Anaconda environment. -L = P + '/lib' -env.Append(LIBPATH=L) -env.Append(LINKFLAGS='-Wl,-rpath,{!r}'.format(L)) -if env['PLATFORM'] == 'posix': - env.Append(LINKFLAGS='-Wl,-rpath-link,{!r}'.format(L)) - -# vim: ft=python diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index c7af470c..00000000 --- a/.travis.yml +++ /dev/null @@ -1,153 +0,0 @@ -dist: xenial -language: cpp - -os: - - linux - - osx - -env: - - MYUSEMC=true MYPYTHON_VERSION=2.7 - - MYUSEMC=true MYPYTHON_VERSION=3.7 - - MYUSEMC=false - -matrix: - exclude: - - os: osx - env: MYUSEMC=true MYPYTHON_VERSION=2.7 - -git: - depth: 999999 - -branches: - except: - - /^v[0-9]/ - - -before_install: - - MYNAME=libdiffpy - - MYCOMMIT="$(git rev-parse HEAD)" - # travis virtual hosts have 2 cores as per https://goo.gl/DQy4oW - - MYNCPU=2 - - umask 022 - - git fetch origin --tags - - 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; - MYPIPFLAGS="--user"; - fi - - MYMCREPO=https://repo.anaconda.com/miniconda - - case ${TRAVIS_OS_NAME} in - linux) - MYMCBUNDLE=Miniconda3-latest-Linux-x86_64.sh; - MYCXXCOMPILER=gxx_linux-64 - ;; - osx) - MYMCBUNDLE=Miniconda3-latest-MacOSX-x86_64.sh; - MYCXXCOMPILER=clangxx_osx-64 - ;; - *) - echo "Unsupported operating system." >&2; - exit 2 ;; - esac - - - mkdir -p ~/pkgs - - - $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 - - $NOMC || conda create --name=testenv --yes $MYCXXCOMPILER - - $NOMC || conda config --add channels diffpy - - - $NOAPT || test "${TRAVIS_OS_NAME}" = "linux" || exit $? - - $NOAPT || sudo apt-get update -qq - - $NOAPT || sudo apt-get install -y - libgsl0-dev libboost-all-dev python-pip - build-essential scons cxxtest - - - $NOBREW || test "${TRAVIS_OS_NAME}" = "osx" || exit $? - - - $NOBREW || brew update - - $NOBREW || brew install gsl - - $NOBREW || brew install scons - - $NOBREW || brew install cxxtest - - $NOBREW || PATH="$(brew --prefix python)/libexec/bin:${PATH}" - - $NOBREW || export CXXTEST="$(brew --prefix cxxtest)"/libexec/bin/cxxtestgen - - - $NOSYS || scons sdist - - $NOSYS || MYTARBUNDLE="$(ls -t "${PWD}"/*.tar.gz | head -1)" - - $NOSYS || pushd ~/pkgs - - $NOSYS || tar xzf "${MYTARBUNDLE}" - - $NOSYS || git clone https://github.com/diffpy/libobjcryst.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 base - - $NOMC || conda build purge - - $NOMC || source activate testenv - - $NOMC || conda install --yes --use-local --file=/tmp/mypackage.txt - - $NOMC || conda install --yes cxxtest scons - - $NOMC || MYPREFIX="${HOME}/mc/envs/testenv" - - - MYSUDO= - - $NOAPT || MYSUDO=sudo - - $NOSYS || $MYSUDO scons -j $MYNCPU -C ~/pkgs/libobjcryst install - - $NOSYS || cd ~/pkgs/"$(basename "${MYTARBUNDLE}" .tar.gz)" - - $NOSYS || scons -j $MYNCPU build=fast lib - - $NOSYS || $MYSUDO scons build=fast install - - $NOSYS || scons -Q build=fast --clean lib - - $NOSYS || MYPREFIX=/usr/local - - # Verify version of the installed library. - - MYINCLUDE="${MYPREFIX}/include" - - MYVERSION="${MYINCLUDE}/diffpy/version.hpp" - - MYGIT_REV=$(grep '^#define DIFFPY_GIT_SHA' "$MYVERSION" | cut -d '"' -f 2) - - if [[ "${MYCOMMIT}" != "${MYGIT_REV}" ]]; then - echo "Version mismatch ${MYCOMMIT} vs ${MYGIT_REV}."; - exit 1; - fi - - - $NOMC || export MYPREFIX - # drop linker flags that spuriously remove linkage with libgslcblas - - $NOMC || LDFLAGS="${LDFLAGS/-Wl,-dead_strip_dylibs/}" - - $NOMC || cp .travis-sconscript.local sconscript.local - - scons -j $MYNCPU build=fast prefix="${MYPREFIX}" test_installed=true alltests - - MYALLTESTSFAST=$(ls -t ${PWD}/build/fast*/tests/alltests | head -1) - - scons -j $MYNCPU build=debug lib alltests - # APT and BREW jobs test builds from expanded source archive, but codecov - # requires compilation from a git repository. Tell scons to do so. - - scons -j $MYNCPU -C $TRAVIS_BUILD_DIR build=coverage lib alltests - - -before_script: - - $NOBREW || USER_BASE="$(python -c 'import site; print(site.USER_BASE)')" - - $NOBREW || PATH="${USER_BASE}/bin:${PATH}" - - -script: - - scons -Q build=debug test - - scons -Q build=debug enable_objcryst=false test - - ${MYALLTESTSFAST} - - scons -j $MYNCPU -C $TRAVIS_BUILD_DIR build=coverage test - - -after_success: - - cd $TRAVIS_BUILD_DIR - - pip install $MYPIPFLAGS codecov - - codecov - - -deploy: - - provider: releases - - draft: true diff --git a/SConstruct b/SConstruct index 5179bba5..7360504c 100644 --- a/SConstruct +++ b/SConstruct @@ -21,7 +21,8 @@ SCons construction environment can be customized in sconscript.local script. """ import os -import platform +from os.path import join as pjoin +from SCons.Script import * def subdictionary(d, keyset): return dict(kv for kv in d.items() if kv[0] in keyset) @@ -37,32 +38,63 @@ DefaultEnvironment(ENV=subdictionary(os.environ, ''' # Create construction environment env = DefaultEnvironment().Clone() -# Variables definitions below work only with 0.98.1 or later. +# Variables definitions below work only with 0.98.1 or later env.EnsureSConsVersion(0, 98, 1) # Customizable compile variables vars = Variables('sconsvars.py') -vars.Add(PathVariable( - 'prefix', - 'installation prefix directory', - '/usr/local')) -vars.Update(env) +# Set PATHs +if 'PREFIX' in os.environ: + vars.Add(PathVariable( + 'prefix', + 'installation prefix directory', + os.environ['PREFIX'])) + vars.Update(env) +elif 'CONDA_PREFIX' in os.environ: + vars.Add(PathVariable( + 'prefix', + 'installation prefix directory', + os.environ['CONDA_PREFIX'])) + vars.Update(env) +else: + vars.Add(PathVariable( + 'prefix', + 'installation prefix directory', + '/usr/local')) + vars.Update(env) + +if env['PLATFORM'] == "win32": + include_path = pjoin(env['prefix'], 'Library', 'include') + lib_path = pjoin(env['prefix'], 'Library', 'lib') + shared_path = pjoin(env['prefix'], 'Library', 'share') + + env['ENV']['TMP'] = os.environ['TMP'] +else: + include_path = pjoin(env['prefix'], 'include') + lib_path = pjoin(env['prefix'], 'lib') + shared_path = pjoin(env['prefix'], 'share') + vars.Add(PathVariable( 'libdir', - 'installation directory for compiled library [prefix/lib]', - env['prefix'] + '/lib', + 'installation directory for compiled programs', + lib_path, PathVariable.PathAccept)) vars.Add(PathVariable( 'includedir', - 'installation directory for C++ header files [prefix/include]', - env['prefix'] + '/include', + 'installation directory for C++ header files', + include_path, PathVariable.PathAccept)) vars.Add(PathVariable( 'datadir', - 'installation directory for architecture independent data [prefix/share]', - env['prefix'] + '/share', + 'installation directory for architecture independent data', + shared_path, PathVariable.PathAccept)) + +env.AppendUnique(CPPPATH=[include_path]) +env.AppendUnique(LIBPATH=[lib_path]) + +# Customizable build variables vars.Add(EnumVariable( 'build', 'compiler settings', @@ -70,7 +102,7 @@ vars.Add(EnumVariable( vars.Add(EnumVariable( 'tool', 'C++ compiler toolkit to be used', - 'default', allowed_values=('default', 'intelc'))) + 'default', allowed_values=('default', 'clang', 'gcc', 'intelc'))) vars.Add(BoolVariable( 'enable_objcryst', 'enable objcryst support, when installed', None)) @@ -83,11 +115,14 @@ vars.Add( vars.Add(BoolVariable( 'test_installed', 'build tests using the installed library.', False)) + vars.Update(env) + env.Help(MY_SCONS_HELP % vars.GenerateHelpText(env)) env['has_objcryst'] = None -btags = [env['build'], platform.machine()] + +btags = [env['build'], env['PLATFORM']] if env['profile']: btags.append('profile') builddir = env.Dir('build/' + '-'.join(btags)) diff --git a/conda-recipe/build.sh b/conda-recipe/build.sh deleted file mode 100644 index 591d6c57..00000000 --- a/conda-recipe/build.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -MYNCPU=$(( (CPU_COUNT > 8) ? 8 : CPU_COUNT )) - -# drop linker flags that spuriously remove linkage with libgslcblas -LDFLAGS="${LDFLAGS/-Wl,-dead_strip_dylibs/}" - -# Apply sconscript.local customizations. -cp ${RECIPE_DIR}/sconscript.local ./ - -# Build and install the library. -scons -j $MYNCPU lib install prefix=$PREFIX diff --git a/conda-recipe/conda_build_config.yaml b/conda-recipe/conda_build_config.yaml deleted file mode 100644 index 3fb0e02f..00000000 --- a/conda-recipe/conda_build_config.yaml +++ /dev/null @@ -1,11 +0,0 @@ -libobjcryst: - - 2017.2.* - -gsl: - - 2.4 - -boost: - - 1.67 - -pin_run_as_build: - libboost: x.x diff --git a/conda-recipe/meta.yaml b/conda-recipe/meta.yaml deleted file mode 100644 index e5fd1eb5..00000000 --- a/conda-recipe/meta.yaml +++ /dev/null @@ -1,51 +0,0 @@ -{% set setupdata = load_setup_py_data(from_recipe_dir=True) %} - -package: - name: libdiffpy - version: {{ setupdata['version'] }} - -source: - # git_url: https://github.com/diffpy/libdiffpy.git - git_url: .. - -build: - number: 0 - run_exports: - - {{ pin_subpackage('libdiffpy', max_pin='x.x') }} - -requirements: - build: - - {{ compiler('cxx') }} - - python - - scons - host: - - libboost {{ boost }} - - gsl {{ gsl }} - - libobjcryst {{ libobjcryst }} - - run: - # NOTE libobjcryst is implicitly added by libobjcryst run_exports - - libboost - - {{ pin_compatible('gsl', min_pin='x.x', max_pin='x') }} - -test: - requires: - - {{ compiler('cxx') }} - - cxxtest - - scons - - source_files: - - SConstruct - - site_scons/ - - src/SConscript - - src/SConscript.configure - - src/tests/ - - # commands: - # Execute the run_test.sh script. - -about: - home: https://github.com/diffpy/libdiffpy - summary: C++ calculators of PDF, bond valence sum and other pair quantities. - license: Modified BSD License - license_file: LICENSE.txt diff --git a/conda-recipe/run_test.sh b/conda-recipe/run_test.sh deleted file mode 100644 index ae0d976d..00000000 --- a/conda-recipe/run_test.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -export CPATH="${PREFIX}/include:${CPATH}" -export LIBRARY_PATH="${PREFIX}/lib:${LIBRARY_PATH}" - -MYNCPU=$(( (CPU_COUNT > 8) ? 8 : CPU_COUNT )) - -# Apply sconscript.local customizations. -cp ${RECIPE_DIR}/sconscript.local ./ - -# Build the unit tests program using the installed library. -scons -j $MYNCPU alltests prefix=$PREFIX test_installed=true - -# Execute the unit tests. -MYALLTESTSFAST=$(ls -t ${PWD}/build/fast*/tests/alltests | head -1) -${MYALLTESTSFAST} 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/conda-recipe/setup.py b/conda-recipe/setup.py deleted file mode 100644 index e03b9486..00000000 --- a/conda-recipe/setup.py +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env python - -"""\ -Dummy distutils setup script that provides version data for meta.yaml. -""" - -import os -import sys -from distutils.core import setup - -MYDIR = os.path.dirname(os.path.abspath(__file__)) -SITESCONSDIR = os.path.abspath(os.path.join(MYDIR, '../site_scons')) -sys.path.insert(0, SITESCONSDIR) - -from libdiffpybuildutils import gitinfo - -ginfo = gitinfo() - -setup( - name='libdiffpy', - version=ginfo['version'], -) diff --git a/doc/manual/Makefile b/docs/Makefile similarity index 100% rename from doc/manual/Makefile rename to docs/Makefile diff --git a/doc/manual/source/conf.py b/docs/source/conf.py similarity index 73% rename from doc/manual/source/conf.py rename to docs/source/conf.py index 12452388..74ef0cd1 100644 --- a/doc/manual/source/conf.py +++ b/docs/source/conf.py @@ -13,75 +13,76 @@ # All configuration values have a default; values that are commented out # serve to show the default. -import sys import os +import sys import time # 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('../../../site_scons')) +# sys.path.insert(0, os.path.abspath('.')) +sys.path.insert(0, os.path.abspath("../../../site_scons")) # 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 ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' +# 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. extensions = [ - 'sphinx.ext.intersphinx', - 'sphinx.ext.ifconfig', - 'm2r', + "sphinx.ext.intersphinx", + "sphinx.ext.ifconfig", + "m2r", ] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # The suffix of source filenames. -source_suffix = ['.rst', '.md'] +source_suffix = [".rst", ".md"] # The encoding of source files. -#source_encoding = 'utf-8-sig' +# source_encoding = 'utf-8-sig' # The master toctree document. -master_doc = 'index' +master_doc = "index" # General information about the project. -project = u'libdiffpy' -copyright = u'%Y, Brookhaven National Laboratory' +project = "libdiffpy" +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 libdiffpybuildutils import getversion + gver = getversion() # The short X.Y version. -vfmt = '%(major)i.%(minor)i' + ('.%(micro)i' if gver['micro'] else '') +vfmt = "%(major)i.%(minor)i" + (".%(micro)i" if gver["micro"] else "") version = vfmt % gver # The full version, including alpha/beta/rc tags. -release = gver['version'] +release = gver["version"] # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. -#language = None +# language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: -#today = '' -fulldate = gver['date'] -today_seconds = time.strptime(fulldate.split()[0], '%Y-%m-%d') -today = time.strftime('%B %d, %Y', today_seconds) +# today = '' +fulldate = gver["date"] +today_seconds = time.strptime(fulldate.split()[0], "%Y-%m-%d") +today = time.strftime("%B %d, %Y", today_seconds) year = today.split()[-1] # Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' +# 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. @@ -89,27 +90,27 @@ # The reST default role (used for this markup: `text`) to use for all # documents. -#default_role = None +# default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True +# add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). -#add_module_names = True +# add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. -#show_authors = False +# 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 = [] +# modindex_common_prefix = [] # If true, keep warnings as "system message" paragraphs in the built documents. -#keep_warnings = False +# keep_warnings = False # Display all warnings for missing links. nitpicky = True @@ -119,35 +120,35 @@ # 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. -#html_theme_path = [] +# html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". -#html_title = None +# html_title = None # A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None +# html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. -#html_logo = None +# html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. -#html_favicon = None +# html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, @@ -157,106 +158,100 @@ # 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 = [] +# 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' +# html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. -#html_use_smartypants = True +# html_use_smartypants = True # Custom sidebar templates, maps document names to template names. -#html_sidebars = {} +# html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. -#html_additional_pages = {} +# html_additional_pages = {} # If false, no module index is generated. -#html_domain_indices = True +# html_domain_indices = True # If false, no index is generated. -#html_use_index = True +# html_use_index = True # If true, the index is split into individual pages for each letter. -#html_split_index = False +# html_split_index = False # If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True +# html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True +# html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True +# html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. -#html_use_opensearch = '' +# html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None +# html_file_suffix = None # Output file base name for HTML help builder. -htmlhelp_basename = 'libdiffpydoc' +htmlhelp_basename = "libdiffpydoc" # -- 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, or own class]). latex_documents = [ - ('index', 'libdiffpy.tex', u'libdiffpy Documentation', - ab_authors, 'manual'), + ("index", "libdiffpy.tex", "libdiffpy Documentation", ab_authors, "manual"), ] # The name of an image file (relative to this directory) to place at the top of # the title page. -#latex_logo = None +# latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. -#latex_use_parts = False +# latex_use_parts = False # If true, show page references after internal links. -#latex_show_pagerefs = False +# latex_show_pagerefs = False # If true, show URL addresses after external links. -#latex_show_urls = False +# latex_show_urls = False # Documents to append as an appendix to all manuals. -#latex_appendices = [] +# latex_appendices = [] # If false, no module index is generated. -#latex_domain_indices = True +# latex_domain_indices = True # -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'libdiffpy', u'libdiffpy Documentation', - ab_authors, 1) -] +man_pages = [("index", "libdiffpy", "libdiffpy Documentation", ab_authors, 1)] # If true, show URL addresses after external links. -#man_show_urls = False +# man_show_urls = False # -- Options for Texinfo output ------------------------------------------- @@ -265,22 +260,28 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', 'libdiffpy', u'libdiffpy Documentation', - ab_authors, 'libdiffpy', 'One line description of project.', - 'Miscellaneous'), + ( + "index", + "libdiffpy", + "libdiffpy Documentation", + ab_authors, + "libdiffpy", + "One line description of project.", + "Miscellaneous", + ), ] # Documents to append as an appendix to all manuals. -#texinfo_appendices = [] +# texinfo_appendices = [] # If false, no module index is generated. -#texinfo_domain_indices = True +# texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' +# texinfo_show_urls = 'footnote' # If true, do not generate a @detailmenu in the "Top" node's menu. -#texinfo_no_detailmenu = False +# texinfo_no_detailmenu = False # Example configuration for intersphinx: refer to the Python standard library. diff --git a/doc/manual/source/index.rst b/docs/source/index.rst similarity index 100% rename from doc/manual/source/index.rst rename to docs/source/index.rst diff --git a/doc/manual/source/license.rst b/docs/source/license.rst similarity index 100% rename from doc/manual/source/license.rst rename to docs/source/license.rst diff --git a/doc/manual/source/release.rst b/docs/source/release.rst similarity index 100% rename from doc/manual/source/release.rst rename to docs/source/release.rst diff --git a/examples/testlib.cpp b/examples/testlib.cpp index 18abadfd..79ad5101 100644 --- a/examples/testlib.cpp +++ b/examples/testlib.cpp @@ -4,16 +4,14 @@ // c++ testlib.cpp -ldiffpy // ./a.out - #include #include -int main(int argc, char* argv[]) -{ - using namespace diffpy::srreal; - ScatteringFactorTablePtr ntbl; - ntbl = ScatteringFactorTable::createByType("neutron"); - ntbl->lookup("Pb"); - std::cout << "Installation of libdiffpy shared library works!\n"; - return 0; +int main(int argc, char* argv[]) { + using namespace diffpy::srreal; + ScatteringFactorTablePtr ntbl; + ntbl = ScatteringFactorTable::createByType("neutron"); + ntbl->lookup("Pb"); + std::cout << "Installation of libdiffpy shared library works!\n"; + return 0; } diff --git a/site_scons/fallback_version.py b/site_scons/fallback_version.py index 01b1119b..058b9857 100644 --- a/site_scons/fallback_version.py +++ b/site_scons/fallback_version.py @@ -1,10 +1,10 @@ #!/usr/bin/env python -''' +""" Definition of FALLBACK_VERSION. Use it when git repository is not available for example, when building from git zip archive. Update FALLBACK_VERSION when tagging a new release. -''' +""" -FALLBACK_VERSION = '1.4.0.post0' +FALLBACK_VERSION = "1.4.1rc1.post0" diff --git a/site_scons/libdiffpybuildutils.py b/site_scons/libdiffpybuildutils.py index a8d8afbd..5312d27b 100644 --- a/site_scons/libdiffpybuildutils.py +++ b/site_scons/libdiffpybuildutils.py @@ -1,7 +1,7 @@ #!/usr/bin/env python -'''Utility functions used by scons and sphinx for version extraction. -''' +"""Utility functions used by scons and sphinx for version extraction. +""" import os import re @@ -21,33 +21,34 @@ def gitinfo(): - 'Extract dictionary of version data from git records.' - from subprocess import Popen, PIPE + "Extract dictionary of version data from git records." + from subprocess import PIPE, Popen + global _cached_gitinfo if _cached_gitinfo is not None: return _cached_gitinfo - nullfile = open(os.devnull, 'w') - kw = dict(stdout=PIPE, stderr=nullfile, cwd=MYDIR, - universal_newlines=True) - proc = Popen(['git', 'describe', '--match=v[[:digit:]]*'], **kw) + nullfile = open(os.devnull, "w") + kw = dict(stdout=PIPE, stderr=nullfile, cwd=MYDIR, universal_newlines=True) + proc = Popen(["git", "describe", "--match=v[[:digit:]]*"], **kw) desc = proc.stdout.read() if proc.wait(): _cached_gitinfo = {} return gitinfo() - proc = Popen(['git', 'log', '-1', '--format=%H %ci'], **kw) + proc = Popen(["git", "log", "-1", "--format=%H %ci"], **kw) glog = proc.stdout.read() - words = desc.strip().split('-') - vtag = words[0].lstrip('v') - vnum = int((words[1:2] or ['0'])[0]) + words = desc.strip().split("-") + vtag = words[0].lstrip("v") + vnum = int((words[1:2] or ["0"])[0]) rv = {} - rv['commit'], rv['date'] = glog.strip().split(None, 1) - rv['patchnumber'] = vnum - rv['version'] = vtag + rv["commit"], rv["date"] = glog.strip().split(None, 1) + rv["patchnumber"] = vnum + rv["version"] = vtag if vnum: - rv['version'] += '.post' + str(vnum) + rv["version"] += ".post" + str(vnum) _cached_gitinfo = rv return gitinfo() + _cached_gitinfo = None @@ -59,41 +60,42 @@ def getversion(): these sources are from git archive bundle. """ from fallback_version import FALLBACK_VERSION - gitarchivecfgfile = os.path.join(MYDIR, 'gitarchive.cfg') + + gitarchivecfgfile = os.path.join(MYDIR, "gitarchive.cfg") assert os.path.isfile(gitarchivecfgfile) with open(gitarchivecfgfile) as fp: gacontent = fp.read() - gaitems = re.findall(r'^(\w+) *= *(\S.*?)\s*$', gacontent, re.M) + gaitems = re.findall(r"^(\w+) *= *(\S.*?)\s*$", gacontent, re.M) ga = dict(gaitems) gi = gitinfo() rv = {} if gi: afb = FALLBACK_VERSION - gfb = gi['version'].split('.post')[0] + '.post0' + gfb = gi["version"].split(".post")[0] + ".post0" if gfb != afb: raise RuntimeError(EMSG_BAD_FALLBACK_VERSION.format(afb, gfb)) rv.update(gi) else: # Not a git repository. Require that gitarchive.cfg is expanded. - if '$Format:' in ga['commit']: + if "$Format:" in ga["commit"]: raise RuntimeError(EMSG_GIT_MISSING) - rv['commit'] = ga['commit'] - rv['date'] = ga['date'] + rv["commit"] = ga["commit"] + rv["date"] = ga["date"] # First assume we have an undetermined post-release. Keep version # suffix as ".post0", but set patchnumber to ensure we are post # FALLBACK_VERSION. - rv['version'] = FALLBACK_VERSION - rv['patchnumber'] = 1 + rv["version"] = FALLBACK_VERSION + rv["patchnumber"] = 1 # If we are at version tag turn this to regular release. - mx = re.search(r'\btag: v(\d[^,]*)', ga['refnames']) + mx = re.search(r"\btag: v(\d[^,]*)", ga["refnames"]) if mx: - rv['version'] = mx.group(1) - rv['patchnumber'] = 0 + rv["version"] = mx.group(1) + rv["patchnumber"] = 0 # rv['version'] is resolved, let's parse its subfields. - vbase = rv['version'].split('.post')[0] - mx = re.match(r'^(\d+)\.(\d+)(?:\.(\d+))?((?:[ab]|rc)\d*)?', vbase) - rv['major'] = int(mx.group(1)) - rv['minor'] = int(mx.group(2)) - rv['micro'] = int(mx.group(3) or 0) - rv['prerelease'] = mx.group(4) + vbase = rv["version"].split(".post")[0] + mx = re.match(r"^(\d+)\.(\d+)(?:\.(\d+))?((?:[ab]|rc)\d*)?", vbase) + rv["major"] = int(mx.group(1)) + rv["minor"] = int(mx.group(2)) + rv["micro"] = int(mx.group(3) or 0) + rv["prerelease"] = mx.group(4) return rv diff --git a/site_scons/site_tools/cxxtest.py b/site_scons/site_tools/cxxtest.py index dc798269..565a27c0 100644 --- a/site_scons/site_tools/cxxtest.py +++ b/site_scons/site_tools/cxxtest.py @@ -1,12 +1,12 @@ # coding=UTF-8 -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # CxxTest: A lightweight C++ unit testing library. # Copyright (c) 2008 Sandia Corporation. # This software is distributed under the LGPL License v3 # For more information, see the COPYING file in the top CxxTest directory. # Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, # the U.S. Government retains certain rights in this software. -#------------------------------------------------------------------------- +# ------------------------------------------------------------------------- # # == Preamble == # Authors of this script are in the Authors file in the same directory as this @@ -63,18 +63,22 @@ # called that. Normal Program builder rules apply. # -from SCons.Script import * +import os + from SCons.Builder import Builder +from SCons.Script import * from SCons.Util import PrependPath, unique, uniquer -import os + # A warning class to notify users of problems class ToolCxxTestWarning(SCons.Warnings.Warning): pass + SCons.Warnings.enableWarningClass(ToolCxxTestWarning) -def accumulateEnvVar(dicts, name, default = []): + +def accumulateEnvVar(dicts, name, default=[]): """ Accumulates the values under key 'name' from the list of dictionaries dict. The default value is appended to the end list if 'name' does not exist in @@ -85,7 +89,8 @@ def accumulateEnvVar(dicts, name, default = []): final += Split(d.get(name, default)) return final -def multiget(dictlist, key, default = None): + +def multiget(dictlist, key, default=None): """ Takes a list of dictionaries as its 1st argument. Checks if the key exists in each one and returns the 1st one it finds. If the key is found in no @@ -97,151 +102,164 @@ def multiget(dictlist, key, default = None): else: return default + def envget(env, key, default=None): """Look in the env, then in os.environ. Otherwise same as multiget.""" return multiget([env, os.environ], key, default) + def prepend_ld_library_path(env, overrides, **kwargs): """Prepend LD_LIBRARY_PATH with LIBPATH to run successfully programs that were linked against local shared libraries.""" # make it unique but preserve order ... - libpath = uniquer(Split(kwargs.get('CXXTEST_LIBPATH', [])) + - Split(env.get( 'CXXTEST_LIBPATH', []))) + libpath = uniquer( + Split(kwargs.get("CXXTEST_LIBPATH", [])) + Split(env.get("CXXTEST_LIBPATH", [])) + ) if len(libpath) > 0: libpath = env.arg2nodes(libpath, env.fs.Dir) - platform = env.get('PLATFORM','') - if platform == 'win32': - var = 'PATH' + platform = env.get("PLATFORM", "") + if platform == "win32": + var = "PATH" else: - var = 'LD_LIBRARY_PATH' - eenv = overrides.get('ENV', env['ENV'].copy()) - canonicalize = lambda p : p.abspath - eenv[var] = PrependPath(eenv.get(var,''), libpath, os.pathsep, 1, canonicalize) - overrides['ENV'] = eenv + var = "LD_LIBRARY_PATH" + eenv = overrides.get("ENV", env["ENV"].copy()) + canonicalize = lambda p: p.abspath + eenv[var] = PrependPath(eenv.get(var, ""), libpath, os.pathsep, 1, canonicalize) + overrides["ENV"] = eenv return overrides -def UnitTest(env, target, source = [], **kwargs): + +def UnitTest(env, target, source=[], **kwargs): """ Prepares the Program call arguments, calls Program and adds the result to the check target. """ # get the c and cxx flags to process. - ccflags = Split( multiget([kwargs, env, os.environ], 'CCFLAGS' )) - cxxflags = Split( multiget([kwargs, env, os.environ], 'CXXFLAGS')) + ccflags = Split(multiget([kwargs, env, os.environ], "CCFLAGS")) + cxxflags = Split(multiget([kwargs, env, os.environ], "CXXFLAGS")) # get the removal c and cxx flags - cxxremove = set( Split( multiget([kwargs, env, os.environ],'CXXTEST_CXXFLAGS_REMOVE'))) - ccremove = set( Split( multiget([kwargs, env, os.environ],'CXXTEST_CCFLAGS_REMOVE' ))) + cxxremove = set( + Split(multiget([kwargs, env, os.environ], "CXXTEST_CXXFLAGS_REMOVE")) + ) + ccremove = set(Split(multiget([kwargs, env, os.environ], "CXXTEST_CCFLAGS_REMOVE"))) # remove the required flags - ccflags = [item for item in ccflags if item not in ccremove] - cxxflags = [item for item in cxxflags if item not in cxxremove] + ccflags = [item for item in ccflags if item not in ccremove] + cxxflags = [item for item in cxxflags if item not in cxxremove] # fill the flags into kwargs kwargs["CXXFLAGS"] = cxxflags - kwargs["CCFLAGS"] = ccflags - test = env.Program(target, source = source, **kwargs) - testCommand = multiget([kwargs, env, os.environ], 'CXXTEST_COMMAND') + kwargs["CCFLAGS"] = ccflags + test = env.Program(target, source=source, **kwargs) + testCommand = multiget([kwargs, env, os.environ], "CXXTEST_COMMAND") if testCommand: - testCommand = testCommand.replace('%t', test[0].abspath) + testCommand = testCommand.replace("%t", test[0].abspath) else: testCommand = test[0].abspath - if multiget([kwargs, env, os.environ], 'CXXTEST_SKIP_ERRORS', False): - runner = env.Action(testCommand, exitstatfunc=lambda x:0) + if multiget([kwargs, env, os.environ], "CXXTEST_SKIP_ERRORS", False): + runner = env.Action(testCommand, exitstatfunc=lambda x: 0) else: runner = env.Action(testCommand) overrides = prepend_ld_library_path(env, {}, **kwargs) - cxxtest_target = multiget([kwargs, env], 'CXXTEST_TARGET') + cxxtest_target = multiget([kwargs, env], "CXXTEST_TARGET") env.Alias(cxxtest_target, test, runner, **overrides) env.AlwaysBuild(cxxtest_target) return test + def isValidScriptPath(cxxtestgen): """check keyword arg or environment variable locating cxxtestgen script""" if cxxtestgen and os.path.exists(cxxtestgen): return True else: - SCons.Warnings.warn(ToolCxxTestWarning, - "Invalid CXXTEST environment variable specified!") + SCons.Warnings.warn( + ToolCxxTestWarning, "Invalid CXXTEST environment variable specified!" + ) return False + def defaultCxxTestGenLocation(env): return os.path.join( - envget(env, 'CXXTEST_CXXTESTGEN_DEFAULT_LOCATION'), - envget(env, 'CXXTEST_CXXTESTGEN_SCRIPT_NAME') - ) + envget(env, "CXXTEST_CXXTESTGEN_DEFAULT_LOCATION"), + envget(env, "CXXTEST_CXXTESTGEN_SCRIPT_NAME"), + ) + def findCxxTestGen(env): """locate the cxxtestgen script by checking environment, path and project""" # check the SCons environment... # Then, check the OS environment... - cxxtest = envget(env, 'CXXTEST', None) + cxxtest = envget(env, "CXXTEST", None) # check for common passing errors and provide diagnostics. if isinstance(cxxtest, (list, tuple, dict)): SCons.Warnings.warn( - ToolCxxTestWarning, - "The CXXTEST variable was specified as a list." - " This is not supported. Please pass a string." - ) + ToolCxxTestWarning, + "The CXXTEST variable was specified as a list." + " This is not supported. Please pass a string.", + ) if cxxtest: try: - #try getting the absolute path of the file first. + # try getting the absolute path of the file first. # Required to expand '#' cxxtest = env.File(cxxtest).abspath except TypeError: try: - #maybe only the directory was specified? + # maybe only the directory was specified? cxxtest = env.File( - os.path.join(cxxtest, defaultCxxTestGenLocation(env) - )).abspath + os.path.join(cxxtest, defaultCxxTestGenLocation(env)) + ).abspath except TypeError: pass # If the user specified the location in the environment, # make sure it was correct if isValidScriptPath(cxxtest): - return os.path.realpath(cxxtest) + return os.path.realpath(cxxtest) # No valid environment variable found, so... # Next, check the path... # Next, check the project check_path = os.path.join( - envget(env, 'CXXTEST_INSTALL_DIR'), - envget(env, 'CXXTEST_CXXTESTGEN_DEFAULT_LOCATION')) + envget(env, "CXXTEST_INSTALL_DIR"), + envget(env, "CXXTEST_CXXTESTGEN_DEFAULT_LOCATION"), + ) - cxxtest = (env.WhereIs(envget(env, 'CXXTEST_CXXTESTGEN_SCRIPT_NAME')) or - env.WhereIs(envget(env, 'CXXTEST_CXXTESTGEN_SCRIPT_NAME'), - path=[Dir(check_path).abspath])) + cxxtest = env.WhereIs(envget(env, "CXXTEST_CXXTESTGEN_SCRIPT_NAME")) or env.WhereIs( + envget(env, "CXXTEST_CXXTESTGEN_SCRIPT_NAME"), path=[Dir(check_path).abspath] + ) if cxxtest: return cxxtest else: # If we weren't able to locate the cxxtestgen script, complain... SCons.Warnings.warn( - ToolCxxTestWarning, - "Unable to locate cxxtestgen in environment, path or" - " project!\n" - "Please set the CXXTEST variable to the path of the" - " cxxtestgen script" - ) + ToolCxxTestWarning, + "Unable to locate cxxtestgen in environment, path or" + " project!\n" + "Please set the CXXTEST variable to the path of the" + " cxxtestgen script", + ) return None + def findCxxTestHeaders(env): - searchfile = 'TestSuite.h' + searchfile = "TestSuite.h" cxxtestgen_pathlen = len(defaultCxxTestGenLocation(env)) - default_path = Dir(envget(env,'CXXTEST_INSTALL_DIR')).abspath + default_path = Dir(envget(env, "CXXTEST_INSTALL_DIR")).abspath - os_cxxtestgen = os.path.realpath(File(env['CXXTEST']).abspath) + os_cxxtestgen = os.path.realpath(File(env["CXXTEST"]).abspath) alt_path = os_cxxtestgen[:-cxxtestgen_pathlen] searchpaths = [default_path, alt_path] foundpaths = [] for p in searchpaths: - if os.path.exists(os.path.join(p, 'cxxtest', searchfile)): + if os.path.exists(os.path.join(p, "cxxtest", searchfile)): foundpaths.append(p) return foundpaths + def generate(env, **kwargs): """ Keyword arguments (all can be set via environment variables as well): @@ -284,52 +302,61 @@ def generate(env, **kwargs): # Expected behaviour: keyword arguments override environment variables; # environment variables override default settings. # - env.SetDefault( CXXTEST_RUNNER = 'ErrorPrinter' ) - env.SetDefault( CXXTEST_OPTS = '' ) - env.SetDefault( CXXTEST_SUFFIX = '.t.h' ) - env.SetDefault( CXXTEST_TARGET = 'check' ) - env.SetDefault( CXXTEST_CPPPATH = ['#'] ) - env.SetDefault( CXXTEST_PYTHON = env.WhereIs('python') ) - env.SetDefault( CXXTEST_SKIP_ERRORS = False ) - env.SetDefault( CXXTEST_CXXFLAGS_REMOVE = - ['-pedantic','-Weffc++','-pedantic-errors'] ) - env.SetDefault( CXXTEST_CCFLAGS_REMOVE = - ['-pedantic','-Weffc++','-pedantic-errors'] ) - env.SetDefault( CXXTEST_INSTALL_DIR = '#/cxxtest/' ) + env.SetDefault(CXXTEST_RUNNER="ErrorPrinter") + env.SetDefault(CXXTEST_OPTS="") + env.SetDefault(CXXTEST_SUFFIX=".t.h") + env.SetDefault(CXXTEST_TARGET="check") + env.SetDefault(CXXTEST_CPPPATH=["#"]) + env.SetDefault(CXXTEST_PYTHON=env.WhereIs("python")) + env.SetDefault(CXXTEST_SKIP_ERRORS=False) + env.SetDefault( + CXXTEST_CXXFLAGS_REMOVE=["-pedantic", "-Weffc++", "-pedantic-errors"] + ) + env.SetDefault(CXXTEST_CCFLAGS_REMOVE=["-pedantic", "-Weffc++", "-pedantic-errors"]) + env.SetDefault(CXXTEST_INSTALL_DIR="#/cxxtest/") # this one's not for public use - it documents where the cxxtestgen script # is located in the CxxTest tree normally. - env.SetDefault( CXXTEST_CXXTESTGEN_DEFAULT_LOCATION = 'bin' ) + env.SetDefault(CXXTEST_CXXTESTGEN_DEFAULT_LOCATION="bin") # the cxxtestgen script name. - env.SetDefault( CXXTEST_CXXTESTGEN_SCRIPT_NAME = 'cxxtestgen' ) + env.SetDefault(CXXTEST_CXXTESTGEN_SCRIPT_NAME="cxxtestgen") - #Here's where keyword arguments are applied + # Here's where keyword arguments are applied env.Replace(**kwargs) - #If the user specified the path to CXXTEST, make sure it is correct - #otherwise, search for and set the default toolpath. - if 'CXXTEST' not in kwargs or not isValidScriptPath(kwargs['CXXTEST']): + # If the user specified the path to CXXTEST, make sure it is correct + # otherwise, search for and set the default toolpath. + if "CXXTEST" not in kwargs or not isValidScriptPath(kwargs["CXXTEST"]): env["CXXTEST"] = findCxxTestGen(env) # find and add the CxxTest headers to the path. - env.AppendUnique( CXXTEST_CPPPATH = findCxxTestHeaders(env) ) + env.AppendUnique(CXXTEST_CPPPATH=findCxxTestHeaders(env)) - cxxtest = env['CXXTEST'] + cxxtest = env["CXXTEST"] if cxxtest: # # Create the Builder (only if we have a valid cxxtestgen!) # cxxtest_builder = Builder( - action = - [["$CXXTEST_PYTHON",cxxtest,"--runner=$CXXTEST_RUNNER", - "$CXXTEST_OPTS","$CXXTEST_ROOT_PART","-o","$TARGET","$SOURCE"]], - suffix = ".cpp", - src_suffix = '$CXXTEST_SUFFIX' - ) + action=[ + [ + "$CXXTEST_PYTHON", + cxxtest, + "--runner=$CXXTEST_RUNNER", + "$CXXTEST_OPTS", + "$CXXTEST_ROOT_PART", + "-o", + "$TARGET", + "$SOURCE", + ] + ], + suffix=".cpp", + src_suffix="$CXXTEST_SUFFIX", + ) else: - cxxtest_builder = (lambda *a: sys.stderr.write("ERROR: CXXTESTGEN NOT FOUND!")) + cxxtest_builder = lambda *a: sys.stderr.write("ERROR: CXXTESTGEN NOT FOUND!") - def CxxTest(env, target, source = None, **kwargs): + def CxxTest(env, target, source=None, **kwargs): """Usage: The function is modelled to be called as the Program() call is: env.CxxTest('target_name') will build the test from the source @@ -344,8 +371,8 @@ def CxxTest(env, target, source = None, **kwargs): for passing different CPPPATHs and the sort. This function also appends CXXTEST_CPPPATH to CPPPATH. It does not clutter the environment's CPPPATH. """ - if (source == None): - suffix = multiget([kwargs, env, os.environ], 'CXXTEST_SUFFIX', "") + if source == None: + suffix = multiget([kwargs, env, os.environ], "CXXTEST_SUFFIX", "") source = [t + suffix for t in target] sources = Flatten(Split(source)) headers = [] @@ -357,7 +384,7 @@ def CxxTest(env, target, source = None, **kwargs): except AttributeError: s = l - if s.endswith(multiget([kwargs, env, os.environ], 'CXXTEST_SUFFIX', None)): + if s.endswith(multiget([kwargs, env, os.environ], "CXXTEST_SUFFIX", None)): headers.append(l) else: linkins.append(l) @@ -370,27 +397,34 @@ def CxxTest(env, target, source = None, **kwargs): else: deps.append(env.CxxTestCpp(headers.pop(0), **kwargs)) deps.extend( - [env.CxxTestCpp(header, CXXTEST_RUNNER = 'none', - CXXTEST_ROOT_PART = '--part', **kwargs) - for header in headers] - ) - deps.extend(linkins) - kwargs['CPPPATH'] = unique( - Split(kwargs.get('CPPPATH', [])) + - Split(env.get( 'CPPPATH', [])) + - Split(kwargs.get('CXXTEST_CPPPATH', [])) + - Split(env.get( 'CXXTEST_CPPPATH', [])) - ) - kwargs['LIBPATH'] = unique( - Split(kwargs.get('LIBPATH', [])) + - Split(env.get( 'LIBPATH', [])) + - Split(kwargs.get('CXXTEST_LIBPATH', [])) + - Split(env.get( 'CXXTEST_LIBPATH', [])) + [ + env.CxxTestCpp( + header, + CXXTEST_RUNNER="none", + CXXTEST_ROOT_PART="--part", + **kwargs + ) + for header in headers + ] ) + deps.extend(linkins) + kwargs["CPPPATH"] = unique( + Split(kwargs.get("CPPPATH", [])) + + Split(env.get("CPPPATH", [])) + + Split(kwargs.get("CXXTEST_CPPPATH", [])) + + Split(env.get("CXXTEST_CPPPATH", [])) + ) + kwargs["LIBPATH"] = unique( + Split(kwargs.get("LIBPATH", [])) + + Split(env.get("LIBPATH", [])) + + Split(kwargs.get("CXXTEST_LIBPATH", [])) + + Split(env.get("CXXTEST_LIBPATH", [])) + ) + + return UnitTest(env, target, source=deps, **kwargs) - return UnitTest(env, target, source = deps, **kwargs) + env.Append(BUILDERS={"CxxTest": CxxTest, "CxxTestCpp": cxxtest_builder}) - env.Append( BUILDERS = { "CxxTest" : CxxTest, "CxxTestCpp" : cxxtest_builder } ) def exists(env): - return os.path.exists(env['CXXTEST']) + return os.path.exists(env["CXXTEST"]) diff --git a/src/SConscript b/src/SConscript index fce570ec..cf2c7a12 100644 --- a/src/SConscript +++ b/src/SConscript @@ -1,66 +1,104 @@ import os +from SCons.Script import * +from os.path import join as pjoin Import('env') # Build environment configuration -------------------------------------------- -# Insert LIBRARY_PATH explicitly because some compilers -# ignore it in the system environment. -env.PrependUnique(LIBPATH=env['ENV'].get('LIBRARY_PATH', '').split(':')) - -# Use Intel C++ compiler if requested by the user. -icpc = None +# Use C++ compiler specified by the 'tool' option. +# Intel C++ compiler 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')]) + env=env.Clone() -fast_linkflags = ['-s'] +# Clang++ compiler +if env['tool'] == 'clang': + llvm = env.WhereIs('clang++') + if not llvm: + print("Cannot find the clang++ compiler.") + Exit(1) + env=env.Clone(tools=['clangxx']) -# 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) +# g++ compiler +if env['tool'] == 'gcc': + gcc = env.WhereIs('g++') + if not gcc: + print("Cannot find the g++ compiler.") + Exit(1) + env=env.Clone(tools=['mingw']) + +# Default use scons auto found compiler # Platform specific intricacies. +fast_linkflags = ['-s'] + +# macOS specific options if env['PLATFORM'] == 'darwin': env.AppendUnique(CXXFLAGS='-ftemplate-depth-256') - env.Append(SHLINKFLAGS=['-install_name', '$TARGET.abspath']) + env.AppendUnique(SHLINKFLAGS=['-install_name', '$TARGET.abspath']) env.AppendUnique(SHLINKFLAGS='-headerpad_max_install_names') fast_linkflags[:] = [] # Compiler specific options -if icpc: - # options for Intel C++ compiler on hpc dev-intel07 - env.PrependUnique(CCFLAGS=['-w1', '-fp-model', 'precise']) - env.PrependUnique(LIBS=['imf']) - fast_optimflags = ['-fast', '-no-ipo'] +if env['PLATFORM'] == "win32": + if env['tool'] == 'clang': + # clang++ on Windows + env['CC'] = 'clang' + env['CCFLAGS'] = ['-O3', '-ffast-math', '-std=c++14', '-m64', '-DBUILD_DLL', '-DREAL=double'] + env.PrependUnique(CPPDEFINES='_USE_MATH_DEFINES') + env['LINKFLAGS']= ['-fuse-ld=lld-link', '-m64', '-lstdc++'] + + elif env['tool'] == 'gcc': + # MinGW + env.PrependUnique(CCFLAGS=['-O3', '-std=c++14', '-m64', '-DBUILD_DLL', '-DREAL=double']) + env.PrependUnique(CPPDEFINES='_USE_MATH_DEFINES') + env.AppendUnique(LINKFLAGS='-m64') + + else: + # Visual c++ + env.PrependUnique(CCFLAGS=['/Ox', '/EHsc', '/MD', '/std:c++14', '/Wall', '/DBUILD_DLL', '/DREAL=double']) + env.AppendUnique(CPPDEFINES=[{'NDEBUG': None}, '_USE_MATH_DEFINES']) + env.AppendUnique(LINKFLAGS=['/OPT:NOREF', '/OPT:NOICF']) + else: - # g++ options - env.PrependUnique(CCFLAGS=['-Wall']) - fast_optimflags = ['-ffast-math'] - -# Configure build variants -if env['build'] == 'debug': - env.Append(CCFLAGS='-g') -elif env['build'] == 'coverage': - env.CacheDir(None) - env.Append(CCFLAGS=['-g', '--coverage', '-O0']) - env.Append(LINKFLAGS='--coverage') -elif env['build'] == 'fast': - env.AppendUnique(CCFLAGS=['-O3'] + fast_optimflags) - env.AppendUnique(CPPDEFINES={'NDEBUG' : None}) - env.AppendUnique(LINKFLAGS=fast_linkflags) - -if env['profile']: - env.AppendUnique(CCFLAGS='-pg') - env.AppendUnique(LINKFLAGS='-pg') + env.PrependUnique(CXXFLAGS='-std=c++11') + if env['tool'] == 'intelc': + # options for Intel C++ compiler on hpc dev-intel07 + env.PrependUnique(CCFLAGS=['-w1', '-fp-model', 'precise']) + env.PrependUnique(LIBS=['imf']) + fast_optimflags = ['-fast', '-no-ipo'] + else: + # g++ options + env.PrependUnique(CCFLAGS=['-Wall', '-DREAL=double']) + fast_optimflags = ['-ffast-math'] + + # Configure build variants + if env['build'] == 'debug': + env.Append(CCFLAGS='-g') + elif env['build'] == 'coverage': + env.CacheDir(None) + env.Append(CCFLAGS=['-g', '--coverage', '-O0']) + env.Append(LINKFLAGS='--coverage') + elif env['build'] == 'fast': + env.AppendUnique(CCFLAGS=['-O3'] + fast_optimflags) + env.AppendUnique(CPPDEFINES={'NDEBUG' : None}) + env.AppendUnique(LINKFLAGS=fast_linkflags) + + if env['profile']: + env.AppendUnique(CCFLAGS='-pg') + env.AppendUnique(LINKFLAGS='-pg') # configure boost and ObjCryst libraries unless non-relevant. skip_configure = (GetOption('clean') or GetOption('help') or (['sdist'] == list(COMMAND_LINE_TARGETS))) + +# Check dependencies if not skip_configure: SConscript('SConscript.configure') @@ -117,11 +155,15 @@ if 'sdist' in COMMAND_LINE_TARGETS: # use new environment with extra libraries needed for libdiffpy. env_lib = env.Clone() # Setup GSL, the GNU Scientific library. -env_lib.ParseConfig("gsl-config --cflags --libs") -# The dladdr call in runtimepath.cpp requires the dl library. -env_lib.AppendUnique(LIBS=['dl']) +# The dladdr call in runtimepath.cpp requires the dl library for Windows. +if env['has_objcryst'] == True: + env_lib.AppendUnique(LIBS=['dl', 'gsl', 'gslcblas','boost_serialization', 'libObjCryst']) +else: + env_lib.AppendUnique(LIBS=['dl', 'gsl', 'gslcblas','boost_serialization']) + libdiffpy = env_lib.SharedLibrary('diffpy', env['lib_sources']) + # Clean up .gcda and .gcno files from coverage analysis. env_lib.Clean(libdiffpy, Glob('diffpy/*.gc??')) env_lib.Clean(libdiffpy, Glob('diffpy/srreal/*.gc??')) @@ -141,17 +183,36 @@ if targets_that_test.intersection(COMMAND_LINE_TARGETS): prefix = env['prefix'] # install-lib -install_lib = env.Install(env['libdir'], libdiffpy) -if env['PLATFORM'] == 'darwin': - # DARWIN_INSTALL_NAME can be pre-set in sconscript.local - env.SetDefault(DARWIN_INSTALL_NAME='$TARGET.abspath') - env.AddPostAction(install_lib, - 'install_name_tool -id $DARWIN_INSTALL_NAME $TARGET') -if env['PLATFORM'] == 'posix' and WhereIs('ldconfig'): - opts = '' if os.getuid() == 0 else '-n' - env.AddPostAction(install_lib, - 'ldconfig %s $TARGET.dir' % opts) -Alias('install-lib', install_lib) +if env['PLATFORM'] in ['darwin', 'posix']: + install_lib = env.Install(env['libdir'], libdiffpy) + if env['PLATFORM'] == 'darwin': + # DARWIN_INSTALL_NAME can be pre-set in sconscript.local + env.SetDefault(DARWIN_INSTALL_NAME='$TARGET.abspath') + env.AddPostAction(install_lib, + 'install_name_tool -id $DARWIN_INSTALL_NAME $TARGET') + if env['PLATFORM'] == 'posix' and WhereIs('ldconfig'): + opts = '' if os.getuid() == 0 else '-n' + env.AddPostAction(install_lib, + 'ldconfig %s $TARGET.dir' % opts) + Alias('install-lib', install_lib) + +if env['PLATFORM'] == 'win32': + bindir = pjoin(prefix, 'Library', 'bin') + for node in libdiffpy: + ext = os.path.splitext(str(node))[1].lower() + if ext == '.dll': + dll_node = node + elif ext == '.lib': + lib_node = node + + if dll_node is None: + print("Warning: DLL file not found in build outputs.") + if lib_node is None: + print("Warning: LIB file not found in build outputs.") + + install_dll = env.Install(bindir, dll_node) + install_lib = env.Install(env['libdir'], lib_node) + Alias('install-lib', [install_dll, install_lib]) # install-include ninc = len(Dir('.').path) + 1 diff --git a/src/SConscript.configure b/src/SConscript.configure index 3bc0568c..e834089f 100644 --- a/src/SConscript.configure +++ b/src/SConscript.configure @@ -19,61 +19,45 @@ def CheckBoostVersion(context, version): context.Result(rv) return rv -# Helper functions ----------------------------------------------------------- - -boostlibtags = ['', '-mt'] -def configure_boost_library(libname): - '''Add a boost library to the configured environment allowing for any - of the boostlibtags name extensions. - - libname -- boost library name without any extension - - Note: CheckLib function automatically adds library to the environment. +def CheckObjCrystVersion(context, version): + '''Check if ObjCryst Library is at least of specified version ''' - # using global conf defined below - for t in boostlibtags: - libnamefull = libname + t - if conf.CheckLib(libnamefull, language='C++'): - boostlibtags[:] = [t] - return - # library not found here - print('This program requires %r library' % libname) - Exit(1) + # Boost versions are in format major.minor.subminor + v_arr = [int(n) for n in version.split(".")] + version_n = str(int(sum([(v * n) for v, n in zip(v_arr, (1e9, 1e6, 1e3))])))+"LL" + context.Message('Checking for ObjCryst version >= %s... ' % (version)) + rv = context.TryCompile('\n'.join([ + '#include ', + '#if LIBOBJCRYST_VERSION < %s', + '#error Installed ObjCryst is too old!', + '#endif', + 'int main() { return 0; }', + '', ]) % version_n, '.cpp') + context.Result(rv) + return rv # Start configuration -------------------------------------------------------- conf = Configure(env, custom_tests={ 'CheckBoostVersion' : CheckBoostVersion, + 'CheckObjCrystVersion' : CheckObjCrystVersion, }) -# Add Conda include and library paths -import os -conda_prefix = Environment(ENV=os.environ)['ENV'].get('CONDA_PREFIX') -if conda_prefix: - env.Append(CPPPATH=[os.path.join(conda_prefix, 'include')]) - env.Append(LIBPATH=[os.path.join(conda_prefix, 'lib')]) - # serialization of unordered_map requires boost 1.56.0 boost_required = '1.56.0' if not conf.CheckBoostVersion(boost_required): print('This software requires Boost %s or later.' % boost_required) Exit(1) -# boost_serialization -configure_boost_library('boost_serialization') - -# ObjCryst - assume a no-objcryst fallback configuration. -conf.env['has_objcryst'] = False -# Detect ObjCryst and exit with error if requested and not found. -# By default conf.env does not contain the 'enable_objcryst' key. +# Check for ObjCryst library if conf.env.get('enable_objcryst', True): - conf.env['has_objcryst'] = conf.CheckLibWithHeader( - 'ObjCryst', 'ObjCryst/ObjCryst/Crystal.h', - language='C++', autoadd=True) - objcryst_requested = conf.env.get('enable_objcryst', False) - if objcryst_requested and not conf.env['has_objcryst']: - print("Adjust compiler paths or build with 'enable_objcryst=False'.") + if not conf.CheckObjCrystVersion('2017.2.1'): + print('ObjCryst library not found. Please install it or disable it.') Exit(1) + else: + conf.env['has_objcryst'] = True +else: + conf.env['has_objcryst'] = False env = conf.Finish() diff --git a/src/diffpy/Attributes.cpp b/src/diffpy/Attributes.cpp index ab2db890..2307182d 100644 --- a/src/diffpy/Attributes.cpp +++ b/src/diffpy/Attributes.cpp @@ -1,21 +1,21 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class Attributes - interface for calling setter and getter methods using -* their string names. -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class Attributes - interface for calling setter and getter methods using + * their string names. + * + *****************************************************************************/ #include @@ -32,192 +32,136 @@ namespace attributes { // Public Methods ------------------------------------------------------------ -double Attributes::getDoubleAttr(const string& name) const -{ - this->checkAttributeName(name); - GetDoubleAttrVisitor vg(name); - this->accept(vg); - return vg.getValue(); +double Attributes::getDoubleAttr(const string& name) const { + this->checkAttributeName(name); + GetDoubleAttrVisitor vg(name); + this->accept(vg); + return vg.getValue(); } - -void Attributes::setDoubleAttr(const string& name, double value) -{ - this->checkAttributeName(name); - SetDoubleAttrVisitor vs(name, value); - this->accept(vs); +void Attributes::setDoubleAttr(const string& name, double value) { + this->checkAttributeName(name); + SetDoubleAttrVisitor vs(name, value); + this->accept(vs); } - -bool Attributes::hasDoubleAttr(const string& name) const -{ - CountDoubleAttrVisitor vc(name); - this->accept(vc); - return vc.count(); +bool Attributes::hasDoubleAttr(const string& name) const { + CountDoubleAttrVisitor vc(name); + this->accept(vc); + return vc.count(); } - -set Attributes::namesOfDoubleAttributes() const -{ - const bool excludereadonly = false; - NamesOfDoubleAttributesVisitor vn(excludereadonly); - this->accept(vn); - set rv = vn.names(); - return rv; +set Attributes::namesOfDoubleAttributes() const { + const bool excludereadonly = false; + NamesOfDoubleAttributesVisitor vn(excludereadonly); + this->accept(vn); + set rv = vn.names(); + return rv; } - -set Attributes::namesOfWritableDoubleAttributes() const -{ - const bool excludereadonly = true; - NamesOfDoubleAttributesVisitor vn(excludereadonly); - this->accept(vn); - set rv = vn.names(); - return rv; +set Attributes::namesOfWritableDoubleAttributes() const { + const bool excludereadonly = true; + NamesOfDoubleAttributesVisitor vn(excludereadonly); + this->accept(vn); + set rv = vn.names(); + return rv; } // Private Methods ----------------------------------------------------------- -void Attributes::checkAttributeName(const string& name) const -{ - CountDoubleAttrVisitor v(name); - this->accept(v); - if (v.count() == 0) - { - ostringstream emsg; - emsg << "Invalid attribute name '" << name << "'."; - throw DoubleAttributeError(emsg.str()); - } - else if (v.count() > 1) - { - ostringstream emsg; - emsg << "Duplicate attribute '" << name << "'."; - throw logic_error(emsg.str()); - } +void Attributes::checkAttributeName(const string& name) const { + CountDoubleAttrVisitor v(name); + this->accept(v); + if (v.count() == 0) { + ostringstream emsg; + emsg << "Invalid attribute name '" << name << "'."; + throw DoubleAttributeError(emsg.str()); + } else if (v.count() > 1) { + ostringstream emsg; + emsg << "Duplicate attribute '" << name << "'."; + throw logic_error(emsg.str()); + } } // Visitor Classes ----------------------------------------------------------- // CountDoubleAttrVisitor -Attributes::CountDoubleAttrVisitor:: -CountDoubleAttrVisitor(const string& name) : - mname(name), - mcount(0) -{ } +Attributes::CountDoubleAttrVisitor::CountDoubleAttrVisitor(const string& name) + : mname(name), mcount(0) {} - -void Attributes::CountDoubleAttrVisitor:: -visit(const Attributes& a) -{ - mcount += a.mdoubleattrs.count(mname); +void Attributes::CountDoubleAttrVisitor::visit(const Attributes& a) { + mcount += a.mdoubleattrs.count(mname); } - -int Attributes::CountDoubleAttrVisitor:: -count() const -{ - return mcount; -} +int Attributes::CountDoubleAttrVisitor::count() const { return mcount; } // GetDoubleAttrVisitor -Attributes::GetDoubleAttrVisitor:: -GetDoubleAttrVisitor(const string& name) : - mname(name) -{ } - - -void Attributes::GetDoubleAttrVisitor:: -visit(const Attributes& a) -{ - DoubleAttributeStorage::const_iterator ai; - ai = a.mdoubleattrs.find(mname); - if (ai != a.mdoubleattrs.end()) - { - mvalue = ai->second->getValue(&a); - } -} +Attributes::GetDoubleAttrVisitor::GetDoubleAttrVisitor(const string& name) + : mname(name) {} - -double Attributes::GetDoubleAttrVisitor:: -getValue() const -{ - return mvalue; +void Attributes::GetDoubleAttrVisitor::visit(const Attributes& a) { + DoubleAttributeStorage::const_iterator ai; + ai = a.mdoubleattrs.find(mname); + if (ai != a.mdoubleattrs.end()) { + mvalue = ai->second->getValue(&a); + } } -// SetDoubleAttrVisitor +double Attributes::GetDoubleAttrVisitor::getValue() const { return mvalue; } -Attributes::SetDoubleAttrVisitor:: -SetDoubleAttrVisitor(const string& name, double value) : - mname(name), - mvalue(value) -{ } +// SetDoubleAttrVisitor +Attributes::SetDoubleAttrVisitor::SetDoubleAttrVisitor(const string& name, + double value) + : mname(name), mvalue(value) {} -void Attributes::SetDoubleAttrVisitor:: -visit(const Attributes& a) -{ - const char* emsg = "Cannot set attribute of a const instance."; - throw logic_error(emsg); +void Attributes::SetDoubleAttrVisitor::visit(const Attributes& a) { + const char* emsg = "Cannot set attribute of a const instance."; + throw logic_error(emsg); } - -void Attributes::SetDoubleAttrVisitor:: -visit(Attributes& a) -{ - DoubleAttributeStorage::iterator ai; - ai = a.mdoubleattrs.find(mname); - if (ai != a.mdoubleattrs.end()) - { - ai->second->setValue(&a, mvalue); - } +void Attributes::SetDoubleAttrVisitor::visit(Attributes& a) { + DoubleAttributeStorage::iterator ai; + ai = a.mdoubleattrs.find(mname); + if (ai != a.mdoubleattrs.end()) { + ai->second->setValue(&a, mvalue); + } } // NamesOfDoubleAttributesVisitor -Attributes::NamesOfDoubleAttributesVisitor:: -NamesOfDoubleAttributesVisitor(bool excludereadonly) -{ - mexcludereadonly = excludereadonly; +Attributes::NamesOfDoubleAttributesVisitor::NamesOfDoubleAttributesVisitor( + bool excludereadonly) { + mexcludereadonly = excludereadonly; } - -void Attributes::NamesOfDoubleAttributesVisitor:: -visit(const Attributes& a) -{ - DoubleAttributeStorage::const_iterator ati; - for (ati = a.mdoubleattrs.begin(); ati != a.mdoubleattrs.end(); ++ati) - { - if (mexcludereadonly && ati->second->isreadonly()) continue; - mnames.insert(ati->first); - } +void Attributes::NamesOfDoubleAttributesVisitor::visit(const Attributes& a) { + DoubleAttributeStorage::const_iterator ati; + for (ati = a.mdoubleattrs.begin(); ati != a.mdoubleattrs.end(); ++ati) { + if (mexcludereadonly && ati->second->isreadonly()) continue; + mnames.insert(ati->first); + } } - -const set& Attributes::NamesOfDoubleAttributesVisitor:: -names() const -{ - return mnames; +const set& Attributes::NamesOfDoubleAttributesVisitor::names() const { + return mnames; } // Non-member Helpers -------------------------------------------------------- -void registerBaseDoubleAttribute(Attributes* obj, - const string& name, BaseDoubleAttribute* pa) -{ - obj->mdoubleattrs[name].reset(pa); +void registerBaseDoubleAttribute(Attributes* obj, const string& name, + BaseDoubleAttribute* pa) { + obj->mdoubleattrs[name].reset(pa); } - -void throwDoubleAttributeReadOnly() -{ - const char* emsg = - "Cannot change value of read-only DoubleAttribute."; - throw DoubleAttributeError(emsg); +void throwDoubleAttributeReadOnly() { + const char* emsg = "Cannot change value of read-only DoubleAttribute."; + throw DoubleAttributeError(emsg); } -} // namespace attributes -} // namespace diffpy +} // namespace attributes +} // namespace diffpy // End of file diff --git a/src/diffpy/Attributes.hpp b/src/diffpy/Attributes.hpp index 8e6a9ae6..1f70b8d7 100644 --- a/src/diffpy/Attributes.hpp +++ b/src/diffpy/Attributes.hpp @@ -1,21 +1,21 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class Attributes - interface for calling setter and getter methods using -* their string names. -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class Attributes - interface for calling setter and getter methods using + * their string names. + * + *****************************************************************************/ #ifndef ATTRIBUTES_HPP_INCLUDED #define ATTRIBUTES_HPP_INCLUDED @@ -26,6 +26,8 @@ #include #include +#include + namespace diffpy { namespace attributes { @@ -35,39 +37,30 @@ class Attributes; /// @brief custom exception for Attributes-related errors. This is /// thrown for invalid names or for attempts to set a read-only attribute. -class DoubleAttributeError : public std::runtime_error -{ - public: - DoubleAttributeError(const std::string msg="") : - std::runtime_error(msg) - { } +class DoubleAttributeError : public std::runtime_error { + public: + DoubleAttributeError(const std::string msg = "") : std::runtime_error(msg) {} }; /// @class BaseDoubleAttribute /// @brief abstract base class for accessing a particular double attribute -class BaseDoubleAttribute -{ - public: - - virtual ~BaseDoubleAttribute() { } - virtual double getValue(const Attributes* obj) const = 0; - virtual void setValue(Attributes* obj, double value) = 0; - virtual bool isreadonly() const = 0; +class DLL_EXPORT BaseDoubleAttribute { + public: + virtual ~BaseDoubleAttribute() {} + virtual double getValue(const Attributes* obj) const = 0; + virtual void setValue(Attributes* obj, double value) = 0; + virtual bool isreadonly() const = 0; }; +class BaseAttributesVisitor { + public: + virtual ~BaseAttributesVisitor() {} -class BaseAttributesVisitor -{ - public: - - virtual ~BaseAttributesVisitor() { } - - virtual void visit(const Attributes& a) = 0; - virtual void visit(Attributes& a) - { - visit(static_cast(a)); - } + virtual void visit(const Attributes& a) = 0; + virtual void visit(Attributes& a) { + visit(static_cast(a)); + } }; /// @class Attributes @@ -75,124 +68,106 @@ class BaseAttributesVisitor /// should derive from Attributes and register their setter and /// getter methods in their constructors. -class Attributes -{ - public: - - // class is virtual - virtual ~Attributes() { } - - // assignments in derived classes should not change mdoubleattrs - // mdoubleattrs should be only changed via registerDoubleAttribute - Attributes& operator=(const Attributes& other) { return *this; } - - // methods - double getDoubleAttr(const std::string& name) const; - void setDoubleAttr(const std::string& name, double value); - bool hasDoubleAttr(const std::string& name) const; - std::set namesOfDoubleAttributes() const; - std::set namesOfWritableDoubleAttributes() const; - // visitors - virtual void accept(BaseAttributesVisitor& v) { v.visit(*this); } - virtual void accept(BaseAttributesVisitor& v) const { v.visit(*this); } - - protected: - - friend void registerBaseDoubleAttribute(Attributes*, - const std::string&, attributes::BaseDoubleAttribute* pa); - template - void registerDoubleAttribute(const std::string& name, T* obj, Getter); - template - void registerDoubleAttribute(const std::string& name, T* obj, Getter, Setter); - - private: - - // types - typedef std::map > - DoubleAttributeStorage; - // data - DoubleAttributeStorage mdoubleattrs; - - // methods - void checkAttributeName(const std::string& name) const; - - // visitor classes - - class CountDoubleAttrVisitor : public BaseAttributesVisitor - { - public: - - CountDoubleAttrVisitor(const std::string& name); - virtual void visit(const Attributes& a); - int count() const; - - private: - - // data - const std::string& mname; - int mcount; - }; - - - class GetDoubleAttrVisitor : public BaseAttributesVisitor - { - public: - - GetDoubleAttrVisitor(const std::string& name); - virtual void visit(const Attributes& a); - double getValue() const; - - private: - - // data - const std::string& mname; - double mvalue; - }; - - - class SetDoubleAttrVisitor : public BaseAttributesVisitor - { - public: - - SetDoubleAttrVisitor(const std::string& name, double value); - virtual void visit(const Attributes& a); - virtual void visit(Attributes& a); - - private: - - // data - const std::string& mname; - double mvalue; - }; - - - class NamesOfDoubleAttributesVisitor : public BaseAttributesVisitor - { - public: - - NamesOfDoubleAttributesVisitor(bool excludereadonly); - virtual void visit(const Attributes& a); - const std::set& names() const; - - private: - - // data - bool mexcludereadonly; - std::set mnames; - }; +class DLL_EXPORT Attributes { + public: + // class is virtual + virtual ~Attributes() {} + + // assignments in derived classes should not change mdoubleattrs + // mdoubleattrs should be only changed via registerDoubleAttribute + Attributes& operator=(const Attributes& other) { return *this; } + + // methods + double getDoubleAttr(const std::string& name) const; + void setDoubleAttr(const std::string& name, double value); + bool hasDoubleAttr(const std::string& name) const; + std::set namesOfDoubleAttributes() const; + std::set namesOfWritableDoubleAttributes() const; + // visitors + virtual void accept(BaseAttributesVisitor& v) { v.visit(*this); } + virtual void accept(BaseAttributesVisitor& v) const { v.visit(*this); } + + protected: + friend DLL_EXPORT void registerBaseDoubleAttribute( + Attributes*, const std::string&, attributes::BaseDoubleAttribute* pa); + template + void registerDoubleAttribute(const std::string& name, T* obj, Getter); + template + void registerDoubleAttribute(const std::string& name, T* obj, Getter, Setter); + + private: + // types + typedef std::map > + DoubleAttributeStorage; + // data + DoubleAttributeStorage mdoubleattrs; + + // methods + void checkAttributeName(const std::string& name) const; + + // visitor classes + + class CountDoubleAttrVisitor : public BaseAttributesVisitor { + public: + CountDoubleAttrVisitor(const std::string& name); + virtual void visit(const Attributes& a); + int count() const; + + private: + // data + const std::string& mname; + int mcount; + }; + + class GetDoubleAttrVisitor : public BaseAttributesVisitor { + public: + GetDoubleAttrVisitor(const std::string& name); + virtual void visit(const Attributes& a); + double getValue() const; + + private: + // data + const std::string& mname; + double mvalue; + }; + + class SetDoubleAttrVisitor : public BaseAttributesVisitor { + public: + SetDoubleAttrVisitor(const std::string& name, double value); + virtual void visit(const Attributes& a); + virtual void visit(Attributes& a); + + private: + // data + const std::string& mname; + double mvalue; + }; + + class NamesOfDoubleAttributesVisitor : public BaseAttributesVisitor { + public: + NamesOfDoubleAttributesVisitor(bool excludereadonly); + virtual void visit(const Attributes& a); + const std::set& names() const; + + private: + // data + bool mexcludereadonly; + std::set mnames; + }; }; // class Attributes // non-member helpers -void registerBaseDoubleAttribute(Attributes* obj, - const std::string& name, BaseDoubleAttribute* pa); +DLL_EXPORT void registerBaseDoubleAttribute(Attributes* obj, + const std::string& name, + BaseDoubleAttribute* pa); -void throwDoubleAttributeReadOnly(); +DLL_EXPORT void throwDoubleAttributeReadOnly(); -} // namespace attributes -} // namespace diffpy +} // namespace attributes +} // namespace diffpy // Implementation ------------------------------------------------------------ @@ -200,8 +175,8 @@ void throwDoubleAttributeReadOnly(); // make selected classes visible in diffpy namespace namespace diffpy { - using attributes::Attributes; - using attributes::BaseAttributesVisitor; -} +using attributes::Attributes; +using attributes::BaseAttributesVisitor; +} // namespace diffpy #endif // ATTRIBUTES_HPP_INCLUDED diff --git a/src/diffpy/EventTicker.cpp b/src/diffpy/EventTicker.cpp index 5caf20fb..7da4f04a 100644 --- a/src/diffpy/EventTicker.cpp +++ b/src/diffpy/EventTicker.cpp @@ -1,24 +1,24 @@ /***************************************************************************** -* -* libdiffpy Complex Modeling Initiative -* (c) 2013 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. -* -****************************************************************************** -* -* class EventTicker for managing modification times of dependent objects. -* -* This is used to determine if cached values need update, due to a change -* of their dependencies. The EventTicker class is inspired by the -* ObjCryst::RefinableObjClock class. -* -*****************************************************************************/ + * + * libdiffpy Complex Modeling Initiative + * (c) 2013 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. + * + ****************************************************************************** + * + * class EventTicker for managing modification times of dependent objects. + * + * This is used to determine if cached values need update, due to a change + * of their dependencies. The EventTicker class is inspired by the + * ObjCryst::RefinableObjClock class. + * + *****************************************************************************/ #include #include @@ -32,77 +32,55 @@ namespace eventticker { // Constructor --------------------------------------------------------------- -EventTicker::EventTicker() : mtick(0, 0) -{ } +EventTicker::EventTicker() : mtick(0, 0) {} // Public Methods ------------------------------------------------------------ -void EventTicker::click() -{ - ++gtick.second; - if (0 >= gtick.second) - { - ++gtick.first; - gtick.second = 0; - } - mtick = gtick; +void EventTicker::click() { + ++gtick.second; + if (0 >= gtick.second) { + ++gtick.first; + gtick.second = 0; + } + mtick = gtick; } - -void EventTicker::updateFrom(const EventTicker& other) -{ - if (other > *this) mtick = other.mtick; +void EventTicker::updateFrom(const EventTicker& other) { + if (other > *this) mtick = other.mtick; } +EventTicker::value_type EventTicker::value() const { return mtick; } -EventTicker::value_type EventTicker::value() const -{ - return mtick; +bool EventTicker::operator<(const EventTicker& other) const { + return mtick < other.mtick; } - -bool EventTicker::operator<(const EventTicker& other) const -{ - return mtick < other.mtick; -} - - -bool EventTicker::operator<=(const EventTicker& other) const -{ - return mtick <= other.mtick; +bool EventTicker::operator<=(const EventTicker& other) const { + return mtick <= other.mtick; } - -bool EventTicker::operator>(const EventTicker& other) const -{ - return mtick > other.mtick; +bool EventTicker::operator>(const EventTicker& other) const { + return mtick > other.mtick; } - -bool EventTicker::operator>=(const EventTicker& other) const -{ - return mtick >= other.mtick; +bool EventTicker::operator>=(const EventTicker& other) const { + return mtick >= other.mtick; } - -bool EventTicker::operator==(const EventTicker& other) const -{ - return mtick == other.mtick; +bool EventTicker::operator==(const EventTicker& other) const { + return mtick == other.mtick; } - -bool EventTicker::operator!=(const EventTicker& other) const -{ - return mtick != other.mtick; +bool EventTicker::operator!=(const EventTicker& other) const { + return mtick != other.mtick; } - // Static Global Data -------------------------------------------------------- EventTicker::value_type EventTicker::gtick(0, 0); -} // namespace eventticker -} // namespace diffpy +} // namespace eventticker +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/EventTicker.hpp b/src/diffpy/EventTicker.hpp index 54d11ef7..ec7cef36 100644 --- a/src/diffpy/EventTicker.hpp +++ b/src/diffpy/EventTicker.hpp @@ -1,24 +1,24 @@ /***************************************************************************** -* -* libdiffpy Complex Modeling Initiative -* (c) 2013 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. -* -****************************************************************************** -* -* class EventTicker for managing modification times of dependent objects. -* -* This is used to determine if cached values need update, due to a change -* of their dependencies. The EventTicker class is inspired by the -* ObjCryst::RefinableObjClock class. -* -*****************************************************************************/ + * + * libdiffpy Complex Modeling Initiative + * (c) 2013 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. + * + ****************************************************************************** + * + * class EventTicker for managing modification times of dependent objects. + * + * This is used to determine if cached values need update, due to a change + * of their dependencies. The EventTicker class is inspired by the + * ObjCryst::RefinableObjClock class. + * + *****************************************************************************/ #ifndef EVENTTICKER_HPP_INCLUDED #define EVENTTICKER_HPP_INCLUDED @@ -26,68 +26,65 @@ #include #include +#include + namespace diffpy { namespace eventticker { -class EventTicker -{ - public: - - // constructor - EventTicker(); - - // types - typedef std::pair value_type; - - // methods - /// record an event and advance the global ticker. - void click(); - /// advance internal ticker if the other ticker is newer. - void updateFrom(const EventTicker& other); - /// return the internal ticker value - value_type value() const; - - // comparison - bool operator<(const EventTicker&) const; - bool operator<=(const EventTicker&) const; - bool operator>(const EventTicker&) const; - bool operator>=(const EventTicker&) const; - bool operator==(const EventTicker&) const; - bool operator!=(const EventTicker&) const; - - private: - - // global counter - static value_type gtick; - - // data - value_type mtick; - - // serialization - friend class boost::serialization::access; - template - void save(Archive& ar, const unsigned int version) const - { - ar << mtick << gtick; - } - - template - void load(Archive& ar, const unsigned int version) - { - value_type ga; - ar >> mtick >> ga; - if (ga > gtick) - { - if (ga.first != gtick.first) mtick.first = mtick.second = 0; - else mtick.second += gtick.second - ga.second; - } - } - - BOOST_SERIALIZATION_SPLIT_MEMBER() - +class DLL_EXPORT EventTicker { + public: + // constructor + EventTicker(); + + // types + typedef std::pair value_type; + + // methods + /// record an event and advance the global ticker. + void click(); + /// advance internal ticker if the other ticker is newer. + void updateFrom(const EventTicker& other); + /// return the internal ticker value + value_type value() const; + + // comparison + bool operator<(const EventTicker&) const; + bool operator<=(const EventTicker&) const; + bool operator>(const EventTicker&) const; + bool operator>=(const EventTicker&) const; + bool operator==(const EventTicker&) const; + bool operator!=(const EventTicker&) const; + + private: + // global counter + static value_type gtick; + + // data + value_type mtick; + + // serialization + friend class boost::serialization::access; + template + void save(Archive& ar, const unsigned int version) const { + ar << mtick << gtick; + } + + template + void load(Archive& ar, const unsigned int version) { + value_type ga; + ar >> mtick >> ga; + if (ga > gtick) { + if (ga.first != gtick.first) + mtick.first = mtick.second = 0; + else + mtick.second += gtick.second - ga.second; + } + } + + BOOST_SERIALIZATION_SPLIT_MEMBER() }; -} // namespace eventticker -} // namespace diffpy +} // namespace eventticker +} // namespace diffpy #endif // EVENTTICKER_HPP_INCLUDED diff --git a/src/diffpy/Export.hpp b/src/diffpy/Export.hpp new file mode 100644 index 00000000..a998ff22 --- /dev/null +++ b/src/diffpy/Export.hpp @@ -0,0 +1,11 @@ +#pragma once + +#if defined(_WIN32) +#if defined(BUILD_DLL) +#define DLL_EXPORT __declspec(dllexport) +#else +#define DLL_EXPORT __declspec(dllimport) +#endif +#else +#define DLL_EXPORT +#endif diff --git a/src/diffpy/HasClassRegistry.hpp b/src/diffpy/HasClassRegistry.hpp index b3f2a55a..2b94e753 100644 --- a/src/diffpy/HasClassRegistry.hpp +++ b/src/diffpy/HasClassRegistry.hpp @@ -1,28 +1,28 @@ /***************************************************************************** -* -* libdiffpy 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. -* -****************************************************************************** -* -* class HasClassRegistry -- template class providing registry for factory -* functions that produce derived classes. To be used as a base for a -* specific class branch. For a proper function, the HasClassRegistry -* template must be instantiated in just one cpp file that includes the -* implementatios in HasClassRegistry.ipp. -* -* A Base class with registry should be declared as -* class Base : public HasClassRegistry -* The derived classes need to implement create, clone and type methods. -* -*****************************************************************************/ + * + * libdiffpy 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. + * + ****************************************************************************** + * + * class HasClassRegistry -- template class providing registry for factory + * functions that produce derived classes. To be used as a base for a + * specific class branch. For a proper function, the HasClassRegistry + * template must be instantiated in just one cpp file that includes the + * implementations in HasClassRegistry.ipp. + * + * A Base class with registry should be declared as + * class Base : public HasClassRegistry + * The derived classes need to implement create, clone and type methods. + * + *****************************************************************************/ #ifndef HASCLASSREGISTRY_HPP_INCLUDED #define HASCLASSREGISTRY_HPP_INCLUDED @@ -37,63 +37,59 @@ namespace diffpy { template -class HasClassRegistry -{ - public: +class HasClassRegistry { + public: + // types + typedef boost::shared_ptr SharedPtr; - // types - typedef boost::shared_ptr SharedPtr; + // Contains virtual methods + virtual ~HasClassRegistry() {} - // Contains virtual methods - virtual ~HasClassRegistry() { } + // methods that have to be implemented in the TBase-derived classes + virtual SharedPtr create() const = 0; + virtual SharedPtr clone() const = 0; + virtual const std::string& type() const = 0; - // methods that have to be implemented in the TBase-derived classes - virtual SharedPtr create() const = 0; - virtual SharedPtr clone() const = 0; - virtual const std::string& type() const = 0; + // methods provided by HasClassRegistry - // methods provided by HasClassRegistry + /// Add a prototype of this instance to the registry. + virtual bool registerThisType() const; - /// Add a prototype of this instance to the registry. - virtual bool registerThisType() const; + /// Make registered type tp available under a different alias. + static bool aliasType(const std::string& tp, const std::string& al); - /// Make registered type tp available under a different alias. - static bool aliasType(const std::string& tp, const std::string& al); + /// Clear registration of the specified type under its standard name + /// or any alias. Return the number of unset names and aliases or + /// 0 if the specified string type was not registered. + static int deregisterType(const std::string& tp); - /// Clear registration of the specified type under its standard name - /// or any alias. Return the number of unset names and aliases or - /// 0 if the specifed string type was not registered. - static int deregisterType(const std::string& tp); + /// Create new instance of a specified string type. + static SharedPtr createByType(const std::string& tp); - /// Create new instance of a specified string type. - static SharedPtr createByType(const std::string& tp); + /// Return true if string is a registered string type or its alias. + static bool isRegisteredType(const std::string& tp); - /// Return true if string is a registered string type or its alias. - static bool isRegisteredType(const std::string& tp); + /// Return a map of string aliases to standard type strings. + static std::map getAliasedTypes(); - /// Return a map of string aliases to standard type strings. - static std::map getAliasedTypes(); + /// Return a set of all registered string types + static std::set getRegisteredTypes(); - /// Return a set of all registered string types - static std::set getRegisteredTypes(); + protected: + /// Optional setup for the registered object. + /// + /// This is used for increasing reference count on Python-extended + /// classes, so they are not destroyed before destroying the C++ + /// object registry. + virtual void setupRegisteredObject(SharedPtr p) const {} - protected: + private: + typedef std::map RegistryStorage; - /// Optional setup for the registered object. - /// - /// This is used for increasing reference count on Python-extended - /// classes, so they are not destroyed before destroying the C++ - /// object registry. - virtual void setupRegisteredObject(SharedPtr p) const { } - - private: - - typedef std::map RegistryStorage; - - /// Return a singleton instance of internal registry - static RegistryStorage& getRegistry(); + /// Return a singleton instance of internal registry + static RegistryStorage& getRegistry(); }; -} // namespace diffpy +} // namespace diffpy #endif // HASCLASSREGISTRY_HPP_INCLUDED diff --git a/src/diffpy/SConscript b/src/diffpy/SConscript index 8e3c07d8..f8b8ad6f 100644 --- a/src/diffpy/SConscript +++ b/src/diffpy/SConscript @@ -4,9 +4,12 @@ Import('env', 'GlobSources') env['lib_includes'] += GlobSources('*.[hi]pp') env['lib_sources'] += [f for f in GlobSources('*.cpp') - if str(f) != 'runtimepath.cpp'] + if str(f) != 'runtimepath.cpp'] rtrp = os.path.relpath(env['runtimepath'], env['libdir']) +if env['PLATFORM'] == "win32": + rtrp = rtrp.replace('\\', '/') + env_rt = env.Clone() env_rt.AppendUnique(CPPDEFINES=dict(DIFFPYRUNTIMERELPATH=rtrp)) rtso = env_rt.SharedObject('runtimepath', 'runtimepath.cpp') diff --git a/src/diffpy/mathutils.hpp b/src/diffpy/mathutils.hpp index f8e8ffec..3713bb98 100644 --- a/src/diffpy/mathutils.hpp +++ b/src/diffpy/mathutils.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* Various common mathematical constants and functions. -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * Various common mathematical constants and functions. + * + *****************************************************************************/ #ifndef MATHUTILS_HPP_INCLUDED #define MATHUTILS_HPP_INCLUDED @@ -43,68 +43,56 @@ double asind(double x); // round-off aware comparison operations -bool eps_eq(const double& x, const double& y, double eps=SQRT_DOUBLE_EPS); -bool eps_gt(const double& x, const double& y, double eps=SQRT_DOUBLE_EPS); -bool eps_lt(const double& x, const double& y, double eps=SQRT_DOUBLE_EPS); +bool eps_eq(const double& x, const double& y, double eps = SQRT_DOUBLE_EPS); +bool eps_gt(const double& x, const double& y, double eps = SQRT_DOUBLE_EPS); +bool eps_lt(const double& x, const double& y, double eps = SQRT_DOUBLE_EPS); // binary functor for round-off aware less-than comparison -class EpsilonLess : public std::binary_function -{ - public: - - // constructor - EpsilonLess(double eps=SQRT_DOUBLE_EPS) : meps(eps) { } - - // comparison method - bool operator()(const double& x, const double& y) const - { - return eps_lt(x, y, meps); - } - template - bool operator()(const Seq0& v0, const Seq1& v1) const - { - bool rv = std::lexicographical_compare( - v0.begin(), v0.end(), - v1.begin(), v1.end(), *this); - return rv; - } - - private: - - double meps; +class EpsilonLess : public std::binary_function { + public: + // constructor + EpsilonLess(double eps = SQRT_DOUBLE_EPS) : meps(eps) {} + + // comparison method + bool operator()(const double& x, const double& y) const { + return eps_lt(x, y, meps); + } + template + bool operator()(const Seq0& v0, const Seq1& v1) const { + bool rv = std::lexicographical_compare(v0.begin(), v0.end(), v1.begin(), + v1.end(), *this); + return rv; + } + + private: + double meps; }; // binary functor for round-off aware equality comparison -class EpsilonEqual : public std::binary_function -{ - public: - - // constructor - EpsilonEqual(double eps=SQRT_DOUBLE_EPS) : meps(eps) { } - - // comparison method - bool operator()(const double& x, const double& y) const - { - return eps_eq(x, y, meps); - } - template - bool operator()(const Seq0& v0, const Seq1& v1) const - { - bool rv = (v0.size() == v1.size()) && - std::equal(v0.begin(), v0.end(), v1.begin(), *this); - return rv; - } - - private: - - double meps; +class EpsilonEqual : public std::binary_function { + public: + // constructor + EpsilonEqual(double eps = SQRT_DOUBLE_EPS) : meps(eps) {} + + // comparison method + bool operator()(const double& x, const double& y) const { + return eps_eq(x, y, meps); + } + template + bool operator()(const Seq0& v0, const Seq1& v1) const { + bool rv = (v0.size() == v1.size()) && + std::equal(v0.begin(), v0.end(), v1.begin(), *this); + return rv; + } + + private: + double meps; }; - -} // namespace mathutils -} // namespace diffpy +} // namespace mathutils +} // namespace diffpy // Implementation ------------------------------------------------------------ diff --git a/src/diffpy/mathutils.ipp b/src/diffpy/mathutils.ipp index acf4d24c..2c60d83a 100644 --- a/src/diffpy/mathutils.ipp +++ b/src/diffpy/mathutils.ipp @@ -34,12 +34,6 @@ inline double remainder(double x, double y) fmod(x, y) : (fmod(x, y) + y); } - -inline double log2(double x) -{ - return log(x) / log(2.0); -} - #endif // _MSC_VER namespace diffpy { diff --git a/src/diffpy/runtimepath.cpp b/src/diffpy/runtimepath.cpp index 0957e74e..93337c0c 100644 --- a/src/diffpy/runtimepath.cpp +++ b/src/diffpy/runtimepath.cpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy Complex Modeling Initiative -* (c) 2013 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. -* -****************************************************************************** -* -* Functions for resolving paths to static data files at runtime. -* -*****************************************************************************/ + * + * libdiffpy Complex Modeling Initiative + * (c) 2013 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. + * + ****************************************************************************** + * + * Functions for resolving paths to static data files at runtime. + * + *****************************************************************************/ #include #include @@ -23,8 +23,54 @@ #include #include #include -#include +#include // not available on Windows, conda install dlfcn-win32 + +// libgen.h is not available on Windows +#ifdef _WIN32 +#include +#include + +// A simple replacement for dirname() on Windows. +inline std::string win_dirname(const std::string& path) { + // Find the last occurrence of either '\' or '/' + size_t pos = path.find_last_of("\\/"); + if (pos == std::string::npos) + return "."; // No directory found, return current directory + return path.substr(0, pos); +} + +// Overload to match the expected C-style interface if needed: +inline char* dirname(char* path) { + static std::string dir; + dir = win_dirname(std::string(path)); + return const_cast(dir.c_str()); +} +#else #include +#endif + +// S_ISDIR, PATH_MAX, realpath, etc. +#ifdef _WIN32 +#include +#include // for _fullpath +#include // for _stat +#include // for _getcwd, etc. + +// Define S_ISDIR using the Windows _S_IFDIR flag from sys/stat.h. +#ifndef S_ISDIR +#define S_ISDIR(mode) (((mode) & _S_IFDIR) == _S_IFDIR) +#endif + +// Use MAX_PATH from as PATH_MAX if not defined. +#ifndef PATH_MAX +#define PATH_MAX MAX_PATH +#endif + +// Define realpath in terms of _fullpath. +// _fullpath returns a pointer to the resolved path in the buffer you provide. +// The usage should be nearly equivalent. +#define realpath(N, R) _fullpath((R), (N), PATH_MAX) +#endif #include #include @@ -39,166 +85,138 @@ namespace { const char* runtimerelpath = #ifdef DIFFPYRUNTIMERELPATH - STRINGIFY(DIFFPYRUNTIMERELPATH) + STRINGIFY(DIFFPYRUNTIMERELPATH) #else - "../share/diffpy/libdiffpy-" - STRINGIFY(DIFFPY_VERSION_MAJOR) - "." - STRINGIFY(DIFFPY_VERSION_MINOR) + "../share/diffpy/libdiffpy-" STRINGIFY(DIFFPY_VERSION_MAJOR) "." STRINGIFY( + DIFFPY_VERSION_MINOR) #endif -; + ; -bool isdir(const string& d) -{ - struct stat sd; - return (stat(d.c_str(), &sd) == 0 && S_ISDIR(sd.st_mode)); +bool isdir(const string& d) { + struct stat sd; + return (stat(d.c_str(), &sd) == 0 && S_ISDIR(sd.st_mode)); } - /// throw runtime error if directory does not exist. -void ensureIsDir(const std::string& d) -{ - if (isdir(d)) return; - string emsg("Directory '@D' does not exist."); - emsg = emsg.replace(emsg.find_first_of('@'), 2, d); - throw runtime_error(emsg); +void ensureIsDir(const std::string& d) { + if (isdir(d)) return; + string emsg("Directory '@D' does not exist."); + emsg = emsg.replace(emsg.find_first_of('@'), 2, d); + throw runtime_error(emsg); } - -const string& diffpyruntime() -{ - char fpb[PATH_MAX]; - static string librt; - static bool did_librt = false; - static string envrt; - static bool did_envrt = false; - // check the DIFFPYRUNTIME environment variable. - char* pe = getenv("DIFFPYRUNTIME"); - if (pe && *pe != '\0') - { - static string dprt; - did_envrt = did_envrt && (dprt == pe); - if (!did_envrt) - { - dprt = pe; - envrt = pe; - size_t pt = envrt.find_last_not_of('/'); - if (pt == string::npos) envrt = envrt.substr(0, 1); - else envrt.erase(pt + 1); - ensureIsDir(envrt); - envrt = realpath(envrt.c_str(), fpb); - did_envrt = true; - } - return envrt; - } - if (did_librt) return librt; - // here we need to resolve path of the libdiffpy shared library - Dl_info i; - dladdr(reinterpret_cast(diffpyruntime), &i); - // first candidate is resolved in relative data path - strncpy(fpb, i.dli_fname, PATH_MAX); - string d1 = string(dirname(fpb)) + "/" + runtimerelpath; - if (isdir(d1)) - { - librt = realpath(d1.c_str(), fpb); - did_librt = true; - return librt; - } - // second candidate is resolved with respect to physical library location - // according to the source tree layout - string d2 = dirname(realpath(i.dli_fname, fpb)); - d2 += "/../../src/runtime"; - if (isdir(d2)) - { - librt = realpath(d2.c_str(), fpb); - did_librt = true; - return librt; +const string& diffpyruntime() { + char fpb[PATH_MAX]; + static string librt; + static bool did_librt = false; + static string envrt; + static bool did_envrt = false; + // check the DIFFPYRUNTIME environment variable. + char* pe = getenv("DIFFPYRUNTIME"); + if (pe && *pe != '\0') { + static string dprt; + did_envrt = did_envrt && (dprt == pe); + if (!did_envrt) { + dprt = pe; + envrt = pe; + size_t pt = envrt.find_last_not_of('/'); + if (pt == string::npos) + envrt = envrt.substr(0, 1); + else + envrt.erase(pt + 1); + ensureIsDir(envrt); + envrt = realpath(envrt.c_str(), fpb); + did_envrt = true; } - // nothing worked - throw exception about the first candidate path. - ensureIsDir(d1); + return envrt; + } + if (did_librt) return librt; + // here we need to resolve path of the libdiffpy shared library + Dl_info i; + dladdr(reinterpret_cast(diffpyruntime), &i); + // first candidate is resolved in relative data path + strncpy(fpb, i.dli_fname, PATH_MAX); + string d1 = string(dirname(fpb)) + "/" + runtimerelpath; + if (isdir(d1)) { + librt = realpath(d1.c_str(), fpb); + did_librt = true; return librt; + } + // second candidate is resolved with respect to physical library location + // according to the source tree layout + string d2 = dirname(realpath(i.dli_fname, fpb)); + d2 += "/../../src/runtime"; + if (isdir(d2)) { + librt = realpath(d2.c_str(), fpb); + did_librt = true; + return librt; + } + // nothing worked - throw exception about the first candidate path. + ensureIsDir(d1); + return librt; } -} // namespace +} // namespace // Implementation ------------------------------------------------------------ namespace diffpy { namespace runtimepath { -string datapath(const std::string& f) -{ - string rv = diffpyruntime(); - rv += (f.empty() ? "" : "/") + f; - return rv; +string datapath(const std::string& f) { + string rv = diffpyruntime(); + rv += (f.empty() ? "" : "/") + f; + return rv; } // class LineReader ---------------------------------------------------------- // Constructor -LineReader::LineReader() : - lineno(0), - commentmark("#") -{ } +LineReader::LineReader() : lineno(0), commentmark("#") {} // Methods -bool LineReader::isignored() const -{ - return words.empty() || this->iscomment(); +bool LineReader::isignored() const { + return words.empty() || this->iscomment(); } - -bool LineReader::iscomment() const -{ - bool rv = !commentmark.empty() && !words.empty() && +bool LineReader::iscomment() const { + bool rv = !commentmark.empty() && !words.empty() && (0 == words[0].compare(0, commentmark.size(), commentmark)); - return rv; -} - - -bool LineReader::isblank() const -{ - return words.empty(); + return rv; } +bool LineReader::isblank() const { return words.empty(); } -size_t LineReader::wcount() const -{ - return words.size(); -} - +size_t LineReader::wcount() const { return words.size(); } -runtime_error LineReader::format_error( - const string& filename, const string& edetail) -{ - ostringstream emsg; - emsg << "Invalid data format in " << - filename << " line " << this->lineno << '.'; - if (!edetail.empty()) emsg << '\n' << edetail; - return runtime_error(emsg.str()); +runtime_error LineReader::format_error(const string& filename, + const string& edetail) { + ostringstream emsg; + emsg << "Invalid data format in " << filename << " line " << this->lineno + << '.'; + if (!edetail.empty()) emsg << '\n' << edetail; + return runtime_error(emsg.str()); } // Non-member operators -istream& operator>> (istream& fp, LineReader& line) -{ - getline(fp, line.line); - if (fp) line.lineno++; - istringstream fpline(line.line); - line.words.clear(); - string w; - if (line.separator.empty()) { - while (fpline >> w) line.words.push_back(w); - } - else { - assert(line.separator.size() == 1); - const char& sep = line.separator[0]; - while (getline(fpline, w, sep)) line.words.push_back(w); - } - return fp; +istream& operator>>(istream& fp, LineReader& line) { + getline(fp, line.line); + if (fp) line.lineno++; + istringstream fpline(line.line); + line.words.clear(); + string w; + if (line.separator.empty()) { + while (fpline >> w) line.words.push_back(w); + } else { + assert(line.separator.size() == 1); + const char& sep = line.separator[0]; + while (getline(fpline, w, sep)) line.words.push_back(w); + } + return fp; } -} // namespace runtimepath -} // namespace diffpy +} // namespace runtimepath +} // namespace diffpy diff --git a/src/diffpy/runtimepath.hpp b/src/diffpy/runtimepath.hpp index fc188f1f..f458f15d 100644 --- a/src/diffpy/runtimepath.hpp +++ b/src/diffpy/runtimepath.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy Complex Modeling Initiative -* (c) 2013 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. -* -****************************************************************************** -* -* Functions for resolving paths to static data files at runtime. -* -*****************************************************************************/ + * + * libdiffpy Complex Modeling Initiative + * (c) 2013 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. + * + ****************************************************************************** + * + * Functions for resolving paths to static data files at runtime. + * + *****************************************************************************/ #ifndef RUNTIMEPATH_HPP_INCLUDED #define RUNTIMEPATH_HPP_INCLUDED @@ -40,32 +40,31 @@ namespace runtimepath { std::string datapath(const std::string& f); /// Helper class for loading text data -class LineReader -{ - public: - // constructor - LineReader(); +class LineReader { + public: + // constructor + LineReader(); - // methods - bool isignored() const; - bool iscomment() const; - bool isblank() const; - size_t wcount() const; - std::runtime_error format_error( - const std::string& filename, const std::string& edetail); + // methods + bool isignored() const; + bool iscomment() const; + bool isblank() const; + size_t wcount() const; + std::runtime_error format_error(const std::string& filename, + const std::string& edetail); - // data - int lineno; - std::string commentmark; - std::string separator; - std::string line; - std::vector words; + // data + int lineno; + std::string commentmark; + std::string separator; + std::string line; + std::vector words; }; // non-member functions for the LineReader class -std::istream& operator>> (std::istream&, LineReader&); +std::istream& operator>>(std::istream&, LineReader&); -} // namespace runtimepath -} // namespace diffpy +} // namespace runtimepath +} // namespace diffpy #endif // RUNTIMEPATH_HPP_INCLUDED diff --git a/src/diffpy/serialization.hpp b/src/diffpy/serialization.hpp index 9d80d14d..09dbba59 100644 --- a/src/diffpy/serialization.hpp +++ b/src/diffpy/serialization.hpp @@ -1,26 +1,26 @@ /***************************************************************************** -* -* libdiffpy 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. -* -****************************************************************************** -* -* Declaration of template functions: -* diffpy::serialization_tostring -* diffpy::serialization_fromstring -* -* Shared definitions of serialization archive types: -* diffpy::serialization::iarchive -* diffpy::serialization::oarchive -* -*****************************************************************************/ + * + * libdiffpy 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. + * + ****************************************************************************** + * + * Declaration of template functions: + * diffpy::serialization_tostring + * diffpy::serialization_fromstring + * + * Shared definitions of serialization archive types: + * diffpy::serialization::iarchive + * diffpy::serialization::oarchive + * + *****************************************************************************/ #ifndef SERIALIZATION_HPP_INCLUDED #define SERIALIZATION_HPP_INCLUDED @@ -32,16 +32,20 @@ namespace diffpy { template - std::string serialization_tostring(const T& tobj); +std::string serialization_tostring(const T& tobj); + template - void serialization_fromstring(T& tobj, const std::string& s); +void serialization_fromstring(T& tobj, const std::string& s); namespace serialization { typedef ::boost::archive::binary_iarchive iarchive; typedef ::boost::archive::binary_oarchive oarchive; -} // namespace serialization -} // namespace diffpy +} // namespace serialization +} // namespace diffpy + +// Pull in the inline definitions and macro logic +#include "serialization.ipp" #endif // SERIALIZATION_HPP_INCLUDED diff --git a/src/diffpy/serialization.ipp b/src/diffpy/serialization.ipp index fba56fff..6663b680 100644 --- a/src/diffpy/serialization.ipp +++ b/src/diffpy/serialization.ipp @@ -54,25 +54,30 @@ void serialization_fromstring(T& tobj, const std::string& s) ia >> tobj; } -} // namespace diffpy - // Macros -------------------------------------------------------------------- +// Macros for explicit instantiation: +// - On Windows (_WIN32), make them no-ops to avoid dllimport/dllexport issues. +// - On other platforms, keep them as they were. +#ifdef _WIN32 + + #define DIFFPY_INSTANTIATE_SERIALIZATION(C) /* no-op */ + #define DIFFPY_INSTANTIATE_PTR_SERIALIZATION(C) /* no-op */ -/// Insert explicit instantiations for serialization_tostring and -/// serialization_fromstring for class C. +#else -#define DIFFPY_INSTANTIATE_SERIALIZATION(C) \ - template \ - std::string \ - diffpy::serialization_tostring(const C&); \ - template \ - void \ - diffpy::serialization_fromstring(C&, const std::string&); \ + /// Insert explicit instantiations for serialization_tostring and + /// serialization_fromstring for class C. + #define DIFFPY_INSTANTIATE_SERIALIZATION(C) \ + template std::string diffpy::serialization_tostring(const C&); \ + template void diffpy::serialization_fromstring(C&, const std::string&); -/// Insert explicit instantiations for serialization_tostring and -/// serialization_fromstring for type boost::shared_ptr. + /// Insert explicit instantiations for serialization_tostring and + /// serialization_fromstring for type boost::shared_ptr. + #define DIFFPY_INSTANTIATE_PTR_SERIALIZATION(C) \ + DIFFPY_INSTANTIATE_SERIALIZATION(boost::shared_ptr) -#define DIFFPY_INSTANTIATE_PTR_SERIALIZATION(C) \ - DIFFPY_INSTANTIATE_SERIALIZATION(boost::shared_ptr) +#endif + +} // namespace diffpy #endif // SERIALIZATION_IPP_INCLUDED diff --git a/src/diffpy/srreal/AtomRadiiTable.cpp b/src/diffpy/srreal/AtomRadiiTable.cpp index 20995f69..8cea5315 100644 --- a/src/diffpy/srreal/AtomRadiiTable.cpp +++ b/src/diffpy/srreal/AtomRadiiTable.cpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2011 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. -* -****************************************************************************** -* -* class AtomRadiiTable -- storage of empirical atomic radii -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2011 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. + * + ****************************************************************************** + * + * class AtomRadiiTable -- storage of empirical atomic radii + * + *****************************************************************************/ #include #include @@ -29,7 +29,7 @@ namespace diffpy { // Unique instantiation of the template registry base class. -template class HasClassRegistry; +template class DLL_EXPORT HasClassRegistry; namespace srreal { @@ -37,97 +37,75 @@ using namespace std; // Public Methods ------------------------------------------------------------ -double AtomRadiiTable::lookup(const string& smbl) const -{ - CustomRadiiStorage::const_iterator tb; - tb = mcustomradius.find(smbl); - if (tb != mcustomradius.end()) return tb->second; - return this->standardLookup(smbl); +double AtomRadiiTable::lookup(const string& smbl) const { + CustomRadiiStorage::const_iterator tb; + tb = mcustomradius.find(smbl); + if (tb != mcustomradius.end()) return tb->second; + return this->standardLookup(smbl); } - -void AtomRadiiTable::setCustom(const string& smbl, double radius) -{ - mcustomradius[smbl] = radius; +void AtomRadiiTable::setCustom(const string& smbl, double radius) { + mcustomradius[smbl] = radius; } - -void AtomRadiiTable::fromString(const string& s) -{ - // create deblanked string - string s1; - remove_copy_if(s.begin(), s.end(), back_inserter(s1), ::isspace); - // replace commas with space so we can use the split function - replace(s1.begin(), s1.end(), ',', ' '); - istringstream ss1(s1); - CustomRadiiStorage rds; - for (string w; ss1 >> w;) - { - string::size_type p = w.find(':'); - if (p == string::npos) - { - ostringstream emsg; - emsg << "Invalid radius specification, missing ':' in '" << - w << "'."; - throw invalid_argument(emsg.str()); - } - string smbl = w.substr(0, p); - double value; - istringstream ssv(w.substr(p + 1)); - if (!(ssv >> value)) - { - ostringstream emsg; - emsg << "Invalid floating point number in '" << w << "'."; - throw invalid_argument(emsg.str()); - } - rds[smbl] = value; +void AtomRadiiTable::fromString(const string& s) { + // create deblanked string + string s1; + remove_copy_if(s.begin(), s.end(), back_inserter(s1), ::isspace); + // replace commas with space so we can use the split function + replace(s1.begin(), s1.end(), ',', ' '); + istringstream ss1(s1); + CustomRadiiStorage rds; + for (string w; ss1 >> w;) { + string::size_type p = w.find(':'); + if (p == string::npos) { + ostringstream emsg; + emsg << "Invalid radius specification, missing ':' in '" << w << "'."; + throw invalid_argument(emsg.str()); } - // everything worked up to here, we can do the assignment - CustomRadiiStorage::const_iterator kv = rds.begin(); - for (; kv != rds.end(); ++kv) mcustomradius[kv->first] = kv->second; -} - - -void AtomRadiiTable::resetCustom(const string& smbl) -{ - mcustomradius.erase(smbl); + string smbl = w.substr(0, p); + double value; + istringstream ssv(w.substr(p + 1)); + if (!(ssv >> value)) { + ostringstream emsg; + emsg << "Invalid floating point number in '" << w << "'."; + throw invalid_argument(emsg.str()); + } + rds[smbl] = value; + } + // everything worked up to here, we can do the assignment + CustomRadiiStorage::const_iterator kv = rds.begin(); + for (; kv != rds.end(); ++kv) mcustomradius[kv->first] = kv->second; } - -void AtomRadiiTable::resetAll() -{ - mcustomradius.clear(); +void AtomRadiiTable::resetCustom(const string& smbl) { + mcustomradius.erase(smbl); } +void AtomRadiiTable::resetAll() { mcustomradius.clear(); } -const AtomRadiiTable::CustomRadiiStorage& -AtomRadiiTable::getAllCustom() const -{ - return mcustomradius; +const AtomRadiiTable::CustomRadiiStorage& AtomRadiiTable::getAllCustom() const { + return mcustomradius; } - -string AtomRadiiTable::toString(string separator) const -{ - CustomRadiiStorage::const_iterator tb; - vector symbols; - for (tb = mcustomradius.begin(); tb != mcustomradius.end(); ++tb) - { - symbols.push_back(tb->first); - } - sort(symbols.begin(), symbols.end()); - ostringstream rv; - vector::const_iterator smbi; - for (smbi = symbols.begin(); smbi != symbols.end(); ++smbi) - { - if (smbi != symbols.begin()) rv << separator; - rv << *smbi << ':' << mcustomradius.at(*smbi); - } - return rv.str(); +string AtomRadiiTable::toString(string separator) const { + CustomRadiiStorage::const_iterator tb; + vector symbols; + for (tb = mcustomradius.begin(); tb != mcustomradius.end(); ++tb) { + symbols.push_back(tb->first); + } + sort(symbols.begin(), symbols.end()); + ostringstream rv; + vector::const_iterator smbi; + for (smbi = symbols.begin(); smbi != symbols.end(); ++smbi) { + if (smbi != symbols.begin()) rv << separator; + rv << *smbi << ':' << mcustomradius.at(*smbi); + } + return rv.str(); } -} // srreal -} // diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/AtomRadiiTable.hpp b/src/diffpy/srreal/AtomRadiiTable.hpp index 830adc40..c1f09f34 100644 --- a/src/diffpy/srreal/AtomRadiiTable.hpp +++ b/src/diffpy/srreal/AtomRadiiTable.hpp @@ -1,24 +1,24 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2011 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. -* -****************************************************************************** -* -* class AtomRadiiTable -- storage of empirical atomic radii -* This is an abstract base class that provides a createByType factory -* function for creating a registered concrete instances. -* The derived classes has to overload the standardLookup method and also -* create, clone and type methods from the HasClassRegistry base. -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2011 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. + * + ****************************************************************************** + * + * class AtomRadiiTable -- storage of empirical atomic radii + * This is an abstract base class that provides a createByType factory + * function for creating a registered concrete instances. + * The derived classes has to overload the standardLookup method and also + * create, clone and type methods from the HasClassRegistry base. + * + *****************************************************************************/ #ifndef ATOMRADIITABLE_HPP_INCLUDED #define ATOMRADIITABLE_HPP_INCLUDED @@ -32,54 +32,51 @@ #include +#include + namespace diffpy { namespace srreal { -class AtomRadiiTable : - public diffpy::HasClassRegistry -{ - public: - - // types - typedef std::unordered_map CustomRadiiStorage; - - // methods - /// fast value lookup, which does not change the table. - double lookup(const std::string& smbl) const; - /// overloadable lookup function that retrieved standard values - virtual double standardLookup(const std::string& smbl) const = 0; - /// set custom radius for a specified atom symbol - void setCustom(const std::string& smbl, double radius); - /// set custom radii from a string in (A1:r1, A2:r2, ...) format - void fromString(const std::string& s); - /// reset custom value for the specified atom type - void resetCustom(const std::string& smbl); - /// reset all custom values - void resetAll(); - /// return all custom radii defined in this table - const CustomRadiiStorage& getAllCustom() const; - /// convert all custom radii to a string in (A1:r1,A2:r2,...) format - std::string toString(std::string separator=",") const; - - private: - - // data - CustomRadiiStorage mcustomradius; - - // serialization - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - ar & mcustomradius; - } - +class DLL_EXPORT AtomRadiiTable + : public diffpy::HasClassRegistry { + public: + // types + typedef std::unordered_map CustomRadiiStorage; + + // methods + /// fast value lookup, which does not change the table. + double lookup(const std::string& smbl) const; + /// overloadable lookup function that retrieved standard values + virtual double standardLookup(const std::string& smbl) const = 0; + /// set custom radius for a specified atom symbol + void setCustom(const std::string& smbl, double radius); + /// set custom radii from a string in (A1:r1, A2:r2, ...) format + void fromString(const std::string& s); + /// reset custom value for the specified atom type + void resetCustom(const std::string& smbl); + /// reset all custom values + void resetAll(); + /// return all custom radii defined in this table + const CustomRadiiStorage& getAllCustom() const; + /// convert all custom radii to a string in (A1:r1,A2:r2,...) format + std::string toString(std::string separator = ",") const; + + private: + // data + CustomRadiiStorage mcustomradius; + + // serialization + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + ar & mcustomradius; + } }; typedef AtomRadiiTable::SharedPtr AtomRadiiTablePtr; -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/AtomUtils.cpp b/src/diffpy/srreal/AtomUtils.cpp index 37cd41ac..b76d5bf8 100644 --- a/src/diffpy/srreal/AtomUtils.cpp +++ b/src/diffpy/srreal/AtomUtils.cpp @@ -1,72 +1,64 @@ /***************************************************************************** -* -* libdiffpy Complex Modeling Initiative -* (c) 2013 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. -* -****************************************************************************** -* -* Small routines related to atom properties. -* -*****************************************************************************/ + * + * libdiffpy Complex Modeling Initiative + * (c) 2013 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. + * + ****************************************************************************** + * + * Small routines related to atom properties. + * + *****************************************************************************/ #include namespace diffpy { namespace srreal { -std::string atomBareSymbol(const std::string& atomtype) -{ - std::string::size_type pb, pe; - pb = atomtype.find_first_not_of("0123456789- \t"); - pe = atomtype.find_last_not_of("+-012345678 \t"); - std::string::size_type npos = std::string::npos; - std::string rv; - if (pb != npos && pe != npos) rv = atomtype.substr(pb, pe - pb + 1); - return rv; +std::string atomBareSymbol(const std::string& atomtype) { + std::string::size_type pb, pe; + pb = atomtype.find_first_not_of("0123456789- \t"); + pe = atomtype.find_last_not_of("+-012345678 \t"); + std::string::size_type npos = std::string::npos; + std::string rv; + if (pb != npos && pe != npos) rv = atomtype.substr(pb, pe - pb + 1); + return rv; } - /// Return valence of possibly ionic symbol such as "S2-" or "Cl-". -int atomValence(const std::string& atomtype) -{ - std::string::const_reverse_iterator ci; - int rv = 0; - for (ci = atomtype.rbegin(); ci != atomtype.rend(); ++ci) - { - if (isspace(*ci)) continue; - // read trailing sign - if (rv == 0) - { - if (*ci == '+') - { - rv = 1; - continue; - } - if (*ci == '-') - { - rv = -1; - continue; - } - break; - } - // allow one [1-8] digit before the +/- sign - if (rv && '0' <= *ci && *ci <= '8') - { - rv *= (*ci - '0'); - } - break; +int atomValence(const std::string& atomtype) { + std::string::const_reverse_iterator ci; + int rv = 0; + for (ci = atomtype.rbegin(); ci != atomtype.rend(); ++ci) { + if (isspace(*ci)) continue; + // read trailing sign + if (rv == 0) { + if (*ci == '+') { + rv = 1; + continue; + } + if (*ci == '-') { + rv = -1; + continue; + } + break; + } + // allow one [1-8] digit before the +/- sign + if (rv && '0' <= *ci && *ci <= '8') { + rv *= (*ci - '0'); } - return rv; + break; + } + return rv; } -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // End of file diff --git a/src/diffpy/srreal/AtomUtils.hpp b/src/diffpy/srreal/AtomUtils.hpp index 30071147..636ab9c3 100644 --- a/src/diffpy/srreal/AtomUtils.hpp +++ b/src/diffpy/srreal/AtomUtils.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy Complex Modeling Initiative -* (c) 2013 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. -* -****************************************************************************** -* -* Small routines related to atom properties. -* -*****************************************************************************/ + * + * libdiffpy Complex Modeling Initiative + * (c) 2013 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. + * + ****************************************************************************** + * + * Small routines related to atom properties. + * + *****************************************************************************/ #ifndef ATOMUTILS_HPP_INCLUDED #define ATOMUTILS_HPP_INCLUDED @@ -31,7 +31,7 @@ std::string atomBareSymbol(const std::string& atomtype); /// Return valence of possibly ionic symbol such as "S2-" or "Cl-". int atomValence(const std::string& atomtype); -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy #endif // ATOMUTILS_HPP_INCLUDED diff --git a/src/diffpy/srreal/AtomicStructureAdapter.cpp b/src/diffpy/srreal/AtomicStructureAdapter.cpp index ac5a0192..f8b0d168 100644 --- a/src/diffpy/srreal/AtomicStructureAdapter.cpp +++ b/src/diffpy/srreal/AtomicStructureAdapter.cpp @@ -1,21 +1,21 @@ /***************************************************************************** -* -* libdiffpy 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. -* -****************************************************************************** -* -* class AtomicStructureAdapter -- universal structure adapter for -* a non-periodic set of atoms. -* -*****************************************************************************/ + * + * libdiffpy 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. + * + ****************************************************************************** + * + * class AtomicStructureAdapter -- universal structure adapter for + * a non-periodic set of atoms. + * + *****************************************************************************/ #include #include @@ -34,62 +34,48 @@ namespace srreal { // class Atom ////////////////////////////////////////////////////////////////////////////// -bool operator< (const Atom& a0, const Atom& a1) -{ - if (a0.atomtype < a1.atomtype) return true; - if (a0.atomtype > a1.atomtype) return false; - R3::Vector::const_iterator p0 = a0.xyz_cartn.begin(); - R3::Vector::const_iterator p1 = a1.xyz_cartn.begin(); - for (; p0 != a0.xyz_cartn.end(); ++p0, ++p1) - { - if (*p0 < *p1) return true; - if (*p0 > *p1) return false; - } - if (a0.occupancy < a1.occupancy) return true; - if (a0.occupancy > a1.occupancy) return false; - if (a0.anisotropy < a1.anisotropy) return true; - if (a0.anisotropy > a1.anisotropy) return false; - typedef R3::Matrix::array_type::const_iterator CIter; - CIter u0 = a0.uij_cartn.data().begin(); - CIter u0last = a0.uij_cartn.data().end(); - CIter u1 = a1.uij_cartn.data().begin(); - for (; u0 != u0last; ++u0, ++u1) - { - if (*u0 < *u1) return true; - if (*u0 > *u1) return false; - } - return false; -} - - -bool operator==(const Atom& a0, const Atom& a1) -{ - bool rv = (&a0 == &a1) || ( - a0.atomtype == a1.atomtype && - (a0.xyz_cartn == a1.xyz_cartn) && - a0.occupancy == a1.occupancy && - a0.anisotropy == a1.anisotropy && - a0.uij_cartn == a1.uij_cartn - ); - return rv; -} - - -bool operator!=(const Atom& a0, const Atom& a1) -{ - return !(a0 == a1); -} - - -size_t hash_value(const Atom& a) -{ - size_t seed = 0; - boost::hash_combine(seed, a.atomtype); - boost::hash_combine(seed, a.xyz_cartn); - boost::hash_combine(seed, a.occupancy); - boost::hash_combine(seed, a.anisotropy); - boost::hash_combine(seed, a.uij_cartn); - return seed; +bool operator<(const Atom& a0, const Atom& a1) { + if (a0.atomtype < a1.atomtype) return true; + if (a0.atomtype > a1.atomtype) return false; + R3::Vector::const_iterator p0 = a0.xyz_cartn.begin(); + R3::Vector::const_iterator p1 = a1.xyz_cartn.begin(); + for (; p0 != a0.xyz_cartn.end(); ++p0, ++p1) { + if (*p0 < *p1) return true; + if (*p0 > *p1) return false; + } + if (a0.occupancy < a1.occupancy) return true; + if (a0.occupancy > a1.occupancy) return false; + if (a0.anisotropy < a1.anisotropy) return true; + if (a0.anisotropy > a1.anisotropy) return false; + typedef R3::Matrix::array_type::const_iterator CIter; + CIter u0 = a0.uij_cartn.data().begin(); + CIter u0last = a0.uij_cartn.data().end(); + CIter u1 = a1.uij_cartn.data().begin(); + for (; u0 != u0last; ++u0, ++u1) { + if (*u0 < *u1) return true; + if (*u0 > *u1) return false; + } + return false; +} + +bool operator==(const Atom& a0, const Atom& a1) { + bool rv = (&a0 == &a1) || + (a0.atomtype == a1.atomtype && (a0.xyz_cartn == a1.xyz_cartn) && + a0.occupancy == a1.occupancy && a0.anisotropy == a1.anisotropy && + a0.uij_cartn == a1.uij_cartn); + return rv; +} + +bool operator!=(const Atom& a0, const Atom& a1) { return !(a0 == a1); } + +size_t hash_value(const Atom& a) { + size_t seed = 0; + boost::hash_combine(seed, a.atomtype); + boost::hash_combine(seed, a.xyz_cartn); + boost::hash_combine(seed, a.occupancy); + boost::hash_combine(seed, a.anisotropy); + boost::hash_combine(seed, a.uij_cartn); + return seed; } ////////////////////////////////////////////////////////////////////////////// @@ -98,58 +84,41 @@ size_t hash_value(const Atom& a) // Public Methods ------------------------------------------------------------ -StructureAdapterPtr AtomicStructureAdapter::clone() const -{ - StructureAdapterPtr rv(new AtomicStructureAdapter(*this)); - return rv; +StructureAdapterPtr AtomicStructureAdapter::clone() const { + StructureAdapterPtr rv(new AtomicStructureAdapter(*this)); + return rv; } - -BaseBondGeneratorPtr AtomicStructureAdapter::createBondGenerator() const -{ - BaseBondGeneratorPtr bnds(new BaseBondGenerator(shared_from_this())); - return bnds; +BaseBondGeneratorPtr AtomicStructureAdapter::createBondGenerator() const { + BaseBondGeneratorPtr bnds(new BaseBondGenerator(shared_from_this())); + return bnds; } +int AtomicStructureAdapter::countSites() const { return matoms.size(); } -int AtomicStructureAdapter::countSites() const -{ - return matoms.size(); +const string& AtomicStructureAdapter::siteAtomType(int idx) const { + assert(0 <= idx && idx < this->countSites()); + return matoms[idx].atomtype; } - -const string& AtomicStructureAdapter::siteAtomType(int idx) const -{ - assert(0 <= idx && idx < this->countSites()); - return matoms[idx].atomtype; +const R3::Vector& AtomicStructureAdapter::siteCartesianPosition(int idx) const { + assert(0 <= idx && idx < this->countSites()); + return matoms[idx].xyz_cartn; } - -const R3::Vector& AtomicStructureAdapter::siteCartesianPosition(int idx) const -{ - assert(0 <= idx && idx < this->countSites()); - return matoms[idx].xyz_cartn; +double AtomicStructureAdapter::siteOccupancy(int idx) const { + assert(0 <= idx && idx < this->countSites()); + return matoms[idx].occupancy; } - -double AtomicStructureAdapter::siteOccupancy(int idx) const -{ - assert(0 <= idx && idx < this->countSites()); - return matoms[idx].occupancy; +bool AtomicStructureAdapter::siteAnisotropy(int idx) const { + assert(0 <= idx && idx < this->countSites()); + return matoms[idx].anisotropy; } - -bool AtomicStructureAdapter::siteAnisotropy(int idx) const -{ - assert(0 <= idx && idx < this->countSites()); - return matoms[idx].anisotropy; -} - - -const R3::Matrix& AtomicStructureAdapter::siteCartesianUij(int idx) const -{ - assert(0 <= idx && idx < this->countSites()); - return matoms[idx].uij_cartn; +const R3::Matrix& AtomicStructureAdapter::siteCartesianUij(int idx) const { + assert(0 <= idx && idx < this->countSites()); + return matoms[idx].uij_cartn; } // helper for diff @@ -157,150 +126,124 @@ namespace { typedef std::pair atomindex; -bool cmpatomindex(const atomindex& ai0, const atomindex& ai1) -{ - return (*(ai0.first) < *(ai1.first)); -} - -} // namespace - -StructureDifference -AtomicStructureAdapter::diff(StructureAdapterConstPtr other) const -{ - using std::min; - StructureDifference sd = this->StructureAdapter::diff(other); - if (sd.stru0 == sd.stru1) return sd; - typedef boost::shared_ptr APtr; - APtr pother = boost::dynamic_pointer_cast(other); - if (!pother) return sd; - // try fast side-by-side comparison - sd.diffmethod = StructureDifference::Method::SIDEBYSIDE; - const AtomicStructureAdapter& astru0 = *this; - const AtomicStructureAdapter& astru1 = *pother; - sd.pop0.clear(); - sd.add1.clear(); - const_iterator ai0 = astru0.matoms.begin(); - const_iterator ai1 = astru1.matoms.begin(); - int nboth = min(astru0.countSites(), astru1.countSites()); - for (int i = 0; i < nboth; ++i, ++ai0, ++ai1) - { - if (*ai0 != *ai1) - { - sd.pop0.push_back(i); - sd.add1.push_back(i); - } - } - for (int i = nboth; ai0 != astru0.matoms.end(); ++i, ++ai0) - { - sd.pop0.push_back(i); - } - for (int i = nboth; ai1 != astru1.matoms.end(); ++i, ++ai1) - { - sd.add1.push_back(i); +bool cmpatomindex(const atomindex& ai0, const atomindex& ai1) { + return (*(ai0.first) < *(ai1.first)); +} + +} // namespace + +StructureDifference AtomicStructureAdapter::diff( + StructureAdapterConstPtr other) const { + using std::min; + StructureDifference sd = this->StructureAdapter::diff(other); + if (sd.stru0 == sd.stru1) return sd; + typedef boost::shared_ptr APtr; + APtr pother = boost::dynamic_pointer_cast(other); + if (!pother) return sd; + // try fast side-by-side comparison + sd.diffmethod = StructureDifference::Method::SIDEBYSIDE; + const AtomicStructureAdapter& astru0 = *this; + const AtomicStructureAdapter& astru1 = *pother; + sd.pop0.clear(); + sd.add1.clear(); + const_iterator ai0 = astru0.matoms.begin(); + const_iterator ai1 = astru1.matoms.begin(); + int nboth = min(astru0.countSites(), astru1.countSites()); + for (int i = 0; i < nboth; ++i, ++ai0, ++ai1) { + if (*ai0 != *ai1) { + sd.pop0.push_back(i); + sd.add1.push_back(i); } - if (sd.allowsfastupdate()) return sd; - // here the structures differ too much when compared side by side. - // Let's compare assuming no relation in atom site order. - sd.pop0.clear(); - sd.add1.clear(); - // let's build sorted vectors of atoms in stru0 and stru1 - sd.diffmethod = StructureDifference::Method::SORTED; - std::vector satoms0, satoms1; - satoms0.reserve(astru0.countSites()); - const_iterator ai = astru0.matoms.begin(); - for (int i = 0; ai != astru0.matoms.end(); ++ai, ++i) - { - satoms0.push_back(atomindex(&(*ai), i)); - } - // use negative index for stru1 atoms so we can tell them apart - // in the output of set_symmetric_difference - satoms1.reserve(astru1.countSites()); - ai = astru1.matoms.begin(); - for (int i = -1; ai != astru1.matoms.end(); ++ai, --i) - { - satoms1.push_back(atomindex(&(*ai), i)); - } - sort(satoms0.begin(), satoms0.end(), cmpatomindex); - sort(satoms1.begin(), satoms1.end(), cmpatomindex); - std::vector symdiffatoms(satoms0.size() + satoms1.size()); - std::vector::iterator ii; - ii = std::set_symmetric_difference(satoms0.begin(), satoms0.end(), - satoms1.begin(), satoms1.end(), - symdiffatoms.begin(), cmpatomindex); - symdiffatoms.erase(ii, symdiffatoms.end()); - for (ii = symdiffatoms.begin(); ii != symdiffatoms.end(); ++ii) - { - if (ii->second >= 0) sd.pop0.push_back(ii->second); - else sd.add1.push_back(-1 * ii->second - 1); - } - assert(sd.pop0.size() <= min(satoms0.size(), symdiffatoms.size())); - assert(sd.add1.size() <= min(satoms1.size(), symdiffatoms.size())); - sort(sd.pop0.begin(), sd.pop0.end()); - sort(sd.add1.begin(), sd.add1.end()); - return sd; + } + for (int i = nboth; ai0 != astru0.matoms.end(); ++i, ++ai0) { + sd.pop0.push_back(i); + } + for (int i = nboth; ai1 != astru1.matoms.end(); ++i, ++ai1) { + sd.add1.push_back(i); + } + if (sd.allowsfastupdate()) return sd; + // here the structures differ too much when compared side by side. + // Let's compare assuming no relation in atom site order. + sd.pop0.clear(); + sd.add1.clear(); + // let's build sorted vectors of atoms in stru0 and stru1 + sd.diffmethod = StructureDifference::Method::SORTED; + std::vector satoms0, satoms1; + satoms0.reserve(astru0.countSites()); + const_iterator ai = astru0.matoms.begin(); + for (int i = 0; ai != astru0.matoms.end(); ++ai, ++i) { + satoms0.push_back(atomindex(&(*ai), i)); + } + // use negative index for stru1 atoms so we can tell them apart + // in the output of set_symmetric_difference + satoms1.reserve(astru1.countSites()); + ai = astru1.matoms.begin(); + for (int i = -1; ai != astru1.matoms.end(); ++ai, --i) { + satoms1.push_back(atomindex(&(*ai), i)); + } + sort(satoms0.begin(), satoms0.end(), cmpatomindex); + sort(satoms1.begin(), satoms1.end(), cmpatomindex); + std::vector symdiffatoms(satoms0.size() + satoms1.size()); + std::vector::iterator ii; + ii = std::set_symmetric_difference(satoms0.begin(), satoms0.end(), + satoms1.begin(), satoms1.end(), + symdiffatoms.begin(), cmpatomindex); + symdiffatoms.erase(ii, symdiffatoms.end()); + for (ii = symdiffatoms.begin(); ii != symdiffatoms.end(); ++ii) { + if (ii->second >= 0) + sd.pop0.push_back(ii->second); + else + sd.add1.push_back(-1 * ii->second - 1); + } + assert(sd.pop0.size() <= min(satoms0.size(), symdiffatoms.size())); + assert(sd.add1.size() <= min(satoms1.size(), symdiffatoms.size())); + sort(sd.pop0.begin(), sd.pop0.end()); + sort(sd.add1.begin(), sd.add1.end()); + return sd; } typedef AtomicStructureAdapter::iterator iterator; -iterator AtomicStructureAdapter::insert(int idx, const Atom& atom) -{ - assert(0 <= idx && idx <= this->countSites()); - return this->insert(matoms.begin() + idx, atom); +iterator AtomicStructureAdapter::insert(int idx, const Atom& atom) { + assert(0 <= idx && idx <= this->countSites()); + return this->insert(matoms.begin() + idx, atom); } - -iterator AtomicStructureAdapter::insert(iterator ii, const Atom& atom) -{ - return matoms.insert(ii, atom); +iterator AtomicStructureAdapter::insert(iterator ii, const Atom& atom) { + return matoms.insert(ii, atom); } - -void AtomicStructureAdapter::append(const Atom& atom) -{ - matoms.push_back(atom); -} - - -void AtomicStructureAdapter::clear() -{ - matoms.clear(); +void AtomicStructureAdapter::append(const Atom& atom) { + matoms.push_back(atom); } +void AtomicStructureAdapter::clear() { matoms.clear(); } -iterator AtomicStructureAdapter::erase(int idx) -{ - assert(0 <= idx && idx < this->countSites()); - return matoms.erase(matoms.begin() + idx); +iterator AtomicStructureAdapter::erase(int idx) { + assert(0 <= idx && idx < this->countSites()); + return matoms.erase(matoms.begin() + idx); } - -iterator AtomicStructureAdapter::erase(iterator pos) -{ - return matoms.erase(pos); +iterator AtomicStructureAdapter::erase(iterator pos) { + return matoms.erase(pos); } - -iterator AtomicStructureAdapter::erase(iterator first, iterator last) -{ - return matoms.erase(first, last); +iterator AtomicStructureAdapter::erase(iterator first, iterator last) { + return matoms.erase(first, last); } - -Atom& AtomicStructureAdapter::operator[](int idx) -{ - assert(0 <= idx && idx < this->countSites()); - return matoms[idx]; +Atom& AtomicStructureAdapter::operator[](int idx) { + assert(0 <= idx && idx < this->countSites()); + return matoms[idx]; } - -const Atom& AtomicStructureAdapter::operator[](int idx) const -{ - assert(0 <= idx && idx < this->countSites()); - return matoms[idx]; +const Atom& AtomicStructureAdapter::operator[](int idx) const { + assert(0 <= idx && idx < this->countSites()); + return matoms[idx]; } -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/AtomicStructureAdapter.hpp b/src/diffpy/srreal/AtomicStructureAdapter.hpp index 6eb3cbc2..de1787f8 100644 --- a/src/diffpy/srreal/AtomicStructureAdapter.hpp +++ b/src/diffpy/srreal/AtomicStructureAdapter.hpp @@ -1,21 +1,21 @@ /***************************************************************************** -* -* libdiffpy 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. -* -****************************************************************************** -* -* class AtomicStructureAdapter -- universal structure adapter for -* a non-periodic set of atoms. -* -*****************************************************************************/ + * + * libdiffpy 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. + * + ****************************************************************************** + * + * class AtomicStructureAdapter -- universal structure adapter for + * a non-periodic set of atoms. + * + *****************************************************************************/ #ifndef ATOMICSTRUCTUREADAPTER_HPP_INCLUDED #define ATOMICSTRUCTUREADAPTER_HPP_INCLUDED @@ -24,152 +24,138 @@ #include +#include + namespace diffpy { namespace srreal { -class Atom -{ - public: - - // constructor - Atom() : - xyz_cartn(0.0, 0.0, 0.0), - occupancy(1.0), - anisotropy(false), - uij_cartn(R3::zeromatrix()) - { }; - - // data - std::string atomtype; - R3::Vector xyz_cartn; - double occupancy; - bool anisotropy; - R3::Matrix uij_cartn; - - private: - - // serialization - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - ar & atomtype; - ar & xyz_cartn; - ar & occupancy; - ar & anisotropy; - ar & uij_cartn; - } - +class DLL_EXPORT Atom { + public: + // constructor + Atom() + : xyz_cartn(0.0, 0.0, 0.0), + occupancy(1.0), + anisotropy(false), + uij_cartn(R3::zeromatrix()) {}; + + // data + std::string atomtype; + R3::Vector xyz_cartn; + double occupancy; + bool anisotropy; + R3::Matrix uij_cartn; + + private: + // serialization + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + ar & atomtype; + ar & xyz_cartn; + ar & occupancy; + ar & anisotropy; + ar & uij_cartn; + } }; // Functions related to class Atom -bool operator<(const Atom&, const Atom&); -inline bool operator>(const Atom& a0, const Atom& a1) { return a1 < a0; } -inline bool operator<=(const Atom& a0, const Atom& a1) { return !(a1 < a0); } -inline bool operator>=(const Atom& a0, const Atom& a1) { return !(a0 < a1); } - -bool operator==(const Atom&, const Atom&); -bool operator!=(const Atom&, const Atom&); -size_t hash_value(const Atom&); - - -class AtomicStructureAdapter : public StructureAdapter -{ - public: - - typedef std::vector AtomVector; - typedef AtomVector::value_type value_type; - typedef AtomVector::iterator iterator; - typedef AtomVector::const_iterator const_iterator; - typedef AtomVector::reverse_iterator reverse_iterator; - typedef AtomVector::const_reverse_iterator const_reverse_iterator; - typedef AtomVector::difference_type difference_type; - typedef AtomVector::size_type size_type; - - // methods - overloaded - virtual StructureAdapterPtr clone() const; - virtual BaseBondGeneratorPtr createBondGenerator() const; - virtual int countSites() const; - // reusing StructureAdapter::numberDensity() - virtual const std::string& siteAtomType(int idx) const; - virtual const R3::Vector& siteCartesianPosition(int idx) const; - // reusing StructureAdapter::siteMultiplicity() - virtual double siteOccupancy(int idx) const; - virtual bool siteAnisotropy(int idx) const; - virtual const R3::Matrix& siteCartesianUij(int idx) const; - virtual StructureDifference diff(StructureAdapterConstPtr other) const; - - // methods - own - iterator insert(int, const Atom&); - iterator insert(iterator position, const Atom&); - template - void insert(iterator position, Iter first, Iter last) - { - matoms.insert(position, first, last); - } - void append(const Atom&); - void clear(); - iterator erase(int idx); - iterator erase(iterator pos); - iterator erase(iterator first, iterator last); - void reserve(size_t sz) { matoms.reserve(sz); } - size_type size() const { return matoms.size(); } - Atom& operator[](int); - const Atom& operator[](int) const; - Atom& at(int idx) { return (*this)[idx]; } - const Atom& at(int idx) const { return (*this)[idx]; } - template - void assign (Iter first, Iter last) { matoms.assign(first, last); } - void assign (size_t n, const Atom& a) { matoms.assign(n, a); } - // iterator forwarding - iterator begin() { return matoms.begin(); } - iterator end() { return matoms.end(); } - const_iterator begin() const { return matoms.begin(); } - const_iterator end() const { return matoms.end(); } - reverse_iterator rbegin() { return matoms.rbegin(); } - reverse_iterator rend() { return matoms.rend(); } - const_reverse_iterator rbegin() const { return matoms.rbegin(); } - const_reverse_iterator rend() const { return matoms.rend(); } - - private: - - // data - AtomVector matoms; - - // comparison - friend bool operator==( - const AtomicStructureAdapter& stru0, - const AtomicStructureAdapter& stru1) - { - return (stru0.matoms == stru1.matoms); - } - - // serialization - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - ar & boost::serialization::base_object(*this); - ar & matoms; - } - +DLL_EXPORT bool operator<(const Atom&, const Atom&); +inline bool operator>(const Atom& a0, const Atom& a1) { return a1 < a0; } +inline bool operator<=(const Atom& a0, const Atom& a1) { return !(a1 < a0); } +inline bool operator>=(const Atom& a0, const Atom& a1) { return !(a0 < a1); } + +DLL_EXPORT bool operator==(const Atom&, const Atom&); +DLL_EXPORT bool operator!=(const Atom&, const Atom&); +DLL_EXPORT size_t hash_value(const Atom&); + +class DLL_EXPORT AtomicStructureAdapter : public StructureAdapter { + public: + typedef std::vector AtomVector; + typedef AtomVector::value_type value_type; + typedef AtomVector::iterator iterator; + typedef AtomVector::const_iterator const_iterator; + typedef AtomVector::reverse_iterator reverse_iterator; + typedef AtomVector::const_reverse_iterator const_reverse_iterator; + typedef AtomVector::difference_type difference_type; + typedef AtomVector::size_type size_type; + + // methods - overloaded + virtual StructureAdapterPtr clone() const; + virtual BaseBondGeneratorPtr createBondGenerator() const; + virtual int countSites() const; + // reusing StructureAdapter::numberDensity() + virtual const std::string& siteAtomType(int idx) const; + virtual const R3::Vector& siteCartesianPosition(int idx) const; + // reusing StructureAdapter::siteMultiplicity() + virtual double siteOccupancy(int idx) const; + virtual bool siteAnisotropy(int idx) const; + virtual const R3::Matrix& siteCartesianUij(int idx) const; + virtual StructureDifference diff(StructureAdapterConstPtr other) const; + + // methods - own + iterator insert(int, const Atom&); + iterator insert(iterator position, const Atom&); + template + void insert(iterator position, Iter first, Iter last) { + matoms.insert(position, first, last); + } + void append(const Atom&); + void clear(); + iterator erase(int idx); + iterator erase(iterator pos); + iterator erase(iterator first, iterator last); + void reserve(size_t sz) { matoms.reserve(sz); } + size_type size() const { return matoms.size(); } + Atom& operator[](int); + const Atom& operator[](int) const; + Atom& at(int idx) { return (*this)[idx]; } + const Atom& at(int idx) const { return (*this)[idx]; } + template + void assign(Iter first, Iter last) { + matoms.assign(first, last); + } + void assign(size_t n, const Atom& a) { matoms.assign(n, a); } + // iterator forwarding + iterator begin() { return matoms.begin(); } + iterator end() { return matoms.end(); } + const_iterator begin() const { return matoms.begin(); } + const_iterator end() const { return matoms.end(); } + reverse_iterator rbegin() { return matoms.rbegin(); } + reverse_iterator rend() { return matoms.rend(); } + const_reverse_iterator rbegin() const { return matoms.rbegin(); } + const_reverse_iterator rend() const { return matoms.rend(); } + + private: + // data + AtomVector matoms; + + // comparison + friend bool operator==(const AtomicStructureAdapter& stru0, + const AtomicStructureAdapter& stru1) { + return (stru0.matoms == stru1.matoms); + } + + // serialization + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + ar& boost::serialization::base_object(*this); + ar & matoms; + } }; typedef boost::shared_ptr AtomicStructureAdapterPtr; // Complementary comparison function -inline -bool operator!=( - const AtomicStructureAdapter& stru0, - const AtomicStructureAdapter& stru1) -{ - return !(stru0 == stru1); +inline bool operator!=(const AtomicStructureAdapter& stru0, + const AtomicStructureAdapter& stru1) { + return !(stru0 == stru1); } -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/BVParam.cpp b/src/diffpy/srreal/BVParam.cpp index 74601708..abb6f906 100644 --- a/src/diffpy/srreal/BVParam.cpp +++ b/src/diffpy/srreal/BVParam.cpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy 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. -* -****************************************************************************** -* -* class BVParam -- bond valence parameters for a cation-anion pair -* -*****************************************************************************/ + * + * libdiffpy 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. + * + ****************************************************************************** + * + * class BVParam -- bond valence parameters for a cation-anion pair + * + *****************************************************************************/ #include #include @@ -30,109 +30,87 @@ namespace srreal { // Constructor --------------------------------------------------------------- -BVParam::BVParam() -{ - mvalence0 = 0; - mvalence1 = 0; - mRo = 0.0; - mB = 0.0; +BVParam::BVParam() { + mvalence0 = 0; + mvalence1 = 0; + mRo = 0.0; + mB = 0.0; } -BVParam::BVParam(const string& atom0, int valence0, - const string& atom1, int valence1, - double Ro, double B, string ref_id) -{ - matom0 = atom0; - mvalence0 = valence0; - matom1 = atom1; - mvalence1 = valence1; - if (mvalence0 < mvalence1) - { - swap(matom0, matom1); - swap(mvalence0, mvalence1); - } - mRo = Ro; - mB = B; - mref_id = ref_id; +BVParam::BVParam(const string& atom0, int valence0, const string& atom1, + int valence1, double Ro, double B, string ref_id) { + matom0 = atom0; + mvalence0 = valence0; + matom1 = atom1; + mvalence1 = valence1; + if (mvalence0 < mvalence1) { + swap(matom0, matom1); + swap(mvalence0, mvalence1); + } + mRo = Ro; + mB = B; + mref_id = ref_id; } // Public Methods ------------------------------------------------------------ -bool BVParam::operator==(const BVParam& other) const -{ - return (this == &other) || ( - mvalence0 == other.mvalence0 && - mvalence1 == other.mvalence1 && - mRo == other.mRo && - mB == other.mB && - matom0 == other.matom0 && - matom1 == other.matom1 && - mref_id == other.mref_id); +bool BVParam::operator==(const BVParam& other) const { + return (this == &other) || + (mvalence0 == other.mvalence0 && mvalence1 == other.mvalence1 && + mRo == other.mRo && mB == other.mB && matom0 == other.matom0 && + matom1 == other.matom1 && mref_id == other.mref_id); } - -bool BVParam::operator!=(const BVParam& other) const -{ - return !(*this == other); +bool BVParam::operator!=(const BVParam& other) const { + return !(*this == other); } - -double BVParam::bondvalence(double distance) const -{ - double rv = (mB > 0.0) ? exp((mRo - distance) / mB) : 0.0; - return rv; +double BVParam::bondvalence(double distance) const { + double rv = (mB > 0.0) ? exp((mRo - distance) / mB) : 0.0; + return rv; } - -double BVParam::bondvalenceToDistance(double bvalence) const -{ - double rv = mRo - mB * log(bvalence); - return rv; +double BVParam::bondvalenceToDistance(double bvalence) const { + double rv = mRo - mB * log(bvalence); + return rv; } - -void BVParam::setFromCifLine(const std::string& cifline) -{ - string a0, a1, ref; - int v0, v1; - double Ro, B; - istringstream linefp(cifline); - linefp >> a0 >> v0 >> a1 >> v1 >> Ro >> B >> ref; - if (!linefp) - { - const char* emsg = "Cannot parse cif line."; - throw invalid_argument(emsg); - } - BVParam bp1(a0, v0, a1, v1, Ro, B, ref); - *this = bp1; +void BVParam::setFromCifLine(const std::string& cifline) { + string a0, a1, ref; + int v0, v1; + double Ro, B; + istringstream linefp(cifline); + linefp >> a0 >> v0 >> a1 >> v1 >> Ro >> B >> ref; + if (!linefp) { + const char* emsg = "Cannot parse cif line."; + throw invalid_argument(emsg); + } + BVParam bp1(a0, v0, a1, v1, Ro, B, ref); + *this = bp1; } // class BVParam::BondHash --------------------------------------------------- -size_t BVParam::BondHash::operator()(const BVParam& bp) const -{ - size_t seed = 0; - boost::hash_combine(seed, bp.matom0); - boost::hash_combine(seed, bp.mvalence0); - boost::hash_combine(seed, bp.matom1); - boost::hash_combine(seed, bp.mvalence1); - return seed; +size_t BVParam::BondHash::operator()(const BVParam& bp) const { + size_t seed = 0; + boost::hash_combine(seed, bp.matom0); + boost::hash_combine(seed, bp.mvalence0); + boost::hash_combine(seed, bp.matom1); + boost::hash_combine(seed, bp.mvalence1); + return seed; } // class BVParam::BondEqual -------------------------------------------------- -bool BVParam::BondEqual::operator()( - const BVParam& bp0, const BVParam& bp1) const -{ - return (&bp0 == &bp1) || ( - bp0.mvalence0 == bp1.mvalence0 && - bp0.mvalence1 == bp1.mvalence1 && - bp0.matom0 == bp1.matom0 && - bp0.matom1 == bp1.matom1); +bool BVParam::BondEqual::operator()(const BVParam& bp0, + const BVParam& bp1) const { + return (&bp0 == &bp1) || + (bp0.mvalence0 == bp1.mvalence0 && bp0.mvalence1 == bp1.mvalence1 && + bp0.matom0 == bp1.matom0 && bp0.matom1 == bp1.matom1); } -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy DIFFPY_INSTANTIATE_SERIALIZATION(diffpy::srreal::BVParam) diff --git a/src/diffpy/srreal/BVParam.hpp b/src/diffpy/srreal/BVParam.hpp index 061fb98c..4a02dd59 100644 --- a/src/diffpy/srreal/BVParam.hpp +++ b/src/diffpy/srreal/BVParam.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy 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. -* -****************************************************************************** -* -* class BVParam -- bond valence parameters for a cation-anion pair -* -*****************************************************************************/ + * + * libdiffpy 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. + * + ****************************************************************************** + * + * class BVParam -- bond valence parameters for a cation-anion pair + * + *****************************************************************************/ #ifndef BVPARAM_HPP_INCLUDED #define BVPARAM_HPP_INCLUDED @@ -22,72 +22,68 @@ #include #include +#include + namespace diffpy { namespace srreal { -class BVParam -{ - public: - - // constructors - BVParam(); - BVParam(const std::string& atom0, int valence0, - const std::string& atom1, int valence1, - double Ro=0.0, double B=0.0, std::string ref_id=""); - - // methods - /// comparison binary_function - bool operator==(const BVParam& other) const; - bool operator!=(const BVParam& other) const; - /// Return bond valence at a specified distance - double bondvalence(double distance) const; - /// Return distance corresponding to a specified bond valence - double bondvalenceToDistance(double bvalence) const; - /// obtain data from a cif record in bvparm.cif - void setFromCifLine(const std::string&); +class DLL_EXPORT BVParam { + public: + // constructors + BVParam(); + BVParam(const std::string& atom0, int valence0, const std::string& atom1, + int valence1, double Ro = 0.0, double B = 0.0, + std::string ref_id = ""); - // data - std::string matom0; - int mvalence0; - std::string matom1; - int mvalence1; - double mRo; - double mB; - std::string mref_id; + // methods + /// comparison binary_function + bool operator==(const BVParam& other) const; + bool operator!=(const BVParam& other) const; + /// Return bond valence at a specified distance + double bondvalence(double distance) const; + /// Return distance corresponding to a specified bond valence + double bondvalenceToDistance(double bvalence) const; + /// obtain data from a cif record in bvparm.cif + void setFromCifLine(const std::string&); - // hash function for cation-anion bond type only - class BondHash - { - public: - size_t operator()(const BVParam&) const; - }; + // data + std::string matom0; + int mvalence0; + std::string matom1; + int mvalence1; + double mRo; + double mB; + std::string mref_id; - // equality test for cation-anion bond type - class BondEqual - { - public: - bool operator()(const BVParam& bp0, const BVParam& bp1) const; - }; + // hash function for cation-anion bond type only + class DLL_EXPORT BondHash { + public: + size_t operator()(const BVParam&) const; + }; - private: + // equality test for cation-anion bond type + class DLL_EXPORT BondEqual { + public: + bool operator()(const BVParam& bp0, const BVParam& bp1) const; + }; - // serialization - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - ar & matom0; - ar & mvalence0; - ar & matom1; - ar & mvalence1; - ar & mRo; - ar & mB; - ar & mref_id; - } + private: + // serialization + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + ar & matom0; + ar & mvalence0; + ar & matom1; + ar & mvalence1; + ar & mRo; + ar & mB; + ar & mref_id; + } }; // class BVParam -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy #endif // BVPARAM_HPP_INCLUDED diff --git a/src/diffpy/srreal/BVParametersTable.cpp b/src/diffpy/srreal/BVParametersTable.cpp index 896cd463..5e8547ba 100644 --- a/src/diffpy/srreal/BVParametersTable.cpp +++ b/src/diffpy/srreal/BVParametersTable.cpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy 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. -* -****************************************************************************** -* -* class BVParametersTable -- table of bond valence sum parameters -* -*****************************************************************************/ + * + * libdiffpy 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. + * + ****************************************************************************** + * + * class BVParametersTable -- table of bond valence sum parameters + * + *****************************************************************************/ #include #include @@ -32,169 +32,134 @@ namespace srreal { // Static Methods ------------------------------------------------------------ -const BVParam& BVParametersTable::none() -{ - static const BVParam bpnone; - return bpnone; +const BVParam& BVParametersTable::none() { + static const BVParam bpnone; + return bpnone; } // Public Methods ------------------------------------------------------------ -int BVParametersTable::getAtomValence(const string& smbl) const -{ - AtomTypeValence::const_iterator ii = matomvalence.find(smbl); - int rv = (ii != matomvalence.end()) ? ii->second : atomValence(smbl); - return rv; +int BVParametersTable::getAtomValence(const string& smbl) const { + AtomTypeValence::const_iterator ii = matomvalence.find(smbl); + int rv = (ii != matomvalence.end()) ? ii->second : atomValence(smbl); + return rv; } - -void BVParametersTable::setAtomValence(const string& smbl, int value) -{ - matomvalence[smbl] = value; +void BVParametersTable::setAtomValence(const string& smbl, int value) { + matomvalence[smbl] = value; } - -void BVParametersTable::resetAtomValences() -{ - matomvalence.clear(); +void BVParametersTable::resetAtomValences() { matomvalence.clear(); } + +const BVParam& BVParametersTable::lookup(const BVParam& bpk) const { + SetOfBVParam::const_iterator bpit; + bpit = mcustomtable.find(bpk); + if (bpit != mcustomtable.end()) return *bpit; + const SetOfBVParam& stdtable = this->getStandardSetOfBVParam(); + bpit = stdtable.find(bpk); + if (bpit != stdtable.end()) return *bpit; + // unspecified cations are marked with valence 9 + // perform this search only if the first atom is indeed a cation + if (!(bpk.mvalence0 > 0)) return this->none(); + BVParam bpk9 = bpk; + bpk9.mvalence0 = 9; + bpit = mcustomtable.find(bpk9); + if (bpit != mcustomtable.end()) return *bpit; + bpit = stdtable.find(bpk9); + if (bpit != stdtable.end()) return *bpit; + // not found - return blank BVParam + return this->none(); } - -const BVParam& BVParametersTable::lookup(const BVParam& bpk) const -{ - SetOfBVParam::const_iterator bpit; - bpit = mcustomtable.find(bpk); - if (bpit != mcustomtable.end()) return *bpit; - const SetOfBVParam& stdtable = this->getStandardSetOfBVParam(); - bpit = stdtable.find(bpk); - if (bpit != stdtable.end()) return *bpit; - // unspecified cations are marked with valence 9 - // perform this search only if the first atom is indeed a cation - if (!(bpk.mvalence0 > 0)) return this->none(); - BVParam bpk9 = bpk; - bpk9.mvalence0 = 9; - bpit = mcustomtable.find(bpk9); - if (bpit != mcustomtable.end()) return *bpit; - bpit = stdtable.find(bpk9); - if (bpit != stdtable.end()) return *bpit; - // not found - return blank BVParam - return this->none(); +const BVParam& BVParametersTable::lookup(const string& smbl0, + const string& smbl1) const { + const int v0 = this->getAtomValence(smbl0); + const int v1 = this->getAtomValence(smbl1); + const BVParam& rv = + this->lookup(atomBareSymbol(smbl0), v0, atomBareSymbol(smbl1), v1); + return rv; } - -const BVParam& -BVParametersTable::lookup(const string& smbl0, const string& smbl1) const -{ - const int v0 = this->getAtomValence(smbl0); - const int v1 = this->getAtomValence(smbl1); - const BVParam& rv = this->lookup( - atomBareSymbol(smbl0), v0, - atomBareSymbol(smbl1), v1); - return rv; -} - - const BVParam& BVParametersTable::lookup(const string& atom0, int valence0, - const string& atom1, int valence1) const -{ - BVParam bpk(atom0, valence0, atom1, valence1); - const BVParam& rv = this->lookup(bpk); - return rv; + const string& atom1, + int valence1) const { + BVParam bpk(atom0, valence0, atom1, valence1); + const BVParam& rv = this->lookup(bpk); + return rv; } - -void BVParametersTable::setCustom(const BVParam& bp) -{ - this->resetCustom(bp); - mcustomtable.insert(bp); +void BVParametersTable::setCustom(const BVParam& bp) { + this->resetCustom(bp); + mcustomtable.insert(bp); } - void BVParametersTable::setCustom(const string& atom0, int valence0, - const string& atom1, int valence1, - double Ro, double b, std::string ref_id) -{ - BVParam bp(atom0, valence0, atom1, valence1, Ro, b, ref_id); - this->setCustom(bp); + const string& atom1, int valence1, double Ro, + double b, std::string ref_id) { + BVParam bp(atom0, valence0, atom1, valence1, Ro, b, ref_id); + this->setCustom(bp); } - -void BVParametersTable::resetCustom(const BVParam& bp) -{ - mcustomtable.erase(bp); +void BVParametersTable::resetCustom(const BVParam& bp) { + mcustomtable.erase(bp); } - void BVParametersTable::resetCustom(const string& atom0, int valence0, - const string& atom1, int valence1) -{ - BVParam bp(atom0, valence0, atom1, valence1); - this->resetCustom(bp); + const string& atom1, int valence1) { + BVParam bp(atom0, valence0, atom1, valence1); + this->resetCustom(bp); } +void BVParametersTable::resetAll() { mcustomtable.clear(); } -void BVParametersTable::resetAll() -{ - mcustomtable.clear(); +const BVParametersTable::SetOfBVParam& BVParametersTable::getAllCustom() const { + return mcustomtable; } - -const BVParametersTable::SetOfBVParam& -BVParametersTable::getAllCustom() const -{ - return mcustomtable; -} - - -BVParametersTable::SetOfBVParam -BVParametersTable::getAll() const -{ - // insert inserts only those items that are not yet in the set, therefore - // we start with the custom table and then add the standard entries. - SetOfBVParam rv = mcustomtable; - const SetOfBVParam& stdtable = this->getStandardSetOfBVParam(); - rv.insert(stdtable.begin(), stdtable.end()); - return rv; +BVParametersTable::SetOfBVParam BVParametersTable::getAll() const { + // insert inserts only those items that are not yet in the set, therefore + // we start with the custom table and then add the standard entries. + SetOfBVParam rv = mcustomtable; + const SetOfBVParam& stdtable = this->getStandardSetOfBVParam(); + rv.insert(stdtable.begin(), stdtable.end()); + return rv; } // Private Methods ----------------------------------------------------------- const BVParametersTable::SetOfBVParam& -BVParametersTable::getStandardSetOfBVParam() const -{ - using namespace diffpy::runtimepath; - using diffpy::validators::ensureFileOK; - static unique_ptr the_set; - if (!the_set) - { - the_set.reset(new SetOfBVParam); - string bvparmfile = datapath("bvparm2011sel.cif"); - ifstream fp(bvparmfile.c_str()); - ensureFileOK(bvparmfile, fp); - // read the header up to _valence_param_B and then up to an empty line. - LineReader lnrd; - lnrd.commentmark = '#'; - while (fp >> lnrd) - { - if (lnrd.wcount() && lnrd.words[0] == "_valence_param_B") break; - } - // skip to an empty line - while (fp >> lnrd && !lnrd.isblank()) { } - // load data lines skipping the empty or commented entries - while (fp >> lnrd) - { - if (lnrd.isignored()) continue; - BVParam bp; - bp.setFromCifLine(lnrd.line); - assert(!the_set->count(bp)); - the_set->insert(bp); - } +BVParametersTable::getStandardSetOfBVParam() const { + using namespace diffpy::runtimepath; + using diffpy::validators::ensureFileOK; + static unique_ptr the_set; + if (!the_set) { + the_set.reset(new SetOfBVParam); + string bvparmfile = datapath("bvparm2011sel.cif"); + ifstream fp(bvparmfile.c_str()); + ensureFileOK(bvparmfile, fp); + // read the header up to _valence_param_B and then up to an empty line. + LineReader lnrd; + lnrd.commentmark = '#'; + while (fp >> lnrd) { + if (lnrd.wcount() && lnrd.words[0] == "_valence_param_B") break; + } + // skip to an empty line + while (fp >> lnrd && !lnrd.isblank()) { + } + // load data lines skipping the empty or commented entries + while (fp >> lnrd) { + if (lnrd.isignored()) continue; + BVParam bp; + bp.setFromCifLine(lnrd.line); + assert(!the_set->count(bp)); + the_set->insert(bp); } - return *the_set; + } + return *the_set; } -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/BVParametersTable.hpp b/src/diffpy/srreal/BVParametersTable.hpp index 690ecb04..c8ca1b74 100644 --- a/src/diffpy/srreal/BVParametersTable.hpp +++ b/src/diffpy/srreal/BVParametersTable.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy 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. -* -****************************************************************************** -* -* class BVParametersTable -- table of bond valence sum parameters -* -*****************************************************************************/ + * + * libdiffpy 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. + * + ****************************************************************************** + * + * class BVParametersTable -- table of bond valence sum parameters + * + *****************************************************************************/ #ifndef BVPARAMETERSTABLE_HPP_INCLUDED #define BVPARAMETERSTABLE_HPP_INCLUDED @@ -27,70 +27,67 @@ #include #include +#include + namespace diffpy { namespace srreal { typedef boost::shared_ptr BVParametersTablePtr; -class BVParametersTable -{ - - public: - - // types - typedef std::unordered_set SetOfBVParam; - - // static methods - static const BVParam& none(); - - // methods - int getAtomValence(const std::string&) const; - void setAtomValence(const std::string&, int value); - void resetAtomValences(); - const BVParam& lookup(const BVParam&) const; - const BVParam& lookup( - const std::string& smbl0, const std::string& smbl1) const; - const BVParam& lookup(const std::string& atom0, int valence0, - const std::string& atom1, int valence1) const; - void setCustom(const BVParam&); - void setCustom(const std::string& atom0, int valence0, - const std::string& atom1, int valence1, - double Ro, double b, std::string ref_id=""); - void resetCustom(const BVParam&); - void resetCustom(const std::string& atom0, int valence0, - const std::string& atom1, int valence1); - void resetAll(); - const SetOfBVParam& getAllCustom() const; - SetOfBVParam getAll() const; - - private: - - // types - typedef std::unordered_map AtomTypeValence; - - // data - SetOfBVParam mcustomtable; - AtomTypeValence matomvalence; - - // methods - const SetOfBVParam& getStandardSetOfBVParam() const; - - // serialization - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - ar & mcustomtable; - if (version >= 1) { - ar & matomvalence; - } - } +class DLL_EXPORT BVParametersTable { + public: + // types + typedef std::unordered_set + SetOfBVParam; + + // static methods + static const BVParam& none(); + + // methods + int getAtomValence(const std::string&) const; + void setAtomValence(const std::string&, int value); + void resetAtomValences(); + const BVParam& lookup(const BVParam&) const; + const BVParam& lookup(const std::string& smbl0, + const std::string& smbl1) const; + const BVParam& lookup(const std::string& atom0, int valence0, + const std::string& atom1, int valence1) const; + void setCustom(const BVParam&); + void setCustom(const std::string& atom0, int valence0, + const std::string& atom1, int valence1, double Ro, double b, + std::string ref_id = ""); + void resetCustom(const BVParam&); + void resetCustom(const std::string& atom0, int valence0, + const std::string& atom1, int valence1); + void resetAll(); + const SetOfBVParam& getAllCustom() const; + SetOfBVParam getAll() const; + + private: + // types + typedef std::unordered_map AtomTypeValence; + + // data + SetOfBVParam mcustomtable; + AtomTypeValence matomvalence; + + // methods + const SetOfBVParam& getStandardSetOfBVParam() const; + + // serialization + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + ar & mcustomtable; + if (version >= 1) { + ar & matomvalence; + } + } }; // class BVParametersTable -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/BVSCalculator.cpp b/src/diffpy/srreal/BVSCalculator.cpp index 44e5de46..b5a66a66 100644 --- a/src/diffpy/srreal/BVSCalculator.cpp +++ b/src/diffpy/srreal/BVSCalculator.cpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy 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. -* -****************************************************************************** -* -* class BVSCalculator -- concrete counter of pairs in a structure. -* -*****************************************************************************/ + * + * libdiffpy 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. + * + ****************************************************************************** + * + * class BVSCalculator -- concrete counter of pairs in a structure. + * + *****************************************************************************/ #include #include @@ -32,209 +32,168 @@ namespace srreal { // Constructor --------------------------------------------------------------- -BVSCalculator::BVSCalculator() -{ - // default configuration - const double valence_precision = 1e-5; - // use very large rmax, it will be cropped by rmaxFromPrecision - this->setRmax(100); - BVParametersTablePtr bvtb(new BVParametersTable); - this->setBVParamTable(bvtb); - this->setValencePrecision(valence_precision); - this->setStructure(mstructure); - // attributes - this->registerDoubleAttribute("valenceprecision", this, - &BVSCalculator::getValencePrecision, - &BVSCalculator::setValencePrecision); - this->registerDoubleAttribute("rmaxused", this, - &BVSCalculator::getRmaxUsed); +BVSCalculator::BVSCalculator() { + // default configuration + const double valence_precision = 1e-5; + // use very large rmax, it will be cropped by rmaxFromPrecision + this->setRmax(100); + BVParametersTablePtr bvtb(new BVParametersTable); + this->setBVParamTable(bvtb); + this->setValencePrecision(valence_precision); + this->setStructure(mstructure); + // attributes + this->registerDoubleAttribute("valenceprecision", this, + &BVSCalculator::getValencePrecision, + &BVSCalculator::setValencePrecision); + this->registerDoubleAttribute("rmaxused", this, &BVSCalculator::getRmaxUsed); } // Public Methods ------------------------------------------------------------ // results -QuantityType BVSCalculator::valences() const -{ - QuantityType rv(mstructure_cache.valences.begin(), - mstructure_cache.valences.end()); - return rv; +QuantityType BVSCalculator::valences() const { + QuantityType rv(mstructure_cache.valences.begin(), + mstructure_cache.valences.end()); + return rv; } - -QuantityType BVSCalculator::bvdiff() const -{ - QuantityType vobs = this->valences(); - assert(vobs.size() == this->value().size()); - int cntsites = this->countSites(); - QuantityType rv(cntsites); - const QuantityType& vsim = this->value(); - for (int i = 0; i < cntsites; ++i) - { - rv[i] = fabs(vobs[i]) - fabs(vsim[i]); - } - return rv; +QuantityType BVSCalculator::bvdiff() const { + QuantityType vobs = this->valences(); + assert(vobs.size() == this->value().size()); + int cntsites = this->countSites(); + QuantityType rv(cntsites); + const QuantityType& vsim = this->value(); + for (int i = 0; i < cntsites; ++i) { + rv[i] = fabs(vobs[i]) - fabs(vsim[i]); + } + return rv; } - -double BVSCalculator::bvmsdiff() const -{ - QuantityType bd = this->bvdiff(); - int cntsites = this->countSites(); - assert(int(bd.size()) == cntsites); - double sumofsquares = 0.0; - for (int i = 0; i < cntsites; ++i) - { - sumofsquares += mstructure->siteMultiplicity(i) * - mstructure->siteOccupancy(i) * bd[i] * bd[i]; - } - double totocc = mstructure->totalOccupancy(); - double rv = (totocc > 0.0) ? (sumofsquares / totocc) : 0.0; - return rv; +double BVSCalculator::bvmsdiff() const { + QuantityType bd = this->bvdiff(); + int cntsites = this->countSites(); + assert(int(bd.size()) == cntsites); + double sumofsquares = 0.0; + for (int i = 0; i < cntsites; ++i) { + sumofsquares += mstructure->siteMultiplicity(i) * + mstructure->siteOccupancy(i) * bd[i] * bd[i]; + } + double totocc = mstructure->totalOccupancy(); + double rv = (totocc > 0.0) ? (sumofsquares / totocc) : 0.0; + return rv; } - -double BVSCalculator::bvrmsdiff() const -{ - double rvsq = this->bvmsdiff(); - return sqrt(rvsq); +double BVSCalculator::bvrmsdiff() const { + double rvsq = this->bvmsdiff(); + return sqrt(rvsq); } - -void BVSCalculator::setBVParamTable(BVParametersTablePtr bvtb) -{ - ensureNonNull("BVParametersTable", bvtb); - mbvptable = bvtb; +void BVSCalculator::setBVParamTable(BVParametersTablePtr bvtb) { + ensureNonNull("BVParametersTable", bvtb); + mbvptable = bvtb; } +BVParametersTablePtr& BVSCalculator::getBVParamTable() { return mbvptable; } -BVParametersTablePtr& BVSCalculator::getBVParamTable() -{ - return mbvptable; +const BVParametersTablePtr& BVSCalculator::getBVParamTable() const { + return mbvptable; } - -const BVParametersTablePtr& BVSCalculator::getBVParamTable() const -{ - return mbvptable; +void BVSCalculator::setValencePrecision(double eps) { + ensureEpsilonPositive("valenceprecision", eps); + mvalenceprecision = eps; } +double BVSCalculator::getValencePrecision() const { return mvalenceprecision; } -void BVSCalculator::setValencePrecision(double eps) -{ - ensureEpsilonPositive("valenceprecision", eps); - mvalenceprecision = eps; -} - - -double BVSCalculator::getValencePrecision() const -{ - return mvalenceprecision; -} - - -double BVSCalculator::getRmaxUsed() const -{ - double rv = min(this->getRmax(), - this->rmaxFromPrecision(this->getValencePrecision())); - return rv; +double BVSCalculator::getRmaxUsed() const { + double rv = + min(this->getRmax(), this->rmaxFromPrecision(this->getValencePrecision())); + return rv; } // Protected Methods --------------------------------------------------------- // PairQuantity overloads -void BVSCalculator::resetValue() -{ - // structure data need to be cached for rmaxFromPrecision - this->cacheStructureData(); - this->resizeValue(this->countSites()); - this->PairQuantity::resetValue(); +void BVSCalculator::resetValue() { + // structure data need to be cached for rmaxFromPrecision + this->cacheStructureData(); + this->resizeValue(this->countSites()); + this->PairQuantity::resetValue(); } - -void BVSCalculator::configureBondGenerator(BaseBondGenerator& bnds) const -{ - bnds.setRmax(this->getRmaxUsed()); +void BVSCalculator::configureBondGenerator(BaseBondGenerator& bnds) const { + bnds.setRmax(this->getRmaxUsed()); } - void BVSCalculator::addPairContribution(const BaseBondGenerator& bnds, - int summationscale) -{ - const string& a0 = mstructure_cache.baresymbols[bnds.site0()]; - const string& a1 = mstructure_cache.baresymbols[bnds.site1()]; - int v0 = mstructure_cache.valences[bnds.site0()]; - int v1 = mstructure_cache.valences[bnds.site1()]; - const BVParametersTable& bvtb = *(this->getBVParamTable()); - const BVParam& bp = bvtb.lookup(a0, v0, a1, v1); - // do nothing if there are no bond parameters for this pair - if (&bp == &bvtb.none()) return; - double valencehalf = bp.bondvalence(bnds.distance()) / 2.0; - int pm0 = (v0 >= 0) ? 1 : -1; - int pm1 = (v1 >= 0) ? 1 : -1; - const double& o0 = mstructure->siteOccupancy(bnds.site0()); - const double& o1 = mstructure->siteOccupancy(bnds.site1()); - mvalue[bnds.site0()] += summationscale * pm0 * valencehalf * o1; - mvalue[bnds.site1()] += summationscale * pm1 * valencehalf * o0; + int summationscale) { + const string& a0 = mstructure_cache.baresymbols[bnds.site0()]; + const string& a1 = mstructure_cache.baresymbols[bnds.site1()]; + int v0 = mstructure_cache.valences[bnds.site0()]; + int v1 = mstructure_cache.valences[bnds.site1()]; + const BVParametersTable& bvtb = *(this->getBVParamTable()); + const BVParam& bp = bvtb.lookup(a0, v0, a1, v1); + // do nothing if there are no bond parameters for this pair + if (&bp == &bvtb.none()) return; + double valencehalf = bp.bondvalence(bnds.distance()) / 2.0; + int pm0 = (v0 >= 0) ? 1 : -1; + int pm1 = (v1 >= 0) ? 1 : -1; + const double& o0 = mstructure->siteOccupancy(bnds.site0()); + const double& o1 = mstructure->siteOccupancy(bnds.site1()); + mvalue[bnds.site0()] += summationscale * pm0 * valencehalf * o1; + mvalue[bnds.site1()] += summationscale * pm1 * valencehalf * o0; } // Private Methods ----------------------------------------------------------- -void BVSCalculator::cacheStructureData() -{ - int cntsites = this->countSites(); - mstructure_cache.baresymbols.resize(cntsites); - mstructure_cache.valences.resize(cntsites); - const BVParametersTable& bvtb = *(this->getBVParamTable()); - for (int i = 0; i < cntsites; ++i) - { - const string& smbl = mstructure->siteAtomType(i); - mstructure_cache.baresymbols[i] = atomBareSymbol(smbl); - mstructure_cache.valences[i] = bvtb.getAtomValence(smbl); - } -} - - -double BVSCalculator::rmaxFromPrecision(double eps) const -{ - const BVParametersTable& bvtb = *(this->getBVParamTable()); - // build a set of unique (symbol, valence) pairs - typedef std::unordered_set< - pair, - boost::hash< pair > - > SymbolValenceSet; - SymbolValenceSet allsymvals; - assert(int(mstructure_cache.baresymbols.size()) == this->countSites()); - assert(int(mstructure_cache.valences.size()) == this->countSites()); - for (int i = 0; i < this->countSites(); ++i) - { - allsymvals.insert(make_pair(mstructure_cache.baresymbols[i], - mstructure_cache.valences[i])); - } - // find all used bond parameters - BVParametersTable::SetOfBVParam bpused; - SymbolValenceSet::const_iterator sv0, sv1; - for (sv0 = allsymvals.begin(); sv0 != allsymvals.end(); ++sv0) - { - for (sv1 = sv0; sv1 != allsymvals.end(); ++sv1) - { - const BVParam& bp = bvtb.lookup( - sv0->first, sv0->second, sv1->first, sv1->second); - bpused.insert(bp); - } - } - double rv = 0.0; - BVParametersTable::SetOfBVParam::iterator bpit; - for (bpit = bpused.begin(); bpit != bpused.end(); ++bpit) - { - rv = max(rv, bpit->bondvalenceToDistance(eps)); +void BVSCalculator::cacheStructureData() { + int cntsites = this->countSites(); + mstructure_cache.baresymbols.resize(cntsites); + mstructure_cache.valences.resize(cntsites); + const BVParametersTable& bvtb = *(this->getBVParamTable()); + for (int i = 0; i < cntsites; ++i) { + const string& smbl = mstructure->siteAtomType(i); + mstructure_cache.baresymbols[i] = atomBareSymbol(smbl); + mstructure_cache.valences[i] = bvtb.getAtomValence(smbl); + } +} + +double BVSCalculator::rmaxFromPrecision(double eps) const { + const BVParametersTable& bvtb = *(this->getBVParamTable()); + // build a set of unique (symbol, valence) pairs + typedef std::unordered_set, + boost::hash > > + SymbolValenceSet; + SymbolValenceSet allsymvals; + assert(int(mstructure_cache.baresymbols.size()) == this->countSites()); + assert(int(mstructure_cache.valences.size()) == this->countSites()); + for (int i = 0; i < this->countSites(); ++i) { + allsymvals.insert( + make_pair(mstructure_cache.baresymbols[i], mstructure_cache.valences[i])); + } + // find all used bond parameters + BVParametersTable::SetOfBVParam bpused; + SymbolValenceSet::const_iterator sv0, sv1; + for (sv0 = allsymvals.begin(); sv0 != allsymvals.end(); ++sv0) { + for (sv1 = sv0; sv1 != allsymvals.end(); ++sv1) { + const BVParam& bp = + bvtb.lookup(sv0->first, sv0->second, sv1->first, sv1->second); + bpused.insert(bp); } - return rv; + } + double rv = 0.0; + BVParametersTable::SetOfBVParam::iterator bpit; + for (bpit = bpused.begin(); bpit != bpused.end(); ++bpit) { + rv = max(rv, bpit->bondvalenceToDistance(eps)); + } + return rv; } -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/BVSCalculator.hpp b/src/diffpy/srreal/BVSCalculator.hpp index c864b31b..3bcd9ce6 100644 --- a/src/diffpy/srreal/BVSCalculator.hpp +++ b/src/diffpy/srreal/BVSCalculator.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy 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. -* -****************************************************************************** -* -* class BVSCalculator -- bond valence sums calculator -* -*****************************************************************************/ + * + * libdiffpy 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. + * + ****************************************************************************** + * + * class BVSCalculator -- bond valence sums calculator + * + *****************************************************************************/ #ifndef BVSCALCULATOR_HPP_INCLUDED #define BVSCALCULATOR_HPP_INCLUDED @@ -22,81 +22,78 @@ #include #include +#include + namespace diffpy { namespace srreal { -class BVSCalculator : public PairQuantity -{ - public: - - // constructor - BVSCalculator(); - - // results - /// expected valence per each site - QuantityType valences() const; - /// difference between expected and calculated absolute valence at - /// each site. Positive for underbonding, negative for overbonding. - QuantityType bvdiff() const; - /// mean square difference of BVS from the expected values - double bvmsdiff() const; - /// root mean square difference of BVS from the expected values - double bvrmsdiff() const; - - // access and configuration of BVS parameters - void setBVParamTable(BVParametersTablePtr); - BVParametersTablePtr& getBVParamTable(); - const BVParametersTablePtr& getBVParamTable() const; - - // R-range configuration using the valence precision - /// set cutoff value for bond valence contributions - void setValencePrecision(double); - /// return cutoff value for bond valence contributions - double getValencePrecision() const; - /// effective rmax value, where valence contributions become smaller - /// than the valence precision cutoff. Always less or equal to rmax. - double getRmaxUsed() const; - - protected: - - // PairQuantity overloads - virtual void resetValue(); - virtual void configureBondGenerator(BaseBondGenerator&) const; - virtual void addPairContribution(const BaseBondGenerator&, int); - - private: - - // methods - void cacheStructureData(); - /// rmax necessary for achieving the specified valence precision - double rmaxFromPrecision(double) const; - - // data - // configuration - BVParametersTablePtr mbvptable; - double mvalenceprecision; - // cache - struct { - std::vector baresymbols; - std::vector valences; - } mstructure_cache; - - // serialization - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - ar & boost::serialization::base_object(*this); - ar & mbvptable; - ar & mvalenceprecision; - ar & mstructure_cache.baresymbols; - ar & mstructure_cache.valences; - } +class DLL_EXPORT BVSCalculator : public PairQuantity { + public: + // constructor + BVSCalculator(); + + // results + /// expected valence per each site + QuantityType valences() const; + /// difference between expected and calculated absolute valence at + /// each site. Positive for underbonding, negative for overbonding. + QuantityType bvdiff() const; + /// mean square difference of BVS from the expected values + double bvmsdiff() const; + /// root mean square difference of BVS from the expected values + double bvrmsdiff() const; + + // access and configuration of BVS parameters + void setBVParamTable(BVParametersTablePtr); + BVParametersTablePtr& getBVParamTable(); + const BVParametersTablePtr& getBVParamTable() const; + + // R-range configuration using the valence precision + /// set cutoff value for bond valence contributions + void setValencePrecision(double); + /// return cutoff value for bond valence contributions + double getValencePrecision() const; + /// effective rmax value, where valence contributions become smaller + /// than the valence precision cutoff. Always less or equal to rmax. + double getRmaxUsed() const; + + protected: + // PairQuantity overloads + virtual void resetValue(); + virtual void configureBondGenerator(BaseBondGenerator&) const; + virtual void addPairContribution(const BaseBondGenerator&, int); + + private: + // methods + void cacheStructureData(); + /// rmax necessary for achieving the specified valence precision + double rmaxFromPrecision(double) const; + + // data + // configuration + BVParametersTablePtr mbvptable; + double mvalenceprecision; + // cache + struct { + std::vector baresymbols; + std::vector valences; + } mstructure_cache; + + // serialization + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + ar& boost::serialization::base_object(*this); + ar & mbvptable; + ar & mvalenceprecision; + ar & mstructure_cache.baresymbols; + ar & mstructure_cache.valences; + } }; // class BVSCalculator -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/BaseBondGenerator.cpp b/src/diffpy/srreal/BaseBondGenerator.cpp index 6fa3b002..e05a9f60 100644 --- a/src/diffpy/srreal/BaseBondGenerator.cpp +++ b/src/diffpy/srreal/BaseBondGenerator.cpp @@ -1,21 +1,21 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class BaseBondGenerator -- semi-abstract class for generation -* of all atom pairs containing specified anchor atom. -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class BaseBondGenerator -- semi-abstract class for generation + * of all atom pairs containing specified anchor atom. + * + *****************************************************************************/ #include #include @@ -26,253 +26,175 @@ using diffpy::mathutils::eps_eq; namespace diffpy { namespace srreal { -//using namespace std; +// using namespace std; // Constructor --------------------------------------------------------------- -BaseBondGenerator::BaseBondGenerator(StructureAdapterConstPtr stru) : - msite_anchor(0), - mrmin(0.0), - mrmax(DEFAULT_BONDGENERATOR_RMAX), - mstructure(stru), - mr0(R3::zerovector), - mr1(R3::zerovector), - mr01(R3::zerovector), - mdistance(0.0) -{ - int cnt = stru->countSites(); - msite_all.resize(cnt); - for (int i = 0; i != cnt; ++i) msite_all[i] = i; - msite_first = msite_all.begin(); - msite_last = msite_all.end(); - this->setFinishedFlag(); +BaseBondGenerator::BaseBondGenerator(StructureAdapterConstPtr stru) + : msite_anchor(0), + mrmin(0.0), + mrmax(DEFAULT_BONDGENERATOR_RMAX), + mstructure(stru), + mr0(R3::zerovector), + mr1(R3::zerovector), + mr01(R3::zerovector), + mdistance(0.0) { + int cnt = stru->countSites(); + msite_all.resize(cnt); + for (int i = 0; i != cnt; ++i) msite_all[i] = i; + msite_first = msite_all.begin(); + msite_last = msite_all.end(); + this->setFinishedFlag(); } // Public Methods ------------------------------------------------------------ // loop control -void BaseBondGenerator::rewind() -{ - msite_current = msite_first; - // avoid calling rewindSymmetry at an invalid site - if (this->finished()) return; - this->rewindSymmetry(); - this->advanceWhileInvalid(); +void BaseBondGenerator::rewind() { + msite_current = msite_first; + // avoid calling rewindSymmetry at an invalid site + if (this->finished()) return; + this->rewindSymmetry(); + this->advanceWhileInvalid(); } - -void BaseBondGenerator::next() -{ - this->getNextBond(); - this->advanceWhileInvalid(); +void BaseBondGenerator::next() { + this->getNextBond(); + this->advanceWhileInvalid(); } - -bool BaseBondGenerator::finished() const -{ - return msite_current >= msite_last; -} +bool BaseBondGenerator::finished() const { return msite_current >= msite_last; } // configuration -void BaseBondGenerator::selectAnchorSite(int anchor) -{ - assert(0 <= anchor && anchor < mstructure->countSites()); - msite_anchor = anchor; - mr0 = mstructure->siteCartesianPosition(msite_anchor); - this->setFinishedFlag(); +void BaseBondGenerator::selectAnchorSite(int anchor) { + assert(0 <= anchor && anchor < mstructure->countSites()); + msite_anchor = anchor; + mr0 = mstructure->siteCartesianPosition(msite_anchor); + this->setFinishedFlag(); } - -void BaseBondGenerator::selectSiteRange(int first, int last) -{ - assert(0 <= first); - assert(last <= mstructure->countSites()); - msite_first = msite_all.begin() + first; - msite_last = msite_all.begin() + last; - this->setFinishedFlag(); +void BaseBondGenerator::selectSiteRange(int first, int last) { + assert(0 <= first); + assert(last <= mstructure->countSites()); + msite_first = msite_all.begin() + first; + msite_last = msite_all.begin() + last; + this->setFinishedFlag(); } - -void BaseBondGenerator::selectSites(const SiteIndices& selection) -{ - msite_selection = selection; - msite_first = msite_selection.begin(); - msite_last = msite_selection.end(); - this->setFinishedFlag(); +void BaseBondGenerator::selectSites(const SiteIndices& selection) { + msite_selection = selection; + msite_first = msite_selection.begin(); + msite_last = msite_selection.end(); + this->setFinishedFlag(); } - -void BaseBondGenerator::selectSites( - SiteIndices::const_iterator first, - SiteIndices::const_iterator last) -{ - msite_first = first; - msite_last = last; - this->setFinishedFlag(); +void BaseBondGenerator::selectSites(SiteIndices::const_iterator first, + SiteIndices::const_iterator last) { + msite_first = first; + msite_last = last; + this->setFinishedFlag(); } - -void BaseBondGenerator::setRmin(double rmin) -{ - if (rmin != mrmin) this->setFinishedFlag(); - mrmin = rmin; +void BaseBondGenerator::setRmin(double rmin) { + if (rmin != mrmin) this->setFinishedFlag(); + mrmin = rmin; } - -void BaseBondGenerator::setRmax(double rmax) -{ - if (rmax != mrmax) this->setFinishedFlag(); - mrmax = rmax; +void BaseBondGenerator::setRmax(double rmax) { + if (rmax != mrmax) this->setFinishedFlag(); + mrmax = rmax; } // data query -const double& BaseBondGenerator::getRmin() const -{ - return mrmin; -} - - -const double& BaseBondGenerator::getRmax() const -{ - return mrmax; -} - - -int BaseBondGenerator::site0() const -{ - return msite_anchor; -} - - -int BaseBondGenerator::site1() const -{ - return *msite_current; -} +const double& BaseBondGenerator::getRmin() const { return mrmin; } +const double& BaseBondGenerator::getRmax() const { return mrmax; } -int BaseBondGenerator::multiplicity() const -{ - return mstructure->siteMultiplicity(this->site0()); -} +int BaseBondGenerator::site0() const { return msite_anchor; } +int BaseBondGenerator::site1() const { return *msite_current; } -const R3::Vector& BaseBondGenerator::r0() const -{ - return mr0; +int BaseBondGenerator::multiplicity() const { + return mstructure->siteMultiplicity(this->site0()); } +const R3::Vector& BaseBondGenerator::r0() const { return mr0; } -const R3::Vector& BaseBondGenerator::r1() const -{ - return mr1; -} +const R3::Vector& BaseBondGenerator::r1() const { return mr1; } +const double& BaseBondGenerator::distance() const { return mdistance; } -const double& BaseBondGenerator::distance() const -{ - return mdistance; -} - +const R3::Vector& BaseBondGenerator::r01() const { return mr01; } -const R3::Vector& BaseBondGenerator::r01() const -{ - return mr01; +const R3::Matrix& BaseBondGenerator::Ucartesian0() const { + return mstructure->siteCartesianUij(this->site0()); } - -const R3::Matrix& BaseBondGenerator::Ucartesian0() const -{ - return mstructure->siteCartesianUij(this->site0()); -} - - -const R3::Matrix& BaseBondGenerator::Ucartesian1() const -{ - return mstructure->siteCartesianUij(this->site1()); +const R3::Matrix& BaseBondGenerator::Ucartesian1() const { + return mstructure->siteCartesianUij(this->site1()); } - -double BaseBondGenerator::msd() const -{ - static R3::Vector s; - s = this->r01(); - double msd0 = meanSquareDisplacement(this->Ucartesian0(), s, - mstructure->siteAnisotropy(this->site0())); - double msd1 = meanSquareDisplacement(this->Ucartesian1(), s, - mstructure->siteAnisotropy(this->site1())); - double rv = msd0 + msd1; - return rv; +double BaseBondGenerator::msd() const { + static R3::Vector s; + s = this->r01(); + double msd0 = meanSquareDisplacement( + this->Ucartesian0(), s, mstructure->siteAnisotropy(this->site0())); + double msd1 = meanSquareDisplacement( + this->Ucartesian1(), s, mstructure->siteAnisotropy(this->site1())); + double rv = msd0 + msd1; + return rv; } // Protected Methods --------------------------------------------------------- -bool BaseBondGenerator::iterateSymmetry() -{ - return false; -} - +bool BaseBondGenerator::iterateSymmetry() { return false; } -void BaseBondGenerator::rewindSymmetry() -{ - mr1 = mstructure->siteCartesianPosition(this->site1()); - this->updateDistance(); +void BaseBondGenerator::rewindSymmetry() { + mr1 = mstructure->siteCartesianPosition(this->site1()); + this->updateDistance(); } - -void BaseBondGenerator::getNextBond() -{ - if (this->iterateSymmetry()) return; - ++msite_current; - // avoid calling rewindSymmetry at an invalid site - if (!(this->finished())) this->rewindSymmetry(); +void BaseBondGenerator::getNextBond() { + if (this->iterateSymmetry()) return; + ++msite_current; + // avoid calling rewindSymmetry at an invalid site + if (!(this->finished())) this->rewindSymmetry(); } - -void BaseBondGenerator::updateDistance() -{ - if ((mdistance = fabs(mr01[0] = mr1[0] - mr0[0])) > mrmax) return; - if ((mdistance = fabs(mr01[1] = mr1[1] - mr0[1])) > mrmax) return; - if ((mdistance = fabs(mr01[2] = mr1[2] - mr0[2])) > mrmax) return; - mdistance = R3::norm(mr01); +void BaseBondGenerator::updateDistance() { + if ((mdistance = fabs(mr01[0] = mr1[0] - mr0[0])) > mrmax) return; + if ((mdistance = fabs(mr01[1] = mr1[1] - mr0[1])) > mrmax) return; + if ((mdistance = fabs(mr01[2] = mr1[2] - mr0[2])) > mrmax) return; + mdistance = R3::norm(mr01); } // Private Methods ----------------------------------------------------------- -void BaseBondGenerator::advanceWhileInvalid() -{ - while (!this->finished() && - (this->bondOutOfRange() || this->atSelfPair())) - { - this->getNextBond(); - } +void BaseBondGenerator::advanceWhileInvalid() { + while (!this->finished() && (this->bondOutOfRange() || this->atSelfPair())) { + this->getNextBond(); + } } // Private Methods ----------------------------------------------------------- -bool BaseBondGenerator::bondOutOfRange() const -{ - const double& d = this->distance(); - bool rv = (d < this->getRmin()) || (d > this->getRmax()); - return rv; +bool BaseBondGenerator::bondOutOfRange() const { + const double& d = this->distance(); + bool rv = (d < this->getRmin()) || (d > this->getRmax()); + return rv; } - -bool BaseBondGenerator::atSelfPair() const -{ - bool rv = eps_eq(this->distance(), 0.0); - return rv; +bool BaseBondGenerator::atSelfPair() const { + bool rv = eps_eq(this->distance(), 0.0); + return rv; } +void BaseBondGenerator::setFinishedFlag() { msite_current = msite_last; } -void BaseBondGenerator::setFinishedFlag() -{ - msite_current = msite_last; -} - -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // End of file diff --git a/src/diffpy/srreal/BaseBondGenerator.hpp b/src/diffpy/srreal/BaseBondGenerator.hpp index 691c4666..435e1510 100644 --- a/src/diffpy/srreal/BaseBondGenerator.hpp +++ b/src/diffpy/srreal/BaseBondGenerator.hpp @@ -1,21 +1,21 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class BaseBondGenerator -- semi-abstract class for a generation -* of all atom pairs containing specified anchor atom. -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class BaseBondGenerator -- semi-abstract class for a generation + * of all atom pairs containing specified anchor atom. + * + *****************************************************************************/ #ifndef BASEBONDGENERATOR_HPP_INCLUDED #define BASEBONDGENERATOR_HPP_INCLUDED @@ -23,85 +23,80 @@ #include #include +#include + namespace diffpy { namespace srreal { /// Use zero default for rmax so any misconfiguration of r-limits is obvious. const double DEFAULT_BONDGENERATOR_RMAX = 0.0; -class BaseBondGenerator -{ - public: - - // constructor - BaseBondGenerator(StructureAdapterConstPtr); - virtual ~BaseBondGenerator() { } - - // methods - // loop control - virtual void rewind(); - bool finished() const; - void next(); - - // configuration - virtual void selectAnchorSite(int); - void selectSiteRange(int first, int last); - void selectSites(const SiteIndices&); - void selectSites( - SiteIndices::const_iterator first, - SiteIndices::const_iterator last); - virtual void setRmin(double); - virtual void setRmax(double); - - // get data - const double& getRmin() const; - const double& getRmax() const; - int site0() const; - int site1() const; - int multiplicity() const; - const R3::Vector& r0() const; - const R3::Vector& r1() const; - const double& distance() const; - const R3::Vector& r01() const; - virtual const R3::Matrix& Ucartesian0() const; - virtual const R3::Matrix& Ucartesian1() const; - double msd() const; - - protected: - - // data - int msite_anchor; - SiteIndices::const_iterator msite_first; - SiteIndices::const_iterator msite_last; - SiteIndices::const_iterator msite_current; - double mrmin; - double mrmax; - StructureAdapterConstPtr mstructure; - R3::Vector mr0; - R3::Vector mr1; - R3::Vector mr01; - double mdistance; - SiteIndices msite_all; - SiteIndices msite_selection; - - // methods - virtual bool iterateSymmetry(); - virtual void rewindSymmetry(); - virtual void getNextBond(); - void updateDistance(); - - private: - - // methods - void advanceWhileInvalid(); - bool bondOutOfRange() const; - bool atSelfPair() const; - void setFinishedFlag(); - +class DLL_EXPORT BaseBondGenerator { + public: + // constructor + BaseBondGenerator(StructureAdapterConstPtr); + virtual ~BaseBondGenerator() {} + + // methods + // loop control + virtual void rewind(); + bool finished() const; + void next(); + + // configuration + virtual void selectAnchorSite(int); + void selectSiteRange(int first, int last); + void selectSites(const SiteIndices&); + void selectSites(SiteIndices::const_iterator first, + SiteIndices::const_iterator last); + virtual void setRmin(double); + virtual void setRmax(double); + + // get data + const double& getRmin() const; + const double& getRmax() const; + int site0() const; + int site1() const; + int multiplicity() const; + const R3::Vector& r0() const; + const R3::Vector& r1() const; + const double& distance() const; + const R3::Vector& r01() const; + virtual const R3::Matrix& Ucartesian0() const; + virtual const R3::Matrix& Ucartesian1() const; + double msd() const; + + protected: + // data + int msite_anchor; + SiteIndices::const_iterator msite_first; + SiteIndices::const_iterator msite_last; + SiteIndices::const_iterator msite_current; + double mrmin; + double mrmax; + StructureAdapterConstPtr mstructure; + R3::Vector mr0; + R3::Vector mr1; + R3::Vector mr01; + double mdistance; + SiteIndices msite_all; + SiteIndices msite_selection; + + // methods + virtual bool iterateSymmetry(); + virtual void rewindSymmetry(); + virtual void getNextBond(); + void updateDistance(); + + private: + // methods + void advanceWhileInvalid(); + bool bondOutOfRange() const; + bool atSelfPair() const; + void setFinishedFlag(); }; - -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy #endif // BASEBONDGENERATOR_HPP_INCLUDED diff --git a/src/diffpy/srreal/BaseDebyeSum.cpp b/src/diffpy/srreal/BaseDebyeSum.cpp index e4165694..1fdfc7e8 100644 --- a/src/diffpy/srreal/BaseDebyeSum.cpp +++ b/src/diffpy/srreal/BaseDebyeSum.cpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy 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. -* -****************************************************************************** -* -* class BaseDebyeSum -- base class for concrete Debye sum calculators -* -*****************************************************************************/ + * + * libdiffpy 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. + * + ****************************************************************************** + * + * class BaseDebyeSum -- base class for concrete Debye sum calculators + * + *****************************************************************************/ #include #include @@ -29,8 +29,8 @@ using namespace std; using namespace diffpy::validators; -using diffpy::mathutils::eps_gt; using diffpy::mathutils::eps_eq; +using diffpy::mathutils::eps_gt; namespace diffpy { namespace srreal { @@ -42,256 +42,205 @@ namespace { /// Default cutoff for the Q-decreasing scale of the sine contributions. const double DEFAULT_DEBYE_PRECISION = 1e-6; -} // namespace +} // namespace // Constructor --------------------------------------------------------------- -BaseDebyeSum::BaseDebyeSum() : - mqmin(0.0), - mqmax(DEFAULT_QGRID_QMAX), - mqstep(DEFAULT_QGRID_QSTEP), - mdebyeprecision(DEFAULT_DEBYE_PRECISION) -{ - mstructure_cache.totaloccupancy = 0.0; - // default configuration - this->setPeakWidthModelByType("jeong"); - this->setEvaluatorType(OPTIMIZED); - // attributes - this->registerDoubleAttribute("debyeprecision", this, - &BaseDebyeSum::getDebyePrecision, - &BaseDebyeSum::setDebyePrecision); +BaseDebyeSum::BaseDebyeSum() + : mqmin(0.0), + mqmax(DEFAULT_QGRID_QMAX), + mqstep(DEFAULT_QGRID_QSTEP), + mdebyeprecision(DEFAULT_DEBYE_PRECISION) { + mstructure_cache.totaloccupancy = 0.0; + // default configuration + this->setPeakWidthModelByType("jeong"); + this->setEvaluatorType(OPTIMIZED); + // attributes + this->registerDoubleAttribute("debyeprecision", this, + &BaseDebyeSum::getDebyePrecision, + &BaseDebyeSum::setDebyePrecision); } // Public Methods ------------------------------------------------------------ // PairQuantity overloads -eventticker::EventTicker& BaseDebyeSum::ticker() const -{ - mticker.updateFrom(this->PeakWidthModelOwner::ticker()); - return mticker; +eventticker::EventTicker& BaseDebyeSum::ticker() const { + mticker.updateFrom(this->PeakWidthModelOwner::ticker()); + return mticker; } // results -QuantityType BaseDebyeSum::getF() const -{ - QuantityType rv = this->value(); - const double& totocc = mstructure_cache.totaloccupancy; - const int npts = pdfutils_qmaxSteps(this); - for (int kq = pdfutils_qminSteps(this); kq < npts; ++kq) - { - double sfavg = this->sfAverageAtkQ(kq); - double fscale = (sfavg * totocc) == 0 ? 0.0 : - 1.0 / (sfavg * sfavg * totocc); - rv[kq] *= fscale; - } - return rv; +QuantityType BaseDebyeSum::getF() const { + QuantityType rv = this->value(); + const double& totocc = mstructure_cache.totaloccupancy; + const int npts = pdfutils_qmaxSteps(this); + for (int kq = pdfutils_qminSteps(this); kq < npts; ++kq) { + double sfavg = this->sfAverageAtkQ(kq); + double fscale = + (sfavg * totocc) == 0 ? 0.0 : 1.0 / (sfavg * sfavg * totocc); + rv[kq] *= fscale; + } + return rv; } // Q-range methods -QuantityType BaseDebyeSum::getQgrid() const -{ - return pdfutils_getQgrid(this); -} +QuantityType BaseDebyeSum::getQgrid() const { return pdfutils_getQgrid(this); } // Q-range configuration -void BaseDebyeSum::setQmin(double qmin) -{ - ensureNonNegative("Qmin", qmin); - if (mqmin != qmin) mticker.click(); - mqmin = qmin; -} - - -const double& BaseDebyeSum::getQmin() const -{ - return mqmin; -} - - -void BaseDebyeSum::setQmax(double qmax) -{ - ensureNonNegative("Qmax", qmax); - if (mqmax != qmax) mticker.click(); - mqmax = qmax; -} - - -const double& BaseDebyeSum::getQmax() const -{ - return mqmax; +void BaseDebyeSum::setQmin(double qmin) { + ensureNonNegative("Qmin", qmin); + if (mqmin != qmin) mticker.click(); + mqmin = qmin; } +const double& BaseDebyeSum::getQmin() const { return mqmin; } -void BaseDebyeSum::setQstep(double qstep) -{ - ensureEpsilonPositive("Qstep", qstep); - if (mqstep != qstep) mticker.click(); - mqstep = qstep; +void BaseDebyeSum::setQmax(double qmax) { + ensureNonNegative("Qmax", qmax); + if (mqmax != qmax) mticker.click(); + mqmax = qmax; } +const double& BaseDebyeSum::getQmax() const { return mqmax; } -const double& BaseDebyeSum::getQstep() const -{ - return mqstep; +void BaseDebyeSum::setQstep(double qstep) { + ensureEpsilonPositive("Qstep", qstep); + if (mqstep != qstep) mticker.click(); + mqstep = qstep; } +const double& BaseDebyeSum::getQstep() const { return mqstep; } -void BaseDebyeSum::setDebyePrecision(double precision) -{ - if (mdebyeprecision != precision) mticker.click(); - mdebyeprecision = precision; +void BaseDebyeSum::setDebyePrecision(double precision) { + if (mdebyeprecision != precision) mticker.click(); + mdebyeprecision = precision; } - -const double& BaseDebyeSum::getDebyePrecision() const -{ - return mdebyeprecision; +const double& BaseDebyeSum::getDebyePrecision() const { + return mdebyeprecision; } // Protected Methods --------------------------------------------------------- // PairQuantity overloads -void BaseDebyeSum::resetValue() -{ - this->cacheStructureData(); - this->resizeValue(pdfutils_qmaxSteps(this)); - this->PairQuantity::resetValue(); +void BaseDebyeSum::resetValue() { + this->cacheStructureData(); + this->resizeValue(pdfutils_qmaxSteps(this)); + this->PairQuantity::resetValue(); } - void BaseDebyeSum::addPairContribution(const BaseBondGenerator& bnds, - int summationscale) -{ - const double dist = bnds.distance(); - if (eps_eq(0.0, dist)) return; - // calculate sigma parameter for the Debye-Waller dampign Gaussian - const double fwhm = this->getPeakWidthModel()->calculate(bnds); - const double fwhmtosigma = 1.0 / (2 * sqrt(2 * M_LN2)); - const double dwsigma = fwhmtosigma * fwhm; - const int nqpts = pdfutils_qmaxSteps(this); - const int smscale = summationscale * bnds.multiplicity(); - const double& sineprec = this->getDebyePrecision(); - for (int kq = pdfutils_qminSteps(this); kq < nqpts; ++kq) - { - const double q = kq * this->getQstep(); - const double dwscale = exp(-0.5 * pow(dwsigma * q, 2)); - const double sinescale = smscale * dwscale * - this->sfSiteAtkQ(bnds.site0(), kq) * - this->sfSiteAtkQ(bnds.site1(), kq) / dist; - if (eps_eq(0.0, sinescale, sineprec)) break; - mvalue[kq] += sinescale * sin(q * dist); - } -} - - -void BaseDebyeSum::stashPartialValue() -{ - mdbsumstash = this->value(); -} - - -void BaseDebyeSum::restorePartialValue() -{ - assert(mdbsumstash.size() == mvalue.size()); - mvalue.swap(mdbsumstash); - mdbsumstash.clear(); -} - - -double BaseDebyeSum::sfSiteAtQ(int siteidx, const double& q) const -{ - return 1.0; + int summationscale) { + const double dist = bnds.distance(); + if (eps_eq(0.0, dist)) return; + // calculate sigma parameter for the Debye-Waller dampign Gaussian + const double fwhm = this->getPeakWidthModel()->calculate(bnds); + const double fwhmtosigma = 1.0 / (2 * sqrt(2 * M_LN2)); + const double dwsigma = fwhmtosigma * fwhm; + const int nqpts = pdfutils_qmaxSteps(this); + const int smscale = summationscale * bnds.multiplicity(); + const double& sineprec = this->getDebyePrecision(); + for (int kq = pdfutils_qminSteps(this); kq < nqpts; ++kq) { + const double q = kq * this->getQstep(); + const double dwscale = exp(-0.5 * pow(dwsigma * q, 2)); + const double sinescale = smscale * dwscale * + this->sfSiteAtkQ(bnds.site0(), kq) * + this->sfSiteAtkQ(bnds.site1(), kq) / dist; + if (eps_eq(0.0, sinescale, sineprec)) break; + mvalue[kq] += sinescale * sin(q * dist); + } +} + +void BaseDebyeSum::stashPartialValue() { mdbsumstash = this->value(); } + +void BaseDebyeSum::restorePartialValue() { + assert(mdbsumstash.size() == mvalue.size()); + mvalue.swap(mdbsumstash); + mdbsumstash.clear(); +} + +double BaseDebyeSum::sfSiteAtQ(int siteidx, const double& q) const { + return 1.0; } // Private Methods ----------------------------------------------------------- -double BaseDebyeSum::sfSiteAtkQ(int siteidx, int kq) const -{ - assert(0 <= siteidx && siteidx < int(mstructure_cache.typeofsite.size())); - int typeidx = mstructure_cache.typeofsite[siteidx]; - assert(typeidx < int(mstructure_cache.sftypeatkq.size())); - const QuantityType& sfarray = mstructure_cache.sftypeatkq[typeidx]; - assert(0 <= kq && kq < int(sfarray.size())); - return sfarray[kq]; -} - - -double BaseDebyeSum::sfAverageAtkQ(int kq) const -{ - assert(kq < int(mstructure_cache.sfaverageatkq.size())); - return mstructure_cache.sfaverageatkq[kq]; -} - - -void BaseDebyeSum::cacheStructureData() -{ - using std::placeholders::_1; - int cntsites = this->countSites(); - const int nqpts = pdfutils_qmaxSteps(this); - QuantityType zeros(nqpts, 0.0); - unordered_map atomtypeidx; - // sftypeatkq - mstructure_cache.typeofsite.clear(); - mstructure_cache.typeofsite.reserve(cntsites); - mstructure_cache.sftypeatkq.clear(); - for (int siteidx = 0; siteidx < cntsites; ++siteidx) - { - const string& smbl = mstructure->siteAtomType(siteidx); - if (!atomtypeidx.count(smbl)) - { - atomtypeidx.insert(make_pair(smbl, int(atomtypeidx.size()))); - } - int tpidx = atomtypeidx[smbl]; - mstructure_cache.typeofsite.push_back(tpidx); - // do nothing if the type has been already cached - if (tpidx < int(mstructure_cache.sftypeatkq.size())) continue; - assert(tpidx == int(mstructure_cache.sftypeatkq.size())); - // here we need to build a new array - mstructure_cache.sftypeatkq.push_back(zeros); - QuantityType& sfarray = mstructure_cache.sftypeatkq.back(); - for (int kq = pdfutils_qminSteps(this); kq < nqpts; ++kq) - { - double q = this->getQstep() * kq; - sfarray[kq] = this->sfSiteAtQ(siteidx, q); - } +double BaseDebyeSum::sfSiteAtkQ(int siteidx, int kq) const { + assert(0 <= siteidx && siteidx < int(mstructure_cache.typeofsite.size())); + int typeidx = mstructure_cache.typeofsite[siteidx]; + assert(typeidx < int(mstructure_cache.sftypeatkq.size())); + const QuantityType& sfarray = mstructure_cache.sftypeatkq[typeidx]; + assert(0 <= kq && kq < int(sfarray.size())); + return sfarray[kq]; +} + +double BaseDebyeSum::sfAverageAtkQ(int kq) const { + assert(kq < int(mstructure_cache.sfaverageatkq.size())); + return mstructure_cache.sfaverageatkq[kq]; +} + +void BaseDebyeSum::cacheStructureData() { + using std::placeholders::_1; + int cntsites = this->countSites(); + const int nqpts = pdfutils_qmaxSteps(this); + QuantityType zeros(nqpts, 0.0); + unordered_map atomtypeidx; + // sftypeatkq + mstructure_cache.typeofsite.clear(); + mstructure_cache.typeofsite.reserve(cntsites); + mstructure_cache.sftypeatkq.clear(); + for (int siteidx = 0; siteidx < cntsites; ++siteidx) { + const string& smbl = mstructure->siteAtomType(siteidx); + if (!atomtypeidx.count(smbl)) { + atomtypeidx.insert(make_pair(smbl, int(atomtypeidx.size()))); } - assert(cntsites == int(mstructure_cache.typeofsite.size())); - assert(atomtypeidx.size() == mstructure_cache.sftypeatkq.size()); - // totaloccupancy - mstructure_cache.totaloccupancy = mstructure->totalOccupancy(); - // sfaverageatkq - QuantityType& sfak = mstructure_cache.sfaverageatkq; - sfak = zeros; - int ntps = mstructure_cache.sftypeatkq.size(); - vector tpmultipl(ntps, 0); - for (int siteidx = 0; siteidx < cntsites; ++siteidx) - { - int tpidx = mstructure_cache.typeofsite[siteidx]; - assert(tpidx < ntps); - tpmultipl[tpidx] += mstructure->siteMultiplicity(siteidx); + int tpidx = atomtypeidx[smbl]; + mstructure_cache.typeofsite.push_back(tpidx); + // do nothing if the type has been already cached + if (tpidx < int(mstructure_cache.sftypeatkq.size())) continue; + assert(tpidx == int(mstructure_cache.sftypeatkq.size())); + // here we need to build a new array + mstructure_cache.sftypeatkq.push_back(zeros); + QuantityType& sfarray = mstructure_cache.sftypeatkq.back(); + for (int kq = pdfutils_qminSteps(this); kq < nqpts; ++kq) { + double q = this->getQstep() * kq; + sfarray[kq] = this->sfSiteAtQ(siteidx, q); } - for (int tpidx = 0; tpidx < ntps; ++tpidx) - { - QuantityType& sfarray = mstructure_cache.sftypeatkq[tpidx]; - const int multipl = tpmultipl[tpidx]; - for (int kq = pdfutils_qminSteps(this); kq < nqpts; ++kq) - { - sfak[kq] += sfarray[kq] * multipl; - } + } + assert(cntsites == int(mstructure_cache.typeofsite.size())); + assert(atomtypeidx.size() == mstructure_cache.sftypeatkq.size()); + // totaloccupancy + mstructure_cache.totaloccupancy = mstructure->totalOccupancy(); + // sfaverageatkq + QuantityType& sfak = mstructure_cache.sfaverageatkq; + sfak = zeros; + int ntps = mstructure_cache.sftypeatkq.size(); + vector tpmultipl(ntps, 0); + for (int siteidx = 0; siteidx < cntsites; ++siteidx) { + int tpidx = mstructure_cache.typeofsite[siteidx]; + assert(tpidx < ntps); + tpmultipl[tpidx] += mstructure->siteMultiplicity(siteidx); + } + for (int tpidx = 0; tpidx < ntps; ++tpidx) { + QuantityType& sfarray = mstructure_cache.sftypeatkq[tpidx]; + const int multipl = tpmultipl[tpidx]; + for (int kq = pdfutils_qminSteps(this); kq < nqpts; ++kq) { + sfak[kq] += sfarray[kq] * multipl; } - const double& totocc = mstructure_cache.totaloccupancy; - const double tosc = eps_gt(totocc, 0.0) ? (1.0 / totocc) : 1.0; - transform(sfak.begin(), sfak.end(), sfak.begin(), + } + const double& totocc = mstructure_cache.totaloccupancy; + const double tosc = eps_gt(totocc, 0.0) ? (1.0 / totocc) : 1.0; + transform(sfak.begin(), sfak.end(), sfak.begin(), bind(multiplies(), tosc, _1)); } -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/BaseDebyeSum.hpp b/src/diffpy/srreal/BaseDebyeSum.hpp index 5eaea6f5..e1ed7248 100644 --- a/src/diffpy/srreal/BaseDebyeSum.hpp +++ b/src/diffpy/srreal/BaseDebyeSum.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy 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. -* -****************************************************************************** -* -* class BaseDebyeSum -- base class for concrete Debye sum calculators -* -*****************************************************************************/ + * + * libdiffpy 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. + * + ****************************************************************************** + * + * class BaseDebyeSum -- base class for concrete Debye sum calculators + * + *****************************************************************************/ #ifndef BASEDEBYESUM_HPP_INCLUDED #define BASEDEBYESUM_HPP_INCLUDED @@ -23,98 +23,94 @@ #include #include +#include + namespace diffpy { namespace srreal { -class BaseDebyeSum : - public PairQuantity, - public PeakWidthModelOwner -{ - public: - - // constructor - BaseDebyeSum(); - - // PairQuantity overloads - virtual eventticker::EventTicker& ticker() const; - - // results - /// F values on a full Q-grid starting at 0 - QuantityType getF() const; - - // Q-range methods - /// Full Q-grid starting at 0 - QuantityType getQgrid() const; - // Q-range configuration - void setQmin(double); - const double& getQmin() const; - void setQmax(double); - const double& getQmax() const; - void setQstep(double); - const double& getQstep() const; - - // Summation cutoff due to Q-dependent pair scaling or large distance - /// set relative cutoff value for Debye sum contribution - void setDebyePrecision(double); - /// return relative cutoff value for Debye sum contribution - const double& getDebyePrecision() const; - - protected: - - // PairQuantity overloads - virtual void resetValue(); - virtual void addPairContribution(const BaseBondGenerator&, int); - // support for PQEvaluatorOptimized - virtual void stashPartialValue(); - virtual void restorePartialValue(); - - // own methods - virtual double sfSiteAtQ(int, const double& Q) const; - - private: - - // methods - /// cache structure factors data for a quick access during summation - double sfSiteAtkQ(int siteidx, int kq) const; - double sfAverageAtkQ(int kq) const; - void cacheStructureData(); - - // data - // configuration - double mqmin; - double mqmax; - double mqstep; - double mdebyeprecision; - struct { - std::vector typeofsite; - std::vector sftypeatkq; - QuantityType sfaverageatkq; - double totaloccupancy; - } mstructure_cache; - QuantityType mdbsumstash; - - // serialization - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - using boost::serialization::base_object; - ar & base_object(*this); - ar & base_object(*this); - ar & mqmin; - ar & mqmax; - ar & mqstep; - ar & mdebyeprecision; - ar & mstructure_cache.typeofsite; - ar & mstructure_cache.sftypeatkq; - ar & mstructure_cache.sfaverageatkq; - ar & mstructure_cache.totaloccupancy; - } +class DLL_EXPORT BaseDebyeSum : public PairQuantity, + public PeakWidthModelOwner { + public: + // constructor + BaseDebyeSum(); + + // PairQuantity overloads + virtual eventticker::EventTicker& ticker() const; + + // results + /// F values on a full Q-grid starting at 0 + QuantityType getF() const; + + // Q-range methods + /// Full Q-grid starting at 0 + QuantityType getQgrid() const; + // Q-range configuration + void setQmin(double); + const double& getQmin() const; + void setQmax(double); + const double& getQmax() const; + void setQstep(double); + const double& getQstep() const; + + // Summation cutoff due to Q-dependent pair scaling or large distance + /// set relative cutoff value for Debye sum contribution + void setDebyePrecision(double); + /// return relative cutoff value for Debye sum contribution + const double& getDebyePrecision() const; + + protected: + // PairQuantity overloads + virtual void resetValue(); + virtual void addPairContribution(const BaseBondGenerator&, int); + // support for PQEvaluatorOptimized + virtual void stashPartialValue(); + virtual void restorePartialValue(); + + // own methods + virtual double sfSiteAtQ(int, const double& Q) const; + + private: + // methods + /// cache structure factors data for a quick access during summation + double sfSiteAtkQ(int siteidx, int kq) const; + double sfAverageAtkQ(int kq) const; + void cacheStructureData(); + + // data + // configuration + double mqmin; + double mqmax; + double mqstep; + double mdebyeprecision; + struct { + std::vector typeofsite; + std::vector sftypeatkq; + QuantityType sfaverageatkq; + double totaloccupancy; + } mstructure_cache; + QuantityType mdbsumstash; + + // serialization + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + using boost::serialization::base_object; + ar& base_object(*this); + ar& base_object(*this); + ar & mqmin; + ar & mqmax; + ar & mqstep; + ar & mdebyeprecision; + ar & mstructure_cache.typeofsite; + ar & mstructure_cache.sftypeatkq; + ar & mstructure_cache.sfaverageatkq; + ar & mstructure_cache.totaloccupancy; + } }; // class BaseDebyeSum -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/BondCalculator.cpp b/src/diffpy/srreal/BondCalculator.cpp index 21e8435a..94b04740 100644 --- a/src/diffpy/srreal/BondCalculator.cpp +++ b/src/diffpy/srreal/BondCalculator.cpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2011 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. -* -****************************************************************************** -* -* class BondCalculator -- bond distance calculator -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2011 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. + * + ****************************************************************************** + * + * class BondCalculator -- bond distance calculator + * + *****************************************************************************/ #include #include @@ -36,263 +36,214 @@ namespace { const double DEFAULT_BONDCALCULATOR_RMAX = 5.0; -} // namespace +} // namespace class BondOp { - - public: - - static bool compare( - const BondCalculator::BondEntry& be0, - const BondCalculator::BondEntry& be1) - { - if (be0.distance < be1.distance) return true; - if (be0.distance > be1.distance) return false; - if (be0.site0 < be1.site0) return true; - if (be0.site0 > be1.site0) return false; - if (be0.site1 < be1.site1) return true; - if (be0.site1 > be1.site1) return false; - if (be0.direction0 < be1.direction0) return true; - if (be0.direction0 > be1.direction0) return false; - if (be0.direction1 < be1.direction1) return true; - if (be0.direction1 > be1.direction1) return false; - if (be0.direction2 < be1.direction2) return true; - if (be0.direction2 > be1.direction2) return false; - return false; - } - - - static bool reverse_compare( - const BondCalculator::BondEntry& be0, - const BondCalculator::BondEntry& be1) - { - return compare(be1, be0); - } - - - static void bmerge( - BondCalculator::BondDataStorage& dstbonds, - const BondCalculator::BondDataStorage& srcbonds) - { - dstbonds.resize(dstbonds.size() + srcbonds.size()); - merge(dstbonds.rbegin() + srcbonds.size(), dstbonds.rend(), - srcbonds.rbegin(), srcbonds.rend(), - dstbonds.rbegin(), reverse_compare); - } - - - static BondCalculator::BondEntry entryFrom( - const BaseBondGenerator& bnds) - { - BondCalculator::BondEntry rv; - rv.distance = bnds.distance(); - rv.site0 = bnds.site0(); - rv.site1 = bnds.site1(); - rv.direction0 = bnds.r01()[0]; - rv.direction1 = bnds.r01()[1]; - rv.direction2 = bnds.r01()[2]; - return rv; - } - + public: + static bool compare(const BondCalculator::BondEntry& be0, + const BondCalculator::BondEntry& be1) { + if (be0.distance < be1.distance) return true; + if (be0.distance > be1.distance) return false; + if (be0.site0 < be1.site0) return true; + if (be0.site0 > be1.site0) return false; + if (be0.site1 < be1.site1) return true; + if (be0.site1 > be1.site1) return false; + if (be0.direction0 < be1.direction0) return true; + if (be0.direction0 > be1.direction0) return false; + if (be0.direction1 < be1.direction1) return true; + if (be0.direction1 > be1.direction1) return false; + if (be0.direction2 < be1.direction2) return true; + if (be0.direction2 > be1.direction2) return false; + return false; + } + + static bool reverse_compare(const BondCalculator::BondEntry& be0, + const BondCalculator::BondEntry& be1) { + return compare(be1, be0); + } + + static void bmerge(BondCalculator::BondDataStorage& dstbonds, + const BondCalculator::BondDataStorage& srcbonds) { + dstbonds.resize(dstbonds.size() + srcbonds.size()); + merge(dstbonds.rbegin() + srcbonds.size(), dstbonds.rend(), + srcbonds.rbegin(), srcbonds.rend(), dstbonds.rbegin(), + reverse_compare); + } + + static BondCalculator::BondEntry entryFrom(const BaseBondGenerator& bnds) { + BondCalculator::BondEntry rv; + rv.distance = bnds.distance(); + rv.site0 = bnds.site0(); + rv.site1 = bnds.site1(); + rv.direction0 = bnds.r01()[0]; + rv.direction1 = bnds.r01()[1]; + rv.direction2 = bnds.r01()[2]; + return rv; + } }; // class BondOp // Constructor --------------------------------------------------------------- -BondCalculator::BondCalculator() -{ - this->setRmax(DEFAULT_BONDCALCULATOR_RMAX); - this->setEvaluatorType(OPTIMIZED); - mevaluator->setFlag(USEFULLSUM, true); - mevaluator->setFlag(FIXEDSITEINDEX, true); +BondCalculator::BondCalculator() { + this->setRmax(DEFAULT_BONDCALCULATOR_RMAX); + this->setEvaluatorType(OPTIMIZED); + mevaluator->setFlag(USEFULLSUM, true); + mevaluator->setFlag(FIXEDSITEINDEX, true); } // Public Methods ------------------------------------------------------------ -QuantityType BondCalculator::distances() const -{ - QuantityType rv; - rv.reserve(this->count()); - BondDataStorage::const_iterator bi = mbonds.begin(); - for (; bi != mbonds.end(); bi++) rv.push_back(bi->distance); - return rv; +QuantityType BondCalculator::distances() const { + QuantityType rv; + rv.reserve(this->count()); + BondDataStorage::const_iterator bi = mbonds.begin(); + for (; bi != mbonds.end(); bi++) rv.push_back(bi->distance); + return rv; } - -vector BondCalculator::directions() const -{ - vector rv; - rv.reserve(this->count()); - BondDataStorage::const_iterator bi = mbonds.begin(); - for (; bi != mbonds.end(); ++bi) - { - R3::Vector dir(bi->direction0, bi->direction1, bi->direction2); - rv.push_back(dir); - } - return rv; +vector BondCalculator::directions() const { + vector rv; + rv.reserve(this->count()); + BondDataStorage::const_iterator bi = mbonds.begin(); + for (; bi != mbonds.end(); ++bi) { + R3::Vector dir(bi->direction0, bi->direction1, bi->direction2); + rv.push_back(dir); + } + return rv; } - -SiteIndices BondCalculator::sites0() const -{ - SiteIndices rv; - rv.reserve(this->count()); - BondDataStorage::const_iterator bi = mbonds.begin(); - for (; bi != mbonds.end(); ++bi) rv.push_back(bi->site0); - return rv; +SiteIndices BondCalculator::sites0() const { + SiteIndices rv; + rv.reserve(this->count()); + BondDataStorage::const_iterator bi = mbonds.begin(); + for (; bi != mbonds.end(); ++bi) rv.push_back(bi->site0); + return rv; } - -SiteIndices BondCalculator::sites1() const -{ - SiteIndices rv; - rv.reserve(this->count()); - BondDataStorage::const_iterator bi = mbonds.begin(); - for (; bi != mbonds.end(); ++bi) rv.push_back(bi->site1); - return rv; +SiteIndices BondCalculator::sites1() const { + SiteIndices rv; + rv.reserve(this->count()); + BondDataStorage::const_iterator bi = mbonds.begin(); + for (; bi != mbonds.end(); ++bi) rv.push_back(bi->site1); + return rv; } - -vector BondCalculator::types0() const -{ - return siteIndicesToTypes(mstructure, this->sites0()); +vector BondCalculator::types0() const { + return siteIndicesToTypes(mstructure, this->sites0()); } - -vector BondCalculator::types1() const -{ - return siteIndicesToTypes(mstructure, this->sites1()); +vector BondCalculator::types1() const { + return siteIndicesToTypes(mstructure, this->sites1()); } - -void BondCalculator::filterCone(R3::Vector coneaxis, double degrees) -{ - using namespace diffpy::validators; - double nmconeaxis = R3::norm(coneaxis); - ensureEpsilonPositive("magnitude of cone vector", nmconeaxis); - coneaxis /= nmconeaxis; - mfilter_directions.push_back(coneaxis); - mfilter_degrees.push_back(degrees); - mticker.click(); +void BondCalculator::filterCone(R3::Vector coneaxis, double degrees) { + using namespace diffpy::validators; + double nmconeaxis = R3::norm(coneaxis); + ensureEpsilonPositive("magnitude of cone vector", nmconeaxis); + coneaxis /= nmconeaxis; + mfilter_directions.push_back(coneaxis); + mfilter_degrees.push_back(degrees); + mticker.click(); } - -void BondCalculator::filterOff() -{ - if (!mfilter_directions.empty()) mticker.click(); - mfilter_directions.clear(); - mfilter_degrees.clear(); +void BondCalculator::filterOff() { + if (!mfilter_directions.empty()) mticker.click(); + mfilter_directions.clear(); + mfilter_degrees.clear(); } // PairQuantity overloads -string BondCalculator::getParallelData() const -{ - ostringstream storage(ios::binary); - diffpy::serialization::oarchive oa(storage, ios::binary); - oa << mpopbonds << maddbonds; - return storage.str(); +string BondCalculator::getParallelData() const { + ostringstream storage(ios::binary); + diffpy::serialization::oarchive oa(storage, ios::binary); + oa << mpopbonds << maddbonds; + return storage.str(); } // Protected Methods --------------------------------------------------------- -void BondCalculator::resetValue() -{ - mvalue.clear(); - mbonds.clear(); - maddbonds.clear(); - mpopbonds.clear(); - this->PairQuantity::resetValue(); -} - - -void BondCalculator::addPairContribution( - const BaseBondGenerator& bnds, - int summationscale) -{ - assert(summationscale == +1 || summationscale == -1); - static R3::Vector ru01; - const R3::Vector& r01 = bnds.r01(); - ru01 = r01 / bnds.distance(); - if (!(this->checkConeFilters(ru01))) return; - BondDataStorage& bes = (summationscale > 0) ? maddbonds : mpopbonds; - bes.push_back(BondOp::entryFrom(bnds)); -} - - -void BondCalculator::executeParallelMerge(const std::string& pdata) -{ - istringstream storage(pdata, ios::binary); - diffpy::serialization::iarchive ia(storage, ios::binary); - BondDataStorage bpop, badd; - ia >> bpop >> badd; - BondOp::bmerge(mpopbonds, bpop); - BondOp::bmerge(maddbonds, badd); -} - - -void BondCalculator::finishValue() -{ - // filter-out entries marked for removal - assert(mpopbonds.size() <= mbonds.size()); - sort(mpopbonds.begin(), mpopbonds.end(), BondOp::compare); - sort(maddbonds.begin(), maddbonds.end(), BondOp::compare); - if (mevaluator->isParallel()) return; - BondDataStorage::iterator last; - last = set_difference(mbonds.begin(), mbonds.end(), - mpopbonds.begin(), mpopbonds.end(), - mbonds.begin(), BondOp::compare); - mbonds.erase(last, mbonds.end()); - if (mbonds.empty()) mbonds.swap(maddbonds); - else BondOp::bmerge(mbonds, maddbonds); - mvalue = this->distances(); - mpopbonds.clear(); - maddbonds.clear(); -} - - -void BondCalculator::stashPartialValue() -{ - mstashedvalue.bonds.swap(mbonds); - mstashedvalue.popbonds.swap(mpopbonds); - // No need to stash maddbonds as they are evaluated after partial value. -} - - -void BondCalculator::restorePartialValue() -{ - mbonds.swap(mstashedvalue.bonds); - mpopbonds.swap(mstashedvalue.popbonds); - mstashedvalue.bonds.clear(); - mstashedvalue.popbonds.clear(); +void BondCalculator::resetValue() { + mvalue.clear(); + mbonds.clear(); + maddbonds.clear(); + mpopbonds.clear(); + this->PairQuantity::resetValue(); +} + +void BondCalculator::addPairContribution(const BaseBondGenerator& bnds, + int summationscale) { + assert(summationscale == +1 || summationscale == -1); + static R3::Vector ru01; + const R3::Vector& r01 = bnds.r01(); + ru01 = r01 / bnds.distance(); + if (!(this->checkConeFilters(ru01))) return; + BondDataStorage& bes = (summationscale > 0) ? maddbonds : mpopbonds; + bes.push_back(BondOp::entryFrom(bnds)); +} + +void BondCalculator::executeParallelMerge(const std::string& pdata) { + istringstream storage(pdata, ios::binary); + diffpy::serialization::iarchive ia(storage, ios::binary); + BondDataStorage bpop, badd; + ia >> bpop >> badd; + BondOp::bmerge(mpopbonds, bpop); + BondOp::bmerge(maddbonds, badd); +} + +void BondCalculator::finishValue() { + // filter-out entries marked for removal + assert(mpopbonds.size() <= mbonds.size()); + sort(mpopbonds.begin(), mpopbonds.end(), BondOp::compare); + sort(maddbonds.begin(), maddbonds.end(), BondOp::compare); + if (mevaluator->isParallel()) return; + BondDataStorage::iterator last; + last = set_difference(mbonds.begin(), mbonds.end(), mpopbonds.begin(), + mpopbonds.end(), mbonds.begin(), BondOp::compare); + mbonds.erase(last, mbonds.end()); + if (mbonds.empty()) + mbonds.swap(maddbonds); + else + BondOp::bmerge(mbonds, maddbonds); + mvalue = this->distances(); + mpopbonds.clear(); + maddbonds.clear(); +} + +void BondCalculator::stashPartialValue() { + mstashedvalue.bonds.swap(mbonds); + mstashedvalue.popbonds.swap(mpopbonds); + // No need to stash maddbonds as they are evaluated after partial value. +} + +void BondCalculator::restorePartialValue() { + mbonds.swap(mstashedvalue.bonds); + mpopbonds.swap(mstashedvalue.popbonds); + mstashedvalue.bonds.clear(); + mstashedvalue.popbonds.clear(); } // Private Methods ----------------------------------------------------------- -int BondCalculator::count() const -{ - return mbonds.size(); -} - +int BondCalculator::count() const { return mbonds.size(); } -bool BondCalculator::checkConeFilters(const R3::Vector& ru01) const -{ - using diffpy::mathutils::eps_eq; - if (mfilter_directions.empty()) return true; - assert(eps_eq(1.0, R3::norm(ru01))); - vector::const_iterator coneax = mfilter_directions.begin(); - vector::const_iterator deg = mfilter_degrees.begin(); - for (; coneax != mfilter_directions.end(); ++coneax, ++deg) - { - if (180.0 <= *deg) return true; - double angledegrees = 180.0 / M_PI * acos(R3::dot(ru01, *coneax)); - if (angledegrees <= *deg) return true; - } - return false; +bool BondCalculator::checkConeFilters(const R3::Vector& ru01) const { + using diffpy::mathutils::eps_eq; + if (mfilter_directions.empty()) return true; + assert(eps_eq(1.0, R3::norm(ru01))); + vector::const_iterator coneax = mfilter_directions.begin(); + vector::const_iterator deg = mfilter_degrees.begin(); + for (; coneax != mfilter_directions.end(); ++coneax, ++deg) { + if (180.0 <= *deg) return true; + double angledegrees = 180.0 / M_PI * acos(R3::dot(ru01, *coneax)); + if (angledegrees <= *deg) return true; + } + return false; } -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/BondCalculator.hpp b/src/diffpy/srreal/BondCalculator.hpp index 49c6876f..f79b1ab4 100644 --- a/src/diffpy/srreal/BondCalculator.hpp +++ b/src/diffpy/srreal/BondCalculator.hpp @@ -1,132 +1,122 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2011 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. -* -****************************************************************************** -* -* class BondCalculator -- bond distance calculator -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2011 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. + * + ****************************************************************************** + * + * class BondCalculator -- bond distance calculator + * + *****************************************************************************/ #ifndef BONDCALCULATOR_HPP_INCLUDED #define BONDCALCULATOR_HPP_INCLUDED #include +#include + namespace diffpy { namespace srreal { -class BondCalculator : public PairQuantity -{ - public: - - // constructor - BondCalculator(); - - // methods - template QuantityType operator()(const T&); - QuantityType distances() const; - std::vector directions() const; - SiteIndices sites0() const; - SiteIndices sites1() const; - std::vector types0() const; - std::vector types1() const; - void filterCone(R3::Vector coneaxis, double degrees); - void filterOff(); - - // PairQuantity overloads - virtual std::string getParallelData() const; - - protected: - - // PairQuantity overloads - virtual void resetValue(); - virtual void addPairContribution(const BaseBondGenerator&, int); - virtual void executeParallelMerge(const std::string& pdata); - virtual void finishValue(); - - // support for PQEvaluatorOptimized - virtual void stashPartialValue(); - virtual void restorePartialValue(); - - friend class BondOp; - class BondEntry { - - public: - - double distance; - int site0; - int site1; - double direction0; - double direction1; - double direction2; - - private: - - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - ar & distance & site0 & site1; - ar & direction0 & direction1 & direction2; - } - - }; - - typedef std::vector BondDataStorage; - - private: - - // serialization - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - using boost::serialization::base_object; - ar & base_object(*this); - ar & mbonds; - ar & mfilter_directions; - ar & mfilter_degrees; - } - - // methods - int count() const; - bool checkConeFilters(const R3::Vector& ru01) const; - - // data - std::vector mfilter_directions; - std::vector mfilter_degrees; - BondDataStorage mbonds; - BondDataStorage mpopbonds; - BondDataStorage maddbonds; - // support for PQEvaluatorOptimized - struct { - BondDataStorage bonds; - BondDataStorage popbonds; - } mstashedvalue; - +class DLL_EXPORT BondCalculator : public PairQuantity { + public: + // constructor + BondCalculator(); + + // methods + template + QuantityType operator()(const T&); + QuantityType distances() const; + std::vector directions() const; + SiteIndices sites0() const; + SiteIndices sites1() const; + std::vector types0() const; + std::vector types1() const; + void filterCone(R3::Vector coneaxis, double degrees); + void filterOff(); + + // PairQuantity overloads + virtual std::string getParallelData() const; + + protected: + // PairQuantity overloads + virtual void resetValue(); + virtual void addPairContribution(const BaseBondGenerator&, int); + virtual void executeParallelMerge(const std::string& pdata); + virtual void finishValue(); + + // support for PQEvaluatorOptimized + virtual void stashPartialValue(); + virtual void restorePartialValue(); + + friend class BondOp; + class BondEntry { + public: + double distance; + int site0; + int site1; + double direction0; + double direction1; + double direction2; + + private: + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + ar & distance & site0 & site1; + ar & direction0 & direction1 & direction2; + } + }; + + typedef std::vector BondDataStorage; + + private: + // serialization + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + using boost::serialization::base_object; + ar& base_object(*this); + ar & mbonds; + ar & mfilter_directions; + ar & mfilter_degrees; + } + + // methods + int count() const; + bool checkConeFilters(const R3::Vector& ru01) const; + + // data + std::vector mfilter_directions; + std::vector mfilter_degrees; + BondDataStorage mbonds; + BondDataStorage mpopbonds; + BondDataStorage maddbonds; + // support for PQEvaluatorOptimized + struct { + BondDataStorage bonds; + BondDataStorage popbonds; + } mstashedvalue; }; // Public Template Methods --------------------------------------------------- template -QuantityType BondCalculator::operator()(const T& stru) -{ - this->eval(stru); - return this->distances(); +QuantityType BondCalculator::operator()(const T& stru) { + this->eval(stru); + return this->distances(); } - -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/ConstantPeakWidth.cpp b/src/diffpy/srreal/ConstantPeakWidth.cpp index 32b8bc78..4bf50b3f 100644 --- a/src/diffpy/srreal/ConstantPeakWidth.cpp +++ b/src/diffpy/srreal/ConstantPeakWidth.cpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class ConstantPeakWidth -- constant peak width model for testing -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class ConstantPeakWidth -- constant peak width model for testing + * + *****************************************************************************/ #include #include @@ -31,102 +31,81 @@ namespace { using diffpy::mathutils::GAUSS_SIGMA_TO_FWHM; const double UtoB = 8 * M_PI * M_PI; - -double getuisowidth(const ConstantPeakWidth* ppwm) -{ - const double rmsd = ppwm->getWidth() / GAUSS_SIGMA_TO_FWHM; - const int pm = (rmsd >= 0) ? +1 : -1; - return pm * 0.5 * rmsd * rmsd; +double getuisowidth(const ConstantPeakWidth* ppwm) { + const double rmsd = ppwm->getWidth() / GAUSS_SIGMA_TO_FWHM; + const int pm = (rmsd >= 0) ? +1 : -1; + return pm * 0.5 * rmsd * rmsd; } -void setuisowidth(ConstantPeakWidth* ppwm, const double& uiso) -{ - const int pm = (uiso >= 0) ? +1 : -1; - const double uisoplus = pm * uiso; - const double fwhm = pm * GAUSS_SIGMA_TO_FWHM * sqrt(2.0 * uisoplus); - ppwm->setWidth(fwhm); +void setuisowidth(ConstantPeakWidth* ppwm, const double& uiso) { + const int pm = (uiso >= 0) ? +1 : -1; + const double uisoplus = pm * uiso; + const double fwhm = pm * GAUSS_SIGMA_TO_FWHM * sqrt(2.0 * uisoplus); + ppwm->setWidth(fwhm); } - -double getbisowidth(const ConstantPeakWidth* ppwm) -{ - return UtoB * getuisowidth(ppwm); +double getbisowidth(const ConstantPeakWidth* ppwm) { + return UtoB * getuisowidth(ppwm); } -void setbisowidth(ConstantPeakWidth* ppwm, const double& biso) -{ - setuisowidth(ppwm, biso / UtoB); +void setbisowidth(ConstantPeakWidth* ppwm, const double& biso) { + setuisowidth(ppwm, biso / UtoB); } -} // namespace +} // namespace // Constructors -------------------------------------------------------------- -ConstantPeakWidth::ConstantPeakWidth() : mwidth(0.0) -{ - this->registerDoubleAttribute("width", this, - &ConstantPeakWidth::getWidth, &ConstantPeakWidth::setWidth); - this->registerDoubleAttribute("bisowidth", this, - &getbisowidth, &setbisowidth); - this->registerDoubleAttribute("uisowidth", this, - &getuisowidth, &setuisowidth); +ConstantPeakWidth::ConstantPeakWidth() : mwidth(0.0) { + this->registerDoubleAttribute("width", this, &ConstantPeakWidth::getWidth, + &ConstantPeakWidth::setWidth); + this->registerDoubleAttribute("bisowidth", this, &getbisowidth, + &setbisowidth); + this->registerDoubleAttribute("uisowidth", this, &getuisowidth, + &setuisowidth); } - -PeakWidthModelPtr ConstantPeakWidth::create() const -{ - PeakWidthModelPtr rv(new ConstantPeakWidth()); - return rv; +PeakWidthModelPtr ConstantPeakWidth::create() const { + PeakWidthModelPtr rv(new ConstantPeakWidth()); + return rv; } - -PeakWidthModelPtr ConstantPeakWidth::clone() const -{ - PeakWidthModelPtr rv(new ConstantPeakWidth(*this)); - return rv; +PeakWidthModelPtr ConstantPeakWidth::clone() const { + PeakWidthModelPtr rv(new ConstantPeakWidth(*this)); + return rv; } // Public Methods ------------------------------------------------------------ -const string& ConstantPeakWidth::type() const -{ - static const string rv = "constant"; - return rv; +const string& ConstantPeakWidth::type() const { + static const string rv = "constant"; + return rv; } - -double ConstantPeakWidth::calculate(const BaseBondGenerator& bnds) const -{ - return this->getWidth(); +double ConstantPeakWidth::calculate(const BaseBondGenerator& bnds) const { + return this->getWidth(); } - -double ConstantPeakWidth::maxWidth( - StructureAdapterPtr stru, double rmin, double rmax) const -{ - return this->getWidth(); +double ConstantPeakWidth::maxWidth(StructureAdapterPtr stru, double rmin, + double rmax) const { + return this->getWidth(); } // data access -const double& ConstantPeakWidth::getWidth() const -{ - return mwidth; -} - +const double& ConstantPeakWidth::getWidth() const { return mwidth; } -void ConstantPeakWidth::setWidth(double width) -{ - if (mwidth != width) mticker.click(); - mwidth = width; +void ConstantPeakWidth::setWidth(double width) { + if (mwidth != width) mticker.click(); + mwidth = width; } // Registration -------------------------------------------------------------- bool reg_ConstantPeakWidth = ConstantPeakWidth().registerThisType(); -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/ConstantPeakWidth.hpp b/src/diffpy/srreal/ConstantPeakWidth.hpp index 8c0f552b..7ba271b3 100644 --- a/src/diffpy/srreal/ConstantPeakWidth.hpp +++ b/src/diffpy/srreal/ConstantPeakWidth.hpp @@ -1,69 +1,64 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class ConstantPeakWidth -- constant peak width -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class ConstantPeakWidth -- constant peak width + * + *****************************************************************************/ #ifndef CONSTANTPEAKWIDTH_HPP_INCLUDED #define CONSTANTPEAKWIDTH_HPP_INCLUDED #include +#include + namespace diffpy { namespace srreal { - -class ConstantPeakWidth : public PeakWidthModel -{ - public: - - // constructors - ConstantPeakWidth(); - virtual PeakWidthModelPtr create() const; - virtual PeakWidthModelPtr clone() const; - - // methods - virtual const std::string& type() const; - virtual double calculate(const BaseBondGenerator&) const; - virtual double maxWidth(StructureAdapterPtr, - double rmin, double rmax) const; - - // data access - const double& getWidth() const; - void setWidth(double); - - private: - - // data - double mwidth; - - // serialization - friend class boost::serialization::access; - - template - void serialize(Archive& ar, const unsigned int version) - { - using boost::serialization::base_object; - ar & base_object(*this); - ar & mwidth; - } - +class DLL_EXPORT ConstantPeakWidth : public PeakWidthModel { + public: + // constructors + ConstantPeakWidth(); + virtual PeakWidthModelPtr create() const; + virtual PeakWidthModelPtr clone() const; + + // methods + virtual const std::string& type() const; + virtual double calculate(const BaseBondGenerator&) const; + virtual double maxWidth(StructureAdapterPtr, double rmin, double rmax) const; + + // data access + const double& getWidth() const; + void setWidth(double); + + private: + // data + double mwidth; + + // serialization + friend class boost::serialization::access; + + template + void serialize(Archive& ar, const unsigned int version) { + using boost::serialization::base_object; + ar& base_object(*this); + ar & mwidth; + } }; -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/ConstantRadiiTable.cpp b/src/diffpy/srreal/ConstantRadiiTable.cpp index 81014d8b..4f1a8df6 100644 --- a/src/diffpy/srreal/ConstantRadiiTable.cpp +++ b/src/diffpy/srreal/ConstantRadiiTable.cpp @@ -1,21 +1,21 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2011 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. -* -****************************************************************************** -* -* class ConstantRadiiTable -- this AtomRadiiTable returns same value -* for all elements unless redefined by the setCustom method. -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2011 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. + * + ****************************************************************************** + * + * class ConstantRadiiTable -- this AtomRadiiTable returns same value + * for all elements unless redefined by the setCustom method. + * + *****************************************************************************/ #include #include @@ -34,56 +34,41 @@ using namespace std; // Constructors -------------------------------------------------------------- -ConstantRadiiTable::ConstantRadiiTable() : mdefaultradius(0.0) -{ } +ConstantRadiiTable::ConstantRadiiTable() : mdefaultradius(0.0) {} // Public Methods ------------------------------------------------------------ // HasClassRegistry methods -AtomRadiiTablePtr ConstantRadiiTable::create() const -{ - return boost::make_shared(); +AtomRadiiTablePtr ConstantRadiiTable::create() const { + return boost::make_shared(); } - -AtomRadiiTablePtr ConstantRadiiTable::clone() const -{ - return boost::make_shared(*this); +AtomRadiiTablePtr ConstantRadiiTable::clone() const { + return boost::make_shared(*this); } - -const string& ConstantRadiiTable::type() const -{ - static string rv = "constant"; - return rv; +const string& ConstantRadiiTable::type() const { + static string rv = "constant"; + return rv; } // own methods -double ConstantRadiiTable::standardLookup(const string& smbl) const -{ - return mdefaultradius; -} - - -void ConstantRadiiTable::setDefault(double value) -{ - mdefaultradius = value; +double ConstantRadiiTable::standardLookup(const string& smbl) const { + return mdefaultradius; } +void ConstantRadiiTable::setDefault(double value) { mdefaultradius = value; } -double ConstantRadiiTable::getDefault() const -{ - return mdefaultradius; -} +double ConstantRadiiTable::getDefault() const { return mdefaultradius; } // Registration -------------------------------------------------------------- bool reg_ConstantRadiiTable = ConstantRadiiTable().registerThisType(); -} // srreal -} // diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/ConstantRadiiTable.hpp b/src/diffpy/srreal/ConstantRadiiTable.hpp index 5a047c75..11dd3ca5 100644 --- a/src/diffpy/srreal/ConstantRadiiTable.hpp +++ b/src/diffpy/srreal/ConstantRadiiTable.hpp @@ -1,65 +1,62 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2011 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. -* -****************************************************************************** -* -* class ConstantRadiiTable -- concrete AtomRadiiTable for a uniform radius -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2011 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. + * + ****************************************************************************** + * + * class ConstantRadiiTable -- concrete AtomRadiiTable for a uniform radius + * + *****************************************************************************/ #ifndef CONSTANTRADIITABLE_HPP_INCLUDED #define CONSTANTRADIITABLE_HPP_INCLUDED #include +#include + namespace diffpy { namespace srreal { -class ConstantRadiiTable : public AtomRadiiTable -{ - public: - - // constructor - ConstantRadiiTable(); - - // methods - HasClassRegistry - SharedPtr create() const; - SharedPtr clone() const; - const std::string& type() const; - // method overloads - double standardLookup(const std::string& smbl) const; - // methods specific for this class - void setDefault(double); - double getDefault() const; - - private: +class DLL_EXPORT ConstantRadiiTable : public AtomRadiiTable { + public: + // constructor + ConstantRadiiTable(); - // data - double mdefaultradius; + // methods - HasClassRegistry + SharedPtr create() const; + SharedPtr clone() const; + const std::string& type() const; + // method overloads + double standardLookup(const std::string& smbl) const; + // methods specific for this class + void setDefault(double); + double getDefault() const; - // serialization - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - using boost::serialization::base_object; - ar & base_object(*this); - ar & mdefaultradius; - } + private: + // data + double mdefaultradius; + // serialization + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + using boost::serialization::base_object; + ar& base_object(*this); + ar & mdefaultradius; + } }; -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/CroppedGaussianProfile.cpp b/src/diffpy/srreal/CroppedGaussianProfile.cpp index aabdba0e..2650980e 100644 --- a/src/diffpy/srreal/CroppedGaussianProfile.cpp +++ b/src/diffpy/srreal/CroppedGaussianProfile.cpp @@ -1,22 +1,22 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class CroppedGaussianProfile -- Gaussian profile cropped to zero beyond -* xboundhi and scaled so that its integrated area equals 1. -* Registered as "croppedgaussian". -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class CroppedGaussianProfile -- Gaussian profile cropped to zero beyond + * xboundhi and scaled so that its integrated area equals 1. + * Registered as "croppedgaussian". + * + *****************************************************************************/ #include @@ -32,63 +32,53 @@ namespace srreal { // Constructors -------------------------------------------------------------- -CroppedGaussianProfile::CroppedGaussianProfile() : mscale(0.0) -{ - // refresh mscale - this->setPrecision(this->getPrecision()); +CroppedGaussianProfile::CroppedGaussianProfile() : mscale(0.0) { + // refresh mscale + this->setPrecision(this->getPrecision()); } - -PeakProfilePtr CroppedGaussianProfile::create() const -{ - PeakProfilePtr rv(new CroppedGaussianProfile()); - return rv; +PeakProfilePtr CroppedGaussianProfile::create() const { + PeakProfilePtr rv(new CroppedGaussianProfile()); + return rv; } - -PeakProfilePtr CroppedGaussianProfile::clone() const -{ - PeakProfilePtr rv(new CroppedGaussianProfile(*this)); - return rv; +PeakProfilePtr CroppedGaussianProfile::clone() const { + PeakProfilePtr rv(new CroppedGaussianProfile(*this)); + return rv; } // Public Methods ------------------------------------------------------------ -const string& CroppedGaussianProfile::type() const -{ - static string rv = "croppedgaussian"; - return rv; +const string& CroppedGaussianProfile::type() const { + static string rv = "croppedgaussian"; + return rv; } - -double CroppedGaussianProfile::operator()(double x, double fwhm) const -{ - double xrel = x / fwhm; - double rv = (fabs(xrel) >= mhalfboundrel) ? 0.0 : - 2 * sqrt(M_LN2 / M_PI) / fwhm * - mscale * exp(-4 * M_LN2 * xrel * xrel); - return rv; +double CroppedGaussianProfile::operator()(double x, double fwhm) const { + double xrel = x / fwhm; + double rv = + (fabs(xrel) >= mhalfboundrel) + ? 0.0 + : 2 * sqrt(M_LN2 / M_PI) / fwhm * mscale * exp(-4 * M_LN2 * xrel * xrel); + return rv; } - -void CroppedGaussianProfile::setPrecision(double eps) -{ - this->GaussianProfile::setPrecision(eps); - double eps1 = this->getPrecision(); - mscale = 1.0; - if (eps1 < 1) - { - double area = gsl_sf_erf(sqrt(-log(eps1))); - mscale = 1.0 / area; - } +void CroppedGaussianProfile::setPrecision(double eps) { + this->GaussianProfile::setPrecision(eps); + double eps1 = this->getPrecision(); + mscale = 1.0; + if (eps1 < 1) { + double area = gsl_sf_erf(sqrt(-log(eps1))); + mscale = 1.0 / area; + } } // Registration -------------------------------------------------------------- bool reg_CroppedGaussianProfile = CroppedGaussianProfile().registerThisType(); -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/CroppedGaussianProfile.hpp b/src/diffpy/srreal/CroppedGaussianProfile.hpp index ed1573ea..f056e52a 100644 --- a/src/diffpy/srreal/CroppedGaussianProfile.hpp +++ b/src/diffpy/srreal/CroppedGaussianProfile.hpp @@ -1,65 +1,62 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class CroppedGaussianProfile -- Gaussian profile cropped to zero beyond -* xboundhi and scaled so that its integrated area equals 1. -* Registered as "croppedgaussian". -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class CroppedGaussianProfile -- Gaussian profile cropped to zero beyond + * xboundhi and scaled so that its integrated area equals 1. + * Registered as "croppedgaussian". + * + *****************************************************************************/ #ifndef CROPPEDGAUSSIANPROFILE_HPP_INCLUDED #define CROPPEDGAUSSIANPROFILE_HPP_INCLUDED #include +#include + namespace diffpy { namespace srreal { -class CroppedGaussianProfile : public GaussianProfile -{ - public: - - // constructors - CroppedGaussianProfile(); - PeakProfilePtr create() const; - PeakProfilePtr clone() const; - - // methods - const std::string& type() const; - double operator()(double x, double fwhm) const; - void setPrecision(double eps); - - private: +class DLL_EXPORT CroppedGaussianProfile : public GaussianProfile { + public: + // constructors + CroppedGaussianProfile(); + PeakProfilePtr create() const; + PeakProfilePtr clone() const; - // data - double mscale; + // methods + const std::string& type() const; + double operator()(double x, double fwhm) const; + void setPrecision(double eps); - // serialization - friend class boost::serialization::access; + private: + // data + double mscale; - template - void serialize(Archive& ar, const unsigned int version) - { - using boost::serialization::base_object; - ar & base_object(*this); - ar & mscale; - } + // serialization + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + using boost::serialization::base_object; + ar& base_object(*this); + ar & mscale; + } }; -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/CrystalStructureAdapter.cpp b/src/diffpy/srreal/CrystalStructureAdapter.cpp index 9db5f0d7..8f9d8a3c 100644 --- a/src/diffpy/srreal/CrystalStructureAdapter.cpp +++ b/src/diffpy/srreal/CrystalStructureAdapter.cpp @@ -1,24 +1,24 @@ /***************************************************************************** -* -* libdiffpy Complex Modeling Initiative -* (c) 2013 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. -* -****************************************************************************** -* -* class CrystalStructureAdapter -- universal adapter for crystal structure -* composed of asymmetric unit cell and list of symmetry operations in -* the space group -* -* class CrystalStructureBondGenerator -- bond generator -* -*****************************************************************************/ + * + * libdiffpy Complex Modeling Initiative + * (c) 2013 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. + * + ****************************************************************************** + * + * class CrystalStructureAdapter -- universal adapter for crystal structure + * composed of asymmetric unit cell and list of symmetry operations in + * the space group + * + * class CrystalStructureBondGenerator -- bond generator + * + *****************************************************************************/ #include @@ -43,238 +43,195 @@ const double DEFAULT_SYMMETRY_PRECISION = 5e-5; // Constructor --------------------------------------------------------------- -CrystalStructureAdapter::CrystalStructureAdapter() : - PeriodicStructureAdapter(), - msymmetry_precision(DEFAULT_SYMMETRY_PRECISION), - msymmetry_cached(false) -{ } +CrystalStructureAdapter::CrystalStructureAdapter() + : PeriodicStructureAdapter(), + msymmetry_precision(DEFAULT_SYMMETRY_PRECISION), + msymmetry_cached(false) {} // Public Methods ------------------------------------------------------------ -StructureAdapterPtr CrystalStructureAdapter::clone() const -{ - StructureAdapterPtr rv(new CrystalStructureAdapter(*this)); - return rv; +StructureAdapterPtr CrystalStructureAdapter::clone() const { + StructureAdapterPtr rv(new CrystalStructureAdapter(*this)); + return rv; } - -BaseBondGeneratorPtr CrystalStructureAdapter::createBondGenerator() const -{ - this->updateSymmetryPositions(); - BaseBondGeneratorPtr bnds( - new CrystalStructureBondGenerator(shared_from_this())); - return bnds; -} - - -int CrystalStructureAdapter::siteMultiplicity(int idx) const -{ - if (!this->isSymmetryCached()) this->updateSymmetryPositions(); - int rv = msymatoms[idx].size(); - return rv; +BaseBondGeneratorPtr CrystalStructureAdapter::createBondGenerator() const { + this->updateSymmetryPositions(); + BaseBondGeneratorPtr bnds( + new CrystalStructureBondGenerator(shared_from_this())); + return bnds; } - -StructureDifference -CrystalStructureAdapter::diff(StructureAdapterConstPtr other) const -{ - StructureDifference sd = this->StructureAdapter::diff(other); - if (sd.stru0 == sd.stru1) return sd; - typedef boost::shared_ptr CPtr; - CPtr cother = boost::dynamic_pointer_cast(other); - if (!cother) return sd; - // compare symmetry operations in both adapters - assert(cother == sd.stru1); - const bool sameprecision = ( - this->getSymmetryPrecision() == cother->getSymmetryPrecision()); - if (!sameprecision) return sd; - if (msymops != cother->msymops) return sd; - sd = this->PeriodicStructureAdapter::diff(other); - return sd; +int CrystalStructureAdapter::siteMultiplicity(int idx) const { + if (!this->isSymmetryCached()) this->updateSymmetryPositions(); + int rv = msymatoms[idx].size(); + return rv; } - -void CrystalStructureAdapter::setSymmetryPrecision(double eps) -{ - using namespace diffpy::validators; - ensureEpsilonPositive("symmetryprecision", eps); - if (eps != msymmetry_precision) msymmetry_cached = false; - msymmetry_precision = eps; +StructureDifference CrystalStructureAdapter::diff( + StructureAdapterConstPtr other) const { + StructureDifference sd = this->StructureAdapter::diff(other); + if (sd.stru0 == sd.stru1) return sd; + typedef boost::shared_ptr CPtr; + CPtr cother = boost::dynamic_pointer_cast(other); + if (!cother) return sd; + // compare symmetry operations in both adapters + assert(cother == sd.stru1); + const bool sameprecision = + (this->getSymmetryPrecision() == cother->getSymmetryPrecision()); + if (!sameprecision) return sd; + if (msymops != cother->msymops) return sd; + sd = this->PeriodicStructureAdapter::diff(other); + return sd; } - -const double& CrystalStructureAdapter::getSymmetryPrecision() const -{ - return msymmetry_precision; +void CrystalStructureAdapter::setSymmetryPrecision(double eps) { + using namespace diffpy::validators; + ensureEpsilonPositive("symmetryprecision", eps); + if (eps != msymmetry_precision) msymmetry_cached = false; + msymmetry_precision = eps; } - -int CrystalStructureAdapter::countSymOps() const -{ - return msymops.size(); +const double& CrystalStructureAdapter::getSymmetryPrecision() const { + return msymmetry_precision; } +int CrystalStructureAdapter::countSymOps() const { return msymops.size(); } -void CrystalStructureAdapter::clearSymOps() -{ - msymops.clear(); - msymmetry_cached = false; +void CrystalStructureAdapter::clearSymOps() { + msymops.clear(); + msymmetry_cached = false; } - -void CrystalStructureAdapter::addSymOp(const SymOpRotTrans& op) -{ - msymops.push_back(op); - msymmetry_cached = false; +void CrystalStructureAdapter::addSymOp(const SymOpRotTrans& op) { + msymops.push_back(op); + msymmetry_cached = false; } - -void CrystalStructureAdapter::addSymOp(const R3::Matrix& R, const R3::Vector& t) -{ - SymOpRotTrans op = {R, t}; - this->addSymOp(op); - assert(!msymmetry_cached); +void CrystalStructureAdapter::addSymOp(const R3::Matrix& R, + const R3::Vector& t) { + SymOpRotTrans op = {R, t}; + this->addSymOp(op); + assert(!msymmetry_cached); } - -const SymOpRotTrans& CrystalStructureAdapter::getSymOp(int i) const -{ - return msymops[i]; +const SymOpRotTrans& CrystalStructureAdapter::getSymOp(int i) const { + return msymops[i]; } - const CrystalStructureAdapter::AtomVector& -CrystalStructureAdapter::getEquivalentAtoms(int idx) const -{ - assert(0 <= idx && idx < this->countSites()); - if (!this->isSymmetryCached()) this->updateSymmetryPositions(); - return msymatoms[idx]; +CrystalStructureAdapter::getEquivalentAtoms(int idx) const { + assert(0 <= idx && idx < this->countSites()); + if (!this->isSymmetryCached()) this->updateSymmetryPositions(); + return msymatoms[idx]; } - -CrystalStructureAdapter::AtomVector -CrystalStructureAdapter::expandLatticeAtom(const Atom& a0) const -{ - using mathutils::eps_eq; - AtomVector eqsites; - vector eqsumpos; - vector eqduplicity; - eqsumpos.reserve(this->countSymOps()); - eqduplicity.reserve(this->countSymOps()); - const Lattice& L = this->getLattice(); - SymOpVector::const_iterator op = msymops.begin(); - Atom a1 = a0; - for (; op != msymops.end(); ++op) - { - // positions and Uij-s are actually fractional here - a1.xyz_cartn = R3::mxvecproduct(op->R, a0.xyz_cartn); - a1.xyz_cartn += op->t; - // check if a1 is a duplicate of an existing symmetry site - int ieq = this->findEqualPosition(eqsites, a1); - if (ieq < 0) - { - // a1 is a new symmetry site - R3::Matrix utmp = R3::prod(a0.uij_cartn, R3::trans(op->R)); - a1.uij_cartn = R3::prod(op->R, utmp); - eqsites.push_back(a1); - eqsumpos.push_back(R3::zerovector); - eqduplicity.push_back(0); - ieq = eqsites.size() - 1; - } - eqsumpos[ieq] += L.ucvFractional(a1.xyz_cartn); - eqduplicity[ieq] += 1; - } - // assume P1 if symmetry operations were not defined - if (msymops.empty()) - { - assert(eqsites.empty()); - assert(eqsumpos.empty()); - assert(eqduplicity.empty()); - eqsites.push_back(a0); - eqsumpos.push_back(a0.xyz_cartn); - eqduplicity.push_back(1); - } - // calculate mean values from equivalent sites and adjust any roundoffs - assert(eqsites.size() == eqduplicity.size()); - assert(eqsites.size() == eqsumpos.size()); - iterator ai = eqsites.begin(); - vector::const_iterator sii = eqsumpos.begin(); - vector::const_iterator dpi = eqduplicity.begin(); - for (; ai != eqsites.end(); ++ai, ++sii, ++dpi) - { - ai->xyz_cartn = (*sii) / (*dpi); +CrystalStructureAdapter::AtomVector CrystalStructureAdapter::expandLatticeAtom( + const Atom& a0) const { + using mathutils::eps_eq; + AtomVector eqsites; + vector eqsumpos; + vector eqduplicity; + eqsumpos.reserve(this->countSymOps()); + eqduplicity.reserve(this->countSymOps()); + const Lattice& L = this->getLattice(); + SymOpVector::const_iterator op = msymops.begin(); + Atom a1 = a0; + for (; op != msymops.end(); ++op) { + // positions and Uij-s are actually fractional here + a1.xyz_cartn = R3::mxvecproduct(op->R, a0.xyz_cartn); + a1.xyz_cartn += op->t; + // check if a1 is a duplicate of an existing symmetry site + int ieq = this->findEqualPosition(eqsites, a1); + if (ieq < 0) { + // a1 is a new symmetry site + R3::Matrix utmp = R3::prod(a0.uij_cartn, R3::trans(op->R)); + a1.uij_cartn = R3::prod(op->R, utmp); + eqsites.push_back(a1); + eqsumpos.push_back(R3::zerovector); + eqduplicity.push_back(0); + ieq = eqsites.size() - 1; } - return eqsites; + eqsumpos[ieq] += L.ucvFractional(a1.xyz_cartn); + eqduplicity[ieq] += 1; + } + // assume P1 if symmetry operations were not defined + if (msymops.empty()) { + assert(eqsites.empty()); + assert(eqsumpos.empty()); + assert(eqduplicity.empty()); + eqsites.push_back(a0); + eqsumpos.push_back(a0.xyz_cartn); + eqduplicity.push_back(1); + } + // calculate mean values from equivalent sites and adjust any roundoffs + assert(eqsites.size() == eqduplicity.size()); + assert(eqsites.size() == eqsumpos.size()); + iterator ai = eqsites.begin(); + vector::const_iterator sii = eqsumpos.begin(); + vector::const_iterator dpi = eqduplicity.begin(); + for (; ai != eqsites.end(); ++ai, ++sii, ++dpi) { + ai->xyz_cartn = (*sii) / (*dpi); + } + return eqsites; } - -void CrystalStructureAdapter::updateSymmetryPositions() const -{ - // build asymmetric unit in lattice coordinates - AtomVector lcatoms(this->begin(), this->end()); - AtomVector::iterator lcai = lcatoms.begin(); - for (; lcai != lcatoms.end(); ++lcai) this->toFractional(*lcai); - // build symmetry positions for all atoms in the asymmetric unit - msymatoms.resize(this->countSites()); - assert(lcatoms.size() == msymatoms.size()); - lcai = lcatoms.begin(); - std::vector::iterator saii = msymatoms.begin(); - for (; lcai != lcatoms.end(); ++lcai, ++saii) - { - *saii = this->expandLatticeAtom(*lcai); - iterator ai = saii->begin(); - for (; ai != saii->end(); ++ai) this->toCartesian(*ai); - } - msymmetry_cached = true; +void CrystalStructureAdapter::updateSymmetryPositions() const { + // build asymmetric unit in lattice coordinates + AtomVector lcatoms(this->begin(), this->end()); + AtomVector::iterator lcai = lcatoms.begin(); + for (; lcai != lcatoms.end(); ++lcai) this->toFractional(*lcai); + // build symmetry positions for all atoms in the asymmetric unit + msymatoms.resize(this->countSites()); + assert(lcatoms.size() == msymatoms.size()); + lcai = lcatoms.begin(); + std::vector::iterator saii = msymatoms.begin(); + for (; lcai != lcatoms.end(); ++lcai, ++saii) { + *saii = this->expandLatticeAtom(*lcai); + iterator ai = saii->begin(); + for (; ai != saii->end(); ++ai) this->toCartesian(*ai); + } + msymmetry_cached = true; } // Private Methods ----------------------------------------------------------- -int CrystalStructureAdapter::findEqualPosition( - const AtomVector& eqsites, const Atom& a0) const -{ - const double symeps = this->getSymmetryPrecision(); - const Lattice& L = this->getLattice(); - R3::Vector dxyz; - const_iterator ai = eqsites.begin(); - for (; ai != eqsites.end(); ++ai) - { - dxyz = ai->xyz_cartn - a0.xyz_cartn; - dxyz[0] -= round(dxyz[0]); - dxyz[1] -= round(dxyz[1]); - dxyz[2] -= round(dxyz[2]); - if (L.norm(dxyz) <= symeps) return (ai - eqsites.begin()); - } - return -1; +int CrystalStructureAdapter::findEqualPosition(const AtomVector& eqsites, + const Atom& a0) const { + const double symeps = this->getSymmetryPrecision(); + const Lattice& L = this->getLattice(); + R3::Vector dxyz; + const_iterator ai = eqsites.begin(); + for (; ai != eqsites.end(); ++ai) { + dxyz = ai->xyz_cartn - a0.xyz_cartn; + dxyz[0] -= round(dxyz[0]); + dxyz[1] -= round(dxyz[1]); + dxyz[2] -= round(dxyz[2]); + if (L.norm(dxyz) <= symeps) return (ai - eqsites.begin()); + } + return -1; } -bool CrystalStructureAdapter::isSymmetryCached() const -{ - msymmetry_cached = msymmetry_cached && - (int(msymatoms.size()) == this->countSites()); - return msymmetry_cached; +bool CrystalStructureAdapter::isSymmetryCached() const { + msymmetry_cached = + msymmetry_cached && (int(msymatoms.size()) == this->countSites()); + return msymmetry_cached; } // Comparison functions ------------------------------------------------------ -bool operator==( - const CrystalStructureAdapter& stru0, - const CrystalStructureAdapter& stru1) -{ - const PeriodicStructureAdapter& pstru0 = stru0; - const PeriodicStructureAdapter& pstru1 = stru1; - bool rv = (&stru0 == &stru1) || ( - (pstru0 == pstru1) && - (stru0.msymops == stru1.msymops)); - return rv; +bool operator==(const CrystalStructureAdapter& stru0, + const CrystalStructureAdapter& stru1) { + const PeriodicStructureAdapter& pstru0 = stru0; + const PeriodicStructureAdapter& pstru1 = stru1; + bool rv = (&stru0 == &stru1) || + ((pstru0 == pstru1) && (stru0.msymops == stru1.msymops)); + return rv; } - -bool operator!=( - const CrystalStructureAdapter& stru0, - const CrystalStructureAdapter& stru1) -{ - return !(stru0 == stru1); +bool operator!=(const CrystalStructureAdapter& stru0, + const CrystalStructureAdapter& stru1) { + return !(stru0 == stru1); } ////////////////////////////////////////////////////////////////////////////// @@ -284,85 +241,73 @@ bool operator!=( // Constructor --------------------------------------------------------------- CrystalStructureBondGenerator::CrystalStructureBondGenerator( - StructureAdapterConstPtr adpt) : PeriodicStructureBondGenerator(adpt) -{ - mcstructure = dynamic_cast(adpt.get()); - assert(mcstructure); - msymidx = 0; - mpuc1 = &(R3::zeromatrix()); + StructureAdapterConstPtr adpt) + : PeriodicStructureBondGenerator(adpt) { + mcstructure = dynamic_cast(adpt.get()); + assert(mcstructure); + msymidx = 0; + mpuc1 = &(R3::zeromatrix()); } // Public Methods ------------------------------------------------------------ -void CrystalStructureBondGenerator::selectAnchorSite(int anchor) -{ - this->BaseBondGenerator::selectAnchorSite(anchor); - const Atom& a0 = this->symatoms(anchor)[0]; - mr0 = a0.xyz_cartn; +void CrystalStructureBondGenerator::selectAnchorSite(int anchor) { + this->BaseBondGenerator::selectAnchorSite(anchor); + const Atom& a0 = this->symatoms(anchor)[0]; + mr0 = a0.xyz_cartn; } - -const R3::Matrix& CrystalStructureBondGenerator::Ucartesian1() const -{ - return *mpuc1; +const R3::Matrix& CrystalStructureBondGenerator::Ucartesian1() const { + return *mpuc1; } // Protected Methods --------------------------------------------------------- -bool CrystalStructureBondGenerator::iterateSymmetry() -{ - // Iterate the sphere at a fixed symmetry position. - if (this->PeriodicStructureBondGenerator::iterateSymmetry()) - { - this->updater1(); - return true; - } - // Advance to the next symmetry position. We are done if they - // were all already used. - const AtomVector& sa = this->symatoms(this->site1()); - ++msymidx; - if (msymidx >= sa.size()) return false; - // rewind the sphere for the new symmetry position. - // this calls CrystalStructureBondGenerator::updater1() - this->PeriodicStructureBondGenerator::rewindSymmetry(); +bool CrystalStructureBondGenerator::iterateSymmetry() { + // Iterate the sphere at a fixed symmetry position. + if (this->PeriodicStructureBondGenerator::iterateSymmetry()) { + this->updater1(); return true; + } + // Advance to the next symmetry position. We are done if they + // were all already used. + const AtomVector& sa = this->symatoms(this->site1()); + ++msymidx; + if (msymidx >= sa.size()) return false; + // rewind the sphere for the new symmetry position. + // this calls CrystalStructureBondGenerator::updater1() + this->PeriodicStructureBondGenerator::rewindSymmetry(); + return true; } - -void CrystalStructureBondGenerator::rewindSymmetry() -{ - msymidx = 0; - // this calls CrystalStructureBondGenerator::updater1() - this->PeriodicStructureBondGenerator::rewindSymmetry(); +void CrystalStructureBondGenerator::rewindSymmetry() { + msymidx = 0; + // this calls CrystalStructureBondGenerator::updater1() + this->PeriodicStructureBondGenerator::rewindSymmetry(); } - -void CrystalStructureBondGenerator::getNextBond() -{ - this->BaseBondGenerator::getNextBond(); +void CrystalStructureBondGenerator::getNextBond() { + this->BaseBondGenerator::getNextBond(); } - -void CrystalStructureBondGenerator::updater1() -{ - const AtomVector& sa = this->symatoms(this->site1()); - assert(msymidx < sa.size()); - mr1 = mrcsphere + sa[msymidx].xyz_cartn; - mpuc1 = &(sa[msymidx].uij_cartn); - this->updateDistance(); +void CrystalStructureBondGenerator::updater1() { + const AtomVector& sa = this->symatoms(this->site1()); + assert(msymidx < sa.size()); + mr1 = mrcsphere + sa[msymidx].xyz_cartn; + mpuc1 = &(sa[msymidx].uij_cartn); + this->updateDistance(); } // Private Methods ----------------------------------------------------------- const CrystalStructureAdapter::AtomVector& -CrystalStructureBondGenerator::symatoms(int idx) -{ - assert(0 <= idx && idx < int(mcstructure->msymatoms.size())); - return mcstructure->msymatoms[idx]; +CrystalStructureBondGenerator::symatoms(int idx) { + assert(0 <= idx && idx < int(mcstructure->msymatoms.size())); + return mcstructure->msymatoms[idx]; } -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/CrystalStructureAdapter.hpp b/src/diffpy/srreal/CrystalStructureAdapter.hpp index 56645810..e0d0c225 100644 --- a/src/diffpy/srreal/CrystalStructureAdapter.hpp +++ b/src/diffpy/srreal/CrystalStructureAdapter.hpp @@ -1,179 +1,162 @@ /***************************************************************************** -* -* libdiffpy Complex Modeling Initiative -* (c) 2013 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. -* -****************************************************************************** -* -* class CrystalStructureAdapter -- universal adapter for crystal structure -* composed of asymmetric unit cell and list of symmetry operations in -* the space group -* -* class CrystalStructureBondGenerator -- bond generator -* -*****************************************************************************/ + * + * libdiffpy Complex Modeling Initiative + * (c) 2013 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. + * + ****************************************************************************** + * + * class CrystalStructureAdapter -- universal adapter for crystal structure + * composed of asymmetric unit cell and list of symmetry operations in + * the space group + * + * class CrystalStructureBondGenerator -- bond generator + * + *****************************************************************************/ #ifndef CRYSTALSTRUCTUREADAPTER_HPP_INCLUDED #define CRYSTALSTRUCTUREADAPTER_HPP_INCLUDED #include +#include + namespace diffpy { namespace srreal { /// store rotation matrix and translation vector for a symmetry operation -class SymOpRotTrans -{ - public: - - R3::Matrix R; - R3::Vector t; - - private: - - // serialization - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - ar & R & t; - } - +class SymOpRotTrans { + public: + R3::Matrix R; + R3::Vector t; + + private: + // serialization + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + ar & R & t; + } }; // Comparison functions -inline -bool operator==(const SymOpRotTrans& op0, const SymOpRotTrans& op1) -{ - return (op0.R == op1.R) && (op0.t == op1.t); +inline bool operator==(const SymOpRotTrans& op0, const SymOpRotTrans& op1) { + return (op0.R == op1.R) && (op0.t == op1.t); } -inline -bool operator!=(const SymOpRotTrans& op0, const SymOpRotTrans& op1) -{ - return !(op0 == op1); +inline bool operator!=(const SymOpRotTrans& op0, const SymOpRotTrans& op1) { + return !(op0 == op1); } - -class CrystalStructureAdapter : public PeriodicStructureAdapter -{ - friend class CrystalStructureBondGenerator; - - public: - - typedef std::vector SymOpVector; - // constructor - CrystalStructureAdapter(); - - // methods - overloaded - virtual StructureAdapterPtr clone() const; - virtual BaseBondGeneratorPtr createBondGenerator() const; - virtual int siteMultiplicity(int idx) const; - virtual StructureDifference diff(StructureAdapterConstPtr other) const; - - // methods - own - void setSymmetryPrecision(double eps); - const double& getSymmetryPrecision() const; - int countSymOps() const; - void clearSymOps(); - void addSymOp(const SymOpRotTrans&); - void addSymOp(const R3::Matrix& R, const R3::Vector& t); - const SymOpRotTrans& getSymOp(int i) const; - /// return all symmetry equivalent atoms in the unit cell for site i - const AtomVector& getEquivalentAtoms(int idx) const; - /// return all symmetry related atoms in fractional coordinates - AtomVector expandLatticeAtom(const Atom&) const; - void updateSymmetryPositions() const; - - private: - - // data - /// array of symmetry operations - SymOpVector msymops; - double msymmetry_precision; - mutable std::vector msymatoms; - mutable bool msymmetry_cached; - - // symmetry helpers - /// return index of AtomVector atom at an equal position or -1 - int findEqualPosition(const AtomVector&, const Atom&) const; - /// fuzzy check if symmetry positions are up to date - /// this only detects addition or removal of atom in the asymmetric - /// unit, but does not check for changes in atom positions. - bool isSymmetryCached() const; - - // comparison - friend bool operator==( - const CrystalStructureAdapter&, const CrystalStructureAdapter&); - - // serialization - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - ar & boost::serialization::base_object(*this); - ar & msymops; - ar & msymmetry_precision; - ar & msymatoms; - ar & msymmetry_cached; - } - +class DLL_EXPORT CrystalStructureAdapter : public PeriodicStructureAdapter { + friend class CrystalStructureBondGenerator; + + public: + typedef std::vector SymOpVector; + // constructor + CrystalStructureAdapter(); + + // methods - overloaded + virtual StructureAdapterPtr clone() const; + virtual BaseBondGeneratorPtr createBondGenerator() const; + virtual int siteMultiplicity(int idx) const; + virtual StructureDifference diff(StructureAdapterConstPtr other) const; + + // methods - own + void setSymmetryPrecision(double eps); + const double& getSymmetryPrecision() const; + int countSymOps() const; + void clearSymOps(); + void addSymOp(const SymOpRotTrans&); + void addSymOp(const R3::Matrix& R, const R3::Vector& t); + const SymOpRotTrans& getSymOp(int i) const; + /// return all symmetry equivalent atoms in the unit cell for site i + const AtomVector& getEquivalentAtoms(int idx) const; + /// return all symmetry related atoms in fractional coordinates + AtomVector expandLatticeAtom(const Atom&) const; + void updateSymmetryPositions() const; + + private: + // data + /// array of symmetry operations + SymOpVector msymops; + double msymmetry_precision; + mutable std::vector msymatoms; + mutable bool msymmetry_cached; + + // symmetry helpers + /// return index of AtomVector atom at an equal position or -1 + int findEqualPosition(const AtomVector&, const Atom&) const; + /// fuzzy check if symmetry positions are up to date + /// this only detects addition or removal of atom in the asymmetric + /// unit, but does not check for changes in atom positions. + bool isSymmetryCached() const; + + // comparison + friend DLL_EXPORT bool operator==(const CrystalStructureAdapter&, + const CrystalStructureAdapter&); + + // serialization + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + ar& boost::serialization::base_object(*this); + ar & msymops; + ar & msymmetry_precision; + ar & msymatoms; + ar & msymmetry_cached; + } }; - typedef boost::shared_ptr CrystalStructureAdapterPtr; // Comparison functions -bool operator==(const CrystalStructureAdapter&, const CrystalStructureAdapter&); -bool operator!=(const CrystalStructureAdapter&, const CrystalStructureAdapter&); - - -class CrystalStructureBondGenerator : public PeriodicStructureBondGenerator -{ - public: - - // constructors - CrystalStructureBondGenerator(StructureAdapterConstPtr); - - // configuration - virtual void selectAnchorSite(int); - - // data access - virtual const R3::Matrix& Ucartesian1() const; +DLL_EXPORT bool operator==(const CrystalStructureAdapter&, + const CrystalStructureAdapter&); +DLL_EXPORT bool operator!=(const CrystalStructureAdapter&, + const CrystalStructureAdapter&); - protected: +class DLL_EXPORT CrystalStructureBondGenerator + : public PeriodicStructureBondGenerator { + public: + // constructors + CrystalStructureBondGenerator(StructureAdapterConstPtr); - // methods - virtual bool iterateSymmetry(); - virtual void rewindSymmetry(); - virtual void getNextBond(); - virtual void updater1(); + // configuration + virtual void selectAnchorSite(int); - // data - const CrystalStructureAdapter* mcstructure; - size_t msymidx; - const R3::Matrix* mpuc1; + // data access + virtual const R3::Matrix& Ucartesian1() const; - private: + protected: + // methods + virtual bool iterateSymmetry(); + virtual void rewindSymmetry(); + virtual void getNextBond(); + virtual void updater1(); - typedef CrystalStructureAdapter::AtomVector AtomVector; + // data + const CrystalStructureAdapter* mcstructure; + size_t msymidx; + const R3::Matrix* mpuc1; - // methods - const AtomVector& symatoms(int idx); + private: + typedef CrystalStructureAdapter::AtomVector AtomVector; + // methods + const AtomVector& symatoms(int idx); }; -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy BOOST_CLASS_EXPORT_KEY(diffpy::srreal::CrystalStructureAdapter) diff --git a/src/diffpy/srreal/DebyePDFCalculator.cpp b/src/diffpy/srreal/DebyePDFCalculator.cpp index d77198ec..4491c840 100644 --- a/src/diffpy/srreal/DebyePDFCalculator.cpp +++ b/src/diffpy/srreal/DebyePDFCalculator.cpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy 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, Chris Farrow -* -* See AUTHORS.txt for a list of people who contributed. -* See LICENSE_DANSE.txt for license information. -* -****************************************************************************** -* -* class DebyePDFCalculator -- calculate PDF from the Debye equation. -* -*****************************************************************************/ + * + * libdiffpy 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, Chris Farrow + * + * See AUTHORS.txt for a list of people who contributed. + * See LICENSE_DANSE.txt for license information. + * + ****************************************************************************** + * + * class DebyePDFCalculator -- calculate PDF from the Debye equation. + * + *****************************************************************************/ #include #include @@ -38,191 +38,154 @@ const double DEFAULT_DEBYEPDFCALCULATOR_QMAX = 25.0; // Constructor --------------------------------------------------------------- -DebyePDFCalculator::DebyePDFCalculator() : - mqminpdf(0.0), - moptimumqstep(false), - mrstep(DEFAULT_PDFCALCULATOR_RSTEP), - mmaxextension(DEFAULT_PDFCALCULATOR_MAXEXTENSION), - mrcalclosteps(0), - mrcalchisteps(0), - mrlimits_are_cached(false) -{ - // default configuration - this->setScatteringFactorTableByType("xray"); - this->setRmax(DEFAULT_PDFCALCULATOR_RMAX); - this->setQmax(DEFAULT_DEBYEPDFCALCULATOR_QMAX); - this->setOptimumQstep(); - // envelopes - this->addEnvelopeByType("scale"); - this->addEnvelopeByType("qresolution"); - // cache all internal data according to an empty structure. - // this rebuilds mstructure_cache and mrlimits_cache. - this->setStructure(mstructure); - // attributes - this->registerDoubleAttribute("qmin", this, - &DebyePDFCalculator::getQmin, &DebyePDFCalculator::setQmin); - this->registerDoubleAttribute("qmax", this, - &DebyePDFCalculator::getQmax, &DebyePDFCalculator::setQmax); - this->registerDoubleAttribute("qstep", this, - &DebyePDFCalculator::getQstep, &DebyePDFCalculator::setQstep); - this->registerDoubleAttribute("rmin", this, - &DebyePDFCalculator::getRmin, &DebyePDFCalculator::setRmin); - this->registerDoubleAttribute("rmax", this, - &DebyePDFCalculator::getRmax, &DebyePDFCalculator::setRmax); - this->registerDoubleAttribute("rstep", this, - &DebyePDFCalculator::getRstep, &DebyePDFCalculator::setRstep); - this->registerDoubleAttribute("maxextension", this, - &DebyePDFCalculator::getMaxExtension, - &DebyePDFCalculator::setMaxExtension); - this->registerDoubleAttribute("extendedrmin", this, - &DebyePDFCalculator::rcalclo); - this->registerDoubleAttribute("extendedrmax", this, - &DebyePDFCalculator::rcalchi); +DebyePDFCalculator::DebyePDFCalculator() + : mqminpdf(0.0), + moptimumqstep(false), + mrstep(DEFAULT_PDFCALCULATOR_RSTEP), + mmaxextension(DEFAULT_PDFCALCULATOR_MAXEXTENSION), + mrcalclosteps(0), + mrcalchisteps(0), + mrlimits_are_cached(false) { + // default configuration + this->setScatteringFactorTableByType("xray"); + this->setRmax(DEFAULT_PDFCALCULATOR_RMAX); + this->setQmax(DEFAULT_DEBYEPDFCALCULATOR_QMAX); + this->setOptimumQstep(); + // envelopes + this->addEnvelopeByType("scale"); + this->addEnvelopeByType("qresolution"); + // cache all internal data according to an empty structure. + // this rebuilds mstructure_cache and mrlimits_cache. + this->setStructure(mstructure); + // attributes + this->registerDoubleAttribute("qmin", this, &DebyePDFCalculator::getQmin, + &DebyePDFCalculator::setQmin); + this->registerDoubleAttribute("qmax", this, &DebyePDFCalculator::getQmax, + &DebyePDFCalculator::setQmax); + this->registerDoubleAttribute("qstep", this, &DebyePDFCalculator::getQstep, + &DebyePDFCalculator::setQstep); + this->registerDoubleAttribute("rmin", this, &DebyePDFCalculator::getRmin, + &DebyePDFCalculator::setRmin); + this->registerDoubleAttribute("rmax", this, &DebyePDFCalculator::getRmax, + &DebyePDFCalculator::setRmax); + this->registerDoubleAttribute("rstep", this, &DebyePDFCalculator::getRstep, + &DebyePDFCalculator::setRstep); + this->registerDoubleAttribute("maxextension", this, + &DebyePDFCalculator::getMaxExtension, + &DebyePDFCalculator::setMaxExtension); + this->registerDoubleAttribute("extendedrmin", this, + &DebyePDFCalculator::rcalclo); + this->registerDoubleAttribute("extendedrmax", this, + &DebyePDFCalculator::rcalchi); } // Public Methods ------------------------------------------------------------ // PairQuantity overloads -eventticker::EventTicker& DebyePDFCalculator::ticker() const -{ - // collect composite tickers for the BaseDebyeSum parent class - eventticker::EventTicker& tic = this->BaseDebyeSum::ticker(); - assert(&mticker == &tic); - tic.updateFrom(this->ScatteringFactorTableOwner::ticker()); - return tic; +eventticker::EventTicker& DebyePDFCalculator::ticker() const { + // collect composite tickers for the BaseDebyeSum parent class + eventticker::EventTicker& tic = this->BaseDebyeSum::ticker(); + assert(&mticker == &tic); + tic.updateFrom(this->ScatteringFactorTableOwner::ticker()); + return tic; } // results -QuantityType DebyePDFCalculator::getPDF() const -{ - QuantityType rgrid = this->getRgrid(); - QuantityType pdf0 = this->getPDFAtQmin(this->getQmin()); - QuantityType pdf1 = this->applyEnvelopes(rgrid, pdf0); - return pdf1; +QuantityType DebyePDFCalculator::getPDF() const { + QuantityType rgrid = this->getRgrid(); + QuantityType pdf0 = this->getPDFAtQmin(this->getQmin()); + QuantityType pdf1 = this->applyEnvelopes(rgrid, pdf0); + return pdf1; } - -QuantityType DebyePDFCalculator::getRDF() const -{ - QuantityType rgrid = this->getRgrid(); - QuantityType rv = this->getRDFperR(); - assert(rv.size() == rgrid.size()); - transform(rgrid.begin(), rgrid.end(), rv.begin(), rv.begin(), +QuantityType DebyePDFCalculator::getRDF() const { + QuantityType rgrid = this->getRgrid(); + QuantityType rv = this->getRDFperR(); + assert(rv.size() == rgrid.size()); + transform(rgrid.begin(), rgrid.end(), rv.begin(), rv.begin(), multiplies()); - return rv; + return rv; } - -QuantityType DebyePDFCalculator::getRDFperR() const -{ - return this->getPDFAtQmin(0.0); +QuantityType DebyePDFCalculator::getRDFperR() const { + return this->getPDFAtQmin(0.0); } // Q-range configuration -void DebyePDFCalculator::setQmin(double qmin) -{ - // NOTE: do not update ticker here, because the actual - // Debye summation is always conducted from Qmin=0. - ensureNonNegative("Qmin", qmin); - this->BaseDebyeSum::setQmin(0.0); - mqminpdf = qmin; +void DebyePDFCalculator::setQmin(double qmin) { + // NOTE: do not update ticker here, because the actual + // Debye summation is always conducted from Qmin=0. + ensureNonNegative("Qmin", qmin); + this->BaseDebyeSum::setQmin(0.0); + mqminpdf = qmin; } +const double& DebyePDFCalculator::getQmin() const { return mqminpdf; } -const double& DebyePDFCalculator::getQmin() const -{ - return mqminpdf; +void DebyePDFCalculator::setQmax(double qmax) { + this->BaseDebyeSum::setQmax(qmax); + this->updateQstep(); } - -void DebyePDFCalculator::setQmax(double qmax) -{ - this->BaseDebyeSum::setQmax(qmax); - this->updateQstep(); +void DebyePDFCalculator::setQstep(double qstep) { + this->BaseDebyeSum::setQstep(qstep); + moptimumqstep = false; + this->updateQstep(); } - -void DebyePDFCalculator::setQstep(double qstep) -{ - this->BaseDebyeSum::setQstep(qstep); - moptimumqstep = false; - this->updateQstep(); -} - - -void DebyePDFCalculator::setOptimumQstep() -{ - moptimumqstep = true; - this->updateQstep(); +void DebyePDFCalculator::setOptimumQstep() { + moptimumqstep = true; + this->updateQstep(); } - -bool DebyePDFCalculator::isOptimumQstep() const -{ - return moptimumqstep; -} +bool DebyePDFCalculator::isOptimumQstep() const { return moptimumqstep; } // R-range methods -QuantityType DebyePDFCalculator::getRgrid() const -{ - return pdfutils_getRgrid(this); +QuantityType DebyePDFCalculator::getRgrid() const { + return pdfutils_getRgrid(this); } // R-range configuration -void DebyePDFCalculator::setRmin(double rmin) -{ - ensureNonNegative("Rmin", rmin); - if (mrmin != rmin) mrlimits_are_cached = false; - this->PairQuantity::setRmin(rmin); +void DebyePDFCalculator::setRmin(double rmin) { + ensureNonNegative("Rmin", rmin); + if (mrmin != rmin) mrlimits_are_cached = false; + this->PairQuantity::setRmin(rmin); } - -void DebyePDFCalculator::setRmax(double rmax) -{ - ensureNonNegative("Rmax", rmax); - if (mrmax != rmax) mrlimits_are_cached = false; - this->PairQuantity::setRmax(rmax); - this->updateQstep(); +void DebyePDFCalculator::setRmax(double rmax) { + ensureNonNegative("Rmax", rmax); + if (mrmax != rmax) mrlimits_are_cached = false; + this->PairQuantity::setRmax(rmax); + this->updateQstep(); } - -void DebyePDFCalculator::setRstep(double rstep) -{ - // NOTE: do not update ticker here, rstep is only used in the FFT - // and not in the Debye summation. - ensureEpsilonPositive("Rstep", rstep); - if (mrstep != rstep) mrlimits_are_cached = false; - mrstep = rstep; +void DebyePDFCalculator::setRstep(double rstep) { + // NOTE: do not update ticker here, rstep is only used in the FFT + // and not in the Debye summation. + ensureEpsilonPositive("Rstep", rstep); + if (mrstep != rstep) mrlimits_are_cached = false; + mrstep = rstep; } +const double& DebyePDFCalculator::getRstep() const { return mrstep; } -const double& DebyePDFCalculator::getRstep() const -{ - return mrstep; +void DebyePDFCalculator::setMaxExtension(double maxextension) { + ensureNonNegative("maxextension", maxextension); + if (mmaxextension != maxextension) { + mticker.click(); + mrlimits_are_cached = false; + } + mmaxextension = maxextension; + this->updateQstep(); } - -void DebyePDFCalculator::setMaxExtension(double maxextension) -{ - ensureNonNegative("maxextension", maxextension); - if (mmaxextension != maxextension) - { - mticker.click(); - mrlimits_are_cached = false; - } - mmaxextension = maxextension; - this->updateQstep(); -} - - -const double& DebyePDFCalculator::getMaxExtension() const -{ - return mmaxextension; +const double& DebyePDFCalculator::getMaxExtension() const { + return mmaxextension; } // Protected Methods --------------------------------------------------------- @@ -233,167 +196,142 @@ namespace { // single implementation for constant and non-constant accept template -void debyepdfcalc_accept(T* obj, diffpy::BaseAttributesVisitor& v) -{ - obj->getPeakWidthModel()->accept(v); - // PDF envelopes - set evnames = obj->usedEnvelopeTypes(); - set::const_iterator nm = evnames.begin(); - for (; nm != evnames.end(); ++nm) - { - obj->getEnvelopeByType(*nm)->accept(v); - } - // finally call standard accept - obj->diffpy::Attributes::accept(v); +void debyepdfcalc_accept(T* obj, diffpy::BaseAttributesVisitor& v) { + obj->getPeakWidthModel()->accept(v); + // PDF envelopes + set evnames = obj->usedEnvelopeTypes(); + set::const_iterator nm = evnames.begin(); + for (; nm != evnames.end(); ++nm) { + obj->getEnvelopeByType(*nm)->accept(v); + } + // finally call standard accept + obj->diffpy::Attributes::accept(v); } -} // namespace - +} // namespace -void DebyePDFCalculator::accept(diffpy::BaseAttributesVisitor& v) -{ - debyepdfcalc_accept(this, v); +void DebyePDFCalculator::accept(diffpy::BaseAttributesVisitor& v) { + debyepdfcalc_accept(this, v); } - -void DebyePDFCalculator::accept(diffpy::BaseAttributesVisitor& v) const -{ - debyepdfcalc_accept(this, v); +void DebyePDFCalculator::accept(diffpy::BaseAttributesVisitor& v) const { + debyepdfcalc_accept(this, v); } // BaseDebyeSum overloads -void DebyePDFCalculator::resetValue() -{ - this->cacheRlimitsData(); - this->updateQstep(); - this->BaseDebyeSum::resetValue(); +void DebyePDFCalculator::resetValue() { + this->cacheRlimitsData(); + this->updateQstep(); + this->BaseDebyeSum::resetValue(); } - -void DebyePDFCalculator::configureBondGenerator(BaseBondGenerator& bnds) const -{ - bnds.setRmin(this->rcalclo()); - bnds.setRmax(this->rcalchi()); +void DebyePDFCalculator::configureBondGenerator(BaseBondGenerator& bnds) const { + bnds.setRmin(this->rcalclo()); + bnds.setRmax(this->rcalchi()); } - -double DebyePDFCalculator::sfSiteAtQ(int siteidx, const double& Q) const -{ - const ScatteringFactorTablePtr& sftable = this->getScatteringFactorTable(); - const string& smbl = mstructure->siteAtomType(siteidx); - const double occupancy = mstructure->siteOccupancy(siteidx); - double rv = sftable->lookup(smbl, Q) * occupancy; - return rv; +double DebyePDFCalculator::sfSiteAtQ(int siteidx, const double& Q) const { + const ScatteringFactorTablePtr& sftable = this->getScatteringFactorTable(); + const string& smbl = mstructure->siteAtomType(siteidx); + const double occupancy = mstructure->siteOccupancy(siteidx); + double rv = sftable->lookup(smbl, Q) * occupancy; + return rv; } // Private Methods ----------------------------------------------------------- -QuantityType DebyePDFCalculator::getPDFAtQmin(double qmin) const -{ - // build a zero padded F vector that gives dr <= rstep - QuantityType fpad = this->getF(); - // zero all F values below qmin - int nqmin = pdfutils_qminSteps(qmin, this->getQstep()); - if (nqmin > int(fpad.size())) nqmin = fpad.size(); - fill(fpad.begin(), fpad.begin() + nqmin, 0.0); - int nfromdr = int(ceil(M_PI / this->getRstep() / this->getQstep())); - if (nfromdr > int(fpad.size())) fpad.resize(nfromdr, 0.0); - QuantityType gpad = fftftog(fpad, this->getQstep()); - const double drpad = M_PI / (gpad.size() * this->getQstep()); - QuantityType rgrid = this->getRgrid(); - QuantityType pdf0(rgrid.size()); - QuantityType::const_iterator ri = rgrid.begin(); - QuantityType::iterator pdfi = pdf0.begin(); - for (; ri != rgrid.end(); ++ri, ++pdfi) - { - double xdrp = *ri / drpad; - int iplo = int(xdrp); - int iphi = iplo + 1; - double wphi = xdrp - iplo; - double wplo = 1.0 - wphi; - assert(iphi < int(gpad.size())); - *pdfi = wplo * gpad[iplo] + wphi * gpad[iphi]; - } - return pdf0; +QuantityType DebyePDFCalculator::getPDFAtQmin(double qmin) const { + // build a zero padded F vector that gives dr <= rstep + QuantityType fpad = this->getF(); + // zero all F values below qmin + int nqmin = pdfutils_qminSteps(qmin, this->getQstep()); + if (nqmin > int(fpad.size())) nqmin = fpad.size(); + fill(fpad.begin(), fpad.begin() + nqmin, 0.0); + int nfromdr = int(ceil(M_PI / this->getRstep() / this->getQstep())); + if (nfromdr > int(fpad.size())) fpad.resize(nfromdr, 0.0); + QuantityType gpad = fftftog(fpad, this->getQstep()); + const double drpad = M_PI / (gpad.size() * this->getQstep()); + QuantityType rgrid = this->getRgrid(); + QuantityType pdf0(rgrid.size()); + QuantityType::const_iterator ri = rgrid.begin(); + QuantityType::iterator pdfi = pdf0.begin(); + for (; ri != rgrid.end(); ++ri, ++pdfi) { + double xdrp = *ri / drpad; + int iplo = int(xdrp); + int iphi = iplo + 1; + double wphi = xdrp - iplo; + double wplo = 1.0 - wphi; + assert(iphi < int(gpad.size())); + *pdfi = wplo * gpad[iplo] + wphi * gpad[iphi]; + } + return pdf0; } - -void DebyePDFCalculator::updateQstep() -{ - double rmaxext = this->rcalchi(); - // Use at least 4 steps to Qmax even for tiny rmaxext. - // Avoid division by zero. - double oqstep = (this->getQmax() * rmaxext / M_PI > 4) ? - (M_PI / rmaxext) : (this->getQmax() / 4); - // if custom qstep is higher than the optimum one, - // force adjustment to the optimum value. - if (this->getQstep() >= oqstep) moptimumqstep = true; - if (moptimumqstep) this->BaseDebyeSum::setQstep(oqstep); +void DebyePDFCalculator::updateQstep() { + double rmaxext = this->rcalchi(); + // Use at least 4 steps to Qmax even for tiny rmaxext. + // Avoid division by zero. + double oqstep = (this->getQmax() * rmaxext / M_PI > 4) + ? (M_PI / rmaxext) + : (this->getQmax() / 4); + // if custom qstep is higher than the optimum one, + // force adjustment to the optimum value. + if (this->getQstep() >= oqstep) moptimumqstep = true; + if (moptimumqstep) this->BaseDebyeSum::setQstep(oqstep); } - -double DebyePDFCalculator::rcalclo() const -{ - if (!mrlimits_are_cached) this->cacheRlimitsData(); - double rv = mrcalclosteps * this->getRstep(); - return rv; +double DebyePDFCalculator::rcalclo() const { + if (!mrlimits_are_cached) this->cacheRlimitsData(); + double rv = mrcalclosteps * this->getRstep(); + return rv; } - -double DebyePDFCalculator::rcalchi() const -{ - if (!mrlimits_are_cached) this->cacheRlimitsData(); - double rv = mrcalchisteps * this->getRstep(); - return rv; +double DebyePDFCalculator::rcalchi() const { + if (!mrlimits_are_cached) this->cacheRlimitsData(); + double rv = mrcalchisteps * this->getRstep(); + return rv; } - -double DebyePDFCalculator::extFromTerminationRipples() const -{ - // number of termination ripples for extending the r-range - const int nripples = 6; - // extension due to termination ripples - double rv = (this->getQmax() > 0.0) ? - (nripples*2*M_PI / this->getQmax()) : 0.0; - return rv; +double DebyePDFCalculator::extFromTerminationRipples() const { + // number of termination ripples for extending the r-range + const int nripples = 6; + // extension due to termination ripples + double rv = + (this->getQmax() > 0.0) ? (nripples * 2 * M_PI / this->getQmax()) : 0.0; + return rv; } - -double DebyePDFCalculator::extFromPeakTails() const -{ - const PeakWidthModel& pwm = *(this->getPeakWidthModel()); - double maxfwhm = pwm.maxWidth( - mstructure, this->getRmin(), this->getRmax()); - // assume Gaussian peak profile - GaussianProfile pkf; - pkf.setPrecision(DEFAULT_PEAKPRECISION); - // Gaussian function is symmetric, no need to use xboundlo - double rv = pkf.xboundhi(maxfwhm); - return rv; +double DebyePDFCalculator::extFromPeakTails() const { + const PeakWidthModel& pwm = *(this->getPeakWidthModel()); + double maxfwhm = pwm.maxWidth(mstructure, this->getRmin(), this->getRmax()); + // assume Gaussian peak profile + GaussianProfile pkf; + pkf.setPrecision(DEFAULT_PEAKPRECISION); + // Gaussian function is symmetric, no need to use xboundlo + double rv = pkf.xboundhi(maxfwhm); + return rv; } - -void DebyePDFCalculator::cacheRlimitsData() const -{ - const int minreductionsteps = 50; - double ext_total = min(this->getMaxExtension(), +void DebyePDFCalculator::cacheRlimitsData() const { + const int minreductionsteps = 50; + double ext_total = + min(this->getMaxExtension(), this->extFromTerminationRipples() + this->extFromPeakTails()); - // abbreviations - const double& rmin = this->getRmin(); - const double& rmax = this->getRmax(); - const double& dr = this->getRstep(); - mrcalclosteps = max(0, pdfutils_rminSteps(rmin - ext_total, dr)); - const int nhi = pdfutils_rmaxSteps(rmax + ext_total, dr); - if (nhi <= (mrcalchisteps - minreductionsteps) || nhi > mrcalchisteps) - { - mrcalchisteps = nhi; - } - mrlimits_are_cached = true; + // abbreviations + const double& rmin = this->getRmin(); + const double& rmax = this->getRmax(); + const double& dr = this->getRstep(); + mrcalclosteps = max(0, pdfutils_rminSteps(rmin - ext_total, dr)); + const int nhi = pdfutils_rmaxSteps(rmax + ext_total, dr); + if (nhi <= (mrcalchisteps - minreductionsteps) || nhi > mrcalchisteps) { + mrcalchisteps = nhi; + } + mrlimits_are_cached = true; } -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/DebyePDFCalculator.hpp b/src/diffpy/srreal/DebyePDFCalculator.hpp index 512e2884..8a5114c0 100644 --- a/src/diffpy/srreal/DebyePDFCalculator.hpp +++ b/src/diffpy/srreal/DebyePDFCalculator.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy 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, Chris Farrow -* -* See AUTHORS.txt for a list of people who contributed. -* See LICENSE_DANSE.txt for license information. -* -****************************************************************************** -* -* class DebyePDFCalculator -- calculate PDF from the Debye equation. -* -*****************************************************************************/ + * + * libdiffpy 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, Chris Farrow + * + * See AUTHORS.txt for a list of people who contributed. + * See LICENSE_DANSE.txt for license information. + * + ****************************************************************************** + * + * class DebyePDFCalculator -- calculate PDF from the Debye equation. + * + *****************************************************************************/ // Comments from Chris Farrow's sources for PDFNanoProfile: // @@ -52,109 +52,105 @@ #include #include +#include + namespace diffpy { namespace srreal { -class DebyePDFCalculator : - public BaseDebyeSum, - public ScatteringFactorTableOwner, - public PDFEnvelopeOwner -{ - public: - - // constructor - DebyePDFCalculator(); - - // PairQuantity overloads - virtual eventticker::EventTicker& ticker() const; - - // results - /// PDF on the specified r-grid - QuantityType getPDF() const; - QuantityType getRDF() const; - QuantityType getRDFperR() const; - - // Q-range configuration - void setQmin(double); - const double& getQmin() const; - void setQmax(double); - void setQstep(double); - void setOptimumQstep(); - bool isOptimumQstep() const; - - // R-range methods - QuantityType getRgrid() const; - // R-range configuration - virtual void setRmin(double); - virtual void setRmax(double); - void setRstep(double); - const double& getRstep() const; - /// maximum total extension of the r-range accounting for both - /// termination ripples and peak tails - void setMaxExtension(double); - /// maximum total extension of the r-range accounting for both - /// termination ripples and peak tails - const double& getMaxExtension() const; - - protected: - - // Attributes overload to direct visitors around data structures - virtual void accept(diffpy::BaseAttributesVisitor& v); - virtual void accept(diffpy::BaseAttributesVisitor& v) const; - - // BaseDebyeSum overloads - virtual void resetValue(); - virtual void configureBondGenerator(BaseBondGenerator&) const; - virtual double sfSiteAtQ(int, const double& Q) const; - - private: - - // methods - QuantityType getPDFAtQmin(double qmin) const; - void updateQstep(); - /// complete lower bound extension of the calculated grid - double rcalclo() const; - /// complete upper bound extension of the calculated grid - double rcalchi() const; - /// r-range extension to allow propagation of termination ripples - double extFromTerminationRipples() const; - /// r-range extension to account for tails from out-of-range peaks - double extFromPeakTails() const; - void cacheRlimitsData() const; - - // data - double mqminpdf; - bool moptimumqstep; - double mrstep; - double mmaxextension; - mutable int mrcalclosteps; - mutable int mrcalchisteps; - mutable bool mrlimits_are_cached; - - // serialization - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - using boost::serialization::base_object; - ar & base_object(*this); - ar & base_object(*this); - ar & base_object(*this); - ar & mqminpdf; - ar & moptimumqstep; - ar & mrstep; - ar & mmaxextension; - ar & mrcalclosteps; - ar & mrcalchisteps; - if (version >= 1) { - ar & mrlimits_are_cached; - } - } +class DLL_EXPORT DebyePDFCalculator : public BaseDebyeSum, + public ScatteringFactorTableOwner, + public PDFEnvelopeOwner { + public: + // constructor + DebyePDFCalculator(); + + // PairQuantity overloads + virtual eventticker::EventTicker& ticker() const; + + // results + /// PDF on the specified r-grid + QuantityType getPDF() const; + QuantityType getRDF() const; + QuantityType getRDFperR() const; + + // Q-range configuration + void setQmin(double); + const double& getQmin() const; + void setQmax(double); + void setQstep(double); + void setOptimumQstep(); + bool isOptimumQstep() const; + + // R-range methods + QuantityType getRgrid() const; + // R-range configuration + virtual void setRmin(double); + virtual void setRmax(double); + void setRstep(double); + const double& getRstep() const; + /// maximum total extension of the r-range accounting for both + /// termination ripples and peak tails + void setMaxExtension(double); + /// maximum total extension of the r-range accounting for both + /// termination ripples and peak tails + const double& getMaxExtension() const; + + protected: + // Attributes overload to direct visitors around data structures + virtual void accept(diffpy::BaseAttributesVisitor& v); + virtual void accept(diffpy::BaseAttributesVisitor& v) const; + + // BaseDebyeSum overloads + virtual void resetValue(); + virtual void configureBondGenerator(BaseBondGenerator&) const; + virtual double sfSiteAtQ(int, const double& Q) const; + + private: + // methods + QuantityType getPDFAtQmin(double qmin) const; + void updateQstep(); + /// complete lower bound extension of the calculated grid + double rcalclo() const; + /// complete upper bound extension of the calculated grid + double rcalchi() const; + /// r-range extension to allow propagation of termination ripples + double extFromTerminationRipples() const; + /// r-range extension to account for tails from out-of-range peaks + double extFromPeakTails() const; + void cacheRlimitsData() const; + + // data + double mqminpdf; + bool moptimumqstep; + double mrstep; + double mmaxextension; + mutable int mrcalclosteps; + mutable int mrcalchisteps; + mutable bool mrlimits_are_cached; + + // serialization + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + using boost::serialization::base_object; + ar& base_object(*this); + ar& base_object(*this); + ar& base_object(*this); + ar & mqminpdf; + ar & moptimumqstep; + ar & mrstep; + ar & mmaxextension; + ar & mrcalclosteps; + ar & mrcalchisteps; + if (version >= 1) { + ar & mrlimits_are_cached; + } + } }; // class DebyePDFCalculator -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/DebyeWallerPeakWidth.cpp b/src/diffpy/srreal/DebyeWallerPeakWidth.cpp index 10c6bfe6..e5f52aec 100644 --- a/src/diffpy/srreal/DebyeWallerPeakWidth.cpp +++ b/src/diffpy/srreal/DebyeWallerPeakWidth.cpp @@ -1,21 +1,21 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 The Trustees of Columbia University -* in the City of New York. All rights reserved. -* -* File coded by: Christopher Farrow, Pavol Juhas -* -* See AUTHORS.txt for a list of people who contributed. -* See LICENSE_DANSE.txt for license information. -* -****************************************************************************** -* -* class DebyeWallerPeakWidth -- peak width calculated assuming independent -* thermal vibrations of atoms forming a pair. -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 The Trustees of Columbia University + * in the City of New York. All rights reserved. + * + * File coded by: Christopher Farrow, Pavol Juhas + * + * See AUTHORS.txt for a list of people who contributed. + * See LICENSE_DANSE.txt for license information. + * + ****************************************************************************** + * + * class DebyeWallerPeakWidth -- peak width calculated assuming independent + * thermal vibrations of atoms forming a pair. + * + *****************************************************************************/ #include #include @@ -28,52 +28,44 @@ using namespace std; // Constructors -------------------------------------------------------------- -PeakWidthModelPtr DebyeWallerPeakWidth::create() const -{ - PeakWidthModelPtr rv(new DebyeWallerPeakWidth()); - return rv; +PeakWidthModelPtr DebyeWallerPeakWidth::create() const { + PeakWidthModelPtr rv(new DebyeWallerPeakWidth()); + return rv; } - -PeakWidthModelPtr DebyeWallerPeakWidth::clone() const -{ - PeakWidthModelPtr rv(new DebyeWallerPeakWidth(*this)); - return rv; +PeakWidthModelPtr DebyeWallerPeakWidth::clone() const { + PeakWidthModelPtr rv(new DebyeWallerPeakWidth(*this)); + return rv; } // Public Methods ------------------------------------------------------------ -const string& DebyeWallerPeakWidth::type() const -{ - static const string rv = "debye-waller"; - return rv; +const string& DebyeWallerPeakWidth::type() const { + static const string rv = "debye-waller"; + return rv; } - -double DebyeWallerPeakWidth::calculate(const BaseBondGenerator& bnds) const -{ - using diffpy::mathutils::GAUSS_SIGMA_TO_FWHM; - double msdval = bnds.msd(); - double rv = (msdval < 0.0) ? 0.0 : GAUSS_SIGMA_TO_FWHM * sqrt(msdval); - return rv; +double DebyeWallerPeakWidth::calculate(const BaseBondGenerator& bnds) const { + using diffpy::mathutils::GAUSS_SIGMA_TO_FWHM; + double msdval = bnds.msd(); + double rv = (msdval < 0.0) ? 0.0 : GAUSS_SIGMA_TO_FWHM * sqrt(msdval); + return rv; } - -double DebyeWallerPeakWidth::maxWidth(StructureAdapterPtr stru, - double rmin, double rmax) const -{ - using diffpy::mathutils::GAUSS_SIGMA_TO_FWHM; - double maxmsd = 2 * maxUii(stru); - double rv = (maxmsd <= 0.0) ? 0.0 : GAUSS_SIGMA_TO_FWHM * sqrt(maxmsd); - return rv; +double DebyeWallerPeakWidth::maxWidth(StructureAdapterPtr stru, double rmin, + double rmax) const { + using diffpy::mathutils::GAUSS_SIGMA_TO_FWHM; + double maxmsd = 2 * maxUii(stru); + double rv = (maxmsd <= 0.0) ? 0.0 : GAUSS_SIGMA_TO_FWHM * sqrt(maxmsd); + return rv; } // Registration -------------------------------------------------------------- bool reg_DebyeWallerPeakWidth = DebyeWallerPeakWidth().registerThisType(); -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/DebyeWallerPeakWidth.hpp b/src/diffpy/srreal/DebyeWallerPeakWidth.hpp index c900f7f1..a6e127c9 100644 --- a/src/diffpy/srreal/DebyeWallerPeakWidth.hpp +++ b/src/diffpy/srreal/DebyeWallerPeakWidth.hpp @@ -1,61 +1,56 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 The Trustees of Columbia University -* in the City of New York. All rights reserved. -* -* File coded by: Christopher Farrow, Pavol Juhas -* -* See AUTHORS.txt for a list of people who contributed. -* See LICENSE_DANSE.txt for license information. -* -****************************************************************************** -* -* class DebyeWallerPeakWidth -- peak width calculated assuming independent -* thermal vibrations of atoms forming a pair. -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 The Trustees of Columbia University + * in the City of New York. All rights reserved. + * + * File coded by: Christopher Farrow, Pavol Juhas + * + * See AUTHORS.txt for a list of people who contributed. + * See LICENSE_DANSE.txt for license information. + * + ****************************************************************************** + * + * class DebyeWallerPeakWidth -- peak width calculated assuming independent + * thermal vibrations of atoms forming a pair. + * + *****************************************************************************/ #ifndef DEBYEWALLERPEAKWIDTH_HPP_INCLUDED #define DEBYEWALLERPEAKWIDTH_HPP_INCLUDED #include +#include + namespace diffpy { namespace srreal { - -class DebyeWallerPeakWidth : public PeakWidthModel -{ - public: - - // constructors - virtual PeakWidthModelPtr create() const; - virtual PeakWidthModelPtr clone() const; - - // methods - virtual const std::string& type() const; - virtual double calculate(const BaseBondGenerator&) const; - virtual double maxWidth(StructureAdapterPtr, - double rmin, double rmax) const; - - private: - - // serialization - friend class boost::serialization::access; - - template - void serialize(Archive& ar, const unsigned int version) - { - using boost::serialization::base_object; - ar & base_object(*this); - } - +class DLL_EXPORT DebyeWallerPeakWidth : public PeakWidthModel { + public: + // constructors + virtual PeakWidthModelPtr create() const; + virtual PeakWidthModelPtr clone() const; + + // methods + virtual const std::string& type() const; + virtual double calculate(const BaseBondGenerator&) const; + virtual double maxWidth(StructureAdapterPtr, double rmin, double rmax) const; + + private: + // serialization + friend class boost::serialization::access; + + template + void serialize(Archive& ar, const unsigned int version) { + using boost::serialization::base_object; + ar& base_object(*this); + } }; -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/EmptyStructureAdapter.cpp b/src/diffpy/srreal/EmptyStructureAdapter.cpp index 84c0658d..46273ac0 100644 --- a/src/diffpy/srreal/EmptyStructureAdapter.cpp +++ b/src/diffpy/srreal/EmptyStructureAdapter.cpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy 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. -* -****************************************************************************** -* -* class EmptyStructureAdapter -- immutable class that is always empty. -* -*****************************************************************************/ + * + * libdiffpy 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. + * + ****************************************************************************** + * + * class EmptyStructureAdapter -- immutable class that is always empty. + * + *****************************************************************************/ #include @@ -30,101 +30,69 @@ namespace { std::out_of_range outofrange("Index out of range."); -} // namespace +} // namespace ////////////////////////////////////////////////////////////////////////////// // class EmptyStructureAdapter ////////////////////////////////////////////////////////////////////////////// -class EmptyStructureAdapter : public StructureAdapter -{ - public: +class EmptyStructureAdapter : public StructureAdapter { + public: + // virtual methods from the base class - // virtual methods from the base class + virtual StructureAdapterPtr clone() const { + StructureAdapterPtr rv = + boost::const_pointer_cast(shared_from_this()); + return rv; + } - virtual StructureAdapterPtr clone() const - { - StructureAdapterPtr rv = - boost::const_pointer_cast(shared_from_this()); - return rv; - } + virtual BaseBondGeneratorPtr createBondGenerator() const { + return boost::make_shared(shared_from_this()); + } + virtual int countSites() const { return 0; } - virtual BaseBondGeneratorPtr createBondGenerator() const - { - return boost::make_shared(shared_from_this()); - } + // reusing StructureAdapter::totalOccupancy() + // reusing StructureAdapter::numberDensity() + virtual const std::string& siteAtomType(int idx) const { throw outofrange; } - virtual int countSites() const - { - return 0; - } + virtual const R3::Vector& siteCartesianPosition(int idx) const { + throw outofrange; + } - // reusing StructureAdapter::totalOccupancy() - // reusing StructureAdapter::numberDensity() + virtual int siteMultiplicity(int idx) const { throw outofrange; } - virtual const std::string& siteAtomType(int idx) const - { - throw outofrange; - } + virtual double siteOccupancy(int idx) const { throw outofrange; } + virtual bool siteAnisotropy(int idx) const { throw outofrange; } - virtual const R3::Vector& siteCartesianPosition(int idx) const - { - throw outofrange; - } + virtual const R3::Matrix& siteCartesianUij(int idx) const { + throw outofrange; + } + // reusing StructureAdapter::customPQConfig() + // reusing StructureAdapter::diff() - virtual int siteMultiplicity(int idx) const - { - throw outofrange; - } - - - virtual double siteOccupancy(int idx) const - { - throw outofrange; - } - - - virtual bool siteAnisotropy(int idx) const - { - throw outofrange; - } - - - virtual const R3::Matrix& siteCartesianUij(int idx) const - { - throw outofrange; - } - - // reusing StructureAdapter::customPQConfig() - // reusing StructureAdapter::diff() - - private: - - // serialization - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - ar & boost::serialization::base_object(*this); - } - + private: + // serialization + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + ar& boost::serialization::base_object(*this); + } }; // Routines ------------------------------------------------------------------ -StructureAdapterPtr emptyStructureAdapter() -{ - static StructureAdapterPtr stru(new EmptyStructureAdapter); - assert(stru && stru->countSites() == 0); - return stru; +StructureAdapterPtr emptyStructureAdapter() { + static StructureAdapterPtr stru(new EmptyStructureAdapter); + assert(stru && stru->countSites() == 0); + return stru; } -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy BOOST_CLASS_EXPORT(diffpy::srreal::EmptyStructureAdapter) DIFFPY_INSTANTIATE_PTR_SERIALIZATION(diffpy::srreal::EmptyStructureAdapter) diff --git a/src/diffpy/srreal/GaussianProfile.cpp b/src/diffpy/srreal/GaussianProfile.cpp index 97622474..e2cc69ef 100644 --- a/src/diffpy/srreal/GaussianProfile.cpp +++ b/src/diffpy/srreal/GaussianProfile.cpp @@ -1,21 +1,21 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class GaussianProfile -- concrete implementation of the PeakProfile class. -* GaussianProfile is registered as "gaussian". -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class GaussianProfile -- concrete implementation of the PeakProfile class. + * GaussianProfile is registered as "gaussian". + * + *****************************************************************************/ #include @@ -32,72 +32,60 @@ using diffpy::mathutils::DOUBLE_EPS; // Constructors -------------------------------------------------------------- -GaussianProfile::GaussianProfile() -{ - // call setPrecision to update mhalfboundrel - this->setPrecision(DOUBLE_EPS); +GaussianProfile::GaussianProfile() { + // call setPrecision to update mhalfboundrel + this->setPrecision(DOUBLE_EPS); } - -PeakProfilePtr GaussianProfile::create() const -{ - PeakProfilePtr rv(new GaussianProfile()); - return rv; +PeakProfilePtr GaussianProfile::create() const { + PeakProfilePtr rv(new GaussianProfile()); + return rv; } - -PeakProfilePtr GaussianProfile::clone() const -{ - PeakProfilePtr rv(new GaussianProfile(*this)); - return rv; +PeakProfilePtr GaussianProfile::clone() const { + PeakProfilePtr rv(new GaussianProfile(*this)); + return rv; } // Public Methods ------------------------------------------------------------ -const string& GaussianProfile::type() const -{ - static string rv = "gaussian"; - return rv; +const string& GaussianProfile::type() const { + static string rv = "gaussian"; + return rv; } - -double GaussianProfile::operator()(double x, double fwhm) const -{ - if ( fwhm <= 0 ) return 0.0; - double xrel = x / fwhm; - double rv = 2 * sqrt(M_LN2 / M_PI) / fwhm * exp(-4 * M_LN2 * xrel * xrel); - return rv; +double GaussianProfile::operator()(double x, double fwhm) const { + if (fwhm <= 0) return 0.0; + double xrel = x / fwhm; + double rv = 2 * sqrt(M_LN2 / M_PI) / fwhm * exp(-4 * M_LN2 * xrel * xrel); + return rv; } - -double GaussianProfile::xboundlo(double fwhm) const -{ - return -1 * this->GaussianProfile::xboundhi(fwhm); +double GaussianProfile::xboundlo(double fwhm) const { + return -1 * this->GaussianProfile::xboundhi(fwhm); } - -double GaussianProfile::xboundhi(double fwhm) const -{ - double rv = (fwhm <= 0.0) ? 0.0 : (mhalfboundrel * fwhm); - return rv; +double GaussianProfile::xboundhi(double fwhm) const { + double rv = (fwhm <= 0.0) ? 0.0 : (mhalfboundrel * fwhm); + return rv; } - -void GaussianProfile::setPrecision(double eps) -{ - // correct any settings below DOUBLE_EPS - double eps1 = max(eps, DOUBLE_EPS); - this->PeakProfile::setPrecision(eps1); - if (eps1 < 1.0) mhalfboundrel = sqrt(-log(eps1) / (4 * M_LN2)); - else mhalfboundrel = 0.0; +void GaussianProfile::setPrecision(double eps) { + // correct any settings below DOUBLE_EPS + double eps1 = max(eps, DOUBLE_EPS); + this->PeakProfile::setPrecision(eps1); + if (eps1 < 1.0) + mhalfboundrel = sqrt(-log(eps1) / (4 * M_LN2)); + else + mhalfboundrel = 0.0; } // Registration -------------------------------------------------------------- bool reg_GaussianProfile = GaussianProfile().registerThisType(); -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/GaussianProfile.hpp b/src/diffpy/srreal/GaussianProfile.hpp index 21b65b65..f5a777e1 100644 --- a/src/diffpy/srreal/GaussianProfile.hpp +++ b/src/diffpy/srreal/GaussianProfile.hpp @@ -1,68 +1,64 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class GaussianProfile -- concrete implementation of the PeakProfile class. -* GaussianProfile is registered as "gaussian". -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class GaussianProfile -- concrete implementation of the PeakProfile class. + * GaussianProfile is registered as "gaussian". + * + *****************************************************************************/ #ifndef GAUSSIANPROFILE_HPP_INCLUDED #define GAUSSIANPROFILE_HPP_INCLUDED #include +#include + namespace diffpy { namespace srreal { -class GaussianProfile : public PeakProfile -{ - public: - - // constructors - GaussianProfile(); - PeakProfilePtr create() const; - PeakProfilePtr clone() const; - - // methods - const std::string& type() const; - double operator()(double x, double fwhm) const; - double xboundlo(double fwhm) const; - double xboundhi(double fwhm) const; - void setPrecision(double eps); - - protected: - - // data - double mhalfboundrel; - - private: - - // serialization - friend class boost::serialization::access; - - template - void serialize(Archive& ar, const unsigned int version) - { - using boost::serialization::base_object; - ar & base_object(*this); - ar & mhalfboundrel; - } - +class DLL_EXPORT GaussianProfile : public PeakProfile { + public: + // constructors + GaussianProfile(); + PeakProfilePtr create() const; + PeakProfilePtr clone() const; + + // methods + const std::string& type() const; + double operator()(double x, double fwhm) const; + double xboundlo(double fwhm) const; + double xboundhi(double fwhm) const; + void setPrecision(double eps); + + protected: + // data + double mhalfboundrel; + + private: + // serialization + friend class boost::serialization::access; + + template + void serialize(Archive& ar, const unsigned int version) { + using boost::serialization::base_object; + ar& base_object(*this); + ar & mhalfboundrel; + } }; -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/JeongPeakWidth.cpp b/src/diffpy/srreal/JeongPeakWidth.cpp index 7cd9679e..cf1874fc 100644 --- a/src/diffpy/srreal/JeongPeakWidth.cpp +++ b/src/diffpy/srreal/JeongPeakWidth.cpp @@ -1,22 +1,22 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 The Trustees of Columbia University -* in the City of New York. All rights reserved. -* -* File coded by: Christopher Farrow, Pavol Juhas -* -* See AUTHORS.txt for a list of people who contributed. -* See LICENSE_DANSE.txt for license information. -* -****************************************************************************** -* -* class DebyeWallerPeakWidth -- peak width model based on -* I.-K. Jeong, et al., Phys. Rev. B 67, 104301 (2003) -* http://link.aps.org/doi/10.1103/PhysRevB.67.104301 -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 The Trustees of Columbia University + * in the City of New York. All rights reserved. + * + * File coded by: Christopher Farrow, Pavol Juhas + * + * See AUTHORS.txt for a list of people who contributed. + * See LICENSE_DANSE.txt for license information. + * + ****************************************************************************** + * + * class DebyeWallerPeakWidth -- peak width model based on + * I.-K. Jeong, et al., Phys. Rev. B 67, 104301 (2003) + * http://link.aps.org/doi/10.1103/PhysRevB.67.104301 + * + *****************************************************************************/ #include #include @@ -29,135 +29,105 @@ using namespace std; // Constructors -------------------------------------------------------------- -JeongPeakWidth::JeongPeakWidth() : - mdelta1(0.0), mdelta2(0.0), mqbroad(0.0), mqbroad_seperable(0.0) -{ - this->registerDoubleAttribute("delta1", - this, &JeongPeakWidth::getDelta1, &JeongPeakWidth::setDelta1); - this->registerDoubleAttribute("delta2", - this, &JeongPeakWidth::getDelta2, &JeongPeakWidth::setDelta2); - this->registerDoubleAttribute("qbroad", - this, &JeongPeakWidth::getQbroad, &JeongPeakWidth::setQbroad); - this->registerDoubleAttribute("qbroad_seperable", - this, &JeongPeakWidth::getQbroad_seperable, &JeongPeakWidth::setQbroad_seperable); +JeongPeakWidth::JeongPeakWidth() + : mdelta1(0.0), mdelta2(0.0), mqbroad(0.0), mqbroad_seperable(0.0) { + this->registerDoubleAttribute("delta1", this, &JeongPeakWidth::getDelta1, + &JeongPeakWidth::setDelta1); + this->registerDoubleAttribute("delta2", this, &JeongPeakWidth::getDelta2, + &JeongPeakWidth::setDelta2); + this->registerDoubleAttribute("qbroad", this, &JeongPeakWidth::getQbroad, + &JeongPeakWidth::setQbroad); + this->registerDoubleAttribute("qbroad_seperable", this, + &JeongPeakWidth::getQbroad_seperable, + &JeongPeakWidth::setQbroad_seperable); } - -PeakWidthModelPtr JeongPeakWidth::create() const -{ - PeakWidthModelPtr rv(new JeongPeakWidth()); - return rv; +PeakWidthModelPtr JeongPeakWidth::create() const { + PeakWidthModelPtr rv(new JeongPeakWidth()); + return rv; } - -PeakWidthModelPtr JeongPeakWidth::clone() const -{ - PeakWidthModelPtr rv(new JeongPeakWidth(*this)); - return rv; +PeakWidthModelPtr JeongPeakWidth::clone() const { + PeakWidthModelPtr rv(new JeongPeakWidth(*this)); + return rv; } // Public Methods ------------------------------------------------------------ -const string& JeongPeakWidth::type() const -{ - static const string rv = "jeong"; - return rv; -} - - -double JeongPeakWidth::calculate(const BaseBondGenerator& bnds) const -{ - double r = bnds.distance(); - double corr = this->msdSharpeningRatio(r); - // avoid calculating square root of negative value - double fwhm = (corr <= 0) ? 0.0 : - (sqrt(corr) * this->DebyeWallerPeakWidth::calculate(bnds) + - pow(this->getQbroad_seperable()*r, 2)); - return fwhm; -} - - -double JeongPeakWidth::maxWidth(StructureAdapterPtr stru, - double rmin, double rmax) const -{ - double maxwidth0 = this->DebyeWallerPeakWidth::maxWidth(stru, rmin, rmax); - double maxmsdsharp = max( - this->msdSharpeningRatio(rmin), - this->msdSharpeningRatio(rmax)); - // if the sharpening factor is larger than 1 adjust the maximum width - double rv = maxwidth0 * sqrt(max(1.0, maxmsdsharp))+ pow(this->getQbroad_seperable()*rmax, 2); - return rv; +const string& JeongPeakWidth::type() const { + static const string rv = "jeong"; + return rv; } -const double& JeongPeakWidth::getDelta1() const -{ - return mdelta1; +double JeongPeakWidth::calculate(const BaseBondGenerator& bnds) const { + double r = bnds.distance(); + double corr = this->msdSharpeningRatio(r); + // avoid calculating square root of negative value + double fwhm = (corr <= 0) + ? 0.0 + : (sqrt(corr) * this->DebyeWallerPeakWidth::calculate(bnds) + + pow(this->getQbroad_seperable() * r, 2)); + return fwhm; } - -void JeongPeakWidth::setDelta1(double delta1) -{ - if (mdelta1 != delta1) mticker.click(); - mdelta1 = delta1; +double JeongPeakWidth::maxWidth(StructureAdapterPtr stru, double rmin, + double rmax) const { + double maxwidth0 = this->DebyeWallerPeakWidth::maxWidth(stru, rmin, rmax); + double maxmsdsharp = + max(this->msdSharpeningRatio(rmin), this->msdSharpeningRatio(rmax)); + // if the sharpening factor is larger than 1 adjust the maximum width + double rv = maxwidth0 * sqrt(max(1.0, maxmsdsharp)) + + pow(this->getQbroad_seperable() * rmax, 2); + return rv; } +const double& JeongPeakWidth::getDelta1() const { return mdelta1; } -const double& JeongPeakWidth::getDelta2() const -{ - return mdelta2; +void JeongPeakWidth::setDelta1(double delta1) { + if (mdelta1 != delta1) mticker.click(); + mdelta1 = delta1; } +const double& JeongPeakWidth::getDelta2() const { return mdelta2; } -void JeongPeakWidth::setDelta2(double delta2) -{ - if (mdelta2 != delta2) mticker.click(); - mdelta2 = delta2; +void JeongPeakWidth::setDelta2(double delta2) { + if (mdelta2 != delta2) mticker.click(); + mdelta2 = delta2; } +const double& JeongPeakWidth::getQbroad() const { return mqbroad; } -const double& JeongPeakWidth::getQbroad() const -{ - return mqbroad; +const double& JeongPeakWidth::getQbroad_seperable() const { + return mqbroad_seperable; } - -const double& JeongPeakWidth::getQbroad_seperable() const -{ - return mqbroad_seperable; +void JeongPeakWidth::setQbroad_seperable(double qbroad_seperable) { + if (mqbroad_seperable != qbroad_seperable) mticker.click(); + mqbroad_seperable = qbroad_seperable; } - -void JeongPeakWidth::setQbroad_seperable(double qbroad_seperable) -{ - if (mqbroad_seperable != qbroad_seperable) mticker.click(); - mqbroad_seperable = qbroad_seperable; -} - - -void JeongPeakWidth::setQbroad(double qbroad) -{ - if (mqbroad != qbroad) mticker.click(); - mqbroad = qbroad; +void JeongPeakWidth::setQbroad(double qbroad) { + if (mqbroad != qbroad) mticker.click(); + mqbroad = qbroad; } // Private Methods ----------------------------------------------------------- -double JeongPeakWidth::msdSharpeningRatio(const double& r) const -{ - using diffpy::mathutils::DOUBLE_EPS; - // avoid division by zero - if (r < DOUBLE_EPS) return 0.0; - double rv = 1.0 - this->getDelta1()/r - this->getDelta2()/pow(r, 2) + - pow(this->getQbroad()*r, 2); - return rv; +double JeongPeakWidth::msdSharpeningRatio(const double& r) const { + using diffpy::mathutils::DOUBLE_EPS; + // avoid division by zero + if (r < DOUBLE_EPS) return 0.0; + double rv = 1.0 - this->getDelta1() / r - this->getDelta2() / pow(r, 2) + + pow(this->getQbroad() * r, 2); + return rv; } // Registration -------------------------------------------------------------- bool reg_JeongPeakWidth = JeongPeakWidth().registerThisType(); -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/JeongPeakWidth.hpp b/src/diffpy/srreal/JeongPeakWidth.hpp index 1acd9a19..ff4c8a9d 100644 --- a/src/diffpy/srreal/JeongPeakWidth.hpp +++ b/src/diffpy/srreal/JeongPeakWidth.hpp @@ -1,87 +1,81 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 The Trustees of Columbia University -* in the City of New York. All rights reserved. -* -* File coded by: Christopher Farrow, Pavol Juhas -* -* See AUTHORS.txt for a list of people who contributed. -* See LICENSE_DANSE.txt for license information. -* -****************************************************************************** -* -* class DebyeWallerPeakWidth -- peak width model based on -* I.-K. Jeong, et al., Phys. Rev. B 67, 104301 (2003) -* http://link.aps.org/doi/10.1103/PhysRevB.67.104301 -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 The Trustees of Columbia University + * in the City of New York. All rights reserved. + * + * File coded by: Christopher Farrow, Pavol Juhas + * + * See AUTHORS.txt for a list of people who contributed. + * See LICENSE_DANSE.txt for license information. + * + ****************************************************************************** + * + * class DebyeWallerPeakWidth -- peak width model based on + * I.-K. Jeong, et al., Phys. Rev. B 67, 104301 (2003) + * http://link.aps.org/doi/10.1103/PhysRevB.67.104301 + * + *****************************************************************************/ #ifndef JEONGPEAKWIDTH_HPP_INCLUDED #define JEONGPEAKWIDTH_HPP_INCLUDED #include +#include + namespace diffpy { namespace srreal { - -class JeongPeakWidth : public DebyeWallerPeakWidth -{ - public: - - // constructors - JeongPeakWidth(); - virtual PeakWidthModelPtr create() const; - virtual PeakWidthModelPtr clone() const; - - // methods - virtual const std::string& type() const; - virtual double calculate(const BaseBondGenerator&) const; - virtual double maxWidth(StructureAdapterPtr, - double rmin, double rmax) const; - - // data access - const double& getDelta1() const; - void setDelta1(double); - const double& getDelta2() const; - void setDelta2(double); - const double& getQbroad() const; - void setQbroad(double); - const double& getQbroad_seperable() const; - void setQbroad_seperable(double); - - private: - - // data - double mdelta1; - double mdelta2; - double mqbroad; - double mqbroad_seperable; - - // methods - double msdSharpeningRatio(const double& r) const; - - // serialization - friend class boost::serialization::access; - - template - void serialize(Archive& ar, const unsigned int version) - { - using boost::serialization::base_object; - ar & base_object(*this); - ar & mdelta1; - ar & mdelta2; - ar & mqbroad; - ar & mqbroad_seperable; - } - +class DLL_EXPORT JeongPeakWidth : public DebyeWallerPeakWidth { + public: + // constructors + JeongPeakWidth(); + virtual PeakWidthModelPtr create() const; + virtual PeakWidthModelPtr clone() const; + + // methods + virtual const std::string& type() const; + virtual double calculate(const BaseBondGenerator&) const; + virtual double maxWidth(StructureAdapterPtr, double rmin, double rmax) const; + + // data access + const double& getDelta1() const; + void setDelta1(double); + const double& getDelta2() const; + void setDelta2(double); + const double& getQbroad() const; + void setQbroad(double); + const double& getQbroad_seperable() const; + void setQbroad_seperable(double); + + private: + // data + double mdelta1; + double mdelta2; + double mqbroad; + double mqbroad_seperable; + + // methods + double msdSharpeningRatio(const double& r) const; + + // serialization + friend class boost::serialization::access; + + template + void serialize(Archive& ar, const unsigned int version) { + using boost::serialization::base_object; + ar& base_object(*this); + ar & mdelta1; + ar & mdelta2; + ar & mqbroad; + ar & mqbroad_seperable; + } }; - -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/Lattice.cpp b/src/diffpy/srreal/Lattice.cpp index 6fd171d4..e8dd6769 100644 --- a/src/diffpy/srreal/Lattice.cpp +++ b/src/diffpy/srreal/Lattice.cpp @@ -1,21 +1,21 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class Lattice -- vector and matrix conversions between general and -* Cartesian coordinate systems -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class Lattice -- vector and matrix conversions between general and + * Cartesian coordinate systems + * + *****************************************************************************/ #include #include @@ -31,282 +31,247 @@ using namespace diffpy::srreal; // Constructors -------------------------------------------------------------- -Lattice::Lattice() -{ - mbaserot = R3::identity(); - this->setLatPar(1.0, 1.0, 1.0, 90.0, 90.0, 90.0); +Lattice::Lattice() { + mbaserot = R3::identity(); + this->setLatPar(1.0, 1.0, 1.0, 90.0, 90.0, 90.0); } - -Lattice::Lattice(double a0, double b0, double c0, - double alpha0, double beta0, double gamma0) -{ - mbaserot = R3::identity(); - this->setLatPar(a0, b0, c0, alpha0, beta0, gamma0); +Lattice::Lattice(double a0, double b0, double c0, double alpha0, double beta0, + double gamma0) { + mbaserot = R3::identity(); + this->setLatPar(a0, b0, c0, alpha0, beta0, gamma0); } // Public Methods ------------------------------------------------------------ -void Lattice::setLatPar(double a0, double b0, double c0, - double alpha0, double beta0, double gamma0) -{ - using diffpy::mathutils::cosd; - using diffpy::mathutils::sind; - using diffpy::mathutils::acosd; - ma = a0; - mb = b0; - mc = c0; - malpha = alpha0; - mbeta = beta0; - mgamma = gamma0; - mcosa = cosd(malpha); - msina = sind(malpha); - mcosb = cosd(mbeta); - msinb = sind(mbeta); - mcosg = cosd(mgamma); - msing = sind(mgamma); - // Vnorm is a volume of unit cell with a=b=c=1 - double Vnorm = this->volumeNormal(); - // reciprocal lattice - mar = msina / (ma * Vnorm); - mbr = msinb / (mb * Vnorm); - mcr = msing / (mc * Vnorm); - mcosar = (mcosb*mcosg - mcosa) / (msinb * msing); - mcosbr = (mcosa*mcosg - mcosb) / (msina * msing); - mcosgr = (mcosa*mcosb - mcosg) / (msina * msinb); - msinar = sqrt(1.0 - mcosar*mcosar); - msinbr = sqrt(1.0 - mcosbr*mcosbr); - msingr = sqrt(1.0 - mcosgr*mcosgr); - malphar = acosd(mcosar); - mbetar = acosd(mcosbr); - mgammar = acosd(mcosgr); - // metric tensor - this->updateMetrics(); - // standard cartesian coordinates of lattice vectors - this->updateStandardBase(); - // calculate unit cell rotation matrix baserot, base = stdbase * baserot - mbase = R3::prod(mstdbase, mbaserot); - mva = R3::row(mbase, 0); - mvb = R3::row(mbase, 1); - mvc = R3::row(mbase, 2); - mrecbase = R3::inverse(mbase); - mvar = R3::column(mrecbase, 0); - mvbr = R3::column(mrecbase, 1); - mvcr = R3::column(mrecbase, 2); - R3::row(mnormbase, 0) = R3::row(mbase, 0) * mar; - R3::row(mnormbase, 1) = R3::row(mbase, 1) * mbr; - R3::row(mnormbase, 2) = R3::row(mbase, 2) * mcr; - R3::column(mrecnormbase, 0) = R3::column(mrecbase, 0) / mar; - R3::column(mrecnormbase, 1) = R3::column(mrecbase, 1) / mbr; - R3::column(mrecnormbase, 2) = R3::column(mrecbase, 2) / mcr; +void Lattice::setLatPar(double a0, double b0, double c0, double alpha0, + double beta0, double gamma0) { + using diffpy::mathutils::acosd; + using diffpy::mathutils::cosd; + using diffpy::mathutils::sind; + ma = a0; + mb = b0; + mc = c0; + malpha = alpha0; + mbeta = beta0; + mgamma = gamma0; + mcosa = cosd(malpha); + msina = sind(malpha); + mcosb = cosd(mbeta); + msinb = sind(mbeta); + mcosg = cosd(mgamma); + msing = sind(mgamma); + // Vnorm is a volume of unit cell with a=b=c=1 + double Vnorm = this->volumeNormal(); + // reciprocal lattice + mar = msina / (ma * Vnorm); + mbr = msinb / (mb * Vnorm); + mcr = msing / (mc * Vnorm); + mcosar = (mcosb * mcosg - mcosa) / (msinb * msing); + mcosbr = (mcosa * mcosg - mcosb) / (msina * msing); + mcosgr = (mcosa * mcosb - mcosg) / (msina * msinb); + msinar = sqrt(1.0 - mcosar * mcosar); + msinbr = sqrt(1.0 - mcosbr * mcosbr); + msingr = sqrt(1.0 - mcosgr * mcosgr); + malphar = acosd(mcosar); + mbetar = acosd(mcosbr); + mgammar = acosd(mcosgr); + // metric tensor + this->updateMetrics(); + // standard cartesian coordinates of lattice vectors + this->updateStandardBase(); + // calculate unit cell rotation matrix baserot, base = stdbase * baserot + mbase = R3::prod(mstdbase, mbaserot); + mva = R3::row(mbase, 0); + mvb = R3::row(mbase, 1); + mvc = R3::row(mbase, 2); + mrecbase = R3::inverse(mbase); + mvar = R3::column(mrecbase, 0); + mvbr = R3::column(mrecbase, 1); + mvcr = R3::column(mrecbase, 2); + R3::row(mnormbase, 0) = R3::row(mbase, 0) * mar; + R3::row(mnormbase, 1) = R3::row(mbase, 1) * mbr; + R3::row(mnormbase, 2) = R3::row(mbase, 2) * mcr; + R3::column(mrecnormbase, 0) = R3::column(mrecbase, 0) / mar; + R3::column(mrecnormbase, 1) = R3::column(mrecbase, 1) / mbr; + R3::column(mrecnormbase, 2) = R3::column(mrecbase, 2) / mcr; } -void Lattice::setLatBase(const R3::Vector& va0, - const R3::Vector& vb0, - const R3::Vector& vc0) -{ - using diffpy::mathutils::acosd; - R3::row(mbase, 0) = va0; - R3::row(mbase, 1) = vb0; - R3::row(mbase, 2) = vc0; - double detbase = R3::determinant(mbase); - if (fabs(detbase) < 1.0e-8) - { - throw invalid_argument("base vectors are degenerate"); - } - else if (detbase < 0.0) - { - throw invalid_argument("base is not right-handed"); - } - mva = va0; - mvb = vb0; - mvc = vc0; - ma = R3::norm(mva); - mb = R3::norm(mvb); - mc = R3::norm(mvc); - mcosa = R3::dot(mvb, mvc) / (mb*mc); - mcosb = R3::dot(mva, mvc) / (ma*mc); - mcosg = R3::dot(mva, mvb) / (ma*mb); - msina = sqrt(1.0 - mcosa*mcosa); - msinb = sqrt(1.0 - mcosb*mcosb); - msing = sqrt(1.0 - mcosg*mcosg); - malpha = acosd(mcosa); - mbeta = acosd(mcosb); - mgamma = acosd(mcosg); - // Vnorm is a volume of unit cell with a=b=c=1 - double Vnorm = this->volumeNormal(); - // reciprocal lattice - mar = msina/(ma*Vnorm); - mbr = msinb/(mb*Vnorm); - mcr = msing/(mc*Vnorm); - mcosar = (mcosb*mcosg - mcosa)/(msinb*msing); - mcosbr = (mcosa*mcosg - mcosb)/(msina*msing); - mcosgr = (mcosa*mcosb - mcosg)/(msina*msinb); - msinar = sqrt(1.0 - mcosar*mcosar); - msinbr = sqrt(1.0 - mcosbr*mcosbr); - msingr = sqrt(1.0 - mcosgr*mcosgr); - malphar = acosd(mcosar); - mbetar = acosd(mcosbr); - mgammar = acosd(mcosgr); - // standard orientation of lattice vectors - this->updateStandardBase(); - // calculate unit cell rotation matrix, base = stdbase*baserot - mbaserot = R3::prod(R3::inverse(mstdbase), mbase); - mrecbase = R3::inverse(mbase); - mvar = R3::column(mrecbase, 0); - mvbr = R3::column(mrecbase, 1); - mvcr = R3::column(mrecbase, 2); - // bases normalized to unit reciprocal vectors - R3::row(mnormbase, 0) = R3::row(mbase, 0) * mar; - R3::row(mnormbase, 1) = R3::row(mbase, 1) * mbr; - R3::row(mnormbase, 2) = R3::row(mbase, 2) * mcr; - R3::column(mrecnormbase, 0) = R3::column(mrecbase, 0) / mar; - R3::column(mrecnormbase, 1) = R3::column(mrecbase, 1) / mbr; - R3::column(mrecnormbase, 2) = R3::column(mrecbase, 2) / mcr; - this->updateMetrics(); +void Lattice::setLatBase(const R3::Vector& va0, const R3::Vector& vb0, + const R3::Vector& vc0) { + using diffpy::mathutils::acosd; + R3::row(mbase, 0) = va0; + R3::row(mbase, 1) = vb0; + R3::row(mbase, 2) = vc0; + double detbase = R3::determinant(mbase); + if (fabs(detbase) < 1.0e-8) { + throw invalid_argument("base vectors are degenerate"); + } else if (detbase < 0.0) { + throw invalid_argument("base is not right-handed"); + } + mva = va0; + mvb = vb0; + mvc = vc0; + ma = R3::norm(mva); + mb = R3::norm(mvb); + mc = R3::norm(mvc); + mcosa = R3::dot(mvb, mvc) / (mb * mc); + mcosb = R3::dot(mva, mvc) / (ma * mc); + mcosg = R3::dot(mva, mvb) / (ma * mb); + msina = sqrt(1.0 - mcosa * mcosa); + msinb = sqrt(1.0 - mcosb * mcosb); + msing = sqrt(1.0 - mcosg * mcosg); + malpha = acosd(mcosa); + mbeta = acosd(mcosb); + mgamma = acosd(mcosg); + // Vnorm is a volume of unit cell with a=b=c=1 + double Vnorm = this->volumeNormal(); + // reciprocal lattice + mar = msina / (ma * Vnorm); + mbr = msinb / (mb * Vnorm); + mcr = msing / (mc * Vnorm); + mcosar = (mcosb * mcosg - mcosa) / (msinb * msing); + mcosbr = (mcosa * mcosg - mcosb) / (msina * msing); + mcosgr = (mcosa * mcosb - mcosg) / (msina * msinb); + msinar = sqrt(1.0 - mcosar * mcosar); + msinbr = sqrt(1.0 - mcosbr * mcosbr); + msingr = sqrt(1.0 - mcosgr * mcosgr); + malphar = acosd(mcosar); + mbetar = acosd(mcosbr); + mgammar = acosd(mcosgr); + // standard orientation of lattice vectors + this->updateStandardBase(); + // calculate unit cell rotation matrix, base = stdbase*baserot + mbaserot = R3::prod(R3::inverse(mstdbase), mbase); + mrecbase = R3::inverse(mbase); + mvar = R3::column(mrecbase, 0); + mvbr = R3::column(mrecbase, 1); + mvcr = R3::column(mrecbase, 2); + // bases normalized to unit reciprocal vectors + R3::row(mnormbase, 0) = R3::row(mbase, 0) * mar; + R3::row(mnormbase, 1) = R3::row(mbase, 1) * mbr; + R3::row(mnormbase, 2) = R3::row(mbase, 2) * mcr; + R3::column(mrecnormbase, 0) = R3::column(mrecbase, 0) / mar; + R3::column(mrecnormbase, 1) = R3::column(mrecbase, 1) / mbr; + R3::column(mrecnormbase, 2) = R3::column(mrecbase, 2) / mcr; + this->updateMetrics(); } - // volumeNormal is a volume of unit cell with a=b=c=1 -double Lattice::volumeNormal() const -{ - double rv = sqrt(1.0 + - 2.0 * mcosa * mcosb * mcosg - - mcosa * mcosa - mcosb * mcosb - mcosg * mcosg); - return rv; +double Lattice::volumeNormal() const { + double rv = sqrt(1.0 + 2.0 * mcosa * mcosb * mcosg - mcosa * mcosa - + mcosb * mcosb - mcosg * mcosg); + return rv; } - -double Lattice::volume() const -{ - double rv = this->volumeNormal() * this->a() * this->b() * this->c(); - return rv; +double Lattice::volume() const { + double rv = this->volumeNormal() * this->a() * this->b() * this->c(); + return rv; } - -const R3::Vector& Lattice::cartesian(const R3::Vector& lv) const -{ - static R3::Vector res; - res = R3::mxvecproduct(lv, mbase); - return res; +const R3::Vector& Lattice::cartesian(const R3::Vector& lv) const { + static R3::Vector res; + res = R3::mxvecproduct(lv, mbase); + return res; } -const R3::Vector& Lattice::fractional(const R3::Vector& cv) const -{ - static R3::Vector res; - res = R3::mxvecproduct(cv, mrecbase); - return res; +const R3::Vector& Lattice::fractional(const R3::Vector& cv) const { + static R3::Vector res; + res = R3::mxvecproduct(cv, mrecbase); + return res; } -const R3::Vector& Lattice::ucvCartesian(const R3::Vector& cv) const -{ - static R3::Vector res; - res = cartesian(ucvFractional(fractional(cv))); - return res; +const R3::Vector& Lattice::ucvCartesian(const R3::Vector& cv) const { + static R3::Vector res; + res = cartesian(ucvFractional(fractional(cv))); + return res; } -const R3::Vector& Lattice::ucvFractional(const R3::Vector& lv) const -{ - using mathutils::eps_eq; - static R3::Vector res; - res = lv - floor(lv); - if (eps_eq(res[0], 1.0)) res[0] = 0.0; - if (eps_eq(res[1], 1.0)) res[1] = 0.0; - if (eps_eq(res[2], 1.0)) res[2] = 0.0; - return res; +const R3::Vector& Lattice::ucvFractional(const R3::Vector& lv) const { + using mathutils::eps_eq; + static R3::Vector res; + res = lv - floor(lv); + if (eps_eq(res[0], 1.0)) res[0] = 0.0; + if (eps_eq(res[1], 1.0)) res[1] = 0.0; + if (eps_eq(res[2], 1.0)) res[2] = 0.0; + return res; } -const R3::Matrix& Lattice::cartesianMatrix(const R3::Matrix& Ml) const -{ - static R3::Matrix res0, res1; - res0 = prod(Ml, mnormbase); - res1 = prod(R3::trans(mnormbase), res0); - return res1; +const R3::Matrix& Lattice::cartesianMatrix(const R3::Matrix& Ml) const { + static R3::Matrix res0, res1; + res0 = prod(Ml, mnormbase); + res1 = prod(R3::trans(mnormbase), res0); + return res1; } -const R3::Matrix& Lattice::fractionalMatrix(const R3::Matrix& Mc) const -{ - static R3::Matrix res0, res1; - res0 = prod(Mc, mrecnormbase); - res1 = prod(R3::trans(mrecnormbase), res0); - return res1; +const R3::Matrix& Lattice::fractionalMatrix(const R3::Matrix& Mc) const { + static R3::Matrix res0, res1; + res0 = prod(Mc, mrecnormbase); + res1 = prod(R3::trans(mrecnormbase), res0); + return res1; } - -const R3::Vector& Lattice::ucMaxDiagonal() const -{ - static list ucdiagonals; - if (ucdiagonals.empty()) - { - ucdiagonals.push_back(R3::Vector(+1, +1, +1)); - ucdiagonals.push_back(R3::Vector(-1, +1, +1)); - ucdiagonals.push_back(R3::Vector(+1, -1, +1)); - ucdiagonals.push_back(R3::Vector(+1, +1, -1)); - } - double maxnorm = -1; - list::iterator ucd; - list::iterator maxucd = ucdiagonals.end(); - for (ucd = ucdiagonals.begin(); ucd != ucdiagonals.end(); ++ucd) - { - double normucd = this->norm(*ucd); - if (normucd > maxnorm) - { - maxnorm = normucd; - maxucd = ucd; - } +const R3::Vector& Lattice::ucMaxDiagonal() const { + static list ucdiagonals; + if (ucdiagonals.empty()) { + ucdiagonals.push_back(R3::Vector(+1, +1, +1)); + ucdiagonals.push_back(R3::Vector(-1, +1, +1)); + ucdiagonals.push_back(R3::Vector(+1, -1, +1)); + ucdiagonals.push_back(R3::Vector(+1, +1, -1)); + } + double maxnorm = -1; + list::iterator ucd; + list::iterator maxucd = ucdiagonals.end(); + for (ucd = ucdiagonals.begin(); ucd != ucdiagonals.end(); ++ucd) { + double normucd = this->norm(*ucd); + if (normucd > maxnorm) { + maxnorm = normucd; + maxucd = ucd; } - assert(maxucd != ucdiagonals.end()); - return *maxucd; + } + assert(maxucd != ucdiagonals.end()); + return *maxucd; } - -double Lattice::ucMaxDiagonalLength() const -{ - const R3::Vector& ucmd = this->ucMaxDiagonal(); - double res = this->norm(ucmd); - return res; +double Lattice::ucMaxDiagonalLength() const { + const R3::Vector& ucmd = this->ucMaxDiagonal(); + double res = this->norm(ucmd); + return res; } - -bool Lattice::operator==(const Lattice& other) const -{ - bool rv = (this->base() == other.base()); - return rv; +bool Lattice::operator==(const Lattice& other) const { + bool rv = (this->base() == other.base()); + return rv; } - -bool Lattice::operator!=(const Lattice& other) const -{ - return !(*this == other); +bool Lattice::operator!=(const Lattice& other) const { + return !(*this == other); } // Private Methods ----------------------------------------------------------- -void Lattice::updateMetrics() -{ - mmetrics(0,0) = ma * ma; - mmetrics(1,1) = mb * mb; - mmetrics(2,2) = mc * mc; - mmetrics(0,1) = mmetrics(1,0) = ma * mb * mcosg; - mmetrics(0,2) = mmetrics(2,0) = ma * mc * mcosb; - mmetrics(1,2) = mmetrics(2,1) = mb * mc * mcosa; +void Lattice::updateMetrics() { + mmetrics(0, 0) = ma * ma; + mmetrics(1, 1) = mb * mb; + mmetrics(2, 2) = mc * mc; + mmetrics(0, 1) = mmetrics(1, 0) = ma * mb * mcosg; + mmetrics(0, 2) = mmetrics(2, 0) = ma * mc * mcosb; + mmetrics(1, 2) = mmetrics(2, 1) = mb * mc * mcosa; } -void Lattice::updateStandardBase() -{ - // a - mstdbase(0,0) = 1.0 / mar; - mstdbase(1,0) = 0.0; - mstdbase(2,0) = 0.0; - // b - mstdbase(0,1) = -mcosgr / msingr / mar; - mstdbase(1,1) = mb * msina; - mstdbase(2,1) = 0.0; - // c - mstdbase(0,2) = mcosb * ma; - mstdbase(1,2) = mb * mcosa; - mstdbase(2,2) = mc; +void Lattice::updateStandardBase() { + // a + mstdbase(0, 0) = 1.0 / mar; + mstdbase(1, 0) = 0.0; + mstdbase(2, 0) = 0.0; + // b + mstdbase(0, 1) = -mcosgr / msingr / mar; + mstdbase(1, 1) = mb * msina; + mstdbase(2, 1) = 0.0; + // c + mstdbase(0, 2) = mcosb * ma; + mstdbase(1, 2) = mb * mcosa; + mstdbase(2, 2) = mc; } - // End of file diff --git a/src/diffpy/srreal/Lattice.hpp b/src/diffpy/srreal/Lattice.hpp index 4e9146c5..1c8c15f3 100644 --- a/src/diffpy/srreal/Lattice.hpp +++ b/src/diffpy/srreal/Lattice.hpp @@ -1,21 +1,21 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class Lattice -- vector and matrix conversions between general and -* Cartesian coordinate systems -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class Lattice -- vector and matrix conversions between general and + * Cartesian coordinate systems + * + *****************************************************************************/ #ifndef LATTICE_HPP_INCLUDED #define LATTICE_HPP_INCLUDED @@ -27,171 +27,162 @@ namespace diffpy { namespace srreal { -class Lattice -{ - public: - - // constructors - - Lattice(); - Lattice(double a, double b, double c, - double alpha, double beta, double gamma); - // create from base vectors - template - Lattice(const V& va, const V& vb, const V& vc); - - // methods - - // set lattice parameters - void setLatPar( - double a, double b, double c, - double alpha, double beta, double gamma ); - // set lattice base vectors - void setLatBase( - const R3::Vector& va, - const R3::Vector& vb, - const R3::Vector& vc); - template - void setLatBase(const V& va, const V& vb, const V& vc); - // direct lattice - double a() const; - double b() const; - double c() const; - double alpha() const; - double beta() const; - double gamma() const; - double cosalpha() const; - double cosbeta() const; - double cosgamma() const; - double sinalpha() const; - double sinbeta() const; - double singamma() const; - const R3::Vector& va() const; - const R3::Vector& vb() const; - const R3::Vector& vc() const; - double volumeNormal() const; - double volume() const; - // reciprocal lattice - double ar() const; - double br() const; - double cr() const; - double alphar() const; - double betar() const; - double gammar() const; - double cosalphar() const; - double cosbetar() const; - double cosgammar() const; - double sinalphar() const; - double sinbetar() const; - double singammar() const; - const R3::Vector& var() const; - const R3::Vector& vbr() const; - const R3::Vector& vcr() const; - // lattice related tensors - // metrics tensor - const R3::Matrix& metrics() const; - // matrix of base vectors, base() = stdbase() * baserot() - const R3::Matrix& base() const; - // standard base vectors - const R3::Matrix& stdbase() const; - // base rotation matrix - const R3::Matrix& baserot() const; - // inverse of base matrix - const R3::Matrix& recbase() const; - // vector operations using lattice coordinates - template - double dot(const V& u, const V& v) const; - template - double norm(const V& u) const; - template - double distance(const V& u, const V& v) const; - // angle in degrees - template - double angledeg(const V& u, const V& v) const; - // angle in radians - template - double anglerad(const V& u, const V& v) const; - // conversion of coordinates and tensors - const R3::Vector& cartesian(const R3::Vector& lv) const; - template - const R3::Vector& cartesian(const V& lv) const; - const R3::Vector& fractional(const R3::Vector& cv) const; - template - const R3::Vector& fractional(const V& cv) const; - const R3::Vector& ucvCartesian(const R3::Vector& cv) const; - template - const R3::Vector& ucvCartesian(const V& cv) const; - const R3::Vector& ucvFractional(const R3::Vector& lv) const; - template - const R3::Vector& ucvFractional(const V& lv) const; - const R3::Matrix& cartesianMatrix(const R3::Matrix& Ml) const; - const R3::Matrix& fractionalMatrix(const R3::Matrix& Mc) const; - // largest cell diagonal in fractional coordinates - const R3::Vector& ucMaxDiagonal() const; - double ucMaxDiagonalLength() const; - - // comparison - bool operator==(const Lattice&) const; - bool operator!=(const Lattice&) const; - - private: - - // methods - void updateMetrics(); - void updateStandardBase(); - - // data - direct lattice parameters - double ma, mb, mc; - double malpha, mbeta, mgamma; - double mcosa, mcosb, mcosg; - double msina, msinb, msing; - R3::Vector mva, mvb, mvc; - - // data - reciprocal lattice parameters - double mar, mbr, mcr; - double malphar, mbetar, mgammar; - double mcosar, mcosbr, mcosgr; - double msinar, msinbr, msingr; - R3::Vector mvar, mvbr, mvcr; - - // data - tensors - // mbase = mstdbase * mbaserot - R3::Matrix mmetrics; // metrics tensor - R3::Matrix mbase; // lattice base - R3::Matrix mstdbase; // standard unit cell base - R3::Matrix mbaserot; // base rotation matrix - R3::Matrix mrecbase; // inverse of base matrix - // base multiplied by magnitudes of reciprocal vectors - R3::Matrix mnormbase; - R3::Matrix mrecnormbase; // inverse of mnormbase - - // serialization - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - ar & ma & mb & mc; - ar & malpha & mbeta & mgamma; - ar & mcosa & mcosb & mcosg; - ar & msina & msinb & msing; - ar & mva & mvb & mvc; - ar & mar & mbr & mcr; - ar & malphar & mbetar & mgammar; - ar & mcosar & mcosbr & mcosgr; - ar & msinar & msinbr & msingr; - ar & mvar & mvbr & mvcr; - ar & mmetrics; - ar & mbase; - ar & mstdbase; - ar & mbaserot; - ar & mrecbase; - ar & mnormbase; - ar & mrecnormbase; - } - +class Lattice { + public: + // constructors + + Lattice(); + Lattice(double a, double b, double c, double alpha, double beta, + double gamma); + // create from base vectors + template + Lattice(const V& va, const V& vb, const V& vc); + + // methods + + // set lattice parameters + void setLatPar(double a, double b, double c, double alpha, double beta, + double gamma); + // set lattice base vectors + void setLatBase(const R3::Vector& va, const R3::Vector& vb, + const R3::Vector& vc); + template + void setLatBase(const V& va, const V& vb, const V& vc); + // direct lattice + double a() const; + double b() const; + double c() const; + double alpha() const; + double beta() const; + double gamma() const; + double cosalpha() const; + double cosbeta() const; + double cosgamma() const; + double sinalpha() const; + double sinbeta() const; + double singamma() const; + const R3::Vector& va() const; + const R3::Vector& vb() const; + const R3::Vector& vc() const; + double volumeNormal() const; + double volume() const; + // reciprocal lattice + double ar() const; + double br() const; + double cr() const; + double alphar() const; + double betar() const; + double gammar() const; + double cosalphar() const; + double cosbetar() const; + double cosgammar() const; + double sinalphar() const; + double sinbetar() const; + double singammar() const; + const R3::Vector& var() const; + const R3::Vector& vbr() const; + const R3::Vector& vcr() const; + // lattice related tensors + // metrics tensor + const R3::Matrix& metrics() const; + // matrix of base vectors, base() = stdbase() * baserot() + const R3::Matrix& base() const; + // standard base vectors + const R3::Matrix& stdbase() const; + // base rotation matrix + const R3::Matrix& baserot() const; + // inverse of base matrix + const R3::Matrix& recbase() const; + // vector operations using lattice coordinates + template + double dot(const V& u, const V& v) const; + template + double norm(const V& u) const; + template + double distance(const V& u, const V& v) const; + // angle in degrees + template + double angledeg(const V& u, const V& v) const; + // angle in radians + template + double anglerad(const V& u, const V& v) const; + // conversion of coordinates and tensors + const R3::Vector& cartesian(const R3::Vector& lv) const; + template + const R3::Vector& cartesian(const V& lv) const; + const R3::Vector& fractional(const R3::Vector& cv) const; + template + const R3::Vector& fractional(const V& cv) const; + const R3::Vector& ucvCartesian(const R3::Vector& cv) const; + template + const R3::Vector& ucvCartesian(const V& cv) const; + const R3::Vector& ucvFractional(const R3::Vector& lv) const; + template + const R3::Vector& ucvFractional(const V& lv) const; + const R3::Matrix& cartesianMatrix(const R3::Matrix& Ml) const; + const R3::Matrix& fractionalMatrix(const R3::Matrix& Mc) const; + // largest cell diagonal in fractional coordinates + const R3::Vector& ucMaxDiagonal() const; + double ucMaxDiagonalLength() const; + + // comparison + bool operator==(const Lattice&) const; + bool operator!=(const Lattice&) const; + + private: + // methods + void updateMetrics(); + void updateStandardBase(); + + // data - direct lattice parameters + double ma, mb, mc; + double malpha, mbeta, mgamma; + double mcosa, mcosb, mcosg; + double msina, msinb, msing; + R3::Vector mva, mvb, mvc; + + // data - reciprocal lattice parameters + double mar, mbr, mcr; + double malphar, mbetar, mgammar; + double mcosar, mcosbr, mcosgr; + double msinar, msinbr, msingr; + R3::Vector mvar, mvbr, mvcr; + + // data - tensors + // mbase = mstdbase * mbaserot + R3::Matrix mmetrics; // metrics tensor + R3::Matrix mbase; // lattice base + R3::Matrix mstdbase; // standard unit cell base + R3::Matrix mbaserot; // base rotation matrix + R3::Matrix mrecbase; // inverse of base matrix + // base multiplied by magnitudes of reciprocal vectors + R3::Matrix mnormbase; + R3::Matrix mrecnormbase; // inverse of mnormbase + + // serialization + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + ar & ma & mb & mc; + ar & malpha & mbeta & mgamma; + ar & mcosa & mcosb & mcosg; + ar & msina & msinb & msing; + ar & mva & mvb & mvc; + ar & mar & mbr & mcr; + ar & malphar & mbetar & mgammar; + ar & mcosar & mcosbr & mcosgr; + ar & msinar & msinbr & msingr; + ar & mvar & mvbr & mvcr; + ar & mmetrics; + ar & mbase; + ar & mstdbase; + ar & mbaserot; + ar & mrecbase; + ar & mnormbase; + ar & mrecnormbase; + } }; - ////////////////////////////////////////////////////////////////////////////// // Definitions ////////////////////////////////////////////////////////////////////////////// @@ -199,366 +190,170 @@ class Lattice // Template Constructor ------------------------------------------------------ template -Lattice::Lattice(const V& va0, const V& vb0, const V& vc0) -{ - this->setLatBase(va0, vb0, vc0); +Lattice::Lattice(const V& va0, const V& vb0, const V& vc0) { + this->setLatBase(va0, vb0, vc0); } // Template and Inline Methods ----------------------------------------------- template -void Lattice::setLatBase(const V& va0, const V& vb0, const V& vc0) -{ - R3::Vector va1(va0[0], va0[1], va0[2]); - R3::Vector vb1(vb0[0], vb0[1], vb0[2]); - R3::Vector vc1(vc0[0], vc0[1], vc0[2]); - this->setLatBase(va1, vb1, vc1); +void Lattice::setLatBase(const V& va0, const V& vb0, const V& vc0) { + R3::Vector va1(va0[0], va0[1], va0[2]); + R3::Vector vb1(vb0[0], vb0[1], vb0[2]); + R3::Vector vc1(vc0[0], vc0[1], vc0[2]); + this->setLatBase(va1, vb1, vc1); } // direct lattice -inline -double Lattice::a() const -{ - return ma; -} - - -inline -double Lattice::b() const -{ - return mb; -} - - -inline -double Lattice::c() const -{ - return mc; -} - - -inline -double Lattice::alpha() const -{ - return malpha; -} - - -inline -double Lattice::beta() const -{ - return mbeta; -} - - -inline -double Lattice::gamma() const -{ - return mgamma; -} - - -inline -double Lattice::cosalpha() const -{ - return mcosa; -} - +inline double Lattice::a() const { return ma; } -inline -double Lattice::cosbeta() const -{ - return mcosb; -} +inline double Lattice::b() const { return mb; } +inline double Lattice::c() const { return mc; } -inline -double Lattice::cosgamma() const -{ - return mcosg; -} - +inline double Lattice::alpha() const { return malpha; } -inline -double Lattice::sinalpha() const -{ - return msina; -} +inline double Lattice::beta() const { return mbeta; } +inline double Lattice::gamma() const { return mgamma; } -inline -double Lattice::sinbeta() const -{ - return msinb; -} +inline double Lattice::cosalpha() const { return mcosa; } +inline double Lattice::cosbeta() const { return mcosb; } -inline -double Lattice::singamma() const -{ - return msing; -} +inline double Lattice::cosgamma() const { return mcosg; } +inline double Lattice::sinalpha() const { return msina; } -inline -const R3::Vector& Lattice::va() const -{ - return mva; -} +inline double Lattice::sinbeta() const { return msinb; } +inline double Lattice::singamma() const { return msing; } -inline -const R3::Vector& Lattice::vb() const -{ - return mvb; -} +inline const R3::Vector& Lattice::va() const { return mva; } +inline const R3::Vector& Lattice::vb() const { return mvb; } -inline -const R3::Vector& Lattice::vc() const -{ - return mvc; -} +inline const R3::Vector& Lattice::vc() const { return mvc; } // reciprocal lattice -inline -double Lattice::ar() const -{ - return mar; -} +inline double Lattice::ar() const { return mar; } +inline double Lattice::br() const { return mbr; } -inline -double Lattice::br() const -{ - return mbr; -} +inline double Lattice::cr() const { return mcr; } +inline double Lattice::alphar() const { return malphar; } -inline -double Lattice::cr() const -{ - return mcr; -} - +inline double Lattice::betar() const { return mbetar; } -inline -double Lattice::alphar() const -{ - return malphar; -} +inline double Lattice::gammar() const { return mgammar; } +inline double Lattice::cosalphar() const { return mcosar; } -inline -double Lattice::betar() const -{ - return mbetar; -} +inline double Lattice::cosbetar() const { return mcosbr; } +inline double Lattice::cosgammar() const { return mcosgr; } -inline -double Lattice::gammar() const -{ - return mgammar; -} +inline double Lattice::sinalphar() const { return msinar; } +inline double Lattice::sinbetar() const { return msinbr; } -inline -double Lattice::cosalphar() const -{ - return mcosar; -} +inline double Lattice::singammar() const { return msingr; } +inline const R3::Vector& Lattice::var() const { return mvar; } -inline -double Lattice::cosbetar() const -{ - return mcosbr; -} +inline const R3::Vector& Lattice::vbr() const { return mvbr; } - -inline -double Lattice::cosgammar() const -{ - return mcosgr; -} - - -inline -double Lattice::sinalphar() const -{ - return msinar; -} - - -inline -double Lattice::sinbetar() const -{ - return msinbr; -} - - -inline -double Lattice::singammar() const -{ - return msingr; -} - - -inline -const R3::Vector& Lattice::var() const -{ - return mvar; -} - - -inline -const R3::Vector& Lattice::vbr() const -{ - return mvbr; -} - - -inline -const R3::Vector& Lattice::vcr() const -{ - return mvcr; -} +inline const R3::Vector& Lattice::vcr() const { return mvcr; } // lattice related tensors -inline -const R3::Matrix& Lattice::metrics() const -{ - return mmetrics; -} - - -inline -const R3::Matrix& Lattice::base() const -{ - return mbase; -} - - -inline -const R3::Matrix& Lattice::stdbase() const -{ - return mstdbase; -} +inline const R3::Matrix& Lattice::metrics() const { return mmetrics; } +inline const R3::Matrix& Lattice::base() const { return mbase; } -inline -const R3::Matrix& Lattice::baserot() const -{ - return mbaserot; -} +inline const R3::Matrix& Lattice::stdbase() const { return mstdbase; } +inline const R3::Matrix& Lattice::baserot() const { return mbaserot; } -inline -const R3::Matrix& Lattice::recbase() const -{ - return mrecbase; -} - +inline const R3::Matrix& Lattice::recbase() const { return mrecbase; } template -double Lattice::dot(const V& u, const V& v) const -{ - const R3::Matrix& M = this->metrics(); - double dp = - u[0] * v[0] * M(0,0) + - u[1] * v[1] * M(1,1) + - u[2] * v[2] * M(2,2) + - (u[0] * v[1] + u[1] * v[0]) * M(0,1) + - (u[0] * v[2] + u[2] * v[0]) * M(0,2) + - (u[2] * v[1] + u[1] * v[2]) * M(1,2); - return dp; +double Lattice::dot(const V& u, const V& v) const { + const R3::Matrix& M = this->metrics(); + double dp = u[0] * v[0] * M(0, 0) + u[1] * v[1] * M(1, 1) + + u[2] * v[2] * M(2, 2) + (u[0] * v[1] + u[1] * v[0]) * M(0, 1) + + (u[0] * v[2] + u[2] * v[0]) * M(0, 2) + + (u[2] * v[1] + u[1] * v[2]) * M(1, 2); + return dp; } - template -double Lattice::norm(const V& u) const -{ - return sqrt(this->dot(u, u)); +double Lattice::norm(const V& u) const { + return sqrt(this->dot(u, u)); } - template -double Lattice::distance(const V& u, const V& v) const -{ - static R3::Vector duv; - duv[0] = u[0] - v[0]; - duv[1] = u[1] - v[1]; - duv[2] = u[2] - v[2]; - return this->norm(duv); +double Lattice::distance(const V& u, const V& v) const { + static R3::Vector duv; + duv[0] = u[0] - v[0]; + duv[1] = u[1] - v[1]; + duv[2] = u[2] - v[2]; + return this->norm(duv); } - template -double Lattice::angledeg(const V& u, const V& v) const -{ - using diffpy::mathutils::acosd; - double ca = dot(u, v)/(norm(u) * norm(v)); - return acosd(ca); +double Lattice::angledeg(const V& u, const V& v) const { + using diffpy::mathutils::acosd; + double ca = dot(u, v) / (norm(u) * norm(v)); + return acosd(ca); } - template -double Lattice::anglerad(const V& u, const V& v) const -{ - double ca = dot(u, v)/(norm(u) * norm(v)); - return acos(ca); +double Lattice::anglerad(const V& u, const V& v) const { + double ca = dot(u, v) / (norm(u) * norm(v)); + return acos(ca); } - template -const R3::Vector& Lattice::cartesian(const V& lv) const -{ - static R3::Vector lvcopy; - lvcopy[0] = lv[0]; - lvcopy[1] = lv[1]; - lvcopy[2] = lv[2]; - return this->cartesian(lvcopy); +const R3::Vector& Lattice::cartesian(const V& lv) const { + static R3::Vector lvcopy; + lvcopy[0] = lv[0]; + lvcopy[1] = lv[1]; + lvcopy[2] = lv[2]; + return this->cartesian(lvcopy); } - template -const R3::Vector& Lattice::fractional(const V& cv) const -{ - static R3::Vector cvcopy; - cvcopy[0] = cv[0]; - cvcopy[1] = cv[1]; - cvcopy[2] = cv[2]; - return this->fractional(cvcopy); +const R3::Vector& Lattice::fractional(const V& cv) const { + static R3::Vector cvcopy; + cvcopy[0] = cv[0]; + cvcopy[1] = cv[1]; + cvcopy[2] = cv[2]; + return this->fractional(cvcopy); } - template -const R3::Vector& Lattice::ucvCartesian(const V& cv) const -{ - static R3::Vector cvcopy; - cvcopy[0] = cv[0]; - cvcopy[1] = cv[1]; - cvcopy[2] = cv[2]; - return this->ucvCartesian(cvcopy); +const R3::Vector& Lattice::ucvCartesian(const V& cv) const { + static R3::Vector cvcopy; + cvcopy[0] = cv[0]; + cvcopy[1] = cv[1]; + cvcopy[2] = cv[2]; + return this->ucvCartesian(cvcopy); } - template -const R3::Vector& Lattice::ucvFractional(const V& cv) const -{ - static R3::Vector cvcopy; - cvcopy[0] = cv[0]; - cvcopy[1] = cv[1]; - cvcopy[2] = cv[2]; - return ucvFractional(cvcopy); +const R3::Vector& Lattice::ucvFractional(const V& cv) const { + static R3::Vector cvcopy; + cvcopy[0] = cv[0]; + cvcopy[1] = cv[1]; + cvcopy[2] = cv[2]; + return ucvFractional(cvcopy); } - -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy #endif // LATTICE_HPP_INCLUDED diff --git a/src/diffpy/srreal/LinearBaseline.cpp b/src/diffpy/srreal/LinearBaseline.cpp index 861d82a3..8033c164 100644 --- a/src/diffpy/srreal/LinearBaseline.cpp +++ b/src/diffpy/srreal/LinearBaseline.cpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class LinearBaseline -- linear PDF baseline -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class LinearBaseline -- linear PDF baseline + * + *****************************************************************************/ #include #include @@ -26,61 +26,43 @@ namespace srreal { // Constructors -------------------------------------------------------------- -LinearBaseline::LinearBaseline() -{ - this->setSlope(0.0); - this->registerDoubleAttribute("slope", this, - &LinearBaseline::getSlope, - &LinearBaseline::setSlope); +LinearBaseline::LinearBaseline() { + this->setSlope(0.0); + this->registerDoubleAttribute("slope", this, &LinearBaseline::getSlope, + &LinearBaseline::setSlope); } - -PDFBaselinePtr LinearBaseline::create() const -{ - PDFBaselinePtr rv(new LinearBaseline()); - return rv; +PDFBaselinePtr LinearBaseline::create() const { + PDFBaselinePtr rv(new LinearBaseline()); + return rv; } - -PDFBaselinePtr LinearBaseline::clone() const -{ - PDFBaselinePtr rv(new LinearBaseline(*this)); - return rv; +PDFBaselinePtr LinearBaseline::clone() const { + PDFBaselinePtr rv(new LinearBaseline(*this)); + return rv; } // Public Methods ------------------------------------------------------------ -const string& LinearBaseline::type() const -{ - static string rv = "linear"; - return rv; -} - - -double LinearBaseline::operator()(const double& r) const -{ - return (this->getSlope() * r); +const string& LinearBaseline::type() const { + static string rv = "linear"; + return rv; } - -void LinearBaseline::setSlope(double sc) -{ - mslope = sc; +double LinearBaseline::operator()(const double& r) const { + return (this->getSlope() * r); } +void LinearBaseline::setSlope(double sc) { mslope = sc; } -const double& LinearBaseline::getSlope() const -{ - return mslope; -} - +const double& LinearBaseline::getSlope() const { return mslope; } // Registration -------------------------------------------------------------- bool reg_LinearBaseline = LinearBaseline().registerThisType(); -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/LinearBaseline.hpp b/src/diffpy/srreal/LinearBaseline.hpp index ab86aa7a..cd19a097 100644 --- a/src/diffpy/srreal/LinearBaseline.hpp +++ b/src/diffpy/srreal/LinearBaseline.hpp @@ -1,67 +1,65 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class LinearBaseline -- linear PDF baseline -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class LinearBaseline -- linear PDF baseline + * + *****************************************************************************/ #ifndef LINEARBASELINE_HPP_INCLUDED #define LINEARBASELINE_HPP_INCLUDED #include +#include + namespace diffpy { namespace srreal { /// @class LinearBaseline /// @brief linear PDF baseline -class LinearBaseline : public PDFBaseline -{ - public: - - // constructors - LinearBaseline(); - PDFBaselinePtr create() const; - PDFBaselinePtr clone() const; - - // methods - const std::string& type() const; - double operator()(const double& r) const; - void setSlope(double sc); - const double& getSlope() const; - - private: - - // data - double mslope; - - // serialization - friend class boost::serialization::access; - - template - void serialize(Archive& ar, const unsigned int version) - { - using boost::serialization::base_object; - ar & base_object(*this); - ar & mslope; - } +class DLL_EXPORT LinearBaseline : public PDFBaseline { + public: + // constructors + LinearBaseline(); + PDFBaselinePtr create() const; + PDFBaselinePtr clone() const; + + // methods + const std::string& type() const; + double operator()(const double& r) const; + void setSlope(double sc); + const double& getSlope() const; + + private: + // data + double mslope; + + // serialization + friend class boost::serialization::access; + + template + void serialize(Archive& ar, const unsigned int version) { + using boost::serialization::base_object; + ar& base_object(*this); + ar & mslope; + } }; // class LinearBaseline -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/NoMetaStructureAdapter.cpp b/src/diffpy/srreal/NoMetaStructureAdapter.cpp index 59f9b540..dcb803da 100644 --- a/src/diffpy/srreal/NoMetaStructureAdapter.cpp +++ b/src/diffpy/srreal/NoMetaStructureAdapter.cpp @@ -1,26 +1,26 @@ /***************************************************************************** -* -* libdiffpy 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. -* -****************************************************************************** -* -* class NoMetaStructureAdapter -- StructureAdapter proxy class that disables -* customPQConfig of another StructureAdapter instance. This may be used -* for preventing the adapter for diffpy.Structure class from applying -* scale, spdiameter and such metadata to the PDFCalculator. -* -* nometa -- factory function that returns a NoMetaStructureAdapter -* instance wrapped in StructureAdapterPtr -* -*****************************************************************************/ + * + * libdiffpy 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. + * + ****************************************************************************** + * + * class NoMetaStructureAdapter -- StructureAdapter proxy class that disables + * customPQConfig of another StructureAdapter instance. This may be used + * for preventing the adapter for diffpy.Structure class from applying + * scale, spdiameter and such metadata to the PDFCalculator. + * + * nometa -- factory function that returns a NoMetaStructureAdapter + * instance wrapped in StructureAdapterPtr + * + *****************************************************************************/ #include #include @@ -36,129 +36,97 @@ namespace srreal { // Constructor --------------------------------------------------------------- NoMetaStructureAdapter::NoMetaStructureAdapter( - StructureAdapterPtr srcstructure) -{ - boost::shared_ptr nmptr = - boost::dynamic_pointer_cast(srcstructure); - if (nmptr) srcstructure = nmptr->getSourceStructure(); - msrcstructure = srcstructure.get() ? - srcstructure : emptyStructureAdapter(); + StructureAdapterPtr srcstructure) { + boost::shared_ptr nmptr = + boost::dynamic_pointer_cast(srcstructure); + if (nmptr) srcstructure = nmptr->getSourceStructure(); + msrcstructure = srcstructure.get() ? srcstructure : emptyStructureAdapter(); } // Public Methods ------------------------------------------------------------ -StructureAdapterPtr NoMetaStructureAdapter::clone() const -{ - boost::shared_ptr rv(new NoMetaStructureAdapter); - if (msrcstructure) rv->msrcstructure = msrcstructure->clone(); - return rv; +StructureAdapterPtr NoMetaStructureAdapter::clone() const { + boost::shared_ptr rv(new NoMetaStructureAdapter); + if (msrcstructure) rv->msrcstructure = msrcstructure->clone(); + return rv; } - -BaseBondGeneratorPtr NoMetaStructureAdapter::createBondGenerator() const -{ - BaseBondGeneratorPtr bnds = msrcstructure->createBondGenerator(); - return bnds; +BaseBondGeneratorPtr NoMetaStructureAdapter::createBondGenerator() const { + BaseBondGeneratorPtr bnds = msrcstructure->createBondGenerator(); + return bnds; } - -int NoMetaStructureAdapter::countSites() const -{ - return msrcstructure->countSites(); +int NoMetaStructureAdapter::countSites() const { + return msrcstructure->countSites(); } - -double NoMetaStructureAdapter::numberDensity() const -{ - return msrcstructure->numberDensity(); +double NoMetaStructureAdapter::numberDensity() const { + return msrcstructure->numberDensity(); } - -const std::string& NoMetaStructureAdapter::siteAtomType(int idx) const -{ - return msrcstructure->siteAtomType(idx); +const std::string& NoMetaStructureAdapter::siteAtomType(int idx) const { + return msrcstructure->siteAtomType(idx); } - -const R3::Vector& NoMetaStructureAdapter::siteCartesianPosition( - int idx) const -{ - return msrcstructure->siteCartesianPosition(idx); +const R3::Vector& NoMetaStructureAdapter::siteCartesianPosition(int idx) const { + return msrcstructure->siteCartesianPosition(idx); } - -int NoMetaStructureAdapter::siteMultiplicity(int idx) const -{ - return msrcstructure->siteMultiplicity(idx); +int NoMetaStructureAdapter::siteMultiplicity(int idx) const { + return msrcstructure->siteMultiplicity(idx); } - -double NoMetaStructureAdapter::siteOccupancy(int idx) const -{ - return msrcstructure->siteOccupancy(idx); +double NoMetaStructureAdapter::siteOccupancy(int idx) const { + return msrcstructure->siteOccupancy(idx); } - -bool NoMetaStructureAdapter::siteAnisotropy(int idx) const -{ - return msrcstructure->siteAnisotropy(idx); +bool NoMetaStructureAdapter::siteAnisotropy(int idx) const { + return msrcstructure->siteAnisotropy(idx); } - -const R3::Matrix& NoMetaStructureAdapter::siteCartesianUij(int idx) const -{ - return msrcstructure->siteCartesianUij(idx); +const R3::Matrix& NoMetaStructureAdapter::siteCartesianUij(int idx) const { + return msrcstructure->siteCartesianUij(idx); } - -void NoMetaStructureAdapter::customPQConfig(PairQuantity* pq) const -{ - // disable customPQConfig of the wrapped PairQuantity +void NoMetaStructureAdapter::customPQConfig(PairQuantity* pq) const { + // disable customPQConfig of the wrapped PairQuantity } - -StructureDifference -NoMetaStructureAdapter::diff(StructureAdapterConstPtr other) const -{ - StructureDifference sd = this->StructureAdapter::diff(other); - if (sd.stru0 == sd.stru1) return sd; - typedef boost::shared_ptr PPtr; - PPtr pother = boost::dynamic_pointer_cast(other); - if (!pother) return sd; - sd = this->getSourceStructure()->diff(pother->getSourceStructure()); - assert(sd.stru0 == this->getSourceStructure()); - assert(sd.stru1 == pother->getSourceStructure()); - sd.stru0 = this->shared_from_this(); - sd.stru1 = other; - return sd; +StructureDifference NoMetaStructureAdapter::diff( + StructureAdapterConstPtr other) const { + StructureDifference sd = this->StructureAdapter::diff(other); + if (sd.stru0 == sd.stru1) return sd; + typedef boost::shared_ptr PPtr; + PPtr pother = boost::dynamic_pointer_cast(other); + if (!pother) return sd; + sd = this->getSourceStructure()->diff(pother->getSourceStructure()); + assert(sd.stru0 == this->getSourceStructure()); + assert(sd.stru1 == pother->getSourceStructure()); + sd.stru0 = this->shared_from_this(); + sd.stru1 = other; + return sd; } - -StructureAdapterPtr -NoMetaStructureAdapter::getSourceStructure() -{ - return msrcstructure; +StructureAdapterPtr NoMetaStructureAdapter::getSourceStructure() { + return msrcstructure; } - -StructureAdapterConstPtr -NoMetaStructureAdapter::getSourceStructure() const -{ - return msrcstructure; +StructureAdapterConstPtr NoMetaStructureAdapter::getSourceStructure() const { + return msrcstructure; } // Routines ------------------------------------------------------------------ -StructureAdapterPtr nometa(StructureAdapterPtr stru) -{ - StructureAdapterPtr rv = - boost::dynamic_pointer_cast(stru) ? stru : - StructureAdapterPtr(new NoMetaStructureAdapter(stru)); - return rv; +StructureAdapterPtr nometa(StructureAdapterPtr stru) { + StructureAdapterPtr rv = + boost::dynamic_pointer_cast(stru) + ? stru + : StructureAdapterPtr(new NoMetaStructureAdapter(stru)); + return rv; } -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/NoMetaStructureAdapter.hpp b/src/diffpy/srreal/NoMetaStructureAdapter.hpp index da454fcc..8aa08336 100644 --- a/src/diffpy/srreal/NoMetaStructureAdapter.hpp +++ b/src/diffpy/srreal/NoMetaStructureAdapter.hpp @@ -1,93 +1,88 @@ /***************************************************************************** -* -* libdiffpy 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. -* -****************************************************************************** -* -* class NoMetaStructureAdapter -- StructureAdapter proxy class that disables -* customPQConfig of another StructureAdapter instance. This may be used -* for preventing the adapter for diffpy.Structure class from applying -* scale, spdiameter and such metadata to the PDFCalculator. -* -* nometa -- factory function that returns a NoMetaStructureAdapter -* instance wrapped in StructureAdapterPtr -* -*****************************************************************************/ + * + * libdiffpy 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. + * + ****************************************************************************** + * + * class NoMetaStructureAdapter -- StructureAdapter proxy class that disables + * customPQConfig of another StructureAdapter instance. This may be used + * for preventing the adapter for diffpy.Structure class from applying + * scale, spdiameter and such metadata to the PDFCalculator. + * + * nometa -- factory function that returns a NoMetaStructureAdapter + * instance wrapped in StructureAdapterPtr + * + *****************************************************************************/ #ifndef NOMETASTRUCTUREADAPTER_HPP_INCLUDED #define NOMETASTRUCTUREADAPTER_HPP_INCLUDED #include +#include + namespace diffpy { namespace srreal { -class NoMetaStructureAdapter : public StructureAdapter -{ - public: - - // constructors - NoMetaStructureAdapter() { } - NoMetaStructureAdapter(StructureAdapterPtr); - - // methods - overloaded - virtual StructureAdapterPtr clone() const; - virtual BaseBondGeneratorPtr createBondGenerator() const; - virtual int countSites() const; - virtual double numberDensity() const; - virtual const std::string& siteAtomType(int idx) const; - virtual const R3::Vector& siteCartesianPosition(int idx) const; - virtual int siteMultiplicity(int idx) const; - virtual double siteOccupancy(int idx) const; - virtual bool siteAnisotropy(int idx) const; - virtual const R3::Matrix& siteCartesianUij(int idx) const; - virtual void customPQConfig(PairQuantity* pq) const; - virtual StructureDifference diff(StructureAdapterConstPtr) const; - - // methods - own - StructureAdapterPtr getSourceStructure(); - StructureAdapterConstPtr getSourceStructure() const; - - private: - - // data - StructureAdapterPtr msrcstructure; - - // serialization - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - ar & boost::serialization::base_object(*this); - ar & msrcstructure; - } - +class DLL_EXPORT NoMetaStructureAdapter : public StructureAdapter { + public: + // constructors + NoMetaStructureAdapter() {} + NoMetaStructureAdapter(StructureAdapterPtr); + + // methods - overloaded + virtual StructureAdapterPtr clone() const; + virtual BaseBondGeneratorPtr createBondGenerator() const; + virtual int countSites() const; + virtual double numberDensity() const; + virtual const std::string& siteAtomType(int idx) const; + virtual const R3::Vector& siteCartesianPosition(int idx) const; + virtual int siteMultiplicity(int idx) const; + virtual double siteOccupancy(int idx) const; + virtual bool siteAnisotropy(int idx) const; + virtual const R3::Matrix& siteCartesianUij(int idx) const; + virtual void customPQConfig(PairQuantity* pq) const; + virtual StructureDifference diff(StructureAdapterConstPtr) const; + + // methods - own + StructureAdapterPtr getSourceStructure(); + StructureAdapterConstPtr getSourceStructure() const; + + private: + // data + StructureAdapterPtr msrcstructure; + + // serialization + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + ar& boost::serialization::base_object(*this); + ar & msrcstructure; + } }; // Routines ------------------------------------------------------------------ /// create NoMetaStructureAdapter from an existing StructureAdapter -StructureAdapterPtr nometa(StructureAdapterPtr stru); - +DLL_EXPORT StructureAdapterPtr nometa(StructureAdapterPtr stru); /// create NoMetaStructureAdapter from an adaptable structure object template -StructureAdapterPtr nometa(const T& stru) -{ - StructureAdapterPtr bstru = convertToStructureAdapter(stru); - return nometa(bstru); +StructureAdapterPtr nometa(const T& stru) { + StructureAdapterPtr bstru = convertToStructureAdapter(stru); + return nometa(bstru); } -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/NoSymmetryStructureAdapter.cpp b/src/diffpy/srreal/NoSymmetryStructureAdapter.cpp index 7c080d7b..6df3e9cb 100644 --- a/src/diffpy/srreal/NoSymmetryStructureAdapter.cpp +++ b/src/diffpy/srreal/NoSymmetryStructureAdapter.cpp @@ -1,28 +1,28 @@ /***************************************************************************** -* -* libdiffpy 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. -* -****************************************************************************** -* -* class NoSymmetryStructureAdapter -- StructureAdapter class that removes -* any symmetry expansions (rotations or periodic translations) from -* another StructureAdapter instance. This can be used to use only -* the asymmetric unit from any adapter to crystal structure. -* -* class NoSymmetryBondGenerator -- bond generator -* -* nosymmetry -- factory function that creates a NoSymmetryStructureAdapter -* instance inside StructureAdapterPtr -* -*****************************************************************************/ + * + * libdiffpy 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. + * + ****************************************************************************** + * + * class NoSymmetryStructureAdapter -- StructureAdapter class that removes + * any symmetry expansions (rotations or periodic translations) from + * another StructureAdapter instance. This can be used to use only + * the asymmetric unit from any adapter to crystal structure. + * + * class NoSymmetryBondGenerator -- bond generator + * + * nosymmetry -- factory function that creates a NoSymmetryStructureAdapter + * instance inside StructureAdapterPtr + * + *****************************************************************************/ #include #include @@ -38,124 +38,94 @@ namespace srreal { // Constructor --------------------------------------------------------------- NoSymmetryStructureAdapter::NoSymmetryStructureAdapter( - StructureAdapterPtr srcstructure) -{ - boost::shared_ptr nmptr = - boost::dynamic_pointer_cast(srcstructure); - if (nmptr) srcstructure = nmptr->getSourceStructure(); - msrcstructure = srcstructure.get() ? - srcstructure : emptyStructureAdapter(); + StructureAdapterPtr srcstructure) { + boost::shared_ptr nmptr = + boost::dynamic_pointer_cast(srcstructure); + if (nmptr) srcstructure = nmptr->getSourceStructure(); + msrcstructure = srcstructure.get() ? srcstructure : emptyStructureAdapter(); } // Public Methods ------------------------------------------------------------ -StructureAdapterPtr NoSymmetryStructureAdapter::clone() const -{ - boost::shared_ptr - rv(new NoSymmetryStructureAdapter); - if (msrcstructure) rv->msrcstructure = msrcstructure->clone(); - return rv; +StructureAdapterPtr NoSymmetryStructureAdapter::clone() const { + boost::shared_ptr rv( + new NoSymmetryStructureAdapter); + if (msrcstructure) rv->msrcstructure = msrcstructure->clone(); + return rv; } - -BaseBondGeneratorPtr NoSymmetryStructureAdapter::createBondGenerator() const -{ - BaseBondGeneratorPtr bnds(new BaseBondGenerator(shared_from_this())); - return bnds; +BaseBondGeneratorPtr NoSymmetryStructureAdapter::createBondGenerator() const { + BaseBondGeneratorPtr bnds(new BaseBondGenerator(shared_from_this())); + return bnds; } - -int NoSymmetryStructureAdapter::countSites() const -{ - return msrcstructure->countSites(); +int NoSymmetryStructureAdapter::countSites() const { + return msrcstructure->countSites(); } +double NoSymmetryStructureAdapter::numberDensity() const { return 0.0; } -double NoSymmetryStructureAdapter::numberDensity() const -{ - return 0.0; +const std::string& NoSymmetryStructureAdapter::siteAtomType(int idx) const { + return msrcstructure->siteAtomType(idx); } - -const std::string& NoSymmetryStructureAdapter::siteAtomType(int idx) const -{ - return msrcstructure->siteAtomType(idx); -} - - const R3::Vector& NoSymmetryStructureAdapter::siteCartesianPosition( - int idx) const -{ - return msrcstructure->siteCartesianPosition(idx); + int idx) const { + return msrcstructure->siteCartesianPosition(idx); } - -double NoSymmetryStructureAdapter::siteOccupancy(int idx) const -{ - return msrcstructure->siteOccupancy(idx); +double NoSymmetryStructureAdapter::siteOccupancy(int idx) const { + return msrcstructure->siteOccupancy(idx); } - -bool NoSymmetryStructureAdapter::siteAnisotropy(int idx) const -{ - return msrcstructure->siteAnisotropy(idx); +bool NoSymmetryStructureAdapter::siteAnisotropy(int idx) const { + return msrcstructure->siteAnisotropy(idx); } - -const R3::Matrix& NoSymmetryStructureAdapter::siteCartesianUij(int idx) const -{ - return msrcstructure->siteCartesianUij(idx); +const R3::Matrix& NoSymmetryStructureAdapter::siteCartesianUij(int idx) const { + return msrcstructure->siteCartesianUij(idx); } - -void NoSymmetryStructureAdapter::customPQConfig(PairQuantity* pq) const -{ - msrcstructure->customPQConfig(pq); +void NoSymmetryStructureAdapter::customPQConfig(PairQuantity* pq) const { + msrcstructure->customPQConfig(pq); } - -StructureDifference -NoSymmetryStructureAdapter::diff(StructureAdapterConstPtr other) const -{ - StructureDifference sd = this->StructureAdapter::diff(other); - if (sd.stru0 == sd.stru1) return sd; - typedef boost::shared_ptr PPtr; - PPtr pother = boost::dynamic_pointer_cast(other); - if (!pother) return sd; - sd = this->getSourceStructure()->diff(pother->getSourceStructure()); - assert(sd.stru0 == this->getSourceStructure()); - assert(sd.stru1 == pother->getSourceStructure()); - sd.stru0 = this->shared_from_this(); - sd.stru1 = other; - return sd; +StructureDifference NoSymmetryStructureAdapter::diff( + StructureAdapterConstPtr other) const { + StructureDifference sd = this->StructureAdapter::diff(other); + if (sd.stru0 == sd.stru1) return sd; + typedef boost::shared_ptr PPtr; + PPtr pother = boost::dynamic_pointer_cast(other); + if (!pother) return sd; + sd = this->getSourceStructure()->diff(pother->getSourceStructure()); + assert(sd.stru0 == this->getSourceStructure()); + assert(sd.stru1 == pother->getSourceStructure()); + sd.stru0 = this->shared_from_this(); + sd.stru1 = other; + return sd; } - -StructureAdapterPtr -NoSymmetryStructureAdapter::getSourceStructure() -{ - return msrcstructure; +StructureAdapterPtr NoSymmetryStructureAdapter::getSourceStructure() { + return msrcstructure; } - -StructureAdapterConstPtr -NoSymmetryStructureAdapter::getSourceStructure() const -{ - return msrcstructure; +StructureAdapterConstPtr NoSymmetryStructureAdapter::getSourceStructure() + const { + return msrcstructure; } // Routines ------------------------------------------------------------------ -StructureAdapterPtr nosymmetry(StructureAdapterPtr stru) -{ - StructureAdapterPtr rv = - boost::dynamic_pointer_cast(stru) ? stru : - StructureAdapterPtr(new NoSymmetryStructureAdapter(stru)); - return rv; +StructureAdapterPtr nosymmetry(StructureAdapterPtr stru) { + StructureAdapterPtr rv = + boost::dynamic_pointer_cast(stru) + ? stru + : StructureAdapterPtr(new NoSymmetryStructureAdapter(stru)); + return rv; } -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/NoSymmetryStructureAdapter.hpp b/src/diffpy/srreal/NoSymmetryStructureAdapter.hpp index 5d8d87c4..bd9526b0 100644 --- a/src/diffpy/srreal/NoSymmetryStructureAdapter.hpp +++ b/src/diffpy/srreal/NoSymmetryStructureAdapter.hpp @@ -1,95 +1,90 @@ /***************************************************************************** -* -* libdiffpy 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. -* -****************************************************************************** -* -* class NoSymmetryStructureAdapter -- StructureAdapter class that removes -* any symmetry expansions (rotations or periodic translations) from -* another StructureAdapter instance. This can be used to use only -* the asymmetric unit from any adapter to crystal structure. -* -* class NoSymmetryBondGenerator -- bond generator -* -* nosymmetry -- factory function that creates a NoSymmetryStructureAdapter -* instance inside StructureAdapterPtr -* -*****************************************************************************/ + * + * libdiffpy 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. + * + ****************************************************************************** + * + * class NoSymmetryStructureAdapter -- StructureAdapter class that removes + * any symmetry expansions (rotations or periodic translations) from + * another StructureAdapter instance. This can be used to use only + * the asymmetric unit from any adapter to crystal structure. + * + * class NoSymmetryBondGenerator -- bond generator + * + * nosymmetry -- factory function that creates a NoSymmetryStructureAdapter + * instance inside StructureAdapterPtr + * + *****************************************************************************/ #ifndef NOSYMMETRYSTRUCTUREADAPTER_HPP_INCLUDED #define NOSYMMETRYSTRUCTUREADAPTER_HPP_INCLUDED #include +#include + namespace diffpy { namespace srreal { -class NoSymmetryStructureAdapter : public StructureAdapter -{ - public: - - // constructors - NoSymmetryStructureAdapter() { } - NoSymmetryStructureAdapter(StructureAdapterPtr); - - // methods - overloaded - virtual StructureAdapterPtr clone() const; - virtual BaseBondGeneratorPtr createBondGenerator() const; - virtual int countSites() const; - virtual double numberDensity() const; - virtual const std::string& siteAtomType(int idx) const; - virtual const R3::Vector& siteCartesianPosition(int idx) const; - // reusing base-class StructureAdapter::siteMultiplicity() - virtual double siteOccupancy(int idx) const; - virtual bool siteAnisotropy(int idx) const; - virtual const R3::Matrix& siteCartesianUij(int idx) const; - virtual void customPQConfig(PairQuantity* pq) const; - virtual StructureDifference diff(StructureAdapterConstPtr) const; - - // methods - own - StructureAdapterPtr getSourceStructure(); - StructureAdapterConstPtr getSourceStructure() const; - - private: - - // data - StructureAdapterPtr msrcstructure; - - // serialization - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - ar & boost::serialization::base_object(*this); - ar & msrcstructure; - } - +class DLL_EXPORT NoSymmetryStructureAdapter : public StructureAdapter { + public: + // constructors + NoSymmetryStructureAdapter() {} + NoSymmetryStructureAdapter(StructureAdapterPtr); + + // methods - overloaded + virtual StructureAdapterPtr clone() const; + virtual BaseBondGeneratorPtr createBondGenerator() const; + virtual int countSites() const; + virtual double numberDensity() const; + virtual const std::string& siteAtomType(int idx) const; + virtual const R3::Vector& siteCartesianPosition(int idx) const; + // reusing base-class StructureAdapter::siteMultiplicity() + virtual double siteOccupancy(int idx) const; + virtual bool siteAnisotropy(int idx) const; + virtual const R3::Matrix& siteCartesianUij(int idx) const; + virtual void customPQConfig(PairQuantity* pq) const; + virtual StructureDifference diff(StructureAdapterConstPtr) const; + + // methods - own + StructureAdapterPtr getSourceStructure(); + StructureAdapterConstPtr getSourceStructure() const; + + private: + // data + StructureAdapterPtr msrcstructure; + + // serialization + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + ar& boost::serialization::base_object(*this); + ar & msrcstructure; + } }; // Routines ------------------------------------------------------------------ /// create NoSymmetryStructureAdapter from an existing StructureAdapter -StructureAdapterPtr nosymmetry(StructureAdapterPtr stru); - +DLL_EXPORT StructureAdapterPtr nosymmetry(StructureAdapterPtr stru); /// create NoSymmetryStructureAdapter from an adaptable structure object template -StructureAdapterPtr nosymmetry(const T& stru) -{ - StructureAdapterPtr bstru = convertToStructureAdapter(stru); - return nosymmetry(bstru); +StructureAdapterPtr nosymmetry(const T& stru) { + StructureAdapterPtr bstru = convertToStructureAdapter(stru); + return nosymmetry(bstru); } -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/ObjCrystStructureAdapter.cpp b/src/diffpy/srreal/ObjCrystStructureAdapter.cpp index f74395ee..51a1f8b9 100644 --- a/src/diffpy/srreal/ObjCrystStructureAdapter.cpp +++ b/src/diffpy/srreal/ObjCrystStructureAdapter.cpp @@ -1,22 +1,22 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 The Trustees of Columbia University -* in the City of New York. All rights reserved. -* -* File coded by: Chris Farrow -* -* See AUTHORS.txt for a list of people who contributed. -* See LICENSE_DANSE.txt for license information. -* -****************************************************************************** -* -* StructureAdapterPtr createStructureAdapter(const ObjCryst::Crystal&) -* StructureAdapterPtr createStructureAdapter(const ObjCryst::Molecule&) -* -- structure adapter factories for ObjCryst objects. -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 The Trustees of Columbia University + * in the City of New York. All rights reserved. + * + * File coded by: Chris Farrow + * + * See AUTHORS.txt for a list of people who contributed. + * See LICENSE_DANSE.txt for license information. + * + ****************************************************************************** + * + * StructureAdapterPtr createStructureAdapter(const ObjCryst::Crystal&) + * StructureAdapterPtr createStructureAdapter(const ObjCryst::Molecule&) + * -- structure adapter factories for ObjCryst objects. + * + *****************************************************************************/ #include #include @@ -39,168 +39,147 @@ namespace { // Utility functions --------------------------------------------------------- -R3::Matrix -getUij(const ObjCryst::ScatteringPower* sp) -{ - const double BtoU = 1.0 / (8 * M_PI * M_PI); - R3::Matrix Uij = R3::zeromatrix(); - if (sp->IsIsotropic()) - { - Uij(0,0) = Uij(1,1) = Uij(2,2) = sp->GetBiso() * BtoU; - } - else - { - Uij(0,0) = sp->GetBij(1,1) * BtoU; - Uij(1,1) = sp->GetBij(2,2) * BtoU; - Uij(2,2) = sp->GetBij(3,3) * BtoU; - Uij(0,1) = Uij(1,0) = sp->GetBij(1,2) * BtoU; - Uij(0,2) = Uij(2,0) = sp->GetBij(1,3) * BtoU; - Uij(1,2) = Uij(2,1) = sp->GetBij(2,3) * BtoU; - } - return Uij; +R3::Matrix getUij(const ObjCryst::ScatteringPower* sp) { + const double BtoU = 1.0 / (8 * M_PI * M_PI); + R3::Matrix Uij = R3::zeromatrix(); + if (sp->IsIsotropic()) { + Uij(0, 0) = Uij(1, 1) = Uij(2, 2) = sp->GetBiso() * BtoU; + } else { + Uij(0, 0) = sp->GetBij(1, 1) * BtoU; + Uij(1, 1) = sp->GetBij(2, 2) * BtoU; + Uij(2, 2) = sp->GetBij(3, 3) * BtoU; + Uij(0, 1) = Uij(1, 0) = sp->GetBij(1, 2) * BtoU; + Uij(0, 2) = Uij(2, 0) = sp->GetBij(1, 3) * BtoU; + Uij(1, 2) = Uij(2, 1) = sp->GetBij(2, 3) * BtoU; + } + return Uij; } - -CrystalStructureAdapter::SymOpVector -fetchSymmetryOperations(const ObjCryst::SpaceGroup& spacegroup) -{ - CrystalStructureAdapter::SymOpVector rv; - const int nbsym = spacegroup.GetNbSymmetrics(); - rv.resize(nbsym); - const vector& sgsymops = - spacegroup.GetSymmetryOperations(); - // copy convert the ObjCryst symmetry operations - int last = sgsymops.size(); - assert(last <= nbsym); - for (int i = 0; i != last; ++i) - { - CrystalStructureAdapter::SymOpVector::value_type& op = rv[i]; - copy(sgsymops[i].mx, sgsymops[i].mx + 9, op.R.data().begin()); - copy(sgsymops[i].tr, sgsymops[i].tr + 3, op.t.data().begin()); +CrystalStructureAdapter::SymOpVector fetchSymmetryOperations( + const ObjCryst::SpaceGroup& spacegroup) { + CrystalStructureAdapter::SymOpVector rv; + const int nbsym = spacegroup.GetNbSymmetrics(); + rv.resize(nbsym); + const vector& sgsymops = + spacegroup.GetSymmetryOperations(); + // copy convert the ObjCryst symmetry operations + int last = sgsymops.size(); + assert(last <= nbsym); + for (int i = 0; i != last; ++i) { + CrystalStructureAdapter::SymOpVector::value_type& op = rv[i]; + copy(sgsymops[i].mx, sgsymops[i].mx + 9, op.R.data().begin()); + copy(sgsymops[i].tr, sgsymops[i].tr + 3, op.t.data().begin()); + } + // apply all origin translations + const vector& sgtrans = + spacegroup.GetTranslationVectors(); + const int nbtran = spacegroup.GetNbTranslationVectors(); + assert(int(sgtrans.size()) == nbtran); + assert(nbtran * last <= nbsym); + for (int nt = 0; nt < nbtran; ++nt) { + const double* pt = sgtrans[nt].tr; + R3::Vector sgt(pt[0], pt[1], pt[2]); + for (int i = 0; i < last; ++i) { + int k = i + nt * last; + assert(k < nbsym); + rv[k] = rv[i]; + rv[k].t += sgt; } - // apply all origin translations - const vector& sgtrans = - spacegroup.GetTranslationVectors(); - const int nbtran = spacegroup.GetNbTranslationVectors(); - assert(int(sgtrans.size()) == nbtran); - assert(nbtran * last <= nbsym); - for (int nt = 0; nt < nbtran; ++nt) - { - const double* pt = sgtrans[nt].tr; - R3::Vector sgt(pt[0], pt[1], pt[2]); - for (int i = 0; i < last; ++i) - { - int k = i + nt * last; - assert(k < nbsym); - rv[k] = rv[i]; - rv[k].t += sgt; - } + } + last = sgsymops.size() * nbtran; + // apply the inversion center if necessary + if (last < nbsym) { + assert(spacegroup.IsCentrosymmetric()); + assert(nbsym == 2 * last); + CrystVector_REAL xyzinv = spacegroup.GetInversionCenter(); + // tinv is the overall translation associated with inversion center. + // it is double the inversion center position. + R3::Vector tinv(xyzinv(0), xyzinv(1), xyzinv(2)); + tinv *= 2.0; + // now apply the inversion center here + for (int i = 0, j = last; i < last; ++i, ++j) { + rv[j].R = -1 * rv[i].R; + rv[j].t = tinv - rv[i].t; } - last = sgsymops.size() * nbtran; - // apply the inversion center if necessary - if (last < nbsym) - { - assert(spacegroup.IsCentrosymmetric()); - assert(nbsym == 2 * last); - CrystVector_REAL xyzinv = spacegroup.GetInversionCenter(); - // tinv is the overall translation associated with inversion center. - // it is double the inversion center position. - R3::Vector tinv(xyzinv(0), xyzinv(1), xyzinv(2)); - tinv *= 2.0; - // now apply the inversion center here - for (int i = 0, j = last; i < last; ++i, ++j) - { - rv[j].R = -1 * rv[i].R; - rv[j].t = tinv - rv[i].t; - } - last *= 2; - } - assert(nbsym == last); - return rv; + last *= 2; + } + assert(nbsym == last); + return rv; } -} // namespace +} // namespace ////////////////////////////////////////////////////////////////////////////// // StructureAdapter factory for ObjCryst::Crystal ////////////////////////////////////////////////////////////////////////////// -StructureAdapterPtr -createStructureAdapter(const ObjCryst::Crystal& cryst) -{ - const double radtodeg = 180 / M_PI; - CrystalStructureAdapterPtr adpt(new CrystalStructureAdapter); - adpt->setLatPar( - cryst.GetLatticePar(0), - cryst.GetLatticePar(1), - cryst.GetLatticePar(2), - radtodeg * cryst.GetLatticePar(3), - radtodeg * cryst.GetLatticePar(4), - radtodeg * cryst.GetLatticePar(5)); - // find out number of scatterers in the asymmetric unit - const ObjCryst::ScatteringComponentList& scl = - cryst.GetScatteringComponentList(); - size_t nbComponent = scl.GetNbComponent(); - adpt->reserve(nbComponent); - Atom ai; - const Lattice& L = adpt->getLattice(); - for (size_t i = 0; i < nbComponent; ++i) - { - const ObjCryst::ScatteringComponent& sc = scl(i); - const ObjCryst::ScatteringPower* sp = sc.mpScattPow; - // Skip over this if it is a dummy atom. A dummy atom has no - // mpScattPow, and therefore no type. It's just in a structure as a - // reference position. - if (sp == NULL) continue; - ai.occupancy = sc.mOccupancy; - ai.anisotropy = !(sp->IsIsotropic()); - ai.atomtype = sp->GetSymbol(); - R3::Vector xyz(sc.mX, sc.mY, sc.mZ); - ai.xyz_cartn = L.cartesian(xyz); - // Store Uij - R3::Matrix uijl = getUij(sp); - ai.uij_cartn = ai.anisotropy ? L.cartesianMatrix(uijl) : uijl; - adpt->append(ai); - } - const ObjCryst::SpaceGroup& spacegroup = cryst.GetSpaceGroup(); - CrystalStructureAdapter::SymOpVector symops = - fetchSymmetryOperations(spacegroup); - CrystalStructureAdapter::SymOpVector::const_iterator op; - for (op = symops.begin(); op != symops.end(); ++op) adpt->addSymOp(*op); - adpt->updateSymmetryPositions(); - return adpt; +StructureAdapterPtr createStructureAdapter(const ObjCryst::Crystal& cryst) { + const double radtodeg = 180 / M_PI; + CrystalStructureAdapterPtr adpt(new CrystalStructureAdapter); + adpt->setLatPar(cryst.GetLatticePar(0), cryst.GetLatticePar(1), + cryst.GetLatticePar(2), radtodeg * cryst.GetLatticePar(3), + radtodeg * cryst.GetLatticePar(4), + radtodeg * cryst.GetLatticePar(5)); + // find out number of scatterers in the asymmetric unit + const ObjCryst::ScatteringComponentList& scl = + cryst.GetScatteringComponentList(); + size_t nbComponent = scl.GetNbComponent(); + adpt->reserve(nbComponent); + Atom ai; + const Lattice& L = adpt->getLattice(); + for (size_t i = 0; i < nbComponent; ++i) { + const ObjCryst::ScatteringComponent& sc = scl(i); + const ObjCryst::ScatteringPower* sp = sc.mpScattPow; + // Skip over this if it is a dummy atom. A dummy atom has no + // mpScattPow, and therefore no type. It's just in a structure as a + // reference position. + if (sp == NULL) continue; + ai.occupancy = sc.mOccupancy; + ai.anisotropy = !(sp->IsIsotropic()); + ai.atomtype = sp->GetSymbol(); + R3::Vector xyz(sc.mX, sc.mY, sc.mZ); + ai.xyz_cartn = L.cartesian(xyz); + // Store Uij + R3::Matrix uijl = getUij(sp); + ai.uij_cartn = ai.anisotropy ? L.cartesianMatrix(uijl) : uijl; + adpt->append(ai); + } + const ObjCryst::SpaceGroup& spacegroup = cryst.GetSpaceGroup(); + CrystalStructureAdapter::SymOpVector symops = + fetchSymmetryOperations(spacegroup); + CrystalStructureAdapter::SymOpVector::const_iterator op; + for (op = symops.begin(); op != symops.end(); ++op) adpt->addSymOp(*op); + adpt->updateSymmetryPositions(); + return adpt; } ////////////////////////////////////////////////////////////////////////////// // StructureAdapter factory for ObjCryst::Molecule ////////////////////////////////////////////////////////////////////////////// -StructureAdapterPtr -createStructureAdapter(const ObjCryst::Molecule& molecule) -{ - AtomicStructureAdapterPtr adpt(new AtomicStructureAdapter); - size_t nbComponent = molecule.GetNbComponent(); - adpt->reserve(nbComponent); - Atom ai; - for (size_t i = 0; i < nbComponent; ++i) - { - const ObjCryst::MolAtom& atom = molecule.GetAtom(i); - if (atom.IsDummy()) continue; - ai.occupancy = atom.GetOccupancy(); - const ObjCryst::ScatteringPower* sp = &(atom.GetScatteringPower()); - ai.anisotropy = !(sp->IsIsotropic()); - ai.atomtype = sp->GetSymbol(); - ai.xyz_cartn[0] = atom.X(); - ai.xyz_cartn[1] = atom.Y(); - ai.xyz_cartn[2] = atom.Z(); - // Store Uij - ai.uij_cartn = getUij(sp); - adpt->append(ai); - } - return adpt; +StructureAdapterPtr createStructureAdapter(const ObjCryst::Molecule& molecule) { + AtomicStructureAdapterPtr adpt(new AtomicStructureAdapter); + size_t nbComponent = molecule.GetNbComponent(); + adpt->reserve(nbComponent); + Atom ai; + for (size_t i = 0; i < nbComponent; ++i) { + const ObjCryst::MolAtom& atom = molecule.GetAtom(i); + if (atom.IsDummy()) continue; + ai.occupancy = atom.GetOccupancy(); + const ObjCryst::ScatteringPower* sp = &(atom.GetScatteringPower()); + ai.anisotropy = !(sp->IsIsotropic()); + ai.atomtype = sp->GetSymbol(); + ai.xyz_cartn[0] = atom.X(); + ai.xyz_cartn[1] = atom.Y(); + ai.xyz_cartn[2] = atom.Z(); + // Store Uij + ai.uij_cartn = getUij(sp); + adpt->append(ai); + } + return adpt; } -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // End of file diff --git a/src/diffpy/srreal/ObjCrystStructureAdapter.hpp b/src/diffpy/srreal/ObjCrystStructureAdapter.hpp index 0cb21cc7..35ca5ee9 100644 --- a/src/diffpy/srreal/ObjCrystStructureAdapter.hpp +++ b/src/diffpy/srreal/ObjCrystStructureAdapter.hpp @@ -1,22 +1,22 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 The Trustees of Columbia University -* in the City of New York. All rights reserved. -* -* File coded by: Chris Farrow -* -* See AUTHORS.txt for a list of people who contributed. -* See LICENSE_DANSE.txt for license information. -* -****************************************************************************** -* -* StructureAdapterPtr createStructureAdapter(const ObjCryst::Crystal&) -* StructureAdapterPtr createStructureAdapter(const ObjCryst::Molecule&) -* -- structure adapter factories for ObjCryst objects. -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 The Trustees of Columbia University + * in the City of New York. All rights reserved. + * + * File coded by: Chris Farrow + * + * See AUTHORS.txt for a list of people who contributed. + * See LICENSE_DANSE.txt for license information. + * + ****************************************************************************** + * + * StructureAdapterPtr createStructureAdapter(const ObjCryst::Crystal&) + * StructureAdapterPtr createStructureAdapter(const ObjCryst::Molecule&) + * -- structure adapter factories for ObjCryst objects. + * + *****************************************************************************/ #ifndef OBJCRYSTSTRUCTUREADAPTER_HPP_INCLUDED #define OBJCRYSTSTRUCTUREADAPTER_HPP_INCLUDED @@ -24,6 +24,9 @@ #include #include #include + +#include + #include namespace diffpy { @@ -31,7 +34,7 @@ namespace srreal { // ObjCryst::Crystal is now adapted with CrystalStructureAdapter -StructureAdapterPtr +DLL_EXPORT StructureAdapterPtr createStructureAdapter(const ObjCryst::Crystal& cryst); // ObjCryst::Molecule can be adapted with AtomicStructureAdapter @@ -40,12 +43,11 @@ createStructureAdapter(const ObjCryst::Crystal& cryst); // as if in a cartesian cell. If this is not what is intended, pass the // molecule as a scattering component within an ObjCryst::Crystal. - -StructureAdapterPtr +DLL_EXPORT StructureAdapterPtr createStructureAdapter(const ObjCryst::Molecule& molecule); -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Required for argument-lookup visibility when instantiating the // convertToStructureAdapter template. diff --git a/src/diffpy/srreal/OverlapCalculator.cpp b/src/diffpy/srreal/OverlapCalculator.cpp index 008addcb..976ad8fb 100644 --- a/src/diffpy/srreal/OverlapCalculator.cpp +++ b/src/diffpy/srreal/OverlapCalculator.cpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2011 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. -* -****************************************************************************** -* -* class OverlapCalculator -- calculator of atom radii overlaps -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2011 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. + * + ****************************************************************************** + * + * class OverlapCalculator -- calculator of atom radii overlaps + * + *****************************************************************************/ #include @@ -35,533 +35,440 @@ namespace srreal { namespace { enum { - DISTANCE_OFFSET, - DIRECTION0_OFFSET, - DIRECTION1_OFFSET, - DIRECTION2_OFFSET, - SITE0_OFFSET, - SITE1_OFFSET, - CHUNK_SIZE, + DISTANCE_OFFSET, + DIRECTION0_OFFSET, + DIRECTION1_OFFSET, + DIRECTION2_OFFSET, + SITE0_OFFSET, + SITE1_OFFSET, + CHUNK_SIZE, }; - template -vector vectorconvert(const QuantityType& v) -{ - vector rv; - rv.reserve(v.size()); - QuantityType::const_iterator x = v.begin(); - for (; x != v.end(); ++x) rv.push_back(T(*x)); - return rv; +vector vectorconvert(const QuantityType& v) { + vector rv; + rv.reserve(v.size()); + QuantityType::const_iterator x = v.begin(); + for (; x != v.end(); ++x) rv.push_back(T(*x)); + return rv; } - -} // namespace +} // namespace // Constructor --------------------------------------------------------------- -OverlapCalculator::OverlapCalculator() -{ - mevaluator->setFlag(USEFULLSUM, true); - // default configuration - AtomRadiiTablePtr table(new ConstantRadiiTable); - this->setAtomRadiiTable(table); - this->cacheStructureData(); - // use very large rmax, it will be cropped by rmaxused - this->setRmax(100); - mneighborids_cached = false; - // attributes - this->registerDoubleAttribute("rmaxused", this, - &OverlapCalculator::getRmaxUsed); +OverlapCalculator::OverlapCalculator() { + mevaluator->setFlag(USEFULLSUM, true); + // default configuration + AtomRadiiTablePtr table(new ConstantRadiiTable); + this->setAtomRadiiTable(table); + this->cacheStructureData(); + // use very large rmax, it will be cropped by rmaxused + this->setRmax(100); + mneighborids_cached = false; + // attributes + this->registerDoubleAttribute("rmaxused", this, + &OverlapCalculator::getRmaxUsed); }; // Public Methods ------------------------------------------------------------ -QuantityType OverlapCalculator::overlaps() const -{ - int n = this->count(); - QuantityType rv; - rv.reserve(n); - for (int idx = 0; idx < n; ++idx) - { - double olp = this->suboverlap(idx); - if (olp <= 0.0) continue; - rv.push_back(olp); - } - return rv; -} - - -QuantityType OverlapCalculator::distances() const -{ - return this->subvector(DISTANCE_OFFSET, OVERLAPPING); -} - - -vector OverlapCalculator::directions() const -{ - int n = this->count(); - vector rv; - rv.reserve(n); - for (int index = 0; index < n; ++index) - { - if (this->suboverlap(index) <= 0.0) continue; - rv.push_back(this->subdirection(index)); - } - return rv; -} - - -SiteIndices OverlapCalculator::sites0() const -{ - QuantityType rv0 = this->subvector(SITE0_OFFSET, OVERLAPPING); - return vectorconvert(rv0); -} - - -SiteIndices OverlapCalculator::sites1() const -{ - QuantityType rv0 = this->subvector(SITE1_OFFSET, OVERLAPPING); - return vectorconvert(rv0); +QuantityType OverlapCalculator::overlaps() const { + int n = this->count(); + QuantityType rv; + rv.reserve(n); + for (int idx = 0; idx < n; ++idx) { + double olp = this->suboverlap(idx); + if (olp <= 0.0) continue; + rv.push_back(olp); + } + return rv; } - -vector OverlapCalculator::types0() const -{ - return siteIndicesToTypes(mstructure, this->sites0()); +QuantityType OverlapCalculator::distances() const { + return this->subvector(DISTANCE_OFFSET, OVERLAPPING); } - -vector OverlapCalculator::types1() const -{ - return siteIndicesToTypes(mstructure, this->sites1()); +vector OverlapCalculator::directions() const { + int n = this->count(); + vector rv; + rv.reserve(n); + for (int index = 0; index < n; ++index) { + if (this->suboverlap(index) <= 0.0) continue; + rv.push_back(this->subdirection(index)); + } + return rv; } - -QuantityType OverlapCalculator::siteSquareOverlaps() const -{ - int n = this->count(); - int cntsites = this->countSites(); - QuantityType rv(cntsites, 0.0); - for (int index = 0; index < n; ++index) - { - double olp = this->suboverlap(index); - if (olp <= 0.0) continue; - double sqoverlap = olp * olp; - int i = int(this->subvalue(SITE0_OFFSET, index)); - int j = int(this->subvalue(SITE1_OFFSET, index)); - rv[i] += sqoverlap * mstructure->siteOccupancy(j); - } - // overlaps are shared by 2 atoms - QuantityType::iterator xi; - for (xi = rv.begin(); xi != rv.end(); ++xi) *xi /= 2; - return rv; -} - - -double OverlapCalculator::totalSquareOverlap() const -{ - int cntsites = this->countSites(); - QuantityType sqoverlap = this->siteSquareOverlaps(); - double rv = 0.0; - for (int i = 0; i < cntsites; ++i) - { - rv += sqoverlap[i] * - mstructure->siteMultiplicity(i) * mstructure->siteOccupancy(i); - } - return rv; -} - - -double OverlapCalculator::meanSquareOverlap() const -{ - double totocc = mstructure->totalOccupancy(); - double rv = (totocc > 0) ? (this->totalSquareOverlap() / totocc) : 0.0; - return rv; +SiteIndices OverlapCalculator::sites0() const { + QuantityType rv0 = this->subvector(SITE0_OFFSET, OVERLAPPING); + return vectorconvert(rv0); } - -double OverlapCalculator::flipDiffTotal(int i, int j) const -{ - int cntsites = this->countSites(); - if (i < 0 || i >= cntsites || j < 0 || j >= cntsites) - { - const char* emsg = "Index out of range."; - throw invalid_argument(emsg); - } - bool sameradii = (i == j) || - (mstructure_cache.siteradii[i] == mstructure_cache.siteradii[j]); - if (sameradii) return 0.0; - // here we have to remove the overlap contributions for i and j - double rv = 0.0; - const list& ineighbors = this->getNeighborIds(i); - const list& jneighbors = this->getNeighborIds(j); - unordered_set allids; - allids.insert(ineighbors.begin(), ineighbors.end()); - allids.insert(jneighbors.begin(), jneighbors.end()); - unordered_set::const_iterator idx; - for (idx = allids.begin(); idx != allids.end(); ++idx) - { - int i1 = int(this->subvalue(SITE0_OFFSET, *idx)); - int j1 = int(this->subvalue(SITE1_OFFSET, *idx)); - double sqscale = - ((i1 == j1) ? 1 : 2) * - mstructure->siteOccupancy(i1) * mstructure->siteOccupancy(j1) * - mstructure->siteMultiplicity(i1) / 2; - double olp0 = this->suboverlap(*idx); - double olp1 = this->suboverlap(*idx, i, j); - rv -= sqscale * olp0 * olp0; - rv += sqscale * olp1 * olp1; - } - return rv; +SiteIndices OverlapCalculator::sites1() const { + QuantityType rv0 = this->subvector(SITE1_OFFSET, OVERLAPPING); + return vectorconvert(rv0); } - -double OverlapCalculator::flipDiffMean(int i, int j) const -{ - double totocc = mstructure->totalOccupancy(); - double rv = (totocc > 0) ? (this->flipDiffTotal(i, j) / totocc) : 0.0; - return rv; +vector OverlapCalculator::types0() const { + return siteIndicesToTypes(mstructure, this->sites0()); } - -vector OverlapCalculator::gradients() const -{ - using diffpy::mathutils::eps_gt; - int n = this->count(); - int cntsites = this->countSites(); - vector rv(cntsites, R3::Vector(0.0, 0.0, 0.0)); - R3::Vector gij; - for (int index = 0; index < n; ++index) - { - double olp = this->suboverlap(index); - if (olp <= 0.0) continue; - const double& dst = this->subvalue(DISTANCE_OFFSET, index); - assert(eps_gt(dst, 0.0)); - int j = int(this->subvalue(SITE1_OFFSET, index)); - gij = -2.0 * olp / dst * this->subdirection(index); - rv[j] += gij; - } - return rv; -} - - -unordered_set OverlapCalculator::getNeighborSites(int i) const -{ - unordered_set rv; - const list& ineighbors = this->getNeighborIds(i); - list::const_iterator idx; - for (idx = ineighbors.begin(); idx != ineighbors.end(); ++idx) - { - double olp = this->suboverlap(*idx); - if (olp <= 0.0) continue; - assert(i == int(this->subvalue(SITE0_OFFSET, *idx))); - int j1 = int(this->subvalue(SITE1_OFFSET, *idx)); - rv.insert(j1); - } - return rv; +vector OverlapCalculator::types1() const { + return siteIndicesToTypes(mstructure, this->sites1()); } - -QuantityType OverlapCalculator::coordinations() const -{ - int cntsites = this->countSites(); - QuantityType rv(cntsites, 0.0); - int n = this->count(); - for (int index = 0; index < n; ++index) - { - double olp = this->suboverlap(index); - if (olp <= 0.0) continue; - int j0 = int(this->subvalue(SITE0_OFFSET, index)); - int j1 = int(this->subvalue(SITE1_OFFSET, index)); - rv[j0] += mstructure->siteOccupancy(j1); - } - return rv; -} - - -unordered_map -OverlapCalculator::coordinationByTypes(int i) const -{ - unordered_map rv; - const list& ineighbors = this->getNeighborIds(i); - list::const_iterator idx; - for (idx = ineighbors.begin(); idx != ineighbors.end(); ++idx) - { - double olp = this->suboverlap(*idx); - if (olp <= 0.0) continue; - int j0 = int(this->subvalue(SITE0_OFFSET, *idx)); - int j1 = int(this->subvalue(SITE1_OFFSET, *idx)); - if (j0 == i) - { - const string& tp = mstructure->siteAtomType(j1); - rv[tp] += mstructure->siteOccupancy(j1); - } - else - { - assert(j1 == i); - const string& tp = mstructure->siteAtomType(j0); - rv[tp] += mstructure->siteOccupancy(j0) * +QuantityType OverlapCalculator::siteSquareOverlaps() const { + int n = this->count(); + int cntsites = this->countSites(); + QuantityType rv(cntsites, 0.0); + for (int index = 0; index < n; ++index) { + double olp = this->suboverlap(index); + if (olp <= 0.0) continue; + double sqoverlap = olp * olp; + int i = int(this->subvalue(SITE0_OFFSET, index)); + int j = int(this->subvalue(SITE1_OFFSET, index)); + rv[i] += sqoverlap * mstructure->siteOccupancy(j); + } + // overlaps are shared by 2 atoms + QuantityType::iterator xi; + for (xi = rv.begin(); xi != rv.end(); ++xi) *xi /= 2; + return rv; +} + +double OverlapCalculator::totalSquareOverlap() const { + int cntsites = this->countSites(); + QuantityType sqoverlap = this->siteSquareOverlaps(); + double rv = 0.0; + for (int i = 0; i < cntsites; ++i) { + rv += sqoverlap[i] * mstructure->siteMultiplicity(i) * + mstructure->siteOccupancy(i); + } + return rv; +} + +double OverlapCalculator::meanSquareOverlap() const { + double totocc = mstructure->totalOccupancy(); + double rv = (totocc > 0) ? (this->totalSquareOverlap() / totocc) : 0.0; + return rv; +} + +double OverlapCalculator::flipDiffTotal(int i, int j) const { + int cntsites = this->countSites(); + if (i < 0 || i >= cntsites || j < 0 || j >= cntsites) { + const char* emsg = "Index out of range."; + throw invalid_argument(emsg); + } + bool sameradii = (i == j) || (mstructure_cache.siteradii[i] == + mstructure_cache.siteradii[j]); + if (sameradii) return 0.0; + // here we have to remove the overlap contributions for i and j + double rv = 0.0; + const list& ineighbors = this->getNeighborIds(i); + const list& jneighbors = this->getNeighborIds(j); + unordered_set allids; + allids.insert(ineighbors.begin(), ineighbors.end()); + allids.insert(jneighbors.begin(), jneighbors.end()); + unordered_set::const_iterator idx; + for (idx = allids.begin(); idx != allids.end(); ++idx) { + int i1 = int(this->subvalue(SITE0_OFFSET, *idx)); + int j1 = int(this->subvalue(SITE1_OFFSET, *idx)); + double sqscale = ((i1 == j1) ? 1 : 2) * mstructure->siteOccupancy(i1) * + mstructure->siteOccupancy(j1) * + mstructure->siteMultiplicity(i1) / 2; + double olp0 = this->suboverlap(*idx); + double olp1 = this->suboverlap(*idx, i, j); + rv -= sqscale * olp0 * olp0; + rv += sqscale * olp1 * olp1; + } + return rv; +} + +double OverlapCalculator::flipDiffMean(int i, int j) const { + double totocc = mstructure->totalOccupancy(); + double rv = (totocc > 0) ? (this->flipDiffTotal(i, j) / totocc) : 0.0; + return rv; +} + +vector OverlapCalculator::gradients() const { + using diffpy::mathutils::eps_gt; + int n = this->count(); + int cntsites = this->countSites(); + vector rv(cntsites, R3::Vector(0.0, 0.0, 0.0)); + R3::Vector gij; + for (int index = 0; index < n; ++index) { + double olp = this->suboverlap(index); + if (olp <= 0.0) continue; + const double& dst = this->subvalue(DISTANCE_OFFSET, index); + assert(eps_gt(dst, 0.0)); + int j = int(this->subvalue(SITE1_OFFSET, index)); + gij = -2.0 * olp / dst * this->subdirection(index); + rv[j] += gij; + } + return rv; +} + +unordered_set OverlapCalculator::getNeighborSites(int i) const { + unordered_set rv; + const list& ineighbors = this->getNeighborIds(i); + list::const_iterator idx; + for (idx = ineighbors.begin(); idx != ineighbors.end(); ++idx) { + double olp = this->suboverlap(*idx); + if (olp <= 0.0) continue; + assert(i == int(this->subvalue(SITE0_OFFSET, *idx))); + int j1 = int(this->subvalue(SITE1_OFFSET, *idx)); + rv.insert(j1); + } + return rv; +} + +QuantityType OverlapCalculator::coordinations() const { + int cntsites = this->countSites(); + QuantityType rv(cntsites, 0.0); + int n = this->count(); + for (int index = 0; index < n; ++index) { + double olp = this->suboverlap(index); + if (olp <= 0.0) continue; + int j0 = int(this->subvalue(SITE0_OFFSET, index)); + int j1 = int(this->subvalue(SITE1_OFFSET, index)); + rv[j0] += mstructure->siteOccupancy(j1); + } + return rv; +} + +unordered_map OverlapCalculator::coordinationByTypes( + int i) const { + unordered_map rv; + const list& ineighbors = this->getNeighborIds(i); + list::const_iterator idx; + for (idx = ineighbors.begin(); idx != ineighbors.end(); ++idx) { + double olp = this->suboverlap(*idx); + if (olp <= 0.0) continue; + int j0 = int(this->subvalue(SITE0_OFFSET, *idx)); + int j1 = int(this->subvalue(SITE1_OFFSET, *idx)); + if (j0 == i) { + const string& tp = mstructure->siteAtomType(j1); + rv[tp] += mstructure->siteOccupancy(j1); + } else { + assert(j1 == i); + const string& tp = mstructure->siteAtomType(j0); + rv[tp] += mstructure->siteOccupancy(j0) * mstructure->siteMultiplicity(j0) / mstructure->siteMultiplicity(j1); - } } - return rv; -} - - -vector< unordered_set > OverlapCalculator::neighborhoods() const -{ - int cntsites = this->countSites(); - typedef unordered_set SiteSet; - typedef std::vector< boost::shared_ptr > SiteSetPointers; - SiteSetPointers rvptr(cntsites); - int n = this->count(); - for (int index = 0; index < n; ++index) - { - double olp = this->suboverlap(index); - if (olp <= 0.0) continue; - int j0 = int(this->subvalue(SITE0_OFFSET, index)); - int j1 = int(this->subvalue(SITE1_OFFSET, index)); - if (!rvptr[j0].get()) - { - rvptr[j0].reset(new SiteSet); - rvptr[j0]->insert(j0); - } - if (!rvptr[j1].get()) - { - rvptr[j0]->insert(j1); - rvptr[j1] = rvptr[j0]; - } - assert(rvptr[j0].get() && rvptr[j1].get()); - if (rvptr[j0].get() == rvptr[j1].get()) continue; - // here we need to unify the j0 and j1 sets - SiteSetPointers::value_type ss1 = rvptr[j1]; - SiteSet::const_iterator idx1 = ss1->begin(); - for (; idx1 != ss1->end(); ++idx1) - { - rvptr[j0]->insert(*idx1); - rvptr[*idx1] = rvptr[j0]; - } + } + return rv; +} + +vector > OverlapCalculator::neighborhoods() const { + int cntsites = this->countSites(); + typedef unordered_set SiteSet; + typedef std::vector > SiteSetPointers; + SiteSetPointers rvptr(cntsites); + int n = this->count(); + for (int index = 0; index < n; ++index) { + double olp = this->suboverlap(index); + if (olp <= 0.0) continue; + int j0 = int(this->subvalue(SITE0_OFFSET, index)); + int j1 = int(this->subvalue(SITE1_OFFSET, index)); + if (!rvptr[j0].get()) { + rvptr[j0].reset(new SiteSet); + rvptr[j0]->insert(j0); } - // helper function that initializes neighbor set at site i - auto initsiteset = [&](int i, int& counter) { - if (!rvptr[i]) { - rvptr[i].reset(new SiteSet(&i, &i + 1)); - ++counter; - } - }; - // count initialized items in rvptr - int cnt = count_if(rvptr.begin(), rvptr.end(), - [](SiteSetPointers::value_type& p) { return bool(p); }); - // create self-neighborhoods unless prohibited by mask - for (int j0 = 0; j0 < cntsites && cnt < cntsites; ++j0) - { - for (int j1 = j0; j1 < cntsites; ++j1) - { - if (rvptr[j0] && rvptr[j1]) continue; - if (!this->getPairMask(j0, j1)) continue; - initsiteset(j0, cnt); - initsiteset(j1, cnt); - } + if (!rvptr[j1].get()) { + rvptr[j0]->insert(j1); + rvptr[j1] = rvptr[j0]; } - unordered_set duplicate; - vector< unordered_set > rv; - SiteSetPointers::const_iterator ssp; - for (ssp = rvptr.begin(); ssp != rvptr.end(); ++ssp) - { - if (!ssp->get() || duplicate.count(ssp->get())) continue; - duplicate.insert(ssp->get()); - rv.push_back(**ssp); + assert(rvptr[j0].get() && rvptr[j1].get()); + if (rvptr[j0].get() == rvptr[j1].get()) continue; + // here we need to unify the j0 and j1 sets + SiteSetPointers::value_type ss1 = rvptr[j1]; + SiteSet::const_iterator idx1 = ss1->begin(); + for (; idx1 != ss1->end(); ++idx1) { + rvptr[j0]->insert(*idx1); + rvptr[*idx1] = rvptr[j0]; } - return rv; + } + // helper function that initializes neighbor set at site i + auto initsiteset = [&](int i, int& counter) { + if (!rvptr[i]) { + rvptr[i].reset(new SiteSet(&i, &i + 1)); + ++counter; + } + }; + // count initialized items in rvptr + int cnt = count_if(rvptr.begin(), rvptr.end(), + [](SiteSetPointers::value_type& p) { return bool(p); }); + // create self-neighborhoods unless prohibited by mask + for (int j0 = 0; j0 < cntsites && cnt < cntsites; ++j0) { + for (int j1 = j0; j1 < cntsites; ++j1) { + if (rvptr[j0] && rvptr[j1]) continue; + if (!this->getPairMask(j0, j1)) continue; + initsiteset(j0, cnt); + initsiteset(j1, cnt); + } + } + unordered_set duplicate; + vector > rv; + SiteSetPointers::const_iterator ssp; + for (ssp = rvptr.begin(); ssp != rvptr.end(); ++ssp) { + if (!ssp->get() || duplicate.count(ssp->get())) continue; + duplicate.insert(ssp->get()); + rv.push_back(**ssp); + } + return rv; } - -void OverlapCalculator::setAtomRadiiTable(AtomRadiiTablePtr table) -{ - ensureNonNull("AtomRadiiTable", table); - matomradiitable = table; +void OverlapCalculator::setAtomRadiiTable(AtomRadiiTablePtr table) { + ensureNonNull("AtomRadiiTable", table); + matomradiitable = table; } - -void OverlapCalculator::setAtomRadiiTableByType(const std::string& tp) -{ - matomradiitable = AtomRadiiTable::createByType(tp); +void OverlapCalculator::setAtomRadiiTableByType(const std::string& tp) { + matomradiitable = AtomRadiiTable::createByType(tp); } - -AtomRadiiTablePtr& OverlapCalculator::getAtomRadiiTable() -{ - return matomradiitable; +AtomRadiiTablePtr& OverlapCalculator::getAtomRadiiTable() { + return matomradiitable; } - -const AtomRadiiTablePtr& OverlapCalculator::getAtomRadiiTable() const -{ - return matomradiitable; +const AtomRadiiTablePtr& OverlapCalculator::getAtomRadiiTable() const { + return matomradiitable; } - -double OverlapCalculator::getRmaxUsed() const -{ - assert(this->countSites() == int(mstructure_cache.siteradii.size())); - double rv = min(this->getRmax(), mstructure_cache.maxseparation); - return rv; +double OverlapCalculator::getRmaxUsed() const { + assert(this->countSites() == int(mstructure_cache.siteradii.size())); + double rv = min(this->getRmax(), mstructure_cache.maxseparation); + return rv; } // Protected Methods --------------------------------------------------------- -void OverlapCalculator::resetValue() -{ - mvalue.clear(); - mneighborids.clear(); - mneighborids_cached = false; - this->cacheStructureData(); - this->PairQuantity::resetValue(); +void OverlapCalculator::resetValue() { + mvalue.clear(); + mneighborids.clear(); + mneighborids_cached = false; + this->cacheStructureData(); + this->PairQuantity::resetValue(); } - -void OverlapCalculator::configureBondGenerator(BaseBondGenerator& bnds) const -{ - bnds.setRmin(this->getRmin()); - bnds.setRmax(this->getRmaxUsed()); +void OverlapCalculator::configureBondGenerator(BaseBondGenerator& bnds) const { + bnds.setRmin(this->getRmin()); + bnds.setRmax(this->getRmaxUsed()); } - -void OverlapCalculator::addPairContribution( - const BaseBondGenerator& bnds, int summationscale) -{ - assert(summationscale == 1); - assert(bnds.distance() <= mstructure_cache.maxseparation); - const R3::Vector& r01 = bnds.r01(); - int baseidx = mvalue.size(); - mvalue.insert(mvalue.end(), CHUNK_SIZE, 0.0); - mvalue[baseidx + DISTANCE_OFFSET] = bnds.distance(); - mvalue[baseidx + DIRECTION0_OFFSET] = r01[0]; - mvalue[baseidx + DIRECTION1_OFFSET] = r01[1]; - mvalue[baseidx + DIRECTION2_OFFSET] = r01[2]; - mvalue[baseidx + SITE0_OFFSET] = bnds.site0(); - mvalue[baseidx + SITE1_OFFSET] = bnds.site1(); +void OverlapCalculator::addPairContribution(const BaseBondGenerator& bnds, + int summationscale) { + assert(summationscale == 1); + assert(bnds.distance() <= mstructure_cache.maxseparation); + const R3::Vector& r01 = bnds.r01(); + int baseidx = mvalue.size(); + mvalue.insert(mvalue.end(), CHUNK_SIZE, 0.0); + mvalue[baseidx + DISTANCE_OFFSET] = bnds.distance(); + mvalue[baseidx + DIRECTION0_OFFSET] = r01[0]; + mvalue[baseidx + DIRECTION1_OFFSET] = r01[1]; + mvalue[baseidx + DIRECTION2_OFFSET] = r01[2]; + mvalue[baseidx + SITE0_OFFSET] = bnds.site0(); + mvalue[baseidx + SITE1_OFFSET] = bnds.site1(); } - -void OverlapCalculator::executeParallelMerge(const std::string& pdata) -{ - istringstream storage(pdata, ios::binary); - diffpy::serialization::iarchive ia(storage, ios::binary); - QuantityType pvalue; - ia >> pvalue; - mvalue.insert(mvalue.end(), pvalue.begin(), pvalue.end()); +void OverlapCalculator::executeParallelMerge(const std::string& pdata) { + istringstream storage(pdata, ios::binary); + diffpy::serialization::iarchive ia(storage, ios::binary); + QuantityType pvalue; + ia >> pvalue; + mvalue.insert(mvalue.end(), pvalue.begin(), pvalue.end()); } // Private Methods ----------------------------------------------------------- -int OverlapCalculator::count() const -{ - int rv = int(mvalue.size()) / CHUNK_SIZE; - return rv; -} - - -QuantityType OverlapCalculator::subvector(int offset, - OverlapCalculator::OverlapFlag flag) const -{ - assert(0 <= offset && offset < CHUNK_SIZE); - assert(flag == ALLVALUES || flag == OVERLAPPING); +int OverlapCalculator::count() const { + int rv = int(mvalue.size()) / CHUNK_SIZE; + return rv; +} + +QuantityType OverlapCalculator::subvector( + int offset, OverlapCalculator::OverlapFlag flag) const { + assert(0 <= offset && offset < CHUNK_SIZE); + assert(flag == ALLVALUES || flag == OVERLAPPING); + int n = this->count(); + QuantityType rv; + rv.reserve(n); + for (int index = 0; index < n; ++index) { + if (OVERLAPPING == flag && this->suboverlap(index) <= 0.0) continue; + rv.push_back(this->subvalue(offset, index)); + } + return rv; +} + +const double& OverlapCalculator::subvalue(int offset, int index) const { + assert(0 <= offset && offset < CHUNK_SIZE); + assert(0 <= index && index < this->count()); + return mvalue[offset + CHUNK_SIZE * index]; +} + +const R3::Vector& OverlapCalculator::subdirection(int index) const { + static R3::Vector rv; + rv[0] = this->subvalue(DIRECTION0_OFFSET, index); + rv[1] = this->subvalue(DIRECTION1_OFFSET, index); + rv[2] = this->subvalue(DIRECTION2_OFFSET, index); + return rv; +} + +double OverlapCalculator::suboverlap(int index, int flipi, int flipj) const { + assert(0 <= flipi && flipi < this->countSites()); + assert(0 <= flipj && flipj < this->countSites()); + int i = int(this->subvalue(SITE0_OFFSET, index)); + int j = int(this->subvalue(SITE1_OFFSET, index)); + const double& radiusi = (flipi == flipj) ? mstructure_cache.siteradii[i] + : (i == flipi) ? mstructure_cache.siteradii[flipj] + : (i == flipj) ? mstructure_cache.siteradii[flipi] + : mstructure_cache.siteradii[i]; + const double& radiusj = (flipi == flipj) ? mstructure_cache.siteradii[j] + : (j == flipi) ? mstructure_cache.siteradii[flipj] + : (j == flipj) ? mstructure_cache.siteradii[flipi] + : mstructure_cache.siteradii[j]; + const double& dij = this->subvalue(DISTANCE_OFFSET, index); + double sepij = radiusi + radiusj; + double rv = (dij < sepij) ? (sepij - dij) : 0.0; + return rv; +} + +void OverlapCalculator::cacheStructureData() { + int cntsites = this->countSites(); + mstructure_cache.siteradii.resize(cntsites); + const AtomRadiiTablePtr& table = this->getAtomRadiiTable(); + for (int i = 0; i < cntsites; ++i) { + const string& smbl = mstructure->siteAtomType(i); + mstructure_cache.siteradii[i] = table->lookup(smbl); + } + double maxradius = mstructure_cache.siteradii.empty() + ? 0.0 + : *max_element(mstructure_cache.siteradii.begin(), + mstructure_cache.siteradii.end()); + mstructure_cache.maxseparation = 2 * maxradius; +} + +const std::list& OverlapCalculator::getNeighborIds(int k) const { + typedef std::list NbList; + assert(0 <= k && k < this->countSites()); + if (!mneighborids_cached) { + assert(mneighborids.empty()); int n = this->count(); - QuantityType rv; - rv.reserve(n); - for (int index = 0; index < n; ++index) - { - if (OVERLAPPING == flag && this->suboverlap(index) <= 0.0) continue; - rv.push_back(this->subvalue(offset, index)); - } - return rv; -} - - -const double& OverlapCalculator::subvalue(int offset, int index) const -{ - assert(0 <= offset && offset < CHUNK_SIZE); - assert(0 <= index && index < this->count()); - return mvalue[offset + CHUNK_SIZE * index]; -} - - -const R3::Vector& OverlapCalculator::subdirection(int index) const -{ - static R3::Vector rv; - rv[0] = this->subvalue(DIRECTION0_OFFSET, index); - rv[1] = this->subvalue(DIRECTION1_OFFSET, index); - rv[2] = this->subvalue(DIRECTION2_OFFSET, index); - return rv; -} - - -double OverlapCalculator::suboverlap(int index, int flipi, int flipj) const -{ - assert(0 <= flipi && flipi < this->countSites()); - assert(0 <= flipj && flipj < this->countSites()); - int i = int(this->subvalue(SITE0_OFFSET, index)); - int j = int(this->subvalue(SITE1_OFFSET, index)); - const double& radiusi = (flipi == flipj) ? mstructure_cache.siteradii[i] : - (i == flipi) ? mstructure_cache.siteradii[flipj] : - (i == flipj) ? mstructure_cache.siteradii[flipi] : - mstructure_cache.siteradii[i]; - const double& radiusj = (flipi == flipj) ? mstructure_cache.siteradii[j] : - (j == flipi) ? mstructure_cache.siteradii[flipj] : - (j == flipj) ? mstructure_cache.siteradii[flipi] : - mstructure_cache.siteradii[j]; - const double& dij = this->subvalue(DISTANCE_OFFSET, index); - double sepij = radiusi + radiusj; - double rv = (dij < sepij) ? (sepij - dij) : 0.0; - return rv; -} - - -void OverlapCalculator::cacheStructureData() -{ - int cntsites = this->countSites(); - mstructure_cache.siteradii.resize(cntsites); - const AtomRadiiTablePtr& table = this->getAtomRadiiTable(); - for (int i = 0; i < cntsites; ++i) - { - const string& smbl = mstructure->siteAtomType(i); - mstructure_cache.siteradii[i] = table->lookup(smbl); - } - double maxradius = mstructure_cache.siteradii.empty() ? - 0.0 : *max_element(mstructure_cache.siteradii.begin(), - mstructure_cache.siteradii.end()); - mstructure_cache.maxseparation = 2 * maxradius; -} - - -const std::list& -OverlapCalculator::getNeighborIds(int k) const -{ - typedef std::list NbList; - assert(0 <= k && k < this->countSites()); - if (!mneighborids_cached) - { - assert(mneighborids.empty()); - int n = this->count(); - for (int idx = 0; idx < n; ++idx) - { - int i = int(this->subvalue(SITE0_OFFSET, idx)); - mneighborids[i].push_back(idx); - } - mneighborids_cached = true; + for (int idx = 0; idx < n; ++idx) { + int i = int(this->subvalue(SITE0_OFFSET, idx)); + mneighborids[i].push_back(idx); } - static NbList noneighbors; - NeighborIdsStorage::const_iterator nbit = mneighborids.find(k); - const NbList& rv = - (nbit == mneighborids.end()) ? noneighbors : nbit->second; - return rv; + mneighborids_cached = true; + } + static NbList noneighbors; + NeighborIdsStorage::const_iterator nbit = mneighborids.find(k); + const NbList& rv = (nbit == mneighborids.end()) ? noneighbors : nbit->second; + return rv; } -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/OverlapCalculator.hpp b/src/diffpy/srreal/OverlapCalculator.hpp index 0a6b5763..c37cdb64 100644 --- a/src/diffpy/srreal/OverlapCalculator.hpp +++ b/src/diffpy/srreal/OverlapCalculator.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2011 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. -* -****************************************************************************** -* -* class OverlapCalculator -- calculator of atom radii overlaps -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2011 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. + * + ****************************************************************************** + * + * class OverlapCalculator -- calculator of atom radii overlaps + * + *****************************************************************************/ #ifndef OVERLAPCALCULATOR_HPP_INCLUDED #define OVERLAPCALCULATOR_HPP_INCLUDED @@ -24,125 +24,118 @@ #include #include +#include + namespace diffpy { namespace srreal { -class OverlapCalculator : public PairQuantity -{ - public: - - // constructor - OverlapCalculator(); - - // methods - /// return siteSquareOverlaps for the specified structure - template QuantityType operator()(const T&); - /// overlap values for all overlapping sites in the structure - QuantityType overlaps() const; - /// distances all overlapping sites in the structure - QuantityType distances() const; - /// directions between the centers of overlapping sites - std::vector directions() const; - /// indices of the first site for all overlapping pairs - SiteIndices sites0() const; - /// indices of the second site for all overlapping pairs - SiteIndices sites1() const; - /// atom symbols for the first site of all overlapping pairs - std::vector types0() const; - /// atom symbols for the second site of all overlapping pairs - std::vector types1() const; - /// sum of squared overlaps at each structure site - QuantityType siteSquareOverlaps() const; - /// sum of squared overlaps for all atoms in the structure - double totalSquareOverlap() const; - /// mean square per one atom in the structure - double meanSquareOverlap() const; - /// difference in the totalSquareOverlap for a flip of two sites - double flipDiffTotal(int i, int j) const; - /// difference in the meanSquareOverlap for a flip of two sites - double flipDiffMean(int i, int j) const; - /// gradients of totalSquareOverlap at each site in the structure - std::vector gradients() const; - /// indices of the neighboring sites - std::unordered_set getNeighborSites(int i) const; - /// coordination number at each site of the structure - QuantityType coordinations() const; - /// coordination number split per each type of neighboring atoms - std::unordered_map - coordinationByTypes(int i) const; - /// sets of site inidices per each sites neighborhood in the structure - std::vector< std::unordered_set > neighborhoods() const; - - // access and configuration of the atom radii - void setAtomRadiiTable(AtomRadiiTablePtr); - void setAtomRadiiTableByType(const std::string& tp); - AtomRadiiTablePtr& getAtomRadiiTable(); - const AtomRadiiTablePtr& getAtomRadiiTable() const; - - /// effective rmax value, usually a double of the maximum atom radius. - double getRmaxUsed() const; - - - protected: - - // PairQuantity overloads - virtual void resetValue(); - virtual void configureBondGenerator(BaseBondGenerator&) const; - virtual void addPairContribution(const BaseBondGenerator&, int); - virtual void executeParallelMerge(const std::string&); - - private: - - // types - enum OverlapFlag {ALLVALUES, OVERLAPPING}; - typedef std::unordered_map > NeighborIdsStorage; - - // methods - int count() const; - QuantityType subvector(int offset, OverlapFlag flag) const; - const double& subvalue(int offset, int index) const; - const R3::Vector& subdirection(int index) const; - double suboverlap(int index, int iflip=0, int jflip=0) const; - void cacheStructureData(); - const std::list& getNeighborIds(int i) const; - - // data - AtomRadiiTablePtr matomradiitable; - mutable NeighborIdsStorage mneighborids; - mutable bool mneighborids_cached; - // cache - struct { - QuantityType siteradii; - double maxseparation; - } mstructure_cache; - - // serialization - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - using boost::serialization::base_object; - ar & base_object(*this); - ar & matomradiitable; - ar & mneighborids; - ar & mstructure_cache.siteradii; - ar & mstructure_cache.maxseparation; - } - +class DLL_EXPORT OverlapCalculator : public PairQuantity { + public: + // constructor + OverlapCalculator(); + + // methods + /// return siteSquareOverlaps for the specified structure + template + QuantityType operator()(const T&); + /// overlap values for all overlapping sites in the structure + QuantityType overlaps() const; + /// distances all overlapping sites in the structure + QuantityType distances() const; + /// directions between the centers of overlapping sites + std::vector directions() const; + /// indices of the first site for all overlapping pairs + SiteIndices sites0() const; + /// indices of the second site for all overlapping pairs + SiteIndices sites1() const; + /// atom symbols for the first site of all overlapping pairs + std::vector types0() const; + /// atom symbols for the second site of all overlapping pairs + std::vector types1() const; + /// sum of squared overlaps at each structure site + QuantityType siteSquareOverlaps() const; + /// sum of squared overlaps for all atoms in the structure + double totalSquareOverlap() const; + /// mean square per one atom in the structure + double meanSquareOverlap() const; + /// difference in the totalSquareOverlap for a flip of two sites + double flipDiffTotal(int i, int j) const; + /// difference in the meanSquareOverlap for a flip of two sites + double flipDiffMean(int i, int j) const; + /// gradients of totalSquareOverlap at each site in the structure + std::vector gradients() const; + /// indices of the neighboring sites + std::unordered_set getNeighborSites(int i) const; + /// coordination number at each site of the structure + QuantityType coordinations() const; + /// coordination number split per each type of neighboring atoms + std::unordered_map coordinationByTypes(int i) const; + /// sets of site inidices per each sites neighborhood in the structure + std::vector > neighborhoods() const; + + // access and configuration of the atom radii + void setAtomRadiiTable(AtomRadiiTablePtr); + void setAtomRadiiTableByType(const std::string& tp); + AtomRadiiTablePtr& getAtomRadiiTable(); + const AtomRadiiTablePtr& getAtomRadiiTable() const; + + /// effective rmax value, usually a double of the maximum atom radius. + double getRmaxUsed() const; + + protected: + // PairQuantity overloads + virtual void resetValue(); + virtual void configureBondGenerator(BaseBondGenerator&) const; + virtual void addPairContribution(const BaseBondGenerator&, int); + virtual void executeParallelMerge(const std::string&); + + private: + // types + enum OverlapFlag { ALLVALUES, OVERLAPPING }; + typedef std::unordered_map > NeighborIdsStorage; + + // methods + int count() const; + QuantityType subvector(int offset, OverlapFlag flag) const; + const double& subvalue(int offset, int index) const; + const R3::Vector& subdirection(int index) const; + double suboverlap(int index, int iflip = 0, int jflip = 0) const; + void cacheStructureData(); + const std::list& getNeighborIds(int i) const; + + // data + AtomRadiiTablePtr matomradiitable; + mutable NeighborIdsStorage mneighborids; + mutable bool mneighborids_cached; + // cache + struct { + QuantityType siteradii; + double maxseparation; + } mstructure_cache; + + // serialization + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + using boost::serialization::base_object; + ar& base_object(*this); + ar & matomradiitable; + ar & mneighborids; + ar & mstructure_cache.siteradii; + ar & mstructure_cache.maxseparation; + } }; // Public Template Methods --------------------------------------------------- template -QuantityType OverlapCalculator::operator()(const T& stru) -{ - this->eval(stru); - return this->siteSquareOverlaps(); +QuantityType OverlapCalculator::operator()(const T& stru) { + this->eval(stru); + return this->siteSquareOverlaps(); } - -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/PDFBaseline.cpp b/src/diffpy/srreal/PDFBaseline.cpp index 96525875..89e13f1a 100644 --- a/src/diffpy/srreal/PDFBaseline.cpp +++ b/src/diffpy/srreal/PDFBaseline.cpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class PDFBaseline -- abstract base class for PDF baseline functions -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class PDFBaseline -- abstract base class for PDF baseline functions + * + *****************************************************************************/ #include #include @@ -23,9 +23,9 @@ namespace diffpy { // Unique instantiation of the template registry base class. -template class HasClassRegistry; +template class DLL_EXPORT HasClassRegistry; -} // namespace diffpy +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/PDFBaseline.hpp b/src/diffpy/srreal/PDFBaseline.hpp index 5329828f..64e57770 100644 --- a/src/diffpy/srreal/PDFBaseline.hpp +++ b/src/diffpy/srreal/PDFBaseline.hpp @@ -1,23 +1,23 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class PDFBaseline -- abstract base class for PDF baseline functions -* A concrete instance of PDFBaseline is a functor, that calculates -* baseline value at a given pair distance r. The baseline is added to -* (R(r) * r) before multiplication by any envelope functions. -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class PDFBaseline -- abstract base class for PDF baseline functions + * A concrete instance of PDFBaseline is a functor, that calculates + * baseline value at a given pair distance r. The baseline is added to + * (R(r) * r) before multiplication by any envelope functions. + * + *****************************************************************************/ #ifndef PDFBASELINE_HPP_INCLUDED #define PDFBASELINE_HPP_INCLUDED @@ -30,34 +30,31 @@ #include #include +#include + namespace diffpy { namespace srreal { /// @class PDFBaseline /// @brief abstract base class for PDF baseline function -class PDFBaseline : - public Attributes, - public HasClassRegistry -{ - public: - - // methods - virtual double operator()(const double& r) const = 0; - - private: - - // serialization - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) { } - +class DLL_EXPORT PDFBaseline : public Attributes, + public HasClassRegistry { + public: + // methods + virtual double operator()(const double& r) const = 0; + + private: + // serialization + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) {} }; typedef PDFBaseline::SharedPtr PDFBaselinePtr; -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/PDFCalculator.cpp b/src/diffpy/srreal/PDFCalculator.cpp index 47c7189a..32970787 100644 --- a/src/diffpy/srreal/PDFCalculator.cpp +++ b/src/diffpy/srreal/PDFCalculator.cpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class PDFCalculator -- real space PDF calculator -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class PDFCalculator -- real space PDF calculator + * + *****************************************************************************/ #include #include @@ -42,406 +42,326 @@ namespace { /// Return true if qstep value can be cheaply recomputed in initial setup. template -bool _initialQstepUpdate(const PDFC* pc) -{ - // Check if we use the initial empty structure and constructor - // has completed, i.e., the last attribute is available. - const bool rv = - (pc->getStructure() == emptyStructureAdapter()) && - pc->hasDoubleAttr("extendedrmax"); - return rv; +bool _initialQstepUpdate(const PDFC* pc) { + // Check if we use the initial empty structure and constructor + // has completed, i.e., the last attribute is available. + const bool rv = (pc->getStructure() == emptyStructureAdapter()) && + pc->hasDoubleAttr("extendedrmax"); + return rv; } -} // namespace +} // namespace // Constructor --------------------------------------------------------------- -PDFCalculator::PDFCalculator() : - mqmin(0.0), - mqmax(DOUBLE_MAX), - mrstep(DEFAULT_PDFCALCULATOR_RSTEP), - mmaxextension(DEFAULT_PDFCALCULATOR_MAXEXTENSION) -{ - // default configuration - mrmax = DEFAULT_PDFCALCULATOR_RMAX; - this->setPeakWidthModelByType("jeong"); - this->setPeakProfileByType("gaussian"); - this->getPeakProfile()->setPrecision(DEFAULT_PEAKPRECISION); - this->setBaselineByType("linear"); - this->setScatteringFactorTableByType("xray"); - // envelopes - this->addEnvelopeByType("scale"); - this->addEnvelopeByType("qresolution"); - // cache all internal data according to an empty structure. - // this rebuilds mstructure_cache and mrlimits_cache. - this->setStructure(mstructure); - // setup the OPTIMIZED evaluator last so that its validation passes. - this->setEvaluatorType(OPTIMIZED); - // attributes - this->registerDoubleAttribute("qmin", this, - &PDFCalculator::getQmin, &PDFCalculator::setQmin); - this->registerDoubleAttribute("qmax", this, - &PDFCalculator::getQmax, &PDFCalculator::setQmax); - this->registerDoubleAttribute("qstep", this, - &PDFCalculator::getQstep); - this->registerDoubleAttribute("rmin", this, - &PDFCalculator::getRmin, &PDFCalculator::setRmin); - this->registerDoubleAttribute("rmax", this, - &PDFCalculator::getRmax, &PDFCalculator::setRmax); - this->registerDoubleAttribute("rstep", this, - &PDFCalculator::getRstep, &PDFCalculator::setRstep); - this->registerDoubleAttribute("maxextension", this, - &PDFCalculator::getMaxExtension, &PDFCalculator::setMaxExtension); - this->registerDoubleAttribute("extendedrmin", this, - &PDFCalculator::getExtendedRmin); - this->registerDoubleAttribute("extendedrmax", this, - &PDFCalculator::getExtendedRmax); +PDFCalculator::PDFCalculator() + : mqmin(0.0), + mqmax(DOUBLE_MAX), + mrstep(DEFAULT_PDFCALCULATOR_RSTEP), + mmaxextension(DEFAULT_PDFCALCULATOR_MAXEXTENSION) { + // default configuration + mrmax = DEFAULT_PDFCALCULATOR_RMAX; + this->setPeakWidthModelByType("jeong"); + this->setPeakProfileByType("gaussian"); + this->getPeakProfile()->setPrecision(DEFAULT_PEAKPRECISION); + this->setBaselineByType("linear"); + this->setScatteringFactorTableByType("xray"); + // envelopes + this->addEnvelopeByType("scale"); + this->addEnvelopeByType("qresolution"); + // cache all internal data according to an empty structure. + // this rebuilds mstructure_cache and mrlimits_cache. + this->setStructure(mstructure); + // setup the OPTIMIZED evaluator last so that its validation passes. + this->setEvaluatorType(OPTIMIZED); + // attributes + this->registerDoubleAttribute("qmin", this, &PDFCalculator::getQmin, + &PDFCalculator::setQmin); + this->registerDoubleAttribute("qmax", this, &PDFCalculator::getQmax, + &PDFCalculator::setQmax); + this->registerDoubleAttribute("qstep", this, &PDFCalculator::getQstep); + this->registerDoubleAttribute("rmin", this, &PDFCalculator::getRmin, + &PDFCalculator::setRmin); + this->registerDoubleAttribute("rmax", this, &PDFCalculator::getRmax, + &PDFCalculator::setRmax); + this->registerDoubleAttribute("rstep", this, &PDFCalculator::getRstep, + &PDFCalculator::setRstep); + this->registerDoubleAttribute("maxextension", this, + &PDFCalculator::getMaxExtension, + &PDFCalculator::setMaxExtension); + this->registerDoubleAttribute("extendedrmin", this, + &PDFCalculator::getExtendedRmin); + this->registerDoubleAttribute("extendedrmax", this, + &PDFCalculator::getExtendedRmax); } // Public Methods ------------------------------------------------------------ // PairQuantity overloads -eventticker::EventTicker& PDFCalculator::ticker() const -{ - eventticker::EventTicker& tic = this->PairQuantity::ticker(); - assert(&mticker == &tic); - tic.updateFrom(this->PeakWidthModelOwner::ticker()); - tic.updateFrom(this->ScatteringFactorTableOwner::ticker()); - const PeakProfilePtr& pkpf = this->getPeakProfile(); - if (pkpf) tic.updateFrom(pkpf->ticker()); - return tic; +eventticker::EventTicker& PDFCalculator::ticker() const { + eventticker::EventTicker& tic = this->PairQuantity::ticker(); + assert(&mticker == &tic); + tic.updateFrom(this->PeakWidthModelOwner::ticker()); + tic.updateFrom(this->ScatteringFactorTableOwner::ticker()); + const PeakProfilePtr& pkpf = this->getPeakProfile(); + if (pkpf) tic.updateFrom(pkpf->ticker()); + return tic; } // results -QuantityType PDFCalculator::getPDF() const -{ - QuantityType pdf = this->getExtendedPDF(); - this->cutRipplePoints(pdf); - return pdf; -} - - -QuantityType PDFCalculator::getRDF() const -{ - QuantityType rdf = this->getExtendedRDF(); - this->cutRipplePoints(rdf); - return rdf; -} - - -QuantityType PDFCalculator::getRDFperR() const -{ - QuantityType rdfperr = this->getExtendedRDFperR(); - this->cutRipplePoints(rdfperr); - return rdfperr; -} - - -QuantityType PDFCalculator::getF() const -{ - QuantityType f_ext = this->getExtendedF(); - assert(pdfutils_qmaxSteps(this) <= int(f_ext.size())); - QuantityType rv(f_ext.begin(), f_ext.begin() + pdfutils_qmaxSteps(this)); - return rv; +QuantityType PDFCalculator::getPDF() const { + QuantityType pdf = this->getExtendedPDF(); + this->cutRipplePoints(pdf); + return pdf; } - -QuantityType PDFCalculator::getExtendedPDF() const -{ - QuantityType rgrid_ext = this->getExtendedRgrid(); - // Skip FFT when qmax is not specified and qmin does not exclude the - // the F(Q=Qstep) point (excluding F(0) == 0 makes no difference to G). - const bool skipfft = - !eps_lt(this->getQmax(), M_PI / this->getRstep()) && - !(1 < pdfutils_qminSteps(this)); - if (skipfft) - { - QuantityType rdfpr = this->getExtendedRDFperR(); - QuantityType rdfprb = this->applyBaseline(rgrid_ext, rdfpr); - QuantityType pdf = this->applyEnvelopes(rgrid_ext, rdfprb); - return pdf; - } - // FFT required here - // we need a full range PDF to apply termination ripples correctly - QuantityType f_ext = this->getExtendedF(); - // zero all F points at Q < Qmin - QuantityType::iterator ii_qmin = - f_ext.begin() + min(pdfutils_qminSteps(this), int(f_ext.size())); - fill(f_ext.begin(), ii_qmin, 0.0); - // zero all F points at Q >= Qmax - assert(pdfutils_qmaxSteps(this) <= int(f_ext.size())); - QuantityType::iterator ii_qmax = f_ext.begin() + pdfutils_qmaxSteps(this); - fill(ii_qmax, f_ext.end(), 0.0); - QuantityType pdf1 = fftftog(f_ext, this->getQstep()); - // cut away the FFT padded points - assert(this->extendedRmaxSteps() <= int(pdf1.size())); - pdf1.erase(pdf1.begin() + this->extendedRmaxSteps(), pdf1.end()); - pdf1.erase(pdf1.begin(), pdf1.begin() + this->extendedRminSteps()); - QuantityType pdf2 = this->applyEnvelopes(rgrid_ext, pdf1); - return pdf2; -} - - -QuantityType PDFCalculator::getExtendedRDF() const -{ - QuantityType rdf(this->countExtendedPoints()); - const double& totocc = mstructure_cache.totaloccupancy; - double sfavg = this->sfAverage(); - double rdf_scale = (totocc * sfavg == 0.0) ? 0.0 : - 1.0 / (totocc * sfavg * sfavg); - QuantityType::iterator iirdf = rdf.begin(); - QuantityType::const_iterator iival, iival_last; - iival = this->value().begin() + - this->extendedRminSteps() - this->rcalcloSteps(); - iival_last = this->value().begin() + - this->extendedRmaxSteps() - this->rcalcloSteps(); - assert(iival >= this->value().begin()); - assert(iival_last <= this->value().end()); - assert(rdf.size() == size_t(iival_last - iival)); - for (; iirdf != rdf.end(); ++iival, ++iirdf) - { - *iirdf = *iival * rdf_scale; - } - return rdf; +QuantityType PDFCalculator::getRDF() const { + QuantityType rdf = this->getExtendedRDF(); + this->cutRipplePoints(rdf); + return rdf; } - -QuantityType PDFCalculator::getExtendedRDFperR() const -{ - QuantityType rdf_ext = this->getExtendedRDF(); - QuantityType rgrid_ext = this->getExtendedRgrid(); - assert(rdf_ext.size() == rgrid_ext.size()); - QuantityType::const_iterator ri = rgrid_ext.begin(); - QuantityType::iterator rdfi = rdf_ext.begin(); - for (; ri != rgrid_ext.end(); ++ri, ++rdfi) - { - *rdfi = eps_gt(*ri, 0) ? (*rdfi / *ri) : 0.0; - } - return rdf_ext; +QuantityType PDFCalculator::getRDFperR() const { + QuantityType rdfperr = this->getExtendedRDFperR(); + this->cutRipplePoints(rdfperr); + return rdfperr; } - -QuantityType PDFCalculator::getExtendedF() const -{ - QuantityType rdfperr_ext = this->getExtendedRDFperR(); - QuantityType rgrid_ext = this->getExtendedRgrid(); - QuantityType rdfperr_ext1 = this->applyBaseline(rgrid_ext, rdfperr_ext); - const double rmin_ext = this->getExtendedRmin(); - QuantityType rv = fftgtof(rdfperr_ext1, this->getRstep(), rmin_ext); - assert(rv.empty() || eps_eq(M_PI, - this->getQstep() * rv.size() * this->getRstep())); - return rv; +QuantityType PDFCalculator::getF() const { + QuantityType f_ext = this->getExtendedF(); + assert(pdfutils_qmaxSteps(this) <= int(f_ext.size())); + QuantityType rv(f_ext.begin(), f_ext.begin() + pdfutils_qmaxSteps(this)); + return rv; } - -QuantityType PDFCalculator::getExtendedRgrid() const -{ - QuantityType rv; - rv.reserve(this->countExtendedPoints()); - // make sure exact value of rmin will be in the extended grid - for (int i = this->extendedRminSteps(); i < this->extendedRmaxSteps(); ++i) - { - rv.push_back(i * this->getRstep()); - } - assert(rv.empty() || !eps_lt(rv.front(), this->getExtendedRmin())); - assert(rv.empty() || !eps_gt(rv.back(), this->getExtendedRmax())); - return rv; +QuantityType PDFCalculator::getExtendedPDF() const { + QuantityType rgrid_ext = this->getExtendedRgrid(); + // Skip FFT when qmax is not specified and qmin does not exclude the + // the F(Q=Qstep) point (excluding F(0) == 0 makes no difference to G). + const bool skipfft = !eps_lt(this->getQmax(), M_PI / this->getRstep()) && + !(1 < pdfutils_qminSteps(this)); + if (skipfft) { + QuantityType rdfpr = this->getExtendedRDFperR(); + QuantityType rdfprb = this->applyBaseline(rgrid_ext, rdfpr); + QuantityType pdf = this->applyEnvelopes(rgrid_ext, rdfprb); + return pdf; + } + // FFT required here + // we need a full range PDF to apply termination ripples correctly + QuantityType f_ext = this->getExtendedF(); + // zero all F points at Q < Qmin + QuantityType::iterator ii_qmin = + f_ext.begin() + min(pdfutils_qminSteps(this), int(f_ext.size())); + fill(f_ext.begin(), ii_qmin, 0.0); + // zero all F points at Q >= Qmax + assert(pdfutils_qmaxSteps(this) <= int(f_ext.size())); + QuantityType::iterator ii_qmax = f_ext.begin() + pdfutils_qmaxSteps(this); + fill(ii_qmax, f_ext.end(), 0.0); + QuantityType pdf1 = fftftog(f_ext, this->getQstep()); + // cut away the FFT padded points + assert(this->extendedRmaxSteps() <= int(pdf1.size())); + pdf1.erase(pdf1.begin() + this->extendedRmaxSteps(), pdf1.end()); + pdf1.erase(pdf1.begin(), pdf1.begin() + this->extendedRminSteps()); + QuantityType pdf2 = this->applyEnvelopes(rgrid_ext, pdf1); + return pdf2; +} + +QuantityType PDFCalculator::getExtendedRDF() const { + QuantityType rdf(this->countExtendedPoints()); + const double& totocc = mstructure_cache.totaloccupancy; + double sfavg = this->sfAverage(); + double rdf_scale = + (totocc * sfavg == 0.0) ? 0.0 : 1.0 / (totocc * sfavg * sfavg); + QuantityType::iterator iirdf = rdf.begin(); + QuantityType::const_iterator iival, iival_last; + iival = + this->value().begin() + this->extendedRminSteps() - this->rcalcloSteps(); + iival_last = + this->value().begin() + this->extendedRmaxSteps() - this->rcalcloSteps(); + assert(iival >= this->value().begin()); + assert(iival_last <= this->value().end()); + assert(rdf.size() == size_t(iival_last - iival)); + for (; iirdf != rdf.end(); ++iival, ++iirdf) { + *iirdf = *iival * rdf_scale; + } + return rdf; +} + +QuantityType PDFCalculator::getExtendedRDFperR() const { + QuantityType rdf_ext = this->getExtendedRDF(); + QuantityType rgrid_ext = this->getExtendedRgrid(); + assert(rdf_ext.size() == rgrid_ext.size()); + QuantityType::const_iterator ri = rgrid_ext.begin(); + QuantityType::iterator rdfi = rdf_ext.begin(); + for (; ri != rgrid_ext.end(); ++ri, ++rdfi) { + *rdfi = eps_gt(*ri, 0) ? (*rdfi / *ri) : 0.0; + } + return rdf_ext; +} + +QuantityType PDFCalculator::getExtendedF() const { + QuantityType rdfperr_ext = this->getExtendedRDFperR(); + QuantityType rgrid_ext = this->getExtendedRgrid(); + QuantityType rdfperr_ext1 = this->applyBaseline(rgrid_ext, rdfperr_ext); + const double rmin_ext = this->getExtendedRmin(); + QuantityType rv = fftgtof(rdfperr_ext1, this->getRstep(), rmin_ext); + assert(rv.empty() || + eps_eq(M_PI, this->getQstep() * rv.size() * this->getRstep())); + return rv; +} + +QuantityType PDFCalculator::getExtendedRgrid() const { + QuantityType rv; + rv.reserve(this->countExtendedPoints()); + // make sure exact value of rmin will be in the extended grid + for (int i = this->extendedRminSteps(); i < this->extendedRmaxSteps(); ++i) { + rv.push_back(i * this->getRstep()); + } + assert(rv.empty() || !eps_lt(rv.front(), this->getExtendedRmin())); + assert(rv.empty() || !eps_gt(rv.back(), this->getExtendedRmax())); + return rv; } // Q-range methods -QuantityType PDFCalculator::getQgrid() const -{ - return pdfutils_getQgrid(this); -} +QuantityType PDFCalculator::getQgrid() const { return pdfutils_getQgrid(this); } // Q-range configuration -void PDFCalculator::setQmin(double qmin) -{ - ensureNonNegative("Qmin", qmin); - mqmin = qmin; +void PDFCalculator::setQmin(double qmin) { + ensureNonNegative("Qmin", qmin); + mqmin = qmin; } +const double& PDFCalculator::getQmin() const { return mqmin; } -const double& PDFCalculator::getQmin() const -{ - return mqmin; +void PDFCalculator::setQmax(double qmax) { + ensureNonNegative("Qmax", qmax); + double qmax1 = (qmax > 0.0) ? qmax : DOUBLE_MAX; + if (qmax1 < mqmax) mticker.click(); + mqmax = qmax1; + if (_initialQstepUpdate(this)) this->resetValue(); } - -void PDFCalculator::setQmax(double qmax) -{ - ensureNonNegative("Qmax", qmax); - double qmax1 = (qmax > 0.0) ? qmax : DOUBLE_MAX; - if (qmax1 < mqmax) mticker.click(); - mqmax = qmax1; - if (_initialQstepUpdate(this)) this->resetValue(); +const double& PDFCalculator::getQmax() const { + static double rv; + rv = min(mqmax, M_PI / this->getRstep()); + return rv; } - -const double& PDFCalculator::getQmax() const -{ - static double rv; - rv = min(mqmax, M_PI / this->getRstep()); - return rv; -} - - -const double& PDFCalculator::getQstep() const -{ - static double rv; - // replicate the zero padding as done in fftgtof - int Npad1 = this->extendedRmaxSteps(); - int Npad2 = (Npad1 > 0) ? (1 << int(ceil(log2(Npad1)))) : 0; - rv = (Npad2 > 0) ? M_PI / (Npad2 * this->getRstep()) : 0.0; - return rv; +const double& PDFCalculator::getQstep() const { + static double rv; + // replicate the zero padding as done in fftgtof + int Npad1 = this->extendedRmaxSteps(); + int Npad2 = (Npad1 > 0) ? (1 << int(ceil(log2(Npad1)))) : 0; + rv = (Npad2 > 0) ? M_PI / (Npad2 * this->getRstep()) : 0.0; + return rv; } // R-range methods -QuantityType PDFCalculator::getRgrid() const -{ - return pdfutils_getRgrid(this); -} +QuantityType PDFCalculator::getRgrid() const { return pdfutils_getRgrid(this); } // R-range configuration -void PDFCalculator::setRmin(double rmin) -{ - ensureNonNegative("Rmin", rmin); - this->PairQuantity::setRmin(rmin); -} - - -void PDFCalculator::setRmax(double rmax) -{ - ensureNonNegative("Rmax", rmax); - this->PairQuantity::setRmax(rmax); - if (_initialQstepUpdate(this)) this->resetValue(); -} - - -void PDFCalculator::setRstep(double rstep) -{ - ensureEpsilonPositive("Rstep", rstep); - if (mrstep != rstep) mticker.click(); - mrstep = rstep; - if (_initialQstepUpdate(this)) this->resetValue(); +void PDFCalculator::setRmin(double rmin) { + ensureNonNegative("Rmin", rmin); + this->PairQuantity::setRmin(rmin); } - -const double& PDFCalculator::getRstep() const -{ - return mrstep; +void PDFCalculator::setRmax(double rmax) { + ensureNonNegative("Rmax", rmax); + this->PairQuantity::setRmax(rmax); + if (_initialQstepUpdate(this)) this->resetValue(); } - -void PDFCalculator::setMaxExtension(double maxextension) -{ - ensureNonNegative("maxextension", maxextension); - if (mmaxextension != maxextension) mticker.click(); - mmaxextension = maxextension; +void PDFCalculator::setRstep(double rstep) { + ensureEpsilonPositive("Rstep", rstep); + if (mrstep != rstep) mticker.click(); + mrstep = rstep; + if (_initialQstepUpdate(this)) this->resetValue(); } +const double& PDFCalculator::getRstep() const { return mrstep; } -const double& PDFCalculator::getMaxExtension() const -{ - return mmaxextension; +void PDFCalculator::setMaxExtension(double maxextension) { + ensureNonNegative("maxextension", maxextension); + if (mmaxextension != maxextension) mticker.click(); + mmaxextension = maxextension; } +const double& PDFCalculator::getMaxExtension() const { return mmaxextension; } -double PDFCalculator::getExtendedRmin() const -{ - double rv = this->extendedRminSteps() * this->getRstep(); - return rv; +double PDFCalculator::getExtendedRmin() const { + double rv = this->extendedRminSteps() * this->getRstep(); + return rv; } - -double PDFCalculator::getExtendedRmax() const -{ - double rv = this->extendedRmaxSteps() * this->getRstep(); - return rv; +double PDFCalculator::getExtendedRmax() const { + double rv = this->extendedRmaxSteps() * this->getRstep(); + return rv; } // PDF peak profile configuration -void PDFCalculator::setPeakProfile(PeakProfilePtr pkf) -{ - ensureNonNull("PeakProfile", pkf); - if (mpeakprofile != pkf) mticker.click(); - mpeakprofile = pkf; +void PDFCalculator::setPeakProfile(PeakProfilePtr pkf) { + ensureNonNull("PeakProfile", pkf); + if (mpeakprofile != pkf) mticker.click(); + mpeakprofile = pkf; } - -void PDFCalculator::setPeakProfileByType(const string& tp) -{ - PeakProfilePtr pkf = PeakProfile::createByType(tp); - if (mpeakprofile.get()) - { - pkf->setPrecision(mpeakprofile->getPrecision()); - } - this->setPeakProfile(pkf); +void PDFCalculator::setPeakProfileByType(const string& tp) { + PeakProfilePtr pkf = PeakProfile::createByType(tp); + if (mpeakprofile.get()) { + pkf->setPrecision(mpeakprofile->getPrecision()); + } + this->setPeakProfile(pkf); } - -PeakProfilePtr& PDFCalculator::getPeakProfile() -{ - assert(mpeakprofile.get()); - return mpeakprofile; +PeakProfilePtr& PDFCalculator::getPeakProfile() { + assert(mpeakprofile.get()); + return mpeakprofile; } - -const PeakProfilePtr& PDFCalculator::getPeakProfile() const -{ - assert(mpeakprofile.get()); - return mpeakprofile; +const PeakProfilePtr& PDFCalculator::getPeakProfile() const { + assert(mpeakprofile.get()); + return mpeakprofile; } // PDF baseline methods -QuantityType PDFCalculator::applyBaseline( - const QuantityType& x, const QuantityType& y) const -{ - assert(x.size() == y.size()); - QuantityType z = y; - const PDFBaseline& baseline = *(this->getBaseline()); - QuantityType::const_iterator xi = x.begin(); - QuantityType::iterator zi = z.begin(); - for (; xi != x.end(); ++xi, ++zi) - { - *zi += baseline(*xi); - } - return z; +QuantityType PDFCalculator::applyBaseline(const QuantityType& x, + const QuantityType& y) const { + assert(x.size() == y.size()); + QuantityType z = y; + const PDFBaseline& baseline = *(this->getBaseline()); + QuantityType::const_iterator xi = x.begin(); + QuantityType::iterator zi = z.begin(); + for (; xi != x.end(); ++xi, ++zi) { + *zi += baseline(*xi); + } + return z; } - -void PDFCalculator::setBaseline(PDFBaselinePtr baseline) -{ - ensureNonNull("PDFBaseline", baseline); - mbaseline = baseline; +void PDFCalculator::setBaseline(PDFBaselinePtr baseline) { + ensureNonNull("PDFBaseline", baseline); + mbaseline = baseline; } - -void PDFCalculator::setBaselineByType(const std::string& tp) -{ - mbaseline = PDFBaseline::createByType(tp); +void PDFCalculator::setBaselineByType(const std::string& tp) { + mbaseline = PDFBaseline::createByType(tp); } - -PDFBaselinePtr& PDFCalculator::getBaseline() -{ - assert(mbaseline.get()); - return mbaseline; +PDFBaselinePtr& PDFCalculator::getBaseline() { + assert(mbaseline.get()); + return mbaseline; } - -const PDFBaselinePtr& PDFCalculator::getBaseline() const -{ - assert(mbaseline.get()); - return mbaseline; +const PDFBaselinePtr& PDFCalculator::getBaseline() const { + assert(mbaseline.get()); + return mbaseline; } // Protected Methods --------------------------------------------------------- @@ -451,310 +371,257 @@ const PDFBaselinePtr& PDFCalculator::getBaseline() const namespace { template -void pdfcalc_accept(T* obj, diffpy::BaseAttributesVisitor& v) -{ - obj->getPeakWidthModel()->accept(v); - obj->getPeakProfile()->accept(v); - obj->getBaseline()->accept(v); - // PDF envelopes - set evnames = obj->usedEnvelopeTypes(); - set::const_iterator nm = evnames.begin(); - for (; nm != evnames.end(); ++nm) - { - obj->getEnvelopeByType(*nm)->accept(v); - } - // finally call standard accept - obj->diffpy::Attributes::accept(v); +void pdfcalc_accept(T* obj, diffpy::BaseAttributesVisitor& v) { + obj->getPeakWidthModel()->accept(v); + obj->getPeakProfile()->accept(v); + obj->getBaseline()->accept(v); + // PDF envelopes + set evnames = obj->usedEnvelopeTypes(); + set::const_iterator nm = evnames.begin(); + for (; nm != evnames.end(); ++nm) { + obj->getEnvelopeByType(*nm)->accept(v); + } + // finally call standard accept + obj->diffpy::Attributes::accept(v); } -} // namespace +} // namespace - -void PDFCalculator::accept(diffpy::BaseAttributesVisitor& v) -{ - pdfcalc_accept(this, v); +void PDFCalculator::accept(diffpy::BaseAttributesVisitor& v) { + pdfcalc_accept(this, v); } - -void PDFCalculator::accept(diffpy::BaseAttributesVisitor& v) const -{ - pdfcalc_accept(this, v); +void PDFCalculator::accept(diffpy::BaseAttributesVisitor& v) const { + pdfcalc_accept(this, v); } // PairQuantity overloads -void PDFCalculator::resetValue() -{ - // calcPoints requires that structure and rlimits data are cached. - this->cacheStructureData(); - this->cacheRlimitsData(); - // when applicable, configure linear baseline - if (this->getBaseline()->type() == "linear") - { - double partialpdfscale = - (0.0 == mstructure_cache.totaloccupancy) ? 0.0 : - mstructure_cache.activeoccupancy / mstructure_cache.totaloccupancy; - double pnumdensity = partialpdfscale * mstructure->numberDensity(); - PDFBaseline& bl = *(this->getBaseline()); - bl.setDoubleAttr("slope", -4 * M_PI * pnumdensity); - } - this->resizeValue(this->countCalcPoints()); - this->PairQuantity::resetValue(); -} - - -void PDFCalculator::configureBondGenerator(BaseBondGenerator& bnds) const -{ - bnds.setRmin(this->rcalclo()); - bnds.setRmax(this->rcalchi()); +void PDFCalculator::resetValue() { + // calcPoints requires that structure and rlimits data are cached. + this->cacheStructureData(); + this->cacheRlimitsData(); + // when applicable, configure linear baseline + if (this->getBaseline()->type() == "linear") { + double partialpdfscale = + (0.0 == mstructure_cache.totaloccupancy) + ? 0.0 + : mstructure_cache.activeoccupancy / mstructure_cache.totaloccupancy; + double pnumdensity = partialpdfscale * mstructure->numberDensity(); + PDFBaseline& bl = *(this->getBaseline()); + bl.setDoubleAttr("slope", -4 * M_PI * pnumdensity); + } + this->resizeValue(this->countCalcPoints()); + this->PairQuantity::resetValue(); +} + +void PDFCalculator::configureBondGenerator(BaseBondGenerator& bnds) const { + bnds.setRmin(this->rcalclo()); + bnds.setRmax(this->rcalchi()); } - void PDFCalculator::addPairContribution(const BaseBondGenerator& bnds, - int summationscale) -{ - double sfprod = this->sfSite(bnds.site0()) * this->sfSite(bnds.site1()); - double peakscale = sfprod * bnds.multiplicity() * summationscale; - double fwhm = this->getPeakWidthModel()->calculate(bnds); - const PeakProfile& pkf = *(this->getPeakProfile()); - double dist = bnds.distance(); - double xlo = dist + pkf.xboundlo(fwhm); - double xhi = dist + pkf.xboundhi(fwhm); - int i = max(0, this->calcIndex(xlo)); - int ilast = min(this->countCalcPoints(), this->calcIndex(xhi) + 1); - assert(ilast <= int(mvalue.size())); - assert(eps_gt(dist, 0.0)); - for (; i < ilast; ++i) - { - double x = (this->rcalcloSteps() + i) * this->getRstep() - dist; - double y = pkf(x, fwhm); - // Contributions in G(r) need to be normalized by pair distance, - // not by r as done in PDFfit or PDFfit2. Here we rescale RDF - // in such way that division by r will give a correct result. - double yrdf = y * (x / dist + 1); - mvalue[i] += peakscale * yrdf; - } -} - - -void PDFCalculator::stashPartialValue() -{ - mstashedvalue.value = this->value(); - mstashedvalue.rclosteps = this->rcalcloSteps(); -} - - -void PDFCalculator::restorePartialValue() -{ - assert(!mstashedvalue.value.empty()); - assert(!mvalue.empty()); - QuantityType::const_iterator si = mstashedvalue.value.begin(); - QuantityType::const_iterator slast = mstashedvalue.value.end(); - QuantityType::iterator ti = mvalue.begin(); - QuantityType::iterator tlast = mvalue.end(); - int leftshift = this->rcalcloSteps() - mstashedvalue.rclosteps; - int sz = mstashedvalue.value.size(); - if (leftshift >= 0) si += min(leftshift, sz); - else ti += min(-leftshift, int(mvalue.size())); - for (; si != slast && ti != tlast; ++si, ++ti) *ti = *si; - mstashedvalue.value.clear(); + int summationscale) { + double sfprod = this->sfSite(bnds.site0()) * this->sfSite(bnds.site1()); + double peakscale = sfprod * bnds.multiplicity() * summationscale; + double fwhm = this->getPeakWidthModel()->calculate(bnds); + const PeakProfile& pkf = *(this->getPeakProfile()); + double dist = bnds.distance(); + double xlo = dist + pkf.xboundlo(fwhm); + double xhi = dist + pkf.xboundhi(fwhm); + int i = max(0, this->calcIndex(xlo)); + int ilast = min(this->countCalcPoints(), this->calcIndex(xhi) + 1); + assert(ilast <= int(mvalue.size())); + assert(eps_gt(dist, 0.0)); + for (; i < ilast; ++i) { + double x = (this->rcalcloSteps() + i) * this->getRstep() - dist; + double y = pkf(x, fwhm); + // Contributions in G(r) need to be normalized by pair distance, + // not by r as done in PDFfit or PDFfit2. Here we rescale RDF + // in such way that division by r will give a correct result. + double yrdf = y * (x / dist + 1); + mvalue[i] += peakscale * yrdf; + } +} + +void PDFCalculator::stashPartialValue() { + mstashedvalue.value = this->value(); + mstashedvalue.rclosteps = this->rcalcloSteps(); +} + +void PDFCalculator::restorePartialValue() { + assert(!mstashedvalue.value.empty()); + assert(!mvalue.empty()); + QuantityType::const_iterator si = mstashedvalue.value.begin(); + QuantityType::const_iterator slast = mstashedvalue.value.end(); + QuantityType::iterator ti = mvalue.begin(); + QuantityType::iterator tlast = mvalue.end(); + int leftshift = this->rcalcloSteps() - mstashedvalue.rclosteps; + int sz = mstashedvalue.value.size(); + if (leftshift >= 0) + si += min(leftshift, sz); + else + ti += min(-leftshift, int(mvalue.size())); + for (; si != slast && ti != tlast; ++si, ++ti) *ti = *si; + mstashedvalue.value.clear(); } // calculation specific -double PDFCalculator::rcalclo() const -{ - double rv = this->rcalcloSteps() * this->getRstep(); - return rv; +double PDFCalculator::rcalclo() const { + double rv = this->rcalcloSteps() * this->getRstep(); + return rv; } - -double PDFCalculator::rcalchi() const -{ - double rv = this->rcalchiSteps() * this->getRstep(); - return rv; +double PDFCalculator::rcalchi() const { + double rv = this->rcalchiSteps() * this->getRstep(); + return rv; } - -double PDFCalculator::extFromTerminationRipples() const -{ - // number of termination ripples for extending the r-range - const int nripples = 6; - // extension due to termination ripples. - // apply only when qmax is below the Nyquist frequency for rstep. - const double& qmax = this->getQmax(); - const double& dr = this->getRstep(); - double rv = (eps_gt(qmax, 0.0) && eps_lt(qmax, M_PI / dr)) ? - (nripples * 2 * M_PI / qmax) : 0.0; - return rv; +double PDFCalculator::extFromTerminationRipples() const { + // number of termination ripples for extending the r-range + const int nripples = 6; + // extension due to termination ripples. + // apply only when qmax is below the Nyquist frequency for rstep. + const double& qmax = this->getQmax(); + const double& dr = this->getRstep(); + double rv = (eps_gt(qmax, 0.0) && eps_lt(qmax, M_PI / dr)) + ? (nripples * 2 * M_PI / qmax) + : 0.0; + return rv; } - -double PDFCalculator::extFromPeakTails() const -{ - // assume uncorrelated neighbors with maxUii - const PeakWidthModel& pwm = *(this->getPeakWidthModel()); - double maxfwhm = pwm.maxWidth( - mstructure, this->getRmin(), this->getRmax()); - const PeakProfile& pkf = *(this->getPeakProfile()); - double xleft = fabs(pkf.xboundlo(maxfwhm)); - double xright = fabs(pkf.xboundhi(maxfwhm)); - double rv = max(xleft, xright); - return rv; +double PDFCalculator::extFromPeakTails() const { + // assume uncorrelated neighbors with maxUii + const PeakWidthModel& pwm = *(this->getPeakWidthModel()); + double maxfwhm = pwm.maxWidth(mstructure, this->getRmin(), this->getRmax()); + const PeakProfile& pkf = *(this->getPeakProfile()); + double xleft = fabs(pkf.xboundlo(maxfwhm)); + double xright = fabs(pkf.xboundhi(maxfwhm)); + double rv = max(xleft, xright); + return rv; } +int PDFCalculator::rcalcloSteps() const { return mrlimits_cache.rcalclosteps; } -int PDFCalculator::rcalcloSteps() const -{ - return mrlimits_cache.rcalclosteps; -} +int PDFCalculator::rcalchiSteps() const { return mrlimits_cache.rcalchisteps; } - -int PDFCalculator::rcalchiSteps() const -{ - return mrlimits_cache.rcalchisteps; +int PDFCalculator::extendedRminSteps() const { + return mrlimits_cache.extendedrminsteps; } - -int PDFCalculator::extendedRminSteps() const -{ - return mrlimits_cache.extendedrminsteps; +int PDFCalculator::extendedRmaxSteps() const { + return mrlimits_cache.extendedrmaxsteps; } - -int PDFCalculator::extendedRmaxSteps() const -{ - return mrlimits_cache.extendedrmaxsteps; +int PDFCalculator::countExtendedPoints() const { + int rv = this->extendedRmaxSteps() - this->extendedRminSteps(); + assert(rv >= 0); + return rv; } - -int PDFCalculator::countExtendedPoints() const -{ - int rv = this->extendedRmaxSteps() - this->extendedRminSteps(); - assert(rv >= 0); - return rv; +int PDFCalculator::countCalcPoints() const { + int rv = this->rcalchiSteps() - this->rcalcloSteps(); + assert(rv >= 0); + return rv; } - -int PDFCalculator::countCalcPoints() const -{ - int rv = this->rcalchiSteps() - this->rcalcloSteps(); - assert(rv >= 0); - return rv; +int PDFCalculator::calcIndex(double r) const { + int rv = int(floor(r / this->getRstep())) - this->rcalcloSteps(); + return rv; } - -int PDFCalculator::calcIndex(double r) const -{ - int rv = int(floor(r / this->getRstep())) - this->rcalcloSteps(); - return rv; +void PDFCalculator::cutRipplePoints(QuantityType& y) const { + if (y.empty()) return; + assert(int(y.size()) == + this->extendedRmaxSteps() - this->extendedRminSteps()); + int ncutlo = pdfutils_rminSteps(this) - this->extendedRminSteps(); + int ncuthi = this->extendedRmaxSteps() - pdfutils_rmaxSteps(this); + assert(ncutlo + ncuthi <= int(y.size())); + y.erase(y.end() - ncuthi, y.end()); + y.erase(y.begin(), y.begin() + ncutlo); } - -void PDFCalculator::cutRipplePoints(QuantityType& y) const -{ - if (y.empty()) return; - assert(int(y.size()) == - this->extendedRmaxSteps() - this->extendedRminSteps()); - int ncutlo = pdfutils_rminSteps(this) - this->extendedRminSteps(); - int ncuthi = this->extendedRmaxSteps() - pdfutils_rmaxSteps(this); - assert(ncutlo + ncuthi <= int(y.size())); - y.erase(y.end() - ncuthi, y.end()); - y.erase(y.begin(), y.begin() + ncutlo); +const double& PDFCalculator::sfSite(int siteidx) const { + assert(0 <= siteidx && siteidx < int(mstructure_cache.sfsite.size())); + return mstructure_cache.sfsite[siteidx]; } +double PDFCalculator::sfAverage() const { return mstructure_cache.sfaverage; } -const double& PDFCalculator::sfSite(int siteidx) const -{ - assert(0 <= siteidx && siteidx < int(mstructure_cache.sfsite.size())); - return mstructure_cache.sfsite[siteidx]; -} - - -double PDFCalculator::sfAverage() const -{ - return mstructure_cache.sfaverage; -} - - -void PDFCalculator::cacheStructureData() -{ - int cntsites = this->countSites(); - // sfsite - unordered_map fcache; - mstructure_cache.sfsite.resize(cntsites); - const ScatteringFactorTablePtr sftable = this->getScatteringFactorTable(); - for (int i = 0; i < cntsites; ++i) - { - const string& smbl = mstructure->siteAtomType(i); - unordered_map::iterator ff = fcache.find(smbl); - if (ff == fcache.end()) - { - const double value = sftable->lookup(smbl); - ff = fcache.insert(make_pair(smbl, value)).first; - } - mstructure_cache.sfsite[i] = ff->second * mstructure->siteOccupancy(i); - } - // sfaverage - double totocc = mstructure->totalOccupancy(); - double totsf = 0.0; - for (int i = 0; i < cntsites; ++i) - { - totsf += this->sfSite(i) * mstructure->siteMultiplicity(i); - } - mstructure_cache.sfaverage = (totocc == 0.0) ? 0.0 : (totsf / totocc); - // totaloccupancy - mstructure_cache.totaloccupancy = totocc; - // active occupancy - double invmasktotal = 0.0; - for (auto&& ij : minvertpairmask) - { - const int& i = ij.first; - const int& j = ij.second; - bool outofbounds = (i < 0 || i >= cntsites || j < 0 || j >= cntsites); - if (outofbounds) continue; - int sumscale = (i == j) ? 1 : 2; - double occij = sumscale * - mstructure->siteOccupancy(i) * mstructure->siteMultiplicity(i) * - mstructure->siteOccupancy(j) * mstructure->siteMultiplicity(j); - invmasktotal += occij; - } - if (totocc > 0.0) invmasktotal /= totocc; - mstructure_cache.activeoccupancy = (mdefaultpairmask) ? - (totocc - invmasktotal) : invmasktotal; -} - - -void PDFCalculator::cacheRlimitsData() -{ - mrlimits_cache.extendedrminsteps = 0; - mrlimits_cache.extendedrmaxsteps = 0; - mrlimits_cache.rcalclosteps = 0; - mrlimits_cache.rcalchisteps = 0; - if (pdfutils_rminSteps(this) >= pdfutils_rmaxSteps(this)) return; - // obtain extension magnitudes and rescale to fit maximum extension - double ext_ripples = this->extFromTerminationRipples(); - double ext_pktails = this->extFromPeakTails(); - double ext_total = ext_ripples + ext_pktails; - if (ext_total > this->getMaxExtension()) - { - double sc = this->getMaxExtension() / ext_total; - ext_ripples *= sc; - ext_pktails *= sc; - ext_total = this->getMaxExtension(); +void PDFCalculator::cacheStructureData() { + int cntsites = this->countSites(); + // sfsite + unordered_map fcache; + mstructure_cache.sfsite.resize(cntsites); + const ScatteringFactorTablePtr sftable = this->getScatteringFactorTable(); + for (int i = 0; i < cntsites; ++i) { + const string& smbl = mstructure->siteAtomType(i); + unordered_map::iterator ff = fcache.find(smbl); + if (ff == fcache.end()) { + const double value = sftable->lookup(smbl); + ff = fcache.insert(make_pair(smbl, value)).first; } - // abbreviations - const double& rmin = this->getRmin(); - const double& rmax = this->getRmax(); - const double& dr = this->getRstep(); - mrlimits_cache.extendedrminsteps = max(0, pdfutils_rminSteps(rmin - ext_ripples, dr)); - mrlimits_cache.extendedrmaxsteps = pdfutils_rmaxSteps(rmax + ext_ripples, dr); - mrlimits_cache.rcalclosteps = max(0, pdfutils_rminSteps(rmin - ext_total, dr)); - mrlimits_cache.rcalchisteps = pdfutils_rmaxSteps(rmax + ext_total, dr); -} - -} // namespace diffpy -} // namespace srreal + mstructure_cache.sfsite[i] = ff->second * mstructure->siteOccupancy(i); + } + // sfaverage + double totocc = mstructure->totalOccupancy(); + double totsf = 0.0; + for (int i = 0; i < cntsites; ++i) { + totsf += this->sfSite(i) * mstructure->siteMultiplicity(i); + } + mstructure_cache.sfaverage = (totocc == 0.0) ? 0.0 : (totsf / totocc); + // totaloccupancy + mstructure_cache.totaloccupancy = totocc; + // active occupancy + double invmasktotal = 0.0; + for (auto&& ij : minvertpairmask) { + const int& i = ij.first; + const int& j = ij.second; + bool outofbounds = (i < 0 || i >= cntsites || j < 0 || j >= cntsites); + if (outofbounds) continue; + int sumscale = (i == j) ? 1 : 2; + double occij = sumscale * mstructure->siteOccupancy(i) * + mstructure->siteMultiplicity(i) * + mstructure->siteOccupancy(j) * + mstructure->siteMultiplicity(j); + invmasktotal += occij; + } + if (totocc > 0.0) invmasktotal /= totocc; + mstructure_cache.activeoccupancy = + (mdefaultpairmask) ? (totocc - invmasktotal) : invmasktotal; +} + +void PDFCalculator::cacheRlimitsData() { + mrlimits_cache.extendedrminsteps = 0; + mrlimits_cache.extendedrmaxsteps = 0; + mrlimits_cache.rcalclosteps = 0; + mrlimits_cache.rcalchisteps = 0; + if (pdfutils_rminSteps(this) >= pdfutils_rmaxSteps(this)) return; + // obtain extension magnitudes and rescale to fit maximum extension + double ext_ripples = this->extFromTerminationRipples(); + double ext_pktails = this->extFromPeakTails(); + double ext_total = ext_ripples + ext_pktails; + if (ext_total > this->getMaxExtension()) { + double sc = this->getMaxExtension() / ext_total; + ext_ripples *= sc; + ext_pktails *= sc; + ext_total = this->getMaxExtension(); + } + // abbreviations + const double& rmin = this->getRmin(); + const double& rmax = this->getRmax(); + const double& dr = this->getRstep(); + mrlimits_cache.extendedrminsteps = + max(0, pdfutils_rminSteps(rmin - ext_ripples, dr)); + mrlimits_cache.extendedrmaxsteps = pdfutils_rmaxSteps(rmax + ext_ripples, dr); + mrlimits_cache.rcalclosteps = + max(0, pdfutils_rminSteps(rmin - ext_total, dr)); + mrlimits_cache.rcalchisteps = pdfutils_rmaxSteps(rmax + ext_total, dr); +} + +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/PDFCalculator.hpp b/src/diffpy/srreal/PDFCalculator.hpp index 79220e0a..2f5c127a 100644 --- a/src/diffpy/srreal/PDFCalculator.hpp +++ b/src/diffpy/srreal/PDFCalculator.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class PDFCalculator -- real space PDF calculator -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class PDFCalculator -- real space PDF calculator + * + *****************************************************************************/ #ifndef PDFCALCULATOR_HPP_INCLUDED #define PDFCALCULATOR_HPP_INCLUDED @@ -26,187 +26,184 @@ #include #include +#include + namespace diffpy { namespace srreal { -class PDFCalculator : - public PairQuantity, - public PeakWidthModelOwner, - public ScatteringFactorTableOwner, - public PDFEnvelopeOwner -{ - public: - - // constructor - PDFCalculator(); - - // PairQuantity overloads - virtual eventticker::EventTicker& ticker() const; - - // results - QuantityType getPDF() const; - QuantityType getRDF() const; - QuantityType getRDFperR() const; - QuantityType getF() const; - - /// PDF on an r-range extended for termination ripples - QuantityType getExtendedPDF() const; - /// RDF on an r-range extended for termination ripples - QuantityType getExtendedRDF() const; - /// RDF divided by r on an r-range extended for termination ripples - QuantityType getExtendedRDFperR() const; - /// F(Q) on a zero-padded grid that reaches r-sampling Qmax = PI/dr - QuantityType getExtendedF() const; - /// r-grid extended for termination ripples - QuantityType getExtendedRgrid() const; - - // Q-range methods - QuantityType getQgrid() const; - // Q-range configuration - void setQmin(double); - const double& getQmin() const; - void setQmax(double); - const double& getQmax() const; - const double& getQstep() const; - - // R-range methods - QuantityType getRgrid() const; - // R-range configuration - virtual void setRmin(double); - virtual void setRmax(double); - void setRstep(double); - const double& getRstep() const; - /// maximum total extension of the r-range accounting for both - /// termination ripples and peak tails - void setMaxExtension(double); - /// maximum total extension of the r-range accounting for both - /// termination ripples and peak tails - const double& getMaxExtension() const; - /// lower bound for the r-range extended for termination ripples - double getExtendedRmin() const; - /// upper bound of the r-range extended for termination ripples - double getExtendedRmax() const; - - // PDF profile configuration - void setPeakProfile(PeakProfilePtr); - void setPeakProfileByType(const std::string& tp); - PeakProfilePtr& getPeakProfile(); - const PeakProfilePtr& getPeakProfile() const; - - // PDF baseline configuration - // application on an array - QuantityType applyBaseline(const QuantityType& x, const QuantityType& y) const; - void setBaseline(PDFBaselinePtr); - void setBaselineByType(const std::string& tp); - PDFBaselinePtr& getBaseline(); - const PDFBaselinePtr& getBaseline() const; - - protected: - - // Attributes overload to direct visitors around data structures - virtual void accept(diffpy::BaseAttributesVisitor& v); - virtual void accept(diffpy::BaseAttributesVisitor& v) const; - - // PairQuantity overloads - virtual void resetValue(); - virtual void configureBondGenerator(BaseBondGenerator&) const; - virtual void addPairContribution(const BaseBondGenerator&, int); - // support for PQEvaluatorOptimized - virtual void stashPartialValue(); - virtual void restorePartialValue(); - - private: - - // methods - calculation specific - /// complete lower bound extension of the calculated grid - double rcalclo() const; - /// complete upper bound extension of the calculated grid - double rcalchi() const; - /// r-range extension to allow propagation of termination ripples - double extFromTerminationRipples() const; - /// r-range extension to account for tails from out-of-range peaks - double extFromPeakTails() const; - /// number of dr steps at rcalclo from 0 - int rcalcloSteps() const; - /// number of dr steps at rhalchi from 0 - int rcalchiSteps() const; - /// number of dr steps at lower extension due to termination ripples - int extendedRminSteps() const; - /// number of dr steps at upper extension due to termination ripples - int extendedRmaxSteps() const; - /// number of points in the r-grid extended with termination ripples - int countExtendedPoints() const; - /// number of points in the complete calculated r-grid - int countCalcPoints() const; - /// index of a nearby point in the complete calculated r-grid - int calcIndex(double r) const; - /// reduce extended grid to user-requested results grid - /// by cutting away the points for termination ripples - void cutRipplePoints(QuantityType& y) const; - - // structure factors - fast lookup by site index - /// effective scattering factor at a given site scaled by occupancy - const double& sfSite(int) const; - /// average scattering factor - double sfAverage() const; - void cacheStructureData(); - void cacheRlimitsData(); - - // data - // configuration - double mqmin; - double mqmax; - double mrstep; - double mmaxextension; - PeakProfilePtr mpeakprofile; - PDFBaselinePtr mbaseline; - struct { - std::vector sfsite; - double sfaverage; - double totaloccupancy; - double activeoccupancy; - } mstructure_cache; - struct { - int extendedrminsteps; - int extendedrmaxsteps; - int rcalclosteps; - int rcalchisteps; - } mrlimits_cache; - // support for PQEvaluatorOptimized - struct { - QuantityType value; - int rclosteps; - } mstashedvalue; - // serialization - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - using boost::serialization::base_object; - ar & base_object(*this); - ar & base_object(*this); - ar & base_object(*this); - ar & base_object(*this); - ar & mqmin; - ar & mqmax; - ar & mrstep; - ar & mmaxextension; - ar & mpeakprofile; - ar & mbaseline; - ar & mstructure_cache.sfsite; - ar & mstructure_cache.sfaverage; - ar & mstructure_cache.totaloccupancy; - ar & mstructure_cache.activeoccupancy; - ar & mrlimits_cache.extendedrminsteps; - ar & mrlimits_cache.extendedrmaxsteps; - ar & mrlimits_cache.rcalclosteps; - ar & mrlimits_cache.rcalchisteps; - } +class DLL_EXPORT PDFCalculator : public PairQuantity, + public PeakWidthModelOwner, + public ScatteringFactorTableOwner, + public PDFEnvelopeOwner { + public: + // constructor + PDFCalculator(); + + // PairQuantity overloads + virtual eventticker::EventTicker& ticker() const; + + // results + QuantityType getPDF() const; + QuantityType getRDF() const; + QuantityType getRDFperR() const; + QuantityType getF() const; + + /// PDF on an r-range extended for termination ripples + QuantityType getExtendedPDF() const; + /// RDF on an r-range extended for termination ripples + QuantityType getExtendedRDF() const; + /// RDF divided by r on an r-range extended for termination ripples + QuantityType getExtendedRDFperR() const; + /// F(Q) on a zero-padded grid that reaches r-sampling Qmax = PI/dr + QuantityType getExtendedF() const; + /// r-grid extended for termination ripples + QuantityType getExtendedRgrid() const; + + // Q-range methods + QuantityType getQgrid() const; + // Q-range configuration + void setQmin(double); + const double& getQmin() const; + void setQmax(double); + const double& getQmax() const; + const double& getQstep() const; + + // R-range methods + QuantityType getRgrid() const; + // R-range configuration + virtual void setRmin(double); + virtual void setRmax(double); + void setRstep(double); + const double& getRstep() const; + /// maximum total extension of the r-range accounting for both + /// termination ripples and peak tails + void setMaxExtension(double); + /// maximum total extension of the r-range accounting for both + /// termination ripples and peak tails + const double& getMaxExtension() const; + /// lower bound for the r-range extended for termination ripples + double getExtendedRmin() const; + /// upper bound of the r-range extended for termination ripples + double getExtendedRmax() const; + + // PDF profile configuration + void setPeakProfile(PeakProfilePtr); + void setPeakProfileByType(const std::string& tp); + PeakProfilePtr& getPeakProfile(); + const PeakProfilePtr& getPeakProfile() const; + + // PDF baseline configuration + // application on an array + QuantityType applyBaseline(const QuantityType& x, + const QuantityType& y) const; + void setBaseline(PDFBaselinePtr); + void setBaselineByType(const std::string& tp); + PDFBaselinePtr& getBaseline(); + const PDFBaselinePtr& getBaseline() const; + + protected: + // Attributes overload to direct visitors around data structures + virtual void accept(diffpy::BaseAttributesVisitor& v); + virtual void accept(diffpy::BaseAttributesVisitor& v) const; + + // PairQuantity overloads + virtual void resetValue(); + virtual void configureBondGenerator(BaseBondGenerator&) const; + virtual void addPairContribution(const BaseBondGenerator&, int); + // support for PQEvaluatorOptimized + virtual void stashPartialValue(); + virtual void restorePartialValue(); + + private: + // methods - calculation specific + /// complete lower bound extension of the calculated grid + double rcalclo() const; + /// complete upper bound extension of the calculated grid + double rcalchi() const; + /// r-range extension to allow propagation of termination ripples + double extFromTerminationRipples() const; + /// r-range extension to account for tails from out-of-range peaks + double extFromPeakTails() const; + /// number of dr steps at rcalclo from 0 + int rcalcloSteps() const; + /// number of dr steps at rhalchi from 0 + int rcalchiSteps() const; + /// number of dr steps at lower extension due to termination ripples + int extendedRminSteps() const; + /// number of dr steps at upper extension due to termination ripples + int extendedRmaxSteps() const; + /// number of points in the r-grid extended with termination ripples + int countExtendedPoints() const; + /// number of points in the complete calculated r-grid + int countCalcPoints() const; + /// index of a nearby point in the complete calculated r-grid + int calcIndex(double r) const; + /// reduce extended grid to user-requested results grid + /// by cutting away the points for termination ripples + void cutRipplePoints(QuantityType& y) const; + + // structure factors - fast lookup by site index + /// effective scattering factor at a given site scaled by occupancy + const double& sfSite(int) const; + /// average scattering factor + double sfAverage() const; + void cacheStructureData(); + void cacheRlimitsData(); + + // data + // configuration + double mqmin; + double mqmax; + double mrstep; + double mmaxextension; + PeakProfilePtr mpeakprofile; + PDFBaselinePtr mbaseline; + struct { + std::vector sfsite; + double sfaverage; + double totaloccupancy; + double activeoccupancy; + } mstructure_cache; + struct { + int extendedrminsteps; + int extendedrmaxsteps; + int rcalclosteps; + int rcalchisteps; + } mrlimits_cache; + // support for PQEvaluatorOptimized + struct { + QuantityType value; + int rclosteps; + } mstashedvalue; + // serialization + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + using boost::serialization::base_object; + ar& base_object(*this); + ar& base_object(*this); + ar& base_object(*this); + ar& base_object(*this); + ar & mqmin; + ar & mqmax; + ar & mrstep; + ar & mmaxextension; + ar & mpeakprofile; + ar & mbaseline; + ar & mstructure_cache.sfsite; + ar & mstructure_cache.sfaverage; + ar & mstructure_cache.totaloccupancy; + ar & mstructure_cache.activeoccupancy; + ar & mrlimits_cache.extendedrminsteps; + ar & mrlimits_cache.extendedrmaxsteps; + ar & mrlimits_cache.rcalclosteps; + ar & mrlimits_cache.rcalchisteps; + } }; // class PDFCalculator -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/PDFEnvelope.cpp b/src/diffpy/srreal/PDFEnvelope.cpp index 04023176..b61e2ae2 100644 --- a/src/diffpy/srreal/PDFEnvelope.cpp +++ b/src/diffpy/srreal/PDFEnvelope.cpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class PDFEnvelope -- abstract base class for PDF envelope functions -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class PDFEnvelope -- abstract base class for PDF envelope functions + * + *****************************************************************************/ #include #include @@ -31,7 +31,7 @@ using diffpy::validators::ensureNonNull; namespace diffpy { // Unique instantiation of the template registry base class. -template class HasClassRegistry; +template class DLL_EXPORT HasClassRegistry; namespace srreal { @@ -39,103 +39,79 @@ namespace srreal { // public methods -QuantityType PDFEnvelopeOwner::applyEnvelopes( - const QuantityType& x, const QuantityType& y) const -{ - assert(x.size() == y.size()); - QuantityType z = y; - EnvelopeStorage::const_iterator evit; - for (evit = menvelope.begin(); evit != menvelope.end(); ++evit) - { - PDFEnvelope& fenvelope = *(evit->second); - QuantityType::const_iterator xi = x.begin(); - QuantityType::iterator zi = z.begin(); - for (; xi != x.end(); ++xi, ++zi) - { - *zi *= fenvelope(*xi); - } +QuantityType PDFEnvelopeOwner::applyEnvelopes(const QuantityType& x, + const QuantityType& y) const { + assert(x.size() == y.size()); + QuantityType z = y; + EnvelopeStorage::const_iterator evit; + for (evit = menvelope.begin(); evit != menvelope.end(); ++evit) { + PDFEnvelope& fenvelope = *(evit->second); + QuantityType::const_iterator xi = x.begin(); + QuantityType::iterator zi = z.begin(); + for (; xi != x.end(); ++xi, ++zi) { + *zi *= fenvelope(*xi); } - return z; + } + return z; } - -void PDFEnvelopeOwner::addEnvelope(PDFEnvelopePtr envlp) -{ - ensureNonNull("PDFEnvelope", envlp); - menvelope[envlp->type()] = envlp; +void PDFEnvelopeOwner::addEnvelope(PDFEnvelopePtr envlp) { + ensureNonNull("PDFEnvelope", envlp); + menvelope[envlp->type()] = envlp; } - -void PDFEnvelopeOwner::addEnvelopeByType(const string& tp) -{ - // this throws invalid_argument for invalid type - PDFEnvelopePtr envlp = PDFEnvelope::createByType(tp); - // we get here only when createByType was successful - menvelope[envlp->type()] = envlp; +void PDFEnvelopeOwner::addEnvelopeByType(const string& tp) { + // this throws invalid_argument for invalid type + PDFEnvelopePtr envlp = PDFEnvelope::createByType(tp); + // we get here only when createByType was successful + menvelope[envlp->type()] = envlp; } - -void PDFEnvelopeOwner::popEnvelope(PDFEnvelopePtr envlp) -{ - EnvelopeStorage::iterator evit = menvelope.begin(); - for (; evit != menvelope.end(); ++evit) - { - if (evit->second == envlp) - { - menvelope.erase(evit); - break; - } +void PDFEnvelopeOwner::popEnvelope(PDFEnvelopePtr envlp) { + EnvelopeStorage::iterator evit = menvelope.begin(); + for (; evit != menvelope.end(); ++evit) { + if (evit->second == envlp) { + menvelope.erase(evit); + break; } + } } - -void PDFEnvelopeOwner::popEnvelopeByType(const string& tp) -{ - menvelope.erase(tp); +void PDFEnvelopeOwner::popEnvelopeByType(const string& tp) { + menvelope.erase(tp); } - -const PDFEnvelopePtr& PDFEnvelopeOwner::getEnvelopeByType(const string& tp) const -{ - // call non-constant method - const PDFEnvelopePtr& rv = - const_cast(this)->getEnvelopeByType(tp); - return rv; +const PDFEnvelopePtr& PDFEnvelopeOwner::getEnvelopeByType( + const string& tp) const { + // call non-constant method + const PDFEnvelopePtr& rv = + const_cast(this)->getEnvelopeByType(tp); + return rv; } - -PDFEnvelopePtr& PDFEnvelopeOwner::getEnvelopeByType(const string& tp) -{ - if (!menvelope.count(tp)) - { - ostringstream emsg; - emsg << "Invalid or missing PDFEnvelope type '" << tp << "'."; - throw invalid_argument(emsg.str()); - } - PDFEnvelopePtr& rv = menvelope[tp]; - return rv; +PDFEnvelopePtr& PDFEnvelopeOwner::getEnvelopeByType(const string& tp) { + if (!menvelope.count(tp)) { + ostringstream emsg; + emsg << "Invalid or missing PDFEnvelope type '" << tp << "'."; + throw invalid_argument(emsg.str()); + } + PDFEnvelopePtr& rv = menvelope[tp]; + return rv; } - -set PDFEnvelopeOwner::usedEnvelopeTypes() const -{ - set rv; - EnvelopeStorage::const_iterator evit; - for (evit = menvelope.begin(); evit != menvelope.end(); ++evit) - { - rv.insert(rv.end(), evit->first); - } - return rv; +set PDFEnvelopeOwner::usedEnvelopeTypes() const { + set rv; + EnvelopeStorage::const_iterator evit; + for (evit = menvelope.begin(); evit != menvelope.end(); ++evit) { + rv.insert(rv.end(), evit->first); + } + return rv; } +void PDFEnvelopeOwner::clearEnvelopes() { menvelope.clear(); } -void PDFEnvelopeOwner::clearEnvelopes() -{ - menvelope.clear(); -} - -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/PDFEnvelope.hpp b/src/diffpy/srreal/PDFEnvelope.hpp index f7035737..6383be0e 100644 --- a/src/diffpy/srreal/PDFEnvelope.hpp +++ b/src/diffpy/srreal/PDFEnvelope.hpp @@ -1,23 +1,23 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class PDFEnvelope -- abstract base class for PDF envelope functions -* A concrete instance of PDFEnvelope is a functor, that calculates -* PDF scaling coefficients at a given pair distance r. Several functors -* can be defined and applied in PDFCalculator. -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class PDFEnvelope -- abstract base class for PDF envelope functions + * A concrete instance of PDFEnvelope is a functor, that calculates + * PDF scaling coefficients at a given pair distance r. Several functors + * can be defined and applied in PDFCalculator. + * + *****************************************************************************/ #ifndef PDFENVELOPE_HPP_INCLUDED #define PDFENVELOPE_HPP_INCLUDED @@ -35,79 +35,68 @@ #include #include +#include + namespace diffpy { namespace srreal { - /// @class PDFEnvelope /// @brief abstract base class for PDF envelope scaling function -class PDFEnvelope : - public diffpy::Attributes, - public diffpy::HasClassRegistry -{ - public: - - // methods - virtual double operator()(const double& r) const = 0; - - private: - - // serialization - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { } - +class DLL_EXPORT PDFEnvelope : public diffpy::Attributes, + public diffpy::HasClassRegistry { + public: + // methods + virtual double operator()(const double& r) const = 0; + + private: + // serialization + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) {} }; - typedef PDFEnvelope::SharedPtr PDFEnvelopePtr; - /// @class PDFEnvelopeOwner /// @brief storage of one or more PDFEnvelope functions and their /// application to unscaled x, y arrays -class PDFEnvelopeOwner -{ - public: - - // application on (x, y) data - QuantityType applyEnvelopes(const QuantityType& x, const QuantityType& y) const; - - // access and configuration of PDF envelope functions - // configuration of envelopes - void addEnvelope(PDFEnvelopePtr); - void addEnvelopeByType(const std::string& tp); - void popEnvelope(PDFEnvelopePtr); - void popEnvelopeByType(const std::string& tp); - const PDFEnvelopePtr& getEnvelopeByType(const std::string& tp) const; - PDFEnvelopePtr& getEnvelopeByType(const std::string& tp); - std::set usedEnvelopeTypes() const; - void clearEnvelopes(); - - private: - - // types - typedef std::map EnvelopeStorage; - - // data - EnvelopeStorage menvelope; - - // serialization - friend class boost::serialization::access; - - template - void serialize(Archive& ar, const unsigned int version) - { - ar & menvelope; - } - +class DLL_EXPORT PDFEnvelopeOwner { + public: + // application on (x, y) data + QuantityType applyEnvelopes(const QuantityType& x, + const QuantityType& y) const; + + // access and configuration of PDF envelope functions + // configuration of envelopes + void addEnvelope(PDFEnvelopePtr); + void addEnvelopeByType(const std::string& tp); + void popEnvelope(PDFEnvelopePtr); + void popEnvelopeByType(const std::string& tp); + const PDFEnvelopePtr& getEnvelopeByType(const std::string& tp) const; + PDFEnvelopePtr& getEnvelopeByType(const std::string& tp); + std::set usedEnvelopeTypes() const; + void clearEnvelopes(); + + private: + // types + typedef std::map EnvelopeStorage; + + // data + EnvelopeStorage menvelope; + + // serialization + friend class boost::serialization::access; + + template + void serialize(Archive& ar, const unsigned int version) { + ar & menvelope; + } }; -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/PDFUtils.cpp b/src/diffpy/srreal/PDFUtils.cpp index 37a50b67..4994c171 100644 --- a/src/diffpy/srreal/PDFUtils.cpp +++ b/src/diffpy/srreal/PDFUtils.cpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* Various common routines useful for PDF calculation. -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * Various common routines useful for PDF calculation. + * + *****************************************************************************/ #include @@ -38,63 +38,56 @@ namespace { const char* EMSGFFT = "Fourier Transformation failed."; -} // namespace +} // namespace // PDFUtils functions -------------------------------------------------------- -QuantityType fftgtof(const QuantityType& g, double rstep, double rmin) -{ - if (g.empty()) return g; - int padrmin = int(round(rmin / rstep)); - int Npad1 = padrmin + g.size(); - // pad to the next power of 2 for fast Fourier transformation - int Npad2 = (1 << int(ceil(log2(Npad1)))); - // sine transformations needs an odd extension - // gpadc array has to be doubled for complex coefficients - int Npad4 = 4 * Npad2; - valarray gpadc(0.0, Npad4); - QuantityType::const_iterator gi; - // copy the original g signal - int ilo = padrmin; - for (gi = g.begin(); gi != g.end(); ++gi, ++ilo) - { - gpadc[2 * ilo] = *gi; - } - // copy the odd part of g skipping the first point, - // because it is periodic image of gpadc[0] - int ihi = 2 * Npad2 - 1; - for (ilo = 1; ilo < Npad2; ++ilo, --ihi) - { - gpadc[2 * ihi] = -1 * gpadc[2 * ilo]; - } - int status; - status = gsl_fft_complex_radix2_inverse(&(gpadc[0]), 1, 2 * Npad2); - if (status != GSL_SUCCESS) throw invalid_argument(EMSGFFT); - QuantityType f(Npad2); - for (int i = 0; i < Npad2; ++i) - { - f[i] = gpadc[2 * i + 1] * Npad2 * rstep; - } - // real components should be all close to zero - assert(fabs(valarray(gpadc[slice(0, 2 * Npad2, 2)]).min()) <= - SQRT_DOUBLE_EPS * gpadc.max()); - assert(fabs(valarray(gpadc[slice(0, 2 * Npad2, 2)]).max()) <= - SQRT_DOUBLE_EPS * gpadc.max()); - return f; +QuantityType fftgtof(const QuantityType& g, double rstep, double rmin) { + if (g.empty()) return g; + int padrmin = int(round(rmin / rstep)); + int Npad1 = padrmin + g.size(); + // pad to the next power of 2 for fast Fourier transformation + int Npad2 = (1 << int(ceil(log2(Npad1)))); + // sine transformations needs an odd extension + // gpadc array has to be doubled for complex coefficients + int Npad4 = 4 * Npad2; + valarray gpadc(0.0, Npad4); + QuantityType::const_iterator gi; + // copy the original g signal + int ilo = padrmin; + for (gi = g.begin(); gi != g.end(); ++gi, ++ilo) { + gpadc[2 * ilo] = *gi; + } + // copy the odd part of g skipping the first point, + // because it is periodic image of gpadc[0] + int ihi = 2 * Npad2 - 1; + for (ilo = 1; ilo < Npad2; ++ilo, --ihi) { + gpadc[2 * ihi] = -1 * gpadc[2 * ilo]; + } + int status; + status = gsl_fft_complex_radix2_inverse(&(gpadc[0]), 1, 2 * Npad2); + if (status != GSL_SUCCESS) throw invalid_argument(EMSGFFT); + QuantityType f(Npad2); + for (int i = 0; i < Npad2; ++i) { + f[i] = gpadc[2 * i + 1] * Npad2 * rstep; + } + // real components should be all close to zero + assert(fabs(valarray(gpadc[slice(0, 2 * Npad2, 2)]).min()) <= + SQRT_DOUBLE_EPS * gpadc.max()); + assert(fabs(valarray(gpadc[slice(0, 2 * Npad2, 2)]).max()) <= + SQRT_DOUBLE_EPS * gpadc.max()); + return f; } - -QuantityType fftftog(const QuantityType& f, double qstep, double qmin) -{ - // ftog is the same as gtof, just normalized by 2 / PI - QuantityType g = fftgtof(f, qstep, qmin); - QuantityType::iterator gi; - for (gi = g.begin(); gi != g.end(); ++gi) *gi *= 2.0 / M_PI; - return g; +QuantityType fftftog(const QuantityType& f, double qstep, double qmin) { + // ftog is the same as gtof, just normalized by 2 / PI + QuantityType g = fftgtof(f, qstep, qmin); + QuantityType::iterator gi; + for (gi = g.begin(); gi != g.end(); ++gi) *gi *= 2.0 / M_PI; + return g; } - -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // End of file diff --git a/src/diffpy/srreal/PDFUtils.hpp b/src/diffpy/srreal/PDFUtils.hpp index 97e2764a..ed40079c 100644 --- a/src/diffpy/srreal/PDFUtils.hpp +++ b/src/diffpy/srreal/PDFUtils.hpp @@ -1,23 +1,23 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* Various common routines useful for PDF calculation: -* meanSquareDisplacement -* maxUii -* fftftog and fftgtof -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * Various common routines useful for PDF calculation: + * meanSquareDisplacement + * maxUii + * fftftog and fftgtof + * + *****************************************************************************/ #ifndef PDFUTILS_HPP_INCLUDED #define PDFUTILS_HPP_INCLUDED @@ -28,6 +28,8 @@ #include #include +#include + namespace diffpy { namespace srreal { @@ -43,23 +45,31 @@ const double DEFAULT_QGRID_QMAX = 10.0; const double DEFAULT_QGRID_QSTEP = 0.05; /// fast Fourier transformation converting G(r) to F(Q) -QuantityType fftgtof(const QuantityType& g, double rstep, double rmin=0.0); +DLL_EXPORT QuantityType fftgtof(const QuantityType& g, double rstep, + double rmin = 0.0); /// fast Fourier transformation converting F(Q) to G(r) -QuantityType fftftog(const QuantityType& f, double qstep, double qmin=0.0); +DLL_EXPORT QuantityType fftftog(const QuantityType& f, double qstep, + double qmin = 0.0); /// shared methods for PDFCalculator and DebyePDFCalculator -template QuantityType pdfutils_getQgrid(const T* pdfc); -template int pdfutils_qminSteps(const T* pdfc); -template int pdfutils_qmaxSteps(const T* pdfc); -template QuantityType pdfutils_getRgrid(const T* pdfc); +template +QuantityType pdfutils_getQgrid(const T* pdfc); +template +int pdfutils_qminSteps(const T* pdfc); +template +int pdfutils_qmaxSteps(const T* pdfc); +template +QuantityType pdfutils_getRgrid(const T* pdfc); int pdfutils_rminSteps(const double& rmin, const double& rstep); -template int pdfutils_rminSteps(const T* pdfc); +template +int pdfutils_rminSteps(const T* pdfc); int pdfutils_rmaxSteps(const double& rmax, const double& rstep); -template int pdfutils_rmaxSteps(const T* pdfc); +template +int pdfutils_rmaxSteps(const T* pdfc); -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Implementation ------------------------------------------------------------ diff --git a/src/diffpy/srreal/PQEvaluator.cpp b/src/diffpy/srreal/PQEvaluator.cpp index 71874053..ff51794d 100644 --- a/src/diffpy/srreal/PQEvaluator.cpp +++ b/src/diffpy/srreal/PQEvaluator.cpp @@ -1,25 +1,24 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class PQEvaluatorBasic -- robust PairQuantity evaluator, the result -* is always calculated from scratch. -* -* class PQEvaluatorOptimized -- optimized PairQuantity evaluator with fast -* quantity updates -* -*****************************************************************************/ - + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class PQEvaluatorBasic -- robust PairQuantity evaluator, the result + * is always calculated from scratch. + * + * class PQEvaluatorOptimized -- optimized PairQuantity evaluator with fast + * quantity updates + * + *****************************************************************************/ #include #include @@ -42,429 +41,340 @@ namespace { // tolerated load variance for splitting outer loop for parallel evaluation const double CPU_LOAD_VARIANCE = 0.1; -SiteIndices -complementary_indices(const int sz, const SiteIndices& indices0) -{ - SiteIndices rv; - rv.reserve(sz); - SiteIndices::const_iterator ii0 = indices0.begin(); - for (int k = 0; k < sz; ++k) - { - if (ii0 == indices0.end() || k < *ii0) - { - rv.push_back(k); - } - else - { - assert(k == *ii0); - ++ii0; - } +SiteIndices complementary_indices(const int sz, const SiteIndices& indices0) { + SiteIndices rv; + rv.reserve(sz); + SiteIndices::const_iterator ii0 = indices0.begin(); + for (int k = 0; k < sz; ++k) { + if (ii0 == indices0.end() || k < *ii0) { + rv.push_back(k); + } else { + assert(k == *ii0); + ++ii0; } - return rv; + } + return rv; } -} // namespace +} // namespace ////////////////////////////////////////////////////////////////////////////// // class PQEvaluatorBasic ////////////////////////////////////////////////////////////////////////////// -PQEvaluatorBasic::PQEvaluatorBasic() : - mconfigflags(0), - mcpuindex(0), mncpu(1), mtypeused(NONE) -{ } - - -PQEvaluatorType PQEvaluatorBasic::typeint() const -{ - return BASIC; -} - - -PQEvaluatorType PQEvaluatorBasic::typeintused() const -{ - return mtypeused; -} - - -void PQEvaluatorBasic::validate(PairQuantity& pq) const -{ - return; -} - - -void PQEvaluatorBasic::updateValue( - PairQuantity& pq, StructureAdapterPtr stru) -{ - mtypeused = BASIC; - pq.setStructure(stru); - BaseBondGeneratorPtr bnds = pq.mstructure->createBondGenerator(); - pq.configureBondGenerator(*bnds); - int cntsites = pq.mstructure->countSites(); - // loop counter - long n = mcpuindex; - // split outer loop for many atoms. The CPUs should have similar load. - bool chop_outer = (mncpu <= ((cntsites - 1) * CPU_LOAD_VARIANCE + 1)); - bool chop_inner = !chop_outer; - const bool hasmask = pq.hasMask(); - if (!this->isParallel()) chop_outer = chop_inner = false; - const bool usefullsum = this->getFlag(USEFULLSUM); - for (int i0 = 0; i0 < cntsites; ++i0) - { - if (chop_outer && (n++ % mncpu)) continue; - bnds->selectAnchorSite(i0); - int i1hi = usefullsum ? cntsites : (i0 + 1); - bnds->selectSiteRange(0, i1hi); - for (bnds->rewind(); !bnds->finished(); bnds->next()) - { - if (chop_inner && (n++ % mncpu)) continue; - int i1 = bnds->site1(); - if (hasmask && !pq.getPairMask(i0, i1)) continue; - int summationscale = (usefullsum || i0 == i1) ? 1 : 2; - pq.addPairContribution(*bnds, summationscale); - } +PQEvaluatorBasic::PQEvaluatorBasic() + : mconfigflags(0), mcpuindex(0), mncpu(1), mtypeused(NONE) {} + +PQEvaluatorType PQEvaluatorBasic::typeint() const { return BASIC; } + +PQEvaluatorType PQEvaluatorBasic::typeintused() const { return mtypeused; } + +void PQEvaluatorBasic::validate(PairQuantity& pq) const { return; } + +void PQEvaluatorBasic::updateValue(PairQuantity& pq, StructureAdapterPtr stru) { + mtypeused = BASIC; + pq.setStructure(stru); + BaseBondGeneratorPtr bnds = pq.mstructure->createBondGenerator(); + pq.configureBondGenerator(*bnds); + int cntsites = pq.mstructure->countSites(); + // loop counter + long n = mcpuindex; + // split outer loop for many atoms. The CPUs should have similar load. + bool chop_outer = (mncpu <= ((cntsites - 1) * CPU_LOAD_VARIANCE + 1)); + bool chop_inner = !chop_outer; + const bool hasmask = pq.hasMask(); + if (!this->isParallel()) chop_outer = chop_inner = false; + const bool usefullsum = this->getFlag(USEFULLSUM); + for (int i0 = 0; i0 < cntsites; ++i0) { + if (chop_outer && (n++ % mncpu)) continue; + bnds->selectAnchorSite(i0); + int i1hi = usefullsum ? cntsites : (i0 + 1); + bnds->selectSiteRange(0, i1hi); + for (bnds->rewind(); !bnds->finished(); bnds->next()) { + if (chop_inner && (n++ % mncpu)) continue; + int i1 = bnds->site1(); + if (hasmask && !pq.getPairMask(i0, i1)) continue; + int summationscale = (usefullsum || i0 == i1) ? 1 : 2; + pq.addPairContribution(*bnds, summationscale); } - mvalue_ticker.click(); + } + mvalue_ticker.click(); } - -void PQEvaluatorBasic::setFlag(PQEvaluatorFlag flag, bool value) -{ - if (value) mconfigflags |= int(flag); - else mconfigflags &= ~int(flag); +void PQEvaluatorBasic::setFlag(PQEvaluatorFlag flag, bool value) { + if (value) + mconfigflags |= int(flag); + else + mconfigflags &= ~int(flag); } - -bool PQEvaluatorBasic::getFlag(PQEvaluatorFlag flag) const -{ - return mconfigflags & int(flag); +bool PQEvaluatorBasic::getFlag(PQEvaluatorFlag flag) const { + return mconfigflags & int(flag); } - -void PQEvaluatorBasic::setupParallelRun(int cpuindex, int ncpu) -{ - // make sure ncpu is at least one - if (ncpu < 1) - { - const char* emsg = "Number of CPU ncpu must be at least 1."; - throw invalid_argument(emsg); - } - mcpuindex = cpuindex; - mncpu = ncpu; +void PQEvaluatorBasic::setupParallelRun(int cpuindex, int ncpu) { + // make sure ncpu is at least one + if (ncpu < 1) { + const char* emsg = "Number of CPU ncpu must be at least 1."; + throw invalid_argument(emsg); + } + mcpuindex = cpuindex; + mncpu = ncpu; } - -bool PQEvaluatorBasic::isParallel() const -{ - return mncpu > 1; -} +bool PQEvaluatorBasic::isParallel() const { return mncpu > 1; } ////////////////////////////////////////////////////////////////////////////// // class PQEvaluatorOptimized ////////////////////////////////////////////////////////////////////////////// -PQEvaluatorType PQEvaluatorOptimized::typeint() const -{ - return OPTIMIZED; -} +PQEvaluatorType PQEvaluatorOptimized::typeint() const { return OPTIMIZED; } - -void PQEvaluatorOptimized::validate(PairQuantity& pq) const -{ - // Check if PairQuantity provides stashPartialValue. - pq.stashPartialValue(); - pq.restorePartialValue(); +void PQEvaluatorOptimized::validate(PairQuantity& pq) const { + // Check if PairQuantity provides stashPartialValue. + pq.stashPartialValue(); + pq.restorePartialValue(); } - -void PQEvaluatorOptimized::updateValue( - PairQuantity& pq, StructureAdapterPtr stru) -{ - mtypeused = OPTIMIZED; - // revert to normal calculation if there is no structure or - // if PairQuantity uses mask - if (pq.ticker() >= mvalue_ticker || !mlast_structure) - { - return this->updateValueCompletely(pq, stru); +void PQEvaluatorOptimized::updateValue(PairQuantity& pq, + StructureAdapterPtr stru) { + mtypeused = OPTIMIZED; + // revert to normal calculation if there is no structure or + // if PairQuantity uses mask + if (pq.ticker() >= mvalue_ticker || !mlast_structure) { + return this->updateValueCompletely(pq, stru); + } + // do not do fast updates if they take more work + StructureDifference sd = mlast_structure->diff(stru); + if (!sd.allowsfastupdate()) { + return this->updateValueCompletely(pq, stru); + } + if ((this->getFlag(FIXEDSITEINDEX) || pq.hasPairMask()) && + sd.diffmethod != StructureDifference::Method::SIDEBYSIDE) { + return this->updateValueCompletely(pq, stru); + } + // Remove contributions from the extra sites in the old structure + assert(sd.stru0 == mlast_structure); + int cntsites0 = sd.stru0->countSites(); + BaseBondGeneratorPtr bnds0 = sd.stru0->createBondGenerator(); + pq.configureBondGenerator(*bnds0); + // loop counter + long n = mcpuindex; + bool usefullsum = this->getFlag(USEFULLSUM); + // the loop is adjusted according to usefullsum and split within + // the outer loop in case of parallel evaluation. + SiteIndices anchors = sd.pop0; + SiteIndices unchanged; + if (!sd.pop0.empty()) { + unchanged = complementary_indices(cntsites0, sd.pop0); + anchors.insert(anchors.end(), unchanged.begin(), unchanged.end()); + } + bnds0->selectSites(anchors.begin(), anchors.end()); + SiteIndices::const_iterator last_anchor = + usefullsum ? anchors.end() : (anchors.begin() + sd.pop0.size()); + SiteIndices::const_iterator ii0; + bool needsreselection = usefullsum; + const bool hasmask = pq.hasMask(); + for (ii0 = anchors.begin(); ii0 != last_anchor; ++ii0) { + if (n++ % mncpu) continue; + const int& i0 = *ii0; + bnds0->selectAnchorSite(i0); + // when using half sum, deselect visited popped sites + if (!usefullsum) bnds0->selectSites(ii0, anchors.end()); + // when using full sum, select only the popped sites when + // anchored at an unchanged atom + else if (needsreselection && ii0 >= (anchors.begin() + sd.pop0.size())) { + bnds0->selectSites(sd.pop0.begin(), sd.pop0.end()); + needsreselection = false; } - // do not do fast updates if they take more work - StructureDifference sd = mlast_structure->diff(stru); - if (!sd.allowsfastupdate()) - { - return this->updateValueCompletely(pq, stru); + for (bnds0->rewind(); !bnds0->finished(); bnds0->next()) { + int i1 = bnds0->site1(); + if (hasmask && !pq.getPairMask(i0, i1)) continue; + const int summationscale = (usefullsum || i0 == i1) ? -1 : -2; + pq.addPairContribution(*bnds0, summationscale); } - if ((this->getFlag(FIXEDSITEINDEX) || pq.hasPairMask()) && - sd.diffmethod != StructureDifference::Method::SIDEBYSIDE) - { - return this->updateValueCompletely(pq, stru); + } + // Add contributions from the new atoms in the updated structure + // save current value to override the resetValue call from setStructure + assert(sd.stru1); + pq.stashPartialValue(); + // setStructure(stru1) calls stru1->customPQConfig(pq), which may totally + // change pq configuration. If so, revert to full calculation. + assert(pq.ticker() < mvalue_ticker); + pq.setStructure(sd.stru1); + if (pq.ticker() >= mvalue_ticker) { + return this->updateValueCompletely(pq, stru); + } + pq.restorePartialValue(); + int cntsites1 = sd.stru1->countSites(); + BaseBondGeneratorPtr bnds1 = sd.stru1->createBondGenerator(); + pq.configureBondGenerator(*bnds1); + anchors = sd.add1; + unchanged.clear(); + if (!sd.add1.empty()) { + unchanged = complementary_indices(cntsites1, sd.add1); + anchors.insert(anchors.begin(), unchanged.begin(), unchanged.end()); + } + bnds1->selectSites(sd.add1.begin(), sd.add1.end()); + SiteIndices::const_iterator first_anchor = + usefullsum ? anchors.begin() : (anchors.end() - sd.add1.size()); + SiteIndices::const_iterator ii1; + needsreselection = usefullsum; + for (ii1 = first_anchor; ii1 != anchors.end(); ++ii1) { + if (n++ % mncpu) continue; + const int& i0 = *ii1; + bnds1->selectAnchorSite(i0); + // when using half sum, activate the added site + if (!usefullsum) bnds1->selectSites(anchors.begin(), ii1 + 1); + // when using full sum select unchanged atoms once anchored + // at an added atom. + else if (needsreselection && ii1 >= (anchors.end() - sd.add1.size())) { + bnds1->selectSites(anchors.begin(), anchors.end()); + needsreselection = false; } - // Remove contributions from the extra sites in the old structure - assert(sd.stru0 == mlast_structure); - int cntsites0 = sd.stru0->countSites(); - BaseBondGeneratorPtr bnds0 = sd.stru0->createBondGenerator(); - pq.configureBondGenerator(*bnds0); - // loop counter - long n = mcpuindex; - bool usefullsum = this->getFlag(USEFULLSUM); - // the loop is adjusted according to usefullsum and split within - // the outer loop in case of parallel evaluation. - SiteIndices anchors = sd.pop0; - SiteIndices unchanged; - if (!sd.pop0.empty()) - { - unchanged = complementary_indices(cntsites0, sd.pop0); - anchors.insert(anchors.end(), unchanged.begin(), unchanged.end()); + for (bnds1->rewind(); !bnds1->finished(); bnds1->next()) { + int i1 = bnds1->site1(); + if (hasmask && !pq.getPairMask(i0, i1)) continue; + const int summationscale = (usefullsum || i0 == i1) ? +1 : +2; + pq.addPairContribution(*bnds1, summationscale); } - bnds0->selectSites(anchors.begin(), anchors.end()); - SiteIndices::const_iterator last_anchor = usefullsum ? - anchors.end() : (anchors.begin() + sd.pop0.size()); - SiteIndices::const_iterator ii0; - bool needsreselection = usefullsum; - const bool hasmask = pq.hasMask(); - for (ii0 = anchors.begin(); ii0 != last_anchor; ++ii0) - { - if (n++ % mncpu) continue; - const int& i0 = *ii0; - bnds0->selectAnchorSite(i0); - // when using half sum, deselect visited popped sites - if (!usefullsum) bnds0->selectSites(ii0, anchors.end()); - // when using full sum, select only the popped sites when - // anchored at an unchanged atom - else if (needsreselection && ii0 >= (anchors.begin() + sd.pop0.size())) - { - bnds0->selectSites(sd.pop0.begin(), sd.pop0.end()); - needsreselection = false; - } - for (bnds0->rewind(); !bnds0->finished(); bnds0->next()) - { - int i1 = bnds0->site1(); - if (hasmask && !pq.getPairMask(i0, i1)) continue; - const int summationscale = (usefullsum || i0 == i1) ? -1 : -2; - pq.addPairContribution(*bnds0, summationscale); - } - } - // Add contributions from the new atoms in the updated structure - // save current value to override the resetValue call from setStructure - assert(sd.stru1); - pq.stashPartialValue(); - // setStructure(stru1) calls stru1->customPQConfig(pq), which may totally - // change pq configuration. If so, revert to full calculation. - assert(pq.ticker() < mvalue_ticker); - pq.setStructure(sd.stru1); - if (pq.ticker() >= mvalue_ticker) - { - return this->updateValueCompletely(pq, stru); - } - pq.restorePartialValue(); - int cntsites1 = sd.stru1->countSites(); - BaseBondGeneratorPtr bnds1 = sd.stru1->createBondGenerator(); - pq.configureBondGenerator(*bnds1); - anchors = sd.add1; - unchanged.clear(); - if (!sd.add1.empty()) - { - unchanged = complementary_indices(cntsites1, sd.add1); - anchors.insert(anchors.begin(), unchanged.begin(), unchanged.end()); - } - bnds1->selectSites(sd.add1.begin(), sd.add1.end()); - SiteIndices::const_iterator first_anchor = usefullsum ? - anchors.begin() : (anchors.end() - sd.add1.size()); - SiteIndices::const_iterator ii1; - needsreselection = usefullsum; - for (ii1 = first_anchor; ii1 != anchors.end(); ++ii1) - { - if (n++ % mncpu) continue; - const int& i0 = *ii1; - bnds1->selectAnchorSite(i0); - // when using half sum, activate the added site - if (!usefullsum) bnds1->selectSites(anchors.begin(), ii1 + 1); - // when using full sum select unchanged atoms once anchored - // at an added atom. - else if (needsreselection && ii1 >= (anchors.end() - sd.add1.size())) - { - bnds1->selectSites(anchors.begin(), anchors.end()); - needsreselection = false; - } - for (bnds1->rewind(); !bnds1->finished(); bnds1->next()) - { - int i1 = bnds1->site1(); - if (hasmask && !pq.getPairMask(i0, i1)) continue; - const int summationscale = (usefullsum || i0 == i1) ? +1 : +2; - pq.addPairContribution(*bnds1, summationscale); - } - } - mlast_structure = pq.getStructure()->clone(); - mvalue_ticker.click(); + } + mlast_structure = pq.getStructure()->clone(); + mvalue_ticker.click(); } - -void PQEvaluatorOptimized::updateValueCompletely( - PairQuantity& pq, StructureAdapterPtr stru) -{ - this->PQEvaluatorBasic::updateValue(pq, stru); - mlast_structure = pq.getStructure()->clone(); +void PQEvaluatorOptimized::updateValueCompletely(PairQuantity& pq, + StructureAdapterPtr stru) { + this->PQEvaluatorBasic::updateValue(pq, stru); + mlast_structure = pq.getStructure()->clone(); } // Helper classes and functions for PQEvaluatorCheck ------------------------- namespace { -bool cmpfabs(const double& x, const double& y) -{ - return fabs(x) < fabs(y); -} - - -class pqresults -{ - public: - - pqresults(const PairQuantity& pq) : - msaved_value(pq.value()) - { } - - - virtual ~pqresults() { } +bool cmpfabs(const double& x, const double& y) { return fabs(x) < fabs(y); } +class pqresults { + public: + pqresults(const PairQuantity& pq) : msaved_value(pq.value()) {} - virtual bool compare(const PairQuantity& pq) const - { - QuantityType::const_iterator smx = max_element( - msaved_value.begin(), msaved_value.end(), cmpfabs); - const double eps = R3::SQRT_DOUBLE_EPS * - (msaved_value.empty() ? 1.0 : max(*smx, 1.0)); - mathutils::EpsilonEqual allclose(eps); - const QuantityType& cur_value = pq.value(); - return allclose(msaved_value, cur_value); - } + virtual ~pqresults() {} - private: + virtual bool compare(const PairQuantity& pq) const { + QuantityType::const_iterator smx = + max_element(msaved_value.begin(), msaved_value.end(), cmpfabs); + const double eps = + R3::SQRT_DOUBLE_EPS * (msaved_value.empty() ? 1.0 : max(*smx, 1.0)); + mathutils::EpsilonEqual allclose(eps); + const QuantityType& cur_value = pq.value(); + return allclose(msaved_value, cur_value); + } - // data - QuantityType msaved_value; + private: + // data + QuantityType msaved_value; }; - -class pqresults_bondcalculator : public pqresults -{ - public: - - pqresults_bondcalculator(const BondCalculator& bc) : - pqresults(bc), - msaved_directions(bc.directions()), - msaved_sites0(bc.sites0()), - msaved_sites1(bc.sites1()), - msaved_types0(bc.types0()), - msaved_types1(bc.types1()) - { } - - - virtual bool compare(const PairQuantity& pq) const - { - if (!(this->pqresults::compare(pq))) return false; - const BondCalculator& bc = dynamic_cast(pq); - if (msaved_sites0 != bc.sites0()) return false; - if (msaved_sites1 != bc.sites1()) return false; - if (msaved_types0 != bc.types0()) return false; - if (msaved_types1 != bc.types1()) return false; - const vector cur_directions = bc.directions(); - const bool szneq = - msaved_directions.size() != cur_directions.size(); - if (szneq) return false; - vector::const_iterator sv, cv; - sv = msaved_directions.begin(); - cv = cur_directions.begin(); - mathutils::EpsilonEqual allclose; - for (; sv != msaved_directions.end(); ++sv, ++cv) - { - if (!allclose(*sv, *cv)) return false; - } - return true; - } - - private: - - // data - vector msaved_directions; - SiteIndices msaved_sites0; - SiteIndices msaved_sites1; - vector msaved_types0; - vector msaved_types1; +class pqresults_bondcalculator : public pqresults { + public: + pqresults_bondcalculator(const BondCalculator& bc) + : pqresults(bc), + msaved_directions(bc.directions()), + msaved_sites0(bc.sites0()), + msaved_sites1(bc.sites1()), + msaved_types0(bc.types0()), + msaved_types1(bc.types1()) {} + + virtual bool compare(const PairQuantity& pq) const { + if (!(this->pqresults::compare(pq))) return false; + const BondCalculator& bc = dynamic_cast(pq); + if (msaved_sites0 != bc.sites0()) return false; + if (msaved_sites1 != bc.sites1()) return false; + if (msaved_types0 != bc.types0()) return false; + if (msaved_types1 != bc.types1()) return false; + const vector cur_directions = bc.directions(); + const bool szneq = msaved_directions.size() != cur_directions.size(); + if (szneq) return false; + vector::const_iterator sv, cv; + sv = msaved_directions.begin(); + cv = cur_directions.begin(); + mathutils::EpsilonEqual allclose; + for (; sv != msaved_directions.end(); ++sv, ++cv) { + if (!allclose(*sv, *cv)) return false; + } + return true; + } + + private: + // data + vector msaved_directions; + SiteIndices msaved_sites0; + SiteIndices msaved_sites1; + vector msaved_types0; + vector msaved_types1; }; - -pqresults* create_pqresults(const PairQuantity& pq) -{ - const BondCalculator* pbc = dynamic_cast(&pq); - if (pbc) return new pqresults_bondcalculator(*pbc); - return new pqresults(pq); +pqresults* create_pqresults(const PairQuantity& pq) { + const BondCalculator* pbc = dynamic_cast(&pq); + if (pbc) return new pqresults_bondcalculator(*pbc); + return new pqresults(pq); } -} // namespace +} // namespace ////////////////////////////////////////////////////////////////////////////// // class PQEvaluatorCheck ////////////////////////////////////////////////////////////////////////////// -PQEvaluatorType PQEvaluatorCheck::typeint() const -{ - return CHECK; -} - - -void PQEvaluatorCheck::updateValue( - PairQuantity& pq, StructureAdapterPtr stru) -{ - this->PQEvaluatorOptimized::updateValue(pq, stru); - if (mtypeused == BASIC) return; - unique_ptr results(create_pqresults(pq)); - this->PQEvaluatorBasic::updateValue(pq, stru); - mtypeused = CHECK; - if (!results->compare(pq)) - { - const char* emsg = "Inconsistent results from OPTIMIZED evaluation."; - throw logic_error(emsg); - } +PQEvaluatorType PQEvaluatorCheck::typeint() const { return CHECK; } + +void PQEvaluatorCheck::updateValue(PairQuantity& pq, StructureAdapterPtr stru) { + this->PQEvaluatorOptimized::updateValue(pq, stru); + if (mtypeused == BASIC) return; + unique_ptr results(create_pqresults(pq)); + this->PQEvaluatorBasic::updateValue(pq, stru); + mtypeused = CHECK; + if (!results->compare(pq)) { + const char* emsg = "Inconsistent results from OPTIMIZED evaluation."; + throw logic_error(emsg); + } } // Factory for PairQuantity evaluators --------------------------------------- -PQEvaluatorPtr createPQEvaluator(PQEvaluatorType pqtp, PQEvaluatorPtr pqevsrc) -{ - PQEvaluatorPtr rv; - switch (pqtp) - { - case BASIC: - rv.reset(new PQEvaluatorBasic()); - break; - - case OPTIMIZED: - rv.reset(new PQEvaluatorOptimized()); - break; - - case CHECK: - rv.reset(new PQEvaluatorCheck()); - break; - - default: - ostringstream emsg; - emsg << "Invalid PQEvaluatorType value " << pqtp; - throw invalid_argument(emsg.str()); - } - if (pqevsrc) - { - rv->mconfigflags = pqevsrc->mconfigflags; - rv->mcpuindex = pqevsrc->mcpuindex; - rv->mncpu = pqevsrc->mncpu; - rv->mvalue_ticker = pqevsrc->mvalue_ticker; - rv->mtypeused = pqevsrc->mtypeused; - } - return rv; +PQEvaluatorPtr createPQEvaluator(PQEvaluatorType pqtp, PQEvaluatorPtr pqevsrc) { + PQEvaluatorPtr rv; + switch (pqtp) { + case BASIC: + rv.reset(new PQEvaluatorBasic()); + break; + + case OPTIMIZED: + rv.reset(new PQEvaluatorOptimized()); + break; + + case CHECK: + rv.reset(new PQEvaluatorCheck()); + break; + + default: + ostringstream emsg; + emsg << "Invalid PQEvaluatorType value " << pqtp; + throw invalid_argument(emsg.str()); + } + if (pqevsrc) { + rv->mconfigflags = pqevsrc->mconfigflags; + rv->mcpuindex = pqevsrc->mcpuindex; + rv->mncpu = pqevsrc->mncpu; + rv->mvalue_ticker = pqevsrc->mvalue_ticker; + rv->mtypeused = pqevsrc->mtypeused; + } + return rv; } - -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/PQEvaluator.hpp b/src/diffpy/srreal/PQEvaluator.hpp index 8fa5f228..049ae786 100644 --- a/src/diffpy/srreal/PQEvaluator.hpp +++ b/src/diffpy/srreal/PQEvaluator.hpp @@ -1,25 +1,24 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class PQEvaluatorBasic -- robust PairQuantity evaluator, the result -* is always calculated from scratch. -* -* class PQEvaluatorOptimized -- optimized PairQuantity evaluator with fast -* quantity updates -* -*****************************************************************************/ - + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class PQEvaluatorBasic -- robust PairQuantity evaluator, the result + * is always calculated from scratch. + * + * class PQEvaluatorOptimized -- optimized PairQuantity evaluator with fast + * quantity updates + * + *****************************************************************************/ #ifndef PQEVALUATOR_HPP_INCLUDED #define PQEVALUATOR_HPP_INCLUDED @@ -33,6 +32,8 @@ #include #include +#include + namespace diffpy { namespace srreal { @@ -42,118 +43,102 @@ class PairQuantity; typedef boost::shared_ptr PQEvaluatorPtr; -enum PQEvaluatorType {NONE, BASIC, OPTIMIZED, CHECK}; +enum PQEvaluatorType { NONE, BASIC, OPTIMIZED, CHECK }; enum PQEvaluatorFlag { - // sum over full matrix of atom pairs, use pair symmetry otherwise. - USEFULLSUM = 1, - // allow fast updates only if unchanged atoms keep their indices. - FIXEDSITEINDEX = 2, + // sum over full matrix of atom pairs, use pair symmetry otherwise. + USEFULLSUM = 1, + // allow fast updates only if unchanged atoms keep their indices. + FIXEDSITEINDEX = 2, }; -class PQEvaluatorBasic -{ - public: - - friend - PQEvaluatorPtr createPQEvaluator(PQEvaluatorType, PQEvaluatorPtr); - // constructor - PQEvaluatorBasic(); - virtual ~PQEvaluatorBasic() { } - - // methods - virtual PQEvaluatorType typeint() const; - PQEvaluatorType typeintused() const; - virtual void updateValue(PairQuantity&, StructureAdapterPtr); - virtual void validate(PairQuantity&) const; - void setFlag(PQEvaluatorFlag flag, bool value); - bool getFlag(PQEvaluatorFlag flag) const; - void setupParallelRun(int cpuindex, int ncpu); - bool isParallel() const; - - protected: - - - // data - /// per-bit storage of boolean configuration flags - int mconfigflags; - /// zero-based index of this CPU - int mcpuindex; - /// total number of the CPU units - int mncpu; - /// ticker for recording when was the value updated - eventticker::EventTicker mvalue_ticker; - /// type of PQEvaluator that was actually used - PQEvaluatorType mtypeused; - - private: - - // serialization - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - ar & mconfigflags & mcpuindex & mncpu & mvalue_ticker; - } +class DLL_EXPORT PQEvaluatorBasic { + public: + friend DLL_EXPORT PQEvaluatorPtr createPQEvaluator(PQEvaluatorType, + PQEvaluatorPtr); + // constructor + PQEvaluatorBasic(); + virtual ~PQEvaluatorBasic() {} + + // methods + virtual PQEvaluatorType typeint() const; + PQEvaluatorType typeintused() const; + virtual void updateValue(PairQuantity&, StructureAdapterPtr); + virtual void validate(PairQuantity&) const; + void setFlag(PQEvaluatorFlag flag, bool value); + bool getFlag(PQEvaluatorFlag flag) const; + void setupParallelRun(int cpuindex, int ncpu); + bool isParallel() const; + + protected: + // data + /// per-bit storage of boolean configuration flags + int mconfigflags; + /// zero-based index of this CPU + int mcpuindex; + /// total number of the CPU units + int mncpu; + /// ticker for recording when was the value updated + eventticker::EventTicker mvalue_ticker; + /// type of PQEvaluator that was actually used + PQEvaluatorType mtypeused; + + private: + // serialization + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + ar & mconfigflags & mcpuindex & mncpu & mvalue_ticker; + } }; - -class PQEvaluatorOptimized : public PQEvaluatorBasic -{ - public: - - // methods - virtual PQEvaluatorType typeint() const; - virtual void validate(PairQuantity&) const; - virtual void updateValue(PairQuantity&, StructureAdapterPtr); - - private: - - // data - StructureAdapterPtr mlast_structure; - - // helper method - void updateValueCompletely(PairQuantity&, StructureAdapterPtr); - - // serialization - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - using boost::serialization::base_object; - ar & base_object(*this); - ar & mlast_structure; - } +class DLL_EXPORT PQEvaluatorOptimized : public PQEvaluatorBasic { + public: + // methods + virtual PQEvaluatorType typeint() const; + virtual void validate(PairQuantity&) const; + virtual void updateValue(PairQuantity&, StructureAdapterPtr); + + private: + // data + StructureAdapterPtr mlast_structure; + + // helper method + void updateValueCompletely(PairQuantity&, StructureAdapterPtr); + + // serialization + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + using boost::serialization::base_object; + ar& base_object(*this); + ar & mlast_structure; + } }; - -class PQEvaluatorCheck : public PQEvaluatorOptimized -{ - public: - - // methods - virtual PQEvaluatorType typeint() const; - virtual void updateValue(PairQuantity&, StructureAdapterPtr); - - private: - - // serialization - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - using boost::serialization::base_object; - ar & base_object(*this); - } +class DLL_EXPORT PQEvaluatorCheck : public PQEvaluatorOptimized { + public: + // methods + virtual PQEvaluatorType typeint() const; + virtual void updateValue(PairQuantity&, StructureAdapterPtr); + + private: + // serialization + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + using boost::serialization::base_object; + ar& base_object(*this); + } }; // Factory function for PairQuantity evaluators ------------------------------ -PQEvaluatorPtr createPQEvaluator( - PQEvaluatorType pqtp, PQEvaluatorPtr pqevsrc=PQEvaluatorPtr()); +DLL_EXPORT PQEvaluatorPtr createPQEvaluator( + PQEvaluatorType pqtp, PQEvaluatorPtr pqevsrc = PQEvaluatorPtr()); -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/PairCounter.cpp b/src/diffpy/srreal/PairCounter.cpp index e11c9f91..71fbe0c9 100644 --- a/src/diffpy/srreal/PairCounter.cpp +++ b/src/diffpy/srreal/PairCounter.cpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class PairCounter -- concrete counter of pairs in a structure. -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class PairCounter -- concrete counter of pairs in a structure. + * + *****************************************************************************/ #include @@ -22,19 +22,17 @@ using namespace diffpy::srreal; // Constructor --------------------------------------------------------------- -PairCounter::PairCounter() -{ - // use very large default rmax. - this->setRmax(1000); - this->resizeValue(1); +PairCounter::PairCounter() { + // use very large default rmax. + this->setRmax(1000); + this->resizeValue(1); } // Protected Methods --------------------------------------------------------- void PairCounter::addPairContribution(const BaseBondGenerator& bnds, - int summationscale) -{ - mvalue.front() += summationscale / 2.0; + int summationscale) { + mvalue.front() += summationscale / 2.0; } // End of file diff --git a/src/diffpy/srreal/PairCounter.hpp b/src/diffpy/srreal/PairCounter.hpp index eef4b92a..d11855ae 100644 --- a/src/diffpy/srreal/PairCounter.hpp +++ b/src/diffpy/srreal/PairCounter.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class PairCounter -- concrete counter of pairs in a structure. -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class PairCounter -- concrete counter of pairs in a structure. + * + *****************************************************************************/ #ifndef PAIRCOUNTER_HPP_INCLUDED #define PAIRCOUNTER_HPP_INCLUDED @@ -24,35 +24,30 @@ namespace diffpy { namespace srreal { -class PairCounter : public PairQuantity -{ - public: +class PairCounter : public PairQuantity { + public: + // constructor + PairCounter(); - // constructor - PairCounter(); - - // methods - template int operator()(const T&); - - protected: - - // methods - virtual void addPairContribution(const BaseBondGenerator&, int); + // methods + template + int operator()(const T&); + protected: + // methods + virtual void addPairContribution(const BaseBondGenerator&, int); }; // Public Template Methods --------------------------------------------------- template -int PairCounter::operator()(const T& stru) -{ - this->eval(stru); - int cnt = int(this->value().front()); - return cnt; +int PairCounter::operator()(const T& stru) { + this->eval(stru); + int cnt = int(this->value().front()); + return cnt; } - -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy #endif // PAIRCOUNTER_HPP_INCLUDED diff --git a/src/diffpy/srreal/PairQuantity.cpp b/src/diffpy/srreal/PairQuantity.cpp index b525b546..060b0938 100644 --- a/src/diffpy/srreal/PairQuantity.cpp +++ b/src/diffpy/srreal/PairQuantity.cpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy 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. -* -****************************************************************************** -* -* class PairQuantity -- general implementation of pair quantity calculator -* -*****************************************************************************/ + * + * libdiffpy 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. + * + ****************************************************************************** + * + * class PairQuantity -- general implementation of pair quantity calculator + * + *****************************************************************************/ #include #include @@ -36,456 +36,349 @@ const string PairQuantity::ALLATOMSSTR = "all"; // Constructor --------------------------------------------------------------- -PairQuantity::PairQuantity() : - mstructure(emptyStructureAdapter()), - mrmin(0.0), - mrmax(DEFAULT_BONDGENERATOR_RMAX), - mdefaultpairmask(true) -{ - this->setEvaluatorType(BASIC); - // attributes - this->registerDoubleAttribute("rmin", this, - &PairQuantity::getRmin, &PairQuantity::setRmin); - this->registerDoubleAttribute("rmax", this, - &PairQuantity::getRmax, &PairQuantity::setRmax); +PairQuantity::PairQuantity() + : mstructure(emptyStructureAdapter()), + mrmin(0.0), + mrmax(DEFAULT_BONDGENERATOR_RMAX), + mdefaultpairmask(true) { + this->setEvaluatorType(BASIC); + // attributes + this->registerDoubleAttribute("rmin", this, &PairQuantity::getRmin, + &PairQuantity::setRmin); + this->registerDoubleAttribute("rmax", this, &PairQuantity::getRmax, + &PairQuantity::setRmax); } // Public Methods ------------------------------------------------------------ -const QuantityType& PairQuantity::eval() -{ - return this->eval(mstructure); -} - +const QuantityType& PairQuantity::eval() { return this->eval(mstructure); } -const QuantityType& PairQuantity::eval(StructureAdapterPtr stru) -{ - mevaluator->updateValue(*this, stru); - this->finishValue(); - return this->value(); +const QuantityType& PairQuantity::eval(StructureAdapterPtr stru) { + mevaluator->updateValue(*this, stru); + this->finishValue(); + return this->value(); } - -void PairQuantity::setStructure(StructureAdapterPtr stru) -{ - mstructure = stru.get() ? stru : emptyStructureAdapter(); - mstructure->customPQConfig(this); - this->updateMaskData(); - this->resetValue(); +void PairQuantity::setStructure(StructureAdapterPtr stru) { + mstructure = stru.get() ? stru : emptyStructureAdapter(); + mstructure->customPQConfig(this); + this->updateMaskData(); + this->resetValue(); } +StructureAdapterPtr& PairQuantity::getStructure() { return mstructure; } -StructureAdapterPtr& PairQuantity::getStructure() -{ - return mstructure; +const StructureAdapterPtr& PairQuantity::getStructure() const { + return mstructure; } +const QuantityType& PairQuantity::value() const { return mvalue; } -const StructureAdapterPtr& PairQuantity::getStructure() const -{ - return mstructure; +void PairQuantity::mergeParallelData(const string& pdata, int ncpu) { + if (mmergedvaluescount >= ncpu) { + const char* emsg = "Number of merged values exceeds NCPU."; + throw runtime_error(emsg); + } + this->executeParallelMerge(pdata); + ++mmergedvaluescount; + if (mmergedvaluescount == ncpu) this->finishValue(); } - -const QuantityType& PairQuantity::value() const -{ - return mvalue; +string PairQuantity::getParallelData() const { + ostringstream storage(ios::binary); + diffpy::serialization::oarchive oa(storage, ios::binary); + oa << this->value(); + return storage.str(); } - -void PairQuantity::mergeParallelData(const string& pdata, int ncpu) -{ - if (mmergedvaluescount >= ncpu) - { - const char* emsg = "Number of merged values exceeds NCPU."; - throw runtime_error(emsg); - } - this->executeParallelMerge(pdata); - ++mmergedvaluescount; - if (mmergedvaluescount == ncpu) this->finishValue(); -} - - -string PairQuantity::getParallelData() const -{ - ostringstream storage(ios::binary); - diffpy::serialization::oarchive oa(storage, ios::binary); - oa << this->value(); - return storage.str(); +void PairQuantity::setRmin(double rmin) { + if (mrmin != rmin) mticker.click(); + mrmin = rmin; } +const double& PairQuantity::getRmin() const { return mrmin; } -void PairQuantity::setRmin(double rmin) -{ - if (mrmin != rmin) mticker.click(); - mrmin = rmin; +void PairQuantity::setRmax(double rmax) { + if (mrmax != rmax) mticker.click(); + mrmax = rmax; } +const double& PairQuantity::getRmax() const { return mrmax; } -const double& PairQuantity::getRmin() const -{ - return mrmin; +void PairQuantity::setEvaluatorType(PQEvaluatorType evtp) { + if (mevaluator.get() && mevaluator->typeint() == evtp) return; + PQEvaluatorPtr pqev = createPQEvaluator(evtp, mevaluator); + // validate the new evaluator object + try { + pqev->validate(*this); + } catch (logic_error e) { + string emsg("EvaluatorType not supported. "); + emsg += e.what(); + throw invalid_argument(emsg); + } + // validator is good here, use it now. + mevaluator = pqev; + this->resetValue(); } - -void PairQuantity::setRmax(double rmax) -{ - if (mrmax != rmax) mticker.click(); - mrmax = rmax; +PQEvaluatorType PairQuantity::getEvaluatorType() const { + return mevaluator->typeint(); } - -const double& PairQuantity::getRmax() const -{ - return mrmax; +PQEvaluatorType PairQuantity::getEvaluatorTypeUsed() const { + return mevaluator->typeintused(); } - -void PairQuantity::setEvaluatorType(PQEvaluatorType evtp) -{ - if (mevaluator.get() && mevaluator->typeint() == evtp) return; - PQEvaluatorPtr pqev = createPQEvaluator(evtp, mevaluator); - // validate the new evaluator object - try - { - pqev->validate(*this); - } - catch (logic_error e) - { - string emsg("EvaluatorType not supported. "); - emsg += e.what(); - throw invalid_argument(emsg); - } - // validator is good here, use it now. - mevaluator = pqev; - this->resetValue(); +void PairQuantity::setupParallelRun(int cpuindex, int ncpu) { + mevaluator->setupParallelRun(cpuindex, ncpu); } - -PQEvaluatorType PairQuantity::getEvaluatorType() const -{ - return mevaluator->typeint(); +void PairQuantity::maskAllPairs(bool mask) { + bool nochange = minvertpairmask.empty() && msiteallmask.empty() && + mtypemask.empty() && (mdefaultpairmask == mask); + if (!nochange) mticker.click(); + minvertpairmask.clear(); + msiteallmask.clear(); + mtypemask.clear(); + mdefaultpairmask = mask; } - -PQEvaluatorType PairQuantity::getEvaluatorTypeUsed() const -{ - return mevaluator->typeintused(); +void PairQuantity::invertMask() { + mticker.click(); + mdefaultpairmask = !mdefaultpairmask; + unordered_map::iterator mm; + for (mm = msiteallmask.begin(); mm != msiteallmask.end(); ++mm) { + mm->second = !(mm->second); + } + TypeMaskStorage::iterator tpmsk; + for (tpmsk = mtypemask.begin(); tpmsk != mtypemask.end(); ++tpmsk) { + tpmsk->second = !(tpmsk->second); + } } - -void PairQuantity::setupParallelRun(int cpuindex, int ncpu) -{ - mevaluator->setupParallelRun(cpuindex, ncpu); -} - - -void PairQuantity::maskAllPairs(bool mask) -{ - bool nochange = minvertpairmask.empty() && msiteallmask.empty() && - mtypemask.empty() && (mdefaultpairmask == mask); - if (!nochange) mticker.click(); - minvertpairmask.clear(); - msiteallmask.clear(); +void PairQuantity::setPairMask(int i, int j, bool mask) { + if (i < 0) i = ALLATOMSINT; + if (j < 0) j = ALLATOMSINT; + // short circuit for all-all + if (ALLATOMSINT == i && ALLATOMSINT == j) { + this->maskAllPairs(mask); + return; + } + bool modified = false; + // update ticker if we are switching from type-mask mode + if (!mtypemask.empty()) { mtypemask.clear(); - mdefaultpairmask = mask; -} - - -void PairQuantity::invertMask() -{ - mticker.click(); - mdefaultpairmask = !mdefaultpairmask; - unordered_map::iterator mm; - for (mm = msiteallmask.begin(); mm != msiteallmask.end(); ++mm) - { - mm->second = !(mm->second); + modified = true; + } + // handle one ALLATOMSINT argument + if (ALLATOMSINT == i || ALLATOMSINT == j) { + int k = (ALLATOMSINT != i) ? i : j; + pair::iterator, bool> pmm; + pmm = msiteallmask.emplace(k, mask); + if (pmm.second || pmm.first->second != mask) modified = true; + pmm.first->second = mask; + int cntsites = this->countSites(); + for (int l = 0; l < cntsites; ++l) { + this->setPairMaskValue(k, l, mask); } + if (modified) mticker.click(); + return; + } + // here neither i nor j is ALLATOMSINT + unordered_map::iterator ii, jj; + ii = msiteallmask.find(i); + if (ii != msiteallmask.end() && mask != ii->second) { + msiteallmask.erase(ii); + modified = true; + } + jj = msiteallmask.find(j); + if (jj != msiteallmask.end() && mask != jj->second) { + msiteallmask.erase(jj); + modified = true; + } + modified = this->setPairMaskValue(i, j, mask) ? true : modified; + if (modified) mticker.click(); +} + +bool PairQuantity::getPairMask(int i, int j) const { + pair ij = (i > j) ? make_pair(j, i) : make_pair(i, j); + bool rv = minvertpairmask.count(ij) ? !mdefaultpairmask : mdefaultpairmask; + return rv; +} + +void PairQuantity::setTypeMask(string smbli, string smblj, bool mask) { + static string upcaseall; + if (upcaseall.empty()) { + upcaseall = ALLATOMSSTR; + transform(upcaseall.begin(), upcaseall.end(), upcaseall.begin(), ::toupper); + } + // accept "ALL" (upper ALLATOMSSTR) for smbli and smblj + if (upcaseall == smbli) smbli = ALLATOMSSTR; + if (upcaseall == smblj) smblj = ALLATOMSSTR; + pair allall(ALLATOMSSTR, ALLATOMSSTR); + pair smblij = + (smbli > smblj) ? make_pair(smblj, smbli) : make_pair(smbli, smblj); + // short circuit for all-all + if (allall == smblij) { + this->maskAllPairs(mask); + return; + } + // msiteallmask is only relevant for index-based masking. + // clean it up to avoid unexpected effects when switching to index masks. + msiteallmask.clear(); + bool modified = false; + // when all is used, remove all typemask elements with the other type + if (ALLATOMSSTR == smbli || ALLATOMSSTR == smblj) { + const string& sk = (ALLATOMSSTR != smbli) ? smbli : smblj; TypeMaskStorage::iterator tpmsk; - for (tpmsk = mtypemask.begin(); tpmsk != mtypemask.end(); ++tpmsk) - { - tpmsk->second = !(tpmsk->second); - } -} - - -void PairQuantity::setPairMask(int i, int j, bool mask) -{ - if (i < 0) i = ALLATOMSINT; - if (j < 0) j = ALLATOMSINT; - // short circuit for all-all - if (ALLATOMSINT == i && ALLATOMSINT == j) - { - this->maskAllPairs(mask); - return; - } - bool modified = false; - // update ticker if we are switching from type-mask mode - if (!mtypemask.empty()) - { - mtypemask.clear(); - modified = true; - } - // handle one ALLATOMSINT argument - if (ALLATOMSINT == i || ALLATOMSINT == j) - { - int k = (ALLATOMSINT != i) ? i : j; - pair::iterator, bool> pmm; - pmm = msiteallmask.emplace(k, mask); - if (pmm.second || pmm.first->second != mask) modified = true; - pmm.first->second = mask; - int cntsites = this->countSites(); - for (int l = 0; l < cntsites; ++l) - { - this->setPairMaskValue(k, l, mask); - } - if (modified) mticker.click(); - return; - } - // here neither i nor j is ALLATOMSINT - unordered_map::iterator ii, jj; - ii = msiteallmask.find(i); - if (ii != msiteallmask.end() && mask != ii->second) - { - msiteallmask.erase(ii); - modified = true; - } - jj = msiteallmask.find(j); - if (jj != msiteallmask.end() && mask != jj->second) - { - msiteallmask.erase(jj); - modified = true; + TypeMaskStorage::iterator skip = mtypemask.find(smblij); + for (tpmsk = mtypemask.begin(); tpmsk != mtypemask.end();) { + const bool eraseitem = (tpmsk != skip) && (sk == tpmsk->first.first || + sk == tpmsk->first.second); + if (eraseitem) { + if (mask != tpmsk->second) modified = true; + tpmsk = mtypemask.erase(tpmsk); + } else + ++tpmsk; } - modified = this->setPairMaskValue(i, j, mask) ? true : modified; - if (modified) mticker.click(); -} - - -bool PairQuantity::getPairMask(int i, int j) const -{ - pair ij = (i > j) ? make_pair(j, i) : make_pair(i, j); - bool rv = minvertpairmask.count(ij) ? - !mdefaultpairmask : mdefaultpairmask; - return rv; -} - - -void PairQuantity:: -setTypeMask(string smbli, string smblj, bool mask) -{ - static string upcaseall; - if (upcaseall.empty()) - { - upcaseall = ALLATOMSSTR; - transform(upcaseall.begin(), upcaseall.end(), - upcaseall.begin(), ::toupper); - } - // accept "ALL" (upper ALLATOMSSTR) for smbli and smblj - if (upcaseall == smbli) smbli = ALLATOMSSTR; - if (upcaseall == smblj) smblj = ALLATOMSSTR; - pair allall(ALLATOMSSTR, ALLATOMSSTR); - pair smblij = (smbli > smblj) ? - make_pair(smblj, smbli) : make_pair(smbli, smblj); - // short circuit for all-all - if (allall == smblij) - { - this->maskAllPairs(mask); - return; - } - // msiteallmask is only relevant for index-based masking. - // clean it up to avoid unexpected effects when switching to index masks. - msiteallmask.clear(); - bool modified = false; - // when all is used, remove all typemask elements with the other type - if (ALLATOMSSTR == smbli || ALLATOMSSTR == smblj) - { - const string& sk = (ALLATOMSSTR != smbli) ? smbli : smblj; - TypeMaskStorage::iterator tpmsk; - TypeMaskStorage::iterator skip = mtypemask.find(smblij); - for (tpmsk = mtypemask.begin(); tpmsk != mtypemask.end();) - { - const bool eraseitem = (tpmsk != skip) && - (sk == tpmsk->first.first || sk == tpmsk->first.second); - if (eraseitem) - { - if (mask != tpmsk->second) modified = true; - tpmsk = mtypemask.erase(tpmsk); - } - else ++tpmsk; - } - } - pair pmm; - pmm = mtypemask.emplace(smblij, mask); - if (pmm.second || pmm.first->second != mask) modified = true; - pmm.first->second = mask; - if (modified) mticker.click(); -} - - -bool PairQuantity::getTypeMask(const string& smbli, const string& smblj) const -{ - pair smblij = (smbli > smblj) ? - make_pair(smblj, smbli) : make_pair(smbli, smblj); - pair alli = (smbli > ALLATOMSSTR) ? - make_pair(ALLATOMSSTR, smbli) : make_pair(smbli, ALLATOMSSTR); - pair allj = (smblj > ALLATOMSSTR) ? - make_pair(ALLATOMSSTR, smblj) : make_pair(smblj, ALLATOMSSTR); - bool rv = mtypemask.count(smblij) ? mtypemask.at(smblij) : - mtypemask.count(alli) ? mtypemask.at(alli) : - mtypemask.count(allj) ? mtypemask.at(allj) : - mdefaultpairmask; - return rv; + } + pair pmm; + pmm = mtypemask.emplace(smblij, mask); + if (pmm.second || pmm.first->second != mask) modified = true; + pmm.first->second = mask; + if (modified) mticker.click(); +} + +bool PairQuantity::getTypeMask(const string& smbli, const string& smblj) const { + pair smblij = + (smbli > smblj) ? make_pair(smblj, smbli) : make_pair(smbli, smblj); + pair alli = (smbli > ALLATOMSSTR) + ? make_pair(ALLATOMSSTR, smbli) + : make_pair(smbli, ALLATOMSSTR); + pair allj = (smblj > ALLATOMSSTR) + ? make_pair(ALLATOMSSTR, smblj) + : make_pair(smblj, ALLATOMSSTR); + bool rv = mtypemask.count(smblij) ? mtypemask.at(smblij) + : mtypemask.count(alli) ? mtypemask.at(alli) + : mtypemask.count(allj) ? mtypemask.at(allj) + : mdefaultpairmask; + return rv; } // Protected Methods --------------------------------------------------------- -void PairQuantity::resizeValue(size_t sz) -{ - mvalue.resize(sz); -} - - -void PairQuantity::resetValue() -{ - mmergedvaluescount = 0; - fill(mvalue.begin(), mvalue.end(), 0.0); -} - +void PairQuantity::resizeValue(size_t sz) { mvalue.resize(sz); } -void PairQuantity::configureBondGenerator(BaseBondGenerator& bnds) const -{ - bnds.setRmin(this->getRmin()); - bnds.setRmax(this->getRmax()); +void PairQuantity::resetValue() { + mmergedvaluescount = 0; + fill(mvalue.begin(), mvalue.end(), 0.0); } - -void PairQuantity::executeParallelMerge(const string& pdata) -{ - istringstream storage(pdata, ios::binary); - diffpy::serialization::iarchive ia(storage, ios::binary); - QuantityType pvalue; - ia >> pvalue; - if (pvalue.size() != mvalue.size()) - { - throw invalid_argument("Merged data array must have the same size."); - } - transform(mvalue.begin(), mvalue.end(), pvalue.begin(), - mvalue.begin(), plus()); +void PairQuantity::configureBondGenerator(BaseBondGenerator& bnds) const { + bnds.setRmin(this->getRmin()); + bnds.setRmax(this->getRmax()); } - -int PairQuantity::countSites() const -{ - int rv = mstructure.get() ? mstructure->countSites() : 0; - return rv; +void PairQuantity::executeParallelMerge(const string& pdata) { + istringstream storage(pdata, ios::binary); + diffpy::serialization::iarchive ia(storage, ios::binary); + QuantityType pvalue; + ia >> pvalue; + if (pvalue.size() != mvalue.size()) { + throw invalid_argument("Merged data array must have the same size."); + } + transform(mvalue.begin(), mvalue.end(), pvalue.begin(), mvalue.begin(), + plus()); } - -bool PairQuantity::hasMask() const -{ - bool rv = !(mdefaultpairmask && minvertpairmask.empty() && - msiteallmask.empty() && mtypemask.empty()); - return rv; +int PairQuantity::countSites() const { + int rv = mstructure.get() ? mstructure->countSites() : 0; + return rv; } - -bool PairQuantity::hasPairMask() const -{ - bool rv = this->hasMask() && !this->hasTypeMask(); - return rv; +bool PairQuantity::hasMask() const { + bool rv = !(mdefaultpairmask && minvertpairmask.empty() && + msiteallmask.empty() && mtypemask.empty()); + return rv; } - -bool PairQuantity::hasTypeMask() const -{ - return !mtypemask.empty(); +bool PairQuantity::hasPairMask() const { + bool rv = this->hasMask() && !this->hasTypeMask(); + return rv; } +bool PairQuantity::hasTypeMask() const { return !mtypemask.empty(); } -void PairQuantity::stashPartialValue() -{ - const char* emsg = - "stashPartialValue() is not defined in the calculator class."; - throw logic_error(emsg); +void PairQuantity::stashPartialValue() { + const char* emsg = + "stashPartialValue() is not defined in the calculator class."; + throw logic_error(emsg); } - -void PairQuantity::restorePartialValue() -{ - const char* emsg = - "restorePartialValue() is not defined in the calculator class."; - throw logic_error(emsg); +void PairQuantity::restorePartialValue() { + const char* emsg = + "restorePartialValue() is not defined in the calculator class."; + throw logic_error(emsg); } // Private Methods ----------------------------------------------------------- -void PairQuantity::updateMaskData() -{ - int cntsites = this->countSites(); - // Propagate masks with ALLATOMSINT to all valid indices. - if (mtypemask.empty()) - { - unordered_map::const_iterator ia; - for (ia = msiteallmask.begin(); ia != msiteallmask.end(); ++ia) - { - for (int j = 0; j < cntsites; ++j) - { - this->setPairMaskValue(ia->first, j, ia->second); - } - } +void PairQuantity::updateMaskData() { + int cntsites = this->countSites(); + // Propagate masks with ALLATOMSINT to all valid indices. + if (mtypemask.empty()) { + unordered_map::const_iterator ia; + for (ia = msiteallmask.begin(); ia != msiteallmask.end(); ++ia) { + for (int j = 0; j < cntsites; ++j) { + this->setPairMaskValue(ia->first, j, ia->second); + } } - // For type masking propagate atom types to corresponding atom indices. - else - { - // build a list of indices per each unique atom type - unordered_map< string, list > siteindices; - for (int i = 0; i < cntsites; ++i) - { - const string& smbl = mstructure->siteAtomType(i); - siteindices[smbl].push_back(i); - siteindices[ALLATOMSSTR].push_back(i); - } - // rebuild minvertpairmask according to mtypemask - minvertpairmask.clear(); - TypeMaskStorage::const_iterator tpmsk; - // build a list of type masks with all-masks at the begining - list< pair > orderedpairs; - for (tpmsk = mtypemask.begin(); tpmsk != mtypemask.end(); ++tpmsk) - { - bool hasall = (ALLATOMSSTR == tpmsk->first.first || - ALLATOMSSTR == tpmsk->first.second); - if (hasall) orderedpairs.push_front(tpmsk->first); - else orderedpairs.push_back(tpmsk->first); - } - list< pair >::const_iterator tpp; - for (tpp = orderedpairs.begin(); tpp != orderedpairs.end(); ++tpp) - { - const list& isites = siteindices[tpp->first]; - const list& jsites = siteindices[tpp->second]; - bool msk = mtypemask.at(*tpp); - list::const_iterator ii, jj; - for (ii = isites.begin(); ii != isites.end(); ++ii) - { - jj = (&isites == &jsites) ? ii : jsites.begin(); - for (; jj != jsites.end(); ++jj) - { - this->setPairMaskValue(*ii, *jj, msk); - } - } + } + // For type masking propagate atom types to corresponding atom indices. + else { + // build a list of indices per each unique atom type + unordered_map > siteindices; + for (int i = 0; i < cntsites; ++i) { + const string& smbl = mstructure->siteAtomType(i); + siteindices[smbl].push_back(i); + siteindices[ALLATOMSSTR].push_back(i); + } + // rebuild minvertpairmask according to mtypemask + minvertpairmask.clear(); + TypeMaskStorage::const_iterator tpmsk; + // build a list of type masks with all-masks at the beginning + list > orderedpairs; + for (tpmsk = mtypemask.begin(); tpmsk != mtypemask.end(); ++tpmsk) { + bool hasall = (ALLATOMSSTR == tpmsk->first.first || + ALLATOMSSTR == tpmsk->first.second); + if (hasall) + orderedpairs.push_front(tpmsk->first); + else + orderedpairs.push_back(tpmsk->first); + } + list >::const_iterator tpp; + for (tpp = orderedpairs.begin(); tpp != orderedpairs.end(); ++tpp) { + const list& isites = siteindices[tpp->first]; + const list& jsites = siteindices[tpp->second]; + bool msk = mtypemask.at(*tpp); + list::const_iterator ii, jj; + for (ii = isites.begin(); ii != isites.end(); ++ii) { + jj = (&isites == &jsites) ? ii : jsites.begin(); + for (; jj != jsites.end(); ++jj) { + this->setPairMaskValue(*ii, *jj, msk); } + } } + } } - -bool PairQuantity::setPairMaskValue(int i, int j, bool mask) -{ - assert(i >= 0 && j >= 0); - pair ij = (i > j) ? make_pair(j, i) : make_pair(i, j); - bool rv; - rv = (mask == mdefaultpairmask) ? - minvertpairmask.erase(ij) : - minvertpairmask.insert(ij).second; - return rv; +bool PairQuantity::setPairMaskValue(int i, int j, bool mask) { + assert(i >= 0 && j >= 0); + pair ij = (i > j) ? make_pair(j, i) : make_pair(i, j); + bool rv; + rv = (mask == mdefaultpairmask) ? minvertpairmask.erase(ij) + : minvertpairmask.insert(ij).second; + return rv; } // Other functions ----------------------------------------------------------- @@ -493,16 +386,15 @@ bool PairQuantity::setPairMaskValue(int i, int j, bool mask) /// The purpose of this function is to support Python pickling of /// PairQuantity objects that hold Python-derived StructureAdapter classes. /// Use it only if you absolutely have to and you know what you do. -StructureAdapterPtr -replacePairQuantityStructure(PairQuantity& pq, StructureAdapterPtr stru) -{ - StructureAdapterPtr rv = pq.mstructure; - pq.mstructure = stru; - return rv; +StructureAdapterPtr replacePairQuantityStructure(PairQuantity& pq, + StructureAdapterPtr stru) { + StructureAdapterPtr rv = pq.mstructure; + pq.mstructure = stru; + return rv; } -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/PairQuantity.hpp b/src/diffpy/srreal/PairQuantity.hpp index b80086ec..41974811 100644 --- a/src/diffpy/srreal/PairQuantity.hpp +++ b/src/diffpy/srreal/PairQuantity.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class PairQuantity -- general implementation of pair quantity calculator -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class PairQuantity -- general implementation of pair quantity calculator + * + *****************************************************************************/ #ifndef PAIRQUANTITY_HPP_INCLUDED #define PAIRQUANTITY_HPP_INCLUDED @@ -32,138 +32,131 @@ #include #include +#include + namespace diffpy { namespace srreal { class BaseBondGenerator; -class PairQuantity : public diffpy::Attributes -{ - public: - - // class constants - static const int ALLATOMSINT; - static const std::string ALLATOMSSTR; - - // constructor - PairQuantity(); - virtual ~PairQuantity() { } - - // methods - const QuantityType& eval(); - template const QuantityType& eval(const T&); - const QuantityType& eval(StructureAdapterPtr); - const QuantityType& value() const; - void mergeParallelData(const std::string& pdata, int ncpu); - virtual std::string getParallelData() const; - - // configuration - template void setStructure(const T&); - void setStructure(StructureAdapterPtr); - StructureAdapterPtr& getStructure(); - const StructureAdapterPtr& getStructure() const; - virtual void setRmin(double); - const double& getRmin() const; - virtual void setRmax(double); - const double& getRmax() const; - void setEvaluatorType(PQEvaluatorType evtp); - PQEvaluatorType getEvaluatorType() const; - PQEvaluatorType getEvaluatorTypeUsed() const; - void setupParallelRun(int cpuindex, int ncpu); - void maskAllPairs(bool mask); - void invertMask(); - void setPairMask(int i, int j, bool mask); - bool getPairMask(int i, int j) const; - void setTypeMask(std::string, std::string, bool mask); - bool getTypeMask(const std::string&, const std::string&) const; - - // ticker for any updates in configuration - virtual eventticker::EventTicker& ticker() const { return mticker; } - - protected: - - friend class PQEvaluatorBasic; - friend class PQEvaluatorOptimized; - friend StructureAdapterPtr - replacePairQuantityStructure(PairQuantity&, StructureAdapterPtr); - - // methods - virtual void resizeValue(size_t); - virtual void resetValue(); - virtual void configureBondGenerator(BaseBondGenerator&) const; - virtual void addPairContribution(const BaseBondGenerator&, int) { } - virtual void executeParallelMerge(const std::string& pdata); - virtual void finishValue() { } - int countSites() const; - // support methods for PQEvaluatorOptimized - bool hasMask() const; - bool hasPairMask() const; - bool hasTypeMask() const; - virtual void stashPartialValue(); - virtual void restorePartialValue(); - - // data - typedef std::unordered_set< - std::pair, - boost::hash< std::pair > - > PairMaskStorage; - typedef std::unordered_map< - std::pair, bool, - boost::hash< std::pair > - > TypeMaskStorage; - QuantityType mvalue; - StructureAdapterPtr mstructure; - double mrmin; - double mrmax; - PQEvaluatorPtr mevaluator; - bool mdefaultpairmask; - PairMaskStorage minvertpairmask; - std::unordered_map msiteallmask; - TypeMaskStorage mtypemask; - int mmergedvaluescount; - mutable eventticker::EventTicker mticker; - - private: - - // methods - void updateMaskData(); - bool setPairMaskValue(int i, int j, bool mask); - - // serialization - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - ar & mvalue; - ar & mstructure; - ar & mrmin; - ar & mrmax; - ar & mevaluator; - ar & mdefaultpairmask; - ar & minvertpairmask; - ar & msiteallmask; - ar & mtypemask; - ar & mmergedvaluescount; - ar & mticker; - } - +class DLL_EXPORT PairQuantity : public diffpy::Attributes { + public: + // class constants + static const int ALLATOMSINT; + static const std::string ALLATOMSSTR; + + // constructor + PairQuantity(); + virtual ~PairQuantity() {} + + // methods + const QuantityType& eval(); + template + const QuantityType& eval(const T&); + const QuantityType& eval(StructureAdapterPtr); + const QuantityType& value() const; + void mergeParallelData(const std::string& pdata, int ncpu); + virtual std::string getParallelData() const; + + // configuration + template + void setStructure(const T&); + void setStructure(StructureAdapterPtr); + StructureAdapterPtr& getStructure(); + const StructureAdapterPtr& getStructure() const; + virtual void setRmin(double); + const double& getRmin() const; + virtual void setRmax(double); + const double& getRmax() const; + void setEvaluatorType(PQEvaluatorType evtp); + PQEvaluatorType getEvaluatorType() const; + PQEvaluatorType getEvaluatorTypeUsed() const; + void setupParallelRun(int cpuindex, int ncpu); + void maskAllPairs(bool mask); + void invertMask(); + void setPairMask(int i, int j, bool mask); + bool getPairMask(int i, int j) const; + void setTypeMask(std::string, std::string, bool mask); + bool getTypeMask(const std::string&, const std::string&) const; + + // ticker for any updates in configuration + virtual eventticker::EventTicker& ticker() const { return mticker; } + + protected: + friend class PQEvaluatorBasic; + friend class PQEvaluatorOptimized; + friend DLL_EXPORT StructureAdapterPtr + replacePairQuantityStructure(PairQuantity&, StructureAdapterPtr); + + // methods + virtual void resizeValue(size_t); + virtual void resetValue(); + virtual void configureBondGenerator(BaseBondGenerator&) const; + virtual void addPairContribution(const BaseBondGenerator&, int) {} + virtual void executeParallelMerge(const std::string& pdata); + virtual void finishValue() {} + int countSites() const; + // support methods for PQEvaluatorOptimized + bool hasMask() const; + bool hasPairMask() const; + bool hasTypeMask() const; + virtual void stashPartialValue(); + virtual void restorePartialValue(); + + // data + typedef std::unordered_set, + boost::hash > > + PairMaskStorage; + typedef std::unordered_map, bool, + boost::hash > > + TypeMaskStorage; + QuantityType mvalue; + StructureAdapterPtr mstructure; + double mrmin; + double mrmax; + PQEvaluatorPtr mevaluator; + bool mdefaultpairmask; + PairMaskStorage minvertpairmask; + std::unordered_map msiteallmask; + TypeMaskStorage mtypemask; + int mmergedvaluescount; + mutable eventticker::EventTicker mticker; + + private: + // methods + void updateMaskData(); + bool setPairMaskValue(int i, int j, bool mask); + + // serialization + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + ar & mvalue; + ar & mstructure; + ar & mrmin; + ar & mrmax; + ar & mevaluator; + ar & mdefaultpairmask; + ar & minvertpairmask; + ar & msiteallmask; + ar & mtypemask; + ar & mmergedvaluescount; + ar & mticker; + } }; // Template Public Methods --------------------------------------------------- template -const QuantityType& PairQuantity::eval(const T& stru) -{ - StructureAdapterPtr pstru = convertToStructureAdapter(stru); - return this->eval(pstru); +const QuantityType& PairQuantity::eval(const T& stru) { + StructureAdapterPtr pstru = convertToStructureAdapter(stru); + return this->eval(pstru); } - template -void PairQuantity::setStructure(const T& stru) -{ - StructureAdapterPtr pstru = convertToStructureAdapter(stru); - this->setStructure(pstru); +void PairQuantity::setStructure(const T& stru) { + StructureAdapterPtr pstru = convertToStructureAdapter(stru); + this->setStructure(pstru); } // Other functions ----------------------------------------------------------- @@ -171,11 +164,11 @@ void PairQuantity::setStructure(const T& stru) /// The purpose of this function is to support Python pickling of /// PairQuantity objects that hold Python-derived StructureAdapter classes. /// Use it only if you absolutely have to and you know what you do. -StructureAdapterPtr +DLL_EXPORT StructureAdapterPtr replacePairQuantityStructure(PairQuantity& pq, StructureAdapterPtr stru); -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/PeakProfile.cpp b/src/diffpy/srreal/PeakProfile.cpp index ced61f2b..555301a3 100644 --- a/src/diffpy/srreal/PeakProfile.cpp +++ b/src/diffpy/srreal/PeakProfile.cpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class PeakProfile -- base class for calculation of peak profiles. -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class PeakProfile -- base class for calculation of peak profiles. + * + *****************************************************************************/ #include #include @@ -23,7 +23,7 @@ namespace diffpy { // Unique instantiation of the template registry base class. -template class HasClassRegistry; +template class DLL_EXPORT HasClassRegistry; namespace srreal { @@ -33,28 +33,23 @@ namespace srreal { // Constructors -------------------------------------------------------------- -PeakProfile::PeakProfile() : mprecision(0.0) -{ - this->registerDoubleAttribute("peakprecision", - this, &PeakProfile::getPrecision, &PeakProfile::setPrecision); +PeakProfile::PeakProfile() : mprecision(0.0) { + this->registerDoubleAttribute("peakprecision", this, + &PeakProfile::getPrecision, + &PeakProfile::setPrecision); } // Public Methods ------------------------------------------------------------ -void PeakProfile::setPrecision(double eps) -{ - if (mprecision != eps) mticker.click(); - mprecision = eps; +void PeakProfile::setPrecision(double eps) { + if (mprecision != eps) mticker.click(); + mprecision = eps; } +const double& PeakProfile::getPrecision() const { return mprecision; } -const double& PeakProfile::getPrecision() const -{ - return mprecision; -} - -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/PeakProfile.hpp b/src/diffpy/srreal/PeakProfile.hpp index 8f6d4e14..ce337efd 100644 --- a/src/diffpy/srreal/PeakProfile.hpp +++ b/src/diffpy/srreal/PeakProfile.hpp @@ -1,25 +1,25 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class PeakProfile -- base class for calculation of peak profiles. -* When possible total integrated area of the profile should eqaul 1. -* The operator()(x, fwhm) returns amplitude of a zero-centered profile. -* Methods xboundlo(fwhm), xboundhi(fwhm) return low and high x-boundaries, -* where amplitude relative to the maximum becomes smaller than precision -* set by setPrecision(). -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class PeakProfile -- base class for calculation of peak profiles. + * When possible total integrated area of the profile should equal 1. + * The operator()(x, fwhm) returns amplitude of a zero-centered profile. + * Methods xboundlo(fwhm), xboundhi(fwhm) return low and high x-boundaries, + * where amplitude relative to the maximum becomes smaller than precision + * set by setPrecision(). + * + *****************************************************************************/ #ifndef PEAKPROFILE_HPP_INCLUDED #define PEAKPROFILE_HPP_INCLUDED @@ -33,49 +33,44 @@ #include #include +#include + namespace diffpy { namespace srreal { -class PeakProfile : - public diffpy::Attributes, - public diffpy::HasClassRegistry -{ - public: - - // constructors - PeakProfile(); - // methods - virtual double operator()(double x, double fwhm) const = 0; - virtual double xboundlo(double fwhm) const = 0; - virtual double xboundhi(double fwhm) const = 0; - virtual void setPrecision(double eps); - const double& getPrecision() const; - virtual eventticker::EventTicker& ticker() const { return mticker; } - - protected: - - // data - mutable eventticker::EventTicker mticker; - - private: - - // data - double mprecision; - - // serialization - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - ar & mticker & mprecision; - } - +class DLL_EXPORT PeakProfile : public diffpy::Attributes, + public diffpy::HasClassRegistry { + public: + // constructors + PeakProfile(); + // methods + virtual double operator()(double x, double fwhm) const = 0; + virtual double xboundlo(double fwhm) const = 0; + virtual double xboundhi(double fwhm) const = 0; + virtual void setPrecision(double eps); + const double& getPrecision() const; + virtual eventticker::EventTicker& ticker() const { return mticker; } + + protected: + // data + mutable eventticker::EventTicker mticker; + + private: + // data + double mprecision; + + // serialization + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + ar & mticker & mprecision; + } }; typedef PeakProfile::SharedPtr PeakProfilePtr; -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/PeakWidthModel.cpp b/src/diffpy/srreal/PeakWidthModel.cpp index 0418d9e1..8cbe3b15 100644 --- a/src/diffpy/srreal/PeakWidthModel.cpp +++ b/src/diffpy/srreal/PeakWidthModel.cpp @@ -1,73 +1,62 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class PeakWidthModel -- base class for calculation of peak widths. -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class PeakWidthModel -- base class for calculation of peak widths. + * + *****************************************************************************/ #include #include #include #include -using std::string; using diffpy::validators::ensureNonNull; +using std::string; namespace diffpy { // Unique instantiation of the template registry base class. -template class HasClassRegistry; +template class DLL_EXPORT HasClassRegistry; namespace srreal { // class PeakWidthModelOwner ------------------------------------------------- -void PeakWidthModelOwner::setPeakWidthModel(PeakWidthModelPtr pwm) -{ - ensureNonNull("PeakWidthModel", pwm); - if (mpwmodel != pwm) mprivateticker.click(); - mpwmodel = pwm; +void PeakWidthModelOwner::setPeakWidthModel(PeakWidthModelPtr pwm) { + ensureNonNull("PeakWidthModel", pwm); + if (mpwmodel != pwm) mprivateticker.click(); + mpwmodel = pwm; } - -void PeakWidthModelOwner::setPeakWidthModelByType(const string& tp) -{ - mpwmodel = PeakWidthModel::createByType(tp); - mprivateticker.click(); +void PeakWidthModelOwner::setPeakWidthModelByType(const string& tp) { + mpwmodel = PeakWidthModel::createByType(tp); + mprivateticker.click(); } +PeakWidthModelPtr& PeakWidthModelOwner::getPeakWidthModel() { return mpwmodel; } -PeakWidthModelPtr& PeakWidthModelOwner::getPeakWidthModel() -{ - return mpwmodel; +const PeakWidthModelPtr& PeakWidthModelOwner::getPeakWidthModel() const { + return mpwmodel; } - -const PeakWidthModelPtr& PeakWidthModelOwner::getPeakWidthModel() const -{ - return mpwmodel; -} - - -eventticker::EventTicker& PeakWidthModelOwner::ticker() const -{ - if (mpwmodel) mprivateticker.updateFrom(mpwmodel->ticker()); - return mprivateticker; +eventticker::EventTicker& PeakWidthModelOwner::ticker() const { + if (mpwmodel) mprivateticker.updateFrom(mpwmodel->ticker()); + return mprivateticker; } -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/PeakWidthModel.hpp b/src/diffpy/srreal/PeakWidthModel.hpp index 25a589bf..e615da22 100644 --- a/src/diffpy/srreal/PeakWidthModel.hpp +++ b/src/diffpy/srreal/PeakWidthModel.hpp @@ -1,26 +1,26 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class PeakWidthModel -- base class for calculation of peak widths. -* The calculate function takes a BondGenerator instance and -* returns full width at half maximum, based on peak model parameters -* and anisotropic displacement parameters of atoms in the pair. -* -* class PeakWidthModelOwner -- to be used as a base class for classes -* that own PeakWidthModel -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class PeakWidthModel -- base class for calculation of peak widths. + * The calculate function takes a BondGenerator instance and + * returns full width at half maximum, based on peak model parameters + * and anisotropic displacement parameters of atoms in the pair. + * + * class PeakWidthModelOwner -- to be used as a base class for classes + * that own PeakWidthModel + * + *****************************************************************************/ #ifndef PEAKWIDTHMODEL_HPP_INCLUDED #define PEAKWIDTHMODEL_HPP_INCLUDED @@ -35,72 +35,61 @@ #include #include +#include + namespace diffpy { namespace srreal { -class PeakWidthModel : - public diffpy::Attributes, - public diffpy::HasClassRegistry -{ - public: - - // methods - virtual double calculate(const BaseBondGenerator&) const = 0; - virtual double maxWidth(StructureAdapterPtr, - double rmin, double rmax) const = 0; - virtual eventticker::EventTicker& ticker() const { return mticker; } - - protected: - - // data - mutable eventticker::EventTicker mticker; - - private: - - // serialization - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - ar & mticker; - } - +class DLL_EXPORT PeakWidthModel + : public diffpy::Attributes, + public diffpy::HasClassRegistry { + public: + // methods + virtual double calculate(const BaseBondGenerator&) const = 0; + virtual double maxWidth(StructureAdapterPtr, double rmin, + double rmax) const = 0; + virtual eventticker::EventTicker& ticker() const { return mticker; } + + protected: + // data + mutable eventticker::EventTicker mticker; + + private: + // serialization + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + ar & mticker; + } }; - typedef PeakWidthModel::SharedPtr PeakWidthModelPtr; - -class PeakWidthModelOwner -{ - public: - - // PDF peak width configuration - void setPeakWidthModel(PeakWidthModelPtr); - void setPeakWidthModelByType(const std::string& tp); - PeakWidthModelPtr& getPeakWidthModel(); - const PeakWidthModelPtr& getPeakWidthModel() const; - eventticker::EventTicker& ticker() const; - - private: - - // data - PeakWidthModelPtr mpwmodel; - mutable eventticker::EventTicker mprivateticker; - - // serialization - friend class boost::serialization::access; - - template - void serialize(Archive& ar, const unsigned int version) - { - ar & mpwmodel & mprivateticker; - } - +class DLL_EXPORT PeakWidthModelOwner { + public: + // PDF peak width configuration + void setPeakWidthModel(PeakWidthModelPtr); + void setPeakWidthModelByType(const std::string& tp); + PeakWidthModelPtr& getPeakWidthModel(); + const PeakWidthModelPtr& getPeakWidthModel() const; + eventticker::EventTicker& ticker() const; + + private: + // data + PeakWidthModelPtr mpwmodel; + mutable eventticker::EventTicker mprivateticker; + + // serialization + friend class boost::serialization::access; + + template + void serialize(Archive& ar, const unsigned int version) { + ar & mpwmodel & mprivateticker; + } }; -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/PeriodicStructureAdapter.cpp b/src/diffpy/srreal/PeriodicStructureAdapter.cpp index 80fdd5f5..01f5cba6 100644 --- a/src/diffpy/srreal/PeriodicStructureAdapter.cpp +++ b/src/diffpy/srreal/PeriodicStructureAdapter.cpp @@ -1,23 +1,23 @@ /***************************************************************************** -* -* libdiffpy Complex Modeling Initiative -* (c) 2013 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. -* -****************************************************************************** -* -* class PeriodicStructureAdapter -- universal adapter for structure with -* periodic boundary conditions that has no space group symmetry -* -* class PeriodicStructureBondGenerator -- bond generator -* -*****************************************************************************/ + * + * libdiffpy Complex Modeling Initiative + * (c) 2013 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. + * + ****************************************************************************** + * + * class PeriodicStructureAdapter -- universal adapter for structure with + * periodic boundary conditions that has no space group symmetry + * + * class PeriodicStructureBondGenerator -- bond generator + * + *****************************************************************************/ #include @@ -37,93 +37,69 @@ namespace srreal { // Public Methods ------------------------------------------------------------ -StructureAdapterPtr PeriodicStructureAdapter::clone() const -{ - StructureAdapterPtr rv(new PeriodicStructureAdapter(*this)); - return rv; +StructureAdapterPtr PeriodicStructureAdapter::clone() const { + StructureAdapterPtr rv(new PeriodicStructureAdapter(*this)); + return rv; } - -BaseBondGeneratorPtr PeriodicStructureAdapter::createBondGenerator() const -{ - BaseBondGeneratorPtr bnds( - new PeriodicStructureBondGenerator(shared_from_this())); - return bnds; -} - - -double PeriodicStructureAdapter::numberDensity() const -{ - const Lattice& L = this->getLattice(); - double rv = this->totalOccupancy() / L.volume(); - return rv; +BaseBondGeneratorPtr PeriodicStructureAdapter::createBondGenerator() const { + BaseBondGeneratorPtr bnds( + new PeriodicStructureBondGenerator(shared_from_this())); + return bnds; } - -StructureDifference -PeriodicStructureAdapter::diff(StructureAdapterConstPtr other) const -{ - StructureDifference sd = this->StructureAdapter::diff(other); - if (sd.stru0 == sd.stru1) return sd; - typedef boost::shared_ptr PPtr; - PPtr pother = boost::dynamic_pointer_cast(other); - if (!pother) return sd; - assert(pother == sd.stru1); - if (this->getLattice() != pother->getLattice()) return sd; - sd = this->AtomicStructureAdapter::diff(other); - return sd; +double PeriodicStructureAdapter::numberDensity() const { + const Lattice& L = this->getLattice(); + double rv = this->totalOccupancy() / L.volume(); + return rv; } - -void PeriodicStructureAdapter::setLatPar( - double a, double b, double c, - double alphadeg, double betadeg, double gammadeg) -{ - mlattice.setLatPar(a, b, c, alphadeg, betadeg, gammadeg); +StructureDifference PeriodicStructureAdapter::diff( + StructureAdapterConstPtr other) const { + StructureDifference sd = this->StructureAdapter::diff(other); + if (sd.stru0 == sd.stru1) return sd; + typedef boost::shared_ptr PPtr; + PPtr pother = boost::dynamic_pointer_cast(other); + if (!pother) return sd; + assert(pother == sd.stru1); + if (this->getLattice() != pother->getLattice()) return sd; + sd = this->AtomicStructureAdapter::diff(other); + return sd; } - -const Lattice& PeriodicStructureAdapter::getLattice() const -{ - return mlattice; +void PeriodicStructureAdapter::setLatPar(double a, double b, double c, + double alphadeg, double betadeg, + double gammadeg) { + mlattice.setLatPar(a, b, c, alphadeg, betadeg, gammadeg); } +const Lattice& PeriodicStructureAdapter::getLattice() const { return mlattice; } -void PeriodicStructureAdapter::toCartesian(Atom& a) const -{ - const Lattice& L = this->getLattice(); - a.xyz_cartn = L.cartesian(a.xyz_cartn); - a.uij_cartn = L.cartesianMatrix(a.uij_cartn); +void PeriodicStructureAdapter::toCartesian(Atom& a) const { + const Lattice& L = this->getLattice(); + a.xyz_cartn = L.cartesian(a.xyz_cartn); + a.uij_cartn = L.cartesianMatrix(a.uij_cartn); } - -void PeriodicStructureAdapter::toFractional(Atom& a) const -{ - const Lattice& L = this->getLattice(); - a.xyz_cartn = L.fractional(a.xyz_cartn); - a.uij_cartn = L.fractionalMatrix(a.uij_cartn); +void PeriodicStructureAdapter::toFractional(Atom& a) const { + const Lattice& L = this->getLattice(); + a.xyz_cartn = L.fractional(a.xyz_cartn); + a.uij_cartn = L.fractionalMatrix(a.uij_cartn); } // Comparison functions ------------------------------------------------------ -bool operator==( - const PeriodicStructureAdapter& stru0, - const PeriodicStructureAdapter& stru1) -{ - const AtomicStructureAdapter& astru0 = stru0; - const AtomicStructureAdapter& astru1 = stru1; - bool rv = - (astru0 == astru1) && - (stru0.getLattice() == stru1.getLattice()); - return rv; +bool operator==(const PeriodicStructureAdapter& stru0, + const PeriodicStructureAdapter& stru1) { + const AtomicStructureAdapter& astru0 = stru0; + const AtomicStructureAdapter& astru1 = stru1; + bool rv = (astru0 == astru1) && (stru0.getLattice() == stru1.getLattice()); + return rv; } - -bool operator!=( - const PeriodicStructureAdapter& stru0, - const PeriodicStructureAdapter& stru1) -{ - return !(stru0 == stru1); +bool operator!=(const PeriodicStructureAdapter& stru0, + const PeriodicStructureAdapter& stru1) { + return !(stru0 == stru1); } ////////////////////////////////////////////////////////////////////////////// @@ -133,107 +109,92 @@ bool operator!=( // Constructor --------------------------------------------------------------- PeriodicStructureBondGenerator::PeriodicStructureBondGenerator( - StructureAdapterConstPtr adpt) : BaseBondGenerator(adpt) -{ - mpstructure = dynamic_cast(adpt.get()); - assert(mpstructure); - int cntsites = mpstructure->countSites(); - mcartesian_positions_uc.reserve(cntsites); - const Lattice& L = mpstructure->getLattice(); - PeriodicStructureAdapter::const_iterator ai = mpstructure->begin(); - R3::Vector xyzc; - for (; ai != mpstructure->end(); ++ai) - { - xyzc = L.ucvCartesian(ai->xyz_cartn); - mcartesian_positions_uc.push_back(xyzc); - } + StructureAdapterConstPtr adpt) + : BaseBondGenerator(adpt) { + mpstructure = dynamic_cast(adpt.get()); + assert(mpstructure); + int cntsites = mpstructure->countSites(); + mcartesian_positions_uc.reserve(cntsites); + const Lattice& L = mpstructure->getLattice(); + PeriodicStructureAdapter::const_iterator ai = mpstructure->begin(); + R3::Vector xyzc; + for (; ai != mpstructure->end(); ++ai) { + xyzc = L.ucvCartesian(ai->xyz_cartn); + mcartesian_positions_uc.push_back(xyzc); + } } // Public Methods ------------------------------------------------------------ -void PeriodicStructureBondGenerator::rewind() -{ - // Delay msphere instantiation to here instead of in constructor, - // so it is possible to use setRmin, setRmax. - if (!msphere.get()) - { - const Lattice& L = mpstructure->getLattice(); - double buffzone = L.ucMaxDiagonalLength(); - double rsphmin = this->getRmin() - buffzone; - double rsphmax = this->getRmax() + buffzone; - msphere.reset(new PointsInSphere(rsphmin, rsphmax, L)); - } - // BaseBondGenerator::rewind calls this->rewindSymmetry, - // which takes care of msphere configuration - this->BaseBondGenerator::rewind(); +void PeriodicStructureBondGenerator::rewind() { + // Delay msphere instantiation to here instead of in constructor, + // so it is possible to use setRmin, setRmax. + if (!msphere.get()) { + const Lattice& L = mpstructure->getLattice(); + double buffzone = L.ucMaxDiagonalLength(); + double rsphmin = this->getRmin() - buffzone; + double rsphmax = this->getRmax() + buffzone; + msphere.reset(new PointsInSphere(rsphmin, rsphmax, L)); + } + // BaseBondGenerator::rewind calls this->rewindSymmetry, + // which takes care of msphere configuration + this->BaseBondGenerator::rewind(); } - -void PeriodicStructureBondGenerator::selectAnchorSite(int anchor) -{ - this->BaseBondGenerator::selectAnchorSite(anchor); - mr0 = mcartesian_positions_uc[anchor]; +void PeriodicStructureBondGenerator::selectAnchorSite(int anchor) { + this->BaseBondGenerator::selectAnchorSite(anchor); + mr0 = mcartesian_positions_uc[anchor]; } - -void PeriodicStructureBondGenerator::setRmin(double rmin) -{ - // destroy msphere so it will be created on rewind with new rmin - if (this->getRmin() != rmin) msphere.reset(); - this->BaseBondGenerator::setRmin(rmin); +void PeriodicStructureBondGenerator::setRmin(double rmin) { + // destroy msphere so it will be created on rewind with new rmin + if (this->getRmin() != rmin) msphere.reset(); + this->BaseBondGenerator::setRmin(rmin); } - -void PeriodicStructureBondGenerator::setRmax(double rmax) -{ - // destroy msphere so it will be created on rewind with new rmax - if (this->getRmax() != rmax) msphere.reset(); - this->BaseBondGenerator::setRmax(rmax); +void PeriodicStructureBondGenerator::setRmax(double rmax) { + // destroy msphere so it will be created on rewind with new rmax + if (this->getRmax() != rmax) msphere.reset(); + this->BaseBondGenerator::setRmax(rmax); } // Protected Methods --------------------------------------------------------- -bool PeriodicStructureBondGenerator::iterateSymmetry() -{ - msphere->next(); - bool done = msphere->finished(); - mrcsphere = done ? R3::zerovector : - mpstructure->getLattice().cartesian(msphere->mno()); - return !done; +bool PeriodicStructureBondGenerator::iterateSymmetry() { + msphere->next(); + bool done = msphere->finished(); + mrcsphere = + done ? R3::zerovector : mpstructure->getLattice().cartesian(msphere->mno()); + return !done; } - -void PeriodicStructureBondGenerator::rewindSymmetry() -{ - msphere->rewind(); - mrcsphere = msphere->finished() ? R3::zerovector : - mpstructure->getLattice().cartesian(msphere->mno()); - this->updater1(); +void PeriodicStructureBondGenerator::rewindSymmetry() { + msphere->rewind(); + mrcsphere = msphere->finished() + ? R3::zerovector + : mpstructure->getLattice().cartesian(msphere->mno()); + this->updater1(); } - -void PeriodicStructureBondGenerator::getNextBond() -{ - ++msite_current; - // go back to the first site if there is next symmetry element - if (msite_current >= msite_last && this->iterateSymmetry()) - { - msite_current = msite_first; - } - // update values only if not finished - if (!this->finished()) this->updater1(); +void PeriodicStructureBondGenerator::getNextBond() { + ++msite_current; + // go back to the first site if there is next symmetry element + if (msite_current >= msite_last && this->iterateSymmetry()) { + msite_current = msite_first; + } + // update values only if not finished + if (!this->finished()) this->updater1(); } // Private Methods ----------------------------------------------------------- -void PeriodicStructureBondGenerator::updater1() -{ - mr1 = mrcsphere + mcartesian_positions_uc[this->site1()]; - this->updateDistance(); +void PeriodicStructureBondGenerator::updater1() { + mr1 = mrcsphere + mcartesian_positions_uc[this->site1()]; + this->updateDistance(); } -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/PeriodicStructureAdapter.hpp b/src/diffpy/srreal/PeriodicStructureAdapter.hpp index d3082e0e..b32f246e 100644 --- a/src/diffpy/srreal/PeriodicStructureAdapter.hpp +++ b/src/diffpy/srreal/PeriodicStructureAdapter.hpp @@ -1,114 +1,108 @@ /***************************************************************************** -* -* libdiffpy Complex Modeling Initiative -* (c) 2013 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. -* -****************************************************************************** -* -* class PeriodicStructureAdapter -- universal adapter for structure with -* periodic boundary conditions that has no space group symmetry -* -* class PeriodicStructureBondGenerator -- bond generator -* -*****************************************************************************/ + * + * libdiffpy Complex Modeling Initiative + * (c) 2013 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. + * + ****************************************************************************** + * + * class PeriodicStructureAdapter -- universal adapter for structure with + * periodic boundary conditions that has no space group symmetry + * + * class PeriodicStructureBondGenerator -- bond generator + * + *****************************************************************************/ #ifndef PERIODICSTRUCTUREADAPTER_HPP_INCLUDED #define PERIODICSTRUCTUREADAPTER_HPP_INCLUDED #include +#include #include +#include + namespace diffpy { namespace srreal { class PointsInSphere; -class PeriodicStructureAdapter : public AtomicStructureAdapter -{ - public: - - // methods - overloaded - virtual StructureAdapterPtr clone() const; - virtual BaseBondGeneratorPtr createBondGenerator() const; - virtual double numberDensity() const; - virtual StructureDifference diff(StructureAdapterConstPtr other) const; - - // methods - own - void setLatPar( - double a, double b, double c, - double alphadeg, double betadeg, double gammadeg); - const Lattice& getLattice() const; - void toCartesian(Atom&) const; - void toFractional(Atom&) const; - - private: - - // data - Lattice mlattice; - - // serialization - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - ar & boost::serialization::base_object(*this); - ar & mlattice; - } - +class DLL_EXPORT PeriodicStructureAdapter : public AtomicStructureAdapter { + public: + // methods - overloaded + virtual StructureAdapterPtr clone() const; + virtual BaseBondGeneratorPtr createBondGenerator() const; + virtual double numberDensity() const; + virtual StructureDifference diff(StructureAdapterConstPtr other) const; + + // methods - own + void setLatPar(double a, double b, double c, double alphadeg, double betadeg, + double gammadeg); + const Lattice& getLattice() const; + void toCartesian(Atom&) const; + void toFractional(Atom&) const; + + private: + // data + Lattice mlattice; + + // serialization + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + ar& boost::serialization::base_object(*this); + ar & mlattice; + } }; typedef boost::shared_ptr PeriodicStructureAdapterPtr; // Comparison functions -bool operator==(const PeriodicStructureAdapter&, const PeriodicStructureAdapter&); -bool operator!=(const PeriodicStructureAdapter&, const PeriodicStructureAdapter&); - - -class PeriodicStructureBondGenerator : public BaseBondGenerator -{ - public: - - // constructors - PeriodicStructureBondGenerator(StructureAdapterConstPtr); - - // methods - // loop control - virtual void rewind(); - - // configuration - virtual void selectAnchorSite(int); - virtual void setRmin(double); - virtual void setRmax(double); - - protected: - - // data - const PeriodicStructureAdapter* mpstructure; - std::unique_ptr msphere; - R3::Vector mrcsphere; - - // methods - virtual bool iterateSymmetry(); - virtual void rewindSymmetry(); - virtual void getNextBond(); - virtual void updater1(); - - private: - - // data - std::vector mcartesian_positions_uc; +DLL_EXPORT bool operator==(const PeriodicStructureAdapter&, + const PeriodicStructureAdapter&); +DLL_EXPORT bool operator!=(const PeriodicStructureAdapter&, + const PeriodicStructureAdapter&); + +class PeriodicStructureBondGenerator : public BaseBondGenerator { + public: + // constructors + PeriodicStructureBondGenerator(StructureAdapterConstPtr); + + // methods + // loop control + virtual void rewind(); + + // configuration + virtual void selectAnchorSite(int); + virtual void setRmin(double); + virtual void setRmax(double); + + protected: + // data + const PeriodicStructureAdapter* mpstructure; + std::unique_ptr msphere; + R3::Vector mrcsphere; + + // methods + virtual bool iterateSymmetry(); + virtual void rewindSymmetry(); + virtual void getNextBond(); + virtual void updater1(); + + private: + // data + std::vector mcartesian_positions_uc; }; -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/PointsInSphere.cpp b/src/diffpy/srreal/PointsInSphere.cpp index 88c24ef5..d6713646 100644 --- a/src/diffpy/srreal/PointsInSphere.cpp +++ b/src/diffpy/srreal/PointsInSphere.cpp @@ -1,22 +1,22 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2006 trustees of the Michigan State University -* 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. -* -****************************************************************************** -* -* classes PointsInSphere, ReflectionsInQminQmax, ReflectionsInDmaxDmin -* -* Comments: sequencers for lattice points insided 3D sphere -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2006 trustees of the Michigan State University + * 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. + * + ****************************************************************************** + * + * classes PointsInSphere, ReflectionsInQminQmax, ReflectionsInDmaxDmin + * + * Comments: sequencers for lattice points inside 3D sphere + * + *****************************************************************************/ #include #include @@ -31,53 +31,56 @@ using pointsinsphere::LatticeParameters; // Constructor --------------------------------------------------------------- -LatticeParameters::LatticeParameters( double _a, double _b, double _c, - double _alpha, double _beta, double _gamma ) : - a(_a), b(_b), c(_c), - alpha(_alpha), beta(_beta), gamma(_gamma) -{ - update(); +LatticeParameters::LatticeParameters(double _a, double _b, double _c, + double _alpha, double _beta, double _gamma) + : a(_a), b(_b), c(_c), alpha(_alpha), beta(_beta), gamma(_gamma) { + update(); } // Public Methods ------------------------------------------------------------ -void LatticeParameters::update() -{ - using diffpy::mathutils::cosd; - using diffpy::mathutils::sind; - ca = cosd(alpha); cb = cosd(beta); cg = cosd(gamma); - sa = sind(alpha); sb = sind(beta); sg = sind(gamma); - // Vunit is a volume of unit cell with a=b=c=1 - const double Vunit = sqrt(1.0 + 2.0*ca*cb*cg - ca*ca - cb*cb - cg*cg); - ar = sa/(a*Vunit); - br = sb/(b*Vunit); - cr = sg/(c*Vunit); - car = (cb*cg - ca)/(sb*sg); sar = sqrt(1.0 - car*car); - cbr = (ca*cg - cb)/(sa*sg); sbr = sqrt(1.0 - cbr*cbr); - cgr = (ca*cb - cg)/(sa*sb); sgr = sqrt(1.0 - cgr*cgr); - alphar = 180.0/M_PI*acos(car); - betar = 180.0/M_PI*acos(cbr); - gammar = 180.0/M_PI*acos(cgr); -} - - -LatticeParameters LatticeParameters::reciprocal() const -{ - using namespace std; - LatticeParameters rec(*this); - swap(rec.a, rec.ar); - swap(rec.b, rec.br); - swap(rec.c, rec.cr); - swap(rec.alpha, rec.alphar); - swap(rec.beta, rec.betar); - swap(rec.gamma, rec.gammar); - swap(rec.ca, rec.car); - swap(rec.cb, rec.cbr); - swap(rec.cg, rec.cgr); - swap(rec.sa, rec.sar); - swap(rec.sb, rec.sbr); - swap(rec.sg, rec.sgr); - return rec; +void LatticeParameters::update() { + using diffpy::mathutils::cosd; + using diffpy::mathutils::sind; + ca = cosd(alpha); + cb = cosd(beta); + cg = cosd(gamma); + sa = sind(alpha); + sb = sind(beta); + sg = sind(gamma); + // Vunit is a volume of unit cell with a=b=c=1 + const double Vunit = + sqrt(1.0 + 2.0 * ca * cb * cg - ca * ca - cb * cb - cg * cg); + ar = sa / (a * Vunit); + br = sb / (b * Vunit); + cr = sg / (c * Vunit); + car = (cb * cg - ca) / (sb * sg); + sar = sqrt(1.0 - car * car); + cbr = (ca * cg - cb) / (sa * sg); + sbr = sqrt(1.0 - cbr * cbr); + cgr = (ca * cb - cg) / (sa * sb); + sgr = sqrt(1.0 - cgr * cgr); + alphar = 180.0 / M_PI * acos(car); + betar = 180.0 / M_PI * acos(cbr); + gammar = 180.0 / M_PI * acos(cgr); +} + +LatticeParameters LatticeParameters::reciprocal() const { + using namespace std; + LatticeParameters rec(*this); + swap(rec.a, rec.ar); + swap(rec.b, rec.br); + swap(rec.c, rec.cr); + swap(rec.alpha, rec.alphar); + swap(rec.beta, rec.betar); + swap(rec.gamma, rec.gammar); + swap(rec.ca, rec.car); + swap(rec.cb, rec.cbr); + swap(rec.cg, rec.cgr); + swap(rec.sa, rec.sar); + swap(rec.sb, rec.sbr); + swap(rec.sg, rec.sgr); + return rec; } ////////////////////////////////////////////////////////////////////////////// @@ -87,186 +90,140 @@ LatticeParameters LatticeParameters::reciprocal() const // Constructors -------------------------------------------------------------- PointsInSphere::PointsInSphere(double rmin, double rmax, - const LatticeParameters& _latpar ) : - _Rmin(rmin), _Rmax(rmax), - latpar(_latpar), - _m(_mno[0]), _n(_mno[1]), _o(_mno[2]) -{ - init(); - rewind(); -} - - -PointsInSphere::PointsInSphere(double rmin, double rmax, - double _a, double _b, double _c, - double _alpha, double _beta, double _gamma) : - _Rmin(rmin), _Rmax(rmax), - latpar(_a, _b, _c, _alpha, _beta, _gamma), - _m(_mno[0]), _n(_mno[1]), _o(_mno[2]) -{ - init(); - rewind(); + const LatticeParameters& _latpar) + : _Rmin(rmin), + _Rmax(rmax), + latpar(_latpar), + _m(_mno[0]), + _n(_mno[1]), + _o(_mno[2]) { + init(); + rewind(); +} + +PointsInSphere::PointsInSphere(double rmin, double rmax, double _a, double _b, + double _c, double _alpha, double _beta, + double _gamma) + : _Rmin(rmin), + _Rmax(rmax), + latpar(_a, _b, _c, _alpha, _beta, _gamma), + _m(_mno[0]), + _n(_mno[1]), + _o(_mno[2]) { + init(); + rewind(); } // Public Methods ------------------------------------------------------------ // loop control -void PointsInSphere::rewind() -{ - mHalfSpan = Rmax()*latpar.ar; - hi_m = int(ceil(mHalfSpan)); - this->_m = -hi_m; - // make indices n, o invalid, reset the neares point - this->_n = hi_n = 0; - this->_o = hi_o = outside_o = 0; - n0plane = o0plane = o0line = 0.0; - // unset excluded zone - oExclHalfSpan = 0.0; - // get the first inside point - next_o(); +void PointsInSphere::rewind() { + mHalfSpan = Rmax() * latpar.ar; + hi_m = int(ceil(mHalfSpan)); + this->_m = -hi_m; + // make indices n, o invalid, reset the nearest point + this->_n = hi_n = 0; + this->_o = hi_o = outside_o = 0; + n0plane = o0plane = o0line = 0.0; + // unset excluded zone + oExclHalfSpan = 0.0; + // get the first inside point + next_o(); } +void PointsInSphere::next() { next_o(); } -void PointsInSphere::next() -{ - next_o(); -} - - -bool PointsInSphere::finished() const -{ - return !(m() < this->hi_m); -} +bool PointsInSphere::finished() const { return !(m() < this->hi_m); } // data access -const double& PointsInSphere::Rmin() const -{ - return this->_Rmin; -} +const double& PointsInSphere::Rmin() const { return this->_Rmin; } +const double& PointsInSphere::Rmax() const { return this->_Rmax; } -const double& PointsInSphere::Rmax() const -{ - return this->_Rmax; -} +const int* PointsInSphere::mno() const { return this->_mno; } +int PointsInSphere::m() const { return this->_mno[0]; } -const int* PointsInSphere::mno() const -{ - return this->_mno; -} +int PointsInSphere::n() const { return this->_mno[1]; } +int PointsInSphere::o() const { return this->_mno[2]; } -int PointsInSphere::m() const -{ - return this->_mno[0]; -} - - -int PointsInSphere::n() const -{ - return this->_mno[1]; -} - - -int PointsInSphere::o() const -{ - return this->_mno[2]; -} - - -double PointsInSphere::r() const -{ - const double &a = latpar.a, &b = latpar.b, &c = latpar.c; - const double &ca = latpar.ca, &cb = latpar.cb, &cg = latpar.cg; - return sqrt( m()*m()*a*a + n()*n()*b*b + o()*o()*c*c - + 2*m()*n()*a*b*cg + 2*m()*o()*a*c*cb + 2*n()*o()*b*c*ca ); +double PointsInSphere::r() const { + const double &a = latpar.a, &b = latpar.b, &c = latpar.c; + const double &ca = latpar.ca, &cb = latpar.cb, &cg = latpar.cg; + return sqrt(m() * m() * a * a + n() * n() * b * b + o() * o() * c * c + + 2 * m() * n() * a * b * cg + 2 * m() * o() * a * c * cb + + 2 * n() * o() * b * c * ca); } // Private Methods ----------------------------------------------------------- -void PointsInSphere::next_m() -{ - this->_m += 1; - if (finished()) - { - return; +void PointsInSphere::next_m() { + this->_m += 1; + if (finished()) { + return; + } + // not finished here + n0plane = m() * dn0dm; + o0plane = m() * do0dm; + RplaneSquare = RmaxSquare - pow(m() / latpar.ar, 2); + nHalfSpan = RplaneSquare > 0.0 ? sqrt(RplaneSquare) * b2r : 0.0; + this->_n = int(floor(n0plane - nHalfSpan)); + hi_n = int(ceil(n0plane + nHalfSpan)); +} + +void PointsInSphere::next_n() { + do { + this->_n += 1; + if (n() < hi_n) { + o0line = o0plane + (n() - n0plane) * do0dn; + double RlineSquare = RplaneSquare - pow((n() - n0plane) / b2r, 2); + oHalfSpan = RlineSquare > 0.0 ? sqrt(RlineSquare) * c1r : 0.0; + // parentheses improve round-off errors around [0,0,0] + double RExclSquare = (RlineSquare - RmaxSquare) + RminSquare; + oExclHalfSpan = RExclSquare > 0.0 ? sqrt(RExclSquare) * c1r : 0.0; + this->_o = int(floor(o0line - oHalfSpan)); + outside_o = int(ceil(o0line + oHalfSpan)); + hi_o = outside_o; + if (oExclHalfSpan) { + int hole_o = int(ceil(o0line - oExclHalfSpan)); + if (fabs(hole_o - o0line) < oExclHalfSpan) hi_o = hole_o; + } + return; } - // not finished here - n0plane = m()*dn0dm; - o0plane = m()*do0dm; - RplaneSquare = RmaxSquare - pow(m()/latpar.ar,2); - nHalfSpan = RplaneSquare > 0.0 ? sqrt(RplaneSquare)*b2r : 0.0; - this->_n = int(floor(n0plane - nHalfSpan)); - hi_n = int(ceil(n0plane + nHalfSpan)); + next_m(); + } while (!finished()); } - -void PointsInSphere::next_n() -{ - do - { - this->_n += 1; - if (n() < hi_n) - { - o0line = o0plane + (n()-n0plane)*do0dn; - double RlineSquare = RplaneSquare - pow((n()-n0plane)/b2r,2); - oHalfSpan = RlineSquare > 0.0 ? sqrt(RlineSquare)*c1r : 0.0; - // parentheses improve round-off errors around [0,0,0] - double RExclSquare = (RlineSquare - RmaxSquare) + RminSquare; - oExclHalfSpan = RExclSquare > 0.0 ? sqrt(RExclSquare)*c1r : 0.0; - this->_o = int(floor(o0line - oHalfSpan)); - outside_o = int(ceil(o0line + oHalfSpan)); - hi_o = outside_o; - if (oExclHalfSpan) - { - int hole_o = int(ceil(o0line - oExclHalfSpan)); - if (fabs(hole_o-o0line) < oExclHalfSpan) hi_o = hole_o; - } - return; - } - next_m(); +void PointsInSphere::next_o() { + do { + this->_o += 1; + if (o() < hi_o) { + return; } - while (!finished()); -} - - -void PointsInSphere::next_o() -{ - do - { - this->_o += 1; - if (o() < hi_o) - { - return; - } - if (hi_o != outside_o) - { - hi_o = outside_o; - this->_o = int( ceil(o0line+oExclHalfSpan) ) - 1; - continue; - } - next_n(); + if (hi_o != outside_o) { + hi_o = outside_o; + this->_o = int(ceil(o0line + oExclHalfSpan)) - 1; + continue; } - while (!finished()); + next_n(); + } while (!finished()); } - -void PointsInSphere::init() -{ - RminSquare = (_Rmin < 0.0) ? -(_Rmin*_Rmin) : _Rmin*_Rmin; - RmaxSquare = (_Rmax < 0.0) ? -(_Rmax*_Rmax) : _Rmax*_Rmax; - dn0dm = latpar.cgr*latpar.br/latpar.ar; - do0dm = latpar.cbr*latpar.cr/latpar.ar; - // 2D reciprocal parameters in bc plane - b2r = 1.0/(latpar.b*latpar.sa); - c2r = 1.0/(latpar.c*latpar.sa); - ca2r = -latpar.ca; - do0dn = ca2r*c2r/b2r; - // 1D reciprocal along c axis - c1r = 1.0/latpar.c; +void PointsInSphere::init() { + RminSquare = (_Rmin < 0.0) ? -(_Rmin * _Rmin) : _Rmin * _Rmin; + RmaxSquare = (_Rmax < 0.0) ? -(_Rmax * _Rmax) : _Rmax * _Rmax; + dn0dm = latpar.cgr * latpar.br / latpar.ar; + do0dm = latpar.cbr * latpar.cr / latpar.ar; + // 2D reciprocal parameters in bc plane + b2r = 1.0 / (latpar.b * latpar.sa); + c2r = 1.0 / (latpar.c * latpar.sa); + ca2r = -latpar.ca; + do0dn = ca2r * c2r / b2r; + // 1D reciprocal along c axis + c1r = 1.0 / latpar.c; } ////////////////////////////////////////////////////////////////////////////// @@ -276,90 +233,48 @@ void PointsInSphere::init() // Constructors -------------------------------------------------------------- ReflectionsInQminQmax::ReflectionsInQminQmax(double qmin, double qmax, - const LatticeParameters& _latpar) : - _Qmin(qmin), _Qmax(qmax), - latpar(_latpar), - sph(qmin*M_1_PI/2.0, qmax*M_1_PI/2.0, latpar.reciprocal()) -{ } - + const LatticeParameters& _latpar) + : _Qmin(qmin), + _Qmax(qmax), + latpar(_latpar), + sph(qmin * M_1_PI / 2.0, qmax * M_1_PI / 2.0, latpar.reciprocal()) {} ReflectionsInQminQmax::ReflectionsInQminQmax(double qmin, double qmax, - double _a, double _b, double _c, - double _alpha, double _beta, double _gamma ) : - _Qmin(qmin), _Qmax(qmax), - latpar(_a, _b, _c, _alpha, _beta, _gamma), - sph(qmin*M_1_PI/2.0, qmax*M_1_PI/2.0, latpar.reciprocal()) -{ } + double _a, double _b, double _c, + double _alpha, double _beta, + double _gamma) + : _Qmin(qmin), + _Qmax(qmax), + latpar(_a, _b, _c, _alpha, _beta, _gamma), + sph(qmin * M_1_PI / 2.0, qmax * M_1_PI / 2.0, latpar.reciprocal()) {} // Public Methods ------------------------------------------------------------ // loop control -void ReflectionsInQminQmax::rewind() -{ - this->sph.rewind(); -} +void ReflectionsInQminQmax::rewind() { this->sph.rewind(); } +void ReflectionsInQminQmax::next() { this->sph.next(); } -void ReflectionsInQminQmax::next() -{ - this->sph.next(); -} - - -bool ReflectionsInQminQmax::finished() const -{ - return this->sph.finished(); -} +bool ReflectionsInQminQmax::finished() const { return this->sph.finished(); } // data access -const double& ReflectionsInQminQmax::Qmin() const -{ - return this->_Qmin; -} - - -const double& ReflectionsInQminQmax::Qmax() const -{ - return this->_Qmax; -} - - -const int* ReflectionsInQminQmax::hkl() const -{ - return this->sph.mno(); -} +const double& ReflectionsInQminQmax::Qmin() const { return this->_Qmin; } +const double& ReflectionsInQminQmax::Qmax() const { return this->_Qmax; } -int ReflectionsInQminQmax::h() const -{ - return this->sph.m(); -} +const int* ReflectionsInQminQmax::hkl() const { return this->sph.mno(); } +int ReflectionsInQminQmax::h() const { return this->sph.m(); } -int ReflectionsInQminQmax::k() const -{ - return this->sph.n(); -} +int ReflectionsInQminQmax::k() const { return this->sph.n(); } +int ReflectionsInQminQmax::l() const { return this->sph.o(); } -int ReflectionsInQminQmax::l() const -{ - return this->sph.o(); -} - - -double ReflectionsInQminQmax::Q() const -{ - return 2.0*M_PI*sph.r(); -} +double ReflectionsInQminQmax::Q() const { return 2.0 * M_PI * sph.r(); } - -double ReflectionsInQminQmax::d() const -{ - return 1.0/sph.r(); -} +double ReflectionsInQminQmax::d() const { return 1.0 / sph.r(); } ////////////////////////////////////////////////////////////////////////////// // class ReflectionsInDmaxDmin @@ -368,33 +283,26 @@ double ReflectionsInQminQmax::d() const // Constructors -------------------------------------------------------------- ReflectionsInDmaxDmin::ReflectionsInDmaxDmin(double dmax, double dmin, - const LatticeParameters& _latpar) : - ReflectionsInQminQmax(2.0*M_PI/dmax, 2.0*M_PI/dmin, _latpar), - _Dmin(dmin), _Dmax(dmax) -{ } - + const LatticeParameters& _latpar) + : ReflectionsInQminQmax(2.0 * M_PI / dmax, 2.0 * M_PI / dmin, _latpar), + _Dmin(dmin), + _Dmax(dmax) {} ReflectionsInDmaxDmin::ReflectionsInDmaxDmin(double dmax, double dmin, - double _a, double _b, double _c, - double _alpha, double _beta, double _gamma) : - ReflectionsInQminQmax(2.0*M_PI/dmax, 2.0*M_PI/dmin, - _a, _b, _c, _alpha, _beta, _gamma), - _Dmin(dmin), _Dmax(dmax) -{ } + double _a, double _b, double _c, + double _alpha, double _beta, + double _gamma) + : ReflectionsInQminQmax(2.0 * M_PI / dmax, 2.0 * M_PI / dmin, _a, _b, _c, + _alpha, _beta, _gamma), + _Dmin(dmin), + _Dmax(dmax) {} // Public Methods ------------------------------------------------------------ // data access -const double& ReflectionsInDmaxDmin::Dmin() const -{ - return this->_Dmin; -} - +const double& ReflectionsInDmaxDmin::Dmin() const { return this->_Dmin; } -const double& ReflectionsInDmaxDmin::Dmax() const -{ - return this->_Dmax; -} +const double& ReflectionsInDmaxDmin::Dmax() const { return this->_Dmax; } // End of file diff --git a/src/diffpy/srreal/PointsInSphere.hpp b/src/diffpy/srreal/PointsInSphere.hpp index 40451aad..c78cbc76 100644 --- a/src/diffpy/srreal/PointsInSphere.hpp +++ b/src/diffpy/srreal/PointsInSphere.hpp @@ -1,52 +1,52 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2006 trustees of the Michigan State University -* 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. -* -****************************************************************************** -* -* classes PointsInSphere, ReflectionsInQminQmax, ReflectionsInDmaxDmin -* -* Constructors: -* -* PointsInSphere(Rmin, Rmax, a, b, c, alpha, beta, gamma) -* ReflectionsInQminQmax(Qmin, Qmax, a, b, c, alpha, beta, gamma) -* ReflectionsInDmaxDmin(Dmax, Dmin, a, b, c, alpha, beta, gamma) -* -* template PointsInSphere(Rmin, Rmax, const Lattice&) -* -* where class Lattice must provide methods a(), b(), c(), -* alpha(), beta(), gamma() -* -* Examples: -* -* PointsInSphere sph(Rmin, Rmax, a, b, c, alpha, beta, gamma) -* for (sph.rewind(); !sph.finished(); sph.next()) -* { -* // lattice indices are in sph.m(), sph.n(), sph.o() or sph.mno() -* // sph.r() is distance from origin, -* // where sph.Rmin() < sph.r() < sph.Rmax() -* } -* -* ReflectionsInQminQmax ref(Qmin, Qmax, a, b, c, alpha, beta, gamma) -* for (ReflectionsInQminQmax ref(Qmin, Qmax, a, b, c, alpha, beta, gamma); -* !ref.finished(); ref.next() ) -* { -* // Miller indices are in ref.h(), ref.k(), ref.l() or ref.hkl() -* // ref.Q() is magnitude of Q vector -* // ref.d() is lattice plane spacing -* } -* -* Tip: add epsilon to Rmax to avoid roundoff issues -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2006 trustees of the Michigan State University + * 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. + * + ****************************************************************************** + * + * classes PointsInSphere, ReflectionsInQminQmax, ReflectionsInDmaxDmin + * + * Constructors: + * + * PointsInSphere(Rmin, Rmax, a, b, c, alpha, beta, gamma) + * ReflectionsInQminQmax(Qmin, Qmax, a, b, c, alpha, beta, gamma) + * ReflectionsInDmaxDmin(Dmax, Dmin, a, b, c, alpha, beta, gamma) + * + * template PointsInSphere(Rmin, Rmax, const Lattice&) + * + * where class Lattice must provide methods a(), b(), c(), + * alpha(), beta(), gamma() + * + * Examples: + * + * PointsInSphere sph(Rmin, Rmax, a, b, c, alpha, beta, gamma) + * for (sph.rewind(); !sph.finished(); sph.next()) + * { + * // lattice indices are in sph.m(), sph.n(), sph.o() or sph.mno() + * // sph.r() is distance from origin, + * // where sph.Rmin() < sph.r() < sph.Rmax() + * } + * + * ReflectionsInQminQmax ref(Qmin, Qmax, a, b, c, alpha, beta, gamma) + * for (ReflectionsInQminQmax ref(Qmin, Qmax, a, b, c, alpha, beta, gamma); + * !ref.finished(); ref.next() ) + * { + * // Miller indices are in ref.h(), ref.k(), ref.l() or ref.hkl() + * // ref.Q() is magnitude of Q vector + * // ref.d() is lattice plane spacing + * } + * + * Tip: add epsilon to Rmax to avoid roundoff issues + * + *****************************************************************************/ #ifndef POINTSINSPHERE_HPP_INCLUDED #define POINTSINSPHERE_HPP_INCLUDED @@ -58,198 +58,180 @@ namespace srreal { namespace pointsinsphere { -class LatticeParameters -{ - public: - - // data - // input arguments - double a, b, c, alpha, beta, gamma; - // cosines and sines of direct lattice angles - double ca, cb, cg, sa, sb, sg; - // reciprocal lattice and its cosines and sines - double ar, br, cr, alphar, betar, gammar; - double car, cbr, cgr, sar, sbr, sgr; - - // constructor - LatticeParameters(double _a, double _b, double _c, - double _alpha, double _beta, double _gamma); - - // methods - // calculate all properties from current lattice parameters - void update(); - // return a reciprocal of this lattice - LatticeParameters reciprocal() const; - +class LatticeParameters { + public: + // data + // input arguments + double a, b, c, alpha, beta, gamma; + // cosines and sines of direct lattice angles + double ca, cb, cg, sa, sb, sg; + // reciprocal lattice and its cosines and sines + double ar, br, cr, alphar, betar, gammar; + double car, cbr, cgr, sar, sbr, sgr; + + // constructor + LatticeParameters(double _a, double _b, double _c, double _alpha, + double _beta, double _gamma); + + // methods + // calculate all properties from current lattice parameters + void update(); + // return a reciprocal of this lattice + LatticeParameters reciprocal() const; }; -} // namespace pointsinsphere - - -class PointsInSphere -{ - public: - - // constructors - PointsInSphere(double rmin, double rmax, - const pointsinsphere::LatticeParameters& _latpar); - PointsInSphere(double rmin, double rmax, - double _a, double _b, double _c, - double _alpha, double _beta, double _gamma); - template - PointsInSphere(double rmin, double rmax, const L&); - - // methods - // loop control - void rewind(); - void next(); - bool finished() const; - // data access - const double& Rmin() const; - const double& Rmax() const; - const int* mno() const; - int m() const; - int n() const; - int o() const; - double r() const; - - private: - - // data - // inputs - const double _Rmin; - const double _Rmax; - const pointsinsphere::LatticeParameters latpar; - // output - int _mno[3]; - int& _m; - int& _n; - int& _o; - // calculated constants set by init() - double RminSquare, RmaxSquare; - // 2D reciprocal parameters and cosine in bc plane - double b2r, c2r, ca2r; - // reciprocal c - double c1r; - // offset of the nearest point to [0,0,0] - double dn0dm, do0dm, do0dn; - // loop variables - double n0plane, o0plane, o0line; - double mHalfSpan, nHalfSpan, oHalfSpan; - // o indices excluded due to Rmin - double oExclHalfSpan; - int hi_m, hi_n, hi_o, outside_o; - double RplaneSquare; - - // methods - // loop advance - void next_m(); - void next_n(); - void next_o(); - void init(); +} // namespace pointsinsphere + +class PointsInSphere { + public: + // constructors + PointsInSphere(double rmin, double rmax, + const pointsinsphere::LatticeParameters& _latpar); + PointsInSphere(double rmin, double rmax, double _a, double _b, double _c, + double _alpha, double _beta, double _gamma); + template + PointsInSphere(double rmin, double rmax, const L&); + + // methods + // loop control + void rewind(); + void next(); + bool finished() const; + // data access + const double& Rmin() const; + const double& Rmax() const; + const int* mno() const; + int m() const; + int n() const; + int o() const; + double r() const; + + private: + // data + // inputs + const double _Rmin; + const double _Rmax; + const pointsinsphere::LatticeParameters latpar; + // output + int _mno[3]; + int& _m; + int& _n; + int& _o; + // calculated constants set by init() + double RminSquare, RmaxSquare; + // 2D reciprocal parameters and cosine in bc plane + double b2r, c2r, ca2r; + // reciprocal c + double c1r; + // offset of the nearest point to [0,0,0] + double dn0dm, do0dm, do0dn; + // loop variables + double n0plane, o0plane, o0line; + double mHalfSpan, nHalfSpan, oHalfSpan; + // o indices excluded due to Rmin + double oExclHalfSpan; + int hi_m, hi_n, hi_o, outside_o; + double RplaneSquare; + + // methods + // loop advance + void next_m(); + void next_n(); + void next_o(); + void init(); }; - -class ReflectionsInQminQmax -{ - public: - - // constructors - ReflectionsInQminQmax(double _Qmin, double _Qmax, - const pointsinsphere::LatticeParameters& _latpar); - ReflectionsInQminQmax(double _Qmin, double _Qmax, - double _a, double _b, double _c, - double _alpha, double _beta, double _gamma); - template - ReflectionsInQminQmax(double _Qmin, double _Qmax, const L&); - - // methods - // loop control - void rewind(); - void next(); - bool finished() const; - // data access - const double& Qmin() const; - const double& Qmax() const; - const int* hkl() const; - int h() const; - int k() const; - int l() const; - double Q() const; - double d() const; - - private: - - // data - // inputs - const double _Qmin; - const double _Qmax; - const pointsinsphere::LatticeParameters latpar; - // composite - PointsInSphere sph; +class ReflectionsInQminQmax { + public: + // constructors + ReflectionsInQminQmax(double _Qmin, double _Qmax, + const pointsinsphere::LatticeParameters& _latpar); + ReflectionsInQminQmax(double _Qmin, double _Qmax, double _a, double _b, + double _c, double _alpha, double _beta, double _gamma); + template + ReflectionsInQminQmax(double _Qmin, double _Qmax, const L&); + + // methods + // loop control + void rewind(); + void next(); + bool finished() const; + // data access + const double& Qmin() const; + const double& Qmax() const; + const int* hkl() const; + int h() const; + int k() const; + int l() const; + double Q() const; + double d() const; + + private: + // data + // inputs + const double _Qmin; + const double _Qmax; + const pointsinsphere::LatticeParameters latpar; + // composite + PointsInSphere sph; }; - -class ReflectionsInDmaxDmin : public ReflectionsInQminQmax -{ - public: - - // constructors - ReflectionsInDmaxDmin(double dmax, double dmin, - const pointsinsphere::LatticeParameters& _latpar); - ReflectionsInDmaxDmin(double dmax, double dmin, - double _a, double _b, double _c, - double _alpha, double _beta, double _gamma); - template - ReflectionsInDmaxDmin(double dmax, double dmin, const L&); - - // methods - // data access - const double& Dmin() const; - const double& Dmax() const; - - private: - - // data - // inputs - const double _Dmin; - const double _Dmax; +class ReflectionsInDmaxDmin : public ReflectionsInQminQmax { + public: + // constructors + ReflectionsInDmaxDmin(double dmax, double dmin, + const pointsinsphere::LatticeParameters& _latpar); + ReflectionsInDmaxDmin(double dmax, double dmin, double _a, double _b, + double _c, double _alpha, double _beta, double _gamma); + template + ReflectionsInDmaxDmin(double dmax, double dmin, const L&); + + // methods + // data access + const double& Dmin() const; + const double& Dmax() const; + + private: + // data + // inputs + const double _Dmin; + const double _Dmax; }; // Template Constructor for PointsInSphere ----------------------------------- template -PointsInSphere::PointsInSphere(double rmin, double rmax, const L& lat) : - _Rmin(rmin), _Rmax(rmax), - latpar(lat.a(), lat.b(), lat.c(), lat.alpha(), lat.beta(), lat.gamma()), - _m(_mno[0]), _n(_mno[1]), _o(_mno[2]) -{ - init(); - rewind(); +PointsInSphere::PointsInSphere(double rmin, double rmax, const L& lat) + : _Rmin(rmin), + _Rmax(rmax), + latpar(lat.a(), lat.b(), lat.c(), lat.alpha(), lat.beta(), lat.gamma()), + _m(_mno[0]), + _n(_mno[1]), + _o(_mno[2]) { + init(); + rewind(); } // Template Constructor for ReflectionsInQminQmax ---------------------------- template -ReflectionsInQminQmax::ReflectionsInQminQmax( - double _qmin, double _qmax, const L& lat) : - _Qmin(_qmin), _Qmax(_qmax), - latpar(lat.a(), lat.b(), lat.c(), - lat.alpha(), lat.beta(), lat.gamma()), - sph(_qmin*M_1_PI/2.0, _qmax*M_1_PI/2.0, latpar.reciprocal()) -{ } +ReflectionsInQminQmax::ReflectionsInQminQmax(double _qmin, double _qmax, + const L& lat) + : _Qmin(_qmin), + _Qmax(_qmax), + latpar(lat.a(), lat.b(), lat.c(), lat.alpha(), lat.beta(), lat.gamma()), + sph(_qmin * M_1_PI / 2.0, _qmax * M_1_PI / 2.0, latpar.reciprocal()) {} // Template Constructor for ReflectionsInDmaxDmin ---------------------------- template -ReflectionsInDmaxDmin::ReflectionsInDmaxDmin( - double dmax, double dmin, const L& lat) : - ReflectionsInQminQmax(2.0*M_PI/dmax, 2.0*M_PI/dmin, lat), - _Dmin(dmin), _Dmax(dmax) -{ } - - -} // namespace srreal -} // namespace diffpy +ReflectionsInDmaxDmin::ReflectionsInDmaxDmin(double dmax, double dmin, + const L& lat) + : ReflectionsInQminQmax(2.0 * M_PI / dmax, 2.0 * M_PI / dmin, lat), + _Dmin(dmin), + _Dmax(dmax) {} + +} // namespace srreal +} // namespace diffpy #endif // POINTSINSPHERE_HPP_INCLUDED diff --git a/src/diffpy/srreal/QResolutionEnvelope.cpp b/src/diffpy/srreal/QResolutionEnvelope.cpp index 53049a23..ca096812 100644 --- a/src/diffpy/srreal/QResolutionEnvelope.cpp +++ b/src/diffpy/srreal/QResolutionEnvelope.cpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class QResolutionEnvelope -- Gaussian envelope due to limited Q resolution -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class QResolutionEnvelope -- Gaussian envelope due to limited Q resolution + * + *****************************************************************************/ #include @@ -28,62 +28,44 @@ namespace srreal { // Constructor --------------------------------------------------------------- -QResolutionEnvelope::QResolutionEnvelope() -{ - this->setQdamp(0.0); - this->registerDoubleAttribute("qdamp", this, - &QResolutionEnvelope::getQdamp, &QResolutionEnvelope::setQdamp); +QResolutionEnvelope::QResolutionEnvelope() { + this->setQdamp(0.0); + this->registerDoubleAttribute("qdamp", this, &QResolutionEnvelope::getQdamp, + &QResolutionEnvelope::setQdamp); } - -PDFEnvelopePtr QResolutionEnvelope::create() const -{ - PDFEnvelopePtr rv(new QResolutionEnvelope()); - return rv; +PDFEnvelopePtr QResolutionEnvelope::create() const { + PDFEnvelopePtr rv(new QResolutionEnvelope()); + return rv; } - -PDFEnvelopePtr QResolutionEnvelope::clone() const -{ - PDFEnvelopePtr rv(new QResolutionEnvelope(*this)); - return rv; +PDFEnvelopePtr QResolutionEnvelope::clone() const { + PDFEnvelopePtr rv(new QResolutionEnvelope(*this)); + return rv; } // Public Methods ------------------------------------------------------------ -const string& QResolutionEnvelope::type() const -{ - static string rv = "qresolution"; - return rv; +const string& QResolutionEnvelope::type() const { + static string rv = "qresolution"; + return rv; } - -double QResolutionEnvelope::operator()(const double& r) const -{ - double rv = (mqdamp > 0.0) ? - exp(-pow(r * mqdamp, 2) / 2) : - 1.0; - return rv; +double QResolutionEnvelope::operator()(const double& r) const { + double rv = (mqdamp > 0.0) ? exp(-pow(r * mqdamp, 2) / 2) : 1.0; + return rv; } +void QResolutionEnvelope::setQdamp(double sc) { mqdamp = sc; } -void QResolutionEnvelope::setQdamp(double sc) -{ - mqdamp = sc; -} - - -const double& QResolutionEnvelope::getQdamp() const -{ - return mqdamp; -} +const double& QResolutionEnvelope::getQdamp() const { return mqdamp; } // Registration -------------------------------------------------------------- bool reg_QResolutionEnvelope = QResolutionEnvelope().registerThisType(); -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/QResolutionEnvelope.hpp b/src/diffpy/srreal/QResolutionEnvelope.hpp index dccb3b37..e1aef643 100644 --- a/src/diffpy/srreal/QResolutionEnvelope.hpp +++ b/src/diffpy/srreal/QResolutionEnvelope.hpp @@ -1,67 +1,65 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class QResolutionEnvelope -- Gaussian envelope due to limited Q resolution -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class QResolutionEnvelope -- Gaussian envelope due to limited Q resolution + * + *****************************************************************************/ #ifndef QRESOLUTIONENVELOPE_HPP_INCLUDED #define QRESOLUTIONENVELOPE_HPP_INCLUDED #include +#include + namespace diffpy { namespace srreal { /// @class QResolutionEnvelope /// @brief wide Gaussian PDF scaling envelope caused by finite Q resolution -class QResolutionEnvelope : public PDFEnvelope -{ - public: - - // constructors - QResolutionEnvelope(); - virtual PDFEnvelopePtr create() const; - virtual PDFEnvelopePtr clone() const; - - // methods - virtual const std::string& type() const; - virtual double operator()(const double& r) const; - void setQdamp(double sc); - const double& getQdamp() const; - - private: - - // data - double mqdamp; - - // serialization - friend class boost::serialization::access; - - template - void serialize(Archive& ar, const unsigned int version) - { - using boost::serialization::base_object; - ar & base_object(*this); - ar & mqdamp; - } +class DLL_EXPORT QResolutionEnvelope : public PDFEnvelope { + public: + // constructors + QResolutionEnvelope(); + virtual PDFEnvelopePtr create() const; + virtual PDFEnvelopePtr clone() const; + + // methods + virtual const std::string& type() const; + virtual double operator()(const double& r) const; + void setQdamp(double sc); + const double& getQdamp() const; + + private: + // data + double mqdamp; + + // serialization + friend class boost::serialization::access; + + template + void serialize(Archive& ar, const unsigned int version) { + using boost::serialization::base_object; + ar& base_object(*this); + ar & mqdamp; + } }; // class QResolutionEnvelope -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/QuantityType.hpp b/src/diffpy/srreal/QuantityType.hpp index 11a1f678..86befa24 100644 --- a/src/diffpy/srreal/QuantityType.hpp +++ b/src/diffpy/srreal/QuantityType.hpp @@ -1,24 +1,24 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2011 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. -* -****************************************************************************** -* -* Shared types and small functions used by PairQuantity calculators. -* -* QuantityType -- type that stores PairQuantity results, an array of doubles -* It is a unique derived class from vector to avoid conflicts with -* boost_python convertors in cctbx. -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2011 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. + * + ****************************************************************************** + * + * Shared types and small functions used by PairQuantity calculators. + * + * QuantityType -- type that stores PairQuantity results, an array of doubles + * It is a unique derived class from vector to avoid conflicts with + * boost_python converters in cctbx. + * + *****************************************************************************/ #ifndef QUANTITYTYPE_HPP_INCLUDED #define QUANTITYTYPE_HPP_INCLUDED @@ -26,38 +26,34 @@ #include #include +#include + namespace diffpy { namespace srreal { -class QuantityType : public std::vector -{ - private: - - typedef std::vector Base; - - public: - - // Constructors from std::vector - QuantityType() : Base() { } - QuantityType(const Base& src) : Base(src) { } - explicit QuantityType(Base::size_type n) : Base(n) { } - explicit QuantityType(Base::size_type n, double x) : Base(n, x) { } - template - QuantityType(Iter first, Iter last) : Base(first, last) { } - - private: - - // serialization - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - ar & boost::serialization::base_object(*this); - } - +class DLL_EXPORT QuantityType : public std::vector { + private: + typedef std::vector Base; + + public: + // Constructors from std::vector + QuantityType() : Base() {} + QuantityType(const Base& src) : Base(src) {} + explicit QuantityType(Base::size_type n) : Base(n) {} + explicit QuantityType(Base::size_type n, double x) : Base(n, x) {} + template + QuantityType(Iter first, Iter last) : Base(first, last) {} + + private: + // serialization + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + ar& boost::serialization::base_object(*this); + } }; -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy #endif // QUANTITYTYPE_HPP_INCLUDED diff --git a/src/diffpy/srreal/R3linalg.cpp b/src/diffpy/srreal/R3linalg.cpp index 19a70cc7..20cca1cb 100644 --- a/src/diffpy/srreal/R3linalg.cpp +++ b/src/diffpy/srreal/R3linalg.cpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* R3linalg -- vector and matrix types and linar algebra operations in R3 space -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * R3linalg -- vector and matrix types and linear algebra operations in R3 space + * + *****************************************************************************/ #include #include @@ -25,112 +25,96 @@ namespace diffpy { namespace srreal { namespace R3 { -const Matrix& identity() -{ - static Matrix mx = ublas::identity_matrix(Ndim); - return mx; -} - +// Constants +DLL_EXPORT const int Ndim = 3; -const Matrix& zeromatrix() -{ - static Matrix mx = ublas::zero_matrix(Ndim, Ndim); - return mx; +// Functions +const Matrix& identity() { + static Matrix mx = ublas::identity_matrix(Ndim); + return mx; } +const Matrix& zeromatrix() { + static Matrix mx = ublas::zero_matrix(Ndim, Ndim); + return mx; +} -double determinant(const Matrix& A) -{ - gsl_matrix* gA = gsl_matrix_alloc(Ndim, Ndim); - for (int i = 0; i != Ndim; ++i) - { - for (int j = 0; j != Ndim; ++j) - { - gsl_matrix_set(gA, i, j, A(i,j)); - } +double determinant(const Matrix& A) { + gsl_matrix* gA = gsl_matrix_alloc(Ndim, Ndim); + for (int i = 0; i != Ndim; ++i) { + for (int j = 0; j != Ndim; ++j) { + gsl_matrix_set(gA, i, j, A(i, j)); } - gsl_permutation* gP = gsl_permutation_alloc(Ndim); - int signum; - gsl_linalg_LU_decomp(gA, gP, &signum); - double det = gsl_linalg_LU_det(gA, signum); - gsl_permutation_free(gP); - gsl_matrix_free(gA); - return det; + } + gsl_permutation* gP = gsl_permutation_alloc(Ndim); + int signum; + gsl_linalg_LU_decomp(gA, gP, &signum); + double det = gsl_linalg_LU_det(gA, signum); + gsl_permutation_free(gP); + gsl_matrix_free(gA); + return det; } - -const Matrix& inverse(const Matrix& A) -{ - static Matrix B; - gsl_matrix* gA = gsl_matrix_alloc(Ndim, Ndim); - for (int i = 0; i != Ndim; ++i) - { - for (int j = 0; j != Ndim; ++j) - { - gsl_matrix_set(gA, i, j, A(i,j)); - } +const Matrix& inverse(const Matrix& A) { + static Matrix B; + gsl_matrix* gA = gsl_matrix_alloc(Ndim, Ndim); + for (int i = 0; i != Ndim; ++i) { + for (int j = 0; j != Ndim; ++j) { + gsl_matrix_set(gA, i, j, A(i, j)); } - gsl_permutation* gP = gsl_permutation_alloc(Ndim); - int signum; - gsl_linalg_LU_decomp(gA, gP, &signum); - double* bdata = &(B.data()[0]); - gsl_matrix_view gB = gsl_matrix_view_array(bdata, Ndim, Ndim); - gsl_linalg_LU_invert(gA, gP, &gB.matrix); - gsl_permutation_free(gP); - gsl_matrix_free(gA); - return B; + } + gsl_permutation* gP = gsl_permutation_alloc(Ndim); + int signum; + gsl_linalg_LU_decomp(gA, gP, &signum); + double* bdata = &(B.data()[0]); + gsl_matrix_view gB = gsl_matrix_view_array(bdata, Ndim, Ndim); + gsl_linalg_LU_invert(gA, gP, &gB.matrix); + gsl_permutation_free(gP); + gsl_matrix_free(gA); + return B; } - -size_t hash_value(const Vector& v) -{ - return boost::hash_range(v.begin(), v.end()); +size_t hash_value(const Vector& v) { + return boost::hash_range(v.begin(), v.end()); } - -size_t hash_value(const Matrix& A) -{ - return boost::hash_range(A.data().begin(), A.data().end()); +size_t hash_value(const Matrix& A) { + return boost::hash_range(A.data().begin(), A.data().end()); } -} // namespace R3 -} // namespace srreal +} // namespace R3 +} // namespace srreal namespace mathutils { // EpsilonLess specialization ------------------------------------------------ -template<> +template <> bool EpsilonLess::operator()( - const srreal::R3::Matrix& A, const srreal::R3::Matrix& B) const -{ - bool rv = std::lexicographical_compare( - A.data().begin(), A.data().end(), - B.data().begin(), B.data().end(), *this); - return rv; + const srreal::R3::Matrix& A, const srreal::R3::Matrix& B) const { + bool rv = std::lexicographical_compare( + A.data().begin(), A.data().end(), B.data().begin(), B.data().end(), *this); + return rv; } // EpsilonEqual specializations ---------------------------------------------- -template<> +template <> bool EpsilonEqual::operator()( - const srreal::R3::Vector& u, const srreal::R3::Vector& v) const -{ - bool rv = std::equal(u.begin(), u.end(), v.begin(), *this); - return rv; + const srreal::R3::Vector& u, const srreal::R3::Vector& v) const { + bool rv = std::equal(u.begin(), u.end(), v.begin(), *this); + return rv; } - -template<> +template <> bool EpsilonEqual::operator()( - const srreal::R3::Matrix& A, const srreal::R3::Matrix& B) const -{ - bool rv = std::equal(A.data().begin(), A.data().end(), - B.data().begin(), *this); - return rv; + const srreal::R3::Matrix& A, const srreal::R3::Matrix& B) const { + bool rv = + std::equal(A.data().begin(), A.data().end(), B.data().begin(), *this); + return rv; } -} // namespace mathutils -} // namespace diffpy +} // namespace mathutils +} // namespace diffpy // End of file diff --git a/src/diffpy/srreal/R3linalg.hpp b/src/diffpy/srreal/R3linalg.hpp index bffd5c7c..c7e73a12 100644 --- a/src/diffpy/srreal/R3linalg.hpp +++ b/src/diffpy/srreal/R3linalg.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* R3linalg -- vector and matrix types and linar algebra operations in R3 space -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * R3linalg -- vector and matrix types and linear algebra operations in R3 space + * + *****************************************************************************/ #ifndef R3LINALG_HPP_INCLUDED #define R3LINALG_HPP_INCLUDED @@ -26,6 +26,8 @@ #include #include +#include + namespace diffpy { namespace srreal { namespace R3 { @@ -33,115 +35,105 @@ namespace R3 { // Declarations -------------------------------------------------------------- namespace ublas = boost::numeric::ublas; +using ublas::column; using ublas::prod; using ublas::row; -using ublas::column; using ublas::trans; // Constants -const int Ndim = 3; +extern DLL_EXPORT const int Ndim; using ::diffpy::mathutils::SQRT_DOUBLE_EPS; const ublas::zero_vector zerovector(Ndim); // Classes -class Vector : public ublas::vector > -{ - typedef ublas::vector > - BaseVector; - - public: - - // constructors - Vector() : BaseVector(3) { } - - Vector(const double& x, const double& y, const double& z) - : BaseVector(3) - { - Vector::iterator xi = this->begin(); - *(xi++) = x; - *(xi++) = y; - *(xi++) = z; - } - - template - Vector(const ublas::vector_expression& r) : BaseVector(r) - { } - - template - void operator=(const ublas::vector_expression& r) - { - BaseVector::operator=(r); - } - - template - void operator=(const BaseVector& r) - { - BaseVector::operator=(r); - } - - private: - - // serialization - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - using boost::serialization::base_object; - ar & base_object(*this); - } +class DLL_EXPORT Vector + : public ublas::vector > { + typedef ublas::vector > BaseVector; + + public: + // constructors + Vector() : BaseVector(3) {} + + Vector(const double& x, const double& y, const double& z) : BaseVector(3) { + Vector::iterator xi = this->begin(); + *(xi++) = x; + *(xi++) = y; + *(xi++) = z; + } + + template + Vector(const ublas::vector_expression& r) : BaseVector(r) {} + + template + void operator=(const ublas::vector_expression& r) { + BaseVector::operator=(r); + } + + template + void operator=(const BaseVector& r) { + BaseVector::operator=(r); + } + + private: + // serialization + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + using boost::serialization::base_object; + ar& base_object(*this); + } }; - -class Matrix : public ublas::matrix > -{ - typedef ublas::matrix > BaseMatrix; - - public: - - // constructors - Matrix() : BaseMatrix(3, 3) { } - - Matrix(const double& x0, const double& x1, const double& x2, - const double& x3, const double& x4, const double& x5, - const double& x6, const double& x7, const double& x8) : - BaseMatrix(3, 3) - { - Matrix::array_type::iterator xi = this->data().begin(); - *(xi++) = x0; *(xi++) = x1; *(xi++) = x2; - *(xi++) = x3; *(xi++) = x4; *(xi++) = x5; - *(xi++) = x6; *(xi++) = x7; *(xi++) = x8; - } - - template - Matrix(const ublas::matrix_expression& r) : BaseMatrix(r) - { } - - template - void operator=(const ublas::matrix_expression& r) - { - BaseMatrix::operator=(r); - } - - template - void operator=(const BaseMatrix& r) - { - BaseMatrix::operator=(r); - } - - private: - - // serialization - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - using boost::serialization::base_object; - ar & base_object(*this); - } +class DLL_EXPORT Matrix + : public ublas::matrix > { + typedef ublas::matrix > + BaseMatrix; + + public: + // constructors + Matrix() : BaseMatrix(3, 3) {} + + Matrix(const double& x0, const double& x1, const double& x2, const double& x3, + const double& x4, const double& x5, const double& x6, const double& x7, + const double& x8) + : BaseMatrix(3, 3) { + Matrix::array_type::iterator xi = this->data().begin(); + *(xi++) = x0; + *(xi++) = x1; + *(xi++) = x2; + *(xi++) = x3; + *(xi++) = x4; + *(xi++) = x5; + *(xi++) = x6; + *(xi++) = x7; + *(xi++) = x8; + } + + template + Matrix(const ublas::matrix_expression& r) : BaseMatrix(r) {} + + template + void operator=(const ublas::matrix_expression& r) { + BaseMatrix::operator=(r); + } + + template + void operator=(const BaseMatrix& r) { + BaseMatrix::operator=(r); + } + + private: + // serialization + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + using boost::serialization::base_object; + ar& base_object(*this); + } }; // Functions @@ -152,44 +144,35 @@ double determinant(const Matrix& A); const Matrix& inverse(const Matrix& A); const Vector& floor(const Vector&); -template double norm(const V&); -template double distance(const V& u, const V& v); -template double dot(const V& u, const V& v); -template Vector cross(const V& u, const V& v); -template const Vector& mxvecproduct(const Matrix&, const V&); -template const Vector& mxvecproduct(const V&, const Matrix&); +template +double norm(const V&); +template +double distance(const V& u, const V& v); +template +double dot(const V& u, const V& v); +template +Vector cross(const V& u, const V& v); +template +const Vector& mxvecproduct(const Matrix&, const V&); +template +const Vector& mxvecproduct(const V&, const Matrix&); // Equality ------------------------------------------------------------------ -inline -bool operator==(const Vector& u, const Vector& v) -{ - bool rv = std::equal(u.begin(), u.end(), v.begin()); - return rv; +inline bool operator==(const Vector& u, const Vector& v) { + bool rv = std::equal(u.begin(), u.end(), v.begin()); + return rv; } +inline bool operator!=(const Vector& u, const Vector& v) { return !(u == v); } -inline -bool operator!=(const Vector& u, const Vector& v) -{ - return !(u == v); +inline bool operator==(const Matrix& A, const Matrix& B) { + bool rv = (&A == &B) || + std::equal(A.data().begin(), A.data().end(), B.data().begin()); + return rv; } - -inline -bool operator==(const Matrix& A, const Matrix& B) -{ - bool rv = (&A == &B) || - std::equal(A.data().begin(), A.data().end(), B.data().begin()); - return rv; -} - - -inline -bool operator!=(const Matrix& A, const Matrix& B) -{ - return !(A == B); -} +inline bool operator!=(const Matrix& A, const Matrix& B) { return !(A == B); } // Hashing ------------------------------------------------------------------- @@ -198,95 +181,82 @@ size_t hash_value(const Matrix& A); // Inlined functions --------------------------------------------------------- -inline -const Vector& floor(const Vector& v) -{ - static Vector res; - Vector::const_iterator xi = v.begin(); - Vector::iterator xo = res.begin(); - for (; xi != v.end(); ++xi, ++xo) *xo = std::floor(*xi); - return res; +inline const Vector& floor(const Vector& v) { + static Vector res; + Vector::const_iterator xi = v.begin(); + Vector::iterator xo = res.begin(); + for (; xi != v.end(); ++xi, ++xo) *xo = std::floor(*xi); + return res; } // Template functions -------------------------------------------------------- template -double norm(const V& u) -{ - return sqrt(R3::dot(u, u)); +double norm(const V& u) { + return sqrt(R3::dot(u, u)); } - template -double distance(const V& u, const V& v) -{ - static R3::Vector duv; - duv[0] = u[0] - v[0]; - duv[1] = u[1] - v[1]; - duv[2] = u[2] - v[2]; - return R3::norm(duv); +double distance(const V& u, const V& v) { + static R3::Vector duv; + duv[0] = u[0] - v[0]; + duv[1] = u[1] - v[1]; + duv[2] = u[2] - v[2]; + return R3::norm(duv); } - template -double dot(const V& u, const V& v) -{ - return (u[0]*v[0] + u[1]*v[1] + u[2]*v[2]); +double dot(const V& u, const V& v) { + return (u[0] * v[0] + u[1] * v[1] + u[2] * v[2]); } - template -Vector cross(const V& u, const V& v) -{ - Vector res; - res[0] = u[1]*v[2] - u[2]*v[1]; - res[1] = u[2]*v[0] - u[0]*v[2]; - res[2] = u[0]*v[1] - u[1]*v[0]; - return res; +Vector cross(const V& u, const V& v) { + Vector res; + res[0] = u[1] * v[2] - u[2] * v[1]; + res[1] = u[2] * v[0] - u[0] * v[2]; + res[2] = u[0] * v[1] - u[1] * v[0]; + return res; } - template -const Vector& mxvecproduct(const Matrix& M, const V& u) -{ - static Vector res; - res[0] = M(0,0)*u[0] + M(0,1)*u[1] + M(0,2)*u[2]; - res[1] = M(1,0)*u[0] + M(1,1)*u[1] + M(1,2)*u[2]; - res[2] = M(2,0)*u[0] + M(2,1)*u[1] + M(2,2)*u[2]; - return res; +const Vector& mxvecproduct(const Matrix& M, const V& u) { + static Vector res; + res[0] = M(0, 0) * u[0] + M(0, 1) * u[1] + M(0, 2) * u[2]; + res[1] = M(1, 0) * u[0] + M(1, 1) * u[1] + M(1, 2) * u[2]; + res[2] = M(2, 0) * u[0] + M(2, 1) * u[1] + M(2, 2) * u[2]; + return res; } - template -const Vector& mxvecproduct(const V& u, const Matrix& M) -{ - static Vector res; - res[0] = u[0]*M(0,0) + u[1]*M(1,0) + u[2]*M(2,0); - res[1] = u[0]*M(0,1) + u[1]*M(1,1) + u[2]*M(2,1); - res[2] = u[0]*M(0,2) + u[1]*M(1,2) + u[2]*M(2,2); - return res; +const Vector& mxvecproduct(const V& u, const Matrix& M) { + static Vector res; + res[0] = u[0] * M(0, 0) + u[1] * M(1, 0) + u[2] * M(2, 0); + res[1] = u[0] * M(0, 1) + u[1] * M(1, 1) + u[2] * M(2, 1); + res[2] = u[0] * M(0, 2) + u[1] * M(1, 2) + u[2] * M(2, 2); + return res; } -} // namespace R3 -} // namespace srreal +} // namespace R3 +} // namespace srreal namespace mathutils { // Template specializations -------------------------------------------------- -template<> +template <> bool EpsilonLess::operator()( - const srreal::R3::Matrix& A, const srreal::R3::Matrix& B) const; + const srreal::R3::Matrix& A, const srreal::R3::Matrix& B) const; -template<> +template <> bool EpsilonEqual::operator()( - const srreal::R3::Vector& u, const srreal::R3::Vector& v) const; + const srreal::R3::Vector& u, const srreal::R3::Vector& v) const; -template<> +template <> bool EpsilonEqual::operator()( - const srreal::R3::Matrix& A, const srreal::R3::Matrix& B) const; + const srreal::R3::Matrix& A, const srreal::R3::Matrix& B) const; -} // namespace mathutils -} // namespace diffpy +} // namespace mathutils +} // namespace diffpy #endif // R3LINALG_HPP_INCLUDED diff --git a/src/diffpy/srreal/SFTElectron.cpp b/src/diffpy/srreal/SFTElectron.cpp index 556aedea..f27df75b 100644 --- a/src/diffpy/srreal/SFTElectron.cpp +++ b/src/diffpy/srreal/SFTElectron.cpp @@ -1,25 +1,25 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class SFTElectron -* -* Implementation of electron ScatteringFactorTable using the formula in -* International Tables Volume C, page 224. -* The instance can be also created by calling the -* createByType("electron") factory. -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class SFTElectron + * + * Implementation of electron ScatteringFactorTable using the formula in + * International Tables Volume C, page 224. + * The instance can be also created by calling the + * createByType("electron") factory. + * + *****************************************************************************/ #include #include @@ -34,44 +34,38 @@ using namespace std; // HasClassRegistry methods -ScatteringFactorTablePtr SFTElectron::create() const -{ - ScatteringFactorTablePtr rv(new SFTElectron()); - return rv; +ScatteringFactorTablePtr SFTElectron::create() const { + ScatteringFactorTablePtr rv(new SFTElectron()); + return rv; } -ScatteringFactorTablePtr SFTElectron::clone() const -{ - ScatteringFactorTablePtr rv(new SFTElectron(*this)); - return rv; +ScatteringFactorTablePtr SFTElectron::clone() const { + ScatteringFactorTablePtr rv(new SFTElectron(*this)); + return rv; } -const string& SFTElectron::type() const -{ - static string rv = "electron"; - return rv; +const string& SFTElectron::type() const { + static string rv = "electron"; + return rv; } // own methods - overloads -const string& SFTElectron::radiationType() const -{ - static string rv = "E"; - return rv; +const string& SFTElectron::radiationType() const { + static string rv = "E"; + return rv; } - -double SFTElectron::standardLookup(const string& smbl, double q) const -{ - return felectronatq(smbl, q); +double SFTElectron::standardLookup(const string& smbl, double q) const { + return felectronatq(smbl, q); } // Registration -------------------------------------------------------------- bool reg_SFTElectron = SFTElectron().registerThisType(); -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/SFTElectron.hpp b/src/diffpy/srreal/SFTElectron.hpp index 86b158dd..b4c91bf5 100644 --- a/src/diffpy/srreal/SFTElectron.hpp +++ b/src/diffpy/srreal/SFTElectron.hpp @@ -1,24 +1,24 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class SFTElectron -* -* SFTElectron gives Q-dependent electron scattering factor according to -* the formula in International Tables Volume C, page 224. -* The formula diverges at Q = 0, where SFTElectron returns DOUBLE_MAX. -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class SFTElectron + * + * SFTElectron gives Q-dependent electron scattering factor according to + * the formula in International Tables Volume C, page 224. + * The formula diverges at Q = 0, where SFTElectron returns DOUBLE_MAX. + * + *****************************************************************************/ #ifndef SFTELECTRON_HPP_INCLUDED #define SFTELECTRON_HPP_INCLUDED @@ -26,39 +26,36 @@ #include #include +#include + namespace diffpy { namespace srreal { -class SFTElectron : public ScatteringFactorTable -{ - public: - - // HasClassRegistry methods - ScatteringFactorTablePtr create() const; - ScatteringFactorTablePtr clone() const; - const std::string& type() const; - // own methods - const std::string& radiationType() const; - // method overloads - double standardLookup(const std::string& smbl, double q) const; +class DLL_EXPORT SFTElectron : public ScatteringFactorTable { + public: + // HasClassRegistry methods + ScatteringFactorTablePtr create() const; + ScatteringFactorTablePtr clone() const; + const std::string& type() const; + // own methods + const std::string& radiationType() const; + // method overloads + double standardLookup(const std::string& smbl, double q) const; - private: + private: + // serialization + friend class boost::serialization::access; - // serialization - friend class boost::serialization::access; - - template - void serialize(Archive& ar, const unsigned int version) - { - using boost::serialization::base_object; - ar & base_object(*this); - } + template + void serialize(Archive& ar, const unsigned int version) { + using boost::serialization::base_object; + ar& base_object(*this); + } }; // class SFTElectron - -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/SFTElectronNumber.cpp b/src/diffpy/srreal/SFTElectronNumber.cpp index 47f65d8e..db37e48e 100644 --- a/src/diffpy/srreal/SFTElectronNumber.cpp +++ b/src/diffpy/srreal/SFTElectronNumber.cpp @@ -1,23 +1,23 @@ /***************************************************************************** -* -* libdiffpy 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. -* -****************************************************************************** -* -* class SFTElectronNumber -* -* ScatteringFactorTable implementation where scattering power equals number -* of valence electrons and is constant with Q. -* -*****************************************************************************/ + * + * libdiffpy 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. + * + ****************************************************************************** + * + * class SFTElectronNumber + * + * ScatteringFactorTable implementation where scattering power equals number + * of valence electrons and is constant with Q. + * + *****************************************************************************/ #include #include @@ -32,45 +32,38 @@ namespace srreal { // HasClassRegistry methods -ScatteringFactorTablePtr SFTElectronNumber::create() const -{ - ScatteringFactorTablePtr rv(new SFTElectronNumber()); - return rv; +ScatteringFactorTablePtr SFTElectronNumber::create() const { + ScatteringFactorTablePtr rv(new SFTElectronNumber()); + return rv; } - -ScatteringFactorTablePtr SFTElectronNumber::clone() const -{ - ScatteringFactorTablePtr rv(new SFTElectronNumber(*this)); - return rv; +ScatteringFactorTablePtr SFTElectronNumber::clone() const { + ScatteringFactorTablePtr rv(new SFTElectronNumber(*this)); + return rv; } -const string& SFTElectronNumber::type() const -{ - static string rv = "electronnumber"; - return rv; +const string& SFTElectronNumber::type() const { + static string rv = "electronnumber"; + return rv; } // own methods - overloads -const string& SFTElectronNumber::radiationType() const -{ - static string rv = "EN"; - return rv; +const string& SFTElectronNumber::radiationType() const { + static string rv = "EN"; + return rv; } - -double SFTElectronNumber::standardLookup(const string& smbl, double q) const -{ - return electronnumber(smbl); +double SFTElectronNumber::standardLookup(const string& smbl, double q) const { + return electronnumber(smbl); } // Registration -------------------------------------------------------------- bool reg_SFTElectronNumber = SFTElectronNumber().registerThisType(); -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/SFTElectronNumber.hpp b/src/diffpy/srreal/SFTElectronNumber.hpp index 3736861b..70a0d1b0 100644 --- a/src/diffpy/srreal/SFTElectronNumber.hpp +++ b/src/diffpy/srreal/SFTElectronNumber.hpp @@ -1,62 +1,59 @@ /***************************************************************************** -* -* libdiffpy 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. -* -****************************************************************************** -* -* class SFTElectronNumber -* -* ScatteringFactorTable with scattering power equal number -* of valence electrons without any Q-dependence -* -*****************************************************************************/ + * + * libdiffpy 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. + * + ****************************************************************************** + * + * class SFTElectronNumber + * + * ScatteringFactorTable with scattering power equal number + * of valence electrons without any Q-dependence + * + *****************************************************************************/ #ifndef SFTELECTRONNUMBER_HPP_INCLUDED #define SFTELECTRONNUMBER_HPP_INCLUDED #include +#include + namespace diffpy { namespace srreal { -class SFTElectronNumber : public ScatteringFactorTable -{ - public: - - // HasClassRegistry methods - ScatteringFactorTablePtr create() const; - ScatteringFactorTablePtr clone() const; - const std::string& type() const; - // own methods - const std::string& radiationType() const; - // method overloads - double standardLookup(const std::string& smbl, double q) const; - - private: - - // serialization - friend class boost::serialization::access; - - template - void serialize(Archive& ar, const unsigned int version) - { - using boost::serialization::base_object; - ar & base_object(*this); - } +class DLL_EXPORT SFTElectronNumber : public ScatteringFactorTable { + public: + // HasClassRegistry methods + ScatteringFactorTablePtr create() const; + ScatteringFactorTablePtr clone() const; + const std::string& type() const; + // own methods + const std::string& radiationType() const; + // method overloads + double standardLookup(const std::string& smbl, double q) const; + + private: + // serialization + friend class boost::serialization::access; + + template + void serialize(Archive& ar, const unsigned int version) { + using boost::serialization::base_object; + ar& base_object(*this); + } }; // class SFTElectronNumber - -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/SFTNeutron.cpp b/src/diffpy/srreal/SFTNeutron.cpp index 96d9af20..0b92b46b 100644 --- a/src/diffpy/srreal/SFTNeutron.cpp +++ b/src/diffpy/srreal/SFTNeutron.cpp @@ -1,25 +1,25 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class SFTNeutron -* -* Implementation of neutron ScatteringFactorTable using coherent cross -* sections data from Paul Kienzle periodictable library for Python. -* approximation. The instance can be also created by calling the -* createByType("neutron") factory. -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class SFTNeutron + * + * Implementation of neutron ScatteringFactorTable using coherent cross + * sections data from Paul Kienzle periodictable library for Python. + * approximation. The instance can be also created by calling the + * createByType("neutron") factory. + * + *****************************************************************************/ #include #include @@ -34,44 +34,38 @@ using namespace std; // HasClassRegistry methods -ScatteringFactorTablePtr SFTNeutron::create() const -{ - ScatteringFactorTablePtr rv(new SFTNeutron()); - return rv; +ScatteringFactorTablePtr SFTNeutron::create() const { + ScatteringFactorTablePtr rv(new SFTNeutron()); + return rv; } -ScatteringFactorTablePtr SFTNeutron::clone() const -{ - ScatteringFactorTablePtr rv(new SFTNeutron(*this)); - return rv; +ScatteringFactorTablePtr SFTNeutron::clone() const { + ScatteringFactorTablePtr rv(new SFTNeutron(*this)); + return rv; } -const string& SFTNeutron::type() const -{ - static string rv = "neutron"; - return rv; +const string& SFTNeutron::type() const { + static string rv = "neutron"; + return rv; } // own methods - overloads -const string& SFTNeutron::radiationType() const -{ - static string rv = "N"; - return rv; +const string& SFTNeutron::radiationType() const { + static string rv = "N"; + return rv; } - -double SFTNeutron::standardLookup(const string& smbl, double q) const -{ - return bcneutron(smbl); +double SFTNeutron::standardLookup(const string& smbl, double q) const { + return bcneutron(smbl); } // Registration -------------------------------------------------------------- bool reg_SFTNeutron = SFTNeutron().registerThisType(); -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/SFTNeutron.hpp b/src/diffpy/srreal/SFTNeutron.hpp index d2264dc6..58af7446 100644 --- a/src/diffpy/srreal/SFTNeutron.hpp +++ b/src/diffpy/srreal/SFTNeutron.hpp @@ -1,62 +1,59 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class SFTNeutron -* -* Neutron ScatteringFactorTable using coherent cross sections extracted -* from Paul Kienzle periodictable library for Python. -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class SFTNeutron + * + * Neutron ScatteringFactorTable using coherent cross sections extracted + * from Paul Kienzle periodictable library for Python. + * + *****************************************************************************/ #ifndef SFTNEUTRON_HPP_INCLUDED #define SFTNEUTRON_HPP_INCLUDED #include +#include + namespace diffpy { namespace srreal { -class SFTNeutron : public ScatteringFactorTable -{ - public: - - // HasClassRegistry methods - ScatteringFactorTablePtr create() const; - ScatteringFactorTablePtr clone() const; - const std::string& type() const; - // own methods - const std::string& radiationType() const; - // method overloads - double standardLookup(const std::string& smbl, double q) const; - - private: - - // serialization - friend class boost::serialization::access; - - template - void serialize(Archive& ar, const unsigned int version) - { - using boost::serialization::base_object; - ar & base_object(*this); - } +class DLL_EXPORT SFTNeutron : public ScatteringFactorTable { + public: + // HasClassRegistry methods + ScatteringFactorTablePtr create() const; + ScatteringFactorTablePtr clone() const; + const std::string& type() const; + // own methods + const std::string& radiationType() const; + // method overloads + double standardLookup(const std::string& smbl, double q) const; + + private: + // serialization + friend class boost::serialization::access; + + template + void serialize(Archive& ar, const unsigned int version) { + using boost::serialization::base_object; + ar& base_object(*this); + } }; // class SFTNeutron - -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/SFTXray.cpp b/src/diffpy/srreal/SFTXray.cpp index 9d24562a..8289e027 100644 --- a/src/diffpy/srreal/SFTXray.cpp +++ b/src/diffpy/srreal/SFTXray.cpp @@ -1,24 +1,24 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class SFTXray -* -* Implementation of x-ray ScatteringFactorTable using Waasmaier and Kirfel -* approximation. The instance can be also created by calling the -* createByType("xray") factory. -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class SFTXray + * + * Implementation of x-ray ScatteringFactorTable using Waasmaier and Kirfel + * approximation. The instance can be also created by calling the + * createByType("xray") factory. + * + *****************************************************************************/ #include #include @@ -33,44 +33,38 @@ using namespace std; // HasClassRegistry methods -ScatteringFactorTablePtr SFTXray::create() const -{ - ScatteringFactorTablePtr rv(new SFTXray()); - return rv; +ScatteringFactorTablePtr SFTXray::create() const { + ScatteringFactorTablePtr rv(new SFTXray()); + return rv; } -ScatteringFactorTablePtr SFTXray::clone() const -{ - ScatteringFactorTablePtr rv(new SFTXray(*this)); - return rv; +ScatteringFactorTablePtr SFTXray::clone() const { + ScatteringFactorTablePtr rv(new SFTXray(*this)); + return rv; } -const string& SFTXray::type() const -{ - static string rv = "xray"; - return rv; +const string& SFTXray::type() const { + static string rv = "xray"; + return rv; } // own methods - overloads -const string& SFTXray::radiationType() const -{ - static string rv = "X"; - return rv; +const string& SFTXray::radiationType() const { + static string rv = "X"; + return rv; } - -double SFTXray::standardLookup(const string& smbl, double q) const -{ - return fxrayatq(smbl, q); +double SFTXray::standardLookup(const string& smbl, double q) const { + return fxrayatq(smbl, q); } // Registration -------------------------------------------------------------- bool reg_SFTXray = SFTXray().registerThisType(); -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/SFTXray.hpp b/src/diffpy/srreal/SFTXray.hpp index 833ff611..687aff5e 100644 --- a/src/diffpy/srreal/SFTXray.hpp +++ b/src/diffpy/srreal/SFTXray.hpp @@ -1,61 +1,58 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class SFTXray -* -* X-ray ScatteringFactorTable using Waasmaier and Kirfel approximation. -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class SFTXray + * + * X-ray ScatteringFactorTable using Waasmaier and Kirfel approximation. + * + *****************************************************************************/ #ifndef SFTXRAY_HPP_INCLUDED #define SFTXRAY_HPP_INCLUDED #include +#include + namespace diffpy { namespace srreal { -class SFTXray : public ScatteringFactorTable -{ - public: - - // HasClassRegistry methods - ScatteringFactorTablePtr create() const; - ScatteringFactorTablePtr clone() const; - const std::string& type() const; - // own methods - const std::string& radiationType() const; - // method overloads - double standardLookup(const std::string& smbl, double q) const; - - private: - - // serialization - friend class boost::serialization::access; - - template - void serialize(Archive& ar, const unsigned int version) - { - using boost::serialization::base_object; - ar & base_object(*this); - } +class DLL_EXPORT SFTXray : public ScatteringFactorTable { + public: + // HasClassRegistry methods + ScatteringFactorTablePtr create() const; + ScatteringFactorTablePtr clone() const; + const std::string& type() const; + // own methods + const std::string& radiationType() const; + // method overloads + double standardLookup(const std::string& smbl, double q) const; + + private: + // serialization + friend class boost::serialization::access; + + template + void serialize(Archive& ar, const unsigned int version) { + using boost::serialization::base_object; + ar& base_object(*this); + } }; // class SFTXray - -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/ScaleEnvelope.cpp b/src/diffpy/srreal/ScaleEnvelope.cpp index 65dab37a..b671a9a8 100644 --- a/src/diffpy/srreal/ScaleEnvelope.cpp +++ b/src/diffpy/srreal/ScaleEnvelope.cpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class ScaleEnvelope -- constant scaling factor -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class ScaleEnvelope -- constant scaling factor + * + *****************************************************************************/ #include #include @@ -26,60 +26,43 @@ namespace srreal { // Constructors -------------------------------------------------------------- -ScaleEnvelope::ScaleEnvelope() -{ - this->setScale(1.0); - this->registerDoubleAttribute("scale", - this, &ScaleEnvelope::getScale, &ScaleEnvelope::setScale); +ScaleEnvelope::ScaleEnvelope() { + this->setScale(1.0); + this->registerDoubleAttribute("scale", this, &ScaleEnvelope::getScale, + &ScaleEnvelope::setScale); } - -PDFEnvelopePtr ScaleEnvelope::create() const -{ - PDFEnvelopePtr rv(new ScaleEnvelope()); - return rv; +PDFEnvelopePtr ScaleEnvelope::create() const { + PDFEnvelopePtr rv(new ScaleEnvelope()); + return rv; } - -PDFEnvelopePtr ScaleEnvelope::clone() const -{ - PDFEnvelopePtr rv(new ScaleEnvelope(*this)); - return rv; +PDFEnvelopePtr ScaleEnvelope::clone() const { + PDFEnvelopePtr rv(new ScaleEnvelope(*this)); + return rv; } // Public Methods ------------------------------------------------------------ -const string& ScaleEnvelope::type() const -{ - static string rv = "scale"; - return rv; -} - - -double ScaleEnvelope::operator()(const double& r) const -{ - return this->getScale(); +const string& ScaleEnvelope::type() const { + static string rv = "scale"; + return rv; } - -void ScaleEnvelope::setScale(double sc) -{ - mscale = sc; +double ScaleEnvelope::operator()(const double& r) const { + return this->getScale(); } +void ScaleEnvelope::setScale(double sc) { mscale = sc; } -const double& ScaleEnvelope::getScale() const -{ - return mscale; -} - +const double& ScaleEnvelope::getScale() const { return mscale; } // Registration -------------------------------------------------------------- bool reg_ScaleEnvelope = ScaleEnvelope().registerThisType(); -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/ScaleEnvelope.hpp b/src/diffpy/srreal/ScaleEnvelope.hpp index a01bb462..8c5c0e7b 100644 --- a/src/diffpy/srreal/ScaleEnvelope.hpp +++ b/src/diffpy/srreal/ScaleEnvelope.hpp @@ -1,67 +1,65 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class ScaleEnvelope -- constant scaling factor -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class ScaleEnvelope -- constant scaling factor + * + *****************************************************************************/ #ifndef SCALEENVELOPE_HPP_INCLUDED #define SCALEENVELOPE_HPP_INCLUDED #include +#include + namespace diffpy { namespace srreal { /// @class ScaleEnvelope /// @brief constant PDF scaling factor -class ScaleEnvelope : public PDFEnvelope -{ - public: - - // constructors - ScaleEnvelope(); - PDFEnvelopePtr create() const; - PDFEnvelopePtr clone() const; - - // methods - const std::string& type() const; - double operator()(const double& r) const; - void setScale(double sc); - const double& getScale() const; - - private: - - // data - double mscale; - - // serialization - friend class boost::serialization::access; - - template - void serialize(Archive& ar, const unsigned int version) - { - using boost::serialization::base_object; - ar & base_object(*this); - ar & mscale; - } +class DLL_EXPORT ScaleEnvelope : public PDFEnvelope { + public: + // constructors + ScaleEnvelope(); + PDFEnvelopePtr create() const; + PDFEnvelopePtr clone() const; + + // methods + const std::string& type() const; + double operator()(const double& r) const; + void setScale(double sc); + const double& getScale() const; + + private: + // data + double mscale; + + // serialization + friend class boost::serialization::access; + + template + void serialize(Archive& ar, const unsigned int version) { + using boost::serialization::base_object; + ar& base_object(*this); + ar & mscale; + } }; // class ScaleEnvelope -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/ScatteringFactorTable.cpp b/src/diffpy/srreal/ScatteringFactorTable.cpp index b5c4872a..28ea556b 100644 --- a/src/diffpy/srreal/ScatteringFactorTable.cpp +++ b/src/diffpy/srreal/ScatteringFactorTable.cpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class ScatteringFactorTable -- base class for looking up scattering factors -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class ScatteringFactorTable -- base class for looking up scattering factors + * + *****************************************************************************/ #include #include @@ -27,7 +27,7 @@ using diffpy::validators::ensureNonNull; namespace diffpy { // Unique instantiation of the template registry base class. -template class HasClassRegistry; +template class DLL_EXPORT HasClassRegistry; namespace srreal { @@ -35,131 +35,104 @@ namespace srreal { // public methods -bool ScatteringFactorTable::registerThisType() const -{ - typedef diffpy::HasClassRegistry HCRBase; - bool rv = this->HCRBase::registerThisType(); - rv = rv && ScatteringFactorTable::aliasType( - this->type(), this->radiationType()); - return rv; +bool ScatteringFactorTable::registerThisType() const { + typedef diffpy::HasClassRegistry HCRBase; + bool rv = this->HCRBase::registerThisType(); + rv = + rv && ScatteringFactorTable::aliasType(this->type(), this->radiationType()); + return rv; } - -double ScatteringFactorTable::lookup(const string& smbl, double q) const -{ - double rv; - CustomDataStorage::const_iterator csft = mcustom.find(smbl); - if (csft != mcustom.end()) - { - const string& srcsmbl = csft->second.first; - const double& scale = csft->second.second; - rv = this->standardLookup(srcsmbl, q) * scale; - } - else { - rv = this->standardLookup(smbl, q); - } - return rv; +double ScatteringFactorTable::lookup(const string& smbl, double q) const { + double rv; + CustomDataStorage::const_iterator csft = mcustom.find(smbl); + if (csft != mcustom.end()) { + const string& srcsmbl = csft->second.first; + const double& scale = csft->second.second; + rv = this->standardLookup(srcsmbl, q) * scale; + } else { + rv = this->standardLookup(smbl, q); + } + return rv; } - -void ScatteringFactorTable::setCustomAs( - const string& smbl, const string& srcsmbl) -{ - const double scale = 1.0; - CustomDataStorage::mapped_type entry(srcsmbl, scale); - if (mcustom.count(smbl) && mcustom.at(smbl) == entry) return; - mcustom[smbl] = entry; - mticker.click(); +void ScatteringFactorTable::setCustomAs(const string& smbl, + const string& srcsmbl) { + const double scale = 1.0; + CustomDataStorage::mapped_type entry(srcsmbl, scale); + if (mcustom.count(smbl) && mcustom.at(smbl) == entry) return; + mcustom[smbl] = entry; + mticker.click(); } - -void ScatteringFactorTable::setCustomAs( - const string& smbl, const string& srcsmbl, - double value, double q) -{ - double fsrc = this->standardLookup(srcsmbl, q); - double scale = value / fsrc; - CustomDataStorage::mapped_type entry(srcsmbl, scale); - if (mcustom.count(smbl) && mcustom.at(smbl) == entry) return; - mcustom[smbl] = entry; - mticker.click(); +void ScatteringFactorTable::setCustomAs(const string& smbl, + const string& srcsmbl, double value, + double q) { + double fsrc = this->standardLookup(srcsmbl, q); + double scale = value / fsrc; + CustomDataStorage::mapped_type entry(srcsmbl, scale); + if (mcustom.count(smbl) && mcustom.at(smbl) == entry) return; + mcustom[smbl] = entry; + mticker.click(); } - -void ScatteringFactorTable::resetCustom(const string& smbl) -{ - if (mcustom.count(smbl)) mticker.click(); - mcustom.erase(smbl); +void ScatteringFactorTable::resetCustom(const string& smbl) { + if (mcustom.count(smbl)) mticker.click(); + mcustom.erase(smbl); } - -void ScatteringFactorTable::resetAll() -{ - if (!mcustom.empty()) mticker.click(); - mcustom.clear(); +void ScatteringFactorTable::resetAll() { + if (!mcustom.empty()) mticker.click(); + mcustom.clear(); } - -unordered_set ScatteringFactorTable::getCustomSymbols() const -{ - unordered_set rv; - CustomDataStorage::const_iterator csft; - for (csft = mcustom.begin(); csft != mcustom.end(); ++csft) - { - rv.insert(csft->first); - } - return rv; +unordered_set ScatteringFactorTable::getCustomSymbols() const { + unordered_set rv; + CustomDataStorage::const_iterator csft; + for (csft = mcustom.begin(); csft != mcustom.end(); ++csft) { + rv.insert(csft->first); + } + return rv; } // class ScatteringFactorTableOwner ------------------------------------------ void ScatteringFactorTableOwner::setScatteringFactorTable( - ScatteringFactorTablePtr sft) -{ - ensureNonNull("ScatteringFactorTable", sft); - if (msftable != sft) mprivateticker.click(); - msftable = sft; + ScatteringFactorTablePtr sft) { + ensureNonNull("ScatteringFactorTable", sft); + if (msftable != sft) mprivateticker.click(); + msftable = sft; } - void ScatteringFactorTableOwner::setScatteringFactorTableByType( - const string& tp) -{ - msftable = ScatteringFactorTable::createByType(tp); - mprivateticker.click(); + const string& tp) { + msftable = ScatteringFactorTable::createByType(tp); + mprivateticker.click(); } - ScatteringFactorTablePtr& -ScatteringFactorTableOwner::getScatteringFactorTable() -{ - return msftable; +ScatteringFactorTableOwner::getScatteringFactorTable() { + return msftable; } - const ScatteringFactorTablePtr& -ScatteringFactorTableOwner::getScatteringFactorTable() const -{ - return msftable; +ScatteringFactorTableOwner::getScatteringFactorTable() const { + return msftable; } - -const string& ScatteringFactorTableOwner::getRadiationType() const -{ - static string empty; - const string& tp = msftable.get() ? msftable->radiationType() : empty; - return tp; +const string& ScatteringFactorTableOwner::getRadiationType() const { + static string empty; + const string& tp = msftable.get() ? msftable->radiationType() : empty; + return tp; } - -eventticker::EventTicker& ScatteringFactorTableOwner::ticker() const -{ - if (msftable) mprivateticker.updateFrom(msftable->ticker()); - return mprivateticker; +eventticker::EventTicker& ScatteringFactorTableOwner::ticker() const { + if (msftable) mprivateticker.updateFrom(msftable->ticker()); + return mprivateticker; } -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/ScatteringFactorTable.hpp b/src/diffpy/srreal/ScatteringFactorTable.hpp index e876748d..6a17adb4 100644 --- a/src/diffpy/srreal/ScatteringFactorTable.hpp +++ b/src/diffpy/srreal/ScatteringFactorTable.hpp @@ -1,23 +1,23 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class ScatteringFactorTable -- base class for looking up scattering factors -* -* class ScatteringFactorTableOwner -- to be used as a base class for classes -* that own ScatteringFactorTable -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class ScatteringFactorTable -- base class for looking up scattering factors + * + * class ScatteringFactorTableOwner -- to be used as a base class for classes + * that own ScatteringFactorTable + * + *****************************************************************************/ #ifndef SCATTERINGFACTORTABLE_HPP_INCLUDED #define SCATTERINGFACTORTABLE_HPP_INCLUDED @@ -33,81 +33,73 @@ #include #include +#include + namespace diffpy { namespace srreal { -class ScatteringFactorTable : - public diffpy::HasClassRegistry -{ - public: - - // HasClassRegistry override - bool registerThisType() const; - - // own methods - virtual const std::string& radiationType() const = 0; - double lookup(const std::string& smbl, double q=0.0) const; - virtual double standardLookup(const std::string&, double) const = 0; - void setCustomAs(const std::string& smbl, const std::string& srcsmbl); - void setCustomAs(const std::string& smbl, const std::string& srcsmbl, - double value, double q=0.0); - void resetCustom(const std::string& smbl); - void resetAll(); - std::unordered_set getCustomSymbols() const; - - typedef std::unordered_map > CustomDataStorage; - virtual eventticker::EventTicker& ticker() const { return mticker; } - - protected: - - // data - CustomDataStorage mcustom; - mutable eventticker::EventTicker mticker; - - private: - - // serialization - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - ar & mcustom & mticker; - } - +class DLL_EXPORT ScatteringFactorTable + : public diffpy::HasClassRegistry { + public: + // HasClassRegistry override + bool registerThisType() const; + + // own methods + virtual const std::string& radiationType() const = 0; + double lookup(const std::string& smbl, double q = 0.0) const; + virtual double standardLookup(const std::string&, double) const = 0; + void setCustomAs(const std::string& smbl, const std::string& srcsmbl); + void setCustomAs(const std::string& smbl, const std::string& srcsmbl, + double value, double q = 0.0); + void resetCustom(const std::string& smbl); + void resetAll(); + std::unordered_set getCustomSymbols() const; + + typedef std::unordered_map > + CustomDataStorage; + virtual eventticker::EventTicker& ticker() const { return mticker; } + + protected: + // data + CustomDataStorage mcustom; + mutable eventticker::EventTicker mticker; + + private: + // serialization + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + ar & mcustom & mticker; + } }; typedef ScatteringFactorTable::SharedPtr ScatteringFactorTablePtr; -class ScatteringFactorTableOwner -{ - public: - - // access and configuration of scattering factors - void setScatteringFactorTable(ScatteringFactorTablePtr); - void setScatteringFactorTableByType(const std::string& tp); - ScatteringFactorTablePtr& getScatteringFactorTable(); - const ScatteringFactorTablePtr& getScatteringFactorTable() const; - const std::string& getRadiationType() const; - eventticker::EventTicker& ticker() const; - - private: - - // data - ScatteringFactorTablePtr msftable; - mutable eventticker::EventTicker mprivateticker; - - // serialization - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - ar & msftable & mprivateticker; - } +class DLL_EXPORT ScatteringFactorTableOwner { + public: + // access and configuration of scattering factors + void setScatteringFactorTable(ScatteringFactorTablePtr); + void setScatteringFactorTableByType(const std::string& tp); + ScatteringFactorTablePtr& getScatteringFactorTable(); + const ScatteringFactorTablePtr& getScatteringFactorTable() const; + const std::string& getRadiationType() const; + eventticker::EventTicker& ticker() const; + + private: + // data + ScatteringFactorTablePtr msftable; + mutable eventticker::EventTicker mprivateticker; + + // serialization + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + ar & msftable & mprivateticker; + } }; -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/SphericalShapeEnvelope.cpp b/src/diffpy/srreal/SphericalShapeEnvelope.cpp index c7f7388c..7e66437d 100644 --- a/src/diffpy/srreal/SphericalShapeEnvelope.cpp +++ b/src/diffpy/srreal/SphericalShapeEnvelope.cpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class SphericalShapeEnvelope -- PDF envelope due to spherical shape factor -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class SphericalShapeEnvelope -- PDF envelope due to spherical shape factor + * + *****************************************************************************/ #include @@ -28,64 +28,50 @@ namespace srreal { // Constructor --------------------------------------------------------------- -SphericalShapeEnvelope::SphericalShapeEnvelope() -{ - this->setSPDiameter(0.0); - this->registerDoubleAttribute("spdiameter", this, - &SphericalShapeEnvelope::getSPDiameter, - &SphericalShapeEnvelope::setSPDiameter); +SphericalShapeEnvelope::SphericalShapeEnvelope() { + this->setSPDiameter(0.0); + this->registerDoubleAttribute("spdiameter", this, + &SphericalShapeEnvelope::getSPDiameter, + &SphericalShapeEnvelope::setSPDiameter); } - -PDFEnvelopePtr SphericalShapeEnvelope::create() const -{ - PDFEnvelopePtr rv(new SphericalShapeEnvelope()); - return rv; +PDFEnvelopePtr SphericalShapeEnvelope::create() const { + PDFEnvelopePtr rv(new SphericalShapeEnvelope()); + return rv; } - -PDFEnvelopePtr SphericalShapeEnvelope::clone() const -{ - PDFEnvelopePtr rv(new SphericalShapeEnvelope(*this)); - return rv; +PDFEnvelopePtr SphericalShapeEnvelope::clone() const { + PDFEnvelopePtr rv(new SphericalShapeEnvelope(*this)); + return rv; } // Public Methods ------------------------------------------------------------ -const string& SphericalShapeEnvelope::type() const -{ - static string rv = "sphericalshape"; - return rv; -} - - -double SphericalShapeEnvelope::operator()(const double& r) const -{ - if (mspdiameter <= 0.0) return 1.0; - if (r > mspdiameter) return 0.0; - double rdratio = r / mspdiameter; - double rv = 1.0 - 1.5 * rdratio + 0.5 * pow(rdratio, 3); - return rv; +const string& SphericalShapeEnvelope::type() const { + static string rv = "sphericalshape"; + return rv; } - -void SphericalShapeEnvelope::setSPDiameter(double spd) -{ - mspdiameter = spd; +double SphericalShapeEnvelope::operator()(const double& r) const { + if (mspdiameter <= 0.0) return 1.0; + if (r > mspdiameter) return 0.0; + double rdratio = r / mspdiameter; + double rv = 1.0 - 1.5 * rdratio + 0.5 * pow(rdratio, 3); + return rv; } +void SphericalShapeEnvelope::setSPDiameter(double spd) { mspdiameter = spd; } -const double& SphericalShapeEnvelope::getSPDiameter() const -{ - return mspdiameter; +const double& SphericalShapeEnvelope::getSPDiameter() const { + return mspdiameter; } // Registration -------------------------------------------------------------- bool reg_SphericalShapeEnvelope = SphericalShapeEnvelope().registerThisType(); -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/SphericalShapeEnvelope.hpp b/src/diffpy/srreal/SphericalShapeEnvelope.hpp index 67ba9740..e7a2c534 100644 --- a/src/diffpy/srreal/SphericalShapeEnvelope.hpp +++ b/src/diffpy/srreal/SphericalShapeEnvelope.hpp @@ -1,26 +1,28 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class SphericalShapeEnvelope -- PDF envelope due to spherical shape factor -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class SphericalShapeEnvelope -- PDF envelope due to spherical shape factor + * + *****************************************************************************/ #ifndef SPHERICALSHAPEENVELOPE_HPP_INCLUDED #define SPHERICALSHAPEENVELOPE_HPP_INCLUDED #include +#include + namespace diffpy { namespace srreal { @@ -29,41 +31,37 @@ namespace srreal { /// Spherical shape envelope is not applied for spherical particle /// diameter, spdiameter, smaller or equal to zero. -class SphericalShapeEnvelope : public PDFEnvelope -{ - public: - - // constructors - SphericalShapeEnvelope(); - virtual PDFEnvelopePtr create() const; - virtual PDFEnvelopePtr clone() const; - - // methods - virtual const std::string& type() const; - virtual double operator()(const double& r) const; - void setSPDiameter(double spd); - const double& getSPDiameter() const; - - private: - - // data - double mspdiameter; - - // serialization - friend class boost::serialization::access; - - template - void serialize(Archive& ar, const unsigned int version) - { - using boost::serialization::base_object; - ar & base_object(*this); - ar & mspdiameter; - } +class DLL_EXPORT SphericalShapeEnvelope : public PDFEnvelope { + public: + // constructors + SphericalShapeEnvelope(); + virtual PDFEnvelopePtr create() const; + virtual PDFEnvelopePtr clone() const; + + // methods + virtual const std::string& type() const; + virtual double operator()(const double& r) const; + void setSPDiameter(double spd); + const double& getSPDiameter() const; + + private: + // data + double mspdiameter; + + // serialization + friend class boost::serialization::access; + + template + void serialize(Archive& ar, const unsigned int version) { + using boost::serialization::base_object; + ar& base_object(*this); + ar & mspdiameter; + } }; // class SphericalShapeEnvelope -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/StepCutEnvelope.cpp b/src/diffpy/srreal/StepCutEnvelope.cpp index 0c186693..e2c1ea7e 100644 --- a/src/diffpy/srreal/StepCutEnvelope.cpp +++ b/src/diffpy/srreal/StepCutEnvelope.cpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class StepCutEnvelope -- empirical step-function PDF envelope. -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class StepCutEnvelope -- empirical step-function PDF envelope. + * + *****************************************************************************/ #include #include @@ -26,60 +26,44 @@ namespace srreal { // Constructor --------------------------------------------------------------- -StepCutEnvelope::StepCutEnvelope() -{ - this->setStepCut(0.0); - this->registerDoubleAttribute("stepcut", this, - &StepCutEnvelope::getStepCut, &StepCutEnvelope::setStepCut); +StepCutEnvelope::StepCutEnvelope() { + this->setStepCut(0.0); + this->registerDoubleAttribute("stepcut", this, &StepCutEnvelope::getStepCut, + &StepCutEnvelope::setStepCut); } - -PDFEnvelopePtr StepCutEnvelope::create() const -{ - PDFEnvelopePtr rv(new StepCutEnvelope()); - return rv; +PDFEnvelopePtr StepCutEnvelope::create() const { + PDFEnvelopePtr rv(new StepCutEnvelope()); + return rv; } - -PDFEnvelopePtr StepCutEnvelope::clone() const -{ - PDFEnvelopePtr rv(new StepCutEnvelope(*this)); - return rv; +PDFEnvelopePtr StepCutEnvelope::clone() const { + PDFEnvelopePtr rv(new StepCutEnvelope(*this)); + return rv; } // Public Methods ------------------------------------------------------------ -const string& StepCutEnvelope::type() const -{ - static string rv = "stepcut"; - return rv; +const string& StepCutEnvelope::type() const { + static string rv = "stepcut"; + return rv; } - -double StepCutEnvelope::operator()(const double& r) const -{ - double rv = (mstepcut > 0.0 && r > mstepcut) ? 0.0 : 1.0; - return rv; +double StepCutEnvelope::operator()(const double& r) const { + double rv = (mstepcut > 0.0 && r > mstepcut) ? 0.0 : 1.0; + return rv; } +void StepCutEnvelope::setStepCut(double sc) { mstepcut = sc; } -void StepCutEnvelope::setStepCut(double sc) -{ - mstepcut = sc; -} - - -const double& StepCutEnvelope::getStepCut() const -{ - return mstepcut; -} +const double& StepCutEnvelope::getStepCut() const { return mstepcut; } // Registration -------------------------------------------------------------- bool reg_StepCutEnvelope = StepCutEnvelope().registerThisType(); -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/StepCutEnvelope.hpp b/src/diffpy/srreal/StepCutEnvelope.hpp index 597b5a64..f47e5721 100644 --- a/src/diffpy/srreal/StepCutEnvelope.hpp +++ b/src/diffpy/srreal/StepCutEnvelope.hpp @@ -1,26 +1,28 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class StepCutEnvelope -- empirical step-function PDF envelope. -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class StepCutEnvelope -- empirical step-function PDF envelope. + * + *****************************************************************************/ #ifndef STEPCUTENVELOPE_HPP_INCLUDED #define STEPCUTENVELOPE_HPP_INCLUDED #include +#include + namespace diffpy { namespace srreal { @@ -28,42 +30,38 @@ namespace srreal { /// @brief empirical step-function PDF envelope. The envelope is not /// applied when the cutoff radius stepcut is smaller or equal zero. -class StepCutEnvelope : public PDFEnvelope -{ - public: - - // constructors - StepCutEnvelope(); - virtual PDFEnvelopePtr create() const; - virtual PDFEnvelopePtr clone() const; - - // methods +class DLL_EXPORT StepCutEnvelope : public PDFEnvelope { + public: + // constructors + StepCutEnvelope(); + virtual PDFEnvelopePtr create() const; + virtual PDFEnvelopePtr clone() const; - virtual const std::string& type() const; - virtual double operator()(const double& r) const; - void setStepCut(double sc); - const double& getStepCut() const; + // methods - private: + virtual const std::string& type() const; + virtual double operator()(const double& r) const; + void setStepCut(double sc); + const double& getStepCut() const; - // data - double mstepcut; + private: + // data + double mstepcut; - // serialization - friend class boost::serialization::access; + // serialization + friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - using boost::serialization::base_object; - ar & base_object(*this); - ar & mstepcut; - } + template + void serialize(Archive& ar, const unsigned int version) { + using boost::serialization::base_object; + ar& base_object(*this); + ar & mstepcut; + } }; // class StepCutEnvelope -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/StructureAdapter.cpp b/src/diffpy/srreal/StructureAdapter.cpp index d3468ea4..b5ac0814 100644 --- a/src/diffpy/srreal/StructureAdapter.cpp +++ b/src/diffpy/srreal/StructureAdapter.cpp @@ -1,21 +1,21 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class StructureAdapter -- abstract base class for interfacing general -* structure objects with srreal classes such as PairQuantity -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class StructureAdapter -- abstract base class for interfacing general + * structure objects with srreal classes such as PairQuantity + * + *****************************************************************************/ #include #include @@ -33,98 +33,70 @@ namespace srreal { // Public Methods ------------------------------------------------------------ -double StructureAdapter::totalOccupancy() const -{ - double total_occupancy = 0.0; - int cntsites = this->countSites(); - for (int i = 0; i < cntsites; ++i) - { - total_occupancy += this->siteOccupancy(i) * this->siteMultiplicity(i); - } - return total_occupancy; -} - - -double StructureAdapter::numberDensity() const -{ - return 0.0; -} - - -const string& StructureAdapter::siteAtomType(int idx) const -{ - static string rv = ""; - return rv; +double StructureAdapter::totalOccupancy() const { + double total_occupancy = 0.0; + int cntsites = this->countSites(); + for (int i = 0; i < cntsites; ++i) { + total_occupancy += this->siteOccupancy(i) * this->siteMultiplicity(i); + } + return total_occupancy; } +double StructureAdapter::numberDensity() const { return 0.0; } -int StructureAdapter::siteMultiplicity(int idx) const -{ - return 1; +const string& StructureAdapter::siteAtomType(int idx) const { + static string rv = ""; + return rv; } +int StructureAdapter::siteMultiplicity(int idx) const { return 1; } -double StructureAdapter::siteOccupancy(int idx) const -{ - return 1.0; -} - +double StructureAdapter::siteOccupancy(int idx) const { return 1.0; } -StructureDifference -StructureAdapter::diff(StructureAdapterConstPtr other) const -{ - StructureDifference sd(this->shared_from_this(), other); - return sd; +StructureDifference StructureAdapter::diff( + StructureAdapterConstPtr other) const { + StructureDifference sd(this->shared_from_this(), other); + return sd; } // Routines ------------------------------------------------------------------ -double meanSquareDisplacement(const R3::Matrix& Uijcartn, - const R3::Vector& s, bool anisotropy) -{ - double rv; - if (anisotropy) - { - assert(R3::norm(s) > 0); - assert(eps_eq(Uijcartn(0,1), Uijcartn(1,0))); - assert(eps_eq(Uijcartn(0,2), Uijcartn(2,0))); - assert(eps_eq(Uijcartn(1,2), Uijcartn(2,1))); - static R3::Vector sn; - sn = s / R3::norm(s); - rv = Uijcartn(0,0) * sn(0) * sn(0) + - Uijcartn(1,1) * sn(1) * sn(1) + - Uijcartn(2,2) * sn(2) * sn(2) + - 2 * Uijcartn(0,1) * sn(0) * sn(1) + - 2 * Uijcartn(0,2) * sn(0) * sn(2) + - 2 * Uijcartn(1,2) * sn(1) * sn(2); - } - else - { - assert(eps_eq(Uijcartn(0,0), Uijcartn(1,1))); - assert(eps_eq(Uijcartn(0,0), Uijcartn(2,2))); - rv = Uijcartn(0,0); - } - return rv; +double meanSquareDisplacement(const R3::Matrix& Uijcartn, const R3::Vector& s, + bool anisotropy) { + double rv; + if (anisotropy) { + assert(R3::norm(s) > 0); + assert(eps_eq(Uijcartn(0, 1), Uijcartn(1, 0))); + assert(eps_eq(Uijcartn(0, 2), Uijcartn(2, 0))); + assert(eps_eq(Uijcartn(1, 2), Uijcartn(2, 1))); + static R3::Vector sn; + sn = s / R3::norm(s); + rv = Uijcartn(0, 0) * sn(0) * sn(0) + Uijcartn(1, 1) * sn(1) * sn(1) + + Uijcartn(2, 2) * sn(2) * sn(2) + 2 * Uijcartn(0, 1) * sn(0) * sn(1) + + 2 * Uijcartn(0, 2) * sn(0) * sn(2) + + 2 * Uijcartn(1, 2) * sn(1) * sn(2); + } else { + assert(eps_eq(Uijcartn(0, 0), Uijcartn(1, 1))); + assert(eps_eq(Uijcartn(0, 0), Uijcartn(2, 2))); + rv = Uijcartn(0, 0); + } + return rv; } - -double maxUii(StructureAdapterPtr stru) -{ - if (!stru) return 0.0; - double rv = 0.0; - for (int i = 0; i < stru->countSites(); ++i) - { - const R3::Matrix& U = stru->siteCartesianUij(i); - for (int k = 0; k < R3::Ndim; k++) - { - if (U(k,k) > rv) rv = U(k,k); - } +double maxUii(StructureAdapterPtr stru) { + if (!stru) return 0.0; + double rv = 0.0; + for (int i = 0; i < stru->countSites(); ++i) { + const R3::Matrix& U = stru->siteCartesianUij(i); + for (int k = 0; k < R3::Ndim; k++) { + if (U(k, k) > rv) rv = U(k, k); } - return rv; + } + return rv; } -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy DIFFPY_INSTANTIATE_PTR_SERIALIZATION(diffpy::srreal::StructureAdapter) diff --git a/src/diffpy/srreal/StructureAdapter.hpp b/src/diffpy/srreal/StructureAdapter.hpp index 1ff4218d..40adc91d 100644 --- a/src/diffpy/srreal/StructureAdapter.hpp +++ b/src/diffpy/srreal/StructureAdapter.hpp @@ -1,21 +1,21 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class StructureAdapter -- abstract base class for interfacing general -* structure objects with srreal classes such as PairQuantity -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class StructureAdapter -- abstract base class for interfacing general + * structure objects with srreal classes such as PairQuantity + * + *****************************************************************************/ #ifndef STRUCTUREADAPTER_HPP_INCLUDED #define STRUCTUREADAPTER_HPP_INCLUDED @@ -32,105 +32,104 @@ #include #include +#include + +#ifdef _MSC_VER +#define DEPRECATED __declspec(deprecated) +#else +#define DEPRECATED __attribute__((deprecated)) +#endif + namespace diffpy { namespace srreal { class PairQuantity; class StructureDifference; - /// @class StructureAdapter /// @brief abstract adaptor to structure data needed by /// PairQuantity calculator -class StructureAdapter : - public boost::enable_shared_from_this -{ - public: - - virtual ~StructureAdapter() { } +class DLL_EXPORT StructureAdapter + : public boost::enable_shared_from_this { + public: + virtual ~StructureAdapter() {} - // methods - virtual StructureAdapterPtr clone() const = 0; + // methods + virtual StructureAdapterPtr clone() const = 0; - /// factory for creating compatible BondGenerator instance. - virtual BaseBondGeneratorPtr createBondGenerator() const = 0; + /// factory for creating compatible BondGenerator instance. + virtual BaseBondGeneratorPtr createBondGenerator() const = 0; - /// number of independent sites in the structure, before - /// any symmetry expansion. - virtual int countSites() const = 0; + /// number of independent sites in the structure, before + /// any symmetry expansion. + virtual int countSites() const = 0; - /// total number of atoms in the structure unit accounting - /// for possibly fractional occupancies. - double totalOccupancy() const; + /// total number of atoms in the structure unit accounting + /// for possibly fractional occupancies. + double totalOccupancy() const; - /// number density in the structure model or 0 when not defined. - virtual double numberDensity() const; + /// number density in the structure model or 0 when not defined. + virtual double numberDensity() const; - /// symbol for element or ion at the independent site @param idx - virtual const std::string& siteAtomType(int idx) const; + /// symbol for element or ion at the independent site @param idx + virtual const std::string& siteAtomType(int idx) const; - /// Cartesian coordinates of the independent site @param idx - virtual const R3::Vector& siteCartesianPosition(int idx) const = 0; + /// Cartesian coordinates of the independent site @param idx + virtual const R3::Vector& siteCartesianPosition(int idx) const = 0; - /// multiplicity of the independent site @param idx in the structure - virtual int siteMultiplicity(int idx) const; + /// multiplicity of the independent site @param idx in the structure + virtual int siteMultiplicity(int idx) const; - /// site occupancy at the independent site @param idx - virtual double siteOccupancy(int idx) const; + /// site occupancy at the independent site @param idx + virtual double siteOccupancy(int idx) const; - /// flag for anisotropic atom displacements at independent site - /// @param idx - virtual bool siteAnisotropy(int idx) const = 0; + /// flag for anisotropic atom displacements at independent site + /// @param idx + virtual bool siteAnisotropy(int idx) const = 0; - /// tensor of atom displacement parameters converted in - /// Cartesian coordinate system at independent site @param idx - virtual const R3::Matrix& siteCartesianUij(int idx) const = 0; + /// tensor of atom displacement parameters converted in + /// Cartesian coordinate system at independent site @param idx + virtual const R3::Matrix& siteCartesianUij(int idx) const = 0; - /// this method allows custom special configuration for a concrete - /// pair of StructureAdapter and PairQuantity objects. - virtual void customPQConfig(PairQuantity* pq) const - __attribute__ ((deprecated)) - { } + /// this method allows custom special configuration for a concrete + /// pair of StructureAdapter and PairQuantity objects. + virtual DEPRECATED void customPQConfig(PairQuantity* pq) const {} - /// Return difference from the other StructureAdapter - virtual StructureDifference diff(StructureAdapterConstPtr) const; - - private: - - // serialization - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) { } + /// Return difference from the other StructureAdapter + virtual StructureDifference diff(StructureAdapterConstPtr) const; + private: + // serialization + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) {} }; // Routines ------------------------------------------------------------------ /// Return a singleton instance of an empty StructureAdapter -StructureAdapterPtr emptyStructureAdapter(); +DLL_EXPORT StructureAdapterPtr emptyStructureAdapter(); /// Calculate MSD along specified direction in Cartesian space. double meanSquareDisplacement(const R3::Matrix& Uijcartn, const R3::Vector& s, - bool anisotropy=true); + bool anisotropy = true); /// Maximum diagonal Uii element from all atoms in the structure. double maxUii(StructureAdapterPtr stru); /// Translate an index container to a vector of string symbols template -std::vector -siteIndicesToTypes(const StructureAdapterPtr& stru, const T& indices) -{ - std::vector rv; - rv.reserve(stru->countSites()); - typename T::const_iterator i; - for (i = indices.begin(); i != indices.end(); ++i) - { - const std::string& smbl = stru->siteAtomType(*i); - rv.push_back(smbl); - } - return rv; +std::vector siteIndicesToTypes(const StructureAdapterPtr& stru, + const T& indices) { + std::vector rv; + rv.reserve(stru->countSites()); + typename T::const_iterator i; + for (i = indices.begin(); i != indices.end(); ++i) { + const std::string& smbl = stru->siteAtomType(*i); + rv.push_back(smbl); + } + return rv; } // Conversion helpers -------------------------------------------------------- @@ -142,43 +141,38 @@ siteIndicesToTypes(const StructureAdapterPtr& stru, const T& indices) /// This converter provides by-value support for StructureAdapter instances. -inline -StructureAdapterPtr createStructureAdapter(const StructureAdapter& stru) -{ - return stru.clone(); +inline StructureAdapterPtr createStructureAdapter( + const StructureAdapter& stru) { + return stru.clone(); } /// convertToStructureAdapter is an interface function that should be used /// by the clients that need to convert to StructureAdapterPtr. template -StructureAdapterPtr convertToStructureAdapter(const T& stru) -{ - StructureAdapterPtr rv = createStructureAdapter(stru); - return rv; +StructureAdapterPtr convertToStructureAdapter(const T& stru) { + StructureAdapterPtr rv = createStructureAdapter(stru); + return rv; } - template -StructureAdapterPtr convertToStructureAdapter(const boost::shared_ptr& stru) -{ - StructureAdapterPtr rv = - boost::dynamic_pointer_cast(stru); - assert(rv); - return rv; +StructureAdapterPtr convertToStructureAdapter( + const boost::shared_ptr& stru) { + StructureAdapterPtr rv = + boost::dynamic_pointer_cast(stru); + assert(rv); + return rv; } - -inline -StructureAdapterPtr convertToStructureAdapter(StructureAdapterConstPtr stru) -{ - StructureAdapterPtr rv = - boost::const_pointer_cast(stru); - return rv; +inline StructureAdapterPtr convertToStructureAdapter( + StructureAdapterConstPtr stru) { + StructureAdapterPtr rv = + boost::const_pointer_cast(stru); + return rv; } -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/StructureDifference.cpp b/src/diffpy/srreal/StructureDifference.cpp index 90a57cb6..4f146569 100644 --- a/src/diffpy/srreal/StructureDifference.cpp +++ b/src/diffpy/srreal/StructureDifference.cpp @@ -1,23 +1,23 @@ /***************************************************************************** -* -* libdiffpy Complex Modeling Initiative -* (c) 2013 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. -* -****************************************************************************** -* -* class StructureDifference for storing differences between two -* instances of the StructureAdapter class. -* -* StructureDifference is returned by the StructureAdapter::diff method. -* -*****************************************************************************/ + * + * libdiffpy Complex Modeling Initiative + * (c) 2013 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. + * + ****************************************************************************** + * + * class StructureDifference for storing differences between two + * instances of the StructureAdapter class. + * + * StructureDifference is returned by the StructureAdapter::diff method. + * + *****************************************************************************/ #include #include @@ -31,40 +31,33 @@ namespace srreal { // Constructors -------------------------------------------------------------- -StructureDifference::StructureDifference() : diffmethod(Method::NONE) -{ } - - -StructureDifference::StructureDifference( - StructureAdapterConstPtr oldstru, - StructureAdapterConstPtr newstru) - : - stru0(oldstru), stru1(newstru), diffmethod(Method::NONE) -{ - if (stru0 && stru0 == stru1) - { - diffmethod = Method::SIDEBYSIDE; - return; - } - // assume completely different structures - int v; - SiteIndices::iterator ii; - int n0 = stru0 ? stru0->countSites() : 0; - pop0.resize(n0); - for (ii = pop0.begin(), v = 0; ii != pop0.end();) *(ii++) = v++; - int n1 = stru1 ? stru1->countSites() : 0; - add1.resize(n1); - for (ii = add1.begin(), v = 0; ii != add1.end();) *(ii++) = v++; +StructureDifference::StructureDifference() : diffmethod(Method::NONE) {} + +StructureDifference::StructureDifference(StructureAdapterConstPtr oldstru, + StructureAdapterConstPtr newstru) + : stru0(oldstru), stru1(newstru), diffmethod(Method::NONE) { + if (stru0 && stru0 == stru1) { + diffmethod = Method::SIDEBYSIDE; + return; + } + // assume completely different structures + int v; + SiteIndices::iterator ii; + int n0 = stru0 ? stru0->countSites() : 0; + pop0.resize(n0); + for (ii = pop0.begin(), v = 0; ii != pop0.end();) *(ii++) = v++; + int n1 = stru1 ? stru1->countSites() : 0; + add1.resize(n1); + for (ii = add1.begin(), v = 0; ii != add1.end();) *(ii++) = v++; } // Public Methods ------------------------------------------------------------ -bool StructureDifference::allowsfastupdate() const -{ - int N0 = stru0 ? stru0->countSites() : 0; - double popbound = (1 - sqrt(0.5)) * N0; - return int(pop0.size()) < popbound; +bool StructureDifference::allowsfastupdate() const { + int N0 = stru0 ? stru0->countSites() : 0; + double popbound = (1 - sqrt(0.5)) * N0; + return int(pop0.size()) < popbound; } -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy diff --git a/src/diffpy/srreal/StructureDifference.hpp b/src/diffpy/srreal/StructureDifference.hpp index 4be27e58..980de159 100644 --- a/src/diffpy/srreal/StructureDifference.hpp +++ b/src/diffpy/srreal/StructureDifference.hpp @@ -1,69 +1,68 @@ /***************************************************************************** -* -* libdiffpy Complex Modeling Initiative -* (c) 2013 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. -* -****************************************************************************** -* -* class StructureDifference for storing differences between two -* instances of the StructureAdapter class. -* -* StructureDifference is returned by the StructureAdapter::diff method. -* -*****************************************************************************/ + * + * libdiffpy Complex Modeling Initiative + * (c) 2013 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. + * + ****************************************************************************** + * + * class StructureDifference for storing differences between two + * instances of the StructureAdapter class. + * + * StructureDifference is returned by the StructureAdapter::diff method. + * + *****************************************************************************/ #ifndef STRUCTUREDIFFERENCE_HPP_INCLUDED #define STRUCTUREDIFFERENCE_HPP_INCLUDED #include +#include + namespace diffpy { namespace srreal { -class StructureDifference { - - public: - - // constructors - StructureDifference(); - StructureDifference(StructureAdapterConstPtr, StructureAdapterConstPtr); - - // enumeration type for difference methods - struct Method { - enum Type {NONE, SIDEBYSIDE, SORTED}; - }; +class DLL_EXPORT StructureDifference { + public: + // constructors + StructureDifference(); + StructureDifference(StructureAdapterConstPtr, StructureAdapterConstPtr); - // data + // enumeration type for difference methods + struct Method { + enum Type { NONE, SIDEBYSIDE, SORTED }; + }; - /// pointer to the original StructureAdapter - StructureAdapterConstPtr stru0; - /// pointer to the new StructureAdapter - StructureAdapterConstPtr stru1; - /// indices of atoms in stru0 that are not in stru1. - /// These atoms need to be removed for a fast update of PairQuantity. - SiteIndices pop0; - /// indices of atoms in stru1 that are not in stru0 - /// These atoms need to be added in a fast update of PairQuantity. - SiteIndices add1; - /// type of comparison used in obtaining this difference - Method::Type diffmethod; + // data - // methods + /// pointer to the original StructureAdapter + StructureAdapterConstPtr stru0; + /// pointer to the new StructureAdapter + StructureAdapterConstPtr stru1; + /// indices of atoms in stru0 that are not in stru1. + /// These atoms need to be removed for a fast update of PairQuantity. + SiteIndices pop0; + /// indices of atoms in stru1 that are not in stru0 + /// These atoms need to be added in a fast update of PairQuantity. + SiteIndices add1; + /// type of comparison used in obtaining this difference + Method::Type diffmethod; - /// Return true if PairQuantity can be fast-updated after changing - /// structure from stru0 to stru1. - bool allowsfastupdate() const; + // methods + /// Return true if PairQuantity can be fast-updated after changing + /// structure from stru0 to stru1. + bool allowsfastupdate() const; }; -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy #endif // STRUCTUREDIFFERENCE_HPP_INCLUDED diff --git a/src/diffpy/srreal/ZeroBaseline.cpp b/src/diffpy/srreal/ZeroBaseline.cpp index eede7bd5..f130ac1a 100644 --- a/src/diffpy/srreal/ZeroBaseline.cpp +++ b/src/diffpy/srreal/ZeroBaseline.cpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class ZeroBaseline -- linear PDF baseline -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class ZeroBaseline -- linear PDF baseline + * + *****************************************************************************/ #include #include @@ -26,39 +26,31 @@ namespace srreal { // Constructors -------------------------------------------------------------- -PDFBaselinePtr ZeroBaseline::create() const -{ - PDFBaselinePtr rv(new ZeroBaseline()); - return rv; +PDFBaselinePtr ZeroBaseline::create() const { + PDFBaselinePtr rv(new ZeroBaseline()); + return rv; } - -PDFBaselinePtr ZeroBaseline::clone() const -{ - PDFBaselinePtr rv(new ZeroBaseline(*this)); - return rv; +PDFBaselinePtr ZeroBaseline::clone() const { + PDFBaselinePtr rv(new ZeroBaseline(*this)); + return rv; } // Public Methods ------------------------------------------------------------ -const string& ZeroBaseline::type() const -{ - static string rv = "zero"; - return rv; +const string& ZeroBaseline::type() const { + static string rv = "zero"; + return rv; } - -double ZeroBaseline::operator()(const double& r) const -{ - return 0.0; -} +double ZeroBaseline::operator()(const double& r) const { return 0.0; } // Registration -------------------------------------------------------------- bool reg_ZeroBaseline = ZeroBaseline().registerThisType(); -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/ZeroBaseline.hpp b/src/diffpy/srreal/ZeroBaseline.hpp index 06ba3978..6ec0619d 100644 --- a/src/diffpy/srreal/ZeroBaseline.hpp +++ b/src/diffpy/srreal/ZeroBaseline.hpp @@ -1,60 +1,58 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class ZeroBaseline -- linear PDF baseline -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class ZeroBaseline -- linear PDF baseline + * + *****************************************************************************/ #ifndef ZEROBASELINE_HPP_INCLUDED #define ZEROBASELINE_HPP_INCLUDED #include +#include + namespace diffpy { namespace srreal { /// @class ZeroBaseline /// @brief trivial zero baseline -class ZeroBaseline : public PDFBaseline -{ - public: - - // constructors - PDFBaselinePtr create() const; - PDFBaselinePtr clone() const; - - // methods - const std::string& type() const; - double operator()(const double& r) const; +class DLL_EXPORT ZeroBaseline : public PDFBaseline { + public: + // constructors + PDFBaselinePtr create() const; + PDFBaselinePtr clone() const; - private: + // methods + const std::string& type() const; + double operator()(const double& r) const; - // serialization - friend class boost::serialization::access; + private: + // serialization + friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - using boost::serialization::base_object; - ar & base_object(*this); - } + template + void serialize(Archive& ar, const unsigned int version) { + using boost::serialization::base_object; + ar& base_object(*this); + } }; // class ZeroBaseline -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy // Serialization ------------------------------------------------------------- diff --git a/src/diffpy/srreal/forwardtypes.hpp b/src/diffpy/srreal/forwardtypes.hpp index fe047063..c6629c42 100644 --- a/src/diffpy/srreal/forwardtypes.hpp +++ b/src/diffpy/srreal/forwardtypes.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy Complex Modeling Initiative -* (c) 2013 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. -* -****************************************************************************** -* -* Forward declaration of commonly used pointer types. -* -*****************************************************************************/ + * + * libdiffpy Complex Modeling Initiative + * (c) 2013 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. + * + ****************************************************************************** + * + * Forward declaration of commonly used pointer types. + * + *****************************************************************************/ #ifndef FORWARDTYPES_HPP_INCLUDED #define FORWARDTYPES_HPP_INCLUDED @@ -28,12 +28,13 @@ namespace srreal { /// shared pointers to structure adapter and bond generator related objects typedef boost::shared_ptr BaseBondGeneratorPtr; typedef boost::shared_ptr StructureAdapterPtr; -typedef boost::shared_ptr StructureAdapterConstPtr; +typedef boost::shared_ptr + StructureAdapterConstPtr; /// type for holding indices for atom sites typedef std::vector SiteIndices; -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy #endif // FORWARDTYPES_HPP_INCLUDED diff --git a/src/diffpy/srreal/scatteringfactordata.cpp b/src/diffpy/srreal/scatteringfactordata.cpp index 6439269d..0d0a20a8 100644 --- a/src/diffpy/srreal/scatteringfactordata.cpp +++ b/src/diffpy/srreal/scatteringfactordata.cpp @@ -44,309 +44,261 @@ namespace { const int WKTerms = 5; -class WaasKirfFormula -{ - public: - - // Constructor - WaasKirfFormula() - { - fill(a, a + WKTerms, 0.0); - fill(b, b + WKTerms, 0.0); - c = 0.0; - } - - WaasKirfFormula(const WaasKirfFormula& wk0) - { - symbol = wk0.symbol; - copy(wk0.a, wk0.a + WKTerms, a); - copy(wk0.b, wk0.b + WKTerms, b); - c = wk0.c; - } - - // methods - double xrayatstol(double stol) const - { - double rv = c; - for (int i = 0; i < WKTerms; ++i) - { - rv += a[i] * exp(-b[i] * stol * stol); - } - return rv; - } - - double Z() const - { - double rv = c; - for (int i = 0; i < WKTerms; ++i) rv += a[i]; - return round(rv); - } - - double electronatstol(double stol) const - { - using diffpy::mathutils::eps_eq; - using diffpy::mathutils::DOUBLE_MAX; - if (eps_eq(stol, 0.0)) return DOUBLE_MAX; - double rv = 0.023934 * - (this->Z() - this->xrayatstol(stol)) / (stol * stol); - return rv; - } - - // data - string symbol; - double a[WKTerms]; - double b[WKTerms]; - double c; +class WaasKirfFormula { + public: + // Constructor + WaasKirfFormula() { + fill(a, a + WKTerms, 0.0); + fill(b, b + WKTerms, 0.0); + c = 0.0; + } + + WaasKirfFormula(const WaasKirfFormula& wk0) { + symbol = wk0.symbol; + copy(wk0.a, wk0.a + WKTerms, a); + copy(wk0.b, wk0.b + WKTerms, b); + c = wk0.c; + } + + // methods + double xrayatstol(double stol) const { + double rv = c; + for (int i = 0; i < WKTerms; ++i) { + rv += a[i] * exp(-b[i] * stol * stol); + } + return rv; + } + + double Z() const { + double rv = c; + for (int i = 0; i < WKTerms; ++i) rv += a[i]; + return round(rv); + } + + double electronatstol(double stol) const { + using diffpy::mathutils::DOUBLE_MAX; + using diffpy::mathutils::eps_eq; + if (eps_eq(stol, 0.0)) return DOUBLE_MAX; + double rv = 0.023934 * (this->Z() - this->xrayatstol(stol)) / (stol * stol); + return rv; + } + + // data + string symbol; + double a[WKTerms]; + double b[WKTerms]; + double c; }; - -class wksmbl_equal : - public binary_function -{ - public: - bool operator() ( - const WaasKirfFormula& wk0, const WaasKirfFormula& wk1) const - { - return wk0.symbol == wk1.symbol; - } +class wksmbl_equal + : public binary_function { + public: + bool operator()(const WaasKirfFormula& wk0, + const WaasKirfFormula& wk1) const { + return wk0.symbol == wk1.symbol; + } }; - -class wksmbl_hash -{ - public: - size_t operator()(const WaasKirfFormula& wk) const - { - hash hasher; - return hasher(wk.symbol); - } +class wksmbl_hash { + public: + size_t operator()(const WaasKirfFormula& wk) const { + hash hasher; + return hasher(wk.symbol); + } }; - -typedef unordered_set SetOfWKFormulas; - - -const SetOfWKFormulas& getWKFormulasSet() -{ - using namespace diffpy::runtimepath; - using diffpy::validators::ensureFileOK; - static unique_ptr the_set; - if (the_set) return *the_set; - the_set.reset(new SetOfWKFormulas); - string wkfile = datapath("f0_WaasKirf.dat"); - ifstream fp(wkfile.c_str()); - ensureFileOK(wkfile, fp); - LineReader line; - line.commentmark = '#'; - for (WaasKirfFormula wk; fp >> line;) - { - if (line.iscomment() && (0 == line.words[0].compare(0, 2, "#S"))) - { - if (line.wcount() < 3) - { - throw line.format_error(wkfile, - "Expected at least 3 columns of data."); - } - wk.symbol = line.words[2]; - continue; - } - if (line.iscomment() && (0 == line.words[0].compare(0, 2, "#L"))) - { - if (wk.symbol.empty()) - { - throw line.format_error(wkfile, - "Missing \"#S\" line with atom symbol definition."); - } - fp >> line; - if (line.wcount() != 11) - { - throw line.format_error(wkfile, "Expected 11 values."); - } - istringstream fpline(line.line); - fpline >> - wk.a[0] >> wk.a[1] >> wk.a[2] >> wk.a[3] >> wk.a[4] >> - wk.c >> wk.b[0] >> wk.b[1] >> wk.b[2] >> wk.b[3] >> wk.b[4]; - if (!fpline) - { - throw line.format_error(wkfile, - "Line should contain 11 floating point values."); - } - if (the_set->count(wk)) - { - string emsg = "Duplicate atom symbol \""; - emsg += wk.symbol + "\"."; - throw line.format_error(wkfile, emsg); - } - the_set->insert(wk); - wk.symbol.clear(); - } - } - return getWKFormulasSet(); -} - - -SetOfWKFormulas::const_iterator findWKFormula(const string& smbl) -{ - using diffpy::srreal::atomBareSymbol; - using diffpy::srreal::atomValence; - WaasKirfFormula wk; - wk.symbol = smbl; - const SetOfWKFormulas& swk = getWKFormulasSet(); - SetOfWKFormulas::const_iterator wkit = swk.find(wk); - if (wkit != swk.end()) return wkit; - // try again with an adjusted charge suffix - wk.symbol = atomBareSymbol(smbl); - int v = atomValence(smbl); - if (v == 0) wkit = swk.find(wk); - else if (abs(v) == 1) - { - wk.symbol += ((v > 0) ? "1+" : "1-"); - wkit = swk.find(wk); +typedef unordered_set + SetOfWKFormulas; + +const SetOfWKFormulas& getWKFormulasSet() { + using namespace diffpy::runtimepath; + using diffpy::validators::ensureFileOK; + static unique_ptr the_set; + if (the_set) return *the_set; + the_set.reset(new SetOfWKFormulas); + string wkfile = datapath("f0_WaasKirf.dat"); + ifstream fp(wkfile.c_str()); + ensureFileOK(wkfile, fp); + LineReader line; + line.commentmark = '#'; + for (WaasKirfFormula wk; fp >> line;) { + if (line.iscomment() && (0 == line.words[0].compare(0, 2, "#S"))) { + if (line.wcount() < 3) { + throw line.format_error(wkfile, "Expected at least 3 columns of data."); + } + wk.symbol = line.words[2]; + continue; } - // raise exception if no match - if (wkit == swk.end()) - { - string emsg("Unknown atom or ion symbol '"); - emsg += smbl + "'."; - throw invalid_argument(emsg); + if (line.iscomment() && (0 == line.words[0].compare(0, 2, "#L"))) { + if (wk.symbol.empty()) { + throw line.format_error( + wkfile, "Missing \"#S\" line with atom symbol definition."); + } + fp >> line; + if (line.wcount() != 11) { + throw line.format_error(wkfile, "Expected 11 values."); + } + istringstream fpline(line.line); + fpline >> wk.a[0] >> wk.a[1] >> wk.a[2] >> wk.a[3] >> wk.a[4] >> wk.c >> + wk.b[0] >> wk.b[1] >> wk.b[2] >> wk.b[3] >> wk.b[4]; + if (!fpline) { + throw line.format_error( + wkfile, "Line should contain 11 floating point values."); + } + if (the_set->count(wk)) { + string emsg = "Duplicate atom symbol \""; + emsg += wk.symbol + "\"."; + throw line.format_error(wkfile, emsg); + } + the_set->insert(wk); + wk.symbol.clear(); } - return wkit; + } + return getWKFormulasSet(); } +SetOfWKFormulas::const_iterator findWKFormula(const string& smbl) { + using diffpy::srreal::atomBareSymbol; + using diffpy::srreal::atomValence; + WaasKirfFormula wk; + wk.symbol = smbl; + const SetOfWKFormulas& swk = getWKFormulasSet(); + SetOfWKFormulas::const_iterator wkit = swk.find(wk); + if (wkit != swk.end()) return wkit; + // try again with an adjusted charge suffix + wk.symbol = atomBareSymbol(smbl); + int v = atomValence(smbl); + if (v == 0) + wkit = swk.find(wk); + else if (abs(v) == 1) { + wk.symbol += ((v > 0) ? "1+" : "1-"); + wkit = swk.find(wk); + } + // raise exception if no match + if (wkit == swk.end()) { + string emsg("Unknown atom or ion symbol '"); + emsg += smbl + "'."; + throw invalid_argument(emsg); + } + return wkit; +} // Electron numbers for elements and ions -typedef unordered_map ElectronNumberStorage; - -ElectronNumberStorage& getElectronNumberTable() -{ - using namespace diffpy::runtimepath; - using diffpy::validators::ensureFileOK; - static unique_ptr entable; - typedef ElectronNumberStorage::value_type ENPair; - if (!entable) - { - entable.reset(new ElectronNumberStorage); - string ionfile = datapath("ionlist.dat"); - ifstream fp0(ionfile.c_str()); - ensureFileOK(ionfile, fp0); - LineReader line; - while (fp0 >> line) - { - if (line.isignored()) continue; - istringstream fpline(line.line); - string element; - int z = 0; - fpline >> element >> z; - if (!fpline) - { - throw line.format_error(ionfile, - "Expected at least 2 columns for (symbol, Z)."); - } - entable->insert(ENPair(element, z)); - for (int v; fpline >> v;) - { - ostringstream smbl; - smbl << element << abs(v) << ((v > 0) ? '+' : '-'); - entable->insert(ENPair(smbl.str(), z - v)); - } - } - const size_t mintablesize = 447; - if (entable->size() < mintablesize) - { - ostringstream emsg; - emsg << "Incomplete file. Expected " << mintablesize << - " items loaded " << entable->size() << "."; - throw line.format_error(ionfile, emsg.str()); - } +typedef unordered_map ElectronNumberStorage; + +ElectronNumberStorage& getElectronNumberTable() { + using namespace diffpy::runtimepath; + using diffpy::validators::ensureFileOK; + static unique_ptr entable; + typedef ElectronNumberStorage::value_type ENPair; + if (!entable) { + entable.reset(new ElectronNumberStorage); + string ionfile = datapath("ionlist.dat"); + ifstream fp0(ionfile.c_str()); + ensureFileOK(ionfile, fp0); + LineReader line; + while (fp0 >> line) { + if (line.isignored()) continue; + istringstream fpline(line.line); + string element; + int z = 0; + fpline >> element >> z; + if (!fpline) { + throw line.format_error(ionfile, + "Expected at least 2 columns for (symbol, Z)."); + } + entable->insert(ENPair(element, z)); + for (int v; fpline >> v;) { + ostringstream smbl; + smbl << element << abs(v) << ((v > 0) ? '+' : '-'); + entable->insert(ENPair(smbl.str(), z - v)); + } + } + const size_t mintablesize = 447; + if (entable->size() < mintablesize) { + ostringstream emsg; + emsg << "Incomplete file. Expected " << mintablesize << " items loaded " + << entable->size() << "."; + throw line.format_error(ionfile, emsg.str()); } - return *entable; + } + return *entable; } // Neutron scattering lengths -typedef unordered_map NeutronBCStorage; - -const NeutronBCStorage& getNeutronBCTable() -{ - using namespace diffpy::runtimepath; - using diffpy::validators::ensureFileOK; - typedef NeutronBCStorage::value_type BCPair; - static unique_ptr bctable; - if (bctable) return *bctable; - bctable.reset(new NeutronBCStorage); - string nsffile = datapath("nsftable.dat"); - ifstream fp(nsffile.c_str()); - ensureFileOK(nsffile, fp); - LineReader line; - line.commentmark = '#'; - line.separator = ','; - while (fp >> line) - { - if (line.isignored()) continue; - if (line.wcount() != 11) - { - throw line.format_error(nsffile, - "Expected 11 comma-separated items."); - } - if (line.words[3].empty()) continue; - string smbl = line.words[0]; - size_t p0 = smbl.find_first_not_of("0123456789-"); - if (p0 == string::npos) - { - throw line.format_error(nsffile, "Missing or invalid atom symbol."); - } - smbl.erase(0, p0); - size_t p1 = smbl.find_last_of('-'); - if (p1 != string::npos) - { - smbl = smbl.substr(p1 + 1) + "-" + smbl.substr(0, p1); - } - istringstream fpbc(line.words[3]); - double bc; - fpbc >> bc; - if (!fpbc) - { - throw line.format_error(nsffile, "Invalid b_c value."); - } - if (bctable->count(smbl)) - { - string emsg = "Duplicate atom symbol \""; - emsg += smbl + "\"."; - throw line.format_error(nsffile, emsg); - } - bctable->insert(BCPair(smbl, bc)); - // elements are not explicitly included if there is just one isotope - // or if all isotopes are unstable - size_t p2 = smbl.find_first_of('-'); - if (p2 != string::npos) - { - string el = smbl.substr(p2 + 1); - // there is just one isotope - const string& chlf = line.words[1]; - bool addel = (chlf == "100") || - (!bctable->count(el) && *chlf.rbegin() == 'Y'); - if (addel) - { - if (bctable->count(el)) - { - string emsg = "Duplicate element entry for \""; - emsg += el + "\"."; - throw line.format_error(nsffile, emsg);; - } - bctable->insert(BCPair(el, bc)); - } +typedef unordered_map NeutronBCStorage; + +const NeutronBCStorage& getNeutronBCTable() { + using namespace diffpy::runtimepath; + using diffpy::validators::ensureFileOK; + typedef NeutronBCStorage::value_type BCPair; + static unique_ptr bctable; + if (bctable) return *bctable; + bctable.reset(new NeutronBCStorage); + string nsffile = datapath("nsftable.dat"); + ifstream fp(nsffile.c_str()); + ensureFileOK(nsffile, fp); + LineReader line; + line.commentmark = '#'; + line.separator = ','; + while (fp >> line) { + if (line.isignored()) continue; + if (line.wcount() != 11) { + throw line.format_error(nsffile, "Expected 11 comma-separated items."); + } + if (line.words[3].empty()) continue; + string smbl = line.words[0]; + size_t p0 = smbl.find_first_not_of("0123456789-"); + if (p0 == string::npos) { + throw line.format_error(nsffile, "Missing or invalid atom symbol."); + } + smbl.erase(0, p0); + size_t p1 = smbl.find_last_of('-'); + if (p1 != string::npos) { + smbl = smbl.substr(p1 + 1) + "-" + smbl.substr(0, p1); + } + istringstream fpbc(line.words[3]); + double bc; + fpbc >> bc; + if (!fpbc) { + throw line.format_error(nsffile, "Invalid b_c value."); + } + if (bctable->count(smbl)) { + string emsg = "Duplicate atom symbol \""; + emsg += smbl + "\"."; + throw line.format_error(nsffile, emsg); + } + bctable->insert(BCPair(smbl, bc)); + // elements are not explicitly included if there is just one isotope + // or if all isotopes are unstable + size_t p2 = smbl.find_first_of('-'); + if (p2 != string::npos) { + string el = smbl.substr(p2 + 1); + // there is just one isotope + const string& chlf = line.words[1]; + bool addel = + (chlf == "100") || (!bctable->count(el) && *chlf.rbegin() == 'Y'); + if (addel) { + if (bctable->count(el)) { + string emsg = "Duplicate element entry for \""; + emsg += el + "\"."; + throw line.format_error(nsffile, emsg); + ; } + bctable->insert(BCPair(el, bc)); + } } - // define aliases for neutron, deuterium and tritium - bctable->insert(BCPair("n", bctable->at("1-n"))); - bctable->insert(BCPair("D", bctable->at("2-H"))); - bctable->insert(BCPair("T", bctable->at("3-H"))); - return getNeutronBCTable(); + } + // define aliases for neutron, deuterium and tritium + bctable->insert(BCPair("n", bctable->at("1-n"))); + bctable->insert(BCPair("D", bctable->at("2-H"))); + bctable->insert(BCPair("T", bctable->at("3-H"))); + return getNeutronBCTable(); } -} // namespace +} // namespace // Implementation ------------------------------------------------------------ @@ -354,74 +306,61 @@ namespace diffpy { namespace srreal { /// X-ray scattering factor of an element or ion a given Q -double fxrayatq(const string& smbl, double q) -{ - const double stol = q / (4 * M_PI); - return fxrayatstol(smbl, stol); +double fxrayatq(const string& smbl, double q) { + const double stol = q / (4 * M_PI); + return fxrayatstol(smbl, stol); } - /// X-ray scattering factor of an element or ion a given sin(theta)/lambda -double fxrayatstol(const string& smbl, double stol) -{ - SetOfWKFormulas::const_iterator wkit = findWKFormula(smbl); - return wkit->xrayatstol(stol); +double fxrayatstol(const string& smbl, double stol) { + SetOfWKFormulas::const_iterator wkit = findWKFormula(smbl); + return wkit->xrayatstol(stol); } - /// Electron scattering factor of an element or ion a given Q -double felectronatq(const string& smbl, double q) -{ - const double stol = q / (4 * M_PI); - SetOfWKFormulas::const_iterator wkit = findWKFormula(smbl); - return wkit->electronatstol(stol); +double felectronatq(const string& smbl, double q) { + const double stol = q / (4 * M_PI); + SetOfWKFormulas::const_iterator wkit = findWKFormula(smbl); + return wkit->electronatstol(stol); } - /// Number of electrons for an element or ion -int electronnumber(const string& smbl) -{ - const ElectronNumberStorage& entable = getElectronNumberTable(); - ElectronNumberStorage::const_iterator it; - it = entable.find(smbl); - // try to build standard symbol when not found - if (it == entable.end()) - { - ostringstream smbl1; - smbl1 << atomBareSymbol(smbl); - int v = atomValence(smbl); - if (v) smbl1 << abs(v) << ((v > 0) ? '+' : '-'); - it = entable.find(smbl1.str()); - } - // throw exception if still not found - if (it == entable.end()) - { - ostringstream emsg; - emsg << "Unknown atom symbol '" << smbl << "'."; - throw invalid_argument(emsg.str()); - } - return it->second; +int electronnumber(const string& smbl) { + const ElectronNumberStorage& entable = getElectronNumberTable(); + ElectronNumberStorage::const_iterator it; + it = entable.find(smbl); + // try to build standard symbol when not found + if (it == entable.end()) { + ostringstream smbl1; + smbl1 << atomBareSymbol(smbl); + int v = atomValence(smbl); + if (v) smbl1 << abs(v) << ((v > 0) ? '+' : '-'); + it = entable.find(smbl1.str()); + } + // throw exception if still not found + if (it == entable.end()) { + ostringstream emsg; + emsg << "Unknown atom symbol '" << smbl << "'."; + throw invalid_argument(emsg.str()); + } + return it->second; } - /// Coherent scattering length of an element or isotope in fm -double bcneutron(const string& smbl) -{ - const NeutronBCStorage& bctable = getNeutronBCTable(); - NeutronBCStorage::const_iterator it = bctable.find(smbl); - if (it != bctable.end()) return it->second; - size_t pe = smbl.find_last_not_of("+-012345678 \t"); - string smblnocharge = - (pe != string::npos) ? smbl.substr(0, pe + 1) : smbl; - it = bctable.find(smblnocharge); - if (it == bctable.end()) - { - string emsg("Unknown atom or isotope symbol '"); - emsg += smbl + "'."; - throw invalid_argument(emsg); - } - return it->second; +double bcneutron(const string& smbl) { + const NeutronBCStorage& bctable = getNeutronBCTable(); + NeutronBCStorage::const_iterator it = bctable.find(smbl); + if (it != bctable.end()) return it->second; + size_t pe = smbl.find_last_not_of("+-012345678 \t"); + string smblnocharge = (pe != string::npos) ? smbl.substr(0, pe + 1) : smbl; + it = bctable.find(smblnocharge); + if (it == bctable.end()) { + string emsg("Unknown atom or isotope symbol '"); + emsg += smbl + "'."; + throw invalid_argument(emsg); + } + return it->second; } -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy diff --git a/src/diffpy/srreal/scatteringfactordata.hpp b/src/diffpy/srreal/scatteringfactordata.hpp index 1844002f..69270ab2 100644 --- a/src/diffpy/srreal/scatteringfactordata.hpp +++ b/src/diffpy/srreal/scatteringfactordata.hpp @@ -45,7 +45,7 @@ int electronnumber(const std::string& smbl); /// Coherent scattering length of an element or isotope in fm double bcneutron(const std::string& smbl); -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy #endif // SCATTERINGFACTORS_HPP_INCLUDED diff --git a/src/diffpy/validators.hpp b/src/diffpy/validators.hpp index 6c6907d0..200040e8 100644 --- a/src/diffpy/validators.hpp +++ b/src/diffpy/validators.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy 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 functions for argument checking. -* -*****************************************************************************/ + * + * libdiffpy 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 functions for argument checking. + * + *****************************************************************************/ #ifndef VALIDATORS_HPP_INCLUDED #define VALIDATORS_HPP_INCLUDED @@ -30,58 +30,50 @@ namespace validators { /// Throw invalid_argument for a negative value template -void ensureNonNegative(const std::string& vname, const T& value) -{ - if (value < 0) - { - std::string emsg(vname); - emsg += " cannot be negative."; - throw std::invalid_argument(emsg); - } +void ensureNonNegative(const std::string& vname, const T& value) { + if (value < 0) { + std::string emsg(vname); + emsg += " cannot be negative."; + throw std::invalid_argument(emsg); + } } /// Throw invalid_argument for a value that is not greater than DOUBLE_EPS template -void ensureEpsilonPositive(const std::string& vname, const T& value) -{ - using diffpy::mathutils::eps_gt; - if (!eps_gt(double(value), 0.0)) - { - std::string emsg(vname); - emsg += " must be epsilon positive."; - throw std::invalid_argument(emsg); - } +void ensureEpsilonPositive(const std::string& vname, const T& value) { + using diffpy::mathutils::eps_gt; + if (!eps_gt(double(value), 0.0)) { + std::string emsg(vname); + emsg += " must be epsilon positive."; + throw std::invalid_argument(emsg); + } } /// Throw invalid_argument if the argument is not true. For boost smart /// pointers this is equivalent to a truth check of p.get(). template -void ensureNonNull(const std::string& vname, const T& p) -{ - if (!p) - { - std::string emsg(vname); - emsg += " cannot be NULL."; - throw std::invalid_argument(emsg); - } +void ensureNonNull(const std::string& vname, const T& p) { + if (!p) { + std::string emsg(vname); + emsg += " cannot be NULL."; + throw std::invalid_argument(emsg); + } } /// Throw runtime_error if a file argument is not true. template -void ensureFileOK(const std::string& fname, const T& fp) -{ - if (!fp) - { - std::string emsg = "Cannot open '"; - emsg += fname + "'."; - throw std::runtime_error(emsg); - } +void ensureFileOK(const std::string& fname, const T& fp) { + if (!fp) { + std::string emsg = "Cannot open '"; + emsg += fname + "'."; + throw std::runtime_error(emsg); + } } -} // namespace validators -} // namespace diffpy +} // namespace validators +} // namespace diffpy #endif // VALIDATORS_HPP_INCLUDED diff --git a/src/diffpy/version.cpp b/src/diffpy/version.cpp index 803f0a6b..685f298d 100644 --- a/src/diffpy/version.cpp +++ b/src/diffpy/version.cpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy Complex Modeling Initiative -* (c) 2014 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. -* -****************************************************************************** -* -* Definitions for the libdiffpy_version_info constants. -* -*****************************************************************************/ + * + * libdiffpy Complex Modeling Initiative + * (c) 2014 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. + * + ****************************************************************************** + * + * Definitions for the libdiffpy_version_info constants. + * + *****************************************************************************/ #include diff --git a/src/diffpy/version.tpl b/src/diffpy/version.tpl index 548fb3ab..6edf3327 100644 --- a/src/diffpy/version.tpl +++ b/src/diffpy/version.tpl @@ -64,7 +64,9 @@ // libdiffpy_version_info will hold runtime version data, which may be // different from client compile-time values. -struct libdiffpy_version_info { +#include + +struct DLL_EXPORT libdiffpy_version_info { static const long long version; static const char* version_str; diff --git a/src/tests/TestAtomRadiiTable.hpp b/src/tests/TestAtomRadiiTable.hpp index 392f8fd2..5033f662 100644 --- a/src/tests/TestAtomRadiiTable.hpp +++ b/src/tests/TestAtomRadiiTable.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2011 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. -* -****************************************************************************** -* -* class TestAtomRadiiTable -- unit tests for the AtomRadiiTable class -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2011 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. + * + ****************************************************************************** + * + * class TestAtomRadiiTable -- unit tests for the AtomRadiiTable class + * + *****************************************************************************/ #include #include @@ -26,112 +26,82 @@ using namespace std; using namespace diffpy::srreal; - -class TestAtomRadiiTable : public CxxTest::TestSuite -{ - - private: - - AtomRadiiTablePtr mrtb; - - public: - - void setUp() - { - mrtb = AtomRadiiTable::createByType("constant"); - } - - - void test_lookup() - { - TS_ASSERT_EQUALS(0.0, mrtb->lookup("everything")); - } - - - void test_setCustom() - { - mrtb->setCustom("C", 1.23); - TS_ASSERT_EQUALS(1.23, mrtb->lookup("C")); - mrtb->setCustom("C", 1.5); - TS_ASSERT_EQUALS(1.5, mrtb->lookup("C")); - mrtb->resetAll(); - TS_ASSERT_EQUALS(0.0, mrtb->lookup("C")); - } - - - void test_fromString() - { - TS_ASSERT_EQUALS(0u, mrtb->getAllCustom().size()); - mrtb->fromString("A:1.1, B:1.2, C: 1.3 \t"); - TS_ASSERT_EQUALS(3u, mrtb->getAllCustom().size()); - TS_ASSERT_EQUALS(1.1, mrtb->lookup("A")); - TS_ASSERT_EQUALS(1.2, mrtb->lookup("B")); - TS_ASSERT_EQUALS(1.3, mrtb->lookup("C")); - TS_ASSERT_THROWS(mrtb->fromString("X12"), invalid_argument); - TS_ASSERT_EQUALS(3u, mrtb->getAllCustom().size()); - mrtb->fromString("D:4.3"); - TS_ASSERT_EQUALS(4.3, mrtb->lookup("D")); - TS_ASSERT_EQUALS(4u, mrtb->getAllCustom().size()); - } - - - void test_resetCustom() - { - mrtb->fromString("A:1.1, B:1.2, C: 1.3"); - TS_ASSERT_EQUALS(3u, mrtb->getAllCustom().size()); - mrtb->resetCustom("B"); - TS_ASSERT_EQUALS(1.1, mrtb->lookup("A")); - TS_ASSERT_EQUALS(1.3, mrtb->lookup("C")); - } - - - void test_resetAll() - { - mrtb->fromString("A:1.1, B:1.2, C: 1.3"); - TS_ASSERT_EQUALS(3u, mrtb->getAllCustom().size()); - mrtb->resetAll(); - TS_ASSERT(mrtb->getAllCustom().empty()); - } - - - void test_toString() - { - TS_ASSERT(mrtb->toString().empty()); - mrtb->fromString("A:1.1, C: 1.3, B:1.2"); - TS_ASSERT_EQUALS(string("A:1.1,B:1.2,C:1.3"), mrtb->toString()); - TS_ASSERT_EQUALS(string("A:1.1, B:1.2, C:1.3"), mrtb->toString(", ")); - mrtb->resetAll(); - TS_ASSERT(mrtb->toString().empty()); - } - - - void test_setDefault() - { - ConstantRadiiTable* crtb = - dynamic_cast(mrtb.get()); - crtb->setDefault(7.1); - TS_ASSERT_EQUALS(7.1, mrtb->lookup("everything")); - crtb->setDefault(3.1); - TS_ASSERT_EQUALS(3.1, mrtb->lookup("Na")); - } - - - void test_serialization() - { - AtomRadiiTablePtr rtb1; - mrtb->setCustom("H", 1.23); - ConstantRadiiTable* crtb = - dynamic_cast(mrtb.get()); - crtb->setDefault(0.5); - rtb1 = dumpandload(mrtb); - TS_ASSERT_EQUALS(1.23, rtb1->lookup("H")); - TS_ASSERT_EQUALS(1u, rtb1->getAllCustom().size()); - TS_ASSERT_DIFFERS(mrtb.get(), rtb1.get()); - ConstantRadiiTable* crtb1 = - dynamic_cast(rtb1.get()); - TS_ASSERT_EQUALS(0.5, crtb1->getDefault()); - } - +class TestAtomRadiiTable : public CxxTest::TestSuite { + private: + AtomRadiiTablePtr mrtb; + + public: + void setUp() { mrtb = AtomRadiiTable::createByType("constant"); } + + void test_lookup() { TS_ASSERT_EQUALS(0.0, mrtb->lookup("everything")); } + + void test_setCustom() { + mrtb->setCustom("C", 1.23); + TS_ASSERT_EQUALS(1.23, mrtb->lookup("C")); + mrtb->setCustom("C", 1.5); + TS_ASSERT_EQUALS(1.5, mrtb->lookup("C")); + mrtb->resetAll(); + TS_ASSERT_EQUALS(0.0, mrtb->lookup("C")); + } + + void test_fromString() { + TS_ASSERT_EQUALS(0u, mrtb->getAllCustom().size()); + mrtb->fromString("A:1.1, B:1.2, C: 1.3 \t"); + TS_ASSERT_EQUALS(3u, mrtb->getAllCustom().size()); + TS_ASSERT_EQUALS(1.1, mrtb->lookup("A")); + TS_ASSERT_EQUALS(1.2, mrtb->lookup("B")); + TS_ASSERT_EQUALS(1.3, mrtb->lookup("C")); + TS_ASSERT_THROWS(mrtb->fromString("X12"), invalid_argument); + TS_ASSERT_EQUALS(3u, mrtb->getAllCustom().size()); + mrtb->fromString("D:4.3"); + TS_ASSERT_EQUALS(4.3, mrtb->lookup("D")); + TS_ASSERT_EQUALS(4u, mrtb->getAllCustom().size()); + } + + void test_resetCustom() { + mrtb->fromString("A:1.1, B:1.2, C: 1.3"); + TS_ASSERT_EQUALS(3u, mrtb->getAllCustom().size()); + mrtb->resetCustom("B"); + TS_ASSERT_EQUALS(1.1, mrtb->lookup("A")); + TS_ASSERT_EQUALS(1.3, mrtb->lookup("C")); + } + + void test_resetAll() { + mrtb->fromString("A:1.1, B:1.2, C: 1.3"); + TS_ASSERT_EQUALS(3u, mrtb->getAllCustom().size()); + mrtb->resetAll(); + TS_ASSERT(mrtb->getAllCustom().empty()); + } + + void test_toString() { + TS_ASSERT(mrtb->toString().empty()); + mrtb->fromString("A:1.1, C: 1.3, B:1.2"); + TS_ASSERT_EQUALS(string("A:1.1,B:1.2,C:1.3"), mrtb->toString()); + TS_ASSERT_EQUALS(string("A:1.1, B:1.2, C:1.3"), mrtb->toString(", ")); + mrtb->resetAll(); + TS_ASSERT(mrtb->toString().empty()); + } + + void test_setDefault() { + ConstantRadiiTable* crtb = dynamic_cast(mrtb.get()); + crtb->setDefault(7.1); + TS_ASSERT_EQUALS(7.1, mrtb->lookup("everything")); + crtb->setDefault(3.1); + TS_ASSERT_EQUALS(3.1, mrtb->lookup("Na")); + } + + void test_serialization() { + AtomRadiiTablePtr rtb1; + mrtb->setCustom("H", 1.23); + ConstantRadiiTable* crtb = dynamic_cast(mrtb.get()); + crtb->setDefault(0.5); + rtb1 = dumpandload(mrtb); + TS_ASSERT_EQUALS(1.23, rtb1->lookup("H")); + TS_ASSERT_EQUALS(1u, rtb1->getAllCustom().size()); + TS_ASSERT_DIFFERS(mrtb.get(), rtb1.get()); + ConstantRadiiTable* crtb1 = dynamic_cast(rtb1.get()); + TS_ASSERT_EQUALS(0.5, crtb1->getDefault()); + } }; // End of file diff --git a/src/tests/TestAtomicStructureAdapter.hpp b/src/tests/TestAtomicStructureAdapter.hpp index c530d6b6..a07c1aa4 100644 --- a/src/tests/TestAtomicStructureAdapter.hpp +++ b/src/tests/TestAtomicStructureAdapter.hpp @@ -1,21 +1,21 @@ /***************************************************************************** -* -* libdiffpy Complex Modeling Initiative -* (c) 2013 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. -* -****************************************************************************** -* -* class TestAtomicStructureAdapter -- unit tests for an adapter that -* stores data in a series of Atom objects -* -*****************************************************************************/ + * + * libdiffpy Complex Modeling Initiative + * (c) 2013 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. + * + ****************************************************************************** + * + * class TestAtomicStructureAdapter -- unit tests for an adapter that + * stores data in a series of Atom objects + * + *****************************************************************************/ #include @@ -34,124 +34,110 @@ using namespace std; // class TestAtomicStructureAdapter ////////////////////////////////////////////////////////////////////////////// -class TestAtomicStructureAdapter : public CxxTest::TestSuite -{ - private: - - StructureAdapterPtr mstru; - AtomicStructureAdapterPtr mpstru; - - public: - - void setUp() - { - mstru = StructureAdapterPtr(new AtomicStructureAdapter); - mpstru = - boost::dynamic_pointer_cast(mstru); - } - - - void test_diff() - { - typedef StructureDifference::Method DM; - const DM::Type& NONE = DM::NONE; - const DM::Type& SIDEBYSIDE = DM::SIDEBYSIDE; - const DM::Type& SORTED = DM::SORTED; - StructureDifference sd; - sd = mstru->diff(emptyStructureAdapter()); - TS_ASSERT(sd.add1.empty()); - TS_ASSERT(!sd.allowsfastupdate()); - sd = mstru->diff(StructureAdapterPtr()); - TS_ASSERT_EQUALS(NONE, sd.diffmethod); - TS_ASSERT(!sd.allowsfastupdate()); - Atom ai; - ai.atomtype = "C"; - const int SZ = 10; - for (int i = 0; i < SZ; ++i) - { - ai.xyz_cartn[0] = i; - mpstru->append(ai); - } - AtomicStructureAdapterPtr cpstru = - boost::make_shared(*mpstru); - sd = mstru->diff(mstru); - TS_ASSERT(sd.allowsfastupdate()) - sd = mstru->diff(cpstru); - TS_ASSERT_EQUALS(SIDEBYSIDE, sd.diffmethod); - TS_ASSERT(sd.allowsfastupdate()) - TS_ASSERT(sd.pop0.empty()); - TS_ASSERT(sd.add1.empty()); - (*cpstru)[0].atomtype = "N"; - sd = mstru->diff(cpstru); - TS_ASSERT_EQUALS(SIDEBYSIDE, sd.diffmethod); - TS_ASSERT(sd.allowsfastupdate()) - TS_ASSERT_EQUALS(1u, sd.pop0.size()); - TS_ASSERT_EQUALS(1u, sd.add1.size()); - for (int i = 1; i < (1 - sqrt(0.5)) * SZ; ++i) - { - cpstru->erase(0); - sd = mstru->diff(cpstru); - TS_ASSERT_EQUALS(SORTED, sd.diffmethod); - TS_ASSERT(sd.allowsfastupdate()); - TS_ASSERT_EQUALS(i, int(sd.pop0.size())); - TS_ASSERT(sd.add1.empty()); - } - cpstru->erase(0); - sd = mstru->diff(cpstru); - TS_ASSERT(!sd.allowsfastupdate()); - Atom a2; - a2.atomtype = "N"; - cpstru->append(a2); - sd = mstru->diff(cpstru); - TS_ASSERT(!sd.allowsfastupdate()); - TS_ASSERT_EQUALS(1u, sd.add1.size()); - } - - - void test_serialization() - { - Atom ai; - ai.atomtype = "C"; - ai.xyz_cartn = R3::Vector(1, 2, 3); - ai.anisotropy = true; - mpstru->append(ai); - ai.atomtype = "H"; - ai.xyz_cartn = R3::Vector(4, 5, 6); - ai.anisotropy = false; - mpstru->append(ai); - StructureAdapterPtr stru1; - stru1 = dumpandload(mstru); - AtomicStructureAdapterPtr astru1 = - boost::dynamic_pointer_cast(stru1); - TS_ASSERT_EQUALS(2, astru1->countSites()); - TS_ASSERT_EQUALS((*mpstru)[0], (*astru1)[0]); - TS_ASSERT_EQUALS((*mpstru)[1], (*astru1)[1]); - } - - - void test_comparison() - { - Atom ai; - ai.atomtype = "C"; - const int SZ = 10; - for (int i = 0; i < SZ; ++i) - { - ai.xyz_cartn[0] = i; - mpstru->append(ai); - } - AtomicStructureAdapterPtr cpstru = - boost::make_shared(*mpstru); - TS_ASSERT_EQUALS(*mpstru, *cpstru); - TS_ASSERT(!(*mpstru != *cpstru)); - cpstru->at(0).atomtype = "H"; - TS_ASSERT_DIFFERS(*mpstru, *cpstru); - TS_ASSERT(!(*mpstru == *cpstru)); - } +class TestAtomicStructureAdapter : public CxxTest::TestSuite { + private: + StructureAdapterPtr mstru; + AtomicStructureAdapterPtr mpstru; + + public: + void setUp() { + mstru = StructureAdapterPtr(new AtomicStructureAdapter); + mpstru = boost::dynamic_pointer_cast(mstru); + } + + void test_diff() { + typedef StructureDifference::Method DM; + const DM::Type& NONE = DM::NONE; + const DM::Type& SIDEBYSIDE = DM::SIDEBYSIDE; + const DM::Type& SORTED = DM::SORTED; + StructureDifference sd; + sd = mstru->diff(emptyStructureAdapter()); + TS_ASSERT(sd.add1.empty()); + TS_ASSERT(!sd.allowsfastupdate()); + sd = mstru->diff(StructureAdapterPtr()); + TS_ASSERT_EQUALS(NONE, sd.diffmethod); + TS_ASSERT(!sd.allowsfastupdate()); + Atom ai; + ai.atomtype = "C"; + const int SZ = 10; + for (int i = 0; i < SZ; ++i) { + ai.xyz_cartn[0] = i; + mpstru->append(ai); + } + AtomicStructureAdapterPtr cpstru = + boost::make_shared(*mpstru); + sd = mstru->diff(mstru); + TS_ASSERT(sd.allowsfastupdate()) + sd = mstru->diff(cpstru); + TS_ASSERT_EQUALS(SIDEBYSIDE, sd.diffmethod); + TS_ASSERT(sd.allowsfastupdate()) + TS_ASSERT(sd.pop0.empty()); + TS_ASSERT(sd.add1.empty()); + (*cpstru)[0].atomtype = "N"; + sd = mstru->diff(cpstru); + TS_ASSERT_EQUALS(SIDEBYSIDE, sd.diffmethod); + TS_ASSERT(sd.allowsfastupdate()) + TS_ASSERT_EQUALS(1u, sd.pop0.size()); + TS_ASSERT_EQUALS(1u, sd.add1.size()); + for (int i = 1; i < (1 - sqrt(0.5)) * SZ; ++i) { + cpstru->erase(0); + sd = mstru->diff(cpstru); + TS_ASSERT_EQUALS(SORTED, sd.diffmethod); + TS_ASSERT(sd.allowsfastupdate()); + TS_ASSERT_EQUALS(i, int(sd.pop0.size())); + TS_ASSERT(sd.add1.empty()); + } + cpstru->erase(0); + sd = mstru->diff(cpstru); + TS_ASSERT(!sd.allowsfastupdate()); + Atom a2; + a2.atomtype = "N"; + cpstru->append(a2); + sd = mstru->diff(cpstru); + TS_ASSERT(!sd.allowsfastupdate()); + TS_ASSERT_EQUALS(1u, sd.add1.size()); + } + + void test_serialization() { + Atom ai; + ai.atomtype = "C"; + ai.xyz_cartn = R3::Vector(1, 2, 3); + ai.anisotropy = true; + mpstru->append(ai); + ai.atomtype = "H"; + ai.xyz_cartn = R3::Vector(4, 5, 6); + ai.anisotropy = false; + mpstru->append(ai); + StructureAdapterPtr stru1; + stru1 = dumpandload(mstru); + AtomicStructureAdapterPtr astru1 = + boost::dynamic_pointer_cast(stru1); + TS_ASSERT_EQUALS(2, astru1->countSites()); + TS_ASSERT_EQUALS((*mpstru)[0], (*astru1)[0]); + TS_ASSERT_EQUALS((*mpstru)[1], (*astru1)[1]); + } + + void test_comparison() { + Atom ai; + ai.atomtype = "C"; + const int SZ = 10; + for (int i = 0; i < SZ; ++i) { + ai.xyz_cartn[0] = i; + mpstru->append(ai); + } + AtomicStructureAdapterPtr cpstru = + boost::make_shared(*mpstru); + TS_ASSERT_EQUALS(*mpstru, *cpstru); + TS_ASSERT(!(*mpstru != *cpstru)); + cpstru->at(0).atomtype = "H"; + TS_ASSERT_DIFFERS(*mpstru, *cpstru); + TS_ASSERT(!(*mpstru == *cpstru)); + } }; // class TestAtomicStructureAdapter -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy using diffpy::srreal::TestAtomicStructureAdapter; diff --git a/src/tests/TestAttributes.hpp b/src/tests/TestAttributes.hpp index 992dc4c4..29fe2272 100644 --- a/src/tests/TestAttributes.hpp +++ b/src/tests/TestAttributes.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy Complex Modeling Initiative -* (c) 2019 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. -* -****************************************************************************** -* -* class TestAttributes -- test the helper Attributes class -* -*****************************************************************************/ + * + * libdiffpy Complex Modeling Initiative + * (c) 2019 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. + * + ****************************************************************************** + * + * class TestAttributes -- test the helper Attributes class + * + *****************************************************************************/ #include @@ -24,65 +24,48 @@ namespace { -class Example : public diffpy::Attributes -{ - public: +class Example : public diffpy::Attributes { + public: + Example() : ma(0.0) { + this->registerDoubleAttribute("a", this, &Example::geta, &Example::seta); + this->registerDoubleAttribute("b", this, &Example::geta); + } - Example() : ma(0.0) - { - this->registerDoubleAttribute("a", this, - &Example::geta, &Example::seta); - this->registerDoubleAttribute("b", this, - &Example::geta); - } - - double geta() const { return ma; } - void seta(double a) { ma = a; } - - private: - - double ma; + double geta() const { return ma; } + void seta(double a) { ma = a; } + private: + double ma; }; -} // namespace +} // namespace // --------------------------------------------------------------------------- -class TestAttributes : public CxxTest::TestSuite -{ - private: - - // data - std::unique_ptr mobj; - - public: - - void setUp() - { - mobj.reset(new Example); - } - - - void test_names() - { - TS_ASSERT_EQUALS(2, mobj->namesOfDoubleAttributes().size()); - TS_ASSERT_EQUALS(1, mobj->namesOfWritableDoubleAttributes().size()); - } - - - void test_getsetdoubleattr() - { - using diffpy::attributes::DoubleAttributeError; - TS_ASSERT_EQUALS(0.0, mobj->getDoubleAttr("a")); - mobj->setDoubleAttr("a", 1.3); - TS_ASSERT_EQUALS(1.3, mobj->getDoubleAttr("a")); - TS_ASSERT_THROWS(mobj->setDoubleAttr("b", 3), DoubleAttributeError); - TS_ASSERT_EQUALS(1.3, mobj->getDoubleAttr("b")); - const Example ex1; - TS_ASSERT_EQUALS(0.0, ex1.getDoubleAttr("a")); - TS_ASSERT_THROWS(ex1.getDoubleAttr("bad"), DoubleAttributeError); - } +class TestAttributes : public CxxTest::TestSuite { + private: + // data + std::unique_ptr mobj; + + public: + void setUp() { mobj.reset(new Example); } + + void test_names() { + TS_ASSERT_EQUALS(2, mobj->namesOfDoubleAttributes().size()); + TS_ASSERT_EQUALS(1, mobj->namesOfWritableDoubleAttributes().size()); + } + + void test_getsetdoubleattr() { + using diffpy::attributes::DoubleAttributeError; + TS_ASSERT_EQUALS(0.0, mobj->getDoubleAttr("a")); + mobj->setDoubleAttr("a", 1.3); + TS_ASSERT_EQUALS(1.3, mobj->getDoubleAttr("a")); + TS_ASSERT_THROWS(mobj->setDoubleAttr("b", 3), DoubleAttributeError); + TS_ASSERT_EQUALS(1.3, mobj->getDoubleAttr("b")); + const Example ex1; + TS_ASSERT_EQUALS(0.0, ex1.getDoubleAttr("a")); + TS_ASSERT_THROWS(ex1.getDoubleAttr("bad"), DoubleAttributeError); + } }; // class TestAttributes diff --git a/src/tests/TestBVParametersTable.hpp b/src/tests/TestBVParametersTable.hpp index 41a985e8..f0d832e4 100644 --- a/src/tests/TestBVParametersTable.hpp +++ b/src/tests/TestBVParametersTable.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class TestBVParametersTable -- unit tests for BVParametersTable class -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class TestBVParametersTable -- unit tests for BVParametersTable class + * + *****************************************************************************/ #include @@ -24,206 +24,173 @@ using namespace std; using namespace diffpy::srreal; - -class TestBVParametersTable : public CxxTest::TestSuite -{ - - private: - - BVParametersTablePtr mbvtb; - - public: - - void setUp() - { - mbvtb.reset(new BVParametersTable); - } - - - void test_copy() - { - BVParam mynacl("Na", 1, "Cl", -1); - mynacl.mRo = 1.23; - mynacl.mB = 0.377; - mbvtb->setCustom(mynacl); - TS_ASSERT_EQUALS(1.23, mbvtb->lookup("Na", 1, "Cl", -1).mRo); - TS_ASSERT_EQUALS(0.377, mbvtb->lookup("Na", 1, "Cl", -1).mB); - BVParametersTable bvcp(*mbvtb); - TS_ASSERT_EQUALS(1.23, bvcp.lookup("Na", 1, "Cl", -1).mRo); - TS_ASSERT_EQUALS(0.377, bvcp.lookup("Na", 1, "Cl", -1).mB); - bvcp.resetAll(); - TS_ASSERT_EQUALS(2.15, bvcp.lookup("Na", 1, "Cl", -1).mRo); - TS_ASSERT_EQUALS(0.37, bvcp.lookup("Na", 1, "Cl", -1).mB); - TS_ASSERT_EQUALS(1.23, mbvtb->lookup("Na", 1, "Cl", -1).mRo); - TS_ASSERT_EQUALS(0.377, mbvtb->lookup("Na", 1, "Cl", -1).mB); - } - - - void test_none() - { - const BVParam& bpnone = BVParametersTable::none(); - TS_ASSERT_EQUALS(&bpnone, &(mbvtb->none())); - TS_ASSERT_EQUALS(0.0, bpnone.bondvalence(0)); - TS_ASSERT_EQUALS(0.0, bpnone.bondvalence(3)); - TS_ASSERT_EQUALS(0.0, bpnone.bondvalence(10)); - TS_ASSERT_EQUALS(0.0, bpnone.bondvalenceToDistance(0.5)); - } - - - void test_atomvalence() - { - TS_ASSERT_EQUALS(0, mbvtb->getAtomValence("O")); - mbvtb->setAtomValence("O", -2); - TS_ASSERT_EQUALS(-2, mbvtb->getAtomValence("O")); - mbvtb->resetAtomValences(); - TS_ASSERT_EQUALS(0, mbvtb->getAtomValence("O")); - } - - - void test_lookup() - { - BVParam bp = mbvtb->lookup("Xx", 0, "Yy", 3); - TS_ASSERT(bp.matom0.empty()); - TS_ASSERT(bp.matom1.empty()); - TS_ASSERT_EQUALS(0, bp.mvalence0); - TS_ASSERT_EQUALS(0, bp.mvalence1); - TS_ASSERT_EQUALS(0.0, bp.mRo); - TS_ASSERT_EQUALS(0.0, bp.mB); - TS_ASSERT_EQUALS(&mbvtb->lookup("Xx", 0, "Yy", 3), - &mbvtb->lookup("Na", 33, "Cl", -11)); - BVParam bk("Na", 1, "Cl", -1); - TS_ASSERT_EQUALS(&mbvtb->lookup(bk), - &mbvtb->lookup("Cl", -1, "Na", 1)); - TS_ASSERT_EQUALS(2.15, mbvtb->lookup(bk).mRo); - TS_ASSERT_EQUALS(0.37, mbvtb->lookup(bk).mB); - TS_ASSERT_EQUALS("b", mbvtb->lookup(bk).mref_id); - const BVParam& bnacl0 = mbvtb->lookup("Na", 1, "Cl", -1); - TS_ASSERT_EQUALS(&bnacl0, &mbvtb->lookup("Na+", "Cl-")); - TS_ASSERT_EQUALS(&bnacl0, &mbvtb->lookup("Cl1-", "Na1+")); - const BVParam& bpnone = BVParametersTable::none(); - TS_ASSERT_EQUALS(&bpnone, &mbvtb->lookup("Na", "Cl")); - mbvtb->setAtomValence("Na", +1); - mbvtb->setAtomValence("Cl", -1); - TS_ASSERT_EQUALS(&bnacl0, &mbvtb->lookup("Na", "Cl")); - } - - - void test_setCustom() - { - BVParam mymgo("Mg", 2, "O", -2); - mymgo.mRo = 2.34; - mymgo.mB = 0.345; - mbvtb->setCustom(mymgo); - TS_ASSERT_EQUALS(2.34, mbvtb->lookup("Mg", 2, "O", -2).mRo); - TS_ASSERT_EQUALS(0.345, mbvtb->lookup(mymgo).mB); - mbvtb->resetCustom(mymgo); - TS_ASSERT_DIFFERS(2.34, mbvtb->lookup("Mg", 2, "O", -2).mRo); - TS_ASSERT_DIFFERS(0.345, mbvtb->lookup(mymgo).mB); - BVParam zrh = mbvtb->lookup("Zr", 4, "H", -1); - TS_ASSERT_EQUALS(1.79, zrh.mRo); - TS_ASSERT_EQUALS(0.37, zrh.mB); - TS_ASSERT_EQUALS(string("b"), zrh.mref_id); - mbvtb->setCustom("H", -1, "Zr", 4, 1.791, 0.371, "check"); - zrh = mbvtb->lookup("Zr", 4, "H", -1); - TS_ASSERT_EQUALS(1.791, zrh.mRo); - TS_ASSERT_EQUALS(0.371, zrh.mB); - TS_ASSERT_EQUALS(string("check"), zrh.mref_id); - mbvtb->setCustom("H", -1, "Zr", 4, 1.791, 0.444, "mate"); - zrh = mbvtb->lookup("Zr", 4, "H", -1); - TS_ASSERT_EQUALS(0.444, zrh.mB); - TS_ASSERT_EQUALS(string("mate"), zrh.mref_id); - } - - - void test_resetAll() - { - BVParam mynacl("Cl", -1, "Na", 1, 2.345, 0.44, "pj1"); - BVParam mymgo("O", -2, "Mg", 2, 3.456, 0.55, "pj2"); - mbvtb->setCustom(mynacl); - mbvtb->setCustom(mymgo); - TS_ASSERT_EQUALS(string("pj1"), mbvtb->lookup(mynacl).mref_id); - TS_ASSERT_EQUALS(string("pj2"), mbvtb->lookup(mymgo).mref_id); - mbvtb->resetAll(); - TS_ASSERT_DIFFERS(string("pj1"), mbvtb->lookup(mynacl).mref_id); - TS_ASSERT_DIFFERS(string("pj2"), mbvtb->lookup(mymgo).mref_id); - } - - - void test_getAllCustom() - { - TS_ASSERT(mbvtb->getAllCustom().empty()); - BVParam mymgo("Mg", 2, "O", -2); - mbvtb->setCustom(mymgo); - TS_ASSERT_EQUALS(1u, mbvtb->getAllCustom().size()); - const BVParam& bp = mbvtb->lookup("O2-", "Mg2+"); - BVParametersTable::SetOfBVParam::const_iterator ii; - ii = mbvtb->getAllCustom().find(mymgo); - TS_ASSERT_DIFFERS(ii, mbvtb->getAllCustom().end()); - TS_ASSERT_DIFFERS(&mymgo, &(*ii)); - TS_ASSERT_EQUALS(&bp, &(*ii)); - TS_ASSERT_EQUALS(mymgo, *ii); - // erase the only custom parameter - mbvtb->resetCustom(*ii); - TS_ASSERT(mbvtb->getAllCustom().empty()); - } - - - void test_getAll() - { - BVParametersTable::SetOfBVParam allpars0, allpars1; - allpars0 = mbvtb->getAll(); - TS_ASSERT(!allpars0.empty()); - size_t cnt0 = allpars0.size(); - BVParam mymgo("Mg", 2, "O", -2); - mbvtb->setCustom(mymgo); - TS_ASSERT_EQUALS(cnt0, mbvtb->getAll().size()); - mbvtb->setCustom(BVParam("Mg", 7, "O", -3)); - allpars1 = mbvtb->getAll(); - size_t cnt1 = allpars1.size(); - TS_ASSERT_EQUALS(cnt0 + 1, cnt1); - mbvtb->resetAll(); - TS_ASSERT_EQUALS(cnt0, mbvtb->getAll().size()); - mbvtb->setCustom(BVParam("Mg", 2, "O", -2, 77, 88)); - allpars1 = mbvtb->getAll(); - const BVParam& mgo = *allpars1.find(BVParam("Mg", 2, "O", -2)); - TS_ASSERT_EQUALS(77.0, mgo.mRo); - TS_ASSERT_EQUALS(88.0, mgo.mB); - } - - - void test_serialization() - { - BVParam mynacl("Cl", -1, "Na", 1, 2.345, 0.44, "pj1"); - BVParam mymgo("O", -2, "Mg", 2, 3.456, 0.55, "pj2"); - mbvtb->setCustom(mynacl); - mbvtb->setCustom(mymgo); - // check serialization of shared pointers - BVParametersTablePtr bvtb1 = dumpandload(mbvtb); - TS_ASSERT_DIFFERS(mbvtb.get(), bvtb1.get()); - TS_ASSERT_EQUALS(2.345, - bvtb1->lookup("Cl", -1, "Na", 1).mRo); - TS_ASSERT_EQUALS(0.44, - bvtb1->lookup("Cl", -1, "Na", 1).mB); - TS_ASSERT_EQUALS(string("pj1"), - bvtb1->lookup("Cl", -1, "Na", 1).mref_id); - TS_ASSERT_EQUALS(3.456, - bvtb1->lookup("O", -2, "Mg", 2).mRo); - TS_ASSERT_EQUALS(0.55, - bvtb1->lookup("O", -2, "Mg", 2).mB); - TS_ASSERT_EQUALS(string("pj2"), - bvtb1->lookup("O", -2, "Mg", 2).mref_id); - // check serialization of instances - BVParametersTable tb2 = dumpandload(*mbvtb); - TS_ASSERT_EQUALS(2u, tb2.getAllCustom().size()); - TS_ASSERT_EQUALS(mynacl, tb2.lookup("Cl-", "Na+")); - // check serialization of customized valences - tb2.setAtomValence("Na", 1); - tb2.setAtomValence("Cl", -1); - BVParametersTable tb3 = dumpandload(tb2); - TS_ASSERT_EQUALS(mynacl, tb3.lookup("Cl", "Na")); - const BVParam& bpnone = BVParametersTable::none(); - TS_ASSERT_EQUALS(bpnone, mbvtb->lookup("Cl", "Na")); - } +class TestBVParametersTable : public CxxTest::TestSuite { + private: + BVParametersTablePtr mbvtb; + + public: + void setUp() { mbvtb.reset(new BVParametersTable); } + + void test_copy() { + BVParam mynacl("Na", 1, "Cl", -1); + mynacl.mRo = 1.23; + mynacl.mB = 0.377; + mbvtb->setCustom(mynacl); + TS_ASSERT_EQUALS(1.23, mbvtb->lookup("Na", 1, "Cl", -1).mRo); + TS_ASSERT_EQUALS(0.377, mbvtb->lookup("Na", 1, "Cl", -1).mB); + BVParametersTable bvcp(*mbvtb); + TS_ASSERT_EQUALS(1.23, bvcp.lookup("Na", 1, "Cl", -1).mRo); + TS_ASSERT_EQUALS(0.377, bvcp.lookup("Na", 1, "Cl", -1).mB); + bvcp.resetAll(); + TS_ASSERT_EQUALS(2.15, bvcp.lookup("Na", 1, "Cl", -1).mRo); + TS_ASSERT_EQUALS(0.37, bvcp.lookup("Na", 1, "Cl", -1).mB); + TS_ASSERT_EQUALS(1.23, mbvtb->lookup("Na", 1, "Cl", -1).mRo); + TS_ASSERT_EQUALS(0.377, mbvtb->lookup("Na", 1, "Cl", -1).mB); + } + + void test_none() { + const BVParam& bpnone = BVParametersTable::none(); + TS_ASSERT_EQUALS(&bpnone, &(mbvtb->none())); + TS_ASSERT_EQUALS(0.0, bpnone.bondvalence(0)); + TS_ASSERT_EQUALS(0.0, bpnone.bondvalence(3)); + TS_ASSERT_EQUALS(0.0, bpnone.bondvalence(10)); + TS_ASSERT_EQUALS(0.0, bpnone.bondvalenceToDistance(0.5)); + } + + void test_atomvalence() { + TS_ASSERT_EQUALS(0, mbvtb->getAtomValence("O")); + mbvtb->setAtomValence("O", -2); + TS_ASSERT_EQUALS(-2, mbvtb->getAtomValence("O")); + mbvtb->resetAtomValences(); + TS_ASSERT_EQUALS(0, mbvtb->getAtomValence("O")); + } + + void test_lookup() { + BVParam bp = mbvtb->lookup("Xx", 0, "Yy", 3); + TS_ASSERT(bp.matom0.empty()); + TS_ASSERT(bp.matom1.empty()); + TS_ASSERT_EQUALS(0, bp.mvalence0); + TS_ASSERT_EQUALS(0, bp.mvalence1); + TS_ASSERT_EQUALS(0.0, bp.mRo); + TS_ASSERT_EQUALS(0.0, bp.mB); + TS_ASSERT_EQUALS(&mbvtb->lookup("Xx", 0, "Yy", 3), + &mbvtb->lookup("Na", 33, "Cl", -11)); + BVParam bk("Na", 1, "Cl", -1); + TS_ASSERT_EQUALS(&mbvtb->lookup(bk), &mbvtb->lookup("Cl", -1, "Na", 1)); + TS_ASSERT_EQUALS(2.15, mbvtb->lookup(bk).mRo); + TS_ASSERT_EQUALS(0.37, mbvtb->lookup(bk).mB); + TS_ASSERT_EQUALS("b", mbvtb->lookup(bk).mref_id); + const BVParam& bnacl0 = mbvtb->lookup("Na", 1, "Cl", -1); + TS_ASSERT_EQUALS(&bnacl0, &mbvtb->lookup("Na+", "Cl-")); + TS_ASSERT_EQUALS(&bnacl0, &mbvtb->lookup("Cl1-", "Na1+")); + const BVParam& bpnone = BVParametersTable::none(); + TS_ASSERT_EQUALS(&bpnone, &mbvtb->lookup("Na", "Cl")); + mbvtb->setAtomValence("Na", +1); + mbvtb->setAtomValence("Cl", -1); + TS_ASSERT_EQUALS(&bnacl0, &mbvtb->lookup("Na", "Cl")); + } + + void test_setCustom() { + BVParam mymgo("Mg", 2, "O", -2); + mymgo.mRo = 2.34; + mymgo.mB = 0.345; + mbvtb->setCustom(mymgo); + TS_ASSERT_EQUALS(2.34, mbvtb->lookup("Mg", 2, "O", -2).mRo); + TS_ASSERT_EQUALS(0.345, mbvtb->lookup(mymgo).mB); + mbvtb->resetCustom(mymgo); + TS_ASSERT_DIFFERS(2.34, mbvtb->lookup("Mg", 2, "O", -2).mRo); + TS_ASSERT_DIFFERS(0.345, mbvtb->lookup(mymgo).mB); + BVParam zrh = mbvtb->lookup("Zr", 4, "H", -1); + TS_ASSERT_EQUALS(1.79, zrh.mRo); + TS_ASSERT_EQUALS(0.37, zrh.mB); + TS_ASSERT_EQUALS(string("b"), zrh.mref_id); + mbvtb->setCustom("H", -1, "Zr", 4, 1.791, 0.371, "check"); + zrh = mbvtb->lookup("Zr", 4, "H", -1); + TS_ASSERT_EQUALS(1.791, zrh.mRo); + TS_ASSERT_EQUALS(0.371, zrh.mB); + TS_ASSERT_EQUALS(string("check"), zrh.mref_id); + mbvtb->setCustom("H", -1, "Zr", 4, 1.791, 0.444, "mate"); + zrh = mbvtb->lookup("Zr", 4, "H", -1); + TS_ASSERT_EQUALS(0.444, zrh.mB); + TS_ASSERT_EQUALS(string("mate"), zrh.mref_id); + } + + void test_resetAll() { + BVParam mynacl("Cl", -1, "Na", 1, 2.345, 0.44, "pj1"); + BVParam mymgo("O", -2, "Mg", 2, 3.456, 0.55, "pj2"); + mbvtb->setCustom(mynacl); + mbvtb->setCustom(mymgo); + TS_ASSERT_EQUALS(string("pj1"), mbvtb->lookup(mynacl).mref_id); + TS_ASSERT_EQUALS(string("pj2"), mbvtb->lookup(mymgo).mref_id); + mbvtb->resetAll(); + TS_ASSERT_DIFFERS(string("pj1"), mbvtb->lookup(mynacl).mref_id); + TS_ASSERT_DIFFERS(string("pj2"), mbvtb->lookup(mymgo).mref_id); + } + + void test_getAllCustom() { + TS_ASSERT(mbvtb->getAllCustom().empty()); + BVParam mymgo("Mg", 2, "O", -2); + mbvtb->setCustom(mymgo); + TS_ASSERT_EQUALS(1u, mbvtb->getAllCustom().size()); + const BVParam& bp = mbvtb->lookup("O2-", "Mg2+"); + BVParametersTable::SetOfBVParam::const_iterator ii; + ii = mbvtb->getAllCustom().find(mymgo); + TS_ASSERT_DIFFERS(ii, mbvtb->getAllCustom().end()); + TS_ASSERT_DIFFERS(&mymgo, &(*ii)); + TS_ASSERT_EQUALS(&bp, &(*ii)); + TS_ASSERT_EQUALS(mymgo, *ii); + // erase the only custom parameter + mbvtb->resetCustom(*ii); + TS_ASSERT(mbvtb->getAllCustom().empty()); + } + + void test_getAll() { + BVParametersTable::SetOfBVParam allpars0, allpars1; + allpars0 = mbvtb->getAll(); + TS_ASSERT(!allpars0.empty()); + size_t cnt0 = allpars0.size(); + BVParam mymgo("Mg", 2, "O", -2); + mbvtb->setCustom(mymgo); + TS_ASSERT_EQUALS(cnt0, mbvtb->getAll().size()); + mbvtb->setCustom(BVParam("Mg", 7, "O", -3)); + allpars1 = mbvtb->getAll(); + size_t cnt1 = allpars1.size(); + TS_ASSERT_EQUALS(cnt0 + 1, cnt1); + mbvtb->resetAll(); + TS_ASSERT_EQUALS(cnt0, mbvtb->getAll().size()); + mbvtb->setCustom(BVParam("Mg", 2, "O", -2, 77, 88)); + allpars1 = mbvtb->getAll(); + const BVParam& mgo = *allpars1.find(BVParam("Mg", 2, "O", -2)); + TS_ASSERT_EQUALS(77.0, mgo.mRo); + TS_ASSERT_EQUALS(88.0, mgo.mB); + } + + void test_serialization() { + BVParam mynacl("Cl", -1, "Na", 1, 2.345, 0.44, "pj1"); + BVParam mymgo("O", -2, "Mg", 2, 3.456, 0.55, "pj2"); + mbvtb->setCustom(mynacl); + mbvtb->setCustom(mymgo); + // check serialization of shared pointers + BVParametersTablePtr bvtb1 = dumpandload(mbvtb); + TS_ASSERT_DIFFERS(mbvtb.get(), bvtb1.get()); + TS_ASSERT_EQUALS(2.345, bvtb1->lookup("Cl", -1, "Na", 1).mRo); + TS_ASSERT_EQUALS(0.44, bvtb1->lookup("Cl", -1, "Na", 1).mB); + TS_ASSERT_EQUALS(string("pj1"), bvtb1->lookup("Cl", -1, "Na", 1).mref_id); + TS_ASSERT_EQUALS(3.456, bvtb1->lookup("O", -2, "Mg", 2).mRo); + TS_ASSERT_EQUALS(0.55, bvtb1->lookup("O", -2, "Mg", 2).mB); + TS_ASSERT_EQUALS(string("pj2"), bvtb1->lookup("O", -2, "Mg", 2).mref_id); + // check serialization of instances + BVParametersTable tb2 = dumpandload(*mbvtb); + TS_ASSERT_EQUALS(2u, tb2.getAllCustom().size()); + TS_ASSERT_EQUALS(mynacl, tb2.lookup("Cl-", "Na+")); + // check serialization of customized valences + tb2.setAtomValence("Na", 1); + tb2.setAtomValence("Cl", -1); + BVParametersTable tb3 = dumpandload(tb2); + TS_ASSERT_EQUALS(mynacl, tb3.lookup("Cl", "Na")); + const BVParam& bpnone = BVParametersTable::none(); + TS_ASSERT_EQUALS(bpnone, mbvtb->lookup("Cl", "Na")); + } }; // class TestBVParametersTable diff --git a/src/tests/TestBVSCalculator.hpp b/src/tests/TestBVSCalculator.hpp index f8001d51..2180856f 100644 --- a/src/tests/TestBVSCalculator.hpp +++ b/src/tests/TestBVSCalculator.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy 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. -* -****************************************************************************** -* -* class TestBVSCalculator -- unit tests suite -* -*****************************************************************************/ + * + * libdiffpy 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. + * + ****************************************************************************** + * + * class TestBVSCalculator -- unit tests suite + * + *****************************************************************************/ #include @@ -24,144 +24,126 @@ #include "test_helpers.hpp" using namespace std; -using diffpy::srreal::BVSCalculator; using diffpy::srreal::BVParametersTablePtr; -using diffpy::srreal::StructureAdapterPtr; +using diffpy::srreal::BVSCalculator; using diffpy::srreal::PeriodicStructureAdapter; using diffpy::srreal::PeriodicStructureAdapterPtr; +using diffpy::srreal::StructureAdapterPtr; ////////////////////////////////////////////////////////////////////////////// // class TestBVSCalculator ////////////////////////////////////////////////////////////////////////////// -class TestBVSCalculator : public CxxTest::TestSuite -{ - private: - - StructureAdapterPtr mnacl; - boost::shared_ptr mbvc; - - public: - - void setUp() - { - CxxTest::setAbortTestOnFail(true); - if (!mnacl) mnacl = loadTestPeriodicStructure("NaCl.stru"); - mbvc.reset(new BVSCalculator); - CxxTest::setAbortTestOnFail(false); - } - - - void test_NaCl() - { - const double eps = 1e-4; - mbvc->eval(mnacl); - TS_ASSERT_EQUALS(8u, mbvc->value().size()); - TS_ASSERT_DELTA(+1.01352, mbvc->value()[0], eps); - TS_ASSERT_DELTA(+1.01352, mbvc->value()[1], eps); - TS_ASSERT_DELTA(+1.01352, mbvc->value()[2], eps); - TS_ASSERT_DELTA(+1.01352, mbvc->value()[3], eps); - TS_ASSERT_DELTA(-1.01352, mbvc->value()[4], eps); - TS_ASSERT_DELTA(-1.01352, mbvc->value()[5], eps); - TS_ASSERT_DELTA(-1.01352, mbvc->value()[6], eps); - TS_ASSERT_DELTA(-1.01352, mbvc->value()[7], eps); - } - - - void test_NaCl_mixed() - { - StructureAdapterPtr nacl_mixed = - loadTestPeriodicStructure("NaCl_mixed.stru"); - mbvc->eval(mnacl); - BVSCalculator bvc; - bvc.eval(nacl_mixed); - TS_ASSERT_DELTA(mbvc->bvrmsdiff(), bvc.bvrmsdiff(), 1e-12); - } - - - void test_customAtomValences() - { - using diffpy::srreal::Atom; - const double eps = 1e-4; - mbvc->eval(mnacl); - TS_ASSERT_DELTA(0.01352, mbvc->bvrmsdiff(), eps); - BVParametersTablePtr bvtb = mbvc->getBVParamTable(); - bvtb->setAtomValence("Cl1-", 0); - mbvc->eval(mnacl); - TS_ASSERT_EQUALS(0.0, mbvc->value()[0]); - TS_ASSERT_EQUALS(0.0, mbvc->value()[4]); - // create structure with bare atom symbols "Na", "Cl". - PeriodicStructureAdapterPtr naclbare = - boost::dynamic_pointer_cast< - PeriodicStructureAdapter>(mnacl->clone()); - for (int i = 0; i < naclbare->countSites(); ++i) - { - Atom& a = naclbare->at(i); - a.atomtype = a.atomtype.substr(0, 2); - } - TS_ASSERT_EQUALS(string("Na"), naclbare->siteAtomType(0)); - // verify valence sums are zero for a standard setup. - mbvc->eval(naclbare); - TS_ASSERT_EQUALS(0.0, mbvc->value()[0]); - TS_ASSERT_EQUALS(0.0, mbvc->value()[4]); - // verify valence sums with custom atom valences. - bvtb->setAtomValence("Na", +1); - bvtb->setAtomValence("Cl", -1); - mbvc->eval(naclbare); - TS_ASSERT_DELTA(0.01352, mbvc->bvrmsdiff(), eps); - } - - - void test_setValencePrecision() - { - TS_ASSERT_THROWS(mbvc->setValencePrecision(0), invalid_argument); - TS_ASSERT_THROWS(mbvc->setValencePrecision(-1), invalid_argument); - TS_ASSERT_THROWS(mbvc->setDoubleAttr("valenceprecision", 0), - invalid_argument); - } - - - void test_getRmaxUsed() - { - mbvc->eval(mnacl); - double rmaxused = mbvc->getDoubleAttr("rmaxused"); - TS_ASSERT_EQUALS(rmaxused, mbvc->getRmaxUsed()); - TS_ASSERT_LESS_THAN(rmaxused, mbvc->getRmax()); - mbvc->setDoubleAttr("valenceprecision", - mbvc->getDoubleAttr("valenceprecision") / 10.0); - TS_ASSERT_LESS_THAN(rmaxused, mbvc->getDoubleAttr("rmaxused")); - mbvc->setValencePrecision(1e-7); - mbvc->setDoubleAttr("rmax", 5.0); - TS_ASSERT_EQUALS(5.0, mbvc->getDoubleAttr("rmaxused")); - // check if value updates with changes in the table. - BVParametersTablePtr bvtb = mbvc->getBVParamTable(); - bvtb->setCustom("Na", 1, "Cl", -1, 0.0, 0); - TS_ASSERT_EQUALS(0.0, mbvc->getDoubleAttr("rmaxused")); - } - - - void test_serialization() - { - mbvc->eval(mnacl); - stringstream storage(ios::in | ios::out | ios::binary); - diffpy::serialization::oarchive oa(storage, ios::binary); - oa << mbvc; - diffpy::serialization::iarchive ia(storage, ios::binary); - boost::shared_ptr bvc1; - TS_ASSERT(!bvc1.get()); - ia >> bvc1; - TS_ASSERT_DIFFERS(mbvc.get(), bvc1.get()); - const double eps=1e-4; - TS_ASSERT_EQUALS(8u, bvc1->value().size()); - TS_ASSERT_DELTA(+1.01352, bvc1->value()[0], eps); - TS_ASSERT_DELTA(+1.01352, bvc1->value()[1], eps); - TS_ASSERT_DELTA(+1.01352, bvc1->value()[2], eps); - TS_ASSERT_DELTA(+1.01352, bvc1->value()[3], eps); - TS_ASSERT_DELTA(-1.01352, bvc1->value()[4], eps); - TS_ASSERT_DELTA(-1.01352, bvc1->value()[5], eps); - TS_ASSERT_DELTA(-1.01352, bvc1->value()[6], eps); - TS_ASSERT_DELTA(-1.01352, bvc1->value()[7], eps); - } +class TestBVSCalculator : public CxxTest::TestSuite { + private: + StructureAdapterPtr mnacl; + boost::shared_ptr mbvc; + + public: + void setUp() { + CxxTest::setAbortTestOnFail(true); + if (!mnacl) mnacl = loadTestPeriodicStructure("NaCl.stru"); + mbvc.reset(new BVSCalculator); + CxxTest::setAbortTestOnFail(false); + } + + void test_NaCl() { + const double eps = 1e-4; + mbvc->eval(mnacl); + TS_ASSERT_EQUALS(8u, mbvc->value().size()); + TS_ASSERT_DELTA(+1.01352, mbvc->value()[0], eps); + TS_ASSERT_DELTA(+1.01352, mbvc->value()[1], eps); + TS_ASSERT_DELTA(+1.01352, mbvc->value()[2], eps); + TS_ASSERT_DELTA(+1.01352, mbvc->value()[3], eps); + TS_ASSERT_DELTA(-1.01352, mbvc->value()[4], eps); + TS_ASSERT_DELTA(-1.01352, mbvc->value()[5], eps); + TS_ASSERT_DELTA(-1.01352, mbvc->value()[6], eps); + TS_ASSERT_DELTA(-1.01352, mbvc->value()[7], eps); + } + + void test_NaCl_mixed() { + StructureAdapterPtr nacl_mixed = + loadTestPeriodicStructure("NaCl_mixed.stru"); + mbvc->eval(mnacl); + BVSCalculator bvc; + bvc.eval(nacl_mixed); + TS_ASSERT_DELTA(mbvc->bvrmsdiff(), bvc.bvrmsdiff(), 1e-12); + } + + void test_customAtomValences() { + using diffpy::srreal::Atom; + const double eps = 1e-4; + mbvc->eval(mnacl); + TS_ASSERT_DELTA(0.01352, mbvc->bvrmsdiff(), eps); + BVParametersTablePtr bvtb = mbvc->getBVParamTable(); + bvtb->setAtomValence("Cl1-", 0); + mbvc->eval(mnacl); + TS_ASSERT_EQUALS(0.0, mbvc->value()[0]); + TS_ASSERT_EQUALS(0.0, mbvc->value()[4]); + // create structure with bare atom symbols "Na", "Cl". + PeriodicStructureAdapterPtr naclbare = + boost::dynamic_pointer_cast(mnacl->clone()); + for (int i = 0; i < naclbare->countSites(); ++i) { + Atom& a = naclbare->at(i); + a.atomtype = a.atomtype.substr(0, 2); + } + TS_ASSERT_EQUALS(string("Na"), naclbare->siteAtomType(0)); + // verify valence sums are zero for a standard setup. + mbvc->eval(naclbare); + TS_ASSERT_EQUALS(0.0, mbvc->value()[0]); + TS_ASSERT_EQUALS(0.0, mbvc->value()[4]); + // verify valence sums with custom atom valences. + bvtb->setAtomValence("Na", +1); + bvtb->setAtomValence("Cl", -1); + mbvc->eval(naclbare); + TS_ASSERT_DELTA(0.01352, mbvc->bvrmsdiff(), eps); + } + + void test_setValencePrecision() { + TS_ASSERT_THROWS(mbvc->setValencePrecision(0), invalid_argument); + TS_ASSERT_THROWS(mbvc->setValencePrecision(-1), invalid_argument); + TS_ASSERT_THROWS(mbvc->setDoubleAttr("valenceprecision", 0), + invalid_argument); + } + + void test_getRmaxUsed() { + mbvc->eval(mnacl); + double rmaxused = mbvc->getDoubleAttr("rmaxused"); + TS_ASSERT_EQUALS(rmaxused, mbvc->getRmaxUsed()); + TS_ASSERT_LESS_THAN(rmaxused, mbvc->getRmax()); + mbvc->setDoubleAttr("valenceprecision", + mbvc->getDoubleAttr("valenceprecision") / 10.0); + TS_ASSERT_LESS_THAN(rmaxused, mbvc->getDoubleAttr("rmaxused")); + mbvc->setValencePrecision(1e-7); + mbvc->setDoubleAttr("rmax", 5.0); + TS_ASSERT_EQUALS(5.0, mbvc->getDoubleAttr("rmaxused")); + // check if value updates with changes in the table. + BVParametersTablePtr bvtb = mbvc->getBVParamTable(); + bvtb->setCustom("Na", 1, "Cl", -1, 0.0, 0); + TS_ASSERT_EQUALS(0.0, mbvc->getDoubleAttr("rmaxused")); + } + + void test_serialization() { + mbvc->eval(mnacl); + stringstream storage(ios::in | ios::out | ios::binary); + diffpy::serialization::oarchive oa(storage, ios::binary); + oa << mbvc; + diffpy::serialization::iarchive ia(storage, ios::binary); + boost::shared_ptr bvc1; + TS_ASSERT(!bvc1.get()); + ia >> bvc1; + TS_ASSERT_DIFFERS(mbvc.get(), bvc1.get()); + const double eps = 1e-4; + TS_ASSERT_EQUALS(8u, bvc1->value().size()); + TS_ASSERT_DELTA(+1.01352, bvc1->value()[0], eps); + TS_ASSERT_DELTA(+1.01352, bvc1->value()[1], eps); + TS_ASSERT_DELTA(+1.01352, bvc1->value()[2], eps); + TS_ASSERT_DELTA(+1.01352, bvc1->value()[3], eps); + TS_ASSERT_DELTA(-1.01352, bvc1->value()[4], eps); + TS_ASSERT_DELTA(-1.01352, bvc1->value()[5], eps); + TS_ASSERT_DELTA(-1.01352, bvc1->value()[6], eps); + TS_ASSERT_DELTA(-1.01352, bvc1->value()[7], eps); + } }; // class TestBVSCalculator diff --git a/src/tests/TestBVSObjCryst.hpp b/src/tests/TestBVSObjCryst.hpp index 84830445..4be8f53c 100644 --- a/src/tests/TestBVSObjCryst.hpp +++ b/src/tests/TestBVSObjCryst.hpp @@ -1,21 +1,21 @@ /***************************************************************************** -* -* libdiffpy 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. -* -****************************************************************************** -* -* class TestBVSObjCryst -- unit tests for BVS calculation for an ObjCryst -* crystal structure -* -*****************************************************************************/ + * + * libdiffpy 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. + * + ****************************************************************************** + * + * class TestBVSObjCryst -- unit tests for BVS calculation for an ObjCryst + * crystal structure + * + *****************************************************************************/ #include @@ -31,44 +31,35 @@ using namespace diffpy::srreal; // class Test ////////////////////////////////////////////////////////////////////////////// -class TestBVSObjCryst : public CxxTest::TestSuite -{ - private: +class TestBVSObjCryst : public CxxTest::TestSuite { + private: + unique_ptr mnacl; + unique_ptr mbvc; - unique_ptr mnacl; - unique_ptr mbvc; + public: + void setUp() { + if (!mnacl.get()) { + mnacl.reset(loadTestCrystal("NaCl.cif")); + } + mbvc.reset(new BVSCalculator); + } - public: + void test_NaCl() { + const double eps = 1e-4; + mbvc->eval(*mnacl); + TS_ASSERT_EQUALS(2u, mbvc->value().size()); + TS_ASSERT_DELTA(+1.01352, mbvc->value()[0], eps); + TS_ASSERT_DELTA(-1.01352, mbvc->value()[1], eps); + } - void setUp() - { - if (!mnacl.get()) - { - mnacl.reset(loadTestCrystal("NaCl.cif")); - } - mbvc.reset(new BVSCalculator); - } - - - void test_NaCl() - { - const double eps = 1e-4; - mbvc->eval(*mnacl); - TS_ASSERT_EQUALS(2u, mbvc->value().size()); - TS_ASSERT_DELTA(+1.01352, mbvc->value()[0], eps); - TS_ASSERT_DELTA(-1.01352, mbvc->value()[1], eps); - } - - - void test_NaCl_mixed() - { - unique_ptr nacl_mixed; - nacl_mixed.reset(loadTestCrystal("NaCl_mixed.cif")); - mbvc->eval(*mnacl); - BVSCalculator bvc; - bvc.eval(*nacl_mixed); - TS_ASSERT_DELTA(mbvc->bvrmsdiff(), bvc.bvrmsdiff(), 1e-12); - } + void test_NaCl_mixed() { + unique_ptr nacl_mixed; + nacl_mixed.reset(loadTestCrystal("NaCl_mixed.cif")); + mbvc->eval(*mnacl); + BVSCalculator bvc; + bvc.eval(*nacl_mixed); + TS_ASSERT_DELTA(mbvc->bvrmsdiff(), bvc.bvrmsdiff(), 1e-12); + } }; // class TestBVSObjCryst diff --git a/src/tests/TestDebyePDFCalculator.hpp b/src/tests/TestDebyePDFCalculator.hpp index 5bd380d3..d48225d8 100644 --- a/src/tests/TestDebyePDFCalculator.hpp +++ b/src/tests/TestDebyePDFCalculator.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2011 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. -* -****************************************************************************** -* -* class TestDebyePDFCalculator -- unit tests for DebyePDFCalculator class -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2011 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. + * + ****************************************************************************** + * + * class TestDebyePDFCalculator -- unit tests for DebyePDFCalculator class + * + *****************************************************************************/ #include @@ -30,334 +30,283 @@ using namespace std; using namespace diffpy::srreal; -class TestDebyePDFCalculator : public CxxTest::TestSuite -{ - private: - - boost::shared_ptr mpdfc; - AtomicStructureAdapterPtr memptystru; - AtomicStructureAdapterPtr mstru10; - AtomicStructureAdapterPtr mstru10d1; - AtomicStructureAdapterPtr mstru10r; - AtomicStructureAdapterPtr mstru9; - diffpy::mathutils::EpsilonEqual allclose; - double meps; - - public: - - void setUp() - { - const int SZ = 10; - meps = diffpy::mathutils::SQRT_DOUBLE_EPS; - mpdfc.reset(new DebyePDFCalculator); - memptystru = boost::make_shared(); - mstru10 = boost::make_shared(); - Atom ai; - ai.atomtype = "C"; - ai.uij_cartn = R3::identity(); - ai.uij_cartn(0, 0) = ai.uij_cartn(1, 1) = - ai.uij_cartn(2, 2) = 0.004; - for (int i = 0; i < SZ; ++i) - { - ai.xyz_cartn[0] = i; - mstru10->append(ai); - } - mstru10d1 = boost::make_shared(*mstru10); - (*mstru10d1)[0].atomtype = "Au"; - mstru10r = boost::make_shared(); - mstru10r->assign(mstru10->rbegin(), mstru10->rend()); - mstru9 = boost::make_shared(*mstru10); - mstru9->erase(9); - } - - - void test_setQmax() - { - const double dq0 = mpdfc->getQstep(); - const double qmax0 = mpdfc->getQmax(); - const double qmax1 = 2 * dq0; - mpdfc->setQmax(qmax1); - TS_ASSERT_EQUALS(qmax1 / 4.0, mpdfc->getQstep()); - mpdfc->setQmax(qmax0); - TS_ASSERT_EQUALS(dq0, mpdfc->getQstep()); - } - - - void test_setQstep() - { - mpdfc->setRstep(2.0); - mpdfc->setQstep(0.02); - TS_ASSERT_EQUALS(0.02, mpdfc->getQstep()); - } - - - void test_access_Envelopes() - { - TS_ASSERT_EQUALS(2u, mpdfc->usedEnvelopeTypes().size()); - TS_ASSERT_EQUALS(1.0, mpdfc->getDoubleAttr("scale")); - TS_ASSERT_EQUALS(0.0, mpdfc->getDoubleAttr("qdamp")); - mpdfc->setDoubleAttr("scale", 3.0); - TS_ASSERT_EQUALS(3.0, mpdfc->getDoubleAttr("scale")); - mpdfc->addEnvelopeByType("scale"); - TS_ASSERT_EQUALS(1.0, mpdfc->getDoubleAttr("scale")); - QResolutionEnvelope qdamp4; - qdamp4.setQdamp(4); - mpdfc->addEnvelope(qdamp4.clone()); - TS_ASSERT_EQUALS(4.0, mpdfc->getDoubleAttr("qdamp")); - TS_ASSERT_THROWS(mpdfc->addEnvelopeByType("invalid"), logic_error); - } - - - void test_getPDF() - { - QuantityType pdf; - TS_ASSERT_EQUALS(1000u, mpdfc->getPDF().size()); - mpdfc->setRmin(2.0); - mpdfc->setRmax(0.0); - mpdfc->eval(memptystru); - pdf = mpdfc->getPDF(); - TS_ASSERT(mpdfc->getPDF().empty()); - mpdfc->setRmax(2.0); - mpdfc->eval(memptystru); - pdf = mpdfc->getPDF(); - TS_ASSERT(mpdfc->getPDF().empty()); - mpdfc->setRmax(2.01001); - mpdfc->eval(memptystru); - pdf = mpdfc->getPDF(); - TS_ASSERT_EQUALS(2u, pdf.size()); - } - - - void test_getRDF() - { - // getRDF is not yet implemented and just returns empty array. - QuantityType rdf = mpdfc->getRDF(); - TS_ASSERT_EQUALS(1000u, rdf.size()); - TS_ASSERT_EQUALS(0.0, *std::min_element(rdf.begin(), rdf.end())); - TS_ASSERT_EQUALS(0.0, *std::max_element(rdf.begin(), rdf.end())); - } - - - void test_getF() - { - QuantityType fq = mpdfc->getF(); - TS_ASSERT_EQUALS(92u, fq.size()); - TS_ASSERT_EQUALS(0.0, *min_element(fq.begin(), fq.end())); - TS_ASSERT_EQUALS(0.0, *max_element(fq.begin(), fq.end())); - } - - - void test_getQgrid() - { - TS_ASSERT_EQUALS(92u, mpdfc->getQgrid().size()); - } - - - void test_getQmin() - { - TS_ASSERT_EQUALS(0.0, mpdfc->getQmin()); - mpdfc->setQmin(1.0); - const DebyePDFCalculator& dpc = *mpdfc; - TS_ASSERT_EQUALS(1.0, dpc.getQmin()); - TS_ASSERT_EQUALS(0.0, dpc.BaseDebyeSum::getQmin()); - } - - - void test_getQmax() - { - TS_ASSERT_DELTA(25.0, mpdfc->getQmax(), meps); - } - - - void test_getQstep() - { - const double rcalchi = ceil((10.0 + 12*M_PI/25.0) / 0.01) * 0.01; - const double qstep = M_PI / rcalchi; - TS_ASSERT_DELTA(qstep, mpdfc->getQstep(), meps); - } - - - void test_getRgrid() - { - QuantityType rgrid0 = mpdfc->getRgrid(); - TS_ASSERT_EQUALS(rgrid0, mpdfc->getRgrid()); - mpdfc->setRmin(5); - mpdfc->setRmax(4); - TS_ASSERT(mpdfc->getRgrid().empty()); - } - - - void test_serialization() - { - // build customized DebyePDFCalculator - mpdfc->setPeakWidthModelByType("constant"); - mpdfc->setDoubleAttr("width", 0.123); - mpdfc->setDoubleAttr("debyeprecision", 0.00011); - mpdfc->setScatteringFactorTableByType("electronnumber"); - mpdfc->getScatteringFactorTable()->setCustomAs("H", "H", 1.1); - // dump it to string - stringstream storage(ios::in | ios::out | ios::binary); - diffpy::serialization::oarchive oa(storage, ios::binary); - oa << mpdfc; - diffpy::serialization::iarchive ia(storage, ios::binary); - boost::shared_ptr pdfc1; - ia >> pdfc1; - TS_ASSERT_DIFFERS(pdfc1.get(), mpdfc.get()); - TS_ASSERT_EQUALS(string("constant"), - pdfc1->getPeakWidthModel()->type()); - TS_ASSERT_EQUALS(0.123, pdfc1->getDoubleAttr("width")); - TS_ASSERT_EQUALS(0.00011, pdfc1->getDoubleAttr("debyeprecision")); - TS_ASSERT_EQUALS(string("electronnumber"), - pdfc1->getScatteringFactorTable()->type()); - TS_ASSERT_EQUALS(1.1, - pdfc1->getScatteringFactorTable()->lookup("H")); - } - - - void test_DBPDF_change_atom() - { - using std::placeholders::_1; - mpdfc->setQmin(1.0); - DebyePDFCalculator pdfcb = *mpdfc; - DebyePDFCalculator pdfco = *mpdfc; - TS_ASSERT_EQUALS(1.0, pdfcb.getQmin()); - pdfcb.setEvaluatorType(BASIC); - pdfco.setEvaluatorType(OPTIMIZED); - TS_ASSERT_EQUALS(NONE, pdfcb.getEvaluatorTypeUsed()); - TS_ASSERT_EQUALS(NONE, pdfco.getEvaluatorTypeUsed()); - pdfcb.eval(mstru10); - pdfco.eval(mstru10); - QuantityType gb = pdfcb.getPDF(); - QuantityType go = pdfco.getPDF(); - TS_ASSERT(!gb.empty()); - TS_ASSERT_EQUALS(gb, go); - int cnonzero = count_if(gb.begin(), gb.end(), - bind(not_equal_to(), _1, 0.0)); - TS_ASSERT(cnonzero); - TS_ASSERT_EQUALS(BASIC, pdfcb.getEvaluatorType()); - TS_ASSERT_EQUALS(OPTIMIZED, pdfco.getEvaluatorType()); - // first call of pdfco should use the BASIC evaluation - TS_ASSERT_EQUALS(BASIC, pdfcb.getEvaluatorTypeUsed()); - TS_ASSERT_EQUALS(BASIC, pdfco.getEvaluatorTypeUsed()); - // test second call on the same structure - pdfco.eval(mstru10); - go = pdfco.getPDF(); - TS_ASSERT_EQUALS(gb, go); - TS_ASSERT_EQUALS(OPTIMIZED, pdfco.getEvaluatorTypeUsed()); - // test structure with one different atom - pdfcb.eval(mstru10d1); - pdfco.eval(mstru10d1); - QuantityType gb1 = pdfcb.getPDF(); - QuantityType go1 = pdfco.getPDF(); - TS_ASSERT(!allclose(gb, gb1)); - TS_ASSERT_EQUALS(OPTIMIZED, pdfco.getEvaluatorTypeUsed()); - TS_ASSERT(allclose(gb1, go1)); - // change position of 1 atom - mstru10d1->at(0).xyz_cartn[1] = 0.5; - pdfcb.eval(mstru10d1); - pdfco.eval(mstru10d1); - QuantityType gb2 = pdfcb.getPDF(); - QuantityType go2 = pdfco.getPDF(); - TS_ASSERT(!allclose(gb1, gb2)); - TS_ASSERT_EQUALS(OPTIMIZED, pdfco.getEvaluatorTypeUsed()); - TS_ASSERT(allclose(gb2, go2)); - } - - - void test_DBPDF_reverse_atoms() - { - mpdfc->setQmin(1.1); - DebyePDFCalculator pdfcb = *mpdfc; - DebyePDFCalculator pdfco = *mpdfc; - pdfcb.setEvaluatorType(BASIC); - pdfco.setEvaluatorType(OPTIMIZED); - pdfcb.eval(mstru10); - pdfco.eval(mstru10); - pdfco.eval(mstru10r); - QuantityType gb = pdfcb.getPDF(); - QuantityType go = pdfco.getPDF(); - TS_ASSERT_EQUALS(OPTIMIZED, pdfco.getEvaluatorTypeUsed()); - TS_ASSERT(allclose(gb, go)); - } - - - void test_DBPDF_remove_atom() - { - mpdfc->setQmin(1.2); - DebyePDFCalculator pdfcb = *mpdfc; - DebyePDFCalculator pdfco = *mpdfc; - pdfcb.setEvaluatorType(BASIC); - pdfco.setEvaluatorType(OPTIMIZED); - pdfcb.eval(mstru9); - pdfco.eval(mstru10); - pdfco.eval(mstru9); - QuantityType gb = pdfcb.getPDF(); - QuantityType go = pdfco.getPDF(); - TS_ASSERT_EQUALS(OPTIMIZED, pdfco.getEvaluatorTypeUsed()); - TS_ASSERT(allclose(gb, go)); - } - - - void test_DBPDF_qmin_click() - { - mpdfc->setEvaluatorType(OPTIMIZED); - TS_ASSERT_EQUALS(NONE, mpdfc->getEvaluatorTypeUsed()); - mpdfc->eval(mstru10); - mpdfc->eval(mstru10); - TS_ASSERT_EQUALS(OPTIMIZED, mpdfc->getEvaluatorTypeUsed()); - mpdfc->setQmin(4); - mpdfc->eval(mstru10); - TS_ASSERT_EQUALS(OPTIMIZED, mpdfc->getEvaluatorTypeUsed()); - mpdfc->setQmin(0); - TS_ASSERT_EQUALS(OPTIMIZED, mpdfc->getEvaluatorTypeUsed()); - } - - - void test_DBPDF_qmax_click() - { - mpdfc->setEvaluatorType(OPTIMIZED); - mpdfc->eval(mstru10); - mpdfc->eval(mstru10); - TS_ASSERT_EQUALS(OPTIMIZED, mpdfc->getEvaluatorTypeUsed()); - mpdfc->setQmax(mpdfc->getQmax()); - mpdfc->eval(mstru10); - TS_ASSERT_EQUALS(OPTIMIZED, mpdfc->getEvaluatorTypeUsed()); - mpdfc->setQmax(mpdfc->getQmax() - 1.0); - mpdfc->eval(mstru10); - TS_ASSERT_EQUALS(BASIC, mpdfc->getEvaluatorTypeUsed()); - } - - - void test_DBPDF_delta12_click() - { - mpdfc->setEvaluatorType(OPTIMIZED); - mpdfc->eval(mstru10); - mpdfc->setDoubleAttr("delta1", mpdfc->getDoubleAttr("delta1")); - mpdfc->setDoubleAttr("delta2", mpdfc->getDoubleAttr("delta2")); - mpdfc->eval(mstru10); - TS_ASSERT_EQUALS(OPTIMIZED, mpdfc->getEvaluatorTypeUsed()); - mpdfc->setDoubleAttr("delta1", 0.5 + mpdfc->getDoubleAttr("delta1")); - mpdfc->eval(mstru10); - TS_ASSERT_EQUALS(BASIC, mpdfc->getEvaluatorTypeUsed()); - mpdfc->eval(mstru10); - mpdfc->setDoubleAttr("delta2", 0.5 + mpdfc->getDoubleAttr("delta2")); - mpdfc->eval(mstru10); - TS_ASSERT_EQUALS(BASIC, mpdfc->getEvaluatorTypeUsed()); - } - - - void test_DBPDF_SFTB_click() - { - mpdfc->setEvaluatorType(OPTIMIZED); - mpdfc->eval(mstru10); - mpdfc->setScatteringFactorTable(mpdfc->getScatteringFactorTable()); - mpdfc->eval(mstru10); - TS_ASSERT_EQUALS(OPTIMIZED, mpdfc->getEvaluatorTypeUsed()); - mpdfc->setScatteringFactorTableByType("neutron"); - mpdfc->eval(mstru10); - TS_ASSERT_EQUALS(BASIC, mpdfc->getEvaluatorTypeUsed()); - } - +class TestDebyePDFCalculator : public CxxTest::TestSuite { + private: + boost::shared_ptr mpdfc; + AtomicStructureAdapterPtr memptystru; + AtomicStructureAdapterPtr mstru10; + AtomicStructureAdapterPtr mstru10d1; + AtomicStructureAdapterPtr mstru10r; + AtomicStructureAdapterPtr mstru9; + diffpy::mathutils::EpsilonEqual allclose; + double meps; + + public: + void setUp() { + const int SZ = 10; + meps = diffpy::mathutils::SQRT_DOUBLE_EPS; + mpdfc.reset(new DebyePDFCalculator); + memptystru = boost::make_shared(); + mstru10 = boost::make_shared(); + Atom ai; + ai.atomtype = "C"; + ai.uij_cartn = R3::identity(); + ai.uij_cartn(0, 0) = ai.uij_cartn(1, 1) = ai.uij_cartn(2, 2) = 0.004; + for (int i = 0; i < SZ; ++i) { + ai.xyz_cartn[0] = i; + mstru10->append(ai); + } + mstru10d1 = boost::make_shared(*mstru10); + (*mstru10d1)[0].atomtype = "Au"; + mstru10r = boost::make_shared(); + mstru10r->assign(mstru10->rbegin(), mstru10->rend()); + mstru9 = boost::make_shared(*mstru10); + mstru9->erase(9); + } + + void test_setQmax() { + const double dq0 = mpdfc->getQstep(); + const double qmax0 = mpdfc->getQmax(); + const double qmax1 = 2 * dq0; + mpdfc->setQmax(qmax1); + TS_ASSERT_EQUALS(qmax1 / 4.0, mpdfc->getQstep()); + mpdfc->setQmax(qmax0); + TS_ASSERT_EQUALS(dq0, mpdfc->getQstep()); + } + + void test_setQstep() { + mpdfc->setRstep(2.0); + mpdfc->setQstep(0.02); + TS_ASSERT_EQUALS(0.02, mpdfc->getQstep()); + } + + void test_access_Envelopes() { + TS_ASSERT_EQUALS(2u, mpdfc->usedEnvelopeTypes().size()); + TS_ASSERT_EQUALS(1.0, mpdfc->getDoubleAttr("scale")); + TS_ASSERT_EQUALS(0.0, mpdfc->getDoubleAttr("qdamp")); + mpdfc->setDoubleAttr("scale", 3.0); + TS_ASSERT_EQUALS(3.0, mpdfc->getDoubleAttr("scale")); + mpdfc->addEnvelopeByType("scale"); + TS_ASSERT_EQUALS(1.0, mpdfc->getDoubleAttr("scale")); + QResolutionEnvelope qdamp4; + qdamp4.setQdamp(4); + mpdfc->addEnvelope(qdamp4.clone()); + TS_ASSERT_EQUALS(4.0, mpdfc->getDoubleAttr("qdamp")); + TS_ASSERT_THROWS(mpdfc->addEnvelopeByType("invalid"), logic_error); + } + + void test_getPDF() { + QuantityType pdf; + TS_ASSERT_EQUALS(1000u, mpdfc->getPDF().size()); + mpdfc->setRmin(2.0); + mpdfc->setRmax(0.0); + mpdfc->eval(memptystru); + pdf = mpdfc->getPDF(); + TS_ASSERT(mpdfc->getPDF().empty()); + mpdfc->setRmax(2.0); + mpdfc->eval(memptystru); + pdf = mpdfc->getPDF(); + TS_ASSERT(mpdfc->getPDF().empty()); + mpdfc->setRmax(2.01001); + mpdfc->eval(memptystru); + pdf = mpdfc->getPDF(); + TS_ASSERT_EQUALS(2u, pdf.size()); + } + + void test_getRDF() { + // getRDF is not yet implemented and just returns empty array. + QuantityType rdf = mpdfc->getRDF(); + TS_ASSERT_EQUALS(1000u, rdf.size()); + TS_ASSERT_EQUALS(0.0, *std::min_element(rdf.begin(), rdf.end())); + TS_ASSERT_EQUALS(0.0, *std::max_element(rdf.begin(), rdf.end())); + } + + void test_getF() { + QuantityType fq = mpdfc->getF(); + TS_ASSERT_EQUALS(92u, fq.size()); + TS_ASSERT_EQUALS(0.0, *min_element(fq.begin(), fq.end())); + TS_ASSERT_EQUALS(0.0, *max_element(fq.begin(), fq.end())); + } + + void test_getQgrid() { TS_ASSERT_EQUALS(92u, mpdfc->getQgrid().size()); } + + void test_getQmin() { + TS_ASSERT_EQUALS(0.0, mpdfc->getQmin()); + mpdfc->setQmin(1.0); + const DebyePDFCalculator& dpc = *mpdfc; + TS_ASSERT_EQUALS(1.0, dpc.getQmin()); + TS_ASSERT_EQUALS(0.0, dpc.BaseDebyeSum::getQmin()); + } + + void test_getQmax() { TS_ASSERT_DELTA(25.0, mpdfc->getQmax(), meps); } + + void test_getQstep() { + const double rcalchi = ceil((10.0 + 12 * M_PI / 25.0) / 0.01) * 0.01; + const double qstep = M_PI / rcalchi; + TS_ASSERT_DELTA(qstep, mpdfc->getQstep(), meps); + } + + void test_getRgrid() { + QuantityType rgrid0 = mpdfc->getRgrid(); + TS_ASSERT_EQUALS(rgrid0, mpdfc->getRgrid()); + mpdfc->setRmin(5); + mpdfc->setRmax(4); + TS_ASSERT(mpdfc->getRgrid().empty()); + } + + void test_serialization() { + // build customized DebyePDFCalculator + mpdfc->setPeakWidthModelByType("constant"); + mpdfc->setDoubleAttr("width", 0.123); + mpdfc->setDoubleAttr("debyeprecision", 0.00011); + mpdfc->setScatteringFactorTableByType("electronnumber"); + mpdfc->getScatteringFactorTable()->setCustomAs("H", "H", 1.1); + // dump it to string + stringstream storage(ios::in | ios::out | ios::binary); + diffpy::serialization::oarchive oa(storage, ios::binary); + oa << mpdfc; + diffpy::serialization::iarchive ia(storage, ios::binary); + boost::shared_ptr pdfc1; + ia >> pdfc1; + TS_ASSERT_DIFFERS(pdfc1.get(), mpdfc.get()); + TS_ASSERT_EQUALS(string("constant"), pdfc1->getPeakWidthModel()->type()); + TS_ASSERT_EQUALS(0.123, pdfc1->getDoubleAttr("width")); + TS_ASSERT_EQUALS(0.00011, pdfc1->getDoubleAttr("debyeprecision")); + TS_ASSERT_EQUALS(string("electronnumber"), + pdfc1->getScatteringFactorTable()->type()); + TS_ASSERT_EQUALS(1.1, pdfc1->getScatteringFactorTable()->lookup("H")); + } + + void test_DBPDF_change_atom() { + using std::placeholders::_1; + mpdfc->setQmin(1.0); + DebyePDFCalculator pdfcb = *mpdfc; + DebyePDFCalculator pdfco = *mpdfc; + TS_ASSERT_EQUALS(1.0, pdfcb.getQmin()); + pdfcb.setEvaluatorType(BASIC); + pdfco.setEvaluatorType(OPTIMIZED); + TS_ASSERT_EQUALS(NONE, pdfcb.getEvaluatorTypeUsed()); + TS_ASSERT_EQUALS(NONE, pdfco.getEvaluatorTypeUsed()); + pdfcb.eval(mstru10); + pdfco.eval(mstru10); + QuantityType gb = pdfcb.getPDF(); + QuantityType go = pdfco.getPDF(); + TS_ASSERT(!gb.empty()); + TS_ASSERT_EQUALS(gb, go); + int cnonzero = + count_if(gb.begin(), gb.end(), bind(not_equal_to(), _1, 0.0)); + TS_ASSERT(cnonzero); + TS_ASSERT_EQUALS(BASIC, pdfcb.getEvaluatorType()); + TS_ASSERT_EQUALS(OPTIMIZED, pdfco.getEvaluatorType()); + // first call of pdfco should use the BASIC evaluation + TS_ASSERT_EQUALS(BASIC, pdfcb.getEvaluatorTypeUsed()); + TS_ASSERT_EQUALS(BASIC, pdfco.getEvaluatorTypeUsed()); + // test second call on the same structure + pdfco.eval(mstru10); + go = pdfco.getPDF(); + TS_ASSERT_EQUALS(gb, go); + TS_ASSERT_EQUALS(OPTIMIZED, pdfco.getEvaluatorTypeUsed()); + // test structure with one different atom + pdfcb.eval(mstru10d1); + pdfco.eval(mstru10d1); + QuantityType gb1 = pdfcb.getPDF(); + QuantityType go1 = pdfco.getPDF(); + TS_ASSERT(!allclose(gb, gb1)); + TS_ASSERT_EQUALS(OPTIMIZED, pdfco.getEvaluatorTypeUsed()); + TS_ASSERT(allclose(gb1, go1)); + // change position of 1 atom + mstru10d1->at(0).xyz_cartn[1] = 0.5; + pdfcb.eval(mstru10d1); + pdfco.eval(mstru10d1); + QuantityType gb2 = pdfcb.getPDF(); + QuantityType go2 = pdfco.getPDF(); + TS_ASSERT(!allclose(gb1, gb2)); + TS_ASSERT_EQUALS(OPTIMIZED, pdfco.getEvaluatorTypeUsed()); + TS_ASSERT(allclose(gb2, go2)); + } + + void test_DBPDF_reverse_atoms() { + mpdfc->setQmin(1.1); + DebyePDFCalculator pdfcb = *mpdfc; + DebyePDFCalculator pdfco = *mpdfc; + pdfcb.setEvaluatorType(BASIC); + pdfco.setEvaluatorType(OPTIMIZED); + pdfcb.eval(mstru10); + pdfco.eval(mstru10); + pdfco.eval(mstru10r); + QuantityType gb = pdfcb.getPDF(); + QuantityType go = pdfco.getPDF(); + TS_ASSERT_EQUALS(OPTIMIZED, pdfco.getEvaluatorTypeUsed()); + TS_ASSERT(allclose(gb, go)); + } + + void test_DBPDF_remove_atom() { + mpdfc->setQmin(1.2); + DebyePDFCalculator pdfcb = *mpdfc; + DebyePDFCalculator pdfco = *mpdfc; + pdfcb.setEvaluatorType(BASIC); + pdfco.setEvaluatorType(OPTIMIZED); + pdfcb.eval(mstru9); + pdfco.eval(mstru10); + pdfco.eval(mstru9); + QuantityType gb = pdfcb.getPDF(); + QuantityType go = pdfco.getPDF(); + TS_ASSERT_EQUALS(OPTIMIZED, pdfco.getEvaluatorTypeUsed()); + TS_ASSERT(allclose(gb, go)); + } + + void test_DBPDF_qmin_click() { + mpdfc->setEvaluatorType(OPTIMIZED); + TS_ASSERT_EQUALS(NONE, mpdfc->getEvaluatorTypeUsed()); + mpdfc->eval(mstru10); + mpdfc->eval(mstru10); + TS_ASSERT_EQUALS(OPTIMIZED, mpdfc->getEvaluatorTypeUsed()); + mpdfc->setQmin(4); + mpdfc->eval(mstru10); + TS_ASSERT_EQUALS(OPTIMIZED, mpdfc->getEvaluatorTypeUsed()); + mpdfc->setQmin(0); + TS_ASSERT_EQUALS(OPTIMIZED, mpdfc->getEvaluatorTypeUsed()); + } + + void test_DBPDF_qmax_click() { + mpdfc->setEvaluatorType(OPTIMIZED); + mpdfc->eval(mstru10); + mpdfc->eval(mstru10); + TS_ASSERT_EQUALS(OPTIMIZED, mpdfc->getEvaluatorTypeUsed()); + mpdfc->setQmax(mpdfc->getQmax()); + mpdfc->eval(mstru10); + TS_ASSERT_EQUALS(OPTIMIZED, mpdfc->getEvaluatorTypeUsed()); + mpdfc->setQmax(mpdfc->getQmax() - 1.0); + mpdfc->eval(mstru10); + TS_ASSERT_EQUALS(BASIC, mpdfc->getEvaluatorTypeUsed()); + } + + void test_DBPDF_delta12_click() { + mpdfc->setEvaluatorType(OPTIMIZED); + mpdfc->eval(mstru10); + mpdfc->setDoubleAttr("delta1", mpdfc->getDoubleAttr("delta1")); + mpdfc->setDoubleAttr("delta2", mpdfc->getDoubleAttr("delta2")); + mpdfc->eval(mstru10); + TS_ASSERT_EQUALS(OPTIMIZED, mpdfc->getEvaluatorTypeUsed()); + mpdfc->setDoubleAttr("delta1", 0.5 + mpdfc->getDoubleAttr("delta1")); + mpdfc->eval(mstru10); + TS_ASSERT_EQUALS(BASIC, mpdfc->getEvaluatorTypeUsed()); + mpdfc->eval(mstru10); + mpdfc->setDoubleAttr("delta2", 0.5 + mpdfc->getDoubleAttr("delta2")); + mpdfc->eval(mstru10); + TS_ASSERT_EQUALS(BASIC, mpdfc->getEvaluatorTypeUsed()); + } + + void test_DBPDF_SFTB_click() { + mpdfc->setEvaluatorType(OPTIMIZED); + mpdfc->eval(mstru10); + mpdfc->setScatteringFactorTable(mpdfc->getScatteringFactorTable()); + mpdfc->eval(mstru10); + TS_ASSERT_EQUALS(OPTIMIZED, mpdfc->getEvaluatorTypeUsed()); + mpdfc->setScatteringFactorTableByType("neutron"); + mpdfc->eval(mstru10); + TS_ASSERT_EQUALS(BASIC, mpdfc->getEvaluatorTypeUsed()); + } }; // class TestDebyePDFCalculator diff --git a/src/tests/TestEmptyStructureAdapter.hpp b/src/tests/TestEmptyStructureAdapter.hpp index d002a229..7ce5ba37 100644 --- a/src/tests/TestEmptyStructureAdapter.hpp +++ b/src/tests/TestEmptyStructureAdapter.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy 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. -* -****************************************************************************** -* -* class TestEmptyStructureAdapter -- test adapter that is always empty -* -*****************************************************************************/ + * + * libdiffpy 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. + * + ****************************************************************************** + * + * class TestEmptyStructureAdapter -- test adapter that is always empty + * + *****************************************************************************/ #include @@ -30,52 +30,40 @@ using namespace std; // class TestEmptyStructureAdapter ////////////////////////////////////////////////////////////////////////////// -class TestEmptyStructureAdapter : public CxxTest::TestSuite -{ - private: - - StructureAdapterPtr mstru; - - public: - - void setUp() - { - mstru = emptyStructureAdapter(); - } - - - void test_empty_instance() - { - TS_ASSERT_EQUALS(0, mstru->countSites()); - TS_ASSERT_EQUALS(mstru.get(), mstru->clone().get()); - TS_ASSERT_EQUALS(mstru, emptyStructureAdapter()); - TS_ASSERT_THROWS(mstru->siteAtomType(0), std::out_of_range); - TS_ASSERT_THROWS(mstru->siteCartesianPosition(0), - std::out_of_range); - TS_ASSERT_THROWS(mstru->siteMultiplicity(0), std::out_of_range); - TS_ASSERT_THROWS(mstru->siteOccupancy(0), std::out_of_range); - TS_ASSERT_THROWS(mstru->siteAnisotropy(0), std::out_of_range); - TS_ASSERT_THROWS(mstru->siteCartesianPosition(0), - std::out_of_range); - } - - - void test_serialization() - { - StructureAdapterPtr stru1; - stru1 = dumpandload(mstru); - AtomicStructureAdapterPtr astru1 = - boost::dynamic_pointer_cast(stru1); - TS_ASSERT(!astru1); - TS_ASSERT_EQUALS(0, stru1->countSites()); - TS_ASSERT_EQUALS(stru1, stru1->clone()); - TS_ASSERT_THROWS(mstru->siteAtomType(0), std::out_of_range); - } +class TestEmptyStructureAdapter : public CxxTest::TestSuite { + private: + StructureAdapterPtr mstru; + + public: + void setUp() { mstru = emptyStructureAdapter(); } + + void test_empty_instance() { + TS_ASSERT_EQUALS(0, mstru->countSites()); + TS_ASSERT_EQUALS(mstru.get(), mstru->clone().get()); + TS_ASSERT_EQUALS(mstru, emptyStructureAdapter()); + TS_ASSERT_THROWS(mstru->siteAtomType(0), std::out_of_range); + TS_ASSERT_THROWS(mstru->siteCartesianPosition(0), std::out_of_range); + TS_ASSERT_THROWS(mstru->siteMultiplicity(0), std::out_of_range); + TS_ASSERT_THROWS(mstru->siteOccupancy(0), std::out_of_range); + TS_ASSERT_THROWS(mstru->siteAnisotropy(0), std::out_of_range); + TS_ASSERT_THROWS(mstru->siteCartesianPosition(0), std::out_of_range); + } + + void test_serialization() { + StructureAdapterPtr stru1; + stru1 = dumpandload(mstru); + AtomicStructureAdapterPtr astru1 = + boost::dynamic_pointer_cast(stru1); + TS_ASSERT(!astru1); + TS_ASSERT_EQUALS(0, stru1->countSites()); + TS_ASSERT_EQUALS(stru1, stru1->clone()); + TS_ASSERT_THROWS(mstru->siteAtomType(0), std::out_of_range); + } }; // class TestEmptyStructureAdapter -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy using diffpy::srreal::TestEmptyStructureAdapter; diff --git a/src/tests/TestHasClassRegistry.hpp b/src/tests/TestHasClassRegistry.hpp index 8f325a0e..346c9e16 100644 --- a/src/tests/TestHasClassRegistry.hpp +++ b/src/tests/TestHasClassRegistry.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy 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. -* -****************************************************************************** -* -* class TestHasClassRegistry -- test registration machinery for named classes. -* -*****************************************************************************/ + * + * libdiffpy 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. + * + ****************************************************************************** + * + * class TestHasClassRegistry -- test registration machinery for named classes. + * + *****************************************************************************/ #include @@ -27,60 +27,47 @@ using diffpy::srreal::ScatteringFactorTablePtr; // class TestHasClassRegistry ////////////////////////////////////////////////////////////////////////////// -class TestHasClassRegistry : public CxxTest::TestSuite -{ - private: - - typedef diffpy::HasClassRegistry HCRBase; - ScatteringFactorTablePtr msftb; - HCRBase* mpreg; - - public: - - void setUp() - { - msftb = ScatteringFactorTable::createByType("xray"); - mpreg = msftb.get(); - } - - void tearDown() - { - // restore SFTXray registration if removed in some test. - msftb->deregisterType(msftb->type()); - msftb->registerThisType(); - TS_ASSERT(ScatteringFactorTable::isRegisteredType("X")); - TS_ASSERT(ScatteringFactorTable::isRegisteredType("xray")); - } - - - void test_deregisterType() - { - TS_ASSERT_EQUALS(0, - ScatteringFactorTable::deregisterType("invalid")); - TS_ASSERT_EQUALS(2, - ScatteringFactorTable::deregisterType("X")); - TS_ASSERT(!(mpreg->isRegisteredType("xray"))); - TS_ASSERT(!(mpreg->isRegisteredType("X"))); - } - - - void test_isRegisteredType() - { - TS_ASSERT(msftb->isRegisteredType("xray")); - TS_ASSERT(ScatteringFactorTable::isRegisteredType("X")); - TS_ASSERT_EQUALS(false, mpreg->isRegisteredType("invalid")); - } - - - void test_getAliasedTypes() - { - std::map atps; - atps = ScatteringFactorTable::getAliasedTypes(); - TS_ASSERT_EQUALS(4, atps.size()); - TS_ASSERT(atps.count("X")); - TS_ASSERT_EQUALS("xray", atps["X"]); - TS_ASSERT_EQUALS("electronnumber", atps["EN"]); - } +class TestHasClassRegistry : public CxxTest::TestSuite { + private: + typedef diffpy::HasClassRegistry HCRBase; + ScatteringFactorTablePtr msftb; + HCRBase* mpreg; + + public: + void setUp() { + msftb = ScatteringFactorTable::createByType("xray"); + mpreg = msftb.get(); + } + + void tearDown() { + // restore SFTXray registration if removed in some test. + msftb->deregisterType(msftb->type()); + msftb->registerThisType(); + TS_ASSERT(ScatteringFactorTable::isRegisteredType("X")); + TS_ASSERT(ScatteringFactorTable::isRegisteredType("xray")); + } + + void test_deregisterType() { + TS_ASSERT_EQUALS(0, ScatteringFactorTable::deregisterType("invalid")); + TS_ASSERT_EQUALS(2, ScatteringFactorTable::deregisterType("X")); + TS_ASSERT(!(mpreg->isRegisteredType("xray"))); + TS_ASSERT(!(mpreg->isRegisteredType("X"))); + } + + void test_isRegisteredType() { + TS_ASSERT(msftb->isRegisteredType("xray")); + TS_ASSERT(ScatteringFactorTable::isRegisteredType("X")); + TS_ASSERT_EQUALS(false, mpreg->isRegisteredType("invalid")); + } + + void test_getAliasedTypes() { + std::map atps; + atps = ScatteringFactorTable::getAliasedTypes(); + TS_ASSERT_EQUALS(4, atps.size()); + TS_ASSERT(atps.count("X")); + TS_ASSERT_EQUALS("xray", atps["X"]); + TS_ASSERT_EQUALS("electronnumber", atps["EN"]); + } }; // class TestHasClassRegistry diff --git a/src/tests/TestLattice.hpp b/src/tests/TestLattice.hpp index 5752aa2f..48d6fa5c 100644 --- a/src/tests/TestLattice.hpp +++ b/src/tests/TestLattice.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class TestLattice -- unit tests for the Lattice class -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class TestLattice -- unit tests for the Lattice class + * + *****************************************************************************/ #include @@ -25,151 +25,124 @@ using namespace std; using namespace diffpy::srreal; using diffpy::mathutils::EpsilonEqual; -class TestLattice : public CxxTest::TestSuite -{ - -private: - - Lattice* lattice; - double precision; - EpsilonEqual allclose; - -public: - - void setUp() - { - lattice = new Lattice(); - precision = 1.0e-8; - allclose = EpsilonEqual(precision); - } - - void tearDown() - { - delete lattice; - } - - void test_Lattice() - { - // default lattice should be cartesian - TS_ASSERT(allclose(lattice->base(), R3::identity())); - // lattice parameters constructor - Lattice lattice1(1.0, 2.0, 3.0, 90, 90, 120); - R3::Vector va = lattice1.va(); - R3::Vector vb = lattice1.vb(); - R3::Vector vc = lattice1.vc(); - double adotb = R3::dot(va, vb); - double adotc = R3::dot(va, vc); - double bdotc = R3::dot(vb, vc); - TS_ASSERT_DELTA(1.0, R3::norm(va), precision); - TS_ASSERT_DELTA(2.0, R3::norm(vb), precision); - TS_ASSERT_DELTA(3.0, R3::norm(vc), precision); - TS_ASSERT_DELTA(-0.5*1.0*2.0, adotb, precision); - TS_ASSERT_DELTA(0.0, adotc, precision); - TS_ASSERT_DELTA(0.0, bdotc, precision); - TS_ASSERT_DELTA(sqrt(4.0/3), lattice1.ar(), precision); - TS_ASSERT_DELTA(sqrt(1.0/3), lattice1.br(), precision); - TS_ASSERT_DELTA(1.0/3, lattice1.cr(), precision); - TS_ASSERT_DELTA(90.0, lattice1.alphar(), precision); - TS_ASSERT_DELTA(90.0, lattice1.betar(), precision); - TS_ASSERT_DELTA(60.0, lattice1.gammar(), precision); - // lattice vectors constructor - va = R3::Vector(1.0, 1.0, 0.0); - vb = R3::Vector(0.0, 1.0, 1.0); - vc = R3::Vector(1.0, 0.0, 1.0); - Lattice lattice2(va, vb, vc); - TS_ASSERT_DELTA(sqrt(2.0), lattice2.a(), precision); - TS_ASSERT_DELTA(60.0, lattice2.alpha(), precision); - } - - void test_setLatPar() - { - lattice->setLatPar(1.0, 2.0, 3.0, 90, 90, 120); - R3::Matrix base_check( - sqrt(0.75), -0.5, 0.0, - 0.0, +2.0, 0.0, - 0.0, +0.0, 3.0); - TS_ASSERT(allclose(base_check, lattice->base())); - R3::Matrix recbase_check( - sqrt(4.0/3), sqrt(1.0/12), 0.0, - 0.0, 0.5, 0.0, - 0.0, 0.0, 1.0/3.0); - TS_ASSERT(allclose(recbase_check, lattice->recbase())); - } - - void test_setLatBase() - { - R3::Vector va(1.0, 1.0, 0.0); - R3::Vector vb(0.0, 1.0, 1.0); - R3::Vector vc(1.0, 0.0, 1.0); - lattice->setLatBase(va, vb, vc); - TS_ASSERT_DELTA(sqrt(2.0), lattice->a(), precision); - TS_ASSERT_DELTA(sqrt(2.0), lattice->b(), precision); - TS_ASSERT_DELTA(sqrt(2.0), lattice->c(), precision); - TS_ASSERT_DELTA(60.0, lattice->alpha(), precision); - TS_ASSERT_DELTA(60.0, lattice->beta(), precision); - TS_ASSERT_DELTA(60.0, lattice->gamma(), precision); - // check determinant of rotation matrix - double detRot0 = R3::determinant(lattice->baserot()); - TS_ASSERT_DELTA(1.0, detRot0, precision); - // check if rotation matrix works - R3::Matrix base_check( - va[0], va[1], va[2], - vb[0], vb[1], vb[2], - vc[0], vc[1], vc[2]); - TS_ASSERT(allclose(base_check, lattice->base())); - R3::Matrix recbase_check( - 0.5, -0.5, 0.5, - 0.5, 0.5, -0.5, - -0.5, 0.5, 0.5); - TS_ASSERT(allclose(recbase_check, lattice->recbase())); - lattice->setLatPar( lattice->a(), lattice->b(), lattice->c(), - 44.0, 66.0, 88.0 ); - TS_ASSERT(!allclose(base_check, lattice->base())); - TS_ASSERT(!allclose(recbase_check, lattice->recbase())); - lattice->setLatPar( lattice->a(), lattice->b(), lattice->c(), - 60.0, 60.0, 60.0 ); - TS_ASSERT(allclose(base_check, lattice->base())); - TS_ASSERT(allclose(recbase_check, lattice->recbase())); - } - - void test_dist() - { - R3::Vector va(1.0, 2.0, 2.0); - R3::Vector vb(0.0, 0.0, 0.0); - TS_ASSERT_DELTA(3.0, - lattice->distance(va, vb), precision); - lattice->setLatPar(2.0, 2.0, 2.0, 90.0, 90.0, 90.0); - TS_ASSERT_DELTA(6.0, - lattice->distance(va, vb), precision); - } - - void test_angle() - { - R3::Vector va(1.0, 0.0, 0.0); - R3::Vector vb(0.0, 1.0, 0.0); - TS_ASSERT_DELTA(90.0, - lattice->angledeg(va, vb), precision); - lattice->setLatPar(2.0, 2.0, 2.0, 90.0, 90.0, 120.0); - TS_ASSERT_DELTA(120.0, - lattice->angledeg(va, vb), precision); - } - - void test_ucvCartesian() - { - R3::Vector ucv; - ucv = lattice->ucvCartesian(R3::Vector(0.1, 0.2, 0.3)); - R3::Vector ucv_check(0.1, 0.2, 0.3); - TS_ASSERT(allclose(ucv_check, ucv)); - ucv = lattice->ucvCartesian(R3::Vector(1.1, 13.2, -0.7)); - TS_ASSERT(allclose(ucv_check, ucv)); - ucv = lattice->ucvCartesian(R3::Vector(0.5, 0.5, 0.5)); - ucv_check = R3::Vector(0.5, 0.5, 0.5); - TS_ASSERT(allclose(ucv_check, ucv)); - lattice->setLatPar(13, 17, 19, 37, 41, 47); - ucv = lattice->ucvCartesian(R3::Vector(100.0, 100.0, 100.0)); - ucv_check = R3::Vector(8.09338442077, 9.55056747225, 30.0389043325); - TS_ASSERT(allclose(ucv_check, ucv)); - } +class TestLattice : public CxxTest::TestSuite { + private: + Lattice* lattice; + double precision; + EpsilonEqual allclose; + + public: + void setUp() { + lattice = new Lattice(); + precision = 1.0e-8; + allclose = EpsilonEqual(precision); + } + + void tearDown() { delete lattice; } + + void test_Lattice() { + // default lattice should be cartesian + TS_ASSERT(allclose(lattice->base(), R3::identity())); + // lattice parameters constructor + Lattice lattice1(1.0, 2.0, 3.0, 90, 90, 120); + R3::Vector va = lattice1.va(); + R3::Vector vb = lattice1.vb(); + R3::Vector vc = lattice1.vc(); + double adotb = R3::dot(va, vb); + double adotc = R3::dot(va, vc); + double bdotc = R3::dot(vb, vc); + TS_ASSERT_DELTA(1.0, R3::norm(va), precision); + TS_ASSERT_DELTA(2.0, R3::norm(vb), precision); + TS_ASSERT_DELTA(3.0, R3::norm(vc), precision); + TS_ASSERT_DELTA(-0.5 * 1.0 * 2.0, adotb, precision); + TS_ASSERT_DELTA(0.0, adotc, precision); + TS_ASSERT_DELTA(0.0, bdotc, precision); + TS_ASSERT_DELTA(sqrt(4.0 / 3), lattice1.ar(), precision); + TS_ASSERT_DELTA(sqrt(1.0 / 3), lattice1.br(), precision); + TS_ASSERT_DELTA(1.0 / 3, lattice1.cr(), precision); + TS_ASSERT_DELTA(90.0, lattice1.alphar(), precision); + TS_ASSERT_DELTA(90.0, lattice1.betar(), precision); + TS_ASSERT_DELTA(60.0, lattice1.gammar(), precision); + // lattice vectors constructor + va = R3::Vector(1.0, 1.0, 0.0); + vb = R3::Vector(0.0, 1.0, 1.0); + vc = R3::Vector(1.0, 0.0, 1.0); + Lattice lattice2(va, vb, vc); + TS_ASSERT_DELTA(sqrt(2.0), lattice2.a(), precision); + TS_ASSERT_DELTA(60.0, lattice2.alpha(), precision); + } + + void test_setLatPar() { + lattice->setLatPar(1.0, 2.0, 3.0, 90, 90, 120); + R3::Matrix base_check(sqrt(0.75), -0.5, 0.0, 0.0, +2.0, 0.0, 0.0, +0.0, + 3.0); + TS_ASSERT(allclose(base_check, lattice->base())); + R3::Matrix recbase_check(sqrt(4.0 / 3), sqrt(1.0 / 12), 0.0, 0.0, 0.5, 0.0, + 0.0, 0.0, 1.0 / 3.0); + TS_ASSERT(allclose(recbase_check, lattice->recbase())); + } + + void test_setLatBase() { + R3::Vector va(1.0, 1.0, 0.0); + R3::Vector vb(0.0, 1.0, 1.0); + R3::Vector vc(1.0, 0.0, 1.0); + lattice->setLatBase(va, vb, vc); + TS_ASSERT_DELTA(sqrt(2.0), lattice->a(), precision); + TS_ASSERT_DELTA(sqrt(2.0), lattice->b(), precision); + TS_ASSERT_DELTA(sqrt(2.0), lattice->c(), precision); + TS_ASSERT_DELTA(60.0, lattice->alpha(), precision); + TS_ASSERT_DELTA(60.0, lattice->beta(), precision); + TS_ASSERT_DELTA(60.0, lattice->gamma(), precision); + // check determinant of rotation matrix + double detRot0 = R3::determinant(lattice->baserot()); + TS_ASSERT_DELTA(1.0, detRot0, precision); + // check if rotation matrix works + R3::Matrix base_check(va[0], va[1], va[2], vb[0], vb[1], vb[2], vc[0], + vc[1], vc[2]); + TS_ASSERT(allclose(base_check, lattice->base())); + R3::Matrix recbase_check(0.5, -0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5); + TS_ASSERT(allclose(recbase_check, lattice->recbase())); + lattice->setLatPar(lattice->a(), lattice->b(), lattice->c(), 44.0, 66.0, + 88.0); + TS_ASSERT(!allclose(base_check, lattice->base())); + TS_ASSERT(!allclose(recbase_check, lattice->recbase())); + lattice->setLatPar(lattice->a(), lattice->b(), lattice->c(), 60.0, 60.0, + 60.0); + TS_ASSERT(allclose(base_check, lattice->base())); + TS_ASSERT(allclose(recbase_check, lattice->recbase())); + } + + void test_dist() { + R3::Vector va(1.0, 2.0, 2.0); + R3::Vector vb(0.0, 0.0, 0.0); + TS_ASSERT_DELTA(3.0, lattice->distance(va, vb), precision); + lattice->setLatPar(2.0, 2.0, 2.0, 90.0, 90.0, 90.0); + TS_ASSERT_DELTA(6.0, lattice->distance(va, vb), precision); + } + + void test_angle() { + R3::Vector va(1.0, 0.0, 0.0); + R3::Vector vb(0.0, 1.0, 0.0); + TS_ASSERT_DELTA(90.0, lattice->angledeg(va, vb), precision); + lattice->setLatPar(2.0, 2.0, 2.0, 90.0, 90.0, 120.0); + TS_ASSERT_DELTA(120.0, lattice->angledeg(va, vb), precision); + } + + void test_ucvCartesian() { + R3::Vector ucv; + ucv = lattice->ucvCartesian(R3::Vector(0.1, 0.2, 0.3)); + R3::Vector ucv_check(0.1, 0.2, 0.3); + TS_ASSERT(allclose(ucv_check, ucv)); + ucv = lattice->ucvCartesian(R3::Vector(1.1, 13.2, -0.7)); + TS_ASSERT(allclose(ucv_check, ucv)); + ucv = lattice->ucvCartesian(R3::Vector(0.5, 0.5, 0.5)); + ucv_check = R3::Vector(0.5, 0.5, 0.5); + TS_ASSERT(allclose(ucv_check, ucv)); + lattice->setLatPar(13, 17, 19, 37, 41, 47); + ucv = lattice->ucvCartesian(R3::Vector(100.0, 100.0, 100.0)); + ucv_check = R3::Vector(8.09338442077, 9.55056747225, 30.0389043325); + TS_ASSERT(allclose(ucv_check, ucv)); + } }; // class TestLattice diff --git a/src/tests/TestNoMetaStructureAdapter.hpp b/src/tests/TestNoMetaStructureAdapter.hpp index 09194799..4fa84399 100644 --- a/src/tests/TestNoMetaStructureAdapter.hpp +++ b/src/tests/TestNoMetaStructureAdapter.hpp @@ -1,21 +1,21 @@ /***************************************************************************** -* -* libdiffpy 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. -* -****************************************************************************** -* -* class TestNoMetaStructureAdapter -- unit tests for an adapter that -* avoids metadata forwarding from the diffpy.Structure classes. -* -*****************************************************************************/ + * + * libdiffpy 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. + * + ****************************************************************************** + * + * class TestNoMetaStructureAdapter -- unit tests for an adapter that + * avoids metadata forwarding from the diffpy.Structure classes. + * + *****************************************************************************/ #include #include @@ -35,78 +35,65 @@ using namespace diffpy::srreal; // class TestNoMetaStructureAdapter ////////////////////////////////////////////////////////////////////////////// -class TestNoMetaStructureAdapter : public CxxTest::TestSuite -{ - private: - - StructureAdapterPtr m_pswt; - - public: - - void setUp() - { - CxxTest::setAbortTestOnFail(true); - if (!m_pswt) - { - StructureAdapterPtr pswt; - pswt = loadTestPeriodicStructure("PbScW25TiO3.stru"); - PeriodicAdapterWithPQConfigPtr pswt_pqcfg; - pswt_pqcfg = addCustomPQConfig(pswt); - pswt_pqcfg->cfg["scale"] = 2.5; - m_pswt = pswt_pqcfg; - } - CxxTest::setAbortTestOnFail(false); - } - - - void test_PDFCalcMeta() - { - PDFCalculator pdfc; - pdfc.setRstep(0.1); - pdfc.setRmax(5.0); - TS_ASSERT_EQUALS(1.0, pdfc.getDoubleAttr("scale")); - pdfc.eval(m_pswt); - TS_ASSERT_EQUALS(2.5, pdfc.getDoubleAttr("scale")); - } - - - void test_PDFCalcNoMeta() - { - PDFCalculator pdfc; - pdfc.setRstep(0.1); - pdfc.setRmax(5.0); - TS_ASSERT_EQUALS(1.0, pdfc.getDoubleAttr("scale")); - pdfc.eval(nometa(m_pswt)); - TS_ASSERT_EQUALS(1.0, pdfc.getDoubleAttr("scale")); - } - - - void test_NoMetaTwice() - { - StructureAdapterPtr adpt0 = nometa(m_pswt); - StructureAdapterPtr adpt1 = nometa(adpt0); - TS_ASSERT_EQUALS(adpt0, adpt1); - } - - - void test_serialization() - { - using namespace diffpy::serialization; - stringstream storage(ios::in | ios::out | ios::binary); - oarchive oa(storage, ios::binary); - StructureAdapterPtr pswtbare0(nometa(m_pswt)); - oa << pswtbare0; - iarchive ia(storage, ios::binary); - StructureAdapterPtr pswtbare1; - TS_ASSERT(!pswtbare1.get()); - ia >> pswtbare1; - TS_ASSERT_DIFFERS(m_pswt.get(), pswtbare1.get()); - TS_ASSERT_EQUALS(56, pswtbare1->countSites()); - TS_ASSERT_EQUALS(string("Pb"), pswtbare1->siteAtomType(0)); - TS_ASSERT_EQUALS(string("Ti"), pswtbare1->siteAtomType(55)); - StructureAdapter& r_pswtbare1 = *pswtbare1; - TS_ASSERT(typeid(NoMetaStructureAdapter) == typeid(r_pswtbare1)); - } +class TestNoMetaStructureAdapter : public CxxTest::TestSuite { + private: + StructureAdapterPtr m_pswt; + + public: + void setUp() { + CxxTest::setAbortTestOnFail(true); + if (!m_pswt) { + StructureAdapterPtr pswt; + pswt = loadTestPeriodicStructure("PbScW25TiO3.stru"); + PeriodicAdapterWithPQConfigPtr pswt_pqcfg; + pswt_pqcfg = addCustomPQConfig(pswt); + pswt_pqcfg->cfg["scale"] = 2.5; + m_pswt = pswt_pqcfg; + } + CxxTest::setAbortTestOnFail(false); + } + + void test_PDFCalcMeta() { + PDFCalculator pdfc; + pdfc.setRstep(0.1); + pdfc.setRmax(5.0); + TS_ASSERT_EQUALS(1.0, pdfc.getDoubleAttr("scale")); + pdfc.eval(m_pswt); + TS_ASSERT_EQUALS(2.5, pdfc.getDoubleAttr("scale")); + } + + void test_PDFCalcNoMeta() { + PDFCalculator pdfc; + pdfc.setRstep(0.1); + pdfc.setRmax(5.0); + TS_ASSERT_EQUALS(1.0, pdfc.getDoubleAttr("scale")); + pdfc.eval(nometa(m_pswt)); + TS_ASSERT_EQUALS(1.0, pdfc.getDoubleAttr("scale")); + } + + void test_NoMetaTwice() { + StructureAdapterPtr adpt0 = nometa(m_pswt); + StructureAdapterPtr adpt1 = nometa(adpt0); + TS_ASSERT_EQUALS(adpt0, adpt1); + } + + void test_serialization() { + using namespace diffpy::serialization; + stringstream storage(ios::in | ios::out | ios::binary); + oarchive oa(storage, ios::binary); + StructureAdapterPtr pswtbare0(nometa(m_pswt)); + oa << pswtbare0; + iarchive ia(storage, ios::binary); + StructureAdapterPtr pswtbare1; + TS_ASSERT(!pswtbare1.get()); + ia >> pswtbare1; + TS_ASSERT_DIFFERS(m_pswt.get(), pswtbare1.get()); + TS_ASSERT_EQUALS(56, pswtbare1->countSites()); + TS_ASSERT_EQUALS(string("Pb"), pswtbare1->siteAtomType(0)); + TS_ASSERT_EQUALS(string("Ti"), pswtbare1->siteAtomType(55)); + StructureAdapter& r_pswtbare1 = *pswtbare1; + TS_ASSERT(typeid(NoMetaStructureAdapter) == typeid(r_pswtbare1)); + } }; // class TestNoMetaStructureAdapter diff --git a/src/tests/TestObjCrystStructureAdapter.hpp b/src/tests/TestObjCrystStructureAdapter.hpp index b3320d8c..c1153572 100644 --- a/src/tests/TestObjCrystStructureAdapter.hpp +++ b/src/tests/TestObjCrystStructureAdapter.hpp @@ -1,23 +1,23 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class TestObjCrystStructureAdapter -- unit tests for an adapter -* to the ObjCryst::Crystal class -* -* class TestObjCrystStructureBondGenerator -- unit tests for bond generator -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class TestObjCrystStructureAdapter -- unit tests for an adapter + * to the ObjCryst::Crystal class + * + * class TestObjCrystStructureBondGenerator -- unit tests for bond generator + * + *****************************************************************************/ #include #include @@ -41,268 +41,227 @@ using ObjCryst::ScatteringPowerAtom; namespace { -int countBonds(diffpy::srreal::BaseBondGenerator& bnds) -{ - int rv = 0; - for (bnds.rewind(); !bnds.finished(); bnds.next()) ++rv; - return rv; +int countBonds(diffpy::srreal::BaseBondGenerator& bnds) { + int rv = 0; + for (bnds.rewind(); !bnds.finished(); bnds.next()) ++rv; + return rv; } - template -double testmsd0(const Tstru& stru, const Tbnds& bnds) -{ - bool anisotropy0 = stru->siteAnisotropy(bnds->site0()); - double rv = meanSquareDisplacement( - bnds->Ucartesian0(), bnds->r01(), anisotropy0); - return rv; +double testmsd0(const Tstru& stru, const Tbnds& bnds) { + bool anisotropy0 = stru->siteAnisotropy(bnds->site0()); + double rv = + meanSquareDisplacement(bnds->Ucartesian0(), bnds->r01(), anisotropy0); + return rv; } - template -double testmsd1(const Tstru& stru, const Tbnds& bnds) -{ - bool anisotropy1 = stru->siteAnisotropy(bnds->site1()); - double rv = meanSquareDisplacement( - bnds->Ucartesian1(), bnds->r01(), anisotropy1); - return rv; +double testmsd1(const Tstru& stru, const Tbnds& bnds) { + bool anisotropy1 = stru->siteAnisotropy(bnds->site1()); + double rv = + meanSquareDisplacement(bnds->Ucartesian1(), bnds->r01(), anisotropy1); + return rv; } - -double diffdegree(StructureAdapterPtr stru0, StructureAdapterPtr stru1) -{ - StructureDifference sd = stru0->diff(stru1); - double tot = 0.0; - if (stru0) tot += stru0->countSites(); - if (stru1) tot += stru1->countSites(); - double rv = (sd.pop0.size() + sd.add1.size()) / (tot ? tot : 1.0); - return rv; +double diffdegree(StructureAdapterPtr stru0, StructureAdapterPtr stru1) { + StructureDifference sd = stru0->diff(stru1); + double tot = 0.0; + if (stru0) tot += stru0->countSites(); + if (stru1) tot += stru1->countSites(); + double rv = (sd.pop0.size() + sd.add1.size()) / (tot ? tot : 1.0); + return rv; } // Defined below Molecule* makeC60Molecule(); -} // namespace +} // namespace ////////////////////////////////////////////////////////////////////////////// // class TestObjCrystStructureAdapter ////////////////////////////////////////////////////////////////////////////// -class TestObjCrystStructureAdapter : public CxxTest::TestSuite -{ - private: - - unique_ptr mcryst_ni; - StructureAdapterPtr m_ni; - unique_ptr mcryst_kbise; - StructureAdapterPtr m_kbise; - unique_ptr mcryst_catio3; - StructureAdapterPtr m_catio3; - - public: - - void setUp() - { - if (!m_ni.get()) - { - mcryst_ni.reset(loadTestCrystal("Ni.cif")); - m_ni = createStructureAdapter(*mcryst_ni); - } - if (!m_kbise.get()) - { - mcryst_kbise.reset(loadTestCrystal("alpha_K2Bi8Se13.cif")); - m_kbise = createStructureAdapter(*mcryst_kbise); - } - if (!m_catio3.get()) - { - mcryst_catio3.reset(loadTestCrystal("CaTiO3.cif")); - m_catio3 = createStructureAdapter(*mcryst_catio3); - } - } - - - void test_typeid() - { - StructureAdapter& r_ni = *m_ni; - TS_ASSERT(typeid(CrystalStructureAdapter) == typeid(r_ni)); - } - - - void test_countSites() - { - TS_ASSERT_EQUALS(1, m_ni->countSites()); - TS_ASSERT_EQUALS(12, m_kbise->countSites()); - TS_ASSERT_EQUALS(4, m_catio3->countSites()); - } - - - void test_totalOccupancy() - { - TS_ASSERT_EQUALS(4.0, m_ni->totalOccupancy()); - TS_ASSERT_EQUALS(23.0, m_kbise->totalOccupancy()); - TS_ASSERT_EQUALS(20.0, m_catio3->totalOccupancy()); - } - - - void test_numberDensity() - { - const double eps = 1.0e-7; - TS_ASSERT_DELTA(0.0914114, m_ni->numberDensity(), eps); - TS_ASSERT_DELTA(0.0335565, m_kbise->numberDensity(), eps); - TS_ASSERT_DELTA(0.0894566, m_catio3->numberDensity(), eps); - } - - - void test_siteCartesianPosition() - { - const double eps = 1.0e-5; - R3::Vector rCa = m_catio3->siteCartesianPosition(1); - TS_ASSERT_DELTA(0.03486, rCa[0], eps); - TS_ASSERT_DELTA(0.19366, rCa[1], eps); - TS_ASSERT_DELTA(1.90975, rCa[2], eps); - } - - - void test_siteAnisotropy() - { - for (int i = 0; i < m_ni->countSites(); ++i) - { - TS_ASSERT_EQUALS(false, m_ni->siteAnisotropy(i)); - } - for (int i = 0; i < m_catio3->countSites(); ++i) - { - TS_ASSERT_EQUALS(true, m_catio3->siteAnisotropy(i)); - } - } - - - void test_siteCartesianUij() - { - // nickel should have all Uij equal zero. - const double* puij = &(m_ni->siteCartesianUij(0).data()[0]); - for (int i = 0; i < 9; ++i) - { - TS_ASSERT_EQUALS(0.0, puij[i]); - } - // check CaTiO3 values - const R3::Matrix& UO2 = m_catio3->siteCartesianUij(3); - const double eps = 1e-8; - TS_ASSERT_DELTA(0.0065, UO2(0,0), eps); - TS_ASSERT_DELTA(0.0060, UO2(1,1), eps); - TS_ASSERT_DELTA(0.0095, UO2(2,2), eps); - TS_ASSERT_DELTA(0.0020, UO2(0,1), eps); - TS_ASSERT_DELTA(0.0020, UO2(1,0), eps); - TS_ASSERT_DELTA(-0.0008, UO2(0,2), eps); - TS_ASSERT_DELTA(-0.0008, UO2(2,0), eps); - TS_ASSERT_DELTA(-0.0010, UO2(1,2), eps); - TS_ASSERT_DELTA(-0.0010, UO2(2,1), eps); - } - - - void test_siteAtomType() - { - TS_ASSERT_EQUALS(string("Ni"), m_ni->siteAtomType(0)); - TS_ASSERT_EQUALS(string("K1+"), m_kbise->siteAtomType(0)); - TS_ASSERT_EQUALS(string("Bi3+"), m_kbise->siteAtomType(1)); - TS_ASSERT_EQUALS(string("Se"), m_kbise->siteAtomType(5)); - TS_ASSERT_EQUALS(string("Se"), m_kbise->siteAtomType(11)); - } - - - void test_diff() - { - StructureAdapterPtr acto = m_catio3; - CrystalStructureAdapterPtr ccto( - boost::dynamic_pointer_cast(acto)); - StructureAdapterPtr acto2 = acto->clone(); - CrystalStructureAdapterPtr ccto2( - boost::dynamic_pointer_cast(acto2)); - TS_ASSERT_EQUALS(0.0, diffdegree(acto, acto)); - TS_ASSERT_EQUALS(1.0, diffdegree(acto, StructureAdapterPtr())); - TS_ASSERT_EQUALS(0.0, diffdegree(acto, acto2)); - TS_ASSERT_EQUALS(0.0, diffdegree(acto, ccto2)); - const double symprec = ccto2->getSymmetryPrecision(); - ccto2->setSymmetryPrecision(0.010723); - TS_ASSERT_EQUALS(1.0, diffdegree(acto, acto2)); - ccto2->setSymmetryPrecision(symprec); - TS_ASSERT_EQUALS(0.0, diffdegree(acto, acto2)); - ccto2->clearSymOps(); - TS_ASSERT_EQUALS(1.0, diffdegree(acto, acto2)); - } - - - void test_getLattice() - { - CrystalStructureAdapter* pkbise = - dynamic_cast(m_kbise.get()); - TS_ASSERT(pkbise); - const Lattice& L = pkbise->getLattice(); - const double eps = 1.0e-12; - TS_ASSERT_DELTA(13.768, L.a(), eps); - TS_ASSERT_DELTA(12.096, L.b(), eps); - TS_ASSERT_DELTA(4.1656, L.c(), eps); - TS_ASSERT_DELTA(89.98, L.alpha(), eps); - TS_ASSERT_DELTA(98.64, L.beta(), eps); - TS_ASSERT_DELTA(87.96, L.gamma(), eps); - } - - - void test_getEquivalentAtoms() - { - diffpy::mathutils::EpsilonEqual allclose; - unique_ptr crst(loadTestCrystal("NH4Br.cif")); - StructureAdapterPtr adpt = createStructureAdapter(*crst); - CrystalStructureAdapterPtr cadpt = - boost::dynamic_pointer_cast(adpt); - TS_ASSERT_EQUALS(2, cadpt->countSites()); - TS_ASSERT_EQUALS(4, cadpt->totalOccupancy()); - CrystalStructureAdapter::AtomVector eq0, eq1; - eq0 = cadpt->getEquivalentAtoms(0); - TS_ASSERT_EQUALS(2, eq0.size()); - cadpt->toFractional(eq0[0]); - cadpt->toFractional(eq0[1]); - TS_ASSERT(allclose(R3::Vector(0, 0.5, 0.03), eq0[0].xyz_cartn)); - TS_ASSERT(allclose(R3::Vector(0.5, 0, 0.97), eq0[1].xyz_cartn)); - eq1 = cadpt->getEquivalentAtoms(1); - TS_ASSERT_EQUALS(2, eq1.size()); - cadpt->toFractional(eq1[0]); - cadpt->toFractional(eq1[1]); - TS_ASSERT(allclose(R3::Vector(0, 0, 0.5), eq1[0].xyz_cartn)); - TS_ASSERT(allclose(R3::Vector(0.5, 0.5, 0.5), eq1[1].xyz_cartn)); - } - - - void test_serialization() - { - stringstream storage(ios::in | ios::out | ios::binary); - diffpy::serialization::oarchive oa(storage, ios::binary); - oa << m_kbise; - diffpy::serialization::iarchive ia(storage, ios::binary); - StructureAdapterPtr kbise1; - TS_ASSERT(!kbise1.get()); - ia >> kbise1; - TS_ASSERT_DIFFERS(m_kbise.get(), kbise1.get()); - const double eps = 1.0e-7; - TS_ASSERT_EQUALS(12, kbise1->countSites()); - TS_ASSERT_EQUALS(23.0, kbise1->totalOccupancy()); - TS_ASSERT_DELTA(0.0335565, kbise1->numberDensity(), eps); - TS_ASSERT_EQUALS(string("K1+"), kbise1->siteAtomType(0)); - TS_ASSERT_EQUALS(string("Bi3+"), kbise1->siteAtomType(1)); - TS_ASSERT_EQUALS(string("Se"), kbise1->siteAtomType(5)); - TS_ASSERT_EQUALS(string("Se"), kbise1->siteAtomType(11)); - CrystalStructureAdapter* pkbise = - dynamic_cast(m_kbise.get()); - CrystalStructureAdapter* pkbise1 = - dynamic_cast(kbise1.get()); - const Lattice& L = pkbise->getLattice(); - const Lattice& L1 = pkbise1->getLattice(); - TS_ASSERT_EQUALS(L.a(), L1.a()); - TS_ASSERT_EQUALS(L.b(), L1.b()); - TS_ASSERT_EQUALS(L.c(), L1.c()); - TS_ASSERT_EQUALS(L.alpha(), L1.alpha()); - TS_ASSERT_EQUALS(L.beta(), L1.beta()); - TS_ASSERT_EQUALS(L.gamma(), L1.gamma()); - } +class TestObjCrystStructureAdapter : public CxxTest::TestSuite { + private: + unique_ptr mcryst_ni; + StructureAdapterPtr m_ni; + unique_ptr mcryst_kbise; + StructureAdapterPtr m_kbise; + unique_ptr mcryst_catio3; + StructureAdapterPtr m_catio3; + + public: + void setUp() { + if (!m_ni.get()) { + mcryst_ni.reset(loadTestCrystal("Ni.cif")); + m_ni = createStructureAdapter(*mcryst_ni); + } + if (!m_kbise.get()) { + mcryst_kbise.reset(loadTestCrystal("alpha_K2Bi8Se13.cif")); + m_kbise = createStructureAdapter(*mcryst_kbise); + } + if (!m_catio3.get()) { + mcryst_catio3.reset(loadTestCrystal("CaTiO3.cif")); + m_catio3 = createStructureAdapter(*mcryst_catio3); + } + } + + void test_typeid() { + StructureAdapter& r_ni = *m_ni; + TS_ASSERT(typeid(CrystalStructureAdapter) == typeid(r_ni)); + } + + void test_countSites() { + TS_ASSERT_EQUALS(1, m_ni->countSites()); + TS_ASSERT_EQUALS(12, m_kbise->countSites()); + TS_ASSERT_EQUALS(4, m_catio3->countSites()); + } + + void test_totalOccupancy() { + TS_ASSERT_EQUALS(4.0, m_ni->totalOccupancy()); + TS_ASSERT_EQUALS(23.0, m_kbise->totalOccupancy()); + TS_ASSERT_EQUALS(20.0, m_catio3->totalOccupancy()); + } + + void test_numberDensity() { + const double eps = 1.0e-7; + TS_ASSERT_DELTA(0.0914114, m_ni->numberDensity(), eps); + TS_ASSERT_DELTA(0.0335565, m_kbise->numberDensity(), eps); + TS_ASSERT_DELTA(0.0894566, m_catio3->numberDensity(), eps); + } + + void test_siteCartesianPosition() { + const double eps = 1.0e-5; + R3::Vector rCa = m_catio3->siteCartesianPosition(1); + TS_ASSERT_DELTA(0.03486, rCa[0], eps); + TS_ASSERT_DELTA(0.19366, rCa[1], eps); + TS_ASSERT_DELTA(1.90975, rCa[2], eps); + } + + void test_siteAnisotropy() { + for (int i = 0; i < m_ni->countSites(); ++i) { + TS_ASSERT_EQUALS(false, m_ni->siteAnisotropy(i)); + } + for (int i = 0; i < m_catio3->countSites(); ++i) { + TS_ASSERT_EQUALS(true, m_catio3->siteAnisotropy(i)); + } + } + + void test_siteCartesianUij() { + // nickel should have all Uij equal zero. + const double* puij = &(m_ni->siteCartesianUij(0).data()[0]); + for (int i = 0; i < 9; ++i) { + TS_ASSERT_EQUALS(0.0, puij[i]); + } + // check CaTiO3 values + const R3::Matrix& UO2 = m_catio3->siteCartesianUij(3); + const double eps = 1e-8; + TS_ASSERT_DELTA(0.0065, UO2(0, 0), eps); + TS_ASSERT_DELTA(0.0060, UO2(1, 1), eps); + TS_ASSERT_DELTA(0.0095, UO2(2, 2), eps); + TS_ASSERT_DELTA(0.0020, UO2(0, 1), eps); + TS_ASSERT_DELTA(0.0020, UO2(1, 0), eps); + TS_ASSERT_DELTA(-0.0008, UO2(0, 2), eps); + TS_ASSERT_DELTA(-0.0008, UO2(2, 0), eps); + TS_ASSERT_DELTA(-0.0010, UO2(1, 2), eps); + TS_ASSERT_DELTA(-0.0010, UO2(2, 1), eps); + } + + void test_siteAtomType() { + TS_ASSERT_EQUALS(string("Ni"), m_ni->siteAtomType(0)); + TS_ASSERT_EQUALS(string("K1+"), m_kbise->siteAtomType(0)); + TS_ASSERT_EQUALS(string("Bi3+"), m_kbise->siteAtomType(1)); + TS_ASSERT_EQUALS(string("Se"), m_kbise->siteAtomType(5)); + TS_ASSERT_EQUALS(string("Se"), m_kbise->siteAtomType(11)); + } + + void test_diff() { + StructureAdapterPtr acto = m_catio3; + CrystalStructureAdapterPtr ccto( + boost::dynamic_pointer_cast(acto)); + StructureAdapterPtr acto2 = acto->clone(); + CrystalStructureAdapterPtr ccto2( + boost::dynamic_pointer_cast(acto2)); + TS_ASSERT_EQUALS(0.0, diffdegree(acto, acto)); + TS_ASSERT_EQUALS(1.0, diffdegree(acto, StructureAdapterPtr())); + TS_ASSERT_EQUALS(0.0, diffdegree(acto, acto2)); + TS_ASSERT_EQUALS(0.0, diffdegree(acto, ccto2)); + const double symprec = ccto2->getSymmetryPrecision(); + ccto2->setSymmetryPrecision(0.010723); + TS_ASSERT_EQUALS(1.0, diffdegree(acto, acto2)); + ccto2->setSymmetryPrecision(symprec); + TS_ASSERT_EQUALS(0.0, diffdegree(acto, acto2)); + ccto2->clearSymOps(); + TS_ASSERT_EQUALS(1.0, diffdegree(acto, acto2)); + } + + void test_getLattice() { + CrystalStructureAdapter* pkbise = + dynamic_cast(m_kbise.get()); + TS_ASSERT(pkbise); + const Lattice& L = pkbise->getLattice(); + const double eps = 1.0e-12; + TS_ASSERT_DELTA(13.768, L.a(), eps); + TS_ASSERT_DELTA(12.096, L.b(), eps); + TS_ASSERT_DELTA(4.1656, L.c(), eps); + TS_ASSERT_DELTA(89.98, L.alpha(), eps); + TS_ASSERT_DELTA(98.64, L.beta(), eps); + TS_ASSERT_DELTA(87.96, L.gamma(), eps); + } + + void test_getEquivalentAtoms() { + diffpy::mathutils::EpsilonEqual allclose; + unique_ptr crst(loadTestCrystal("NH4Br.cif")); + StructureAdapterPtr adpt = createStructureAdapter(*crst); + CrystalStructureAdapterPtr cadpt = + boost::dynamic_pointer_cast(adpt); + TS_ASSERT_EQUALS(2, cadpt->countSites()); + TS_ASSERT_EQUALS(4, cadpt->totalOccupancy()); + CrystalStructureAdapter::AtomVector eq0, eq1; + eq0 = cadpt->getEquivalentAtoms(0); + TS_ASSERT_EQUALS(2, eq0.size()); + cadpt->toFractional(eq0[0]); + cadpt->toFractional(eq0[1]); + TS_ASSERT(allclose(R3::Vector(0, 0.5, 0.03), eq0[0].xyz_cartn)); + TS_ASSERT(allclose(R3::Vector(0.5, 0, 0.97), eq0[1].xyz_cartn)); + eq1 = cadpt->getEquivalentAtoms(1); + TS_ASSERT_EQUALS(2, eq1.size()); + cadpt->toFractional(eq1[0]); + cadpt->toFractional(eq1[1]); + TS_ASSERT(allclose(R3::Vector(0, 0, 0.5), eq1[0].xyz_cartn)); + TS_ASSERT(allclose(R3::Vector(0.5, 0.5, 0.5), eq1[1].xyz_cartn)); + } + + void test_serialization() { + stringstream storage(ios::in | ios::out | ios::binary); + diffpy::serialization::oarchive oa(storage, ios::binary); + oa << m_kbise; + diffpy::serialization::iarchive ia(storage, ios::binary); + StructureAdapterPtr kbise1; + TS_ASSERT(!kbise1.get()); + ia >> kbise1; + TS_ASSERT_DIFFERS(m_kbise.get(), kbise1.get()); + const double eps = 1.0e-7; + TS_ASSERT_EQUALS(12, kbise1->countSites()); + TS_ASSERT_EQUALS(23.0, kbise1->totalOccupancy()); + TS_ASSERT_DELTA(0.0335565, kbise1->numberDensity(), eps); + TS_ASSERT_EQUALS(string("K1+"), kbise1->siteAtomType(0)); + TS_ASSERT_EQUALS(string("Bi3+"), kbise1->siteAtomType(1)); + TS_ASSERT_EQUALS(string("Se"), kbise1->siteAtomType(5)); + TS_ASSERT_EQUALS(string("Se"), kbise1->siteAtomType(11)); + CrystalStructureAdapter* pkbise = + dynamic_cast(m_kbise.get()); + CrystalStructureAdapter* pkbise1 = + dynamic_cast(kbise1.get()); + const Lattice& L = pkbise->getLattice(); + const Lattice& L1 = pkbise1->getLattice(); + TS_ASSERT_EQUALS(L.a(), L1.a()); + TS_ASSERT_EQUALS(L.b(), L1.b()); + TS_ASSERT_EQUALS(L.c(), L1.c()); + TS_ASSERT_EQUALS(L.alpha(), L1.alpha()); + TS_ASSERT_EQUALS(L.beta(), L1.beta()); + TS_ASSERT_EQUALS(L.gamma(), L1.gamma()); + } }; // class TestObjCrystStructureAdapter @@ -310,405 +269,337 @@ class TestObjCrystStructureAdapter : public CxxTest::TestSuite // class TestObjCrystStructureBondGenerator ////////////////////////////////////////////////////////////////////////////// -class TestObjCrystStructureBondGenerator : public CxxTest::TestSuite -{ - private: - - unique_ptr mcryst_ni; - StructureAdapterPtr m_ni; - BaseBondGeneratorPtr m_nibnds; - - public: - - void setUp() - { - if (!m_ni.get()) - { - mcryst_ni.reset(loadTestCrystal("Ni.cif")); - m_ni = createStructureAdapter(*mcryst_ni); - } - m_nibnds = m_ni->createBondGenerator(); - } - - - void test_typeid() - { - BaseBondGenerator& r_nibnds = *m_nibnds; - TS_ASSERT(typeid(CrystalStructureBondGenerator) == - typeid(r_nibnds)); - } - - - void test_bondCountNickel() - { - m_nibnds->selectAnchorSite(0); - m_nibnds->setRmin(0); - m_nibnds->setRmax(1.0); - TS_ASSERT_EQUALS(0, countBonds(*m_nibnds)); - m_nibnds->setRmin(-10); - TS_ASSERT_EQUALS(0, countBonds(*m_nibnds)); - // there are 12 nearest neighbors at 2.49 - m_nibnds->setRmax(3); - TS_ASSERT_EQUALS(12, countBonds(*m_nibnds)); - // there are no bonds between 2.6 and 3.4 - m_nibnds->setRmin(2.6); - m_nibnds->setRmax(3.4); - TS_ASSERT_EQUALS(0, countBonds(*m_nibnds)); - // there are 6 second nearest neighbors at 3.52 - m_nibnds->setRmax(3.6); - TS_ASSERT_EQUALS(6, countBonds(*m_nibnds)); - // which sums to 18 neigbhors within radius 3.6 - m_nibnds->setRmin(0); - TS_ASSERT_EQUALS(18, countBonds(*m_nibnds)); - } - - - void test_bondCountWurtzite() - { - unique_ptr wurtzite(loadTestCrystal("ZnS_wurtzite.cif")); - StructureAdapterPtr stru = createStructureAdapter(*wurtzite); - BaseBondGeneratorPtr bnds = stru->createBondGenerator(); - TS_ASSERT_EQUALS(2, stru->countSites()); - bnds->selectAnchorSite(0); - bnds->selectSiteRange(0, 2); - bnds->setRmin(0); - // there should be no bond below the ZnS distance 2.31 - bnds->setRmax(2.2); - TS_ASSERT_EQUALS(0, countBonds(*bnds)); - // z-neighbor is slightly more distant than 3 in the lower plane - bnds->setRmax(2.35); - TS_ASSERT_EQUALS(3, countBonds(*bnds)); - bnds->setRmax(2.5); - TS_ASSERT_EQUALS(4, countBonds(*bnds)); - // there are 12 second nearest neighbors at 3.81 - bnds->setRmin(3.7); - bnds->setRmax(3.82); - TS_ASSERT_EQUALS(12, countBonds(*bnds)); - // and one more at 3.83 - bnds->setRmax(3.85); - TS_ASSERT_EQUALS(13, countBonds(*bnds)); - // making the total 17 - bnds->setRmin(0); - TS_ASSERT_EQUALS(17, countBonds(*bnds)); - // and the same happens for all other sites - bnds->selectAnchorSite(1); - TS_ASSERT_EQUALS(17, countBonds(*bnds)); - } - - - void test_LiTaO3() - { - const string lithium = "Li1+"; - const string tantalum = "Ta5+"; - const string oxygen = "O2-"; - const double epsu = 1e-5; - unique_ptr litao3(loadTestCrystal("LiTaO3.cif")); - StructureAdapterPtr stru = createStructureAdapter(*litao3); - TS_ASSERT_EQUALS(3, stru->countSites()); - BaseBondGeneratorPtr bnds = stru->createBondGenerator(); - bnds->selectAnchorSite(0); - bnds->selectSiteRange(0, 3); - // there are 3 oxygen neighbors at 2.065 - bnds->setRmax(2.1); - TS_ASSERT_EQUALS(3, countBonds(*bnds)); - // Li at site 0 is isotropic, oxygens have equal msd-s towards Li - for (bnds->rewind(); !bnds->finished(); bnds->next()) - { - TS_ASSERT_EQUALS(lithium, stru->siteAtomType(bnds->site0())); - TS_ASSERT_EQUALS(oxygen, stru->siteAtomType(bnds->site1())); - TS_ASSERT_DELTA(0.00265968, testmsd0(stru, bnds), epsu); - TS_ASSERT_DELTA(0.00710945, testmsd1(stru, bnds), epsu); - } - // there are 3 oxygen neighbors at 2.26 - bnds->setRmin(2.2); - bnds->setRmax(2.3); - TS_ASSERT_EQUALS(3, countBonds(*bnds)); - for (bnds->rewind(); !bnds->finished(); bnds->next()) - { - TS_ASSERT_EQUALS(oxygen, stru->siteAtomType(bnds->site1())); - TS_ASSERT_DELTA(0.00265968, testmsd0(stru, bnds), epsu); - TS_ASSERT_DELTA(0.00824319, testmsd1(stru, bnds), epsu); - } - // finally there are 4 Ta neighbors between 2.8 and 3.1 - bnds->setRmin(2.8); - bnds->setRmax(3.1); - TS_ASSERT_EQUALS(4, countBonds(*bnds)); - for (bnds->rewind(); !bnds->finished(); bnds->next()) - { - TS_ASSERT_DELTA(0.00265968, testmsd0(stru, bnds), epsu); - TS_ASSERT_EQUALS(tantalum, stru->siteAtomType(bnds->site1())); - R3::Vector r01xy = bnds->r01(); - r01xy[2] = 0.0; - // for the tantalum above Li the msd equals U33 - if (R3::norm(r01xy) < 0.1) - { - TS_ASSERT_DELTA(0.00356, testmsd1(stru, bnds), epsu); - } - // other 3 tantalums are related by tripple axis and - // have the same msd towards the central Li - else - { - TS_ASSERT_DELTA(0.00486942, testmsd1(stru, bnds), epsu); - } - } - } - - +class TestObjCrystStructureBondGenerator : public CxxTest::TestSuite { + private: + unique_ptr mcryst_ni; + StructureAdapterPtr m_ni; + BaseBondGeneratorPtr m_nibnds; + + public: + void setUp() { + if (!m_ni.get()) { + mcryst_ni.reset(loadTestCrystal("Ni.cif")); + m_ni = createStructureAdapter(*mcryst_ni); + } + m_nibnds = m_ni->createBondGenerator(); + } + + void test_typeid() { + BaseBondGenerator& r_nibnds = *m_nibnds; + TS_ASSERT(typeid(CrystalStructureBondGenerator) == typeid(r_nibnds)); + } + + void test_bondCountNickel() { + m_nibnds->selectAnchorSite(0); + m_nibnds->setRmin(0); + m_nibnds->setRmax(1.0); + TS_ASSERT_EQUALS(0, countBonds(*m_nibnds)); + m_nibnds->setRmin(-10); + TS_ASSERT_EQUALS(0, countBonds(*m_nibnds)); + // there are 12 nearest neighbors at 2.49 + m_nibnds->setRmax(3); + TS_ASSERT_EQUALS(12, countBonds(*m_nibnds)); + // there are no bonds between 2.6 and 3.4 + m_nibnds->setRmin(2.6); + m_nibnds->setRmax(3.4); + TS_ASSERT_EQUALS(0, countBonds(*m_nibnds)); + // there are 6 second nearest neighbors at 3.52 + m_nibnds->setRmax(3.6); + TS_ASSERT_EQUALS(6, countBonds(*m_nibnds)); + // which sums to 18 neighbors within radius 3.6 + m_nibnds->setRmin(0); + TS_ASSERT_EQUALS(18, countBonds(*m_nibnds)); + } + + void test_bondCountWurtzite() { + unique_ptr wurtzite(loadTestCrystal("ZnS_wurtzite.cif")); + StructureAdapterPtr stru = createStructureAdapter(*wurtzite); + BaseBondGeneratorPtr bnds = stru->createBondGenerator(); + TS_ASSERT_EQUALS(2, stru->countSites()); + bnds->selectAnchorSite(0); + bnds->selectSiteRange(0, 2); + bnds->setRmin(0); + // there should be no bond below the ZnS distance 2.31 + bnds->setRmax(2.2); + TS_ASSERT_EQUALS(0, countBonds(*bnds)); + // z-neighbor is slightly more distant than 3 in the lower plane + bnds->setRmax(2.35); + TS_ASSERT_EQUALS(3, countBonds(*bnds)); + bnds->setRmax(2.5); + TS_ASSERT_EQUALS(4, countBonds(*bnds)); + // there are 12 second nearest neighbors at 3.81 + bnds->setRmin(3.7); + bnds->setRmax(3.82); + TS_ASSERT_EQUALS(12, countBonds(*bnds)); + // and one more at 3.83 + bnds->setRmax(3.85); + TS_ASSERT_EQUALS(13, countBonds(*bnds)); + // making the total 17 + bnds->setRmin(0); + TS_ASSERT_EQUALS(17, countBonds(*bnds)); + // and the same happens for all other sites + bnds->selectAnchorSite(1); + TS_ASSERT_EQUALS(17, countBonds(*bnds)); + } + + void test_LiTaO3() { + const string lithium = "Li1+"; + const string tantalum = "Ta5+"; + const string oxygen = "O2-"; + const double epsu = 1e-5; + unique_ptr litao3(loadTestCrystal("LiTaO3.cif")); + StructureAdapterPtr stru = createStructureAdapter(*litao3); + TS_ASSERT_EQUALS(3, stru->countSites()); + BaseBondGeneratorPtr bnds = stru->createBondGenerator(); + bnds->selectAnchorSite(0); + bnds->selectSiteRange(0, 3); + // there are 3 oxygen neighbors at 2.065 + bnds->setRmax(2.1); + TS_ASSERT_EQUALS(3, countBonds(*bnds)); + // Li at site 0 is isotropic, oxygens have equal msd-s towards Li + for (bnds->rewind(); !bnds->finished(); bnds->next()) { + TS_ASSERT_EQUALS(lithium, stru->siteAtomType(bnds->site0())); + TS_ASSERT_EQUALS(oxygen, stru->siteAtomType(bnds->site1())); + TS_ASSERT_DELTA(0.00265968, testmsd0(stru, bnds), epsu); + TS_ASSERT_DELTA(0.00710945, testmsd1(stru, bnds), epsu); + } + // there are 3 oxygen neighbors at 2.26 + bnds->setRmin(2.2); + bnds->setRmax(2.3); + TS_ASSERT_EQUALS(3, countBonds(*bnds)); + for (bnds->rewind(); !bnds->finished(); bnds->next()) { + TS_ASSERT_EQUALS(oxygen, stru->siteAtomType(bnds->site1())); + TS_ASSERT_DELTA(0.00265968, testmsd0(stru, bnds), epsu); + TS_ASSERT_DELTA(0.00824319, testmsd1(stru, bnds), epsu); + } + // finally there are 4 Ta neighbors between 2.8 and 3.1 + bnds->setRmin(2.8); + bnds->setRmax(3.1); + TS_ASSERT_EQUALS(4, countBonds(*bnds)); + for (bnds->rewind(); !bnds->finished(); bnds->next()) { + TS_ASSERT_DELTA(0.00265968, testmsd0(stru, bnds), epsu); + TS_ASSERT_EQUALS(tantalum, stru->siteAtomType(bnds->site1())); + R3::Vector r01xy = bnds->r01(); + r01xy[2] = 0.0; + // for the tantalum above Li the msd equals U33 + if (R3::norm(r01xy) < 0.1) { + TS_ASSERT_DELTA(0.00356, testmsd1(stru, bnds), epsu); + } + // other 3 tantalums are related by triple axis and + // have the same msd towards the central Li + else { + TS_ASSERT_DELTA(0.00486942, testmsd1(stru, bnds), epsu); + } + } + } }; // class TestObjCrystStructureBondGenerator - ////////////////////////////////////////////////////////////////////////////// // class TestObjCrystMoleculeAdapter ////////////////////////////////////////////////////////////////////////////// - -class TestObjCrystMoleculeAdapter : public CxxTest::TestSuite -{ - private: - - Molecule* mmol_c60; - StructureAdapterPtr m_c60; - - public: - - void setUp() - { - mmol_c60 = makeC60Molecule(); - m_c60 = createStructureAdapter(*mmol_c60); - } - - void tearDown() - { - Crystal* crst = &(mmol_c60->GetCrystal()); - delete crst; - } - - - void test_typeid() - { - StructureAdapter& r_c60 = *m_c60; - TS_ASSERT(typeid(AtomicStructureAdapter) == typeid(r_c60)); - } - - - void test_countSites() - { - TS_ASSERT_EQUALS(60, m_c60->countSites()); - } - - - void test_totalOccupancy() - { - TS_ASSERT_EQUALS(60, m_c60->totalOccupancy()); - } - - - void test_numberDensity() - { - const double eps = 1.0e-7; - TS_ASSERT_DELTA(0.0, m_c60->numberDensity(), eps); - } - - - void test_siteCartesianPosition() - { - const double eps = 1.0e-5; - R3::Vector rC0 = m_c60->siteCartesianPosition(0); - TS_ASSERT_DELTA(3.45127, rC0[0], eps); - TS_ASSERT_DELTA(0.68500, rC0[1], eps); - TS_ASSERT_DELTA(0.00000, rC0[2], eps); - } - - - void test_siteAnisotropy() - { - for (int i = 0; i < m_c60->countSites(); ++i) - { - TS_ASSERT_EQUALS(false, m_c60->siteAnisotropy(i)); - } - } - - - void test_siteCartesianUij() - { - double BtoU = 1.0 / (8 * M_PI * M_PI); - const R3::Matrix Uij = m_c60->siteCartesianUij(0); - TS_ASSERT_EQUALS(0.0, Uij(0,1)); - TS_ASSERT_EQUALS(0.0, Uij(0,2)); - TS_ASSERT_EQUALS(0.0, Uij(1,0)); - TS_ASSERT_EQUALS(0.0, Uij(1,2)); - TS_ASSERT_EQUALS(0.0, Uij(2,0)); - TS_ASSERT_EQUALS(0.0, Uij(2,1)); - TS_ASSERT_EQUALS(BtoU, Uij(0,0)); - TS_ASSERT_EQUALS(BtoU, Uij(1,1)); - TS_ASSERT_EQUALS(BtoU, Uij(2,2)); - } - - - void test_siteAtomType() - { - for (int i = 0; i < m_c60->countSites(); ++i) - { - TS_ASSERT_EQUALS(string("C"), m_c60->siteAtomType(i)); - } - } - - - void test_serialization() - { - StructureAdapterPtr c60a; - c60a = dumpandload(m_c60); - TS_ASSERT_DIFFERS(m_c60.get(), c60a.get()); - TS_ASSERT_EQUALS(60, c60a->countSites()); - TS_ASSERT_EQUALS(60.0, c60a->totalOccupancy()); - TS_ASSERT_EQUALS(0.0, c60a->numberDensity()); - R3::Vector dxyz(1, 2, 3); - dxyz = m_c60->siteCartesianPosition(0) - c60a->siteCartesianPosition(0); - TS_ASSERT_EQUALS(0.0, R3::norm(dxyz)); - dxyz = m_c60->siteCartesianPosition(37) - c60a->siteCartesianPosition(37); - TS_ASSERT_EQUALS(0.0, R3::norm(dxyz)); - for (int i = 0; i < c60a->countSites(); ++i) - { - TS_ASSERT_EQUALS(string("C"), c60a->siteAtomType(i)); - } - } +class TestObjCrystMoleculeAdapter : public CxxTest::TestSuite { + private: + Molecule* mmol_c60; + StructureAdapterPtr m_c60; + + public: + void setUp() { + mmol_c60 = makeC60Molecule(); + m_c60 = createStructureAdapter(*mmol_c60); + } + + void tearDown() { + Crystal* crst = &(mmol_c60->GetCrystal()); + delete crst; + } + + void test_typeid() { + StructureAdapter& r_c60 = *m_c60; + TS_ASSERT(typeid(AtomicStructureAdapter) == typeid(r_c60)); + } + + void test_countSites() { TS_ASSERT_EQUALS(60, m_c60->countSites()); } + + void test_totalOccupancy() { TS_ASSERT_EQUALS(60, m_c60->totalOccupancy()); } + + void test_numberDensity() { + const double eps = 1.0e-7; + TS_ASSERT_DELTA(0.0, m_c60->numberDensity(), eps); + } + + void test_siteCartesianPosition() { + const double eps = 1.0e-5; + R3::Vector rC0 = m_c60->siteCartesianPosition(0); + TS_ASSERT_DELTA(3.45127, rC0[0], eps); + TS_ASSERT_DELTA(0.68500, rC0[1], eps); + TS_ASSERT_DELTA(0.00000, rC0[2], eps); + } + + void test_siteAnisotropy() { + for (int i = 0; i < m_c60->countSites(); ++i) { + TS_ASSERT_EQUALS(false, m_c60->siteAnisotropy(i)); + } + } + + void test_siteCartesianUij() { + double BtoU = 1.0 / (8 * M_PI * M_PI); + const R3::Matrix Uij = m_c60->siteCartesianUij(0); + TS_ASSERT_EQUALS(0.0, Uij(0, 1)); + TS_ASSERT_EQUALS(0.0, Uij(0, 2)); + TS_ASSERT_EQUALS(0.0, Uij(1, 0)); + TS_ASSERT_EQUALS(0.0, Uij(1, 2)); + TS_ASSERT_EQUALS(0.0, Uij(2, 0)); + TS_ASSERT_EQUALS(0.0, Uij(2, 1)); + TS_ASSERT_EQUALS(BtoU, Uij(0, 0)); + TS_ASSERT_EQUALS(BtoU, Uij(1, 1)); + TS_ASSERT_EQUALS(BtoU, Uij(2, 2)); + } + + void test_siteAtomType() { + for (int i = 0; i < m_c60->countSites(); ++i) { + TS_ASSERT_EQUALS(string("C"), m_c60->siteAtomType(i)); + } + } + + void test_serialization() { + StructureAdapterPtr c60a; + c60a = dumpandload(m_c60); + TS_ASSERT_DIFFERS(m_c60.get(), c60a.get()); + TS_ASSERT_EQUALS(60, c60a->countSites()); + TS_ASSERT_EQUALS(60.0, c60a->totalOccupancy()); + TS_ASSERT_EQUALS(0.0, c60a->numberDensity()); + R3::Vector dxyz(1, 2, 3); + dxyz = m_c60->siteCartesianPosition(0) - c60a->siteCartesianPosition(0); + TS_ASSERT_EQUALS(0.0, R3::norm(dxyz)); + dxyz = m_c60->siteCartesianPosition(37) - c60a->siteCartesianPosition(37); + TS_ASSERT_EQUALS(0.0, R3::norm(dxyz)); + for (int i = 0; i < c60a->countSites(); ++i) { + TS_ASSERT_EQUALS(string("C"), c60a->siteAtomType(i)); + } + } }; // class TestObjCrystMoleculeAdapter - ////////////////////////////////////////////////////////////////////////////// // class TestObjCrystMoleculeBondGenerator ////////////////////////////////////////////////////////////////////////////// -class TestObjCrystMoleculeBondGenerator : public CxxTest::TestSuite -{ - private: - - Molecule* mmol_c60; - StructureAdapterPtr m_c60; - BaseBondGeneratorPtr m_c60bnds; - - public: - - void setUp() - { - mmol_c60 = makeC60Molecule(); - m_c60 = createStructureAdapter(*mmol_c60); - m_c60bnds = m_c60->createBondGenerator(); - } - - void tearDown() - { - Crystal* crst = &(mmol_c60->GetCrystal()); - delete crst; - } - - - void test_typeid() - { - BaseBondGenerator& r_c60bnds = *m_c60bnds; - TS_ASSERT(typeid(BaseBondGenerator) == typeid(r_c60bnds)); - } - - - void test_bondCountC60() - { - m_c60bnds->selectAnchorSite(0); - m_c60bnds->setRmin(0); - m_c60bnds->setRmax(1.0); - TS_ASSERT_EQUALS(0, countBonds(*m_c60bnds)); - m_c60bnds->setRmin(-10); - TS_ASSERT_EQUALS(0, countBonds(*m_c60bnds)); - // there are 3 nearest neighbors at 1.44 - m_c60bnds->setRmax(1.5); - TS_ASSERT_EQUALS(3, countBonds(*m_c60bnds)); - // There are 59 neighbors total - m_c60bnds->setRmax(8); - TS_ASSERT_EQUALS(59, countBonds(*m_c60bnds)); - } - +class TestObjCrystMoleculeBondGenerator : public CxxTest::TestSuite { + private: + Molecule* mmol_c60; + StructureAdapterPtr m_c60; + BaseBondGeneratorPtr m_c60bnds; + + public: + void setUp() { + mmol_c60 = makeC60Molecule(); + m_c60 = createStructureAdapter(*mmol_c60); + m_c60bnds = m_c60->createBondGenerator(); + } + + void tearDown() { + Crystal* crst = &(mmol_c60->GetCrystal()); + delete crst; + } + + void test_typeid() { + BaseBondGenerator& r_c60bnds = *m_c60bnds; + TS_ASSERT(typeid(BaseBondGenerator) == typeid(r_c60bnds)); + } + + void test_bondCountC60() { + m_c60bnds->selectAnchorSite(0); + m_c60bnds->setRmin(0); + m_c60bnds->setRmax(1.0); + TS_ASSERT_EQUALS(0, countBonds(*m_c60bnds)); + m_c60bnds->setRmin(-10); + TS_ASSERT_EQUALS(0, countBonds(*m_c60bnds)); + // there are 3 nearest neighbors at 1.44 + m_c60bnds->setRmax(1.5); + TS_ASSERT_EQUALS(3, countBonds(*m_c60bnds)); + // There are 59 neighbors total + m_c60bnds->setRmax(8); + TS_ASSERT_EQUALS(59, countBonds(*m_c60bnds)); + } }; // class TestObjCrystMoleculeBondGenerator - namespace { -Molecule* makeC60Molecule() -{ - - Crystal* cryst = new Crystal(1, 1, 1, "P1"); - Molecule* mol = new Molecule(*cryst, "c60"); - cryst->AddScatterer(mol); - - // Populate the molecule - ScatteringPowerAtom* sp = new ScatteringPowerAtom("C", "C"); - cryst->AddScatteringPower(sp); - mol->AddAtom(3.451266498, 0.685000000, 0.000000000, sp, "C0"); - mol->AddAtom(3.451266498, -0.685000000, 0.000000000, sp, "C1"); - mol->AddAtom(-3.451266498, 0.685000000, 0.000000000, sp, "C2"); - mol->AddAtom(-3.451266498, -0.685000000, 0.000000000, sp, "C3"); - mol->AddAtom(0.685000000, 0.000000000, 3.451266498, sp, "C4"); - mol->AddAtom(-0.685000000, 0.000000000, 3.451266498, sp, "C5"); - mol->AddAtom(0.685000000, 0.000000000, -3.451266498, sp, "C6"); - mol->AddAtom(-0.685000000, 0.000000000, -3.451266498, sp, "C7"); - mol->AddAtom(0.000000000, 3.451266498, 0.685000000, sp, "C8"); - mol->AddAtom(0.000000000, 3.451266498, -0.685000000, sp, "C9"); - mol->AddAtom(0.000000000, -3.451266498, 0.685000000, sp, "C10"); - mol->AddAtom(0.000000000, -3.451266498, -0.685000000, sp, "C11"); - mol->AddAtom(3.003809890, 1.409000000, 1.171456608, sp, "C12"); - mol->AddAtom(3.003809890, 1.409000000, -1.171456608, sp, "C13"); - mol->AddAtom(3.003809890, -1.409000000, 1.171456608, sp, "C14"); - mol->AddAtom(3.003809890, -1.409000000, -1.171456608, sp, "C15"); - mol->AddAtom(-3.003809890, 1.409000000, 1.171456608, sp, "C16"); - mol->AddAtom(-3.003809890, 1.409000000, -1.171456608, sp, "C17"); - mol->AddAtom(-3.003809890, -1.409000000, 1.171456608, sp, "C18"); - mol->AddAtom(-3.003809890, -1.409000000, -1.171456608, sp, "C19"); - mol->AddAtom(1.409000000, 1.171456608, 3.003809890, sp, "C20"); - mol->AddAtom(1.409000000, -1.171456608, 3.003809890, sp, "C21"); - mol->AddAtom(-1.409000000, 1.171456608, 3.003809890, sp, "C22"); - mol->AddAtom(-1.409000000, -1.171456608, 3.003809890, sp, "C23"); - mol->AddAtom(1.409000000, 1.171456608, -3.003809890, sp, "C24"); - mol->AddAtom(1.409000000, -1.171456608, -3.003809890, sp, "C25"); - mol->AddAtom(-1.409000000, 1.171456608, -3.003809890, sp, "C26"); - mol->AddAtom(-1.409000000, -1.171456608, -3.003809890, sp, "C27"); - mol->AddAtom(1.171456608, 3.003809890, 1.409000000, sp, "C28"); - mol->AddAtom(-1.171456608, 3.003809890, 1.409000000, sp, "C29"); - mol->AddAtom(1.171456608, 3.003809890, -1.409000000, sp, "C30"); - mol->AddAtom(-1.171456608, 3.003809890, -1.409000000, sp, "C31"); - mol->AddAtom(1.171456608, -3.003809890, 1.409000000, sp, "C32"); - mol->AddAtom(-1.171456608, -3.003809890, 1.409000000, sp, "C33"); - mol->AddAtom(1.171456608, -3.003809890, -1.409000000, sp, "C34"); - mol->AddAtom(-1.171456608, -3.003809890, -1.409000000, sp, "C35"); - mol->AddAtom(2.580456608, 0.724000000, 2.279809890, sp, "C36"); - mol->AddAtom(2.580456608, 0.724000000, -2.279809890, sp, "C37"); - mol->AddAtom(2.580456608, -0.724000000, 2.279809890, sp, "C38"); - mol->AddAtom(2.580456608, -0.724000000, -2.279809890, sp, "C39"); - mol->AddAtom(-2.580456608, 0.724000000, 2.279809890, sp, "C40"); - mol->AddAtom(-2.580456608, 0.724000000, -2.279809890, sp, "C41"); - mol->AddAtom(-2.580456608, -0.724000000, 2.279809890, sp, "C42"); - mol->AddAtom(-2.580456608, -0.724000000, -2.279809890, sp, "C43"); - mol->AddAtom(0.724000000, 2.279809890, 2.580456608, sp, "C44"); - mol->AddAtom(0.724000000, -2.279809890, 2.580456608, sp, "C45"); - mol->AddAtom(-0.724000000, 2.279809890, 2.580456608, sp, "C46"); - mol->AddAtom(-0.724000000, -2.279809890, 2.580456608, sp, "C47"); - mol->AddAtom(0.724000000, 2.279809890, -2.580456608, sp, "C48"); - mol->AddAtom(0.724000000, -2.279809890, -2.580456608, sp, "C49"); - mol->AddAtom(-0.724000000, 2.279809890, -2.580456608, sp, "C50"); - mol->AddAtom(-0.724000000, -2.279809890, -2.580456608, sp, "C51"); - mol->AddAtom(2.279809890, 2.580456608, 0.724000000, sp, "C52"); - mol->AddAtom(-2.279809890, 2.580456608, 0.724000000, sp, "C53"); - mol->AddAtom(2.279809890, 2.580456608, -0.724000000, sp, "C54"); - mol->AddAtom(-2.279809890, 2.580456608, -0.724000000, sp, "C55"); - mol->AddAtom(2.279809890, -2.580456608, 0.724000000, sp, "C56"); - mol->AddAtom(-2.279809890, -2.580456608, 0.724000000, sp, "C57"); - mol->AddAtom(2.279809890, -2.580456608, -0.724000000, sp, "C58"); - mol->AddAtom(-2.279809890, -2.580456608, -0.724000000, sp, "C59"); - - return mol; +Molecule* makeC60Molecule() { + Crystal* cryst = new Crystal(1, 1, 1, "P1"); + Molecule* mol = new Molecule(*cryst, "c60"); + cryst->AddScatterer(mol); + + // Populate the molecule + ScatteringPowerAtom* sp = new ScatteringPowerAtom("C", "C"); + cryst->AddScatteringPower(sp); + mol->AddAtom(3.451266498, 0.685000000, 0.000000000, sp, "C0"); + mol->AddAtom(3.451266498, -0.685000000, 0.000000000, sp, "C1"); + mol->AddAtom(-3.451266498, 0.685000000, 0.000000000, sp, "C2"); + mol->AddAtom(-3.451266498, -0.685000000, 0.000000000, sp, "C3"); + mol->AddAtom(0.685000000, 0.000000000, 3.451266498, sp, "C4"); + mol->AddAtom(-0.685000000, 0.000000000, 3.451266498, sp, "C5"); + mol->AddAtom(0.685000000, 0.000000000, -3.451266498, sp, "C6"); + mol->AddAtom(-0.685000000, 0.000000000, -3.451266498, sp, "C7"); + mol->AddAtom(0.000000000, 3.451266498, 0.685000000, sp, "C8"); + mol->AddAtom(0.000000000, 3.451266498, -0.685000000, sp, "C9"); + mol->AddAtom(0.000000000, -3.451266498, 0.685000000, sp, "C10"); + mol->AddAtom(0.000000000, -3.451266498, -0.685000000, sp, "C11"); + mol->AddAtom(3.003809890, 1.409000000, 1.171456608, sp, "C12"); + mol->AddAtom(3.003809890, 1.409000000, -1.171456608, sp, "C13"); + mol->AddAtom(3.003809890, -1.409000000, 1.171456608, sp, "C14"); + mol->AddAtom(3.003809890, -1.409000000, -1.171456608, sp, "C15"); + mol->AddAtom(-3.003809890, 1.409000000, 1.171456608, sp, "C16"); + mol->AddAtom(-3.003809890, 1.409000000, -1.171456608, sp, "C17"); + mol->AddAtom(-3.003809890, -1.409000000, 1.171456608, sp, "C18"); + mol->AddAtom(-3.003809890, -1.409000000, -1.171456608, sp, "C19"); + mol->AddAtom(1.409000000, 1.171456608, 3.003809890, sp, "C20"); + mol->AddAtom(1.409000000, -1.171456608, 3.003809890, sp, "C21"); + mol->AddAtom(-1.409000000, 1.171456608, 3.003809890, sp, "C22"); + mol->AddAtom(-1.409000000, -1.171456608, 3.003809890, sp, "C23"); + mol->AddAtom(1.409000000, 1.171456608, -3.003809890, sp, "C24"); + mol->AddAtom(1.409000000, -1.171456608, -3.003809890, sp, "C25"); + mol->AddAtom(-1.409000000, 1.171456608, -3.003809890, sp, "C26"); + mol->AddAtom(-1.409000000, -1.171456608, -3.003809890, sp, "C27"); + mol->AddAtom(1.171456608, 3.003809890, 1.409000000, sp, "C28"); + mol->AddAtom(-1.171456608, 3.003809890, 1.409000000, sp, "C29"); + mol->AddAtom(1.171456608, 3.003809890, -1.409000000, sp, "C30"); + mol->AddAtom(-1.171456608, 3.003809890, -1.409000000, sp, "C31"); + mol->AddAtom(1.171456608, -3.003809890, 1.409000000, sp, "C32"); + mol->AddAtom(-1.171456608, -3.003809890, 1.409000000, sp, "C33"); + mol->AddAtom(1.171456608, -3.003809890, -1.409000000, sp, "C34"); + mol->AddAtom(-1.171456608, -3.003809890, -1.409000000, sp, "C35"); + mol->AddAtom(2.580456608, 0.724000000, 2.279809890, sp, "C36"); + mol->AddAtom(2.580456608, 0.724000000, -2.279809890, sp, "C37"); + mol->AddAtom(2.580456608, -0.724000000, 2.279809890, sp, "C38"); + mol->AddAtom(2.580456608, -0.724000000, -2.279809890, sp, "C39"); + mol->AddAtom(-2.580456608, 0.724000000, 2.279809890, sp, "C40"); + mol->AddAtom(-2.580456608, 0.724000000, -2.279809890, sp, "C41"); + mol->AddAtom(-2.580456608, -0.724000000, 2.279809890, sp, "C42"); + mol->AddAtom(-2.580456608, -0.724000000, -2.279809890, sp, "C43"); + mol->AddAtom(0.724000000, 2.279809890, 2.580456608, sp, "C44"); + mol->AddAtom(0.724000000, -2.279809890, 2.580456608, sp, "C45"); + mol->AddAtom(-0.724000000, 2.279809890, 2.580456608, sp, "C46"); + mol->AddAtom(-0.724000000, -2.279809890, 2.580456608, sp, "C47"); + mol->AddAtom(0.724000000, 2.279809890, -2.580456608, sp, "C48"); + mol->AddAtom(0.724000000, -2.279809890, -2.580456608, sp, "C49"); + mol->AddAtom(-0.724000000, 2.279809890, -2.580456608, sp, "C50"); + mol->AddAtom(-0.724000000, -2.279809890, -2.580456608, sp, "C51"); + mol->AddAtom(2.279809890, 2.580456608, 0.724000000, sp, "C52"); + mol->AddAtom(-2.279809890, 2.580456608, 0.724000000, sp, "C53"); + mol->AddAtom(2.279809890, 2.580456608, -0.724000000, sp, "C54"); + mol->AddAtom(-2.279809890, 2.580456608, -0.724000000, sp, "C55"); + mol->AddAtom(2.279809890, -2.580456608, 0.724000000, sp, "C56"); + mol->AddAtom(-2.279809890, -2.580456608, 0.724000000, sp, "C57"); + mol->AddAtom(2.279809890, -2.580456608, -0.724000000, sp, "C58"); + mol->AddAtom(-2.279809890, -2.580456608, -0.724000000, sp, "C59"); + + return mol; } -} // namespace - +} // namespace // End of file diff --git a/src/tests/TestOverlapCalculator.hpp b/src/tests/TestOverlapCalculator.hpp index 6f1dce84..ea9b01a5 100644 --- a/src/tests/TestOverlapCalculator.hpp +++ b/src/tests/TestOverlapCalculator.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2011 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. -* -****************************************************************************** -* -* class TestOverlapCalculator -- unit tests for the OverlapCalculator class -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2011 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. + * + ****************************************************************************** + * + * class TestOverlapCalculator -- unit tests for the OverlapCalculator class + * + *****************************************************************************/ #include @@ -31,332 +31,293 @@ using namespace std; using namespace diffpy::srreal; -class TestOverlapCalculator : public CxxTest::TestSuite -{ - private: - - boost::shared_ptr molc; - StructureAdapterPtr mnacl; - double meps; - - public: - - void setUp() - { - CxxTest::setAbortTestOnFail(true); - meps = diffpy::mathutils::SQRT_DOUBLE_EPS; - molc.reset(new OverlapCalculator); - molc->getAtomRadiiTable()->setCustom("", 1.0); - molc->getAtomRadiiTable()->setCustom("Na1+", 1.5); - molc->getAtomRadiiTable()->setCustom("Cl1-", 1.8); - if (!mnacl) mnacl = loadTestPeriodicStructure("NaCl.stru"); - CxxTest::setAbortTestOnFail(true); - } - - - void test_rmin() - { - molc->eval(mnacl); - TS_ASSERT(molc->distances().size()); - double tot = molc->totalSquareOverlap(); - TS_ASSERT_LESS_THAN(0.0, tot); - molc->setRmin(10); - molc->eval(); - TS_ASSERT(molc->distances().empty()); - TS_ASSERT_EQUALS(0.0, molc->totalSquareOverlap()); - molc->setRmin(2); - molc->eval(); - TS_ASSERT_EQUALS(tot, molc->totalSquareOverlap()); - } - - - void test_rmax() - { - molc->setRmax(2.5); - molc->eval(mnacl); - TS_ASSERT(molc->distances().empty()) - TS_ASSERT_EQUALS(0.0, molc->totalSquareOverlap()); - } - - - void test_lineNoTouch() - { - AtomicStructureAdapterPtr stru(new AtomicStructureAdapter); - Atom a0, a1; - a0.xyz_cartn = R3::Vector(0.0, 0.0, 0.0); - a1.xyz_cartn = R3::Vector(0.0, 0.0, 2.0); - stru->append(a0); - stru->append(a1); - molc->eval(stru); - TS_ASSERT_EQUALS(0.0, molc->totalSquareOverlap()); - QuantityType sqolps = molc->siteSquareOverlaps(); - TS_ASSERT_EQUALS(2u, sqolps.size()); - TS_ASSERT_EQUALS(0.0, sqolps[0]); - TS_ASSERT_EQUALS(0.0, sqolps[1]); - TS_ASSERT_EQUALS(0.0, molc->flipDiffTotal(0, 0)); - TS_ASSERT_EQUALS(0.0, molc->flipDiffTotal(0, 1)); - std::vector g = molc->gradients(); - TS_ASSERT_EQUALS(2u, g.size()); - TS_ASSERT_EQUALS(0.0, R3::norm(g[0])); - TS_ASSERT_EQUALS(0.0, R3::norm(g[1])); - } - - - void test_lineTouch() - { - AtomicStructureAdapterPtr stru(new AtomicStructureAdapter); - Atom a0, a1; - a0.xyz_cartn = R3::Vector(0.0, 0.0, 0.0); - a1.xyz_cartn = R3::Vector(0.0, 0.0, 1.5); - stru->append(a0); - stru->append(a1); - molc->eval(stru); - TS_ASSERT_EQUALS(0.25, molc->totalSquareOverlap()); - QuantityType sqolps = molc->siteSquareOverlaps(); - TS_ASSERT_EQUALS(2u, sqolps.size()); - TS_ASSERT_EQUALS(0.125, sqolps[0]); - TS_ASSERT_EQUALS(0.125, sqolps[1]); - TS_ASSERT_EQUALS(0.0, molc->flipDiffTotal(0, 1)); - std::vector g = molc->gradients(); - TS_ASSERT_EQUALS(2u, g.size()); - R3::Vector g0(0.0, 0.0, +1); - TS_ASSERT_EQUALS(0.0, R3::distance(g0, g[0])); - R3::Vector g1(0.0, 0.0, -1); - TS_ASSERT_EQUALS(0.0, R3::distance(g1, g[1])); - } - - - void test_gradients() - { - AtomicStructureAdapterPtr stru(new AtomicStructureAdapter); - Atom a0, a1; - a0.xyz_cartn = R3::Vector(0.0, 0.0, 0.0); - a1.xyz_cartn = R3::Vector(0.17, 0.31, 0.37); - stru->append(a0); - stru->append(a1); - molc->eval(stru); - std::vector g = molc->gradients(); - double dx = 1e-6; - double tsqo0 = molc->totalSquareOverlap(); - R3::Vector r1 = stru->siteCartesianPosition(1); - R3::Vector gn1; - for (int k = 0; k != R3::Ndim; ++k) - { - R3::Vector& xyz1 = stru->at(1).xyz_cartn; - xyz1 = r1; - xyz1[k] += dx; - molc->eval(stru); - gn1[k] = (molc->totalSquareOverlap() - tsqo0) / dx; - } - TS_ASSERT(R3::norm(gn1) > 1.0); - TS_ASSERT_DELTA(0.0, R3::norm(gn1 - g[1]), 1e-5); - TS_ASSERT_DELTA(0.0, R3::norm(g[0] + g[1]), 1e-5); - } - - - void test_bccTouch() - { - using namespace boost; - PeriodicStructureAdapterPtr bcc(new PeriodicStructureAdapter); - bcc->setLatPar(2.0, 2.0, 2.0, 90, 90, 90); - Atom a; - a.atomtype = "C"; - bcc->append(a); - a.xyz_cartn = R3::Vector(0.5, 0.5, 0.5); - bcc->toCartesian(a); - bcc->append(a); - molc->getAtomRadiiTable()->setCustom("C", 1.0); - molc->eval(bcc); - TS_ASSERT_EQUALS(2, molc->getStructure()->countSites()); - TS_ASSERT_EQUALS(8 * pow(2.0 - sqrt(3.0), 2), - molc->totalSquareOverlap()); - // gradient is zero due to bcc symmetry - std::vector g = molc->gradients(); - TS_ASSERT_DELTA(0.0, R3::norm(g[0]), meps); - TS_ASSERT_DELTA(0.0, R3::norm(g[1]), meps); - // move the second atom so it touches only one ball - bcc->at(1).xyz_cartn = R3::Vector(-0.25, 0.0, 0.0); - bcc->toCartesian(bcc->at(1)); - molc->eval(bcc); - double tsqo = 1.5 * 1.5 + 0.5 * 0.5; - TS_ASSERT_DELTA(tsqo, molc->totalSquareOverlap(), meps); - g = molc->gradients(); - TS_ASSERT_EQUALS(2u, g.size()); - double gx = 1.5 + 0.5; - TS_ASSERT_DELTA(-gx, g[0][0], meps); - TS_ASSERT_DELTA(0.0, g[0][1], meps); - TS_ASSERT_DELTA(0.0, g[0][2], meps); - TS_ASSERT_DELTA(+gx, g[1][0], meps); - TS_ASSERT_DELTA(0.0, g[1][1], meps); - TS_ASSERT_DELTA(0.0, g[1][2], meps); - }; - - - void test_NaCl_overlap() - { - double olp = pow(3.3 - 5.62 / 2, 2) * 6 / 2; - molc->eval(mnacl); - TS_ASSERT_DELTA(olp, molc->meanSquareOverlap(), meps); - QuantityType sqolps = molc->siteSquareOverlaps(); - TS_ASSERT_EQUALS(8u, sqolps.size()); - for (int i = 0; i < 8; ++i) - { - TS_ASSERT_DELTA(olp, sqolps[i], meps); - } - } - - - void test_NaCl_flips() - { - molc->eval(mnacl); - // flipping the same type should not change the cost - TS_ASSERT_EQUALS(0.0, molc->flipDiffTotal(0, 0)); - TS_ASSERT_EQUALS(0.0, molc->flipDiffTotal(0, 1)); - TS_ASSERT_EQUALS(0.0, molc->flipDiffTotal(0, 2)); - TS_ASSERT_EQUALS(0.0, molc->flipDiffTotal(0, 3)); - // flipping with the second Cl neighbor - TS_ASSERT_DELTA(1.08, molc->flipDiffTotal(0, 4), meps); - TS_ASSERT_DELTA(1.08 / 8, molc->flipDiffMean(0, 4), meps); - // flipping with the nearest Cl neighbor - TS_ASSERT_DELTA(0.72, molc->flipDiffTotal(0, 5), meps); - TS_ASSERT_DELTA(0.72, molc->flipDiffTotal(0, 6), meps); - TS_ASSERT_DELTA(0.72, molc->flipDiffTotal(0, 7), meps); - } - - - void test_NaCl_gradient() - { - using namespace boost; - molc->eval(mnacl); - // default gradients are all zero - std::vector g = molc->gradients(); - TS_ASSERT_EQUALS(8u, g.size()); - for (int i = 0; i < 8; ++i) - { - TS_ASSERT_DELTA(0.0, R3::norm(g[i]), meps); - } - StructureAdapterPtr nacl1 = mnacl->clone(); - PeriodicStructureAdapter& nacl1ref = - static_cast(*nacl1); - R3::Vector& xyzc0 = nacl1ref[0].xyz_cartn; - xyzc0 = R3::Vector(0.02, 0.03, 0.07); - molc->eval(nacl1); - double c0 = molc->totalSquareOverlap(); - R3::Vector g0 = molc->gradients()[0]; - TS_ASSERT(R3::norm(g0) > meps); - R3::Vector g0n; - const double dx = 1e-8; - for (int i = 0; i < R3::Ndim; ++i) - { - xyzc0[i] += dx; - molc->eval(nacl1); - g0n[i] = (molc->totalSquareOverlap() - c0) / dx; - xyzc0[i] -= dx; - } - TS_ASSERT_DELTA(0.0, R3::norm(g0 - g0n), 1e-6); - } - - - void test_getNeighborSites() - { - molc->eval(mnacl); - auto nbsites = molc->getNeighborSites(0); - TS_ASSERT_EQUALS(3u, nbsites.size()); - for (int j = 5; j < 8; ++j) { - TS_ASSERT(nbsites.count(j)); - } - } - - - void test_coordinations() - { - using std::placeholders::_1; - molc->eval(mnacl); - auto cnums = molc->coordinations(); - TS_ASSERT_EQUALS(8u, cnums.size()); - auto eq6 = bind(equal_to(), _1, 6.0); - TS_ASSERT(all_of(cnums.begin(), cnums.end(), eq6)); - } - - - void test_coordinationByTypes() - { - molc->eval(mnacl); - auto cbtb0 = molc->coordinationByTypes(0); - auto cbtb3 = molc->coordinationByTypes(3); - auto cbtb5 = molc->coordinationByTypes(5); - TS_ASSERT_EQUALS(1u, cbtb0.size()) - TS_ASSERT_EQUALS(1u, cbtb5.size()) - TS_ASSERT_EQUALS(cbtb0, cbtb3); - TS_ASSERT_EQUALS(6, cbtb0.at("Cl1-")); - TS_ASSERT_EQUALS(6, cbtb5.at("Na1+")); - } - - - void test_neighborhoods() - { - auto tb = molc->getAtomRadiiTable(); - molc->eval(mnacl); - auto nbhood = molc->neighborhoods(); - TS_ASSERT_EQUALS(1u, nbhood.size()); - TS_ASSERT_EQUALS(8u, nbhood[0].size()); - tb->resetAll(); - molc->eval(mnacl); - auto nbsep = molc->neighborhoods(); - TS_ASSERT_EQUALS(8u, nbsep.size()); - int nb5site = *(nbsep[5].begin()); - TS_ASSERT_EQUALS(5, nb5site); - molc->maskAllPairs(false); - molc->eval(mnacl); - auto nbdark = molc->neighborhoods(); - TS_ASSERT(nbdark.empty()); - molc->setTypeMask("Na1+", "Na1+", true); - molc->eval(mnacl); - auto nbnanasep = molc->neighborhoods(); - TS_ASSERT_EQUALS(4u, nbnanasep.size()); - int nb3site = *(nbnanasep[3].begin()); - TS_ASSERT_EQUALS(3, nb3site); - tb->setCustom("Na1+", 5); - tb->setCustom("Cl1-", 5); - molc->eval(mnacl); - auto nbnana = molc->neighborhoods(); - TS_ASSERT_EQUALS(1u, nbnana.size()); - TS_ASSERT_EQUALS(4u, nbnana[0].size()); - TS_ASSERT(nbnana[0].count(0)); - TS_ASSERT(!nbnana[0].count(4)); - } - - - void test_NaCl_mixed_overlap() - { - StructureAdapterPtr nacl_mixed; - nacl_mixed = loadTestPeriodicStructure("NaCl_mixed.stru"); - molc->eval(nacl_mixed); - double olp = pow(3.3 - 5.62 / 2, 2) * 6 / 2; - TS_ASSERT_DELTA(olp, molc->meanSquareOverlap(), meps); - } - - - void test_serialization() - { - // build customized PDFCalculator - AtomicStructureAdapterPtr stru(new AtomicStructureAdapter); - Atom a0, a1; - a0.xyz_cartn = R3::Vector(0.0, 0.0, 0.0); - a1.xyz_cartn = R3::Vector(0.0, 0.0, 1.5); - stru->append(a0); - stru->append(a1); - molc->eval(stru); - boost::shared_ptr olc1; - olc1 = dumpandload(molc); - TS_ASSERT_DIFFERS(molc.get(), olc1.get()); - TS_ASSERT_EQUALS(2, olc1->getStructure()->countSites()); - TS_ASSERT_EQUALS(0.25, olc1->totalSquareOverlap()); - QuantityType sqolps = molc->siteSquareOverlaps(); - TS_ASSERT_EQUALS(2u, olc1->siteSquareOverlaps().size()); - TS_ASSERT_EQUALS(0.125, olc1->siteSquareOverlaps()[0]); - TS_ASSERT_EQUALS(0.125, olc1->siteSquareOverlaps()[1]); - } +class TestOverlapCalculator : public CxxTest::TestSuite { + private: + boost::shared_ptr molc; + StructureAdapterPtr mnacl; + double meps; + + public: + void setUp() { + CxxTest::setAbortTestOnFail(true); + meps = diffpy::mathutils::SQRT_DOUBLE_EPS; + molc.reset(new OverlapCalculator); + molc->getAtomRadiiTable()->setCustom("", 1.0); + molc->getAtomRadiiTable()->setCustom("Na1+", 1.5); + molc->getAtomRadiiTable()->setCustom("Cl1-", 1.8); + if (!mnacl) mnacl = loadTestPeriodicStructure("NaCl.stru"); + CxxTest::setAbortTestOnFail(true); + } + + void test_rmin() { + molc->eval(mnacl); + TS_ASSERT(molc->distances().size()); + double tot = molc->totalSquareOverlap(); + TS_ASSERT_LESS_THAN(0.0, tot); + molc->setRmin(10); + molc->eval(); + TS_ASSERT(molc->distances().empty()); + TS_ASSERT_EQUALS(0.0, molc->totalSquareOverlap()); + molc->setRmin(2); + molc->eval(); + TS_ASSERT_EQUALS(tot, molc->totalSquareOverlap()); + } + + void test_rmax() { + molc->setRmax(2.5); + molc->eval(mnacl); + TS_ASSERT(molc->distances().empty()) + TS_ASSERT_EQUALS(0.0, molc->totalSquareOverlap()); + } + + void test_lineNoTouch() { + AtomicStructureAdapterPtr stru(new AtomicStructureAdapter); + Atom a0, a1; + a0.xyz_cartn = R3::Vector(0.0, 0.0, 0.0); + a1.xyz_cartn = R3::Vector(0.0, 0.0, 2.0); + stru->append(a0); + stru->append(a1); + molc->eval(stru); + TS_ASSERT_EQUALS(0.0, molc->totalSquareOverlap()); + QuantityType sqolps = molc->siteSquareOverlaps(); + TS_ASSERT_EQUALS(2u, sqolps.size()); + TS_ASSERT_EQUALS(0.0, sqolps[0]); + TS_ASSERT_EQUALS(0.0, sqolps[1]); + TS_ASSERT_EQUALS(0.0, molc->flipDiffTotal(0, 0)); + TS_ASSERT_EQUALS(0.0, molc->flipDiffTotal(0, 1)); + std::vector g = molc->gradients(); + TS_ASSERT_EQUALS(2u, g.size()); + TS_ASSERT_EQUALS(0.0, R3::norm(g[0])); + TS_ASSERT_EQUALS(0.0, R3::norm(g[1])); + } + + void test_lineTouch() { + AtomicStructureAdapterPtr stru(new AtomicStructureAdapter); + Atom a0, a1; + a0.xyz_cartn = R3::Vector(0.0, 0.0, 0.0); + a1.xyz_cartn = R3::Vector(0.0, 0.0, 1.5); + stru->append(a0); + stru->append(a1); + molc->eval(stru); + TS_ASSERT_EQUALS(0.25, molc->totalSquareOverlap()); + QuantityType sqolps = molc->siteSquareOverlaps(); + TS_ASSERT_EQUALS(2u, sqolps.size()); + TS_ASSERT_EQUALS(0.125, sqolps[0]); + TS_ASSERT_EQUALS(0.125, sqolps[1]); + TS_ASSERT_EQUALS(0.0, molc->flipDiffTotal(0, 1)); + std::vector g = molc->gradients(); + TS_ASSERT_EQUALS(2u, g.size()); + R3::Vector g0(0.0, 0.0, +1); + TS_ASSERT_EQUALS(0.0, R3::distance(g0, g[0])); + R3::Vector g1(0.0, 0.0, -1); + TS_ASSERT_EQUALS(0.0, R3::distance(g1, g[1])); + } + + void test_gradients() { + AtomicStructureAdapterPtr stru(new AtomicStructureAdapter); + Atom a0, a1; + a0.xyz_cartn = R3::Vector(0.0, 0.0, 0.0); + a1.xyz_cartn = R3::Vector(0.17, 0.31, 0.37); + stru->append(a0); + stru->append(a1); + molc->eval(stru); + std::vector g = molc->gradients(); + double dx = 1e-6; + double tsqo0 = molc->totalSquareOverlap(); + R3::Vector r1 = stru->siteCartesianPosition(1); + R3::Vector gn1; + for (int k = 0; k != R3::Ndim; ++k) { + R3::Vector& xyz1 = stru->at(1).xyz_cartn; + xyz1 = r1; + xyz1[k] += dx; + molc->eval(stru); + gn1[k] = (molc->totalSquareOverlap() - tsqo0) / dx; + } + TS_ASSERT(R3::norm(gn1) > 1.0); + TS_ASSERT_DELTA(0.0, R3::norm(gn1 - g[1]), 1e-5); + TS_ASSERT_DELTA(0.0, R3::norm(g[0] + g[1]), 1e-5); + } + + void test_bccTouch() { + using namespace boost; + PeriodicStructureAdapterPtr bcc(new PeriodicStructureAdapter); + bcc->setLatPar(2.0, 2.0, 2.0, 90, 90, 90); + Atom a; + a.atomtype = "C"; + bcc->append(a); + a.xyz_cartn = R3::Vector(0.5, 0.5, 0.5); + bcc->toCartesian(a); + bcc->append(a); + molc->getAtomRadiiTable()->setCustom("C", 1.0); + molc->eval(bcc); + TS_ASSERT_EQUALS(2, molc->getStructure()->countSites()); + TS_ASSERT_EQUALS(8 * pow(2.0 - sqrt(3.0), 2), molc->totalSquareOverlap()); + // gradient is zero due to bcc symmetry + std::vector g = molc->gradients(); + TS_ASSERT_DELTA(0.0, R3::norm(g[0]), meps); + TS_ASSERT_DELTA(0.0, R3::norm(g[1]), meps); + // move the second atom so it touches only one ball + bcc->at(1).xyz_cartn = R3::Vector(-0.25, 0.0, 0.0); + bcc->toCartesian(bcc->at(1)); + molc->eval(bcc); + double tsqo = 1.5 * 1.5 + 0.5 * 0.5; + TS_ASSERT_DELTA(tsqo, molc->totalSquareOverlap(), meps); + g = molc->gradients(); + TS_ASSERT_EQUALS(2u, g.size()); + double gx = 1.5 + 0.5; + TS_ASSERT_DELTA(-gx, g[0][0], meps); + TS_ASSERT_DELTA(0.0, g[0][1], meps); + TS_ASSERT_DELTA(0.0, g[0][2], meps); + TS_ASSERT_DELTA(+gx, g[1][0], meps); + TS_ASSERT_DELTA(0.0, g[1][1], meps); + TS_ASSERT_DELTA(0.0, g[1][2], meps); + }; + + void test_NaCl_overlap() { + double olp = pow(3.3 - 5.62 / 2, 2) * 6 / 2; + molc->eval(mnacl); + TS_ASSERT_DELTA(olp, molc->meanSquareOverlap(), meps); + QuantityType sqolps = molc->siteSquareOverlaps(); + TS_ASSERT_EQUALS(8u, sqolps.size()); + for (int i = 0; i < 8; ++i) { + TS_ASSERT_DELTA(olp, sqolps[i], meps); + } + } + + void test_NaCl_flips() { + molc->eval(mnacl); + // flipping the same type should not change the cost + TS_ASSERT_EQUALS(0.0, molc->flipDiffTotal(0, 0)); + TS_ASSERT_EQUALS(0.0, molc->flipDiffTotal(0, 1)); + TS_ASSERT_EQUALS(0.0, molc->flipDiffTotal(0, 2)); + TS_ASSERT_EQUALS(0.0, molc->flipDiffTotal(0, 3)); + // flipping with the second Cl neighbor + TS_ASSERT_DELTA(1.08, molc->flipDiffTotal(0, 4), meps); + TS_ASSERT_DELTA(1.08 / 8, molc->flipDiffMean(0, 4), meps); + // flipping with the nearest Cl neighbor + TS_ASSERT_DELTA(0.72, molc->flipDiffTotal(0, 5), meps); + TS_ASSERT_DELTA(0.72, molc->flipDiffTotal(0, 6), meps); + TS_ASSERT_DELTA(0.72, molc->flipDiffTotal(0, 7), meps); + } + + void test_NaCl_gradient() { + using namespace boost; + molc->eval(mnacl); + // default gradients are all zero + std::vector g = molc->gradients(); + TS_ASSERT_EQUALS(8u, g.size()); + for (int i = 0; i < 8; ++i) { + TS_ASSERT_DELTA(0.0, R3::norm(g[i]), meps); + } + StructureAdapterPtr nacl1 = mnacl->clone(); + PeriodicStructureAdapter& nacl1ref = + static_cast(*nacl1); + R3::Vector& xyzc0 = nacl1ref[0].xyz_cartn; + xyzc0 = R3::Vector(0.02, 0.03, 0.07); + molc->eval(nacl1); + double c0 = molc->totalSquareOverlap(); + R3::Vector g0 = molc->gradients()[0]; + TS_ASSERT(R3::norm(g0) > meps); + R3::Vector g0n; + const double dx = 1e-8; + for (int i = 0; i < R3::Ndim; ++i) { + xyzc0[i] += dx; + molc->eval(nacl1); + g0n[i] = (molc->totalSquareOverlap() - c0) / dx; + xyzc0[i] -= dx; + } + TS_ASSERT_DELTA(0.0, R3::norm(g0 - g0n), 1e-6); + } + + void test_getNeighborSites() { + molc->eval(mnacl); + auto nbsites = molc->getNeighborSites(0); + TS_ASSERT_EQUALS(3u, nbsites.size()); + for (int j = 5; j < 8; ++j) { + TS_ASSERT(nbsites.count(j)); + } + } + + void test_coordinations() { + using std::placeholders::_1; + molc->eval(mnacl); + auto cnums = molc->coordinations(); + TS_ASSERT_EQUALS(8u, cnums.size()); + auto eq6 = bind(equal_to(), _1, 6.0); + TS_ASSERT(all_of(cnums.begin(), cnums.end(), eq6)); + } + + void test_coordinationByTypes() { + molc->eval(mnacl); + auto cbtb0 = molc->coordinationByTypes(0); + auto cbtb3 = molc->coordinationByTypes(3); + auto cbtb5 = molc->coordinationByTypes(5); + TS_ASSERT_EQUALS(1u, cbtb0.size()) + TS_ASSERT_EQUALS(1u, cbtb5.size()) + TS_ASSERT_EQUALS(cbtb0, cbtb3); + TS_ASSERT_EQUALS(6, cbtb0.at("Cl1-")); + TS_ASSERT_EQUALS(6, cbtb5.at("Na1+")); + } + + void test_neighborhoods() { + auto tb = molc->getAtomRadiiTable(); + molc->eval(mnacl); + auto nbhood = molc->neighborhoods(); + TS_ASSERT_EQUALS(1u, nbhood.size()); + TS_ASSERT_EQUALS(8u, nbhood[0].size()); + tb->resetAll(); + molc->eval(mnacl); + auto nbsep = molc->neighborhoods(); + TS_ASSERT_EQUALS(8u, nbsep.size()); + int nb5site = *(nbsep[5].begin()); + TS_ASSERT_EQUALS(5, nb5site); + molc->maskAllPairs(false); + molc->eval(mnacl); + auto nbdark = molc->neighborhoods(); + TS_ASSERT(nbdark.empty()); + molc->setTypeMask("Na1+", "Na1+", true); + molc->eval(mnacl); + auto nbnanasep = molc->neighborhoods(); + TS_ASSERT_EQUALS(4u, nbnanasep.size()); + int nb3site = *(nbnanasep[3].begin()); + TS_ASSERT_EQUALS(3, nb3site); + tb->setCustom("Na1+", 5); + tb->setCustom("Cl1-", 5); + molc->eval(mnacl); + auto nbnana = molc->neighborhoods(); + TS_ASSERT_EQUALS(1u, nbnana.size()); + TS_ASSERT_EQUALS(4u, nbnana[0].size()); + TS_ASSERT(nbnana[0].count(0)); + TS_ASSERT(!nbnana[0].count(4)); + } + + void test_NaCl_mixed_overlap() { + StructureAdapterPtr nacl_mixed; + nacl_mixed = loadTestPeriodicStructure("NaCl_mixed.stru"); + molc->eval(nacl_mixed); + double olp = pow(3.3 - 5.62 / 2, 2) * 6 / 2; + TS_ASSERT_DELTA(olp, molc->meanSquareOverlap(), meps); + } + + void test_serialization() { + // build customized PDFCalculator + AtomicStructureAdapterPtr stru(new AtomicStructureAdapter); + Atom a0, a1; + a0.xyz_cartn = R3::Vector(0.0, 0.0, 0.0); + a1.xyz_cartn = R3::Vector(0.0, 0.0, 1.5); + stru->append(a0); + stru->append(a1); + molc->eval(stru); + boost::shared_ptr olc1; + olc1 = dumpandload(molc); + TS_ASSERT_DIFFERS(molc.get(), olc1.get()); + TS_ASSERT_EQUALS(2, olc1->getStructure()->countSites()); + TS_ASSERT_EQUALS(0.25, olc1->totalSquareOverlap()); + QuantityType sqolps = molc->siteSquareOverlaps(); + TS_ASSERT_EQUALS(2u, olc1->siteSquareOverlaps().size()); + TS_ASSERT_EQUALS(0.125, olc1->siteSquareOverlaps()[0]); + TS_ASSERT_EQUALS(0.125, olc1->siteSquareOverlaps()[1]); + } }; // class TestOverlapCalculator diff --git a/src/tests/TestPDFBaseline.hpp b/src/tests/TestPDFBaseline.hpp index 34494f9e..2be1d58a 100644 --- a/src/tests/TestPDFBaseline.hpp +++ b/src/tests/TestPDFBaseline.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy Complex Modeling Initiative -* (c) 2019 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. -* -****************************************************************************** -* -* class TestPDFBaseline -- test PDFBaseline and derived classes -* -*****************************************************************************/ + * + * libdiffpy Complex Modeling Initiative + * (c) 2019 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. + * + ****************************************************************************** + * + * class TestPDFBaseline -- test PDFBaseline and derived classes + * + *****************************************************************************/ #include @@ -30,70 +30,58 @@ namespace srreal { // class TestPDFBaseline ////////////////////////////////////////////////////////////////////////////// -class TestPDFBaseline : public CxxTest::TestSuite -{ - private: - - // data - PDFBaselinePtr ml; - LinearBaseline* mcl; - PDFBaselinePtr mz; - ZeroBaseline* mcz; - - public: - - void setUp() - { - ml = PDFBaseline::createByType("linear"); - mcl = static_cast(ml.get()); - mz = PDFBaseline::createByType("zero"); - mcz = static_cast(mz.get()); - } - - - void test_clone() - { - TS_ASSERT_EQUALS("linear", ml->clone()->type()); - TS_ASSERT_EQUALS("zero", mz->clone()->type()); - } - - - void test_attributes() - { - TS_ASSERT_EQUALS(1, ml->namesOfDoubleAttributes().size()); - TS_ASSERT_EQUALS(0, mz->namesOfDoubleAttributes().size()); - mcl->setSlope(0.1); - TS_ASSERT_EQUALS(0.1, ml->getDoubleAttr("slope")); - ml->setDoubleAttr("slope", 0.2); - TS_ASSERT_EQUALS(0.2, mcl->getSlope()); - } - - - void test_calculate() - { - TS_ASSERT_EQUALS(0.0, (*ml)(2.0)); - TS_ASSERT_EQUALS(0.0, (*mz)(2.0)); - mcl->setSlope(-2); - TS_ASSERT_EQUALS(-4.0, (*ml)(2.0)); - } - - - void test_serialization() - { - mcl->setSlope(0.3); - PDFBaselinePtr bl1 = dumpandload(ml); - LinearBaseline* cbl1 = dynamic_cast(bl1.get()); - TS_ASSERT(cbl1); - TS_ASSERT_EQUALS(0.3, cbl1->getSlope()); - PDFBaselinePtr bz1 = dumpandload(mz); - ZeroBaseline* cbz1 = dynamic_cast(bz1.get()); - TS_ASSERT(cbz1); - } +class TestPDFBaseline : public CxxTest::TestSuite { + private: + // data + PDFBaselinePtr ml; + LinearBaseline* mcl; + PDFBaselinePtr mz; + ZeroBaseline* mcz; + + public: + void setUp() { + ml = PDFBaseline::createByType("linear"); + mcl = static_cast(ml.get()); + mz = PDFBaseline::createByType("zero"); + mcz = static_cast(mz.get()); + } + + void test_clone() { + TS_ASSERT_EQUALS("linear", ml->clone()->type()); + TS_ASSERT_EQUALS("zero", mz->clone()->type()); + } + + void test_attributes() { + TS_ASSERT_EQUALS(1, ml->namesOfDoubleAttributes().size()); + TS_ASSERT_EQUALS(0, mz->namesOfDoubleAttributes().size()); + mcl->setSlope(0.1); + TS_ASSERT_EQUALS(0.1, ml->getDoubleAttr("slope")); + ml->setDoubleAttr("slope", 0.2); + TS_ASSERT_EQUALS(0.2, mcl->getSlope()); + } + + void test_calculate() { + TS_ASSERT_EQUALS(0.0, (*ml)(2.0)); + TS_ASSERT_EQUALS(0.0, (*mz)(2.0)); + mcl->setSlope(-2); + TS_ASSERT_EQUALS(-4.0, (*ml)(2.0)); + } + + void test_serialization() { + mcl->setSlope(0.3); + PDFBaselinePtr bl1 = dumpandload(ml); + LinearBaseline* cbl1 = dynamic_cast(bl1.get()); + TS_ASSERT(cbl1); + TS_ASSERT_EQUALS(0.3, cbl1->getSlope()); + PDFBaselinePtr bz1 = dumpandload(mz); + ZeroBaseline* cbz1 = dynamic_cast(bz1.get()); + TS_ASSERT(cbz1); + } }; // class TestPDFBaseline -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy using diffpy::srreal::TestPDFBaseline; diff --git a/src/tests/TestPDFCalculator.hpp b/src/tests/TestPDFCalculator.hpp index ff70c7ad..f02be8e3 100644 --- a/src/tests/TestPDFCalculator.hpp +++ b/src/tests/TestPDFCalculator.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class TestPDFCalculator -- unit tests for PDFCalculator class -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class TestPDFCalculator -- unit tests for PDFCalculator class + * + *****************************************************************************/ #include @@ -29,254 +29,210 @@ using namespace std; using namespace diffpy::srreal; -class TestPDFCalculator : public CxxTest::TestSuite -{ - private: - - boost::shared_ptr mpdfc; - StructureAdapterPtr memptystru; - double meps; - double mepsdb; - - public: - - void setUp() - { - memptystru = emptyStructureAdapter(); - meps = diffpy::mathutils::SQRT_DOUBLE_EPS; - mepsdb = 10 * diffpy::mathutils::DOUBLE_EPS; - mpdfc.reset(new PDFCalculator); - } - - - void test_setPeakWidthModel() - { - const PeakWidthModelPtr& jpw0 = mpdfc->getPeakWidthModel(); - TS_ASSERT_EQUALS(0.0, jpw0->getDoubleAttr("delta1")); - TS_ASSERT_EQUALS(0.0, jpw0->getDoubleAttr("delta2")); - TS_ASSERT_EQUALS(0.0, jpw0->getDoubleAttr("qbroad")); - TS_ASSERT_EQUALS(0.0, jpw0->getDoubleAttr("qbroad_seperable")); - JeongPeakWidth jpw; - jpw.setDelta1(1.0); - jpw.setDelta2(2.0); - jpw.setQbroad(3.0); - jpw.setQbroad_seperable(4.0); - mpdfc->setPeakWidthModel(jpw.clone()); - const PeakWidthModelPtr& jpw1 = mpdfc->getPeakWidthModel(); - TS_ASSERT_EQUALS(1.0, jpw1->getDoubleAttr("delta1")); - TS_ASSERT_EQUALS(2.0, jpw1->getDoubleAttr("delta2")); - TS_ASSERT_EQUALS(3.0, jpw1->getDoubleAttr("qbroad")); - TS_ASSERT_EQUALS(4.0, jpw1->getDoubleAttr("qbroad_seperable")); - } - - - void test_getPeakWidthModel() - { - string tp = "jeong"; - TS_ASSERT_EQUALS(tp, mpdfc->getPeakWidthModel()->type()); - PeakWidthModelPtr pwm(PeakWidthModel::createByType("debye-waller")); - mpdfc->setPeakWidthModel(pwm); - tp = "debye-waller"; - TS_ASSERT_EQUALS(tp, mpdfc->getPeakWidthModel()->type()); - mpdfc->setPeakWidthModel(ConstantPeakWidth().clone()); - tp = "constant"; - TS_ASSERT_EQUALS(tp, mpdfc->getPeakWidthModel()->type()); - } - - - void test_access_PeakProfile() - { - PeakProfilePtr pkf(mpdfc->getPeakProfile()->clone()); - pkf->setPrecision(1.1); - mpdfc->setPeakProfile(pkf); - TS_ASSERT_EQUALS(1.1, mpdfc->getPeakProfile()->getPrecision()); - TS_ASSERT_EQUALS(1.1, mpdfc->getDoubleAttr("peakprecision")); - mpdfc->setDoubleAttr("peakprecision", 0.2); - TS_ASSERT_EQUALS(0.2, mpdfc->getDoubleAttr("peakprecision")); - TS_ASSERT_EQUALS(pkf->type(), mpdfc->getPeakProfile()->type()); - mpdfc->setPeakProfileByType("gaussian"); - TS_ASSERT_EQUALS(0.2, mpdfc->getDoubleAttr("peakprecision")); - TS_ASSERT_THROWS(mpdfc->setPeakProfileByType("invalid"), - logic_error); - } - - - void test_access_Envelopes() - { - TS_ASSERT_EQUALS(2u, mpdfc->usedEnvelopeTypes().size()); - TS_ASSERT_EQUALS(1.0, mpdfc->getDoubleAttr("scale")); - TS_ASSERT_EQUALS(0.0, mpdfc->getDoubleAttr("qdamp")); - mpdfc->setDoubleAttr("scale", 3.0); - TS_ASSERT_EQUALS(3.0, mpdfc->getDoubleAttr("scale")); - mpdfc->addEnvelopeByType("scale"); - TS_ASSERT_EQUALS(1.0, mpdfc->getDoubleAttr("scale")); - QResolutionEnvelope qdamp4; - qdamp4.setQdamp(4); - mpdfc->addEnvelope(qdamp4.clone()); - TS_ASSERT_EQUALS(4.0, mpdfc->getDoubleAttr("qdamp")); - TS_ASSERT_THROWS(mpdfc->addEnvelopeByType("invalid"), logic_error); - } - - - void test_getPDF() - { - QuantityType pdf; - pdf = mpdfc->getPDF(); - TS_ASSERT_EQUALS(1000u, pdf.size()); - mpdfc->setRmin(2.0); - mpdfc->setRmax(0.0); - mpdfc->eval(memptystru); - pdf = mpdfc->getPDF(); - TS_ASSERT(pdf.empty()); - mpdfc->setRmax(2.0); - mpdfc->eval(memptystru); - pdf = mpdfc->getPDF(); - TS_ASSERT(pdf.empty()); - mpdfc->setRmax(2.01001); - mpdfc->eval(memptystru); - pdf = mpdfc->getPDF(); - TS_ASSERT_EQUALS(2u, pdf.size()); - TS_ASSERT_EQUALS(0.0, pdf[0]); - TS_ASSERT_EQUALS(0.0, pdf[1]); - } - - - void test_getRDF() - { - QuantityType rdf = mpdfc->getRDF(); - TS_ASSERT_EQUALS(1000u, rdf.size()); - TS_ASSERT_EQUALS(0.0, *min_element(rdf.begin(), rdf.end())); - TS_ASSERT_EQUALS(0.0, *max_element(rdf.begin(), rdf.end())); - mpdfc->eval(memptystru); - rdf = mpdfc->getRDF(); - TS_ASSERT_EQUALS(1000u, rdf.size()); - TS_ASSERT_EQUALS(0.0, *min_element(rdf.begin(), rdf.end())); - TS_ASSERT_EQUALS(0.0, *max_element(rdf.begin(), rdf.end())); - mpdfc->setRmin(2.0); - mpdfc->setRmax(0.0); - mpdfc->eval(memptystru); - rdf = mpdfc->getRDF(); - TS_ASSERT(rdf.empty()); - mpdfc->setRmax(2.01001); - mpdfc->eval(memptystru); - rdf = mpdfc->getRDF(); - TS_ASSERT_EQUALS(2u, rdf.size()); - TS_ASSERT_EQUALS(0.0, rdf[0]); - TS_ASSERT_EQUALS(0.0, rdf[1]); - - } - - - void test_getF() - { - QuantityType fq = mpdfc->getF(); - TS_ASSERT_EQUALS(1024u, fq.size()); - TS_ASSERT_EQUALS(0.0, *min_element(fq.begin(), fq.end())); - TS_ASSERT_EQUALS(0.0, *max_element(fq.begin(), fq.end())); - } - - - void test_getQgrid() - { - TS_ASSERT_EQUALS(1024u, mpdfc->getQgrid().size()); - } - - - void test_getQmin() - { - TS_ASSERT_EQUALS(0.0, mpdfc->getQmin()); - } - - - void test_getQmax() - { - TS_ASSERT_DELTA(100 * M_PI, mpdfc->getQmax(), meps); - } - - - void test_getQstep() - { - const double qstep0 = 100 * M_PI / 1024; - const double qstep1 = 100 * M_PI / 2048; - const double qstep2 = 100 * M_PI / 4096; - const double qstep3 = M_PI / (1024 * 0.03); - TS_ASSERT_DELTA(qstep0, mpdfc->getQstep(), meps); - mpdfc->setRmax(20); - TS_ASSERT_DELTA(qstep1, mpdfc->getQstep(), meps); - mpdfc->setQmax(10); - TS_ASSERT_DELTA(qstep2, mpdfc->getQstep(), meps); - mpdfc->setRstep(0.03); - TS_ASSERT_DELTA(qstep3, mpdfc->getQstep(), meps); - // test qstep after evaluation of some structure. - StructureAdapterPtr catio3; - catio3 = loadTestPeriodicStructure("CaTiO3.stru"); - mpdfc->eval(catio3); - TS_ASSERT_DELTA(qstep3, mpdfc->getQstep(), meps); - // now qstep is not updated because of non-trivial structure. - mpdfc->setRstep(0.01); - TS_ASSERT_DIFFERS(qstep2, mpdfc->getQstep()); - // qstep is correct after calculation. - mpdfc->eval(); - TS_ASSERT_DELTA(qstep2, mpdfc->getQstep(), meps); - } - - - void test_getRgrid() - { - QuantityType rgrid0 = mpdfc->getRgrid(); - TS_ASSERT_EQUALS(rgrid0, mpdfc->getRgrid()); - mpdfc->setRmin(5); - mpdfc->setRmax(4); - TS_ASSERT(mpdfc->getRgrid().empty()); - } - - - void test_getExtendedRmin() - { - // empty structure should not extend the grid at all. - TS_ASSERT_EQUALS(0.0, mpdfc->getExtendedRmin()); - mpdfc->setRmin(5); - mpdfc->eval(memptystru); - TS_ASSERT_DELTA(5.0, mpdfc->getExtendedRmin(), mepsdb); - } - - - void test_getExtendedRmax() - { - // empty structure should not extend the grid at all. - TS_ASSERT_DELTA(10.0, mpdfc->getExtendedRmax(), mepsdb); - mpdfc->setRmax(7); - mpdfc->eval(memptystru); - TS_ASSERT_DELTA(7.0, mpdfc->getExtendedRmax(), mepsdb); - } - - - void test_serialization() - { - // build customized PDFCalculator - mpdfc->setPeakWidthModelByType("constant"); - mpdfc->setDoubleAttr("width", 0.123); - mpdfc->setPeakProfileByType("gaussian"); - mpdfc->setDoubleAttr("peakprecision", 0.011); - mpdfc->setScatteringFactorTableByType("electronnumber"); - mpdfc->getScatteringFactorTable()->setCustomAs("H", "H", 1.1); - // dump it to string - stringstream storage(ios::in | ios::out | ios::binary); - diffpy::serialization::oarchive oa(storage, ios::binary); - oa << mpdfc; - diffpy::serialization::iarchive ia(storage, ios::binary); - boost::shared_ptr pdfc1; - ia >> pdfc1; - TS_ASSERT_DIFFERS(pdfc1.get(), mpdfc.get()); - TS_ASSERT_EQUALS(string("constant"), - pdfc1->getPeakWidthModel()->type()); - TS_ASSERT_EQUALS(0.123, pdfc1->getDoubleAttr("width")); - TS_ASSERT_EQUALS(0.011, pdfc1->getDoubleAttr("peakprecision")); - TS_ASSERT_EQUALS(string("electronnumber"), - pdfc1->getScatteringFactorTable()->type()); - TS_ASSERT_EQUALS(1.1, - pdfc1->getScatteringFactorTable()->lookup("H")); - } +class TestPDFCalculator : public CxxTest::TestSuite { + private: + boost::shared_ptr mpdfc; + StructureAdapterPtr memptystru; + double meps; + double mepsdb; + + public: + void setUp() { + memptystru = emptyStructureAdapter(); + meps = diffpy::mathutils::SQRT_DOUBLE_EPS; + mepsdb = 10 * diffpy::mathutils::DOUBLE_EPS; + mpdfc.reset(new PDFCalculator); + } + + void test_setPeakWidthModel() { + const PeakWidthModelPtr& jpw0 = mpdfc->getPeakWidthModel(); + TS_ASSERT_EQUALS(0.0, jpw0->getDoubleAttr("delta1")); + TS_ASSERT_EQUALS(0.0, jpw0->getDoubleAttr("delta2")); + TS_ASSERT_EQUALS(0.0, jpw0->getDoubleAttr("qbroad")); + TS_ASSERT_EQUALS(0.0, jpw0->getDoubleAttr("qbroad_seperable")); + JeongPeakWidth jpw; + jpw.setDelta1(1.0); + jpw.setDelta2(2.0); + jpw.setQbroad(3.0); + jpw.setQbroad_seperable(4.0); + mpdfc->setPeakWidthModel(jpw.clone()); + const PeakWidthModelPtr& jpw1 = mpdfc->getPeakWidthModel(); + TS_ASSERT_EQUALS(1.0, jpw1->getDoubleAttr("delta1")); + TS_ASSERT_EQUALS(2.0, jpw1->getDoubleAttr("delta2")); + TS_ASSERT_EQUALS(3.0, jpw1->getDoubleAttr("qbroad")); + TS_ASSERT_EQUALS(4.0, jpw1->getDoubleAttr("qbroad_seperable")); + } + + void test_getPeakWidthModel() { + string tp = "jeong"; + TS_ASSERT_EQUALS(tp, mpdfc->getPeakWidthModel()->type()); + PeakWidthModelPtr pwm(PeakWidthModel::createByType("debye-waller")); + mpdfc->setPeakWidthModel(pwm); + tp = "debye-waller"; + TS_ASSERT_EQUALS(tp, mpdfc->getPeakWidthModel()->type()); + mpdfc->setPeakWidthModel(ConstantPeakWidth().clone()); + tp = "constant"; + TS_ASSERT_EQUALS(tp, mpdfc->getPeakWidthModel()->type()); + } + + void test_access_PeakProfile() { + PeakProfilePtr pkf(mpdfc->getPeakProfile()->clone()); + pkf->setPrecision(1.1); + mpdfc->setPeakProfile(pkf); + TS_ASSERT_EQUALS(1.1, mpdfc->getPeakProfile()->getPrecision()); + TS_ASSERT_EQUALS(1.1, mpdfc->getDoubleAttr("peakprecision")); + mpdfc->setDoubleAttr("peakprecision", 0.2); + TS_ASSERT_EQUALS(0.2, mpdfc->getDoubleAttr("peakprecision")); + TS_ASSERT_EQUALS(pkf->type(), mpdfc->getPeakProfile()->type()); + mpdfc->setPeakProfileByType("gaussian"); + TS_ASSERT_EQUALS(0.2, mpdfc->getDoubleAttr("peakprecision")); + TS_ASSERT_THROWS(mpdfc->setPeakProfileByType("invalid"), logic_error); + } + + void test_access_Envelopes() { + TS_ASSERT_EQUALS(2u, mpdfc->usedEnvelopeTypes().size()); + TS_ASSERT_EQUALS(1.0, mpdfc->getDoubleAttr("scale")); + TS_ASSERT_EQUALS(0.0, mpdfc->getDoubleAttr("qdamp")); + mpdfc->setDoubleAttr("scale", 3.0); + TS_ASSERT_EQUALS(3.0, mpdfc->getDoubleAttr("scale")); + mpdfc->addEnvelopeByType("scale"); + TS_ASSERT_EQUALS(1.0, mpdfc->getDoubleAttr("scale")); + QResolutionEnvelope qdamp4; + qdamp4.setQdamp(4); + mpdfc->addEnvelope(qdamp4.clone()); + TS_ASSERT_EQUALS(4.0, mpdfc->getDoubleAttr("qdamp")); + TS_ASSERT_THROWS(mpdfc->addEnvelopeByType("invalid"), logic_error); + } + + void test_getPDF() { + QuantityType pdf; + pdf = mpdfc->getPDF(); + TS_ASSERT_EQUALS(1000u, pdf.size()); + mpdfc->setRmin(2.0); + mpdfc->setRmax(0.0); + mpdfc->eval(memptystru); + pdf = mpdfc->getPDF(); + TS_ASSERT(pdf.empty()); + mpdfc->setRmax(2.0); + mpdfc->eval(memptystru); + pdf = mpdfc->getPDF(); + TS_ASSERT(pdf.empty()); + mpdfc->setRmax(2.01001); + mpdfc->eval(memptystru); + pdf = mpdfc->getPDF(); + TS_ASSERT_EQUALS(2u, pdf.size()); + TS_ASSERT_EQUALS(0.0, pdf[0]); + TS_ASSERT_EQUALS(0.0, pdf[1]); + } + + void test_getRDF() { + QuantityType rdf = mpdfc->getRDF(); + TS_ASSERT_EQUALS(1000u, rdf.size()); + TS_ASSERT_EQUALS(0.0, *min_element(rdf.begin(), rdf.end())); + TS_ASSERT_EQUALS(0.0, *max_element(rdf.begin(), rdf.end())); + mpdfc->eval(memptystru); + rdf = mpdfc->getRDF(); + TS_ASSERT_EQUALS(1000u, rdf.size()); + TS_ASSERT_EQUALS(0.0, *min_element(rdf.begin(), rdf.end())); + TS_ASSERT_EQUALS(0.0, *max_element(rdf.begin(), rdf.end())); + mpdfc->setRmin(2.0); + mpdfc->setRmax(0.0); + mpdfc->eval(memptystru); + rdf = mpdfc->getRDF(); + TS_ASSERT(rdf.empty()); + mpdfc->setRmax(2.01001); + mpdfc->eval(memptystru); + rdf = mpdfc->getRDF(); + TS_ASSERT_EQUALS(2u, rdf.size()); + TS_ASSERT_EQUALS(0.0, rdf[0]); + TS_ASSERT_EQUALS(0.0, rdf[1]); + } + + void test_getF() { + QuantityType fq = mpdfc->getF(); + TS_ASSERT_EQUALS(1024u, fq.size()); + TS_ASSERT_EQUALS(0.0, *min_element(fq.begin(), fq.end())); + TS_ASSERT_EQUALS(0.0, *max_element(fq.begin(), fq.end())); + } + + void test_getQgrid() { TS_ASSERT_EQUALS(1024u, mpdfc->getQgrid().size()); } + + void test_getQmin() { TS_ASSERT_EQUALS(0.0, mpdfc->getQmin()); } + + void test_getQmax() { TS_ASSERT_DELTA(100 * M_PI, mpdfc->getQmax(), meps); } + + void test_getQstep() { + const double qstep0 = 100 * M_PI / 1024; + const double qstep1 = 100 * M_PI / 2048; + const double qstep2 = 100 * M_PI / 4096; + const double qstep3 = M_PI / (1024 * 0.03); + TS_ASSERT_DELTA(qstep0, mpdfc->getQstep(), meps); + mpdfc->setRmax(20); + TS_ASSERT_DELTA(qstep1, mpdfc->getQstep(), meps); + mpdfc->setQmax(10); + TS_ASSERT_DELTA(qstep2, mpdfc->getQstep(), meps); + mpdfc->setRstep(0.03); + TS_ASSERT_DELTA(qstep3, mpdfc->getQstep(), meps); + // test qstep after evaluation of some structure. + StructureAdapterPtr catio3; + catio3 = loadTestPeriodicStructure("CaTiO3.stru"); + mpdfc->eval(catio3); + TS_ASSERT_DELTA(qstep3, mpdfc->getQstep(), meps); + // now qstep is not updated because of non-trivial structure. + mpdfc->setRstep(0.01); + TS_ASSERT_DIFFERS(qstep2, mpdfc->getQstep()); + // qstep is correct after calculation. + mpdfc->eval(); + TS_ASSERT_DELTA(qstep2, mpdfc->getQstep(), meps); + } + + void test_getRgrid() { + QuantityType rgrid0 = mpdfc->getRgrid(); + TS_ASSERT_EQUALS(rgrid0, mpdfc->getRgrid()); + mpdfc->setRmin(5); + mpdfc->setRmax(4); + TS_ASSERT(mpdfc->getRgrid().empty()); + } + + void test_getExtendedRmin() { + // empty structure should not extend the grid at all. + TS_ASSERT_EQUALS(0.0, mpdfc->getExtendedRmin()); + mpdfc->setRmin(5); + mpdfc->eval(memptystru); + TS_ASSERT_DELTA(5.0, mpdfc->getExtendedRmin(), mepsdb); + } + + void test_getExtendedRmax() { + // empty structure should not extend the grid at all. + TS_ASSERT_DELTA(10.0, mpdfc->getExtendedRmax(), mepsdb); + mpdfc->setRmax(7); + mpdfc->eval(memptystru); + TS_ASSERT_DELTA(7.0, mpdfc->getExtendedRmax(), mepsdb); + } + + void test_serialization() { + // build customized PDFCalculator + mpdfc->setPeakWidthModelByType("constant"); + mpdfc->setDoubleAttr("width", 0.123); + mpdfc->setPeakProfileByType("gaussian"); + mpdfc->setDoubleAttr("peakprecision", 0.011); + mpdfc->setScatteringFactorTableByType("electronnumber"); + mpdfc->getScatteringFactorTable()->setCustomAs("H", "H", 1.1); + // dump it to string + stringstream storage(ios::in | ios::out | ios::binary); + diffpy::serialization::oarchive oa(storage, ios::binary); + oa << mpdfc; + diffpy::serialization::iarchive ia(storage, ios::binary); + boost::shared_ptr pdfc1; + ia >> pdfc1; + TS_ASSERT_DIFFERS(pdfc1.get(), mpdfc.get()); + TS_ASSERT_EQUALS(string("constant"), pdfc1->getPeakWidthModel()->type()); + TS_ASSERT_EQUALS(0.123, pdfc1->getDoubleAttr("width")); + TS_ASSERT_EQUALS(0.011, pdfc1->getDoubleAttr("peakprecision")); + TS_ASSERT_EQUALS(string("electronnumber"), + pdfc1->getScatteringFactorTable()->type()); + TS_ASSERT_EQUALS(1.1, pdfc1->getScatteringFactorTable()->lookup("H")); + } }; // class TestPDFCalculator diff --git a/src/tests/TestPQEvaluator.hpp b/src/tests/TestPQEvaluator.hpp index 0e4141c2..99ddc262 100644 --- a/src/tests/TestPQEvaluator.hpp +++ b/src/tests/TestPQEvaluator.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy Complex Modeling Initiative -* (c) 2013 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. -* -****************************************************************************** -* -* class TestPQEvaluator -- unit tests for the PairQuantity evaluator class -* -*****************************************************************************/ + * + * libdiffpy Complex Modeling Initiative + * (c) 2013 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. + * + ****************************************************************************** + * + * class TestPQEvaluator -- unit tests for the PairQuantity evaluator class + * + *****************************************************************************/ #include @@ -38,260 +38,226 @@ using diffpy::mathutils::EpsilonEqual; // calculator with invalid support for OPTIMIZED evaluation -class BadPairCounter : public PairCounter -{ - protected: - - // intentionally faulty support for PQEvaluatorOptimized - virtual void stashPartialValue() { } - virtual void restorePartialValue() { } +class BadPairCounter : public PairCounter { + protected: + // intentionally faulty support for PQEvaluatorOptimized + virtual void stashPartialValue() {} + virtual void restorePartialValue() {} }; ////////////////////////////////////////////////////////////////////////////// // class TestPQEvaluator ////////////////////////////////////////////////////////////////////////////// -class TestPQEvaluator : public CxxTest::TestSuite -{ - private: - - // data - EpsilonEqual allclose; - PDFCalculator mpdfcb; - PDFCalculator mpdfco; - QuantityType mzeros; - AtomicStructureAdapterPtr mstru10; - AtomicStructureAdapterPtr mstru10d1; - AtomicStructureAdapterPtr mstru10r; - AtomicStructureAdapterPtr mstru9; - - // methods - QuantityType pdfcdiff(StructureAdapterPtr stru) - { - mpdfcb.eval(stru); - mpdfco.eval(stru); - QuantityType gb = mpdfcb.getPDF(); - QuantityType go = mpdfco.getPDF(); - assert(mpdfcb.getRgrid() == mpdfco.getRgrid()); - QuantityType rv(gb.size()); - transform(gb.begin(), gb.end(), go.begin(), - rv.begin(), minus()); - return rv; - } - - public: - - void setUp() - { - // setup PDFCalculator instances and the zero vector for comparison - mpdfcb.setEvaluatorType(BASIC); - mpdfco.setEvaluatorType(OPTIMIZED); - mzeros.assign(mpdfcb.getRgrid().size(), 0.0); - // setup structure instances - const int SZ = 10; - mstru10 = boost::make_shared(); - Atom ai; - ai.atomtype = "C"; - ai.uij_cartn = R3::identity(); - ai.uij_cartn(0, 0) = ai.uij_cartn(1, 1) = - ai.uij_cartn(2, 2) = 0.004; - for (int i = 0; i < SZ; ++i) - { - ai.xyz_cartn[0] = i; - mstru10->append(ai); - } - mstru10d1 = boost::make_shared(*mstru10); - (*mstru10d1)[0].atomtype = "Au"; - mstru10r = boost::make_shared(); - mstru10r->assign(mstru10->rbegin(), mstru10->rend()); - mstru9 = boost::make_shared(*mstru10); - mstru9->erase(9); - } - - - void test_initial_evaluator_type_used() - { - PDFCalculator pdfc; - TS_ASSERT_EQUALS(NONE, pdfc.getEvaluatorTypeUsed()); - pdfc.setEvaluatorType(OPTIMIZED); - TS_ASSERT_EQUALS(NONE, pdfc.getEvaluatorTypeUsed()); - pdfc.setEvaluatorType(CHECK); - TS_ASSERT_EQUALS(NONE, pdfc.getEvaluatorTypeUsed()); - pdfc.setEvaluatorType(BASIC); - TS_ASSERT_EQUALS(NONE, pdfc.getEvaluatorTypeUsed()); - } - - - void test_PDF_change_atom() - { - using std::placeholders::_1; - TS_ASSERT_EQUALS(BASIC, mpdfcb.getEvaluatorType()); - TS_ASSERT_EQUALS(OPTIMIZED, mpdfco.getEvaluatorType()); - TS_ASSERT_EQUALS(mzeros, this->pdfcdiff(mstru10)); - // first call of mpdfco should use the BASIC evaluation - TS_ASSERT_EQUALS(BASIC, mpdfcb.getEvaluatorTypeUsed()); - TS_ASSERT_EQUALS(BASIC, mpdfco.getEvaluatorTypeUsed()); - // verify there are some non-zero values in the PDF. - QuantityType gb = mpdfcb.getPDF(); - TS_ASSERT(!gb.empty()); - int cnonzero = count_if(gb.begin(), gb.end(), - bind(not_equal_to(), _1, 0.0)); - TS_ASSERT(cnonzero); - // test second call on the same structure - mpdfco.eval(mstru10); - TS_ASSERT_EQUALS(gb, mpdfco.getPDF()); - TS_ASSERT_EQUALS(OPTIMIZED, mpdfco.getEvaluatorTypeUsed()); - // test structure with one different atom - TS_ASSERT(allclose(mzeros, this->pdfcdiff(mstru10d1))); - TS_ASSERT_EQUALS(OPTIMIZED, mpdfco.getEvaluatorTypeUsed()); - QuantityType gb1 = mpdfcb.getPDF(); - TS_ASSERT(!allclose(gb, gb1)); - // change position of 1 atom - mstru10d1->at(0).xyz_cartn[1] = 0.5; - TS_ASSERT(allclose(mzeros, this->pdfcdiff(mstru10d1))); - TS_ASSERT_EQUALS(OPTIMIZED, mpdfco.getEvaluatorTypeUsed()); - QuantityType gb2 = mpdfcb.getPDF(); - TS_ASSERT(!allclose(gb1, gb2)); - } - - - void test_PDF_reverse_atoms() - { - mpdfco.eval(mstru10); - TS_ASSERT(allclose(mzeros, this->pdfcdiff(mstru10r))); - TS_ASSERT_EQUALS(OPTIMIZED, mpdfco.getEvaluatorTypeUsed()); - } - - - void test_PDF_remove_atom() - { - mpdfco.eval(mstru10); - TS_ASSERT(allclose(mzeros, this->pdfcdiff(mstru9))); - TS_ASSERT_EQUALS(OPTIMIZED, mpdfco.getEvaluatorTypeUsed()); - } - - - void test_PDF_type_mask() - { - mpdfcb.setTypeMask("O2-", "all", false); - mpdfco.setTypeMask("O2-", "all", false); - PeriodicStructureAdapterPtr litao = - boost::dynamic_pointer_cast( - loadTestPeriodicStructure("LiTaO3.stru")); - TS_ASSERT_EQUALS(mzeros, this->pdfcdiff(litao)); - TS_ASSERT_EQUALS(BASIC, mpdfco.getEvaluatorTypeUsed()); - QuantityType gb0 = mpdfcb.getPDF(); - // change masked-away oxygen - Atom& o29 = litao->at(29); - TS_ASSERT_EQUALS("O2-", o29.atomtype); - o29.xyz_cartn = R3::Vector(0.1, 0.2, 0.3); - TS_ASSERT_EQUALS(mzeros, this->pdfcdiff(litao)); - TS_ASSERT_EQUALS(OPTIMIZED, mpdfco.getEvaluatorTypeUsed()); - QuantityType gb1 = mpdfcb.getPDF(); - TS_ASSERT_EQUALS(gb0, gb1); - // change active lithium - Atom& li0 = litao->at(0); - li0.occupancy = 0.1; - TS_ASSERT(allclose(mzeros, this->pdfcdiff(litao))); - TS_ASSERT_EQUALS(OPTIMIZED, mpdfco.getEvaluatorTypeUsed()); - QuantityType gb2 = mpdfcb.getPDF(); - TS_ASSERT(!allclose(gb0, gb2)); - } - - - void test_PDF_pair_mask() - { - mpdfcb.setPairMask(0, 3, false); - mpdfco.setPairMask(0, 3, false); - TS_ASSERT_EQUALS(mzeros, this->pdfcdiff(mstru10)); - TS_ASSERT_EQUALS(BASIC, mpdfco.getEvaluatorTypeUsed()); - QuantityType gb0 = mpdfcb.getPDF(); - // check structure with one changed atom - TS_ASSERT(allclose(mzeros, this->pdfcdiff(mstru10d1))); - TS_ASSERT_EQUALS(OPTIMIZED, mpdfco.getEvaluatorTypeUsed()); - QuantityType gb1 = mpdfcb.getPDF(); - TS_ASSERT(!allclose(gb0, gb1)); - // check structure with one removed atom - TS_ASSERT(allclose(mzeros, this->pdfcdiff(mstru9))); - TS_ASSERT_EQUALS(OPTIMIZED, mpdfco.getEvaluatorTypeUsed()); - QuantityType gb2 = mpdfcb.getPDF(); - TS_ASSERT(!allclose(gb1, gb2)); - // check full evaluation for structure with reversed atoms - mpdfco.eval(mstru10); - TS_ASSERT_EQUALS(mzeros, this->pdfcdiff(mstru10r)); - TS_ASSERT_EQUALS(BASIC, mpdfco.getEvaluatorTypeUsed()); - QuantityType gb3 = mpdfcb.getPDF(); - TS_ASSERT(allclose(gb0, gb3)); - // check effect of pair mask updates - mpdfco.eval(mstru10r); - TS_ASSERT_EQUALS(OPTIMIZED, mpdfco.getEvaluatorTypeUsed()); - mpdfco.setPairMask(0, 3, false); - mpdfco.eval(mstru10r); - TS_ASSERT_EQUALS(OPTIMIZED, mpdfco.getEvaluatorTypeUsed()); - mpdfco.setPairMask(0, 3, true); - mpdfco.eval(mstru10r); - TS_ASSERT_EQUALS(BASIC, mpdfco.getEvaluatorTypeUsed()); - } - - - void test_optimized_supported() - { - mpdfcb.eval(mstru10); - TS_ASSERT_EQUALS(BASIC, mpdfcb.getEvaluatorTypeUsed()); - mpdfcb.setEvaluatorType(OPTIMIZED); - TS_ASSERT_EQUALS(BASIC, mpdfcb.getEvaluatorTypeUsed()); - } - - - void test_optimized_unsupported() - { - OverlapCalculator olc; - TS_ASSERT_EQUALS(BASIC, olc.getEvaluatorType()); - TS_ASSERT_THROWS( - olc.setEvaluatorType(OPTIMIZED), invalid_argument); - TS_ASSERT_EQUALS(BASIC, olc.getEvaluatorType()); - } - - - void test_checkevaluator_unsupported() - { - OverlapCalculator olc; - TS_ASSERT_EQUALS(BASIC, olc.getEvaluatorType()); - TS_ASSERT_THROWS( - olc.setEvaluatorType(CHECK), invalid_argument); - TS_ASSERT_EQUALS(BASIC, olc.getEvaluatorType()); - } - - - void test_checkevaluator_passes() - { - mpdfco.setEvaluatorType(CHECK); - TS_ASSERT_EQUALS(CHECK, mpdfco.getEvaluatorType()); - mpdfco.eval(mstru10); - TS_ASSERT_EQUALS(BASIC, mpdfco.getEvaluatorTypeUsed()); - mpdfco.eval(mstru10); - TS_ASSERT_EQUALS(CHECK, mpdfco.getEvaluatorTypeUsed()); - mpdfco.eval(mstru9); - TS_ASSERT_EQUALS(CHECK, mpdfco.getEvaluatorTypeUsed()); - mpdfco.eval(emptyStructureAdapter()); - TS_ASSERT_EQUALS(BASIC, mpdfco.getEvaluatorTypeUsed()); - } - - - void test_checkevaluator_fails() - { - BadPairCounter badcounter; - badcounter.setEvaluatorType(CHECK); - TS_ASSERT_EQUALS(45, badcounter(mstru10)); - TS_ASSERT_EQUALS(BASIC, badcounter.getEvaluatorTypeUsed()); - TS_ASSERT_THROWS(badcounter(mstru10), logic_error); - TS_ASSERT_EQUALS(CHECK, badcounter.getEvaluatorTypeUsed()); - } +class TestPQEvaluator : public CxxTest::TestSuite { + private: + // data + EpsilonEqual allclose; + PDFCalculator mpdfcb; + PDFCalculator mpdfco; + QuantityType mzeros; + AtomicStructureAdapterPtr mstru10; + AtomicStructureAdapterPtr mstru10d1; + AtomicStructureAdapterPtr mstru10r; + AtomicStructureAdapterPtr mstru9; + + // methods + QuantityType pdfcdiff(StructureAdapterPtr stru) { + mpdfcb.eval(stru); + mpdfco.eval(stru); + QuantityType gb = mpdfcb.getPDF(); + QuantityType go = mpdfco.getPDF(); + assert(mpdfcb.getRgrid() == mpdfco.getRgrid()); + QuantityType rv(gb.size()); + transform(gb.begin(), gb.end(), go.begin(), rv.begin(), minus()); + return rv; + } + + public: + void setUp() { + // setup PDFCalculator instances and the zero vector for comparison + mpdfcb.setEvaluatorType(BASIC); + mpdfco.setEvaluatorType(OPTIMIZED); + mzeros.assign(mpdfcb.getRgrid().size(), 0.0); + // setup structure instances + const int SZ = 10; + mstru10 = boost::make_shared(); + Atom ai; + ai.atomtype = "C"; + ai.uij_cartn = R3::identity(); + ai.uij_cartn(0, 0) = ai.uij_cartn(1, 1) = ai.uij_cartn(2, 2) = 0.004; + for (int i = 0; i < SZ; ++i) { + ai.xyz_cartn[0] = i; + mstru10->append(ai); + } + mstru10d1 = boost::make_shared(*mstru10); + (*mstru10d1)[0].atomtype = "Au"; + mstru10r = boost::make_shared(); + mstru10r->assign(mstru10->rbegin(), mstru10->rend()); + mstru9 = boost::make_shared(*mstru10); + mstru9->erase(9); + } + + void test_initial_evaluator_type_used() { + PDFCalculator pdfc; + TS_ASSERT_EQUALS(NONE, pdfc.getEvaluatorTypeUsed()); + pdfc.setEvaluatorType(OPTIMIZED); + TS_ASSERT_EQUALS(NONE, pdfc.getEvaluatorTypeUsed()); + pdfc.setEvaluatorType(CHECK); + TS_ASSERT_EQUALS(NONE, pdfc.getEvaluatorTypeUsed()); + pdfc.setEvaluatorType(BASIC); + TS_ASSERT_EQUALS(NONE, pdfc.getEvaluatorTypeUsed()); + } + + void test_PDF_change_atom() { + using std::placeholders::_1; + TS_ASSERT_EQUALS(BASIC, mpdfcb.getEvaluatorType()); + TS_ASSERT_EQUALS(OPTIMIZED, mpdfco.getEvaluatorType()); + TS_ASSERT_EQUALS(mzeros, this->pdfcdiff(mstru10)); + // first call of mpdfco should use the BASIC evaluation + TS_ASSERT_EQUALS(BASIC, mpdfcb.getEvaluatorTypeUsed()); + TS_ASSERT_EQUALS(BASIC, mpdfco.getEvaluatorTypeUsed()); + // verify there are some non-zero values in the PDF. + QuantityType gb = mpdfcb.getPDF(); + TS_ASSERT(!gb.empty()); + int cnonzero = + count_if(gb.begin(), gb.end(), bind(not_equal_to(), _1, 0.0)); + TS_ASSERT(cnonzero); + // test second call on the same structure + mpdfco.eval(mstru10); + TS_ASSERT_EQUALS(gb, mpdfco.getPDF()); + TS_ASSERT_EQUALS(OPTIMIZED, mpdfco.getEvaluatorTypeUsed()); + // test structure with one different atom + TS_ASSERT(allclose(mzeros, this->pdfcdiff(mstru10d1))); + TS_ASSERT_EQUALS(OPTIMIZED, mpdfco.getEvaluatorTypeUsed()); + QuantityType gb1 = mpdfcb.getPDF(); + TS_ASSERT(!allclose(gb, gb1)); + // change position of 1 atom + mstru10d1->at(0).xyz_cartn[1] = 0.5; + TS_ASSERT(allclose(mzeros, this->pdfcdiff(mstru10d1))); + TS_ASSERT_EQUALS(OPTIMIZED, mpdfco.getEvaluatorTypeUsed()); + QuantityType gb2 = mpdfcb.getPDF(); + TS_ASSERT(!allclose(gb1, gb2)); + } + + void test_PDF_reverse_atoms() { + mpdfco.eval(mstru10); + TS_ASSERT(allclose(mzeros, this->pdfcdiff(mstru10r))); + TS_ASSERT_EQUALS(OPTIMIZED, mpdfco.getEvaluatorTypeUsed()); + } + + void test_PDF_remove_atom() { + mpdfco.eval(mstru10); + TS_ASSERT(allclose(mzeros, this->pdfcdiff(mstru9))); + TS_ASSERT_EQUALS(OPTIMIZED, mpdfco.getEvaluatorTypeUsed()); + } + + void test_PDF_type_mask() { + mpdfcb.setTypeMask("O2-", "all", false); + mpdfco.setTypeMask("O2-", "all", false); + PeriodicStructureAdapterPtr litao = + boost::dynamic_pointer_cast( + loadTestPeriodicStructure("LiTaO3.stru")); + TS_ASSERT_EQUALS(mzeros, this->pdfcdiff(litao)); + TS_ASSERT_EQUALS(BASIC, mpdfco.getEvaluatorTypeUsed()); + QuantityType gb0 = mpdfcb.getPDF(); + // change masked-away oxygen + Atom& o29 = litao->at(29); + TS_ASSERT_EQUALS("O2-", o29.atomtype); + o29.xyz_cartn = R3::Vector(0.1, 0.2, 0.3); + TS_ASSERT_EQUALS(mzeros, this->pdfcdiff(litao)); + TS_ASSERT_EQUALS(OPTIMIZED, mpdfco.getEvaluatorTypeUsed()); + QuantityType gb1 = mpdfcb.getPDF(); + TS_ASSERT_EQUALS(gb0, gb1); + // change active lithium + Atom& li0 = litao->at(0); + li0.occupancy = 0.1; + TS_ASSERT(allclose(mzeros, this->pdfcdiff(litao))); + TS_ASSERT_EQUALS(OPTIMIZED, mpdfco.getEvaluatorTypeUsed()); + QuantityType gb2 = mpdfcb.getPDF(); + TS_ASSERT(!allclose(gb0, gb2)); + } + + void test_PDF_pair_mask() { + mpdfcb.setPairMask(0, 3, false); + mpdfco.setPairMask(0, 3, false); + TS_ASSERT_EQUALS(mzeros, this->pdfcdiff(mstru10)); + TS_ASSERT_EQUALS(BASIC, mpdfco.getEvaluatorTypeUsed()); + QuantityType gb0 = mpdfcb.getPDF(); + // check structure with one changed atom + TS_ASSERT(allclose(mzeros, this->pdfcdiff(mstru10d1))); + TS_ASSERT_EQUALS(OPTIMIZED, mpdfco.getEvaluatorTypeUsed()); + QuantityType gb1 = mpdfcb.getPDF(); + TS_ASSERT(!allclose(gb0, gb1)); + // check structure with one removed atom + TS_ASSERT(allclose(mzeros, this->pdfcdiff(mstru9))); + TS_ASSERT_EQUALS(OPTIMIZED, mpdfco.getEvaluatorTypeUsed()); + QuantityType gb2 = mpdfcb.getPDF(); + TS_ASSERT(!allclose(gb1, gb2)); + // check full evaluation for structure with reversed atoms + mpdfco.eval(mstru10); + TS_ASSERT_EQUALS(mzeros, this->pdfcdiff(mstru10r)); + TS_ASSERT_EQUALS(BASIC, mpdfco.getEvaluatorTypeUsed()); + QuantityType gb3 = mpdfcb.getPDF(); + TS_ASSERT(allclose(gb0, gb3)); + // check effect of pair mask updates + mpdfco.eval(mstru10r); + TS_ASSERT_EQUALS(OPTIMIZED, mpdfco.getEvaluatorTypeUsed()); + mpdfco.setPairMask(0, 3, false); + mpdfco.eval(mstru10r); + TS_ASSERT_EQUALS(OPTIMIZED, mpdfco.getEvaluatorTypeUsed()); + mpdfco.setPairMask(0, 3, true); + mpdfco.eval(mstru10r); + TS_ASSERT_EQUALS(BASIC, mpdfco.getEvaluatorTypeUsed()); + } + + void test_optimized_supported() { + mpdfcb.eval(mstru10); + TS_ASSERT_EQUALS(BASIC, mpdfcb.getEvaluatorTypeUsed()); + mpdfcb.setEvaluatorType(OPTIMIZED); + TS_ASSERT_EQUALS(BASIC, mpdfcb.getEvaluatorTypeUsed()); + } + + void test_optimized_unsupported() { + OverlapCalculator olc; + TS_ASSERT_EQUALS(BASIC, olc.getEvaluatorType()); + TS_ASSERT_THROWS(olc.setEvaluatorType(OPTIMIZED), invalid_argument); + TS_ASSERT_EQUALS(BASIC, olc.getEvaluatorType()); + } + + void test_checkevaluator_unsupported() { + OverlapCalculator olc; + TS_ASSERT_EQUALS(BASIC, olc.getEvaluatorType()); + TS_ASSERT_THROWS(olc.setEvaluatorType(CHECK), invalid_argument); + TS_ASSERT_EQUALS(BASIC, olc.getEvaluatorType()); + } + + void test_checkevaluator_passes() { + mpdfco.setEvaluatorType(CHECK); + TS_ASSERT_EQUALS(CHECK, mpdfco.getEvaluatorType()); + mpdfco.eval(mstru10); + TS_ASSERT_EQUALS(BASIC, mpdfco.getEvaluatorTypeUsed()); + mpdfco.eval(mstru10); + TS_ASSERT_EQUALS(CHECK, mpdfco.getEvaluatorTypeUsed()); + mpdfco.eval(mstru9); + TS_ASSERT_EQUALS(CHECK, mpdfco.getEvaluatorTypeUsed()); + mpdfco.eval(emptyStructureAdapter()); + TS_ASSERT_EQUALS(BASIC, mpdfco.getEvaluatorTypeUsed()); + } + + void test_checkevaluator_fails() { + BadPairCounter badcounter; + badcounter.setEvaluatorType(CHECK); + TS_ASSERT_EQUALS(45, badcounter(mstru10)); + TS_ASSERT_EQUALS(BASIC, badcounter.getEvaluatorTypeUsed()); + TS_ASSERT_THROWS(badcounter(mstru10), logic_error); + TS_ASSERT_EQUALS(CHECK, badcounter.getEvaluatorTypeUsed()); + } }; // class TestPQEvaluator -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy using diffpy::srreal::TestPQEvaluator; diff --git a/src/tests/TestPairCounter.hpp b/src/tests/TestPairCounter.hpp index e697086c..5858f063 100644 --- a/src/tests/TestPairCounter.hpp +++ b/src/tests/TestPairCounter.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class TestPairCounter -- unit tests for PairCounter class -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class TestPairCounter -- unit tests for PairCounter class + * + *****************************************************************************/ #include @@ -24,133 +24,113 @@ using namespace std; using namespace diffpy::srreal; -class TestPairCounter : public CxxTest::TestSuite -{ - -private: - - AtomicStructureAdapterPtr mstru; - AtomicStructureAdapterPtr mline100; - -public: - - void setUp() - { - mstru.reset(new AtomicStructureAdapter); - if (!mline100) - { - mline100.reset(new AtomicStructureAdapter); - Atom a; - for (int i = 0; i < 100; ++i) - { - a.xyz_cartn = R3::Vector(1.0*i, 0.0, 0.0); - mline100->append(a); - } - } - } - - - void test_call() - { - PairCounter pcount; - Atom a; - for (int i = 0; i < 100; ++i) - { - int npairs = i * (i - 1) / 2; - TS_ASSERT_EQUALS(npairs, pcount(mstru)); - a.xyz_cartn = R3::Vector(1.0*i, 0.0, 0.0); - mstru->append(a); - } - mstru->clear(); - TS_ASSERT_EQUALS(0, pcount(mstru)); - } - - - void test_setRmin() - { - PairCounter pcount; - TS_ASSERT_EQUALS(100*99/2, pcount(mline100)); - pcount.setRmin(100); - TS_ASSERT_EQUALS(0, pcount(mline100)); - pcount.setRmin(99.0); - TS_ASSERT_EQUALS(1, pcount(mline100)); - pcount.setRmin(1.1); - TS_ASSERT_EQUALS(100*99/2 - 99, pcount(mline100)); +class TestPairCounter : public CxxTest::TestSuite { + private: + AtomicStructureAdapterPtr mstru; + AtomicStructureAdapterPtr mline100; + + public: + void setUp() { + mstru.reset(new AtomicStructureAdapter); + if (!mline100) { + mline100.reset(new AtomicStructureAdapter); + Atom a; + for (int i = 0; i < 100; ++i) { + a.xyz_cartn = R3::Vector(1.0 * i, 0.0, 0.0); + mline100->append(a); + } } - - - void test_setRmax() - { - PairCounter pcount; - pcount.setRmax(0.9); - TS_ASSERT_EQUALS(0, pcount(mline100)); - pcount.setRmax(1.1); - TS_ASSERT_EQUALS(99, pcount(mline100)); - pcount.setRmax(98.5); - TS_ASSERT_EQUALS(100*99/2 - 1, pcount(mline100)); + } + + void test_call() { + PairCounter pcount; + Atom a; + for (int i = 0; i < 100; ++i) { + int npairs = i * (i - 1) / 2; + TS_ASSERT_EQUALS(npairs, pcount(mstru)); + a.xyz_cartn = R3::Vector(1.0 * i, 0.0, 0.0); + mstru->append(a); } - - - void test_maskTicker() - { - using diffpy::eventticker::EventTicker; - PairCounter pcount; - EventTicker et0 = pcount.ticker(); - pcount.maskAllPairs(true); - pcount.setPairMask(pcount.ALLATOMSINT, pcount.ALLATOMSINT, true); - pcount.setTypeMask("all", "all", true); - TS_ASSERT_EQUALS(et0, pcount.ticker()); - pcount.setTypeMask("A", "B", true); - EventTicker et1 = pcount.ticker(); - TS_ASSERT_LESS_THAN(et0, et1); - pcount.setTypeMask("A", "B", true); - TS_ASSERT_EQUALS(et1, pcount.ticker()); - pcount.setTypeMask("A", "B", false); - EventTicker et2 = pcount.ticker(); - TS_ASSERT_LESS_THAN(et1, et2); - pcount.setTypeMask("A", "all", false); - EventTicker et3 = pcount.ticker(); - TS_ASSERT_LESS_THAN(et2, et3); - pcount.setTypeMask("A", "all", false); - TS_ASSERT_EQUALS(et3, pcount.ticker()); - pcount.setTypeMask("A", "all", true); - EventTicker et4 = pcount.ticker(); - TS_ASSERT_LESS_THAN(et3, et4); - pcount.setPairMask(0, 0, false); - EventTicker et5 = pcount.ticker(); - TS_ASSERT_LESS_THAN(et4, et5); - pcount.setPairMask(0, 0, false); - TS_ASSERT_EQUALS(et5, pcount.ticker()); - pcount.setPairMask(0, 5, true); - TS_ASSERT_EQUALS(et5, pcount.ticker()); - pcount.setPairMask(0, 5, false); - TS_ASSERT_LESS_THAN(et5, pcount.ticker()); + mstru->clear(); + TS_ASSERT_EQUALS(0, pcount(mstru)); + } + + void test_setRmin() { + PairCounter pcount; + TS_ASSERT_EQUALS(100 * 99 / 2, pcount(mline100)); + pcount.setRmin(100); + TS_ASSERT_EQUALS(0, pcount(mline100)); + pcount.setRmin(99.0); + TS_ASSERT_EQUALS(1, pcount(mline100)); + pcount.setRmin(1.1); + TS_ASSERT_EQUALS(100 * 99 / 2 - 99, pcount(mline100)); + } + + void test_setRmax() { + PairCounter pcount; + pcount.setRmax(0.9); + TS_ASSERT_EQUALS(0, pcount(mline100)); + pcount.setRmax(1.1); + TS_ASSERT_EQUALS(99, pcount(mline100)); + pcount.setRmax(98.5); + TS_ASSERT_EQUALS(100 * 99 / 2 - 1, pcount(mline100)); + } + + void test_maskTicker() { + using diffpy::eventticker::EventTicker; + PairCounter pcount; + EventTicker et0 = pcount.ticker(); + pcount.maskAllPairs(true); + pcount.setPairMask(pcount.ALLATOMSINT, pcount.ALLATOMSINT, true); + pcount.setTypeMask("all", "all", true); + TS_ASSERT_EQUALS(et0, pcount.ticker()); + pcount.setTypeMask("A", "B", true); + EventTicker et1 = pcount.ticker(); + TS_ASSERT_LESS_THAN(et0, et1); + pcount.setTypeMask("A", "B", true); + TS_ASSERT_EQUALS(et1, pcount.ticker()); + pcount.setTypeMask("A", "B", false); + EventTicker et2 = pcount.ticker(); + TS_ASSERT_LESS_THAN(et1, et2); + pcount.setTypeMask("A", "all", false); + EventTicker et3 = pcount.ticker(); + TS_ASSERT_LESS_THAN(et2, et3); + pcount.setTypeMask("A", "all", false); + TS_ASSERT_EQUALS(et3, pcount.ticker()); + pcount.setTypeMask("A", "all", true); + EventTicker et4 = pcount.ticker(); + TS_ASSERT_LESS_THAN(et3, et4); + pcount.setPairMask(0, 0, false); + EventTicker et5 = pcount.ticker(); + TS_ASSERT_LESS_THAN(et4, et5); + pcount.setPairMask(0, 0, false); + TS_ASSERT_EQUALS(et5, pcount.ticker()); + pcount.setPairMask(0, 5, true); + TS_ASSERT_EQUALS(et5, pcount.ticker()); + pcount.setPairMask(0, 5, false); + TS_ASSERT_LESS_THAN(et5, pcount.ticker()); + } + + void test_parallel() { + const int ncpu = 7; + PairCounter pmaster; + PairCounter pslave[ncpu]; + bool allequal = true; + for (int cpuindex = 0; cpuindex < ncpu; ++cpuindex) { + pslave[cpuindex].setupParallelRun(cpuindex, ncpu); + pslave[cpuindex].eval(mline100); + allequal = + allequal && (pslave[cpuindex].value()[0] == pslave[0].value()[0]); } - - - void test_parallel() - { - const int ncpu = 7; - PairCounter pmaster; - PairCounter pslave[ncpu]; - bool allequal = true; - for (int cpuindex = 0; cpuindex < ncpu; ++cpuindex) - { - pslave[cpuindex].setupParallelRun(cpuindex, ncpu); - pslave[cpuindex].eval(mline100); - allequal = allequal && - (pslave[cpuindex].value()[0] == pslave[0].value()[0]); - } - TS_ASSERT(!allequal); - pmaster.setStructure(mline100); - TS_ASSERT_EQUALS(1u, pmaster.value().size()); - TS_ASSERT_EQUALS(0.0, pmaster.value()[0]); - for (PairCounter* p = pslave; p != pslave + ncpu; ++p) - { - pmaster.mergeParallelData(p->getParallelData(), ncpu); - } - TS_ASSERT_EQUALS(100 * 99 / 2, pmaster.value()[0]); + TS_ASSERT(!allequal); + pmaster.setStructure(mline100); + TS_ASSERT_EQUALS(1u, pmaster.value().size()); + TS_ASSERT_EQUALS(0.0, pmaster.value()[0]); + for (PairCounter* p = pslave; p != pslave + ncpu; ++p) { + pmaster.mergeParallelData(p->getParallelData(), ncpu); } + TS_ASSERT_EQUALS(100 * 99 / 2, pmaster.value()[0]); + } }; // class TestPairCounter diff --git a/src/tests/TestPeakProfile.hpp b/src/tests/TestPeakProfile.hpp index 44b9875f..63b168ee 100644 --- a/src/tests/TestPeakProfile.hpp +++ b/src/tests/TestPeakProfile.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class TestPeakProfile -- unit tests for various PeakProfile classes -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class TestPeakProfile -- unit tests for various PeakProfile classes + * + *****************************************************************************/ #include #include @@ -30,136 +30,113 @@ using namespace std; using namespace diffpy::srreal; using diffpy::mathutils::eps_eq; - -class TestPeakProfile : public CxxTest::TestSuite -{ - - private: - - PeakProfilePtr mpkgauss; - PeakProfilePtr mpkgcrop; - double meps; - - public: - - void setUp() - { - mpkgauss = PeakProfile::createByType("gaussian"); - mpkgcrop = PeakProfile::createByType("croppedgaussian"); - meps = 10 * diffpy::mathutils::DOUBLE_EPS; - } - - - void test_factory() - { - TS_ASSERT_THROWS(PeakProfile::createByType("invalid"), - invalid_argument); - TS_ASSERT_EQUALS(string("gaussian"), mpkgauss->type()); - } - - - void test_clone() - { - TS_ASSERT_EQUALS("gaussian", mpkgauss->clone()->type()); - TS_ASSERT_EQUALS("croppedgaussian", mpkgcrop->clone()->type()); - } - - - void test_attributes() - { - TS_ASSERT_EQUALS(1, mpkgauss->namesOfDoubleAttributes().size()); - TS_ASSERT_EQUALS(1, mpkgcrop->namesOfDoubleAttributes().size()); - mpkgauss->setDoubleAttr("peakprecision", 0.05); - const double lo0 = mpkgauss->xboundlo(0.2); - GaussianProfile g; - TS_ASSERT(!eps_eq(lo0, g.xboundlo(0.2))); - g.setPrecision(0.05); - TS_ASSERT_EQUALS(lo0, g.xboundlo(0.2)); - mpkgcrop->setDoubleAttr("peakprecision", 0.05); - CroppedGaussianProfile fcrop; - TS_ASSERT(!eps_eq(fcrop(0.1, 0.2), (*mpkgcrop)(0.1, 0.2))); - fcrop.setPrecision(0.05); - TS_ASSERT_EQUALS(fcrop(0.1, 0.2), (*mpkgcrop)(0.1, 0.2)); - } - - - void test_y() - { - double Afwhm1 = 2 * sqrt(M_LN2 / M_PI); - const PeakProfile& pkgauss = *mpkgauss; - TS_ASSERT_DELTA(Afwhm1, pkgauss(0, 1), meps); - TS_ASSERT_DELTA(Afwhm1 / 2, pkgauss(+0.5, 1), meps); - TS_ASSERT_DELTA(Afwhm1 / 2, pkgauss(-0.5, 1), meps); - const PeakProfile& pkgcrop = *mpkgcrop; - mpkgauss->setDoubleAttr("peakprecision", 1e-6); - mpkgcrop->setDoubleAttr("peakprecision", 1e-6); - TS_ASSERT(pkgcrop(0, 1) > pkgauss(0, 1) + meps); - TS_ASSERT_EQUALS(0, pkgcrop(1, 0.1)); - } - - - void test_xboundlo() - { - const double epsy = 1e-8; - mpkgauss->setPrecision(epsy); - const double Afwhm1 = 2 * sqrt(M_LN2 / M_PI); - const double xblo1 = mpkgauss->xboundlo(1); - const double Afwhm3 = Afwhm1 / 3; - const double xblo3 = mpkgauss->xboundlo(3); - TS_ASSERT_DELTA(epsy, (*mpkgauss)(xblo1, 1) / Afwhm1, meps); - TS_ASSERT_DELTA(epsy, (*mpkgauss)(xblo3, 3) / Afwhm3, meps); - TS_ASSERT(xblo1 < 0); - TS_ASSERT(xblo3 < 0); - mpkgauss->setPrecision(10); - TS_ASSERT_EQUALS(0.0, mpkgauss->xboundlo(1)); - mpkgauss->setPrecision(0.1); - TS_ASSERT_EQUALS(0.0, mpkgauss->xboundlo(0)); - TS_ASSERT_EQUALS(0.0, mpkgauss->xboundlo(-1)); - } - - - void test_xboundhi() - { - const double epsy = 1e-8; - mpkgauss->setPrecision(epsy); - const double Afwhm1 = 2 * sqrt(M_LN2 / M_PI); - const double xbhi1 = mpkgauss->xboundhi(1); - const double Afwhm3 = Afwhm1 / 3; - const double xbhi3 = mpkgauss->xboundhi(3); - TS_ASSERT_DELTA(epsy, (*mpkgauss)(xbhi1, 1) / Afwhm1, meps); - TS_ASSERT_DELTA(epsy, (*mpkgauss)(xbhi3, 3) / Afwhm3, meps); - TS_ASSERT(xbhi1 > 0); - TS_ASSERT(xbhi3 > 0); - } - - - void test_setPrecision() - { - using diffpy::mathutils::DOUBLE_EPS; - double epsy = 1e-7; - TS_ASSERT_DELTA(0.0, mpkgauss->getPrecision(), 10 * DOUBLE_EPS); - mpkgauss->setPrecision(epsy); - TS_ASSERT_EQUALS(epsy, mpkgauss->getPrecision()); - double xbhi1 = mpkgauss->xboundhi(1); - mpkgauss->setPrecision(1e-4); - TS_ASSERT(xbhi1 != mpkgauss->xboundhi(1)); - } - - - void test_serialization() - { - mpkgauss->setPrecision(0.0123); - PeakProfilePtr pk1 = dumpandload(mpkgauss); - TS_ASSERT(pk1.get()); - TS_ASSERT_DIFFERS(mpkgauss.get(), pk1.get()); - TS_ASSERT_EQUALS(string("gaussian"), pk1->type()); - TS_ASSERT_EQUALS(0.0123, pk1->getPrecision()); - mpkgcrop->setPrecision(0.004); - PeakProfilePtr pk2 = dumpandload(mpkgcrop); - TS_ASSERT_EQUALS("croppedgaussian", pk2->type()); - TS_ASSERT_EQUALS(0.004, pk2->getPrecision()); - TS_ASSERT_EQUALS((*mpkgcrop)(0.1, 0.2), (*pk2)(0.1, 0.2)); - } +class TestPeakProfile : public CxxTest::TestSuite { + private: + PeakProfilePtr mpkgauss; + PeakProfilePtr mpkgcrop; + double meps; + + public: + void setUp() { + mpkgauss = PeakProfile::createByType("gaussian"); + mpkgcrop = PeakProfile::createByType("croppedgaussian"); + meps = 10 * diffpy::mathutils::DOUBLE_EPS; + } + + void test_factory() { + TS_ASSERT_THROWS(PeakProfile::createByType("invalid"), invalid_argument); + TS_ASSERT_EQUALS(string("gaussian"), mpkgauss->type()); + } + + void test_clone() { + TS_ASSERT_EQUALS("gaussian", mpkgauss->clone()->type()); + TS_ASSERT_EQUALS("croppedgaussian", mpkgcrop->clone()->type()); + } + + void test_attributes() { + TS_ASSERT_EQUALS(1, mpkgauss->namesOfDoubleAttributes().size()); + TS_ASSERT_EQUALS(1, mpkgcrop->namesOfDoubleAttributes().size()); + mpkgauss->setDoubleAttr("peakprecision", 0.05); + const double lo0 = mpkgauss->xboundlo(0.2); + GaussianProfile g; + TS_ASSERT(!eps_eq(lo0, g.xboundlo(0.2))); + g.setPrecision(0.05); + TS_ASSERT_EQUALS(lo0, g.xboundlo(0.2)); + mpkgcrop->setDoubleAttr("peakprecision", 0.05); + CroppedGaussianProfile fcrop; + TS_ASSERT(!eps_eq(fcrop(0.1, 0.2), (*mpkgcrop)(0.1, 0.2))); + fcrop.setPrecision(0.05); + TS_ASSERT_EQUALS(fcrop(0.1, 0.2), (*mpkgcrop)(0.1, 0.2)); + } + + void test_y() { + double Afwhm1 = 2 * sqrt(M_LN2 / M_PI); + const PeakProfile& pkgauss = *mpkgauss; + TS_ASSERT_DELTA(Afwhm1, pkgauss(0, 1), meps); + TS_ASSERT_DELTA(Afwhm1 / 2, pkgauss(+0.5, 1), meps); + TS_ASSERT_DELTA(Afwhm1 / 2, pkgauss(-0.5, 1), meps); + const PeakProfile& pkgcrop = *mpkgcrop; + mpkgauss->setDoubleAttr("peakprecision", 1e-6); + mpkgcrop->setDoubleAttr("peakprecision", 1e-6); + TS_ASSERT(pkgcrop(0, 1) > pkgauss(0, 1) + meps); + TS_ASSERT_EQUALS(0, pkgcrop(1, 0.1)); + } + + void test_xboundlo() { + const double epsy = 1e-8; + mpkgauss->setPrecision(epsy); + const double Afwhm1 = 2 * sqrt(M_LN2 / M_PI); + const double xblo1 = mpkgauss->xboundlo(1); + const double Afwhm3 = Afwhm1 / 3; + const double xblo3 = mpkgauss->xboundlo(3); + TS_ASSERT_DELTA(epsy, (*mpkgauss)(xblo1, 1) / Afwhm1, meps); + TS_ASSERT_DELTA(epsy, (*mpkgauss)(xblo3, 3) / Afwhm3, meps); + TS_ASSERT(xblo1 < 0); + TS_ASSERT(xblo3 < 0); + mpkgauss->setPrecision(10); + TS_ASSERT_EQUALS(0.0, mpkgauss->xboundlo(1)); + mpkgauss->setPrecision(0.1); + TS_ASSERT_EQUALS(0.0, mpkgauss->xboundlo(0)); + TS_ASSERT_EQUALS(0.0, mpkgauss->xboundlo(-1)); + } + + void test_xboundhi() { + const double epsy = 1e-8; + mpkgauss->setPrecision(epsy); + const double Afwhm1 = 2 * sqrt(M_LN2 / M_PI); + const double xbhi1 = mpkgauss->xboundhi(1); + const double Afwhm3 = Afwhm1 / 3; + const double xbhi3 = mpkgauss->xboundhi(3); + TS_ASSERT_DELTA(epsy, (*mpkgauss)(xbhi1, 1) / Afwhm1, meps); + TS_ASSERT_DELTA(epsy, (*mpkgauss)(xbhi3, 3) / Afwhm3, meps); + TS_ASSERT(xbhi1 > 0); + TS_ASSERT(xbhi3 > 0); + } + + void test_setPrecision() { + using diffpy::mathutils::DOUBLE_EPS; + double epsy = 1e-7; + TS_ASSERT_DELTA(0.0, mpkgauss->getPrecision(), 10 * DOUBLE_EPS); + mpkgauss->setPrecision(epsy); + TS_ASSERT_EQUALS(epsy, mpkgauss->getPrecision()); + double xbhi1 = mpkgauss->xboundhi(1); + mpkgauss->setPrecision(1e-4); + TS_ASSERT(xbhi1 != mpkgauss->xboundhi(1)); + } + + void test_serialization() { + mpkgauss->setPrecision(0.0123); + PeakProfilePtr pk1 = dumpandload(mpkgauss); + TS_ASSERT(pk1.get()); + TS_ASSERT_DIFFERS(mpkgauss.get(), pk1.get()); + TS_ASSERT_EQUALS(string("gaussian"), pk1->type()); + TS_ASSERT_EQUALS(0.0123, pk1->getPrecision()); + mpkgcrop->setPrecision(0.004); + PeakProfilePtr pk2 = dumpandload(mpkgcrop); + TS_ASSERT_EQUALS("croppedgaussian", pk2->type()); + TS_ASSERT_EQUALS(0.004, pk2->getPrecision()); + TS_ASSERT_EQUALS((*mpkgcrop)(0.1, 0.2), (*pk2)(0.1, 0.2)); + } }; // class TestPeakProfile diff --git a/src/tests/TestPeakWidthModel.hpp b/src/tests/TestPeakWidthModel.hpp index d42e0200..bd48a956 100644 --- a/src/tests/TestPeakWidthModel.hpp +++ b/src/tests/TestPeakWidthModel.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy Complex Modeling Initiative -* (c) 2019 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. -* -****************************************************************************** -* -* class TestPeakWidthModel -- test PeakWidthModel and derived classes -* -*****************************************************************************/ + * + * libdiffpy Complex Modeling Initiative + * (c) 2019 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. + * + ****************************************************************************** + * + * class TestPeakWidthModel -- test PeakWidthModel and derived classes + * + *****************************************************************************/ #include @@ -35,170 +35,147 @@ const double UtoB = 8 * M_PI * M_PI; // class TestPeakWidthModel ////////////////////////////////////////////////////////////////////////////// -class TestPeakWidthModel : public CxxTest::TestSuite -{ - private: - - // data - PeakWidthModelPtr mcnpw; - ConstantPeakWidth* mccnpw; - PeakWidthModelPtr mdwpw; - PeakWidthModelPtr mjepw; - JeongPeakWidth* mcjepw; - double meps; - - // methods - static AtomicStructureAdapterPtr dimer() - { - AtomicStructureAdapterPtr adpt(new AtomicStructureAdapter); - Atom a; - a.atomtype = "C"; - a.uij_cartn = R3::identity() * tuiso; - adpt->append(a); - a.xyz_cartn[2] = 1; - adpt->append(a); - return adpt; - } - - public: - - void setUp() - { - mcnpw = PeakWidthModel::createByType("constant"); - mccnpw = static_cast(mcnpw.get()); - mdwpw = PeakWidthModel::createByType("debye-waller"); - mjepw = PeakWidthModel::createByType("jeong"); - mcjepw = static_cast(mjepw.get()); - meps = 10 * diffpy::mathutils::DOUBLE_EPS; - } - - - void test_clone() - { - TS_ASSERT_EQUALS("constant", mcnpw->clone()->type()); - TS_ASSERT_EQUALS("debye-waller", mdwpw->clone()->type()); - TS_ASSERT_EQUALS("jeong", mjepw->clone()->type()); - } - - - void test_attributes() - { - TS_ASSERT_EQUALS(0, mdwpw->namesOfDoubleAttributes().size()); - TS_ASSERT_EQUALS(4, mjepw->namesOfDoubleAttributes().size()); - mcjepw->setDelta1(0.1); - mcjepw->setDelta2(0.2); - mcjepw->setQbroad(0.3); - mcjepw->setQbroad_seperable(0.4); - TS_ASSERT_EQUALS(0.1, mjepw->getDoubleAttr("delta1")); - TS_ASSERT_EQUALS(0.2, mjepw->getDoubleAttr("delta2")); - TS_ASSERT_EQUALS(0.3, mjepw->getDoubleAttr("qbroad")); - TS_ASSERT_EQUALS(0.4, mjepw->getDoubleAttr("qbroad_seperable")); - } - - - void test_calculate() - { - using diffpy::mathutils::GAUSS_SIGMA_TO_FWHM; - AtomicStructureAdapterPtr adpt = dimer(); - BaseBondGeneratorPtr bnds = adpt->createBondGenerator(); - bnds->setRmax(2.0); - bnds->rewind(); - const double w = GAUSS_SIGMA_TO_FWHM * sqrt(2 * tuiso); - TS_ASSERT_DELTA(w, mdwpw->calculate(*bnds), meps); - TS_ASSERT_DELTA(w, mjepw->calculate(*bnds), meps); - mcjepw->setDelta2(0.75); - TS_ASSERT_DELTA(0.5 * w, mjepw->calculate(*bnds), meps); - mcjepw->setDelta2(0); - mcjepw->setQbroad(sqrt(3)); - mcjepw->setQbroad_seperable(0); - TS_ASSERT_DELTA(2 * w, mjepw->calculate(*bnds), meps); - } - - - void test_serialization() - { - PeakWidthModelPtr pwm1 = dumpandload(mdwpw); - DebyeWallerPeakWidth* cpwm1 = - dynamic_cast(pwm1.get()); - TS_ASSERT(cpwm1); - mcjepw->setDelta1(1.1); - mcjepw->setDoubleAttr("delta2", 2.2); - mcjepw->setDoubleAttr("qbroad", 0.03); - mcjepw->setDoubleAttr("qbroad_seperable", 0.003); - PeakWidthModelPtr pwm2 = dumpandload(mjepw); - JeongPeakWidth* cpwm2 = dynamic_cast(pwm2.get()); - TS_ASSERT(cpwm2); - TS_ASSERT_EQUALS(1.1, pwm2->getDoubleAttr("delta1")); - TS_ASSERT_EQUALS(2.2, pwm2->getDoubleAttr("delta2")); - TS_ASSERT_EQUALS(0.03, pwm2->getDoubleAttr("qbroad")); - TS_ASSERT_EQUALS(0.003, pwm2->getDoubleAttr("qbroad_seperable")); - } - - - void test_CPWM_attributes() - { - TS_ASSERT_EQUALS("constant", mcnpw->type()); - TS_ASSERT(mcnpw->hasDoubleAttr("width")); - TS_ASSERT(mcnpw->hasDoubleAttr("bisowidth")); - TS_ASSERT(mcnpw->hasDoubleAttr("uisowidth")); - TS_ASSERT_EQUALS(3, mcnpw->namesOfDoubleAttributes().size()); - mccnpw->setWidth(0.1); - TS_ASSERT_EQUALS(0.1, mcnpw->getDoubleAttr("width")); - TS_ASSERT_EQUALS(0.1, mcnpw->maxWidth(dimer(), 0, 4)); - const double bw0 = mcnpw->getDoubleAttr("bisowidth"); - const double uw0 = mcnpw->getDoubleAttr("uisowidth"); - mccnpw->setWidth(2 * mccnpw->getWidth()); - TS_ASSERT_DELTA(bw0, UtoB * uw0, meps); - TS_ASSERT_DELTA(4 * bw0, mcnpw->getDoubleAttr("bisowidth"), meps); - TS_ASSERT_DELTA(4 * uw0, mcnpw->getDoubleAttr("uisowidth"), meps); - } - - - void test_CPWM_bisowidth() - { - const double biso = UtoB * tuiso; - mcnpw->setDoubleAttr("bisowidth", biso); - TS_ASSERT_DELTA(tuiso, mcnpw->getDoubleAttr("uisowidth"), meps); - mcnpw->setDoubleAttr("uisowidth", -tuiso); - TS_ASSERT_DELTA(-biso, mcnpw->getDoubleAttr("bisowidth"), meps); - } - - - void test_CPWM_uisowidth() - { - StructureAdapterPtr adpt = dimer(); - BaseBondGeneratorPtr bnds = adpt->createBondGenerator(); - PeakWidthModelPtr dwpw(new DebyeWallerPeakWidth); - bnds->setRmax(2.0); - bnds->rewind(); - const double w0 = dwpw->calculate(*bnds); - TS_ASSERT_EQUALS(0.0, mcnpw->calculate(*bnds)); - mcnpw->setDoubleAttr("uisowidth", tuiso); - TS_ASSERT_DELTA(w0, mcnpw->calculate(*bnds), meps); - mcnpw->setDoubleAttr("uisowidth", -tuiso); - TS_ASSERT_DELTA(-tuiso, mcnpw->getDoubleAttr("uisowidth"), meps); - TS_ASSERT_DELTA(-w0, mcnpw->getDoubleAttr("width"), meps); - } - - - void test_CPWM_serialization() - { - PeakWidthModelPtr pwm1 = dumpandload(mcnpw); - TS_ASSERT_EQUALS("constant", pwm1->type()); - TS_ASSERT_EQUALS(0.0, pwm1->getDoubleAttr("width")); - mcnpw->setDoubleAttr("width", 0.1); - double uw0 = mcnpw->getDoubleAttr("uisowidth"); - PeakWidthModelPtr pwm2 = dumpandload(mcnpw); - TS_ASSERT_EQUALS(0.1, pwm2->getDoubleAttr("width")); - TS_ASSERT_DELTA(uw0, pwm2->getDoubleAttr("uisowidth"), meps); - } - - +class TestPeakWidthModel : public CxxTest::TestSuite { + private: + // data + PeakWidthModelPtr mcnpw; + ConstantPeakWidth* mccnpw; + PeakWidthModelPtr mdwpw; + PeakWidthModelPtr mjepw; + JeongPeakWidth* mcjepw; + double meps; + + // methods + static AtomicStructureAdapterPtr dimer() { + AtomicStructureAdapterPtr adpt(new AtomicStructureAdapter); + Atom a; + a.atomtype = "C"; + a.uij_cartn = R3::identity() * tuiso; + adpt->append(a); + a.xyz_cartn[2] = 1; + adpt->append(a); + return adpt; + } + + public: + void setUp() { + mcnpw = PeakWidthModel::createByType("constant"); + mccnpw = static_cast(mcnpw.get()); + mdwpw = PeakWidthModel::createByType("debye-waller"); + mjepw = PeakWidthModel::createByType("jeong"); + mcjepw = static_cast(mjepw.get()); + meps = 10 * diffpy::mathutils::DOUBLE_EPS; + } + + void test_clone() { + TS_ASSERT_EQUALS("constant", mcnpw->clone()->type()); + TS_ASSERT_EQUALS("debye-waller", mdwpw->clone()->type()); + TS_ASSERT_EQUALS("jeong", mjepw->clone()->type()); + } + + void test_attributes() { + TS_ASSERT_EQUALS(0, mdwpw->namesOfDoubleAttributes().size()); + TS_ASSERT_EQUALS(4, mjepw->namesOfDoubleAttributes().size()); + mcjepw->setDelta1(0.1); + mcjepw->setDelta2(0.2); + mcjepw->setQbroad(0.3); + mcjepw->setQbroad_seperable(0.4); + TS_ASSERT_EQUALS(0.1, mjepw->getDoubleAttr("delta1")); + TS_ASSERT_EQUALS(0.2, mjepw->getDoubleAttr("delta2")); + TS_ASSERT_EQUALS(0.3, mjepw->getDoubleAttr("qbroad")); + TS_ASSERT_EQUALS(0.4, mjepw->getDoubleAttr("qbroad_seperable")); + } + + void test_calculate() { + using diffpy::mathutils::GAUSS_SIGMA_TO_FWHM; + AtomicStructureAdapterPtr adpt = dimer(); + BaseBondGeneratorPtr bnds = adpt->createBondGenerator(); + bnds->setRmax(2.0); + bnds->rewind(); + const double w = GAUSS_SIGMA_TO_FWHM * sqrt(2 * tuiso); + TS_ASSERT_DELTA(w, mdwpw->calculate(*bnds), meps); + TS_ASSERT_DELTA(w, mjepw->calculate(*bnds), meps); + mcjepw->setDelta2(0.75); + TS_ASSERT_DELTA(0.5 * w, mjepw->calculate(*bnds), meps); + mcjepw->setDelta2(0); + mcjepw->setQbroad(sqrt(3)); + mcjepw->setQbroad_seperable(0); + TS_ASSERT_DELTA(2 * w, mjepw->calculate(*bnds), meps); + } + + void test_serialization() { + PeakWidthModelPtr pwm1 = dumpandload(mdwpw); + DebyeWallerPeakWidth* cpwm1 = + dynamic_cast(pwm1.get()); + TS_ASSERT(cpwm1); + mcjepw->setDelta1(1.1); + mcjepw->setDoubleAttr("delta2", 2.2); + mcjepw->setDoubleAttr("qbroad", 0.03); + mcjepw->setDoubleAttr("qbroad_seperable", 0.003); + PeakWidthModelPtr pwm2 = dumpandload(mjepw); + JeongPeakWidth* cpwm2 = dynamic_cast(pwm2.get()); + TS_ASSERT(cpwm2); + TS_ASSERT_EQUALS(1.1, pwm2->getDoubleAttr("delta1")); + TS_ASSERT_EQUALS(2.2, pwm2->getDoubleAttr("delta2")); + TS_ASSERT_EQUALS(0.03, pwm2->getDoubleAttr("qbroad")); + TS_ASSERT_EQUALS(0.003, pwm2->getDoubleAttr("qbroad_seperable")); + } + + void test_CPWM_attributes() { + TS_ASSERT_EQUALS("constant", mcnpw->type()); + TS_ASSERT(mcnpw->hasDoubleAttr("width")); + TS_ASSERT(mcnpw->hasDoubleAttr("bisowidth")); + TS_ASSERT(mcnpw->hasDoubleAttr("uisowidth")); + TS_ASSERT_EQUALS(3, mcnpw->namesOfDoubleAttributes().size()); + mccnpw->setWidth(0.1); + TS_ASSERT_EQUALS(0.1, mcnpw->getDoubleAttr("width")); + TS_ASSERT_EQUALS(0.1, mcnpw->maxWidth(dimer(), 0, 4)); + const double bw0 = mcnpw->getDoubleAttr("bisowidth"); + const double uw0 = mcnpw->getDoubleAttr("uisowidth"); + mccnpw->setWidth(2 * mccnpw->getWidth()); + TS_ASSERT_DELTA(bw0, UtoB * uw0, meps); + TS_ASSERT_DELTA(4 * bw0, mcnpw->getDoubleAttr("bisowidth"), meps); + TS_ASSERT_DELTA(4 * uw0, mcnpw->getDoubleAttr("uisowidth"), meps); + } + + void test_CPWM_bisowidth() { + const double biso = UtoB * tuiso; + mcnpw->setDoubleAttr("bisowidth", biso); + TS_ASSERT_DELTA(tuiso, mcnpw->getDoubleAttr("uisowidth"), meps); + mcnpw->setDoubleAttr("uisowidth", -tuiso); + TS_ASSERT_DELTA(-biso, mcnpw->getDoubleAttr("bisowidth"), meps); + } + + void test_CPWM_uisowidth() { + StructureAdapterPtr adpt = dimer(); + BaseBondGeneratorPtr bnds = adpt->createBondGenerator(); + PeakWidthModelPtr dwpw(new DebyeWallerPeakWidth); + bnds->setRmax(2.0); + bnds->rewind(); + const double w0 = dwpw->calculate(*bnds); + TS_ASSERT_EQUALS(0.0, mcnpw->calculate(*bnds)); + mcnpw->setDoubleAttr("uisowidth", tuiso); + TS_ASSERT_DELTA(w0, mcnpw->calculate(*bnds), meps); + mcnpw->setDoubleAttr("uisowidth", -tuiso); + TS_ASSERT_DELTA(-tuiso, mcnpw->getDoubleAttr("uisowidth"), meps); + TS_ASSERT_DELTA(-w0, mcnpw->getDoubleAttr("width"), meps); + } + + void test_CPWM_serialization() { + PeakWidthModelPtr pwm1 = dumpandload(mcnpw); + TS_ASSERT_EQUALS("constant", pwm1->type()); + TS_ASSERT_EQUALS(0.0, pwm1->getDoubleAttr("width")); + mcnpw->setDoubleAttr("width", 0.1); + double uw0 = mcnpw->getDoubleAttr("uisowidth"); + PeakWidthModelPtr pwm2 = dumpandload(mcnpw); + TS_ASSERT_EQUALS(0.1, pwm2->getDoubleAttr("width")); + TS_ASSERT_DELTA(uw0, pwm2->getDoubleAttr("uisowidth"), meps); + } }; // class TestPeakWidthModel -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy using diffpy::srreal::TestPeakWidthModel; diff --git a/src/tests/TestPeriodicStructureAdapter.hpp b/src/tests/TestPeriodicStructureAdapter.hpp index f00e6a0e..05411413 100644 --- a/src/tests/TestPeriodicStructureAdapter.hpp +++ b/src/tests/TestPeriodicStructureAdapter.hpp @@ -1,23 +1,23 @@ /***************************************************************************** -* -* libdiffpy Complex Modeling Initiative -* (c) 2013 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. -* -****************************************************************************** -* -* class TestPeriodicStructureAdapter -- unit tests for an adapter -* for periodic structures -* -* class TestPeriodicStructureBondGenerator -- unit tests for bond generator -* -*****************************************************************************/ + * + * libdiffpy Complex Modeling Initiative + * (c) 2013 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. + * + ****************************************************************************** + * + * class TestPeriodicStructureAdapter -- unit tests for an adapter + * for periodic structures + * + * class TestPeriodicStructureBondGenerator -- unit tests for bond generator + * + *****************************************************************************/ #include #include @@ -37,220 +37,183 @@ using namespace std; namespace { -int countBonds(BaseBondGenerator& bnds) -{ - int rv = 0; - for (bnds.rewind(); !bnds.finished(); bnds.next()) ++rv; - return rv; +int countBonds(BaseBondGenerator& bnds) { + int rv = 0; + for (bnds.rewind(); !bnds.finished(); bnds.next()) ++rv; + return rv; } - template -double testmsd0(const Tstru& stru, const Tbnds& bnds) -{ - bool anisotropy0 = stru->siteAnisotropy(bnds->site0()); - double rv = meanSquareDisplacement( - bnds->Ucartesian0(), bnds->r01(), anisotropy0); - return rv; +double testmsd0(const Tstru& stru, const Tbnds& bnds) { + bool anisotropy0 = stru->siteAnisotropy(bnds->site0()); + double rv = + meanSquareDisplacement(bnds->Ucartesian0(), bnds->r01(), anisotropy0); + return rv; } - template -double testmsd1(const Tstru& stru, const Tbnds& bnds) -{ - bool anisotropy1 = stru->siteAnisotropy(bnds->site1()); - double rv = meanSquareDisplacement( - bnds->Ucartesian1(), bnds->r01(), anisotropy1); - return rv; +double testmsd1(const Tstru& stru, const Tbnds& bnds) { + bool anisotropy1 = stru->siteAnisotropy(bnds->site1()); + double rv = + meanSquareDisplacement(bnds->Ucartesian1(), bnds->r01(), anisotropy1); + return rv; } -} // namespace +} // namespace ////////////////////////////////////////////////////////////////////////////// // class TestPeriodicStructureAdapter ////////////////////////////////////////////////////////////////////////////// -class TestPeriodicStructureAdapter : public CxxTest::TestSuite -{ - private: - - StructureAdapterPtr m_ni; - StructureAdapterPtr m_kbise; - StructureAdapterPtr m_catio3; - StructureAdapterPtr m_pswt; - - public: - - void setUp() - { - CxxTest::setAbortTestOnFail(true); - if (!m_ni) - { - m_ni = loadTestPeriodicStructure("Ni.stru"); - } - if (!m_kbise) - { - m_kbise = loadTestPeriodicStructure("alpha_K2Bi8Se13.stru"); - } - if (!m_catio3) - { - m_catio3 = loadTestPeriodicStructure("CaTiO3.stru"); - } - if (!m_pswt) - { - m_pswt = loadTestPeriodicStructure("PbScW25TiO3.stru"); - } - CxxTest::setAbortTestOnFail(false); - } - - - void test_typeid() - { - StructureAdapter& r_ni = *m_ni; - TS_ASSERT(typeid(PeriodicStructureAdapter) == typeid(r_ni)); - } - - - void test_countSites() - { - TS_ASSERT_EQUALS(4, m_ni->countSites()); - TS_ASSERT_EQUALS(23, m_kbise->countSites()); - TS_ASSERT_EQUALS(20, m_catio3->countSites()); - TS_ASSERT_EQUALS(56, m_pswt->countSites()); - } - - - void test_totalOccupancy() - { - const double eps = 10 * diffpy::mathutils::DOUBLE_EPS; - TS_ASSERT_EQUALS(4.0, m_ni->totalOccupancy()); - TS_ASSERT_EQUALS(23.0, m_kbise->totalOccupancy()); - TS_ASSERT_EQUALS(20.0, m_catio3->totalOccupancy()); - TS_ASSERT_DELTA(40.0, m_pswt->totalOccupancy(), eps); - } - - - void test_numberDensity() - { - const double eps = 1.0e-7; - TS_ASSERT_DELTA(0.0914114, m_ni->numberDensity(), eps); - TS_ASSERT_DELTA(0.0335565, m_kbise->numberDensity(), eps); - TS_ASSERT_DELTA(0.0894566, m_catio3->numberDensity(), eps); - TS_ASSERT_DELTA(0.0760332, m_pswt->numberDensity(), eps); - } - - - void test_siteCartesianPosition() - { - const double eps = 1.0e-5; - R3::Vector rCa = m_catio3->siteCartesianPosition(4); - TS_ASSERT_DELTA(0.03486, rCa[0], eps); - TS_ASSERT_DELTA(0.19366, rCa[1], eps); - TS_ASSERT_DELTA(1.90975, rCa[2], eps); - } - - - void test_siteAnisotropy() - { - for (int i = 0; i < m_ni->countSites(); ++i) - { - TS_ASSERT_EQUALS(false, m_ni->siteAnisotropy(i)); - } - for (int i = 0; i < m_catio3->countSites(); ++i) - { - TS_ASSERT_EQUALS(true, m_catio3->siteAnisotropy(i)); - } - } - - - void test_siteCartesianUij() - { - // nickel should have all Uij equal zero. - TS_ASSERT_EQUALS(R3::zeromatrix(), m_ni->siteCartesianUij(0)); - // check CaTiO3 values - const R3::Matrix& UO2 = m_catio3->siteCartesianUij(12); - const double eps = 1e-8; - TS_ASSERT_DELTA(0.0065, UO2(0,0), eps); - TS_ASSERT_DELTA(0.0060, UO2(1,1), eps); - TS_ASSERT_DELTA(0.0095, UO2(2,2), eps); - TS_ASSERT_DELTA(0.0020, UO2(0,1), eps); - TS_ASSERT_DELTA(0.0020, UO2(1,0), eps); - TS_ASSERT_DELTA(-0.0008, UO2(0,2), eps); - TS_ASSERT_DELTA(-0.0008, UO2(2,0), eps); - TS_ASSERT_DELTA(-0.0010, UO2(1,2), eps); - TS_ASSERT_DELTA(-0.0010, UO2(2,1), eps); - } - - - void test_siteAtomType() - { - TS_ASSERT_EQUALS(string("Ni"), m_ni->siteAtomType(0)); - TS_ASSERT_EQUALS(string("Ni"), m_ni->siteAtomType(3)); - TS_ASSERT_EQUALS(string("K1+"), m_kbise->siteAtomType(0)); - TS_ASSERT_EQUALS(string("Bi3+"), m_kbise->siteAtomType(2)); - TS_ASSERT_EQUALS(string("Se"), m_kbise->siteAtomType(10)); - TS_ASSERT_EQUALS(string("Se"), m_kbise->siteAtomType(22)); - } - - - void test_getLattice() - { - PeriodicStructureAdapterPtr pkbise = - boost::dynamic_pointer_cast(m_kbise); - TS_ASSERT(pkbise); - const Lattice& L = pkbise->getLattice(); - const double eps = 1.0e-12; - TS_ASSERT_DELTA(13.768, L.a(), eps); - TS_ASSERT_DELTA(12.096, L.b(), eps); - TS_ASSERT_DELTA(4.1656, L.c(), eps); - TS_ASSERT_DELTA(89.98, L.alpha(), eps); - TS_ASSERT_DELTA(98.64, L.beta(), eps); - TS_ASSERT_DELTA(87.96, L.gamma(), eps); - } - - - void test_serialization() - { - StructureAdapterPtr kbise1 = dumpandload(m_kbise); - TS_ASSERT_DIFFERS(m_kbise.get(), kbise1.get()); - const double eps = 1.0e-7; - TS_ASSERT_EQUALS(23, kbise1->countSites()); - TS_ASSERT_EQUALS(23.0, kbise1->totalOccupancy()); - TS_ASSERT_DELTA(0.0335565, kbise1->numberDensity(), eps); - TS_ASSERT_EQUALS(string("K1+"), kbise1->siteAtomType(0)); - TS_ASSERT_EQUALS(string("Bi3+"), kbise1->siteAtomType(2)); - TS_ASSERT_EQUALS(string("Se"), kbise1->siteAtomType(10)); - TS_ASSERT_EQUALS(string("Se"), kbise1->siteAtomType(22)); - PeriodicStructureAdapterPtr pkbise = - boost::dynamic_pointer_cast(m_kbise); - PeriodicStructureAdapterPtr pkbise1 = - boost::dynamic_pointer_cast(kbise1); - const Lattice& L = pkbise->getLattice(); - const Lattice& L1 = pkbise1->getLattice(); - TS_ASSERT_EQUALS(L.a(), L1.a()); - TS_ASSERT_EQUALS(L.b(), L1.b()); - TS_ASSERT_EQUALS(L.c(), L1.c()); - TS_ASSERT_EQUALS(L.alpha(), L1.alpha()); - TS_ASSERT_EQUALS(L.beta(), L1.beta()); - TS_ASSERT_EQUALS(L.gamma(), L1.gamma()); - } - - - void test_comparison() - { - const PeriodicStructureAdapter& kbise0 = - static_cast(*m_kbise); - PeriodicStructureAdapter kbise1(kbise0); - PeriodicStructureAdapter kbise2(kbise0); - TS_ASSERT_EQUALS(kbise0, kbise1); - TS_ASSERT(!(kbise0 != kbise1)); - TS_ASSERT(kbise1.countSites()); - kbise1.erase(0); - TS_ASSERT_DIFFERS(kbise0, kbise1); - TS_ASSERT(!(kbise0 == kbise1)); - kbise2.setLatPar(3, 4, 5, 91, 92, 93); - TS_ASSERT_DIFFERS(kbise0, kbise2); - } +class TestPeriodicStructureAdapter : public CxxTest::TestSuite { + private: + StructureAdapterPtr m_ni; + StructureAdapterPtr m_kbise; + StructureAdapterPtr m_catio3; + StructureAdapterPtr m_pswt; + + public: + void setUp() { + CxxTest::setAbortTestOnFail(true); + if (!m_ni) { + m_ni = loadTestPeriodicStructure("Ni.stru"); + } + if (!m_kbise) { + m_kbise = loadTestPeriodicStructure("alpha_K2Bi8Se13.stru"); + } + if (!m_catio3) { + m_catio3 = loadTestPeriodicStructure("CaTiO3.stru"); + } + if (!m_pswt) { + m_pswt = loadTestPeriodicStructure("PbScW25TiO3.stru"); + } + CxxTest::setAbortTestOnFail(false); + } + + void test_typeid() { + StructureAdapter& r_ni = *m_ni; + TS_ASSERT(typeid(PeriodicStructureAdapter) == typeid(r_ni)); + } + + void test_countSites() { + TS_ASSERT_EQUALS(4, m_ni->countSites()); + TS_ASSERT_EQUALS(23, m_kbise->countSites()); + TS_ASSERT_EQUALS(20, m_catio3->countSites()); + TS_ASSERT_EQUALS(56, m_pswt->countSites()); + } + + void test_totalOccupancy() { + const double eps = 10 * diffpy::mathutils::DOUBLE_EPS; + TS_ASSERT_EQUALS(4.0, m_ni->totalOccupancy()); + TS_ASSERT_EQUALS(23.0, m_kbise->totalOccupancy()); + TS_ASSERT_EQUALS(20.0, m_catio3->totalOccupancy()); + TS_ASSERT_DELTA(40.0, m_pswt->totalOccupancy(), eps); + } + + void test_numberDensity() { + const double eps = 1.0e-7; + TS_ASSERT_DELTA(0.0914114, m_ni->numberDensity(), eps); + TS_ASSERT_DELTA(0.0335565, m_kbise->numberDensity(), eps); + TS_ASSERT_DELTA(0.0894566, m_catio3->numberDensity(), eps); + TS_ASSERT_DELTA(0.0760332, m_pswt->numberDensity(), eps); + } + + void test_siteCartesianPosition() { + const double eps = 1.0e-5; + R3::Vector rCa = m_catio3->siteCartesianPosition(4); + TS_ASSERT_DELTA(0.03486, rCa[0], eps); + TS_ASSERT_DELTA(0.19366, rCa[1], eps); + TS_ASSERT_DELTA(1.90975, rCa[2], eps); + } + + void test_siteAnisotropy() { + for (int i = 0; i < m_ni->countSites(); ++i) { + TS_ASSERT_EQUALS(false, m_ni->siteAnisotropy(i)); + } + for (int i = 0; i < m_catio3->countSites(); ++i) { + TS_ASSERT_EQUALS(true, m_catio3->siteAnisotropy(i)); + } + } + + void test_siteCartesianUij() { + // nickel should have all Uij equal zero. + TS_ASSERT_EQUALS(R3::zeromatrix(), m_ni->siteCartesianUij(0)); + // check CaTiO3 values + const R3::Matrix& UO2 = m_catio3->siteCartesianUij(12); + const double eps = 1e-8; + TS_ASSERT_DELTA(0.0065, UO2(0, 0), eps); + TS_ASSERT_DELTA(0.0060, UO2(1, 1), eps); + TS_ASSERT_DELTA(0.0095, UO2(2, 2), eps); + TS_ASSERT_DELTA(0.0020, UO2(0, 1), eps); + TS_ASSERT_DELTA(0.0020, UO2(1, 0), eps); + TS_ASSERT_DELTA(-0.0008, UO2(0, 2), eps); + TS_ASSERT_DELTA(-0.0008, UO2(2, 0), eps); + TS_ASSERT_DELTA(-0.0010, UO2(1, 2), eps); + TS_ASSERT_DELTA(-0.0010, UO2(2, 1), eps); + } + + void test_siteAtomType() { + TS_ASSERT_EQUALS(string("Ni"), m_ni->siteAtomType(0)); + TS_ASSERT_EQUALS(string("Ni"), m_ni->siteAtomType(3)); + TS_ASSERT_EQUALS(string("K1+"), m_kbise->siteAtomType(0)); + TS_ASSERT_EQUALS(string("Bi3+"), m_kbise->siteAtomType(2)); + TS_ASSERT_EQUALS(string("Se"), m_kbise->siteAtomType(10)); + TS_ASSERT_EQUALS(string("Se"), m_kbise->siteAtomType(22)); + } + + void test_getLattice() { + PeriodicStructureAdapterPtr pkbise = + boost::dynamic_pointer_cast(m_kbise); + TS_ASSERT(pkbise); + const Lattice& L = pkbise->getLattice(); + const double eps = 1.0e-12; + TS_ASSERT_DELTA(13.768, L.a(), eps); + TS_ASSERT_DELTA(12.096, L.b(), eps); + TS_ASSERT_DELTA(4.1656, L.c(), eps); + TS_ASSERT_DELTA(89.98, L.alpha(), eps); + TS_ASSERT_DELTA(98.64, L.beta(), eps); + TS_ASSERT_DELTA(87.96, L.gamma(), eps); + } + + void test_serialization() { + StructureAdapterPtr kbise1 = dumpandload(m_kbise); + TS_ASSERT_DIFFERS(m_kbise.get(), kbise1.get()); + const double eps = 1.0e-7; + TS_ASSERT_EQUALS(23, kbise1->countSites()); + TS_ASSERT_EQUALS(23.0, kbise1->totalOccupancy()); + TS_ASSERT_DELTA(0.0335565, kbise1->numberDensity(), eps); + TS_ASSERT_EQUALS(string("K1+"), kbise1->siteAtomType(0)); + TS_ASSERT_EQUALS(string("Bi3+"), kbise1->siteAtomType(2)); + TS_ASSERT_EQUALS(string("Se"), kbise1->siteAtomType(10)); + TS_ASSERT_EQUALS(string("Se"), kbise1->siteAtomType(22)); + PeriodicStructureAdapterPtr pkbise = + boost::dynamic_pointer_cast(m_kbise); + PeriodicStructureAdapterPtr pkbise1 = + boost::dynamic_pointer_cast(kbise1); + const Lattice& L = pkbise->getLattice(); + const Lattice& L1 = pkbise1->getLattice(); + TS_ASSERT_EQUALS(L.a(), L1.a()); + TS_ASSERT_EQUALS(L.b(), L1.b()); + TS_ASSERT_EQUALS(L.c(), L1.c()); + TS_ASSERT_EQUALS(L.alpha(), L1.alpha()); + TS_ASSERT_EQUALS(L.beta(), L1.beta()); + TS_ASSERT_EQUALS(L.gamma(), L1.gamma()); + } + + void test_comparison() { + const PeriodicStructureAdapter& kbise0 = + static_cast(*m_kbise); + PeriodicStructureAdapter kbise1(kbise0); + PeriodicStructureAdapter kbise2(kbise0); + TS_ASSERT_EQUALS(kbise0, kbise1); + TS_ASSERT(!(kbise0 != kbise1)); + TS_ASSERT(kbise1.countSites()); + kbise1.erase(0); + TS_ASSERT_DIFFERS(kbise0, kbise1); + TS_ASSERT(!(kbise0 == kbise1)); + kbise2.setLatPar(3, 4, 5, 91, 92, 93); + TS_ASSERT_DIFFERS(kbise0, kbise2); + } }; // class TestPeriodicStructureAdapter @@ -258,169 +221,149 @@ class TestPeriodicStructureAdapter : public CxxTest::TestSuite // class TestPeriodicStructureBondGenerator ////////////////////////////////////////////////////////////////////////////// -class TestPeriodicStructureBondGenerator : public CxxTest::TestSuite -{ - private: - - StructureAdapterPtr m_ni; - BaseBondGeneratorPtr m_nibnds; - - public: - - void setUp() - { - CxxTest::setAbortTestOnFail(true); - if (!m_ni) - { - m_ni = loadTestPeriodicStructure("Ni.stru"); - } - m_nibnds = m_ni->createBondGenerator(); - CxxTest::setAbortTestOnFail(false); - } - - - void test_typeid() - { - BaseBondGenerator& r_nibnds = *m_nibnds; - TS_ASSERT(typeid(PeriodicStructureBondGenerator) == - typeid(r_nibnds)); - } - - - void test_bondCountNickel() - { - m_nibnds->selectAnchorSite(0); - m_nibnds->setRmin(0); - m_nibnds->setRmax(1.0); - TS_ASSERT_EQUALS(0, countBonds(*m_nibnds)); - m_nibnds->selectAnchorSite(3); - TS_ASSERT_EQUALS(0, countBonds(*m_nibnds)); - m_nibnds->setRmin(-10); - TS_ASSERT_EQUALS(0, countBonds(*m_nibnds)); - // there are 12 nearest neighbors at 2.49 - m_nibnds->setRmax(3); - TS_ASSERT_EQUALS(12, countBonds(*m_nibnds)); - m_nibnds->selectAnchorSite(0); - TS_ASSERT_EQUALS(12, countBonds(*m_nibnds)); - // there are no self neighbors below the cell length of 3.52 - m_nibnds->selectAnchorSite(0); - m_nibnds->selectSiteRange(0, 1); - TS_ASSERT_EQUALS(0, countBonds(*m_nibnds)); - // and any other unit cell atom would give 4 neighbors - m_nibnds->selectAnchorSite(0); - m_nibnds->selectSiteRange(3, 4); - TS_ASSERT_EQUALS(4, countBonds(*m_nibnds)); - // there are no bonds between 2.6 and 3.4 - m_nibnds->setRmin(2.6); - m_nibnds->setRmax(3.4); - m_nibnds->selectSiteRange(0, 4); - TS_ASSERT_EQUALS(0, countBonds(*m_nibnds)); - // there are 6 second nearest neighbors at 3.52 - m_nibnds->setRmax(3.6); - TS_ASSERT_EQUALS(6, countBonds(*m_nibnds)); - // which sums to 18 neigbhors within radius 3.6 - m_nibnds->setRmin(0); - TS_ASSERT_EQUALS(18, countBonds(*m_nibnds)); - } - - - void test_bondCountWurtzite() - { - StructureAdapterPtr stru = - loadTestPeriodicStructure("ZnS_wurtzite.stru"); - BaseBondGeneratorPtr bnds = stru->createBondGenerator(); - TS_ASSERT_EQUALS(4, stru->countSites()); - bnds->selectAnchorSite(0); - bnds->selectSiteRange(0, 4); - bnds->setRmin(0); - // there should be no bond below the ZnS distance 2.31 - bnds->setRmax(2.2); - TS_ASSERT_EQUALS(0, countBonds(*bnds)); - // z-neighbor is slightly more distant than 3 in the lower plane - bnds->setRmax(2.35); - TS_ASSERT_EQUALS(3, countBonds(*bnds)); - bnds->setRmax(2.5); - TS_ASSERT_EQUALS(4, countBonds(*bnds)); - // there are 12 second nearest neighbors at 3.81 - bnds->setRmin(3.7); - bnds->setRmax(3.82); - TS_ASSERT_EQUALS(12, countBonds(*bnds)); - // and one more at 3.83 - bnds->setRmax(3.85); - TS_ASSERT_EQUALS(13, countBonds(*bnds)); - // making the total 17 - bnds->setRmin(0); - TS_ASSERT_EQUALS(17, countBonds(*bnds)); - // and the same happens for all other sites - bnds->selectAnchorSite(1); - TS_ASSERT_EQUALS(17, countBonds(*bnds)); - bnds->selectAnchorSite(2); - TS_ASSERT_EQUALS(17, countBonds(*bnds)); - bnds->selectAnchorSite(3); - TS_ASSERT_EQUALS(17, countBonds(*bnds)); - } - - - void test_LiTaO3() - { - const string lithium = "Li1+"; - const string tantalum = "Ta5+"; - const string oxygen = "O2-"; - const double epsu = 1e-5; - StructureAdapterPtr stru = loadTestPeriodicStructure("LiTaO3.stru"); - TS_ASSERT_EQUALS(30, stru->countSites()); - BaseBondGeneratorPtr bnds = stru->createBondGenerator(); - bnds->selectAnchorSite(0); - bnds->selectSiteRange(0, 30); - // there are 3 oxygen neighbors at 2.065 - bnds->setRmax(2.1); - TS_ASSERT_EQUALS(3, countBonds(*bnds)); - // Li at site 0 is isotropic, oxygens have equal msd-s towards Li - for (bnds->rewind(); !bnds->finished(); bnds->next()) - { - TS_ASSERT_EQUALS(lithium, stru->siteAtomType(bnds->site0())); - TS_ASSERT_EQUALS(oxygen, stru->siteAtomType(bnds->site1())); - TS_ASSERT_DELTA(0.00265968, testmsd0(stru, bnds), epsu); - TS_ASSERT_DELTA(0.00710945, testmsd1(stru, bnds), epsu); - } - // there are 3 oxygen neighbors at 2.26 - bnds->setRmin(2.2); - bnds->setRmax(2.3); - TS_ASSERT_EQUALS(3, countBonds(*bnds)); - for (bnds->rewind(); !bnds->finished(); bnds->next()) - { - TS_ASSERT_EQUALS(oxygen, stru->siteAtomType(bnds->site1())); - TS_ASSERT_DELTA(0.00265968, testmsd0(stru, bnds), epsu); - TS_ASSERT_DELTA(0.00824319, testmsd1(stru, bnds), epsu); - } - // finally there are 4 Ta neighbors between 2.8 and 3.1 - bnds->setRmin(2.8); - bnds->setRmax(3.1); - TS_ASSERT_EQUALS(4, countBonds(*bnds)); - for (bnds->rewind(); !bnds->finished(); bnds->next()) - { - TS_ASSERT_DELTA(0.00265968, testmsd0(stru, bnds), epsu); - TS_ASSERT_EQUALS(tantalum, stru->siteAtomType(bnds->site1())); - R3::Vector r01xy = bnds->r01(); - r01xy[2] = 0.0; - // for the tantalum above Li the msd equals U33 - if (R3::norm(r01xy) < 0.1) - { - TS_ASSERT_DELTA(0.00356, testmsd1(stru, bnds), epsu); - } - // other 3 tantalums are related by tripple axis and - // have the same msd towards the central Li - else - { - TS_ASSERT_DELTA(0.00486942, testmsd1(stru, bnds), epsu); - } - } - } +class TestPeriodicStructureBondGenerator : public CxxTest::TestSuite { + private: + StructureAdapterPtr m_ni; + BaseBondGeneratorPtr m_nibnds; + + public: + void setUp() { + CxxTest::setAbortTestOnFail(true); + if (!m_ni) { + m_ni = loadTestPeriodicStructure("Ni.stru"); + } + m_nibnds = m_ni->createBondGenerator(); + CxxTest::setAbortTestOnFail(false); + } + + void test_typeid() { + BaseBondGenerator& r_nibnds = *m_nibnds; + TS_ASSERT(typeid(PeriodicStructureBondGenerator) == typeid(r_nibnds)); + } + + void test_bondCountNickel() { + m_nibnds->selectAnchorSite(0); + m_nibnds->setRmin(0); + m_nibnds->setRmax(1.0); + TS_ASSERT_EQUALS(0, countBonds(*m_nibnds)); + m_nibnds->selectAnchorSite(3); + TS_ASSERT_EQUALS(0, countBonds(*m_nibnds)); + m_nibnds->setRmin(-10); + TS_ASSERT_EQUALS(0, countBonds(*m_nibnds)); + // there are 12 nearest neighbors at 2.49 + m_nibnds->setRmax(3); + TS_ASSERT_EQUALS(12, countBonds(*m_nibnds)); + m_nibnds->selectAnchorSite(0); + TS_ASSERT_EQUALS(12, countBonds(*m_nibnds)); + // there are no self neighbors below the cell length of 3.52 + m_nibnds->selectAnchorSite(0); + m_nibnds->selectSiteRange(0, 1); + TS_ASSERT_EQUALS(0, countBonds(*m_nibnds)); + // and any other unit cell atom would give 4 neighbors + m_nibnds->selectAnchorSite(0); + m_nibnds->selectSiteRange(3, 4); + TS_ASSERT_EQUALS(4, countBonds(*m_nibnds)); + // there are no bonds between 2.6 and 3.4 + m_nibnds->setRmin(2.6); + m_nibnds->setRmax(3.4); + m_nibnds->selectSiteRange(0, 4); + TS_ASSERT_EQUALS(0, countBonds(*m_nibnds)); + // there are 6 second nearest neighbors at 3.52 + m_nibnds->setRmax(3.6); + TS_ASSERT_EQUALS(6, countBonds(*m_nibnds)); + // which sums to 18 neighbors within radius 3.6 + m_nibnds->setRmin(0); + TS_ASSERT_EQUALS(18, countBonds(*m_nibnds)); + } + + void test_bondCountWurtzite() { + StructureAdapterPtr stru = loadTestPeriodicStructure("ZnS_wurtzite.stru"); + BaseBondGeneratorPtr bnds = stru->createBondGenerator(); + TS_ASSERT_EQUALS(4, stru->countSites()); + bnds->selectAnchorSite(0); + bnds->selectSiteRange(0, 4); + bnds->setRmin(0); + // there should be no bond below the ZnS distance 2.31 + bnds->setRmax(2.2); + TS_ASSERT_EQUALS(0, countBonds(*bnds)); + // z-neighbor is slightly more distant than 3 in the lower plane + bnds->setRmax(2.35); + TS_ASSERT_EQUALS(3, countBonds(*bnds)); + bnds->setRmax(2.5); + TS_ASSERT_EQUALS(4, countBonds(*bnds)); + // there are 12 second nearest neighbors at 3.81 + bnds->setRmin(3.7); + bnds->setRmax(3.82); + TS_ASSERT_EQUALS(12, countBonds(*bnds)); + // and one more at 3.83 + bnds->setRmax(3.85); + TS_ASSERT_EQUALS(13, countBonds(*bnds)); + // making the total 17 + bnds->setRmin(0); + TS_ASSERT_EQUALS(17, countBonds(*bnds)); + // and the same happens for all other sites + bnds->selectAnchorSite(1); + TS_ASSERT_EQUALS(17, countBonds(*bnds)); + bnds->selectAnchorSite(2); + TS_ASSERT_EQUALS(17, countBonds(*bnds)); + bnds->selectAnchorSite(3); + TS_ASSERT_EQUALS(17, countBonds(*bnds)); + } + + void test_LiTaO3() { + const string lithium = "Li1+"; + const string tantalum = "Ta5+"; + const string oxygen = "O2-"; + const double epsu = 1e-5; + StructureAdapterPtr stru = loadTestPeriodicStructure("LiTaO3.stru"); + TS_ASSERT_EQUALS(30, stru->countSites()); + BaseBondGeneratorPtr bnds = stru->createBondGenerator(); + bnds->selectAnchorSite(0); + bnds->selectSiteRange(0, 30); + // there are 3 oxygen neighbors at 2.065 + bnds->setRmax(2.1); + TS_ASSERT_EQUALS(3, countBonds(*bnds)); + // Li at site 0 is isotropic, oxygens have equal msd-s towards Li + for (bnds->rewind(); !bnds->finished(); bnds->next()) { + TS_ASSERT_EQUALS(lithium, stru->siteAtomType(bnds->site0())); + TS_ASSERT_EQUALS(oxygen, stru->siteAtomType(bnds->site1())); + TS_ASSERT_DELTA(0.00265968, testmsd0(stru, bnds), epsu); + TS_ASSERT_DELTA(0.00710945, testmsd1(stru, bnds), epsu); + } + // there are 3 oxygen neighbors at 2.26 + bnds->setRmin(2.2); + bnds->setRmax(2.3); + TS_ASSERT_EQUALS(3, countBonds(*bnds)); + for (bnds->rewind(); !bnds->finished(); bnds->next()) { + TS_ASSERT_EQUALS(oxygen, stru->siteAtomType(bnds->site1())); + TS_ASSERT_DELTA(0.00265968, testmsd0(stru, bnds), epsu); + TS_ASSERT_DELTA(0.00824319, testmsd1(stru, bnds), epsu); + } + // finally there are 4 Ta neighbors between 2.8 and 3.1 + bnds->setRmin(2.8); + bnds->setRmax(3.1); + TS_ASSERT_EQUALS(4, countBonds(*bnds)); + for (bnds->rewind(); !bnds->finished(); bnds->next()) { + TS_ASSERT_DELTA(0.00265968, testmsd0(stru, bnds), epsu); + TS_ASSERT_EQUALS(tantalum, stru->siteAtomType(bnds->site1())); + R3::Vector r01xy = bnds->r01(); + r01xy[2] = 0.0; + // for the tantalum above Li the msd equals U33 + if (R3::norm(r01xy) < 0.1) { + TS_ASSERT_DELTA(0.00356, testmsd1(stru, bnds), epsu); + } + // other 3 tantalums are related by triple axis and + // have the same msd towards the central Li + else { + TS_ASSERT_DELTA(0.00486942, testmsd1(stru, bnds), epsu); + } + } + } }; // class TestPeriodicStructureBondGenerator -} // namespace srreal -} // namespace diffpy +} // namespace srreal +} // namespace diffpy using diffpy::srreal::TestPeriodicStructureAdapter; using diffpy::srreal::TestPeriodicStructureBondGenerator; diff --git a/src/tests/TestPointsInSphere.hpp b/src/tests/TestPointsInSphere.hpp index 6be10856..814569d1 100644 --- a/src/tests/TestPointsInSphere.hpp +++ b/src/tests/TestPointsInSphere.hpp @@ -1,22 +1,22 @@ /*********************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2006 trustees of the Michigan State University -* 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 PointsInSphere module -* -* Comments: -* -***********************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2006 trustees of the Michigan State University + * 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 PointsInSphere module + * + * Comments: + * + ***********************************************************************/ #include @@ -31,32 +31,32 @@ namespace { const double eps = 1.0e-8; -struct vidxgroup -{ - double vijk[4]; - vidxgroup(double v, const int* ijk) - { - vijk[0] = v; - for (size_t i = 0; i != 3; ++i) { vijk[i+1] = ijk[i]; } - } - vidxgroup(double v, int i, int j, int k) - { - vijk[0] = v; vijk[1] = i; vijk[2] = j; vijk[3] = k; +struct vidxgroup { + double vijk[4]; + vidxgroup(double v, const int *ijk) { + vijk[0] = v; + for (size_t i = 0; i != 3; ++i) { + vijk[i + 1] = ijk[i]; } + } + vidxgroup(double v, int i, int j, int k) { + vijk[0] = v; + vijk[1] = i; + vijk[2] = j; + vijk[3] = k; + } }; -bool operator<(const vidxgroup &x, const vidxgroup &y) -{ - if (x.vijk[0] < y.vijk[0] - eps) return true; - if (x.vijk[0] > y.vijk[0] + eps) return false; - return lexicographical_compare(x.vijk, x.vijk + 4, y.vijk, y.vijk + 4); +bool operator<(const vidxgroup &x, const vidxgroup &y) { + if (x.vijk[0] < y.vijk[0] - eps) return true; + if (x.vijk[0] > y.vijk[0] + eps) return false; + return lexicographical_compare(x.vijk, x.vijk + 4, y.vijk, y.vijk + 4); } -bool operator==(const vidxgroup &x, const vidxgroup &y) -{ - bool eq = (fabs(x.vijk[0] - y.vijk[0]) < eps) && - equal(x.vijk+1, x.vijk+4, y.vijk+1); - return eq; +bool operator==(const vidxgroup &x, const vidxgroup &y) { + bool eq = (fabs(x.vijk[0] - y.vijk[0]) < eps) && + equal(x.vijk + 1, x.vijk + 4, y.vijk + 1); + return eq; } /* avoid warnings about unused function. @@ -67,7 +67,7 @@ ostream& operator<<(ostream &s, const vidxgroup &x) } */ -} // namespace +} // namespace //////////////////////////////////////////////////////////////////////// // TestPointsInSphere @@ -75,146 +75,111 @@ ostream& operator<<(ostream &s, const vidxgroup &x) using diffpy::srreal::pointsinsphere::LatticeParameters; -class TestPointsInSphere : public CxxTest::TestSuite -{ - -private: - - LatticeParameters* latpar; - -public: - - void setUp() - { - latpar = new LatticeParameters(1, 1, 1, 90, 90, 90); - } +class TestPointsInSphere : public CxxTest::TestSuite { + private: + LatticeParameters *latpar; - void tearDown() - { - delete latpar; - } + public: + void setUp() { latpar = new LatticeParameters(1, 1, 1, 90, 90, 90); } -private: + void tearDown() { delete latpar; } - int count(double Rmin, double Rmax) - { - int c = 0; - PointsInSphere sph(Rmin, Rmax, *latpar); - for (; !sph.finished(); sph.next()) ++c; - return c; - } + private: + int count(double Rmin, double Rmax) { + int c = 0; + PointsInSphere sph(Rmin, Rmax, *latpar); + for (; !sph.finished(); sph.next()) ++c; + return c; + } - vector sortedPoints(double Rmin, double Rmax) - { - vector ridx; - for ( PointsInSphere sph(Rmin, Rmax, *latpar); - not sph.finished(); sph.next() ) - { - ridx.push_back(vidxgroup(sph.r(), sph.mno())); - } - sort(ridx.begin(), ridx.end()); - return ridx; + vector sortedPoints(double Rmin, double Rmax) { + vector ridx; + for (PointsInSphere sph(Rmin, Rmax, *latpar); not sph.finished(); + sph.next()) { + ridx.push_back(vidxgroup(sph.r(), sph.mno())); } - -public: - - void test_Cubic() - { - latpar->a = latpar->b = latpar->c = 1.0; - latpar->alpha = latpar->beta = latpar->gamma = 90.0; - latpar->update(); - TS_ASSERT_EQUALS(0, count(0.0, 0.0)); - TS_ASSERT_EQUALS(0, count(eps, 0.5)); - TS_ASSERT_EQUALS(0, count(1.0 + eps, 1.1)); - TS_ASSERT_EQUALS(1, count(0.0, eps)); - TS_ASSERT_EQUALS(7, count(0.0, 1 + eps)); - TS_ASSERT_EQUALS(19, count(0.0, sqrt(2.0) + eps)); - TS_ASSERT_EQUALS(12, count(1.0 + eps, sqrt(2.0) + eps)); + sort(ridx.begin(), ridx.end()); + return ridx; + } + + public: + void test_Cubic() { + latpar->a = latpar->b = latpar->c = 1.0; + latpar->alpha = latpar->beta = latpar->gamma = 90.0; + latpar->update(); + TS_ASSERT_EQUALS(0, count(0.0, 0.0)); + TS_ASSERT_EQUALS(0, count(eps, 0.5)); + TS_ASSERT_EQUALS(0, count(1.0 + eps, 1.1)); + TS_ASSERT_EQUALS(1, count(0.0, eps)); + TS_ASSERT_EQUALS(7, count(0.0, 1 + eps)); + TS_ASSERT_EQUALS(19, count(0.0, sqrt(2.0) + eps)); + TS_ASSERT_EQUALS(12, count(1.0 + eps, sqrt(2.0) + eps)); + } + + void test_Orthorombic() { + latpar->a = 1.0; + latpar->b = 2.0; + latpar->c = 3.0; + latpar->alpha = latpar->beta = latpar->gamma = 90.0; + latpar->update(); + TS_ASSERT_EQUALS(3, count(0.0, 1.1)); + TS_ASSERT_EQUALS(4, count(1.9, 2.1)); + vidxgroup ep[] = { + vidxgroup(0, 0, 0, 0), vidxgroup(1, -1, 0, 0), + vidxgroup(1, 1, 0, 0), vidxgroup(2, -2, 0, 0), + vidxgroup(2, 0, -1, 0), vidxgroup(2, 0, 1, 0), + vidxgroup(2, 2, 0, 0), vidxgroup(sqrt(5.0), -1, -1, 0), + vidxgroup(sqrt(5.0), -1, 1, 0), vidxgroup(sqrt(5.0), 1, -1, 0), + vidxgroup(sqrt(5.0), 1, 1, 0), vidxgroup(sqrt(8.0), -2, -1, 0), + vidxgroup(sqrt(8.0), -2, 1, 0), vidxgroup(sqrt(8.0), 2, -1, 0), + vidxgroup(sqrt(8.0), 2, 1, 0), vidxgroup(3, -3, 0, 0), + vidxgroup(3, 0, 0, -1), vidxgroup(3, 0, 0, 1), + vidxgroup(3, 3, 0, 0), + }; + vector exp_pts(ep, ep + sizeof(ep) / sizeof(vidxgroup)); + vector act_pts = sortedPoints(0.0, 3.0 + eps); + TS_ASSERT_EQUALS(exp_pts.size(), act_pts.size()); + for (size_t i = 0; i != exp_pts.size(); ++i) { + TS_ASSERT_EQUALS(exp_pts[i], act_pts[i]); } - - void test_Orthorombic() - { - latpar->a = 1.0; latpar->b = 2.0; latpar->c = 3.0; - latpar->alpha = latpar->beta = latpar->gamma = 90.0; - latpar->update(); - TS_ASSERT_EQUALS(3, count(0.0, 1.1)); - TS_ASSERT_EQUALS(4, count(1.9, 2.1)); - vidxgroup ep[] = { - vidxgroup(0, 0, 0, 0), - vidxgroup(1, -1, 0, 0), - vidxgroup(1, 1, 0, 0), - vidxgroup(2, -2, 0, 0), - vidxgroup(2, 0, -1, 0), - vidxgroup(2, 0, 1, 0), - vidxgroup(2, 2, 0, 0), - vidxgroup(sqrt(5.0), -1, -1, 0), - vidxgroup(sqrt(5.0), -1, 1, 0), - vidxgroup(sqrt(5.0), 1, -1, 0), - vidxgroup(sqrt(5.0), 1, 1, 0), - vidxgroup(sqrt(8.0), -2, -1, 0), - vidxgroup(sqrt(8.0), -2, 1, 0), - vidxgroup(sqrt(8.0), 2, -1, 0), - vidxgroup(sqrt(8.0), 2, 1, 0), - vidxgroup(3, -3, 0, 0), - vidxgroup(3, 0, 0, -1), - vidxgroup(3, 0, 0, 1), - vidxgroup(3, 3, 0, 0), - }; - vector exp_pts(ep, ep + sizeof(ep)/sizeof(vidxgroup)); - vector act_pts = sortedPoints(0.0, 3.0+eps); - TS_ASSERT_EQUALS(exp_pts.size(), act_pts.size()); - for (size_t i = 0; i != exp_pts.size(); ++i) - { - TS_ASSERT_EQUALS(exp_pts[i], act_pts[i]); - } - } - - void test_Hexagonal() - { - latpar->a = 1.0; latpar->b = 1.0; latpar->c = 2.0; - latpar->alpha = latpar->beta = 90.0; latpar->gamma = 120.0; - latpar->update(); - TS_ASSERT_EQUALS(7, count(0.0, 1+eps)); - vidxgroup ep[] = { - vidxgroup(0, 0, 0, 0), - vidxgroup(1, -1, -1, 0), - vidxgroup(1, -1, 0, 0), - vidxgroup(1, 0, -1, 0), - vidxgroup(1, 0, 1, 0), - vidxgroup(1, 1, 0, 0), - vidxgroup(1, 1, 1, 0), - vidxgroup(sqrt(3.0), -2, -1, 0), - vidxgroup(sqrt(3.0), -1, -2, 0), - vidxgroup(sqrt(3.0), -1, 1, 0), - vidxgroup(sqrt(3.0), 1, -1, 0), - vidxgroup(sqrt(3.0), 1, 2, 0), - vidxgroup(sqrt(3.0), 2, 1, 0), - vidxgroup(2, -2, -2, 0), - vidxgroup(2, -2, 0, 0), - vidxgroup(2, 0, -2, 0), - vidxgroup(2, 0, 0, -1), - vidxgroup(2, 0, 0, 1), - vidxgroup(2, 0, 2, 0), - vidxgroup(2, 2, 0, 0), - vidxgroup(2, 2, 2, 0), - }; - vector exp_pts(ep, ep + sizeof(ep)/sizeof(vidxgroup)); - vector act_pts = sortedPoints(0.0, 2.0+eps); - TS_ASSERT_EQUALS(exp_pts.size(), act_pts.size()); - for (size_t i = 0; i != exp_pts.size(); ++i) - { - TS_ASSERT_EQUALS(exp_pts[i], act_pts[i]); - } - } - - void test_FCC() - { - latpar->a = latpar->b = latpar->c = sqrt(0.5); - latpar->alpha = latpar->beta = latpar->gamma = 60.0; - latpar->update(); - TS_ASSERT_EQUALS(13, count(0.0, sqrt(0.5)+eps)); - TS_ASSERT_EQUALS(19, count(0.0, 1.0+eps)); + } + + void test_Hexagonal() { + latpar->a = 1.0; + latpar->b = 1.0; + latpar->c = 2.0; + latpar->alpha = latpar->beta = 90.0; + latpar->gamma = 120.0; + latpar->update(); + TS_ASSERT_EQUALS(7, count(0.0, 1 + eps)); + vidxgroup ep[] = { + vidxgroup(0, 0, 0, 0), vidxgroup(1, -1, -1, 0), + vidxgroup(1, -1, 0, 0), vidxgroup(1, 0, -1, 0), + vidxgroup(1, 0, 1, 0), vidxgroup(1, 1, 0, 0), + vidxgroup(1, 1, 1, 0), vidxgroup(sqrt(3.0), -2, -1, 0), + vidxgroup(sqrt(3.0), -1, -2, 0), vidxgroup(sqrt(3.0), -1, 1, 0), + vidxgroup(sqrt(3.0), 1, -1, 0), vidxgroup(sqrt(3.0), 1, 2, 0), + vidxgroup(sqrt(3.0), 2, 1, 0), vidxgroup(2, -2, -2, 0), + vidxgroup(2, -2, 0, 0), vidxgroup(2, 0, -2, 0), + vidxgroup(2, 0, 0, -1), vidxgroup(2, 0, 0, 1), + vidxgroup(2, 0, 2, 0), vidxgroup(2, 2, 0, 0), + vidxgroup(2, 2, 2, 0), + }; + vector exp_pts(ep, ep + sizeof(ep) / sizeof(vidxgroup)); + vector act_pts = sortedPoints(0.0, 2.0 + eps); + TS_ASSERT_EQUALS(exp_pts.size(), act_pts.size()); + for (size_t i = 0; i != exp_pts.size(); ++i) { + TS_ASSERT_EQUALS(exp_pts[i], act_pts[i]); } + } + + void test_FCC() { + latpar->a = latpar->b = latpar->c = sqrt(0.5); + latpar->alpha = latpar->beta = latpar->gamma = 60.0; + latpar->update(); + TS_ASSERT_EQUALS(13, count(0.0, sqrt(0.5) + eps)); + TS_ASSERT_EQUALS(19, count(0.0, 1.0 + eps)); + } }; // class TestPointsInSphere diff --git a/src/tests/TestR3linalg.hpp b/src/tests/TestR3linalg.hpp index 8f779dfb..dfc23175 100644 --- a/src/tests/TestR3linalg.hpp +++ b/src/tests/TestR3linalg.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class TestR3linalg -- unit test suite for the R3linalg module -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class TestR3linalg -- unit test suite for the R3linalg module + * + *****************************************************************************/ #include @@ -24,115 +24,74 @@ using namespace std; using namespace diffpy::srreal; using diffpy::mathutils::EpsilonEqual; - -class TestR3linalg : public CxxTest::TestSuite -{ - -private: - - double precision; - EpsilonEqual allclose; - -public: - - void setUp() - { - precision = 1.0e-12; - allclose = EpsilonEqual(precision); - } - - - void test_determinant() - { - // default lattice should be cartesian - R3::Matrix A1( - 9, 1, 9, - 6, 7, 4, - 0, 2, 9); - R3::Matrix A2( - 9, 1, 9, - 0, 2, 9, - 6, 7, 4); - double detA = 549; - TS_ASSERT_EQUALS(detA, R3::determinant(A1)); - TS_ASSERT_EQUALS(-detA, R3::determinant(A2)); - } - - - void test_inverse() - { - R3::Matrix A( - 0.5359, -0.5904, 0.8670, - -0.0053, 0.7559, 0.2692, - -0.8926, 0.9424, 0.9692); - R3::Matrix invA( - 0.49063197005867, 1.42323870111089, -0.83420736316541, - -0.24089965988852, 1.32489393619466, -0.15249839300481, - 0.68609361943181, 0.02249568627913, 0.41178393851247); - TS_ASSERT(allclose(invA, R3::inverse(A))); - } - - - void test_transpose() - { - R3::Matrix A( - 0.5359, -0.5904, 0.8670, - -0.0053, 0.7559, 0.2692, - -0.8926, 0.9424, 0.9692); - R3::Matrix Atrans( - 0.5359, -0.0053, -0.8926, - -0.5904, 0.7559, 0.9424, - 0.8670, 0.2692, 0.9692); - TS_ASSERT_EQUALS(Atrans, R3::trans(A)); - } - - - void test_norm() - { - R3::Vector v1(3.0, 4.0, 0.0); - R3::Vector v2(0.67538115798129, 0.72108424545413, 0.15458914063315); - TS_ASSERT_DELTA(5.0, R3::norm(v1), precision); - TS_ASSERT_DELTA(1.0, R3::norm(v2), precision); - } - - - void test_dot() - { - R3::Vector v1(-0.97157650177843, 0.43206192654604, 0.56318686427062); - R3::Vector v2(-0.04787719419083, 0.55895824010234, -0.34472910285751); - double dot_v1v2 = 0.09387402846316; - TS_ASSERT_DELTA(dot_v1v2, R3::dot(v1, v2), precision); - } - - - void test_cross() - { - R3::Vector v1( - -0.55160549932839, -0.58291452407504, 0.12378162306543); - R3::Vector v2( - 0.60842511285200, -0.97946444006248, -0.02828214306095); - R3::Vector v1xv2( - 0.13772577008800, 0.05971126233738, 0.89493780662849); - TS_ASSERT(allclose(v1xv2, R3::cross(v1, v2))); - } - - - void test_product() - { - R3::Matrix M( - 0.459631856585519, 0.726448904209060, 0.085844209317482, - 0.806838095807669, 0.240116998848762, 0.305032463662873, - 0.019487235483683, 0.580605953831255, 0.726077578738676); - R3::Vector v( - 0.608652521912322, 0.519716469261062, 0.842577887601566); - R3::Vector prod_Mv( - 0.729633980805669, 0.872890409522479, 0.925388343907868); - R3::Vector prod_vM( - 0.715502648789536, 1.056153454546559, 0.822556602046019); - TS_ASSERT(allclose(prod_Mv, R3::mxvecproduct(M, v))); - TS_ASSERT(allclose(prod_vM, R3::mxvecproduct(v, M))); - } - +class TestR3linalg : public CxxTest::TestSuite { + private: + double precision; + EpsilonEqual allclose; + + public: + void setUp() { + precision = 1.0e-12; + allclose = EpsilonEqual(precision); + } + + void test_determinant() { + // default lattice should be cartesian + R3::Matrix A1(9, 1, 9, 6, 7, 4, 0, 2, 9); + R3::Matrix A2(9, 1, 9, 0, 2, 9, 6, 7, 4); + double detA = 549; + TS_ASSERT_EQUALS(detA, R3::determinant(A1)); + TS_ASSERT_EQUALS(-detA, R3::determinant(A2)); + } + + void test_inverse() { + R3::Matrix A(0.5359, -0.5904, 0.8670, -0.0053, 0.7559, 0.2692, -0.8926, + 0.9424, 0.9692); + R3::Matrix invA(0.49063197005867, 1.42323870111089, -0.83420736316541, + -0.24089965988852, 1.32489393619466, -0.15249839300481, + 0.68609361943181, 0.02249568627913, 0.41178393851247); + TS_ASSERT(allclose(invA, R3::inverse(A))); + } + + void test_transpose() { + R3::Matrix A(0.5359, -0.5904, 0.8670, -0.0053, 0.7559, 0.2692, -0.8926, + 0.9424, 0.9692); + R3::Matrix Atrans(0.5359, -0.0053, -0.8926, -0.5904, 0.7559, 0.9424, 0.8670, + 0.2692, 0.9692); + TS_ASSERT_EQUALS(Atrans, R3::trans(A)); + } + + void test_norm() { + R3::Vector v1(3.0, 4.0, 0.0); + R3::Vector v2(0.67538115798129, 0.72108424545413, 0.15458914063315); + TS_ASSERT_DELTA(5.0, R3::norm(v1), precision); + TS_ASSERT_DELTA(1.0, R3::norm(v2), precision); + } + + void test_dot() { + R3::Vector v1(-0.97157650177843, 0.43206192654604, 0.56318686427062); + R3::Vector v2(-0.04787719419083, 0.55895824010234, -0.34472910285751); + double dot_v1v2 = 0.09387402846316; + TS_ASSERT_DELTA(dot_v1v2, R3::dot(v1, v2), precision); + } + + void test_cross() { + R3::Vector v1(-0.55160549932839, -0.58291452407504, 0.12378162306543); + R3::Vector v2(0.60842511285200, -0.97946444006248, -0.02828214306095); + R3::Vector v1xv2(0.13772577008800, 0.05971126233738, 0.89493780662849); + TS_ASSERT(allclose(v1xv2, R3::cross(v1, v2))); + } + + void test_product() { + R3::Matrix M(0.459631856585519, 0.726448904209060, 0.085844209317482, + 0.806838095807669, 0.240116998848762, 0.305032463662873, + 0.019487235483683, 0.580605953831255, 0.726077578738676); + R3::Vector v(0.608652521912322, 0.519716469261062, 0.842577887601566); + R3::Vector prod_Mv(0.729633980805669, 0.872890409522479, 0.925388343907868); + R3::Vector prod_vM(0.715502648789536, 1.056153454546559, 0.822556602046019); + TS_ASSERT(allclose(prod_Mv, R3::mxvecproduct(M, v))); + TS_ASSERT(allclose(prod_vM, R3::mxvecproduct(v, M))); + } }; // class TestR3linalg diff --git a/src/tests/TestRuntimePath.hpp b/src/tests/TestRuntimePath.hpp index 36b52189..ea0d46f7 100644 --- a/src/tests/TestRuntimePath.hpp +++ b/src/tests/TestRuntimePath.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy Complex Modeling Initiative -* (c) 2013 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. -* -****************************************************************************** -* -* class TestRuntimePath -- unit tests for the resolution of datafile paths -* -*****************************************************************************/ + * + * libdiffpy Complex Modeling Initiative + * (c) 2013 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. + * + ****************************************************************************** + * + * class TestRuntimePath -- unit tests for the resolution of datafile paths + * + *****************************************************************************/ #include #include @@ -26,63 +26,48 @@ using diffpy::runtimepath::datapath; - -class TestRuntimePath : public CxxTest::TestSuite -{ - - private: - - bool mhas_diffpyruntime; - std::string mdiffpyruntime; - - bool filereadable(std::string& fname) - { - std::ifstream fp(fname.c_str()); - return bool(fp); - } - - public: - - void setUp() - { - char* pe = getenv("DIFFPYRUNTIME"); - mhas_diffpyruntime = pe; - if (mhas_diffpyruntime) mdiffpyruntime = pe; - unsetenv("DIFFPYRUNTIME"); - } - - - void tearDown() - { - unsetenv("DIFFPYRUNTIME"); - if (mhas_diffpyruntime) - { - setenv("DIFFPYRUNTIME", mdiffpyruntime.c_str(), 1); - } - } - - - void test_datapath() - { - std::string f = datapath("f0_WaasKirf.dat"); - TS_ASSERT(filereadable(f)); - std::string d = datapath(""); - TS_ASSERT_EQUALS(f, d + '/' + "f0_WaasKirf.dat"); - } - - - void test_envvar_lookup() - { - using namespace std; - setenv("DIFFPYRUNTIME", "does/not/exist", 0); - TS_ASSERT_THROWS(datapath("f0_WaasKirf.dat"), runtime_error); - TS_ASSERT_THROWS(datapath("NaCl.cif"), runtime_error); - string td = prepend_testdata_dir(""); - setenv("DIFFPYRUNTIME", td.c_str(), 1); - string fnacl = prepend_testdata_dir("NaCl.cif"); - TS_ASSERT_EQUALS(fnacl, datapath("NaCl.cif")); - } - +class TestRuntimePath : public CxxTest::TestSuite { + private: + bool mhas_diffpyruntime; + std::string mdiffpyruntime; + + bool filereadable(std::string& fname) { + std::ifstream fp(fname.c_str()); + return bool(fp); + } + + public: + void setUp() { + char* pe = getenv("DIFFPYRUNTIME"); + mhas_diffpyruntime = pe; + if (mhas_diffpyruntime) mdiffpyruntime = pe; + unsetenv("DIFFPYRUNTIME"); + } + + void tearDown() { + unsetenv("DIFFPYRUNTIME"); + if (mhas_diffpyruntime) { + setenv("DIFFPYRUNTIME", mdiffpyruntime.c_str(), 1); + } + } + + void test_datapath() { + std::string f = datapath("f0_WaasKirf.dat"); + TS_ASSERT(filereadable(f)); + std::string d = datapath(""); + TS_ASSERT_EQUALS(f, d + '/' + "f0_WaasKirf.dat"); + } + + void test_envvar_lookup() { + using namespace std; + setenv("DIFFPYRUNTIME", "does/not/exist", 0); + TS_ASSERT_THROWS(datapath("f0_WaasKirf.dat"), runtime_error); + TS_ASSERT_THROWS(datapath("NaCl.cif"), runtime_error); + string td = prepend_testdata_dir(""); + setenv("DIFFPYRUNTIME", td.c_str(), 1); + string fnacl = prepend_testdata_dir("NaCl.cif"); + TS_ASSERT_EQUALS(fnacl, datapath("NaCl.cif")); + } }; // End of file diff --git a/src/tests/TestScatteringFactorTable.hpp b/src/tests/TestScatteringFactorTable.hpp index 5c517a2d..cfb3e64a 100644 --- a/src/tests/TestScatteringFactorTable.hpp +++ b/src/tests/TestScatteringFactorTable.hpp @@ -1,21 +1,21 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class TestScatteringFactorTable -- unit tests for implementations -* of the ScatteringFactorTable class -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class TestScatteringFactorTable -- unit tests for implementations + * of the ScatteringFactorTable class + * + *****************************************************************************/ #include #include @@ -28,184 +28,158 @@ using namespace std; using namespace diffpy::srreal; - -class TestScatteringFactorTable : public CxxTest::TestSuite -{ - - private: - - double mtol; - double meps; - ScatteringFactorTablePtr msftb; - - public: - - void setUp() - { - mtol = 1.0e-4; - meps = 10 * diffpy::mathutils::DOUBLE_EPS; - } - - - void test_factory() - { - ScatteringFactorTablePtr sfx0, sfx1, sfn0, sfn1; - TS_ASSERT_THROWS(ScatteringFactorTable::createByType("invalid"), - invalid_argument); - sfx0 = ScatteringFactorTable::createByType("xray"); - sfx1 = ScatteringFactorTable::createByType("X"); - TS_ASSERT(sfx0.get()); - TS_ASSERT(sfx1.get()); - TS_ASSERT_EQUALS(sfx0->type(), sfx1->type()); - ScatteringFactorTable& r_sfx0 = *sfx0; - ScatteringFactorTable& r_sfx1 = *sfx1; - TS_ASSERT(typeid(r_sfx0) == typeid(r_sfx1)); - sfn0 = ScatteringFactorTable::createByType("neutron"); - sfn1 = ScatteringFactorTable::createByType("N"); - TS_ASSERT(sfn0.get()); - TS_ASSERT(sfn1.get()); - TS_ASSERT_EQUALS(sfn0->type(), sfn1->type()); - ScatteringFactorTable& r_sfn0 = *sfn0; - ScatteringFactorTable& r_sfn1 = *sfn1; - TS_ASSERT(typeid(r_sfn0) == typeid(r_sfn1)); - } - - - void test_setCustomAs() - { - msftb = ScatteringFactorTable::createByType("X"); - TS_ASSERT_THROWS(msftb->lookup(""), invalid_argument); - TS_ASSERT_DELTA(6.0, msftb->lookup("C"), 0.01); - msftb->setCustomAs("C", "C", 6.3); - TS_ASSERT_DELTA(6.3, msftb->lookup("C"), meps); - msftb->setCustomAs("C", "C", 6.4); - TS_ASSERT_DELTA(6.4, msftb->lookup("C"), meps); - TS_ASSERT_THROWS(msftb->lookup("Ccustom"), invalid_argument); - msftb->setCustomAs("Ccustom", "C", 6.5); - TS_ASSERT_DELTA(6.5, msftb->lookup("Ccustom"), meps); - msftb->resetCustom("C"); - TS_ASSERT_DELTA(6.5, msftb->lookup("Ccustom"), meps); - TS_ASSERT_DELTA(6.0, msftb->lookup("C"), 0.01); - msftb->resetAll(); - TS_ASSERT_THROWS(msftb->lookup("Ccustom"), invalid_argument); - TS_ASSERT_DELTA(6.0, msftb->lookup("C"), 0.01); - msftb->setCustomAs("Calias", "C"); - TS_ASSERT_EQUALS(msftb->lookup("C", 0), - msftb->lookup("Calias", 0)); - TS_ASSERT_DELTA(msftb->lookup("C", 2.5), - msftb->lookup("Calias", 2.5), meps); - } - - - void test_getCustomSymbols() - { - msftb = ScatteringFactorTable::createByType("X"); - TS_ASSERT(msftb->getCustomSymbols().empty()); - msftb->setCustomAs("C", "C", 6.1); - TS_ASSERT_EQUALS(1u, msftb->getCustomSymbols().size()); - TS_ASSERT_EQUALS(1u, msftb->getCustomSymbols().count("C")); - msftb->setCustomAs("C", "C", 6.3); - TS_ASSERT_EQUALS(1u, msftb->getCustomSymbols().size()); - TS_ASSERT_EQUALS(1u, msftb->getCustomSymbols().count("C")); - TS_ASSERT_DELTA(6.3, msftb->lookup("C"), meps); - ScatteringFactorTablePtr sftb1 = msftb->clone(); - msftb->resetCustom("C"); - TS_ASSERT(msftb->getCustomSymbols().empty()); - TS_ASSERT_EQUALS(1u, sftb1->getCustomSymbols().size()); - TS_ASSERT_EQUALS(1u, sftb1->getCustomSymbols().count("C")); - TS_ASSERT_DELTA(6.3, sftb1->lookup("C"), meps); - sftb1->resetAll(); - TS_ASSERT(msftb->getCustomSymbols().empty()); - } - - - void test_ticker() - { - using diffpy::eventticker::EventTicker; - msftb = ScatteringFactorTable::createByType("X"); - EventTicker e0 = msftb->ticker(); - TS_ASSERT_EQUALS(e0, msftb->clone()->ticker()); - TS_ASSERT_EQUALS(e0, dumpandload(msftb)->ticker()); - msftb->setCustomAs("C", "C", 6.1); - TS_ASSERT_LESS_THAN(e0, msftb->ticker()); - } - - - void test_SFTXray() - { - msftb = ScatteringFactorTable::createByType("X"); - TS_ASSERT_DELTA(1.0, msftb->lookup("H"), 0.01); - TS_ASSERT_DELTA(8.0, msftb->lookup("O"), 0.01); - TS_ASSERT_DELTA(10.0, msftb->lookup("O2-"), 0.01); - TS_ASSERT_DELTA(11.0, msftb->lookup("Na"), 0.01); - TS_ASSERT_DELTA(10.0, msftb->lookup("Na+"), 0.01); - TS_ASSERT_EQUALS(msftb->lookup("Na+"), msftb->lookup("Na1+")); - TS_ASSERT_DELTA(74.0, msftb->lookup("W"), 0.04); - TS_ASSERT_DELTA(88.0, msftb->lookup("Ra"), 0.04); - TS_ASSERT_EQUALS(msftb->lookup("Si"), msftb->lookup("Si0+")); - TS_ASSERT_EQUALS("xray", msftb->clone()->type()); - } - - - void test_SFTElectron() - { - using diffpy::mathutils::DOUBLE_MAX; - msftb = ScatteringFactorTable::createByType("E"); - TS_ASSERT_EQUALS(DOUBLE_MAX, msftb->lookup("H")); - TS_ASSERT_EQUALS(DOUBLE_MAX, msftb->lookup("Ra")); - TS_ASSERT_DELTA(3.42104, msftb->lookup("Na", 1), 1e-5); - TS_ASSERT_DELTA(1.34868, msftb->lookup("Na", 3), 1e-5); - TS_ASSERT_DELTA(0.832158, msftb->lookup("Na", 5), 1e-5); - TS_ASSERT_THROWS(msftb->lookup("H4+"), invalid_argument); - TS_ASSERT_THROWS(msftb->lookup("H4+", 3), invalid_argument); - TS_ASSERT_EQUALS("electron", msftb->clone()->type()); - } - - - void test_SFTNeutron() - { - msftb = ScatteringFactorTable::createByType("N"); - TS_ASSERT_DELTA(3.63, msftb->lookup("Na"), mtol); - TS_ASSERT_DELTA(-3.37, msftb->lookup("Ti"), mtol); - TS_ASSERT_DELTA(5.805, msftb->lookup("O"), mtol); - TS_ASSERT_DELTA(6.6484, msftb->lookup("C"), mtol); - TS_ASSERT_EQUALS(msftb->lookup("Na"), msftb->lookup("Na1+")); - TS_ASSERT_EQUALS(msftb->lookup("Ge"), msftb->lookup("Ge0+")); - TS_ASSERT_EQUALS("neutron", msftb->clone()->type()); - } - - - void test_ElectronNumber() - { - msftb = ScatteringFactorTable::createByType("electronnumber"); - TS_ASSERT_EQUALS(8.0, msftb->lookup("O")); - TS_ASSERT_EQUALS(10.0, msftb->lookup("O2-")); - TS_ASSERT_EQUALS(18.0, msftb->lookup("K+")); - TS_ASSERT_EQUALS(18.0, msftb->lookup("K1+")); - TS_ASSERT_EQUALS(68.0, msftb->lookup("W6+")); - TS_ASSERT_THROWS(msftb->lookup("H4+"), invalid_argument); - TS_ASSERT_THROWS(msftb->lookup("O3+"), invalid_argument); - TS_ASSERT_EQUALS("electronnumber", msftb->clone()->type()); - } - - - void test_serialization() - { - ScatteringFactorTablePtr sftb1; - msftb = ScatteringFactorTable::createByType("electronnumber"); - msftb->setCustomAs("H", "H", 1.23); - sftb1 = dumpandload(msftb); - TS_ASSERT_EQUALS(string("electronnumber"), sftb1->type()); - TS_ASSERT_EQUALS(1.23, sftb1->lookup("H")); - TS_ASSERT_EQUALS(1u, sftb1->getCustomSymbols().size()); - sftb1 = dumpandload(ScatteringFactorTable::createByType("N")); - TS_ASSERT_EQUALS(string("neutron"), sftb1->type()); - sftb1 = dumpandload(ScatteringFactorTable::createByType("X")); - TS_ASSERT_EQUALS(string("xray"), sftb1->type()); - sftb1 = dumpandload(ScatteringFactorTable::createByType("E")); - TS_ASSERT_EQUALS(string("electron"), sftb1->type()); - } - +class TestScatteringFactorTable : public CxxTest::TestSuite { + private: + double mtol; + double meps; + ScatteringFactorTablePtr msftb; + + public: + void setUp() { + mtol = 1.0e-4; + meps = 10 * diffpy::mathutils::DOUBLE_EPS; + } + + void test_factory() { + ScatteringFactorTablePtr sfx0, sfx1, sfn0, sfn1; + TS_ASSERT_THROWS(ScatteringFactorTable::createByType("invalid"), + invalid_argument); + sfx0 = ScatteringFactorTable::createByType("xray"); + sfx1 = ScatteringFactorTable::createByType("X"); + TS_ASSERT(sfx0.get()); + TS_ASSERT(sfx1.get()); + TS_ASSERT_EQUALS(sfx0->type(), sfx1->type()); + ScatteringFactorTable& r_sfx0 = *sfx0; + ScatteringFactorTable& r_sfx1 = *sfx1; + TS_ASSERT(typeid(r_sfx0) == typeid(r_sfx1)); + sfn0 = ScatteringFactorTable::createByType("neutron"); + sfn1 = ScatteringFactorTable::createByType("N"); + TS_ASSERT(sfn0.get()); + TS_ASSERT(sfn1.get()); + TS_ASSERT_EQUALS(sfn0->type(), sfn1->type()); + ScatteringFactorTable& r_sfn0 = *sfn0; + ScatteringFactorTable& r_sfn1 = *sfn1; + TS_ASSERT(typeid(r_sfn0) == typeid(r_sfn1)); + } + + void test_setCustomAs() { + msftb = ScatteringFactorTable::createByType("X"); + TS_ASSERT_THROWS(msftb->lookup(""), invalid_argument); + TS_ASSERT_DELTA(6.0, msftb->lookup("C"), 0.01); + msftb->setCustomAs("C", "C", 6.3); + TS_ASSERT_DELTA(6.3, msftb->lookup("C"), meps); + msftb->setCustomAs("C", "C", 6.4); + TS_ASSERT_DELTA(6.4, msftb->lookup("C"), meps); + TS_ASSERT_THROWS(msftb->lookup("Ccustom"), invalid_argument); + msftb->setCustomAs("Ccustom", "C", 6.5); + TS_ASSERT_DELTA(6.5, msftb->lookup("Ccustom"), meps); + msftb->resetCustom("C"); + TS_ASSERT_DELTA(6.5, msftb->lookup("Ccustom"), meps); + TS_ASSERT_DELTA(6.0, msftb->lookup("C"), 0.01); + msftb->resetAll(); + TS_ASSERT_THROWS(msftb->lookup("Ccustom"), invalid_argument); + TS_ASSERT_DELTA(6.0, msftb->lookup("C"), 0.01); + msftb->setCustomAs("Calias", "C"); + TS_ASSERT_EQUALS(msftb->lookup("C", 0), msftb->lookup("Calias", 0)); + TS_ASSERT_DELTA(msftb->lookup("C", 2.5), msftb->lookup("Calias", 2.5), + meps); + } + + void test_getCustomSymbols() { + msftb = ScatteringFactorTable::createByType("X"); + TS_ASSERT(msftb->getCustomSymbols().empty()); + msftb->setCustomAs("C", "C", 6.1); + TS_ASSERT_EQUALS(1u, msftb->getCustomSymbols().size()); + TS_ASSERT_EQUALS(1u, msftb->getCustomSymbols().count("C")); + msftb->setCustomAs("C", "C", 6.3); + TS_ASSERT_EQUALS(1u, msftb->getCustomSymbols().size()); + TS_ASSERT_EQUALS(1u, msftb->getCustomSymbols().count("C")); + TS_ASSERT_DELTA(6.3, msftb->lookup("C"), meps); + ScatteringFactorTablePtr sftb1 = msftb->clone(); + msftb->resetCustom("C"); + TS_ASSERT(msftb->getCustomSymbols().empty()); + TS_ASSERT_EQUALS(1u, sftb1->getCustomSymbols().size()); + TS_ASSERT_EQUALS(1u, sftb1->getCustomSymbols().count("C")); + TS_ASSERT_DELTA(6.3, sftb1->lookup("C"), meps); + sftb1->resetAll(); + TS_ASSERT(msftb->getCustomSymbols().empty()); + } + + void test_ticker() { + using diffpy::eventticker::EventTicker; + msftb = ScatteringFactorTable::createByType("X"); + EventTicker e0 = msftb->ticker(); + TS_ASSERT_EQUALS(e0, msftb->clone()->ticker()); + TS_ASSERT_EQUALS(e0, dumpandload(msftb)->ticker()); + msftb->setCustomAs("C", "C", 6.1); + TS_ASSERT_LESS_THAN(e0, msftb->ticker()); + } + + void test_SFTXray() { + msftb = ScatteringFactorTable::createByType("X"); + TS_ASSERT_DELTA(1.0, msftb->lookup("H"), 0.01); + TS_ASSERT_DELTA(8.0, msftb->lookup("O"), 0.01); + TS_ASSERT_DELTA(10.0, msftb->lookup("O2-"), 0.01); + TS_ASSERT_DELTA(11.0, msftb->lookup("Na"), 0.01); + TS_ASSERT_DELTA(10.0, msftb->lookup("Na+"), 0.01); + TS_ASSERT_EQUALS(msftb->lookup("Na+"), msftb->lookup("Na1+")); + TS_ASSERT_DELTA(74.0, msftb->lookup("W"), 0.04); + TS_ASSERT_DELTA(88.0, msftb->lookup("Ra"), 0.04); + TS_ASSERT_EQUALS(msftb->lookup("Si"), msftb->lookup("Si0+")); + TS_ASSERT_EQUALS("xray", msftb->clone()->type()); + } + + void test_SFTElectron() { + using diffpy::mathutils::DOUBLE_MAX; + msftb = ScatteringFactorTable::createByType("E"); + TS_ASSERT_EQUALS(DOUBLE_MAX, msftb->lookup("H")); + TS_ASSERT_EQUALS(DOUBLE_MAX, msftb->lookup("Ra")); + TS_ASSERT_DELTA(3.42104, msftb->lookup("Na", 1), 1e-5); + TS_ASSERT_DELTA(1.34868, msftb->lookup("Na", 3), 1e-5); + TS_ASSERT_DELTA(0.832158, msftb->lookup("Na", 5), 1e-5); + TS_ASSERT_THROWS(msftb->lookup("H4+"), invalid_argument); + TS_ASSERT_THROWS(msftb->lookup("H4+", 3), invalid_argument); + TS_ASSERT_EQUALS("electron", msftb->clone()->type()); + } + + void test_SFTNeutron() { + msftb = ScatteringFactorTable::createByType("N"); + TS_ASSERT_DELTA(3.63, msftb->lookup("Na"), mtol); + TS_ASSERT_DELTA(-3.37, msftb->lookup("Ti"), mtol); + TS_ASSERT_DELTA(5.805, msftb->lookup("O"), mtol); + TS_ASSERT_DELTA(6.6484, msftb->lookup("C"), mtol); + TS_ASSERT_EQUALS(msftb->lookup("Na"), msftb->lookup("Na1+")); + TS_ASSERT_EQUALS(msftb->lookup("Ge"), msftb->lookup("Ge0+")); + TS_ASSERT_EQUALS("neutron", msftb->clone()->type()); + } + + void test_ElectronNumber() { + msftb = ScatteringFactorTable::createByType("electronnumber"); + TS_ASSERT_EQUALS(8.0, msftb->lookup("O")); + TS_ASSERT_EQUALS(10.0, msftb->lookup("O2-")); + TS_ASSERT_EQUALS(18.0, msftb->lookup("K+")); + TS_ASSERT_EQUALS(18.0, msftb->lookup("K1+")); + TS_ASSERT_EQUALS(68.0, msftb->lookup("W6+")); + TS_ASSERT_THROWS(msftb->lookup("H4+"), invalid_argument); + TS_ASSERT_THROWS(msftb->lookup("O3+"), invalid_argument); + TS_ASSERT_EQUALS("electronnumber", msftb->clone()->type()); + } + + void test_serialization() { + ScatteringFactorTablePtr sftb1; + msftb = ScatteringFactorTable::createByType("electronnumber"); + msftb->setCustomAs("H", "H", 1.23); + sftb1 = dumpandload(msftb); + TS_ASSERT_EQUALS(string("electronnumber"), sftb1->type()); + TS_ASSERT_EQUALS(1.23, sftb1->lookup("H")); + TS_ASSERT_EQUALS(1u, sftb1->getCustomSymbols().size()); + sftb1 = dumpandload(ScatteringFactorTable::createByType("N")); + TS_ASSERT_EQUALS(string("neutron"), sftb1->type()); + sftb1 = dumpandload(ScatteringFactorTable::createByType("X")); + TS_ASSERT_EQUALS(string("xray"), sftb1->type()); + sftb1 = dumpandload(ScatteringFactorTable::createByType("E")); + TS_ASSERT_EQUALS(string("electron"), sftb1->type()); + } }; // End of file diff --git a/src/tests/TestSphericalShapeEnvelope.hpp b/src/tests/TestSphericalShapeEnvelope.hpp index 2bf667c8..2b6fde07 100644 --- a/src/tests/TestSphericalShapeEnvelope.hpp +++ b/src/tests/TestSphericalShapeEnvelope.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class TestSphericalShapeEnvelope -- unit tests for SphericalShapeEnvelope -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class TestSphericalShapeEnvelope -- unit tests for SphericalShapeEnvelope + * + *****************************************************************************/ #include @@ -24,66 +24,48 @@ using namespace std; using namespace diffpy::srreal; -class TestSphericalShapeEnvelope : public CxxTest::TestSuite -{ - private: - - PDFEnvelopePtr menvelope; - - public: - - void setUp() - { - menvelope = PDFEnvelope::createByType("sphericalshape"); - } - - - void test_create() - { - TS_ASSERT_EQUALS(0.0, menvelope->getDoubleAttr("spdiameter")); - menvelope->setDoubleAttr("spdiameter", 13.0); - TS_ASSERT_EQUALS(13.0, menvelope->getDoubleAttr("spdiameter")); - PDFEnvelopePtr e1 = menvelope->create(); - TS_ASSERT_EQUALS(0.0, e1->getDoubleAttr("spdiameter")); - } - - - void test_copy() - { - menvelope->setDoubleAttr("spdiameter", 13.0); - TS_ASSERT_EQUALS(13.0, menvelope->getDoubleAttr("spdiameter")); - PDFEnvelopePtr e1 = menvelope->clone(); - TS_ASSERT_EQUALS(13.0, e1->getDoubleAttr("spdiameter")); - } - - - void test_type() - { - TS_ASSERT_EQUALS("sphericalshape", menvelope->type()); - } - - - void test_parentheses_operator() - { - const PDFEnvelope& fne = *menvelope; - TS_ASSERT_EQUALS(1.0, fne(0.0)); - TS_ASSERT_EQUALS(1.0, fne(100.0)); - menvelope->setDoubleAttr("spdiameter", 10.0); - TS_ASSERT_EQUALS(1.0, fne(0.0)); - TS_ASSERT_EQUALS(0.0, fne(10.0)); - TS_ASSERT_EQUALS(0.0, fne(100)); - TS_ASSERT(fne(9.99) > 0.0); - TS_ASSERT_DELTA(0.3125, fne(5), 1e-8); - } - - - void test_serialization() - { - menvelope->setDoubleAttr("spdiameter", 13.1); - PDFEnvelopePtr e1 = dumpandload(menvelope); - TS_ASSERT_EQUALS(string("sphericalshape"), e1->type()); - TS_ASSERT_EQUALS(13.1, e1->getDoubleAttr("spdiameter")); - } +class TestSphericalShapeEnvelope : public CxxTest::TestSuite { + private: + PDFEnvelopePtr menvelope; + + public: + void setUp() { menvelope = PDFEnvelope::createByType("sphericalshape"); } + + void test_create() { + TS_ASSERT_EQUALS(0.0, menvelope->getDoubleAttr("spdiameter")); + menvelope->setDoubleAttr("spdiameter", 13.0); + TS_ASSERT_EQUALS(13.0, menvelope->getDoubleAttr("spdiameter")); + PDFEnvelopePtr e1 = menvelope->create(); + TS_ASSERT_EQUALS(0.0, e1->getDoubleAttr("spdiameter")); + } + + void test_copy() { + menvelope->setDoubleAttr("spdiameter", 13.0); + TS_ASSERT_EQUALS(13.0, menvelope->getDoubleAttr("spdiameter")); + PDFEnvelopePtr e1 = menvelope->clone(); + TS_ASSERT_EQUALS(13.0, e1->getDoubleAttr("spdiameter")); + } + + void test_type() { TS_ASSERT_EQUALS("sphericalshape", menvelope->type()); } + + void test_parentheses_operator() { + const PDFEnvelope& fne = *menvelope; + TS_ASSERT_EQUALS(1.0, fne(0.0)); + TS_ASSERT_EQUALS(1.0, fne(100.0)); + menvelope->setDoubleAttr("spdiameter", 10.0); + TS_ASSERT_EQUALS(1.0, fne(0.0)); + TS_ASSERT_EQUALS(0.0, fne(10.0)); + TS_ASSERT_EQUALS(0.0, fne(100)); + TS_ASSERT(fne(9.99) > 0.0); + TS_ASSERT_DELTA(0.3125, fne(5), 1e-8); + } + + void test_serialization() { + menvelope->setDoubleAttr("spdiameter", 13.1); + PDFEnvelopePtr e1 = dumpandload(menvelope); + TS_ASSERT_EQUALS(string("sphericalshape"), e1->type()); + TS_ASSERT_EQUALS(13.1, e1->getDoubleAttr("spdiameter")); + } }; // class TestSphericalShapeEnvelope diff --git a/src/tests/TestStepCutEnvelope.hpp b/src/tests/TestStepCutEnvelope.hpp index ffb49a0f..1abbc86e 100644 --- a/src/tests/TestStepCutEnvelope.hpp +++ b/src/tests/TestStepCutEnvelope.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* class TestStepCutEnvelope -- unit tests for StepCutEnvelope class -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * class TestStepCutEnvelope -- unit tests for StepCutEnvelope class + * + *****************************************************************************/ #include @@ -24,67 +24,49 @@ using namespace std; using namespace diffpy::srreal; -class TestStepCutEnvelope : public CxxTest::TestSuite -{ - private: - - PDFEnvelopePtr menvelope; - - public: - - void setUp() - { - menvelope = PDFEnvelope::createByType("stepcut"); - } - - - void test_create() - { - TS_ASSERT_EQUALS(0.0, menvelope->getDoubleAttr("stepcut")); - menvelope->setDoubleAttr("stepcut", 13.0); - TS_ASSERT_EQUALS(13.0, menvelope->getDoubleAttr("stepcut")); - PDFEnvelopePtr e1(menvelope->create()); - TS_ASSERT_EQUALS(0.0, e1->getDoubleAttr("stepcut")); - } - - - void test_copy() - { - menvelope->setDoubleAttr("stepcut", 13.0); - TS_ASSERT_EQUALS(13.0, menvelope->getDoubleAttr("stepcut")); - PDFEnvelopePtr e1(menvelope->clone()); - TS_ASSERT_EQUALS(13.0, e1->getDoubleAttr("stepcut")); - } - - - void test_type() - { - TS_ASSERT_EQUALS("stepcut", menvelope->type()); - } - - - void test_parentheses_operator() - { - const PDFEnvelope& fne = *menvelope; - TS_ASSERT_EQUALS(1.0, fne(-1.0)); - TS_ASSERT_EQUALS(1.0, fne(0.0)); - TS_ASSERT_EQUALS(1.0, fne(+1.0)); - menvelope->setDoubleAttr("stepcut", 1.0); - TS_ASSERT_EQUALS(1.0, fne(-1.0)); - TS_ASSERT_EQUALS(1.0, fne(0.0)); - TS_ASSERT_EQUALS(1.0, fne(+1.0)); - TS_ASSERT_EQUALS(0.0, fne(+1.0001)); - TS_ASSERT_EQUALS(0.0, fne(+2.0)); - } - - - void test_serialization() - { - menvelope->setDoubleAttr("stepcut", 13.1); - PDFEnvelopePtr e1 = dumpandload(menvelope); - TS_ASSERT_EQUALS(string("stepcut"), e1->type()); - TS_ASSERT_EQUALS(13.1, e1->getDoubleAttr("stepcut")); - } +class TestStepCutEnvelope : public CxxTest::TestSuite { + private: + PDFEnvelopePtr menvelope; + + public: + void setUp() { menvelope = PDFEnvelope::createByType("stepcut"); } + + void test_create() { + TS_ASSERT_EQUALS(0.0, menvelope->getDoubleAttr("stepcut")); + menvelope->setDoubleAttr("stepcut", 13.0); + TS_ASSERT_EQUALS(13.0, menvelope->getDoubleAttr("stepcut")); + PDFEnvelopePtr e1(menvelope->create()); + TS_ASSERT_EQUALS(0.0, e1->getDoubleAttr("stepcut")); + } + + void test_copy() { + menvelope->setDoubleAttr("stepcut", 13.0); + TS_ASSERT_EQUALS(13.0, menvelope->getDoubleAttr("stepcut")); + PDFEnvelopePtr e1(menvelope->clone()); + TS_ASSERT_EQUALS(13.0, e1->getDoubleAttr("stepcut")); + } + + void test_type() { TS_ASSERT_EQUALS("stepcut", menvelope->type()); } + + void test_parentheses_operator() { + const PDFEnvelope& fne = *menvelope; + TS_ASSERT_EQUALS(1.0, fne(-1.0)); + TS_ASSERT_EQUALS(1.0, fne(0.0)); + TS_ASSERT_EQUALS(1.0, fne(+1.0)); + menvelope->setDoubleAttr("stepcut", 1.0); + TS_ASSERT_EQUALS(1.0, fne(-1.0)); + TS_ASSERT_EQUALS(1.0, fne(0.0)); + TS_ASSERT_EQUALS(1.0, fne(+1.0)); + TS_ASSERT_EQUALS(0.0, fne(+1.0001)); + TS_ASSERT_EQUALS(0.0, fne(+2.0)); + } + + void test_serialization() { + menvelope->setDoubleAttr("stepcut", 13.1); + PDFEnvelopePtr e1 = dumpandload(menvelope); + TS_ASSERT_EQUALS(string("stepcut"), e1->type()); + TS_ASSERT_EQUALS(13.1, e1->getDoubleAttr("stepcut")); + } }; // class TestStepCutEnvelope diff --git a/src/tests/objcryst_helpers.cpp b/src/tests/objcryst_helpers.cpp index 76a61df1..a43da6f0 100644 --- a/src/tests/objcryst_helpers.cpp +++ b/src/tests/objcryst_helpers.cpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy 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. -* -****************************************************************************** -* -* shared helpers for loading diffpy structure objects. -* -*****************************************************************************/ + * + * libdiffpy 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. + * + ****************************************************************************** + * + * shared helpers for loading diffpy structure objects. + * + *****************************************************************************/ #include #include @@ -29,22 +29,20 @@ using namespace std; namespace { -void NoMessages(const string&) { } +void NoMessages(const string&) {} -} // namespace +} // namespace - -ObjCryst::Crystal* loadTestCrystal(const string& tailname) -{ - string fp = prepend_testdata_dir(tailname); - ifstream in(fp.c_str()); - // suppress the chatty output from CreateCrystalFromCIF - void (*OCMessages)(const string&) = ObjCryst::fpObjCrystInformUser; - ObjCryst::fpObjCrystInformUser = NoMessages; - ObjCryst::CIF cif(in); - ObjCryst::Crystal* crst = ObjCryst::CreateCrystalFromCIF(cif, false); - ObjCryst::fpObjCrystInformUser = OCMessages; - return crst; +ObjCryst::Crystal* loadTestCrystal(const string& tailname) { + string fp = prepend_testdata_dir(tailname); + ifstream in(fp.c_str()); + // suppress the chatty output from CreateCrystalFromCIF + void (*OCMessages)(const string&) = ObjCryst::fpObjCrystInformUser; + ObjCryst::fpObjCrystInformUser = NoMessages; + ObjCryst::CIF cif(in); + ObjCryst::Crystal* crst = ObjCryst::CreateCrystalFromCIF(cif, false); + ObjCryst::fpObjCrystInformUser = OCMessages; + return crst; } // End of file diff --git a/src/tests/objcryst_helpers.hpp b/src/tests/objcryst_helpers.hpp index 55d0e35e..437598a3 100644 --- a/src/tests/objcryst_helpers.hpp +++ b/src/tests/objcryst_helpers.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy 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. -* -****************************************************************************** -* -* shared helpers for loading diffpy structure objects. -* -*****************************************************************************/ + * + * libdiffpy 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. + * + ****************************************************************************** + * + * shared helpers for loading diffpy structure objects. + * + *****************************************************************************/ #ifndef OBJCRYST_HELPERS_HPP_INCLUDED #define OBJCRYST_HELPERS_HPP_INCLUDED diff --git a/src/tests/serialization_helpers.hpp b/src/tests/serialization_helpers.hpp index 4e689474..6ae112df 100644 --- a/src/tests/serialization_helpers.hpp +++ b/src/tests/serialization_helpers.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy 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. -* -****************************************************************************** -* -* helper template function for testing of serialization. -* -*****************************************************************************/ + * + * libdiffpy 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. + * + ****************************************************************************** + * + * helper template function for testing of serialization. + * + *****************************************************************************/ #ifndef SERIALIZATION_HELPERS_HPP_INCLUDED #define SERIALIZATION_HELPERS_HPP_INCLUDED @@ -22,17 +22,14 @@ #include #include - /// Return a duplicate object by saving and loading from a string template -T dumpandload(const T& src) -{ - using namespace diffpy; - std::string data = serialization_tostring(src); - T rv; - serialization_fromstring(rv, data); - return rv; +T dumpandload(const T& src) { + using namespace diffpy; + std::string data = serialization_tostring(src); + T rv; + serialization_fromstring(rv, data); + return rv; } - #endif // SERIALIZATION_HELPERS_HPP_INCLUDED diff --git a/src/tests/test_custompqconfig.hpp b/src/tests/test_custompqconfig.hpp index 04b75465..8dac6524 100644 --- a/src/tests/test_custompqconfig.hpp +++ b/src/tests/test_custompqconfig.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy Complex Modeling Initiative -* (c) 2014 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. -* -****************************************************************************** -* -* Helper class for testing the effect of customPQConfig. -* -*****************************************************************************/ + * + * libdiffpy Complex Modeling Initiative + * (c) 2014 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. + * + ****************************************************************************** + * + * Helper class for testing the effect of customPQConfig. + * + *****************************************************************************/ #ifndef TEST_CUSTOMPQCONFIG_HPP_INCLUDED #define TEST_CUSTOMPQCONFIG_HPP_INCLUDED @@ -22,48 +22,39 @@ #include #include -using diffpy::srreal::StructureAdapterPtr; using diffpy::srreal::PeriodicStructureAdapter; using diffpy::srreal::PeriodicStructureAdapterPtr; +using diffpy::srreal::StructureAdapterPtr; // --------------------------------------------------------------------------- -class PeriodicAdapterWithPQConfig : - public PeriodicStructureAdapter -{ - public: - - // constructors - PeriodicAdapterWithPQConfig() { } - PeriodicAdapterWithPQConfig(const PeriodicStructureAdapter& src) - : PeriodicStructureAdapter(src) - { } - - // overloads - void customPQConfig(diffpy::srreal::PairQuantity* pq) const - { - std::map::const_iterator it; - for (it = cfg.begin(); it != cfg.end(); ++it) - { - pq->setDoubleAttr(it->first, it->second); - } - } - - // data - std::map cfg; - - private: - - // serialization - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - using boost::serialization::base_object; - ar & base_object(*this); - ar & cfg; - } - +class PeriodicAdapterWithPQConfig : public PeriodicStructureAdapter { + public: + // constructors + PeriodicAdapterWithPQConfig() {} + PeriodicAdapterWithPQConfig(const PeriodicStructureAdapter& src) + : PeriodicStructureAdapter(src) {} + + // overloads + void customPQConfig(diffpy::srreal::PairQuantity* pq) const { + std::map::const_iterator it; + for (it = cfg.begin(); it != cfg.end(); ++it) { + pq->setDoubleAttr(it->first, it->second); + } + } + + // data + std::map cfg; + + private: + // serialization + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) { + using boost::serialization::base_object; + ar& base_object(*this); + ar & cfg; + } }; BOOST_CLASS_EXPORT(PeriodicAdapterWithPQConfig) @@ -71,16 +62,14 @@ BOOST_CLASS_EXPORT(PeriodicAdapterWithPQConfig) // Typedefs and Functions ---------------------------------------------------- typedef boost::shared_ptr - PeriodicAdapterWithPQConfigPtr; - -inline -PeriodicAdapterWithPQConfigPtr -addCustomPQConfig(StructureAdapterPtr stru) -{ - PeriodicStructureAdapterPtr pstru = - boost::dynamic_pointer_cast(stru); - return PeriodicAdapterWithPQConfigPtr( - new PeriodicAdapterWithPQConfig(*pstru)); + PeriodicAdapterWithPQConfigPtr; + +inline PeriodicAdapterWithPQConfigPtr addCustomPQConfig( + StructureAdapterPtr stru) { + PeriodicStructureAdapterPtr pstru = + boost::dynamic_pointer_cast(stru); + return PeriodicAdapterWithPQConfigPtr( + new PeriodicAdapterWithPQConfig(*pstru)); } #endif // TEST_CUSTOMPQCONFIG_HPP_INCLUDED diff --git a/src/tests/test_helpers.cpp b/src/tests/test_helpers.cpp index d8f5bdf9..3f6821f9 100644 --- a/src/tests/test_helpers.cpp +++ b/src/tests/test_helpers.cpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* Definitions of helper functions for other unit tests. -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * Definitions of helper functions for other unit tests. + * + *****************************************************************************/ #include #include @@ -38,104 +38,89 @@ // Path utilities ------------------------------------------------------------ -std::string prepend_tests_dir(const std::string& f) -{ - std::string rv = STRINGIFY(DIFFPYTESTSDIRPATH); - rv = rv + '/' + f; - return rv; +std::string prepend_tests_dir(const std::string& f) { + std::string rv = STRINGIFY(DIFFPYTESTSDIRPATH); + rv = rv + '/' + f; + return rv; } - -std::string prepend_testdata_dir(const std::string& f) -{ - using std::string; - string ft = "testdata/"; - ft += f; - string rv = prepend_tests_dir(ft); - return rv; +std::string prepend_testdata_dir(const std::string& f) { + using std::string; + string ft = "testdata/"; + ft += f; + string rv = prepend_tests_dir(ft); + return rv; } // Load PeriodicStructureAdapter from a PdfFit formatted file. -diffpy::srreal::StructureAdapterPtr - loadTestPeriodicStructure(const std::string& tailname) -{ - using namespace std; - using namespace diffpy::srreal; - using diffpy::runtimepath::LineReader; - using diffpy::mathutils::eps_eq; - // instantiate PeriodicStructureAdapter - StructureAdapterPtr pstru(new PeriodicStructureAdapter); - PeriodicStructureAdapter& stru = - static_cast(*pstru); - // open data file - string fullpath = prepend_testdata_dir(tailname); - ifstream fp(fullpath.c_str()); - LineReader line; - string fileformat; - // process structure file header - while (fp >> line) - { - if (line.wcount() >= 2 && boost::iequals(line.words[0], "format")) - { - fileformat = line.words[1]; - assert(boost::iequals(fileformat, "pdffit")); - } - if (line.wcount() == 7 && line.words[0] == "cell") - { - boost::replace_all(line.line, ",", " "); - string skip; - double a, b, c, alpha, beta, gamma; - istringstream fpwords(line.line); - fpwords >> skip >> a >> b >> c >> alpha >> beta >> gamma; - stru.setLatPar(a, b, c, alpha, beta, gamma); - } if (line.wcount() == 1 && line.words[0] == "atoms") break; +diffpy::srreal::StructureAdapterPtr loadTestPeriodicStructure( + const std::string& tailname) { + using namespace std; + using namespace diffpy::srreal; + using diffpy::mathutils::eps_eq; + using diffpy::runtimepath::LineReader; + // instantiate PeriodicStructureAdapter + StructureAdapterPtr pstru(new PeriodicStructureAdapter); + PeriodicStructureAdapter& stru = + static_cast(*pstru); + // open data file + string fullpath = prepend_testdata_dir(tailname); + ifstream fp(fullpath.c_str()); + LineReader line; + string fileformat; + // process structure file header + while (fp >> line) { + if (line.wcount() >= 2 && boost::iequals(line.words[0], "format")) { + fileformat = line.words[1]; + assert(boost::iequals(fileformat, "pdffit")); + } + if (line.wcount() == 7 && line.words[0] == "cell") { + boost::replace_all(line.line, ",", " "); + string skip; + double a, b, c, alpha, beta, gamma; + istringstream fpwords(line.line); + fpwords >> skip >> a >> b >> c >> alpha >> beta >> gamma; + stru.setLatPar(a, b, c, alpha, beta, gamma); + } + if (line.wcount() == 1 && line.words[0] == "atoms") break; + } + assert(!fileformat.empty()); + // load atoms + while (true) { + Atom ai; + double ignore; + R3::Vector& xyz = ai.xyz_cartn; + R3::Matrix& Uc = ai.uij_cartn; + fp >> ai.atomtype >> xyz[0] >> xyz[1] >> xyz[2] >> ai.occupancy >> ignore >> + ignore >> ignore >> ignore >> Uc(0, 0) >> Uc(1, 1) >> Uc(2, 2) >> + ignore >> ignore >> ignore >> Uc(0, 1) >> Uc(0, 2) >> Uc(1, 2) >> + ignore >> ignore >> ignore; + Uc(1, 0) = Uc(0, 1); + Uc(2, 0) = Uc(0, 2); + Uc(2, 1) = Uc(1, 2); + if (!fp) break; + // convert string symbol to standard case + boost::to_lower(ai.atomtype); + string::iterator tt = ai.atomtype.begin(); + for (; tt != ai.atomtype.end(); ++tt) { + if (isalpha(*tt)) { + *tt = toupper(*tt); + break; + } } - assert(!fileformat.empty()); - // load atoms - while (true) - { - Atom ai; - double ignore; - R3::Vector& xyz = ai.xyz_cartn; - R3::Matrix& Uc = ai.uij_cartn; - fp >> - ai.atomtype >> xyz[0] >> xyz[1] >> xyz[2] >> ai.occupancy >> - ignore >> ignore >> ignore >> ignore >> - Uc(0, 0) >> Uc(1, 1) >> Uc(2, 2) >> - ignore >> ignore >> ignore >> - Uc(0, 1) >> Uc(0, 2) >> Uc(1, 2) >> - ignore >> ignore >> ignore; - Uc(1, 0) = Uc(0, 1); - Uc(2, 0) = Uc(0, 2); - Uc(2, 1) = Uc(1, 2); - if (!fp) break; - // convert string symbol to standard case - boost::to_lower(ai.atomtype); - string::iterator tt = ai.atomtype.begin(); - for (; tt != ai.atomtype.end(); ++tt) - { - if (isalpha(*tt)) - { - *tt = toupper(*tt); - break; - } - } - // convert coordinates and the ADP matrix and determine anisotropy - stru.toCartesian(ai); + // convert coordinates and the ADP matrix and determine anisotropy + stru.toCartesian(ai); + ai.anisotropy = !eps_eq(Uc(0, 0), Uc(1, 1)) || !eps_eq(Uc(0, 0), Uc(2, 2)); + for (int i = 0; !ai.anisotropy && i < R3::Ndim; ++i) { + for (int j = i + 1; j < R3::Ndim; ++j) { ai.anisotropy = - !eps_eq(Uc(0, 0), Uc(1, 1)) || !eps_eq(Uc(0, 0), Uc(2, 2)); - for (int i = 0; !ai.anisotropy && i < R3::Ndim; ++i) - { - for (int j = i + 1; j < R3::Ndim; ++j) - { - ai.anisotropy = ai.anisotropy || - !eps_eq(0.0, Uc(i, j)) || !eps_eq(0.0, Uc(j, i)); - } - } - stru.append(ai); + ai.anisotropy || !eps_eq(0.0, Uc(i, j)) || !eps_eq(0.0, Uc(j, i)); + } } - return pstru; + stru.append(ai); + } + return pstru; } // End of test_helpers.cpp diff --git a/src/tests/test_helpers.hpp b/src/tests/test_helpers.hpp index f1fd3c23..2c75fe23 100644 --- a/src/tests/test_helpers.hpp +++ b/src/tests/test_helpers.hpp @@ -1,20 +1,20 @@ /***************************************************************************** -* -* libdiffpy by DANSE Diffraction group -* Simon J. L. Billinge -* (c) 2009 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. -* -****************************************************************************** -* -* Helper functions used in other unit tests. -* -*****************************************************************************/ + * + * libdiffpy by DANSE Diffraction group + * Simon J. L. Billinge + * (c) 2009 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. + * + ****************************************************************************** + * + * Helper functions used in other unit tests. + * + *****************************************************************************/ #ifndef TEST_HELPERS_HPP_INCLUDED #define TEST_HELPERS_HPP_INCLUDED @@ -25,7 +25,7 @@ std::string prepend_tests_dir(const std::string& f); std::string prepend_testdata_dir(const std::string& f); -diffpy::srreal::StructureAdapterPtr - loadTestPeriodicStructure(const std::string& tailname); +diffpy::srreal::StructureAdapterPtr loadTestPeriodicStructure( + const std::string& tailname); #endif // TEST_HELPERS_HPP_INCLUDED