From 8f80d5f5fd4d2fdba529507a6ad253bbe6a944a6 Mon Sep 17 00:00:00 2001 From: Andrew Sazonov Date: Fri, 26 Jul 2024 15:16:02 +0200 Subject: [PATCH] pycrysfml v0.1.1 (#17) * Switch to GitHub M1 and minor changes (#8) (#9) * Switch to GitHub M1 and minor changes (#8) * Switch from FlyCI M2 to GH M1 * Force numpy to be < 2 * Get the package version from pyproject.toml, not from scripts.toml * Increase performance test median from 10% to 25% * Try autodetecting python lib and site packages * Fix python lib path for Windows * Move ifport_lib definition from scripts.py to scripts.toml * Clean up * Update README.md * Minor changes * Update README.md * Auto push benchmark results by GitHub Action for macOS + gfortran * Auto push benchmark results by GitHub Action for macOS + gfortran * Auto push benchmark results by GitHub Action for Windows + gfortran * Auto push benchmark results by GitHub Action for Linux + ifort * Auto push benchmark results by GitHub Action for Linux + gfortran * Auto push benchmark results by GitHub Action for Windows + ifort * Auto push benchmark results by GitHub Action for Linux + ifx * pycrysfml v0.1.0 (#16) * Try new implementation of pycfml * Add CFML_Utilities module * Add building pycfml so * Some debugging * Add missing CFML_Wraps_Utils * Clean up * Trigger new backend * Add missing Wraps_Atoms * Add 'Download PYCFML repository' step * Temporarily keep only ubuntu-22.04 + ifort * More dedug * Update unit tests to follow new api syntax * Add py api files to pycfml dist * Restructure CI script * Switch to the new structure of CrysFML2008 * debug pycfml unit tests * Add change_runpath_for_built_pycfml * debug * Debug pycfml import * More debug * More debug * Try windows CI * Temporarily disable parallel builds * Try link *.obj * New template for building pycfml shared object * Add 'Math_In_Limits' to the CrysFML build * add macos and clean up * Temporarily disable macos CI * Clean up * Add missing CFML modules * Disable some problematic modules * Refactor build scripts * rename package from pyproject08 to pyproject * add change_runpath_for_built_pycfml * Refactoring * Rename pycrysfml08 to pycrysfml in tests * Add build CFML test programs * Add run CFML test programs * Fix CFML functional tests * debug * Capitalize test dirs * Clean up * Follow update in CrysFML2008 * Update PythonAPI folder name * Try uv to install python deps * Remove uv * Colorize terminal output * Update scripts.py * fix colors * Debug color * Add flag to enable backslash escapes * Add all platforms * Try on ubuntu only * Fix build pycfml lib cmd * Try ubuntu only * Change build pycfml cmd back * Enable all platforms * Add Wraps_Utilities.f90 * emporary disable due to error when building pycfml shared object * Try calculating diffraction pattern * Fix macos rpath change script * Add more debug * Update pycfml import debug * Try macos 12 + ifort build combination * Modify __init__.py * Suppress the error message when copying files * Enable macos-12 + ifort * Fix suppress the error message command * Add pycrysfml unit tests * Allow parallel builds * Fix python wheel name on macos * Add examples, issues, extend tests * Fix python package name on macos * Fix powder pattern from json tests * Update examples and issues * Licensing (#11) * Updating Licence to comply with ILL rules * Updating Licence Classifier * Updating Licence Classifier * Revert name to Pycrysfml08 --------- Co-authored-by: Elisa Rebolini * Update project description * Upload python wheel to GH releases * Add new step to publish python wheels * Fix required python version to be >= 3.9 * Add CI build on pull_request * Switch from tomllib to toml to support python <3.11 * Add missing toml lib * Remove python 3.9 from build matrix * Minor fixes * Do not suppress error messages * Update rpath delete template to follow gcc bump from 13.2.0 to 13.3.0 * Clean up * Fix rpaths * Update readme * Add more platforms for the python package build * Update readme * Move __init__.py to src/ * Rename scripts to build * Rename build.py/.toml into pybuild.py/.toml * Remove ipynb checkpoints from saving to GIT * Add how to use section to readme * No need to convert np type array in pycrysfml * Try using pkg-config --libs python3-embed on macos --------- Co-authored-by: Elisa Rebolini * try auto path * Try copying Python * Debug * try adding custom rpaths * Try setting DYLD_FALLBACK_LIBRARY_PATH * More debug * Change path to Python in __init__.py * Add back all build matrices + build in release mode * Clean up build script * Add pyCFML benchmark tests * Auto push pyCFML benchmark results by GitHub Action for Linux + gfortran * Auto push pyCFML benchmark results by GitHub Action for macOS + gfortran * Auto push pyCFML benchmark results by GitHub Action for Linux + ifx * Auto push pyCFML benchmark results by GitHub Action for Linux + ifort * Auto push pyCFML benchmark results by GitHub Action for macOS + gfortran * Auto push pyCFML benchmark results by GitHub Action for Windows + ifort * Auto push pyCFML benchmark results by GitHub Action for Windows + gfortran * Split main CI build script into debug and release * Always run job 'test' in release build * Fix benchmarking * Auto push pyCFML benchmark results by GitHub Action for macOS + gfortran * Auto push pyCFML benchmark results by GitHub Action for Windows + gfortran * Auto push pyCFML benchmark results by GitHub Action for macOS + gfortran * Remove some debug code * Add libmvec.so.1 to gfortran release build * Auto push pyCFML benchmark results by GitHub Action for macos-14 + gfortran * Auto push pyCFML benchmark results by GitHub Action for ubuntu-24.04 + gfortran * Auto push pyCFML benchmark results by GitHub Action for macos-12 + gfortran * Auto push pyCFML benchmark results by GitHub Action for windows-2022 + gfortran * Add example * Fix benchmarks * Auto push pyCFML benchmark results by GitHub Action for ubuntu-24.04 + gfortran * Auto push pyCFML benchmark results by GitHub Action for ubuntu-24.04 + gfortran * Auto push pyCFML benchmark results by GitHub Action for ubuntu-24.04 + gfortran * Auto push pyCFML benchmark results by GitHub Action for macos-12 + gfortran * Auto push pyCFML benchmark results by GitHub Action for windows-2022 + gfortran * Auto push pyCFML benchmark results by GitHub Action for macos-12 + gfortran * Auto push pyCFML benchmark results by GitHub Action for windows-2022 + gfortran * Auto push pyCFML benchmark results by GitHub Action for windows-2022 + gfortran * Auto push pyCFML benchmark results by GitHub Action for macos-14 + gfortran * Auto push pyCFML benchmark results by GitHub Action for macos-14 + gfortran * Auto push pyCFML benchmark results by GitHub Action for macos-12 + gfortran * Update pybuild.toml * Increase benchmark fail to > 50% * Regenerate benchmark results [save benchmark results] * Try to build and run CFML test programs on all platforms * Fix build script * Update readme [save benchmark results] * Fix run_pycfml_functional_tests_with_benchmarks_save.sh [save benchmark results] * Auto push pyCFML benchmarks : release-build-and-test : ubuntu-24.04 : gfortran * Auto push pyCFML benchmarks : release-build-and-test : ubuntu-24.04 : gfortran * Auto push pyCFML benchmarks : release-build-and-test : macos-14 : gfortran * Auto push pyCFML benchmarks : release-build-and-test : ubuntu-24.04 : gfortran * Auto push pyCFML benchmarks : release-build-and-test : macos-14 : gfortran * Auto push pyCFML benchmarks : release-build-and-test : macos-12 : gfortran * Auto push pyCFML benchmarks : release-build-and-test : windows-2022 : gfortran * Auto push pyCFML benchmarks : release-build-and-test : windows-2022 : gfortran * Auto push pyCFML benchmarks : release-build-and-test : macos-12 : gfortran * Auto push pyCFML benchmarks : release-build-and-test : macos-14 : gfortran * Auto push pyCFML benchmarks : release-build-and-test : windows-2022 : gfortran * Auto push pyCFML benchmarks : release-build-and-test : macos-12 : gfortran * Prepare for release 0.1.1 --------- Co-authored-by: Elisa Rebolini --- ...15b099d367c6498146221_20240423_100042.json | 205 -- ...9d995840c186ee18b16f8_20240423_102536.json | 205 -- ...fba3555ed7382b4554eef_20240423_102545.json | 205 -- ...94b33d6952117b5ae4ecb_20240423_103228.json | 205 -- ...3ef3fc80f580cef85088a_20240423_104436.json | 205 -- ...b2de4195dbfc5fd3068c8_20240423_114357.json | 205 -- ...15b099d367c6498146221_20240423_100001.json | 113 - ...2554619af175779f60ea5_20240423_101041.json | 113 - ...9d995840c186ee18b16f8_20240423_102457.json | 113 - ...fba3555ed7382b4554eef_20240423_102513.json | 113 - ...94b33d6952117b5ae4ecb_20240423_103157.json | 113 - ...3ef3fc80f580cef85088a_20240423_104410.json | 113 - ...b2de4195dbfc5fd3068c8_20240423_114319.json | 113 - ...15b099d367c6498146221_20240423_100107.json | 220 -- ...2554619af175779f60ea5_20240423_101121.json | 220 -- ...9d995840c186ee18b16f8_20240423_102546.json | 220 -- ...fba3555ed7382b4554eef_20240423_102602.json | 202 -- ...15b099d367c6498146221_20240423_095950.json | 240 -- ...2554619af175779f60ea5_20240423_101034.json | 240 -- ...9d995840c186ee18b16f8_20240423_102449.json | 240 -- ...fba3555ed7382b4554eef_20240423_102457.json | 240 -- ...94b33d6952117b5ae4ecb_20240423_103137.json | 240 -- ...3ef3fc80f580cef85088a_20240423_104359.json | 240 -- ...b2de4195dbfc5fd3068c8_20240423_114307.json | 240 -- ...15b099d367c6498146221_20240423_100421.json | 205 -- ...2554619af175779f60ea5_20240423_101451.json | 205 -- ...fba3555ed7382b4554eef_20240423_103506.json | 205 -- ...94b33d6952117b5ae4ecb_20240423_103552.json | 205 -- ...b2de4195dbfc5fd3068c8_20240423_114727.json | 205 -- ...15b099d367c6498146221_20240423_100326.json | 240 -- ...2554619af175779f60ea5_20240423_101411.json | 240 -- ...fba3555ed7382b4554eef_20240423_102839.json | 240 -- ...94b33d6952117b5ae4ecb_20240423_103518.json | 240 -- ...3ef3fc80f580cef85088a_20240423_104734.json | 240 -- ...b2de4195dbfc5fd3068c8_20240423_114640.json | 240 -- ...15b099d367c6498146221_20240423_100332.json | 240 -- ...9d995840c186ee18b16f8_20240423_102756.json | 240 -- ...fba3555ed7382b4554eef_20240423_102831.json | 240 -- ...94b33d6952117b5ae4ecb_20240423_103507.json | 240 -- ...3ef3fc80f580cef85088a_20240423_104708.json | 240 -- ...ef7f554d092f5c20d299_20240726_130208.json} | 96 +- ...ef7f554d092f5c20d299_20240726_130211.json} | 82 +- ...ef7f554d092f5c20d299_20240726_130235.json} | 96 +- ...9ef7f554d092f5c20d299_20240726_130228.json | 113 + ...9ef7f554d092f5c20d299_20240726_130153.json | 113 + ...9ef7f554d092f5c20d299_20240726_130141.json | 113 + ...ef7f554d092f5c20d299_20240726_130156.json} | 92 +- ...ef7f554d092f5c20d299_20240726_130428.json} | 82 +- ...ef7f554d092f5c20d299_20240726_130216.json} | 96 +- ...ef7f554d092f5c20d299_20240726_130139.json} | 108 +- ...ef7f554d092f5c20d299_20240726_130145.json} | 100 +- ...ef7f554d092f5c20d299_20240726_130140.json} | 104 +- ...54_20240726_115911_uncommited-changes.json | 113 + .github/workflows/{main.yml => debug.yml} | 200 +- .github/workflows/release.yml | 300 ++ .gitignore | 17 +- COPYING | 674 ++++ COPYING.lesser | 165 + LICENSE | 41 +- README.md | 251 +- RELEASE.md | 3 + .../srtio3-pm3m-pattern_Nebil-ifort.xy | 0 .../srtio3-pnma-pattern_Andrew-ifort.y | 0 .../srtio3-pattern-simulation.ipynb | 801 +++++ .../srtio3-pattern-simulation.py | 77 + .../first-calc_vs_second-calc.png | Bin 0 -> 38908 bytes .../first-calc_vs_second-calc/script.py | 155 + .../y-pm3m_first-calc.txt | 2781 +++++++++++++++++ .../y-pm3m_second-calc.txt | 2781 +++++++++++++++++ pybuild.py | 1532 +++++++++ pybuild.toml | 1053 +++++++ pyproject.toml | 45 +- scripts.py | 1127 ------- scripts.toml | 950 ------ scripts/empty.txt | 0 src/__init__.py | 37 + .../{cfml => CFML}/D19_instrm.geom | 0 .../{cfml => CFML}/LiFePO4n.cfl | 0 .../{cfml => CFML}/LiFePO4n_sum_desired.bvs | 0 .../{cfml => CFML}/SrTiO3s.cfl | 0 .../{cfml => CFML}/SrTiO3s_desired.dat | 0 .../{cfml/test_d19.cfl => CFML/d19.cfl} | 0 .../d19_desired.hkl} | 0 .../{cfml => CFML}/if_ponsin_desired.dat | 0 .../{cfml => CFML}/mfe_msfac.cfl | 0 .../{cfml => CFML}/mfe_sfac.cfl | 0 .../{cfml => CFML}/molecule_PPH3_Z.cfl | 0 .../molecule_PPH3_Z_fc_desired.cfl | 0 .../{cfml => CFML}/ponsin.cfl | 0 .../{cfml => CFML}/test__Bond_Str.py | 40 +- .../{cfml => CFML}/test__Molecules.py | 41 +- .../{cfml => CFML}/test__PowderPattern.py | 53 +- .../{cfml => CFML}/test__StructureFactors.py | 56 +- .../{cfml => CFML}/test__hkl_gen.py | 52 +- .../srtio3-pm3m-pattern_Nebil-ifort.xy | 2781 +++++++++++++++++ .../srtio3-pnma-pattern_Andrew-ifort.y | 2781 +++++++++++++++++ .../test__powder_pattern_from_json.py | 132 + .../pycfml/test__powder_mod.py | 185 -- .../pycfml/test__powder_mod_2.py | 187 -- .../pyCFML/_old/_test__cfml_metrics__debug.py | 66 + .../_old/_test__py_cfml_metrics.py} | 18 +- .../_old/_test__py_cfml_profiles.py} | 0 .../_old/_test__py_cfml_sxtal_geom.py} | 0 .../unit_tests/pyCFML/import/test__import.py | 40 + 104 files changed, 17590 insertions(+), 11368 deletions(-) delete mode 100644 .benchmarks/github/gfortran/AMD64/Windows-CPython-3.11-64bit/0001_85b81446abfdc74949b15b099d367c6498146221_20240423_100042.json delete mode 100644 .benchmarks/github/gfortran/AMD64/Windows-CPython-3.11-64bit/0003_53c48b1cb9568e544b39d995840c186ee18b16f8_20240423_102536.json delete mode 100644 .benchmarks/github/gfortran/AMD64/Windows-CPython-3.11-64bit/0003_904f83215f95337ba21fba3555ed7382b4554eef_20240423_102545.json delete mode 100644 .benchmarks/github/gfortran/AMD64/Windows-CPython-3.11-64bit/0004_a35d0b5acf769d4a68794b33d6952117b5ae4ecb_20240423_103228.json delete mode 100644 .benchmarks/github/gfortran/AMD64/Windows-CPython-3.11-64bit/0005_774a8273e467cce7cc73ef3fc80f580cef85088a_20240423_104436.json delete mode 100644 .benchmarks/github/gfortran/AMD64/Windows-CPython-3.11-64bit/0006_2e27ea3e143b990c623b2de4195dbfc5fd3068c8_20240423_114357.json delete mode 100644 .benchmarks/github/gfortran/arm/Darwin-CPython-3.11-64bit/0001_85b81446abfdc74949b15b099d367c6498146221_20240423_100001.json delete mode 100644 .benchmarks/github/gfortran/arm/Darwin-CPython-3.11-64bit/0002_f2feb7460687645f07e2554619af175779f60ea5_20240423_101041.json delete mode 100644 .benchmarks/github/gfortran/arm/Darwin-CPython-3.11-64bit/0003_53c48b1cb9568e544b39d995840c186ee18b16f8_20240423_102457.json delete mode 100644 .benchmarks/github/gfortran/arm/Darwin-CPython-3.11-64bit/0003_904f83215f95337ba21fba3555ed7382b4554eef_20240423_102513.json delete mode 100644 .benchmarks/github/gfortran/arm/Darwin-CPython-3.11-64bit/0004_a35d0b5acf769d4a68794b33d6952117b5ae4ecb_20240423_103157.json delete mode 100644 .benchmarks/github/gfortran/arm/Darwin-CPython-3.11-64bit/0005_774a8273e467cce7cc73ef3fc80f580cef85088a_20240423_104410.json delete mode 100644 .benchmarks/github/gfortran/arm/Darwin-CPython-3.11-64bit/0006_2e27ea3e143b990c623b2de4195dbfc5fd3068c8_20240423_114319.json delete mode 100644 .benchmarks/github/gfortran/i386/Darwin-CPython-3.11-64bit/0001_85b81446abfdc74949b15b099d367c6498146221_20240423_100107.json delete mode 100644 .benchmarks/github/gfortran/i386/Darwin-CPython-3.11-64bit/0002_f2feb7460687645f07e2554619af175779f60ea5_20240423_101121.json delete mode 100644 .benchmarks/github/gfortran/i386/Darwin-CPython-3.11-64bit/0003_53c48b1cb9568e544b39d995840c186ee18b16f8_20240423_102546.json delete mode 100644 .benchmarks/github/gfortran/i386/Darwin-CPython-3.11-64bit/0003_904f83215f95337ba21fba3555ed7382b4554eef_20240423_102602.json delete mode 100644 .benchmarks/github/gfortran/x86_64/Linux-CPython-3.11-64bit/0001_85b81446abfdc74949b15b099d367c6498146221_20240423_095950.json delete mode 100644 .benchmarks/github/gfortran/x86_64/Linux-CPython-3.11-64bit/0002_f2feb7460687645f07e2554619af175779f60ea5_20240423_101034.json delete mode 100644 .benchmarks/github/gfortran/x86_64/Linux-CPython-3.11-64bit/0003_53c48b1cb9568e544b39d995840c186ee18b16f8_20240423_102449.json delete mode 100644 .benchmarks/github/gfortran/x86_64/Linux-CPython-3.11-64bit/0003_904f83215f95337ba21fba3555ed7382b4554eef_20240423_102457.json delete mode 100644 .benchmarks/github/gfortran/x86_64/Linux-CPython-3.11-64bit/0004_a35d0b5acf769d4a68794b33d6952117b5ae4ecb_20240423_103137.json delete mode 100644 .benchmarks/github/gfortran/x86_64/Linux-CPython-3.11-64bit/0005_774a8273e467cce7cc73ef3fc80f580cef85088a_20240423_104359.json delete mode 100644 .benchmarks/github/gfortran/x86_64/Linux-CPython-3.11-64bit/0006_2e27ea3e143b990c623b2de4195dbfc5fd3068c8_20240423_114307.json delete mode 100644 .benchmarks/github/ifort/AMD64/Windows-CPython-3.11-64bit/0001_85b81446abfdc74949b15b099d367c6498146221_20240423_100421.json delete mode 100644 .benchmarks/github/ifort/AMD64/Windows-CPython-3.11-64bit/0002_f2feb7460687645f07e2554619af175779f60ea5_20240423_101451.json delete mode 100644 .benchmarks/github/ifort/AMD64/Windows-CPython-3.11-64bit/0003_904f83215f95337ba21fba3555ed7382b4554eef_20240423_103506.json delete mode 100644 .benchmarks/github/ifort/AMD64/Windows-CPython-3.11-64bit/0004_a35d0b5acf769d4a68794b33d6952117b5ae4ecb_20240423_103552.json delete mode 100644 .benchmarks/github/ifort/AMD64/Windows-CPython-3.11-64bit/0006_2e27ea3e143b990c623b2de4195dbfc5fd3068c8_20240423_114727.json delete mode 100644 .benchmarks/github/ifort/x86_64/Linux-CPython-3.11-64bit/0001_85b81446abfdc74949b15b099d367c6498146221_20240423_100326.json delete mode 100644 .benchmarks/github/ifort/x86_64/Linux-CPython-3.11-64bit/0002_f2feb7460687645f07e2554619af175779f60ea5_20240423_101411.json delete mode 100644 .benchmarks/github/ifort/x86_64/Linux-CPython-3.11-64bit/0003_904f83215f95337ba21fba3555ed7382b4554eef_20240423_102839.json delete mode 100644 .benchmarks/github/ifort/x86_64/Linux-CPython-3.11-64bit/0004_a35d0b5acf769d4a68794b33d6952117b5ae4ecb_20240423_103518.json delete mode 100644 .benchmarks/github/ifort/x86_64/Linux-CPython-3.11-64bit/0005_774a8273e467cce7cc73ef3fc80f580cef85088a_20240423_104734.json delete mode 100644 .benchmarks/github/ifort/x86_64/Linux-CPython-3.11-64bit/0006_2e27ea3e143b990c623b2de4195dbfc5fd3068c8_20240423_114640.json delete mode 100644 .benchmarks/github/ifx/x86_64/Linux-CPython-3.11-64bit/0001_85b81446abfdc74949b15b099d367c6498146221_20240423_100332.json delete mode 100644 .benchmarks/github/ifx/x86_64/Linux-CPython-3.11-64bit/0003_53c48b1cb9568e544b39d995840c186ee18b16f8_20240423_102756.json delete mode 100644 .benchmarks/github/ifx/x86_64/Linux-CPython-3.11-64bit/0003_904f83215f95337ba21fba3555ed7382b4554eef_20240423_102831.json delete mode 100644 .benchmarks/github/ifx/x86_64/Linux-CPython-3.11-64bit/0004_a35d0b5acf769d4a68794b33d6952117b5ae4ecb_20240423_103507.json delete mode 100644 .benchmarks/github/ifx/x86_64/Linux-CPython-3.11-64bit/0005_774a8273e467cce7cc73ef3fc80f580cef85088a_20240423_104708.json rename .benchmarks/{github/gfortran/AMD64/Windows-CPython-3.11-64bit/0002_f2feb7460687645f07e2554619af175779f60ea5_20240423_101101.json => pyCFML/github/gfortran/AMD64/Windows-CPython-3.10-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130208.json} (63%) rename .benchmarks/{github/ifort/AMD64/Windows-CPython-3.11-64bit/0005_774a8273e467cce7cc73ef3fc80f580cef85088a_20240423_104832.json => pyCFML/github/gfortran/AMD64/Windows-CPython-3.11-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130211.json} (67%) rename .benchmarks/{github/ifort/AMD64/Windows-CPython-3.11-64bit/0003_53c48b1cb9568e544b39d995840c186ee18b16f8_20240423_102906.json => pyCFML/github/gfortran/AMD64/Windows-CPython-3.12-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130235.json} (63%) create mode 100644 .benchmarks/pyCFML/github/gfortran/arm/Darwin-CPython-3.10-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130228.json create mode 100644 .benchmarks/pyCFML/github/gfortran/arm/Darwin-CPython-3.11-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130153.json create mode 100644 .benchmarks/pyCFML/github/gfortran/arm/Darwin-CPython-3.12-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130141.json rename .benchmarks/{github/gfortran/i386/Darwin-CPython-3.11-64bit/0005_774a8273e467cce7cc73ef3fc80f580cef85088a_20240423_104424.json => pyCFML/github/gfortran/i386/Darwin-CPython-3.10-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130156.json} (66%) rename .benchmarks/{github/gfortran/i386/Darwin-CPython-3.11-64bit/0006_2e27ea3e143b990c623b2de4195dbfc5fd3068c8_20240423_114335.json => pyCFML/github/gfortran/i386/Darwin-CPython-3.11-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130428.json} (69%) rename .benchmarks/{github/gfortran/i386/Darwin-CPython-3.11-64bit/0004_a35d0b5acf769d4a68794b33d6952117b5ae4ecb_20240423_103216.json => pyCFML/github/gfortran/i386/Darwin-CPython-3.12-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130216.json} (65%) rename .benchmarks/{github/ifort/x86_64/Linux-CPython-3.11-64bit/0003_53c48b1cb9568e544b39d995840c186ee18b16f8_20240423_102820.json => pyCFML/github/gfortran/x86_64/Linux-CPython-3.10-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130139.json} (65%) rename .benchmarks/{github/ifx/x86_64/Linux-CPython-3.11-64bit/0002_f2feb7460687645f07e2554619af175779f60ea5_20240423_101404.json => pyCFML/github/gfortran/x86_64/Linux-CPython-3.11-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130145.json} (67%) rename .benchmarks/{github/ifx/x86_64/Linux-CPython-3.11-64bit/0006_2e27ea3e143b990c623b2de4195dbfc5fd3068c8_20240423_114617.json => pyCFML/github/gfortran/x86_64/Linux-CPython-3.12-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130140.json} (66%) create mode 100644 .benchmarks/pyCFML/local/gfortran/arm/Darwin-CPython-3.11-64bit/0001_4c5918320a07e1bd72494d2c13d16afc1ea8c654_20240726_115911_uncommited-changes.json rename .github/workflows/{main.yml => debug.yml} (54%) create mode 100644 .github/workflows/release.yml create mode 100644 COPYING create mode 100644 COPYING.lesser create mode 100644 RELEASE.md rename {tests/functional_tests/pycfml => examples/pyCFML/cfml_utilities/powder_pattern_from_json/desired}/srtio3-pm3m-pattern_Nebil-ifort.xy (100%) rename tests/functional_tests/pycfml/srtio3-pmmm-pattern_Andrew-ifort.xy => examples/pyCFML/cfml_utilities/powder_pattern_from_json/desired/srtio3-pnma-pattern_Andrew-ifort.y (100%) create mode 100644 examples/pyCFML/cfml_utilities/powder_pattern_from_json/srtio3-pattern-simulation.ipynb create mode 100644 examples/pyCFML/cfml_utilities/powder_pattern_from_json/srtio3-pattern-simulation.py create mode 100644 issues/pyCFML/cfml_utilities/powder_pattern_from_json/first-calc_vs_second-calc/first-calc_vs_second-calc.png create mode 100644 issues/pyCFML/cfml_utilities/powder_pattern_from_json/first-calc_vs_second-calc/script.py create mode 100644 issues/pyCFML/cfml_utilities/powder_pattern_from_json/first-calc_vs_second-calc/y-pm3m_first-calc.txt create mode 100644 issues/pyCFML/cfml_utilities/powder_pattern_from_json/first-calc_vs_second-calc/y-pm3m_second-calc.txt create mode 100644 pybuild.py create mode 100644 pybuild.toml delete mode 100644 scripts.py delete mode 100644 scripts.toml delete mode 100644 scripts/empty.txt create mode 100644 src/__init__.py rename tests/functional_tests/{cfml => CFML}/D19_instrm.geom (100%) rename tests/functional_tests/{cfml => CFML}/LiFePO4n.cfl (100%) rename tests/functional_tests/{cfml => CFML}/LiFePO4n_sum_desired.bvs (100%) rename tests/functional_tests/{cfml => CFML}/SrTiO3s.cfl (100%) rename tests/functional_tests/{cfml => CFML}/SrTiO3s_desired.dat (100%) rename tests/functional_tests/{cfml/test_d19.cfl => CFML/d19.cfl} (100%) rename tests/functional_tests/{cfml/test_d19_desired.hkl => CFML/d19_desired.hkl} (100%) rename tests/functional_tests/{cfml => CFML}/if_ponsin_desired.dat (100%) rename tests/functional_tests/{cfml => CFML}/mfe_msfac.cfl (100%) rename tests/functional_tests/{cfml => CFML}/mfe_sfac.cfl (100%) rename tests/functional_tests/{cfml => CFML}/molecule_PPH3_Z.cfl (100%) rename tests/functional_tests/{cfml => CFML}/molecule_PPH3_Z_fc_desired.cfl (100%) rename tests/functional_tests/{cfml => CFML}/ponsin.cfl (100%) rename tests/functional_tests/{cfml => CFML}/test__Bond_Str.py (74%) rename tests/functional_tests/{cfml => CFML}/test__Molecules.py (70%) rename tests/functional_tests/{cfml => CFML}/test__PowderPattern.py (64%) rename tests/functional_tests/{cfml => CFML}/test__StructureFactors.py (57%) rename tests/functional_tests/{cfml => CFML}/test__hkl_gen.py (54%) create mode 100644 tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/desired/srtio3-pm3m-pattern_Nebil-ifort.xy create mode 100644 tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/desired/srtio3-pnma-pattern_Andrew-ifort.y create mode 100644 tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/test__powder_pattern_from_json.py delete mode 100644 tests/functional_tests/pycfml/test__powder_mod.py delete mode 100644 tests/functional_tests/pycfml/test__powder_mod_2.py create mode 100644 tests/unit_tests/pyCFML/_old/_test__cfml_metrics__debug.py rename tests/unit_tests/{pycfml/test__py_cfml_metrics.py => pyCFML/_old/_test__py_cfml_metrics.py} (92%) rename tests/unit_tests/{pycfml/test__py_cfml_profiles.py => pyCFML/_old/_test__py_cfml_profiles.py} (100%) rename tests/unit_tests/{pycfml/test__py_cfml_sxtal_geom.py => pyCFML/_old/_test__py_cfml_sxtal_geom.py} (100%) create mode 100644 tests/unit_tests/pyCFML/import/test__import.py diff --git a/.benchmarks/github/gfortran/AMD64/Windows-CPython-3.11-64bit/0001_85b81446abfdc74949b15b099d367c6498146221_20240423_100042.json b/.benchmarks/github/gfortran/AMD64/Windows-CPython-3.11-64bit/0001_85b81446abfdc74949b15b099d367c6498146221_20240423_100042.json deleted file mode 100644 index 1282996..0000000 --- a/.benchmarks/github/gfortran/AMD64/Windows-CPython-3.11-64bit/0001_85b81446abfdc74949b15b099d367c6498146221_20240423_100042.json +++ /dev/null @@ -1,205 +0,0 @@ -{ - "machine_info": { - "node": "fv-az836-701", - "processor": "AMD64 Family 25 Model 1 Stepping 1, AuthenticAMD", - "machine": "AMD64", - "python_compiler": "MSC v.1938 64 bit (AMD64)", - "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", - "python_build": [ - "tags/v3.11.9:de54cf5", - "Apr 2 2024 10:12:12" - ], - "release": "10", - "system": "Windows", - "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "X86_64", - "bits": 64, - "count": 4, - "arch_string_raw": "AMD64", - "vendor_id_raw": "AuthenticAMD", - "brand_raw": "AMD EPYC 7763 64-Core Processor", - "hz_actual_friendly": "2.4450 GHz", - "hz_actual": [ - 2445000000, - 0 - ], - "stepping": 1, - "model": 1, - "family": 25, - "hz_advertised_friendly": "2.4450 GHz", - "hz_advertised": [ - 2445000000, - 0 - ], - "flags": [ - "3dnow", - "3dnowext", - "3dnowprefetch", - "abm", - "adx", - "aes", - "apic", - "avx", - "avx2", - "bmi1", - "bmi2", - "clflush", - "clflushopt", - "clwb", - "cmov", - "cmp_legacy", - "cr8_legacy", - "cx16", - "cx8", - "de", - "dts", - "erms", - "f16c", - "fma", - "fpu", - "fxsr", - "ht", - "hypervisor", - "ia64", - "invpcid", - "lahf_lm", - "mca", - "mce", - "misalignsse", - "mmx", - "movbe", - "msr", - "mtrr", - "osvw", - "osxsave", - "pae", - "pat", - "pcid", - "pclmulqdq", - "pge", - "pni", - "popcnt", - "pse", - "pse36", - "rdpid", - "rdrnd", - "rdseed", - "sep", - "sepamd", - "serial", - "sha", - "smap", - "smep", - "ss", - "sse", - "sse2", - "sse4_1", - "sse4_2", - "sse4a", - "ssse3", - "tm", - "topoext", - "tsc", - "umip", - "vaes", - "vme", - "vpclmulqdq", - "xsave" - ], - "l2_cache_size": 65536, - "l2_cache_line_size": 512, - "l2_cache_associativity": 6 - } - }, - "commit_info": { - "id": "85b81446abfdc74949b15b099d367c6498146221", - "time": "2024-04-23T11:58:35+02:00", - "author_time": "2024-04-23T11:58:35+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__mol_tpcr__molecule_PPH3_Z", - "fullname": "tests/functional_tests/cfml/test__Molecules.py::test__mol_tpcr__molecule_PPH3_Z", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 0.018099300000017138, - "max": 0.030228500000021086, - "mean": 0.02368633571428802, - "stddev": 0.0050426921382178014, - "rounds": 56, - "median": 0.02067655000001878, - "iqr": 0.009954450000009274, - "q1": 0.018757250000021486, - "q3": 0.02871170000003076, - "iqr_outliers": 0, - "stddev_outliers": 24, - "outliers": "24;0", - "ld15iqr": 0.018099300000017138, - "hd15iqr": 0.030228500000021086, - "ops": 42.21843395543795, - "total": 1.3264348000001291, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.972841399999993, - "max": 2.9772115000000667, - "mean": 2.975317999999993, - "stddev": 0.0018389290565519226, - "rounds": 5, - "median": 2.9755801999999676, - "iqr": 0.003129299999983459, - "q1": 2.9738007999999923, - "q3": 2.9769300999999757, - "iqr_outliers": 0, - "stddev_outliers": 2, - "outliers": "2;0", - "ld15iqr": 2.972841399999993, - "hd15iqr": 2.9772115000000667, - "ops": 0.3360985279556681, - "total": 14.876589999999965, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T10:01:28.672295", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/gfortran/AMD64/Windows-CPython-3.11-64bit/0003_53c48b1cb9568e544b39d995840c186ee18b16f8_20240423_102536.json b/.benchmarks/github/gfortran/AMD64/Windows-CPython-3.11-64bit/0003_53c48b1cb9568e544b39d995840c186ee18b16f8_20240423_102536.json deleted file mode 100644 index a13901c..0000000 --- a/.benchmarks/github/gfortran/AMD64/Windows-CPython-3.11-64bit/0003_53c48b1cb9568e544b39d995840c186ee18b16f8_20240423_102536.json +++ /dev/null @@ -1,205 +0,0 @@ -{ - "machine_info": { - "node": "fv-az1564-336", - "processor": "AMD64 Family 25 Model 1 Stepping 1, AuthenticAMD", - "machine": "AMD64", - "python_compiler": "MSC v.1938 64 bit (AMD64)", - "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", - "python_build": [ - "tags/v3.11.9:de54cf5", - "Apr 2 2024 10:12:12" - ], - "release": "10", - "system": "Windows", - "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "X86_64", - "bits": 64, - "count": 4, - "arch_string_raw": "AMD64", - "vendor_id_raw": "AuthenticAMD", - "brand_raw": "AMD EPYC 7763 64-Core Processor", - "hz_actual_friendly": "2.4450 GHz", - "hz_actual": [ - 2445000000, - 0 - ], - "stepping": 1, - "model": 1, - "family": 25, - "hz_advertised_friendly": "2.4450 GHz", - "hz_advertised": [ - 2445000000, - 0 - ], - "flags": [ - "3dnow", - "3dnowext", - "3dnowprefetch", - "abm", - "adx", - "aes", - "apic", - "avx", - "avx2", - "bmi1", - "bmi2", - "clflush", - "clflushopt", - "clwb", - "cmov", - "cmp_legacy", - "cr8_legacy", - "cx16", - "cx8", - "de", - "dts", - "erms", - "f16c", - "fma", - "fpu", - "fxsr", - "ht", - "hypervisor", - "ia64", - "invpcid", - "lahf_lm", - "mca", - "mce", - "misalignsse", - "mmx", - "movbe", - "msr", - "mtrr", - "osvw", - "osxsave", - "pae", - "pat", - "pcid", - "pclmulqdq", - "pge", - "pni", - "popcnt", - "pse", - "pse36", - "rdpid", - "rdrnd", - "rdseed", - "sep", - "sepamd", - "serial", - "sha", - "smap", - "smep", - "ss", - "sse", - "sse2", - "sse4_1", - "sse4_2", - "sse4a", - "ssse3", - "tm", - "topoext", - "tsc", - "umip", - "vaes", - "vme", - "vpclmulqdq", - "xsave" - ], - "l2_cache_size": 65536, - "l2_cache_line_size": 512, - "l2_cache_associativity": 6 - } - }, - "commit_info": { - "id": "53c48b1cb9568e544b39d995840c186ee18b16f8", - "time": "2024-04-23T12:23:31+02:00", - "author_time": "2024-04-23T12:23:31+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__mol_tpcr__molecule_PPH3_Z", - "fullname": "tests/functional_tests/cfml/test__Molecules.py::test__mol_tpcr__molecule_PPH3_Z", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 0.018355199999973593, - "max": 0.0327802999998994, - "mean": 0.024554205555558737, - "stddev": 0.005158707790703776, - "rounds": 54, - "median": 0.02841349999994236, - "iqr": 0.010168300000032104, - "q1": 0.01874750000001768, - "q3": 0.028915800000049785, - "iqr_outliers": 0, - "stddev_outliers": 24, - "outliers": "24;0", - "ld15iqr": 0.018355199999973593, - "hd15iqr": 0.0327802999998994, - "ops": 40.72622092119016, - "total": 1.3259271000001718, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.9628618000000415, - "max": 2.980336599999987, - "mean": 2.9724193199999718, - "stddev": 0.007367184478928145, - "rounds": 5, - "median": 2.970892899999967, - "iqr": 0.012286674999955949, - "q1": 2.9672584499999743, - "q3": 2.9795451249999303, - "iqr_outliers": 0, - "stddev_outliers": 2, - "outliers": "2;0", - "ld15iqr": 2.9628618000000415, - "hd15iqr": 2.980336599999987, - "ops": 0.33642628860318724, - "total": 14.862096599999859, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T10:26:22.018999", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/gfortran/AMD64/Windows-CPython-3.11-64bit/0003_904f83215f95337ba21fba3555ed7382b4554eef_20240423_102545.json b/.benchmarks/github/gfortran/AMD64/Windows-CPython-3.11-64bit/0003_904f83215f95337ba21fba3555ed7382b4554eef_20240423_102545.json deleted file mode 100644 index ef4e0f9..0000000 --- a/.benchmarks/github/gfortran/AMD64/Windows-CPython-3.11-64bit/0003_904f83215f95337ba21fba3555ed7382b4554eef_20240423_102545.json +++ /dev/null @@ -1,205 +0,0 @@ -{ - "machine_info": { - "node": "fv-az742-134", - "processor": "AMD64 Family 25 Model 1 Stepping 1, AuthenticAMD", - "machine": "AMD64", - "python_compiler": "MSC v.1938 64 bit (AMD64)", - "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", - "python_build": [ - "tags/v3.11.9:de54cf5", - "Apr 2 2024 10:12:12" - ], - "release": "10", - "system": "Windows", - "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "X86_64", - "bits": 64, - "count": 4, - "arch_string_raw": "AMD64", - "vendor_id_raw": "AuthenticAMD", - "brand_raw": "AMD EPYC 7763 64-Core Processor", - "hz_actual_friendly": "2.4450 GHz", - "hz_actual": [ - 2445000000, - 0 - ], - "stepping": 1, - "model": 1, - "family": 25, - "hz_advertised_friendly": "2.4450 GHz", - "hz_advertised": [ - 2445000000, - 0 - ], - "flags": [ - "3dnow", - "3dnowext", - "3dnowprefetch", - "abm", - "adx", - "aes", - "apic", - "avx", - "avx2", - "bmi1", - "bmi2", - "clflush", - "clflushopt", - "clwb", - "cmov", - "cmp_legacy", - "cr8_legacy", - "cx16", - "cx8", - "de", - "dts", - "erms", - "f16c", - "fma", - "fpu", - "fxsr", - "ht", - "hypervisor", - "ia64", - "invpcid", - "lahf_lm", - "mca", - "mce", - "misalignsse", - "mmx", - "movbe", - "msr", - "mtrr", - "osvw", - "osxsave", - "pae", - "pat", - "pcid", - "pclmulqdq", - "pge", - "pni", - "popcnt", - "pse", - "pse36", - "rdpid", - "rdrnd", - "rdseed", - "sep", - "sepamd", - "serial", - "sha", - "smap", - "smep", - "ss", - "sse", - "sse2", - "sse4_1", - "sse4_2", - "sse4a", - "ssse3", - "tm", - "topoext", - "tsc", - "umip", - "vaes", - "vme", - "vpclmulqdq", - "xsave" - ], - "l2_cache_size": 65536, - "l2_cache_line_size": 512, - "l2_cache_associativity": 6 - } - }, - "commit_info": { - "id": "904f83215f95337ba21fba3555ed7382b4554eef", - "time": "2024-04-23T12:23:40+02:00", - "author_time": "2024-04-23T12:23:40+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__mol_tpcr__molecule_PPH3_Z", - "fullname": "tests/functional_tests/cfml/test__Molecules.py::test__mol_tpcr__molecule_PPH3_Z", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 0.01790619999997034, - "max": 0.03223639999998795, - "mean": 0.02379233214285697, - "stddev": 0.005156197956277, - "rounds": 56, - "median": 0.027773099999990336, - "iqr": 0.010132249999969645, - "q1": 0.018067300000041087, - "q3": 0.02819955000001073, - "iqr_outliers": 0, - "stddev_outliers": 26, - "outliers": "26;0", - "ld15iqr": 0.01790619999997034, - "hd15iqr": 0.03223639999998795, - "ops": 42.03034801278294, - "total": 1.3323705999999902, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.9720263000000386, - "max": 2.982663699999989, - "mean": 2.975751439999999, - "stddev": 0.004671818651012417, - "rounds": 5, - "median": 2.9734116999999287, - "iqr": 0.0073806749999789645, - "q1": 2.9721417250000286, - "q3": 2.9795224000000076, - "iqr_outliers": 0, - "stddev_outliers": 1, - "outliers": "1;0", - "ld15iqr": 2.9720263000000386, - "hd15iqr": 2.982663699999989, - "ops": 0.3360495727425407, - "total": 14.878757199999995, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T10:26:31.371279", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/gfortran/AMD64/Windows-CPython-3.11-64bit/0004_a35d0b5acf769d4a68794b33d6952117b5ae4ecb_20240423_103228.json b/.benchmarks/github/gfortran/AMD64/Windows-CPython-3.11-64bit/0004_a35d0b5acf769d4a68794b33d6952117b5ae4ecb_20240423_103228.json deleted file mode 100644 index bf9299f..0000000 --- a/.benchmarks/github/gfortran/AMD64/Windows-CPython-3.11-64bit/0004_a35d0b5acf769d4a68794b33d6952117b5ae4ecb_20240423_103228.json +++ /dev/null @@ -1,205 +0,0 @@ -{ - "machine_info": { - "node": "fv-az1390-498", - "processor": "AMD64 Family 25 Model 1 Stepping 1, AuthenticAMD", - "machine": "AMD64", - "python_compiler": "MSC v.1938 64 bit (AMD64)", - "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", - "python_build": [ - "tags/v3.11.9:de54cf5", - "Apr 2 2024 10:12:12" - ], - "release": "10", - "system": "Windows", - "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "X86_64", - "bits": 64, - "count": 4, - "arch_string_raw": "AMD64", - "vendor_id_raw": "AuthenticAMD", - "brand_raw": "AMD EPYC 7763 64-Core Processor", - "hz_actual_friendly": "2.4450 GHz", - "hz_actual": [ - 2445000000, - 0 - ], - "stepping": 1, - "model": 1, - "family": 25, - "hz_advertised_friendly": "2.4450 GHz", - "hz_advertised": [ - 2445000000, - 0 - ], - "flags": [ - "3dnow", - "3dnowext", - "3dnowprefetch", - "abm", - "adx", - "aes", - "apic", - "avx", - "avx2", - "bmi1", - "bmi2", - "clflush", - "clflushopt", - "clwb", - "cmov", - "cmp_legacy", - "cr8_legacy", - "cx16", - "cx8", - "de", - "dts", - "erms", - "f16c", - "fma", - "fpu", - "fxsr", - "ht", - "hypervisor", - "ia64", - "invpcid", - "lahf_lm", - "mca", - "mce", - "misalignsse", - "mmx", - "movbe", - "msr", - "mtrr", - "osvw", - "osxsave", - "pae", - "pat", - "pcid", - "pclmulqdq", - "pge", - "pni", - "popcnt", - "pse", - "pse36", - "rdpid", - "rdrnd", - "rdseed", - "sep", - "sepamd", - "serial", - "sha", - "smap", - "smep", - "ss", - "sse", - "sse2", - "sse4_1", - "sse4_2", - "sse4a", - "ssse3", - "tm", - "topoext", - "tsc", - "umip", - "vaes", - "vme", - "vpclmulqdq", - "xsave" - ], - "l2_cache_size": 65536, - "l2_cache_line_size": 512, - "l2_cache_associativity": 6 - } - }, - "commit_info": { - "id": "a35d0b5acf769d4a68794b33d6952117b5ae4ecb", - "time": "2024-04-23T12:30:14+02:00", - "author_time": "2024-04-23T12:30:14+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__mol_tpcr__molecule_PPH3_Z", - "fullname": "tests/functional_tests/cfml/test__Molecules.py::test__mol_tpcr__molecule_PPH3_Z", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 0.01779810000005, - "max": 0.02936639999995805, - "mean": 0.023714101754391873, - "stddev": 0.0050667545040890055, - "rounds": 57, - "median": 0.027818200000069737, - "iqr": 0.009955375000004096, - "q1": 0.018084175000012692, - "q3": 0.02803955000001679, - "iqr_outliers": 0, - "stddev_outliers": 28, - "outliers": "28;0", - "ld15iqr": 0.01779810000005, - "hd15iqr": 0.02936639999995805, - "ops": 42.16900181828726, - "total": 1.3517038000003367, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.9669165999999905, - "max": 2.9739819000000125, - "mean": 2.9699076400000193, - "stddev": 0.002906508678464097, - "rounds": 5, - "median": 2.970157699999959, - "iqr": 0.004630875000003698, - "q1": 2.9672276250000493, - "q3": 2.971858500000053, - "iqr_outliers": 0, - "stddev_outliers": 2, - "outliers": "2;0", - "ld15iqr": 2.9669165999999905, - "hd15iqr": 2.9739819000000125, - "ops": 0.33671080761285677, - "total": 14.849538200000097, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T10:33:13.750326", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/gfortran/AMD64/Windows-CPython-3.11-64bit/0005_774a8273e467cce7cc73ef3fc80f580cef85088a_20240423_104436.json b/.benchmarks/github/gfortran/AMD64/Windows-CPython-3.11-64bit/0005_774a8273e467cce7cc73ef3fc80f580cef85088a_20240423_104436.json deleted file mode 100644 index e119d94..0000000 --- a/.benchmarks/github/gfortran/AMD64/Windows-CPython-3.11-64bit/0005_774a8273e467cce7cc73ef3fc80f580cef85088a_20240423_104436.json +++ /dev/null @@ -1,205 +0,0 @@ -{ - "machine_info": { - "node": "fv-az1105-600", - "processor": "AMD64 Family 25 Model 1 Stepping 1, AuthenticAMD", - "machine": "AMD64", - "python_compiler": "MSC v.1938 64 bit (AMD64)", - "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", - "python_build": [ - "tags/v3.11.9:de54cf5", - "Apr 2 2024 10:12:12" - ], - "release": "10", - "system": "Windows", - "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "X86_64", - "bits": 64, - "count": 4, - "arch_string_raw": "AMD64", - "vendor_id_raw": "AuthenticAMD", - "brand_raw": "AMD EPYC 7763 64-Core Processor", - "hz_actual_friendly": "2.4450 GHz", - "hz_actual": [ - 2445000000, - 0 - ], - "stepping": 1, - "model": 1, - "family": 25, - "hz_advertised_friendly": "2.4450 GHz", - "hz_advertised": [ - 2445000000, - 0 - ], - "flags": [ - "3dnow", - "3dnowext", - "3dnowprefetch", - "abm", - "adx", - "aes", - "apic", - "avx", - "avx2", - "bmi1", - "bmi2", - "clflush", - "clflushopt", - "clwb", - "cmov", - "cmp_legacy", - "cr8_legacy", - "cx16", - "cx8", - "de", - "dts", - "erms", - "f16c", - "fma", - "fpu", - "fxsr", - "ht", - "hypervisor", - "ia64", - "invpcid", - "lahf_lm", - "mca", - "mce", - "misalignsse", - "mmx", - "movbe", - "msr", - "mtrr", - "osvw", - "osxsave", - "pae", - "pat", - "pcid", - "pclmulqdq", - "pge", - "pni", - "popcnt", - "pse", - "pse36", - "rdpid", - "rdrnd", - "rdseed", - "sep", - "sepamd", - "serial", - "sha", - "smap", - "smep", - "ss", - "sse", - "sse2", - "sse4_1", - "sse4_2", - "sse4a", - "ssse3", - "tm", - "topoext", - "tsc", - "umip", - "vaes", - "vme", - "vpclmulqdq", - "xsave" - ], - "l2_cache_size": 65536, - "l2_cache_line_size": 512, - "l2_cache_associativity": 6 - } - }, - "commit_info": { - "id": "774a8273e467cce7cc73ef3fc80f580cef85088a", - "time": "2024-04-23T12:42:42+02:00", - "author_time": "2024-04-23T12:42:42+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.9546636000000035, - "max": 2.994392399999981, - "mean": 2.971963100000005, - "stddev": 0.01434547481785342, - "rounds": 5, - "median": 2.971164299999998, - "iqr": 0.013419099999964601, - "q1": 2.9642706500000315, - "q3": 2.977689749999996, - "iqr_outliers": 0, - "stddev_outliers": 2, - "outliers": "2;0", - "ld15iqr": 2.9546636000000035, - "hd15iqr": 2.994392399999981, - "ops": 0.33647793271726634, - "total": 14.859815500000025, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__ponsin", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__ponsin", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 5.158625299999983, - "max": 5.285331199999973, - "mean": 5.211546419999979, - "stddev": 0.06026298860628095, - "rounds": 5, - "median": 5.177203200000008, - "iqr": 0.10676167499998712, - "q1": 5.165828374999975, - "q3": 5.2725900499999625, - "iqr_outliers": 0, - "stddev_outliers": 1, - "outliers": "1;0", - "ld15iqr": 5.158625299999983, - "hd15iqr": 5.285331199999973, - "ops": 0.1918816257996612, - "total": 26.057732099999896, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T10:46:26.006826", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/gfortran/AMD64/Windows-CPython-3.11-64bit/0006_2e27ea3e143b990c623b2de4195dbfc5fd3068c8_20240423_114357.json b/.benchmarks/github/gfortran/AMD64/Windows-CPython-3.11-64bit/0006_2e27ea3e143b990c623b2de4195dbfc5fd3068c8_20240423_114357.json deleted file mode 100644 index 98c2280..0000000 --- a/.benchmarks/github/gfortran/AMD64/Windows-CPython-3.11-64bit/0006_2e27ea3e143b990c623b2de4195dbfc5fd3068c8_20240423_114357.json +++ /dev/null @@ -1,205 +0,0 @@ -{ - "machine_info": { - "node": "fv-az836-701", - "processor": "AMD64 Family 25 Model 1 Stepping 1, AuthenticAMD", - "machine": "AMD64", - "python_compiler": "MSC v.1938 64 bit (AMD64)", - "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", - "python_build": [ - "tags/v3.11.9:de54cf5", - "Apr 2 2024 10:12:12" - ], - "release": "10", - "system": "Windows", - "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "X86_64", - "bits": 64, - "count": 4, - "arch_string_raw": "AMD64", - "vendor_id_raw": "AuthenticAMD", - "brand_raw": "AMD EPYC 7763 64-Core Processor", - "hz_actual_friendly": "2.4450 GHz", - "hz_actual": [ - 2445000000, - 0 - ], - "stepping": 1, - "model": 1, - "family": 25, - "hz_advertised_friendly": "2.4450 GHz", - "hz_advertised": [ - 2445000000, - 0 - ], - "flags": [ - "3dnow", - "3dnowext", - "3dnowprefetch", - "abm", - "adx", - "aes", - "apic", - "avx", - "avx2", - "bmi1", - "bmi2", - "clflush", - "clflushopt", - "clwb", - "cmov", - "cmp_legacy", - "cr8_legacy", - "cx16", - "cx8", - "de", - "dts", - "erms", - "f16c", - "fma", - "fpu", - "fxsr", - "ht", - "hypervisor", - "ia64", - "invpcid", - "lahf_lm", - "mca", - "mce", - "misalignsse", - "mmx", - "movbe", - "msr", - "mtrr", - "osvw", - "osxsave", - "pae", - "pat", - "pcid", - "pclmulqdq", - "pge", - "pni", - "popcnt", - "pse", - "pse36", - "rdpid", - "rdrnd", - "rdseed", - "sep", - "sepamd", - "serial", - "sha", - "smap", - "smep", - "ss", - "sse", - "sse2", - "sse4_1", - "sse4_2", - "sse4a", - "ssse3", - "tm", - "topoext", - "tsc", - "umip", - "vaes", - "vme", - "vpclmulqdq", - "xsave" - ], - "l2_cache_size": 65536, - "l2_cache_line_size": 512, - "l2_cache_associativity": 6 - } - }, - "commit_info": { - "id": "2e27ea3e143b990c623b2de4195dbfc5fd3068c8", - "time": "2024-04-23T13:41:53+02:00", - "author_time": "2024-04-23T13:41:53+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.9669558000000507, - "max": 2.979225100000008, - "mean": 2.9734775999999785, - "stddev": 0.004705628783146228, - "rounds": 5, - "median": 2.974907299999927, - "iqr": 0.006544174999959296, - "q1": 2.9698629499999925, - "q3": 2.9764071249999517, - "iqr_outliers": 0, - "stddev_outliers": 2, - "outliers": "2;0", - "ld15iqr": 2.9669558000000507, - "hd15iqr": 2.979225100000008, - "ops": 0.3363065523009177, - "total": 14.867387999999892, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__ponsin", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__ponsin", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 5.133410499999968, - "max": 5.163078299999938, - "mean": 5.152457839999966, - "stddev": 0.011796882012966472, - "rounds": 5, - "median": 5.157530599999973, - "iqr": 0.014895349999989094, - "q1": 5.145214599999974, - "q3": 5.160109949999963, - "iqr_outliers": 0, - "stddev_outliers": 1, - "outliers": "1;0", - "ld15iqr": 5.133410499999968, - "hd15iqr": 5.163078299999938, - "ops": 0.19408213149008643, - "total": 25.762289199999827, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T11:45:46.227551", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/gfortran/arm/Darwin-CPython-3.11-64bit/0001_85b81446abfdc74949b15b099d367c6498146221_20240423_100001.json b/.benchmarks/github/gfortran/arm/Darwin-CPython-3.11-64bit/0001_85b81446abfdc74949b15b099d367c6498146221_20240423_100001.json deleted file mode 100644 index 6e54900..0000000 --- a/.benchmarks/github/gfortran/arm/Darwin-CPython-3.11-64bit/0001_85b81446abfdc74949b15b099d367c6498146221_20240423_100001.json +++ /dev/null @@ -1,113 +0,0 @@ -{ - "machine_info": { - "node": "Mac-1713866348367.local", - "processor": "arm", - "machine": "arm64", - "python_compiler": "Clang 13.0.0 (clang-1300.0.29.30)", - "python_implementation": "CPython", - "python_implementation_version": "3.11.8", - "python_version": "3.11.8", - "python_build": [ - "v3.11.8:db85d51d3e", - "Feb 6 2024 18:02:37" - ], - "release": "23.3.0", - "system": "Darwin", - "cpu": { - "python_version": "3.11.8.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "ARM_8", - "bits": 64, - "count": 4, - "arch_string_raw": "arm64", - "brand_raw": "Apple M2 (Virtual)" - } - }, - "commit_info": { - "id": "85b81446abfdc74949b15b099d367c6498146221", - "time": "2024-04-23T11:58:35+02:00", - "author_time": "2024-04-23T11:58:35+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__mol_tpcr__molecule_PPH3_Z", - "fullname": "tests/functional_tests/cfml/test__Molecules.py::test__mol_tpcr__molecule_PPH3_Z", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 0.003859000000005608, - "max": 0.015845500000011725, - "mean": 0.0042445416245211, - "stddev": 0.0009421238882586816, - "rounds": 261, - "median": 0.004028208000008249, - "iqr": 0.00027343799999357543, - "q1": 0.003947708000008987, - "q3": 0.0042211460000025625, - "iqr_outliers": 15, - "stddev_outliers": 13, - "outliers": "13;15", - "ld15iqr": 0.003859000000005608, - "hd15iqr": 0.00500725000000557, - "ops": 235.5967000589439, - "total": 1.107825364000007, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.311826707999998, - "max": 2.3389755409999964, - "mean": 2.321852149799997, - "stddev": 0.011325604469375737, - "rounds": 5, - "median": 2.317313416999994, - "iqr": 0.01715145749999536, - "q1": 2.313203958500001, - "q3": 2.330355415999996, - "iqr_outliers": 0, - "stddev_outliers": 1, - "outliers": "1;0", - "ld15iqr": 2.311826707999998, - "hd15iqr": 2.3389755409999964, - "ops": 0.4306906450034466, - "total": 11.609260748999986, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T10:00:35.784136", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/gfortran/arm/Darwin-CPython-3.11-64bit/0002_f2feb7460687645f07e2554619af175779f60ea5_20240423_101041.json b/.benchmarks/github/gfortran/arm/Darwin-CPython-3.11-64bit/0002_f2feb7460687645f07e2554619af175779f60ea5_20240423_101041.json deleted file mode 100644 index caa5c40..0000000 --- a/.benchmarks/github/gfortran/arm/Darwin-CPython-3.11-64bit/0002_f2feb7460687645f07e2554619af175779f60ea5_20240423_101041.json +++ /dev/null @@ -1,113 +0,0 @@ -{ - "machine_info": { - "node": "Mac-1713866990433.local", - "processor": "arm", - "machine": "arm64", - "python_compiler": "Clang 13.0.0 (clang-1300.0.29.30)", - "python_implementation": "CPython", - "python_implementation_version": "3.11.8", - "python_version": "3.11.8", - "python_build": [ - "v3.11.8:db85d51d3e", - "Feb 6 2024 18:02:37" - ], - "release": "23.3.0", - "system": "Darwin", - "cpu": { - "python_version": "3.11.8.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "ARM_8", - "bits": 64, - "count": 4, - "arch_string_raw": "arm64", - "brand_raw": "Apple M2 (Virtual)" - } - }, - "commit_info": { - "id": "f2feb7460687645f07e2554619af175779f60ea5", - "time": "2024-04-23T12:09:18+02:00", - "author_time": "2024-04-23T12:09:18+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__mol_tpcr__molecule_PPH3_Z", - "fullname": "tests/functional_tests/cfml/test__Molecules.py::test__mol_tpcr__molecule_PPH3_Z", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 0.003856708000000708, - "max": 0.016496250000002988, - "mean": 0.004136255176706824, - "stddev": 0.000878790311658476, - "rounds": 249, - "median": 0.00399637499999983, - "iqr": 0.00012539524998445017, - "q1": 0.003946031500007052, - "q3": 0.0040714267499915024, - "iqr_outliers": 26, - "stddev_outliers": 6, - "outliers": "6;26", - "ld15iqr": 0.003856708000000708, - "hd15iqr": 0.0042609169999963115, - "ops": 241.76458107117398, - "total": 1.0299275389999991, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.3009696660000003, - "max": 2.3492622499999953, - "mean": 2.319624449799997, - "stddev": 0.018051904001394337, - "rounds": 5, - "median": 2.3162478329999914, - "iqr": 0.01850345849998547, - "q1": 2.308893197750006, - "q3": 2.3273966562499915, - "iqr_outliers": 0, - "stddev_outliers": 2, - "outliers": "2;0", - "ld15iqr": 2.3009696660000003, - "hd15iqr": 2.3492622499999953, - "ops": 0.4311042677991354, - "total": 11.598122248999985, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T10:11:16.252795", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/gfortran/arm/Darwin-CPython-3.11-64bit/0003_53c48b1cb9568e544b39d995840c186ee18b16f8_20240423_102457.json b/.benchmarks/github/gfortran/arm/Darwin-CPython-3.11-64bit/0003_53c48b1cb9568e544b39d995840c186ee18b16f8_20240423_102457.json deleted file mode 100644 index ec678cd..0000000 --- a/.benchmarks/github/gfortran/arm/Darwin-CPython-3.11-64bit/0003_53c48b1cb9568e544b39d995840c186ee18b16f8_20240423_102457.json +++ /dev/null @@ -1,113 +0,0 @@ -{ - "machine_info": { - "node": "Mac-1713867838818.local", - "processor": "arm", - "machine": "arm64", - "python_compiler": "Clang 13.0.0 (clang-1300.0.29.30)", - "python_implementation": "CPython", - "python_implementation_version": "3.11.8", - "python_version": "3.11.8", - "python_build": [ - "v3.11.8:db85d51d3e", - "Feb 6 2024 18:02:37" - ], - "release": "23.3.0", - "system": "Darwin", - "cpu": { - "python_version": "3.11.8.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "ARM_8", - "bits": 64, - "count": 4, - "arch_string_raw": "arm64", - "brand_raw": "Apple M2 (Virtual)" - } - }, - "commit_info": { - "id": "53c48b1cb9568e544b39d995840c186ee18b16f8", - "time": "2024-04-23T12:23:31+02:00", - "author_time": "2024-04-23T12:23:31+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__mol_tpcr__molecule_PPH3_Z", - "fullname": "tests/functional_tests/cfml/test__Molecules.py::test__mol_tpcr__molecule_PPH3_Z", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 0.003859375000004661, - "max": 0.004834916999996608, - "mean": 0.004031492162162289, - "stddev": 0.00014590150670199616, - "rounds": 259, - "median": 0.0039835000000039145, - "iqr": 0.00014460425000351051, - "q1": 0.003933958499999335, - "q3": 0.004078562750002845, - "iqr_outliers": 19, - "stddev_outliers": 59, - "outliers": "59;19", - "ld15iqr": 0.003859375000004661, - "hd15iqr": 0.004311500000000024, - "ops": 248.0471150075734, - "total": 1.0441564700000328, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.294560582999992, - "max": 2.3345470409999933, - "mean": 2.314963233199998, - "stddev": 0.018275237619359, - "rounds": 5, - "median": 2.3061165000000017, - "iqr": 0.03150389499998951, - "q1": 2.302733521250005, - "q3": 2.3342374162499944, - "iqr_outliers": 0, - "stddev_outliers": 3, - "outliers": "3;0", - "ld15iqr": 2.294560582999992, - "hd15iqr": 2.3345470409999933, - "ops": 0.43197230334310294, - "total": 11.57481616599999, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T10:25:31.664797", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/gfortran/arm/Darwin-CPython-3.11-64bit/0003_904f83215f95337ba21fba3555ed7382b4554eef_20240423_102513.json b/.benchmarks/github/gfortran/arm/Darwin-CPython-3.11-64bit/0003_904f83215f95337ba21fba3555ed7382b4554eef_20240423_102513.json deleted file mode 100644 index 511a178..0000000 --- a/.benchmarks/github/gfortran/arm/Darwin-CPython-3.11-64bit/0003_904f83215f95337ba21fba3555ed7382b4554eef_20240423_102513.json +++ /dev/null @@ -1,113 +0,0 @@ -{ - "machine_info": { - "node": "Mac-1713867853263.local", - "processor": "arm", - "machine": "arm64", - "python_compiler": "Clang 13.0.0 (clang-1300.0.29.30)", - "python_implementation": "CPython", - "python_implementation_version": "3.11.8", - "python_version": "3.11.8", - "python_build": [ - "v3.11.8:db85d51d3e", - "Feb 6 2024 18:02:37" - ], - "release": "23.3.0", - "system": "Darwin", - "cpu": { - "python_version": "3.11.8.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "ARM_8", - "bits": 64, - "count": 4, - "arch_string_raw": "arm64", - "brand_raw": "Apple M2 (Virtual)" - } - }, - "commit_info": { - "id": "904f83215f95337ba21fba3555ed7382b4554eef", - "time": "2024-04-23T12:23:40+02:00", - "author_time": "2024-04-23T12:23:40+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__mol_tpcr__molecule_PPH3_Z", - "fullname": "tests/functional_tests/cfml/test__Molecules.py::test__mol_tpcr__molecule_PPH3_Z", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 0.004490625000002524, - "max": 0.017026291999997056, - "mean": 0.007036280798165355, - "stddev": 0.0022803094075191056, - "rounds": 218, - "median": 0.006081104499997991, - "iqr": 0.0033474159999968833, - "q1": 0.005265084000001252, - "q3": 0.008612499999998136, - "iqr_outliers": 3, - "stddev_outliers": 56, - "outliers": "56;3", - "ld15iqr": 0.004490625000002524, - "hd15iqr": 0.013844042000002332, - "ops": 142.12053621577192, - "total": 1.5339092140000474, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.410065000000003, - "max": 2.479063124999996, - "mean": 2.454257333199999, - "stddev": 0.026590392593699705, - "rounds": 5, - "median": 2.4613860829999936, - "iqr": 0.029525750249995042, - "q1": 2.441667812250003, - "q3": 2.471193562499998, - "iqr_outliers": 0, - "stddev_outliers": 1, - "outliers": "1;0", - "ld15iqr": 2.410065000000003, - "hd15iqr": 2.479063124999996, - "ops": 0.40745523563176794, - "total": 12.271286665999995, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T10:25:51.255719", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/gfortran/arm/Darwin-CPython-3.11-64bit/0004_a35d0b5acf769d4a68794b33d6952117b5ae4ecb_20240423_103157.json b/.benchmarks/github/gfortran/arm/Darwin-CPython-3.11-64bit/0004_a35d0b5acf769d4a68794b33d6952117b5ae4ecb_20240423_103157.json deleted file mode 100644 index 8a7d7e4..0000000 --- a/.benchmarks/github/gfortran/arm/Darwin-CPython-3.11-64bit/0004_a35d0b5acf769d4a68794b33d6952117b5ae4ecb_20240423_103157.json +++ /dev/null @@ -1,113 +0,0 @@ -{ - "machine_info": { - "node": "Mac-1713868260968.local", - "processor": "arm", - "machine": "arm64", - "python_compiler": "Clang 13.0.0 (clang-1300.0.29.30)", - "python_implementation": "CPython", - "python_implementation_version": "3.11.8", - "python_version": "3.11.8", - "python_build": [ - "v3.11.8:db85d51d3e", - "Feb 6 2024 18:02:37" - ], - "release": "23.3.0", - "system": "Darwin", - "cpu": { - "python_version": "3.11.8.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "ARM_8", - "bits": 64, - "count": 4, - "arch_string_raw": "arm64", - "brand_raw": "Apple M2 (Virtual)" - } - }, - "commit_info": { - "id": "a35d0b5acf769d4a68794b33d6952117b5ae4ecb", - "time": "2024-04-23T12:30:14+02:00", - "author_time": "2024-04-23T12:30:14+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__mol_tpcr__molecule_PPH3_Z", - "fullname": "tests/functional_tests/cfml/test__Molecules.py::test__mol_tpcr__molecule_PPH3_Z", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 0.0038557919999959722, - "max": 0.004807083000002876, - "mean": 0.0040164845444013685, - "stddev": 0.00010766170645782881, - "rounds": 259, - "median": 0.003996624999999199, - "iqr": 0.00011160474999982739, - "q1": 0.003948541249997106, - "q3": 0.004060145999996934, - "iqr_outliers": 9, - "stddev_outliers": 59, - "outliers": "59;9", - "ld15iqr": 0.0038557919999959722, - "hd15iqr": 0.0042278750000122045, - "ops": 248.9739444893205, - "total": 1.0402694969999544, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.293533584000002, - "max": 2.3401268749999957, - "mean": 2.3210943499999983, - "stddev": 0.020257957743167555, - "rounds": 5, - "median": 2.3273012079999944, - "iqr": 0.034849572000005935, - "q1": 2.303474052499997, - "q3": 2.3383236245000028, - "iqr_outliers": 0, - "stddev_outliers": 1, - "outliers": "1;0", - "ld15iqr": 2.293533584000002, - "hd15iqr": 2.3401268749999957, - "ops": 0.430831258539749, - "total": 11.605471749999992, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T10:32:31.751779", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/gfortran/arm/Darwin-CPython-3.11-64bit/0005_774a8273e467cce7cc73ef3fc80f580cef85088a_20240423_104410.json b/.benchmarks/github/gfortran/arm/Darwin-CPython-3.11-64bit/0005_774a8273e467cce7cc73ef3fc80f580cef85088a_20240423_104410.json deleted file mode 100644 index 52422c1..0000000 --- a/.benchmarks/github/gfortran/arm/Darwin-CPython-3.11-64bit/0005_774a8273e467cce7cc73ef3fc80f580cef85088a_20240423_104410.json +++ /dev/null @@ -1,113 +0,0 @@ -{ - "machine_info": { - "node": "Mac-1713868995040.local", - "processor": "arm", - "machine": "arm64", - "python_compiler": "Clang 13.0.0 (clang-1300.0.29.30)", - "python_implementation": "CPython", - "python_implementation_version": "3.11.8", - "python_version": "3.11.8", - "python_build": [ - "v3.11.8:db85d51d3e", - "Feb 6 2024 18:02:37" - ], - "release": "23.3.0", - "system": "Darwin", - "cpu": { - "python_version": "3.11.8.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "ARM_8", - "bits": 64, - "count": 4, - "arch_string_raw": "arm64", - "brand_raw": "Apple M2 (Virtual)" - } - }, - "commit_info": { - "id": "774a8273e467cce7cc73ef3fc80f580cef85088a", - "time": "2024-04-23T12:42:42+02:00", - "author_time": "2024-04-23T12:42:42+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.3092720419999893, - "max": 2.376199749999998, - "mean": 2.3369921999999974, - "stddev": 0.025052244573645778, - "rounds": 5, - "median": 2.328232583000002, - "iqr": 0.028560519749991187, - "q1": 2.323124948500002, - "q3": 2.3516854682499932, - "iqr_outliers": 0, - "stddev_outliers": 2, - "outliers": "2;0", - "ld15iqr": 2.3092720419999893, - "hd15iqr": 2.376199749999998, - "ops": 0.42790044399805915, - "total": 11.684960999999987, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__ponsin", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__ponsin", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.961177958999997, - "max": 3.0266849999999863, - "mean": 2.9817177001999995, - "stddev": 0.0260755092419641, - "rounds": 5, - "median": 2.9762868749999996, - "iqr": 0.024984323500000016, - "q1": 2.9651552082500032, - "q3": 2.9901395317500032, - "iqr_outliers": 0, - "stddev_outliers": 1, - "outliers": "1;0", - "ld15iqr": 2.961177958999997, - "hd15iqr": 3.0266849999999863, - "ops": 0.3353771552326784, - "total": 14.908588500999997, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T10:45:20.582699", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/gfortran/arm/Darwin-CPython-3.11-64bit/0006_2e27ea3e143b990c623b2de4195dbfc5fd3068c8_20240423_114319.json b/.benchmarks/github/gfortran/arm/Darwin-CPython-3.11-64bit/0006_2e27ea3e143b990c623b2de4195dbfc5fd3068c8_20240423_114319.json deleted file mode 100644 index 86f5922..0000000 --- a/.benchmarks/github/gfortran/arm/Darwin-CPython-3.11-64bit/0006_2e27ea3e143b990c623b2de4195dbfc5fd3068c8_20240423_114319.json +++ /dev/null @@ -1,113 +0,0 @@ -{ - "machine_info": { - "node": "Mac-1713872543754.local", - "processor": "arm", - "machine": "arm64", - "python_compiler": "Clang 13.0.0 (clang-1300.0.29.30)", - "python_implementation": "CPython", - "python_implementation_version": "3.11.8", - "python_version": "3.11.8", - "python_build": [ - "v3.11.8:db85d51d3e", - "Feb 6 2024 18:02:37" - ], - "release": "23.3.0", - "system": "Darwin", - "cpu": { - "python_version": "3.11.8.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "ARM_8", - "bits": 64, - "count": 4, - "arch_string_raw": "arm64", - "brand_raw": "Apple M2 (Virtual)" - } - }, - "commit_info": { - "id": "2e27ea3e143b990c623b2de4195dbfc5fd3068c8", - "time": "2024-04-23T13:41:53+02:00", - "author_time": "2024-04-23T13:41:53+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.307155832999996, - "max": 2.3615575000000035, - "mean": 2.3358279915999987, - "stddev": 0.024219498279867985, - "rounds": 5, - "median": 2.330443041999999, - "iqr": 0.043573479000002635, - "q1": 2.3167962707499967, - "q3": 2.3603697497499994, - "iqr_outliers": 0, - "stddev_outliers": 2, - "outliers": "2;0", - "ld15iqr": 2.307155832999996, - "hd15iqr": 2.3615575000000035, - "ops": 0.42811371539178217, - "total": 11.679139957999993, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__ponsin", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__ponsin", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.956954666999991, - "max": 3.0011436249999974, - "mean": 2.975406216600001, - "stddev": 0.01699094695141466, - "rounds": 5, - "median": 2.969464500000015, - "iqr": 0.02245552025000208, - "q1": 2.9645851354999984, - "q3": 2.9870406557500004, - "iqr_outliers": 0, - "stddev_outliers": 2, - "outliers": "2;0", - "ld15iqr": 2.956954666999991, - "hd15iqr": 3.0011436249999974, - "ops": 0.33608856310809915, - "total": 14.877031083000006, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T11:44:29.621046", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/gfortran/i386/Darwin-CPython-3.11-64bit/0001_85b81446abfdc74949b15b099d367c6498146221_20240423_100107.json b/.benchmarks/github/gfortran/i386/Darwin-CPython-3.11-64bit/0001_85b81446abfdc74949b15b099d367c6498146221_20240423_100107.json deleted file mode 100644 index a5ab96a..0000000 --- a/.benchmarks/github/gfortran/i386/Darwin-CPython-3.11-64bit/0001_85b81446abfdc74949b15b099d367c6498146221_20240423_100107.json +++ /dev/null @@ -1,220 +0,0 @@ -{ - "machine_info": { - "node": "Mac-1713865204183.local", - "processor": "i386", - "machine": "x86_64", - "python_compiler": "Clang 13.0.0 (clang-1300.0.29.30)", - "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", - "python_build": [ - "v3.11.9:de54cf5be3", - "Apr 2 2024 07:12:50" - ], - "release": "21.6.0", - "system": "Darwin", - "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "X86_64", - "bits": 64, - "count": 4, - "arch_string_raw": "x86_64", - "vendor_id_raw": "GenuineIntel", - "brand_raw": "Intel(R) Core(TM) i7-8700B CPU @ 3.20GHz", - "hz_advertised_friendly": "3.2000 GHz", - "hz_actual_friendly": "3.1900 GHz", - "hz_advertised": [ - 3200000000, - 0 - ], - "hz_actual": [ - 3190000000, - 0 - ], - "l2_cache_size": 262144, - "stepping": 10, - "model": 58, - "family": 6, - "flags": [ - "1gbpage", - "3dnowprefetch", - "abm", - "adx", - "aes", - "apic", - "avx", - "avx1.0", - "avx2", - "bmi1", - "bmi2", - "clflush", - "clflushopt", - "clfsh", - "clfsopt", - "cmov", - "cx16", - "cx8", - "de", - "ds_cpl", - "dscpl", - "dtes64", - "em64t", - "erms", - "f16c", - "fma", - "fpu", - "fpu_csds", - "fxsr", - "hle", - "ht", - "htt", - "hypervisor", - "intel_pt", - "invpcid", - "ipt", - "lahf", - "lahf_lm", - "lzcnt", - "mca", - "mce", - "mmx", - "movbe", - "mpx", - "msr", - "mtrr", - "osxsave", - "pae", - "pat", - "pbe", - "pcid", - "pclmulqdq", - "pge", - "pni", - "popcnt", - "prefetchw", - "pse", - "pse36", - "rdrand", - "rdrnd", - "rdseed", - "rdwrfsgs", - "rtm", - "seglim64", - "sep", - "sgx", - "smap", - "smep", - "ss", - "sse", - "sse2", - "sse3", - "sse4.1", - "sse4.2", - "sse4_1", - "sse4_2", - "ssse3", - "syscall", - "tpr", - "tsc", - "tsc_thread_offset", - "vme", - "vmm", - "vmx", - "x2apic", - "xd", - "xsave", - "xtpr" - ], - "l2_cache_line_size": 256, - "l2_cache_associativity": 6 - } - }, - "commit_info": { - "id": "85b81446abfdc74949b15b099d367c6498146221", - "time": "2024-04-23T11:58:35+02:00", - "author_time": "2024-04-23T11:58:35+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__mol_tpcr__molecule_PPH3_Z", - "fullname": "tests/functional_tests/cfml/test__Molecules.py::test__mol_tpcr__molecule_PPH3_Z", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 0.010158717999956934, - "max": 0.015840728999819476, - "mean": 0.01225436848146251, - "stddev": 0.0013143095796844329, - "rounds": 81, - "median": 0.012283597999839913, - "iqr": 0.0017989307499419738, - "q1": 0.011298675999967145, - "q3": 0.013097606749909119, - "iqr_outliers": 2, - "stddev_outliers": 26, - "outliers": "26;2", - "ld15iqr": 0.010158717999956934, - "hd15iqr": 0.015837072000067565, - "ops": 81.60355235871396, - "total": 0.9926038469984633, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.7382976919998328, - "max": 3.0260988289999204, - "mean": 2.868473976599989, - "stddev": 0.13374184621052082, - "rounds": 5, - "median": 2.847457390000045, - "iqr": 0.25348649275008484, - "q1": 2.7427498082499824, - "q3": 2.996236301000067, - "iqr_outliers": 0, - "stddev_outliers": 1, - "outliers": "1;0", - "ld15iqr": 2.7382976919998328, - "hd15iqr": 3.0260988289999204, - "ops": 0.3486174210251344, - "total": 14.342369882999947, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T10:01:52.168740", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/gfortran/i386/Darwin-CPython-3.11-64bit/0002_f2feb7460687645f07e2554619af175779f60ea5_20240423_101121.json b/.benchmarks/github/gfortran/i386/Darwin-CPython-3.11-64bit/0002_f2feb7460687645f07e2554619af175779f60ea5_20240423_101121.json deleted file mode 100644 index 6ccb311..0000000 --- a/.benchmarks/github/gfortran/i386/Darwin-CPython-3.11-64bit/0002_f2feb7460687645f07e2554619af175779f60ea5_20240423_101121.json +++ /dev/null @@ -1,220 +0,0 @@ -{ - "machine_info": { - "node": "Mac-1713866414419.local", - "processor": "i386", - "machine": "x86_64", - "python_compiler": "Clang 13.0.0 (clang-1300.0.29.30)", - "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", - "python_build": [ - "v3.11.9:de54cf5be3", - "Apr 2 2024 07:12:50" - ], - "release": "21.6.0", - "system": "Darwin", - "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "X86_64", - "bits": 64, - "count": 4, - "arch_string_raw": "x86_64", - "vendor_id_raw": "GenuineIntel", - "brand_raw": "Intel(R) Core(TM) i7-8700B CPU @ 3.20GHz", - "hz_advertised_friendly": "3.2000 GHz", - "hz_actual_friendly": "3.1900 GHz", - "hz_advertised": [ - 3200000000, - 0 - ], - "hz_actual": [ - 3190000000, - 0 - ], - "l2_cache_size": 262144, - "stepping": 10, - "model": 58, - "family": 6, - "flags": [ - "1gbpage", - "3dnowprefetch", - "abm", - "adx", - "aes", - "apic", - "avx", - "avx1.0", - "avx2", - "bmi1", - "bmi2", - "clflush", - "clflushopt", - "clfsh", - "clfsopt", - "cmov", - "cx16", - "cx8", - "de", - "ds_cpl", - "dscpl", - "dtes64", - "em64t", - "erms", - "f16c", - "fma", - "fpu", - "fpu_csds", - "fxsr", - "hle", - "ht", - "htt", - "hypervisor", - "intel_pt", - "invpcid", - "ipt", - "lahf", - "lahf_lm", - "lzcnt", - "mca", - "mce", - "mmx", - "movbe", - "mpx", - "msr", - "mtrr", - "osxsave", - "pae", - "pat", - "pbe", - "pcid", - "pclmulqdq", - "pge", - "pni", - "popcnt", - "prefetchw", - "pse", - "pse36", - "rdrand", - "rdrnd", - "rdseed", - "rdwrfsgs", - "rtm", - "seglim64", - "sep", - "sgx", - "smap", - "smep", - "ss", - "sse", - "sse2", - "sse3", - "sse4.1", - "sse4.2", - "sse4_1", - "sse4_2", - "ssse3", - "syscall", - "tpr", - "tsc", - "tsc_thread_offset", - "vme", - "vmm", - "vmx", - "x2apic", - "xd", - "xsave", - "xtpr" - ], - "l2_cache_line_size": 256, - "l2_cache_associativity": 6 - } - }, - "commit_info": { - "id": "f2feb7460687645f07e2554619af175779f60ea5", - "time": "2024-04-23T12:09:18+02:00", - "author_time": "2024-04-23T12:09:18+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__mol_tpcr__molecule_PPH3_Z", - "fullname": "tests/functional_tests/cfml/test__Molecules.py::test__mol_tpcr__molecule_PPH3_Z", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 0.008362379999994118, - "max": 0.017647681999960696, - "mean": 0.01139687715238519, - "stddev": 0.001716537913940145, - "rounds": 105, - "median": 0.0115397940001003, - "iqr": 0.0014188130000150068, - "q1": 0.010674308500028928, - "q3": 0.012093121500043935, - "iqr_outliers": 11, - "stddev_outliers": 29, - "outliers": "29;11", - "ld15iqr": 0.008556725000062215, - "hd15iqr": 0.014570738999964306, - "ops": 87.74333412821912, - "total": 1.1966721010004449, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.9724249759999566, - "max": 3.0306908659999863, - "mean": 3.0071610577999763, - "stddev": 0.02177747351180015, - "rounds": 5, - "median": 3.0077351289999115, - "iqr": 0.0240494349999949, - "q1": 2.9977226320000057, - "q3": 3.0217720670000006, - "iqr_outliers": 0, - "stddev_outliers": 2, - "outliers": "2;0", - "ld15iqr": 2.9724249759999566, - "hd15iqr": 3.0306908659999863, - "ops": 0.33253955500860166, - "total": 15.035805288999882, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T10:12:06.246177", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/gfortran/i386/Darwin-CPython-3.11-64bit/0003_53c48b1cb9568e544b39d995840c186ee18b16f8_20240423_102546.json b/.benchmarks/github/gfortran/i386/Darwin-CPython-3.11-64bit/0003_53c48b1cb9568e544b39d995840c186ee18b16f8_20240423_102546.json deleted file mode 100644 index 7c8d396..0000000 --- a/.benchmarks/github/gfortran/i386/Darwin-CPython-3.11-64bit/0003_53c48b1cb9568e544b39d995840c186ee18b16f8_20240423_102546.json +++ /dev/null @@ -1,220 +0,0 @@ -{ - "machine_info": { - "node": "Mac-1713865881844.local", - "processor": "i386", - "machine": "x86_64", - "python_compiler": "Clang 13.0.0 (clang-1300.0.29.30)", - "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", - "python_build": [ - "v3.11.9:de54cf5be3", - "Apr 2 2024 07:12:50" - ], - "release": "21.6.0", - "system": "Darwin", - "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "X86_64", - "bits": 64, - "count": 4, - "arch_string_raw": "x86_64", - "vendor_id_raw": "GenuineIntel", - "brand_raw": "Intel(R) Core(TM) i7-8700B CPU @ 3.20GHz", - "hz_advertised_friendly": "3.2000 GHz", - "hz_actual_friendly": "3.1900 GHz", - "hz_advertised": [ - 3200000000, - 0 - ], - "hz_actual": [ - 3190000000, - 0 - ], - "l2_cache_size": 262144, - "stepping": 10, - "model": 58, - "family": 6, - "flags": [ - "1gbpage", - "3dnowprefetch", - "abm", - "adx", - "aes", - "apic", - "avx", - "avx1.0", - "avx2", - "bmi1", - "bmi2", - "clflush", - "clflushopt", - "clfsh", - "clfsopt", - "cmov", - "cx16", - "cx8", - "de", - "ds_cpl", - "dscpl", - "dtes64", - "em64t", - "erms", - "f16c", - "fma", - "fpu", - "fpu_csds", - "fxsr", - "hle", - "ht", - "htt", - "hypervisor", - "intel_pt", - "invpcid", - "ipt", - "lahf", - "lahf_lm", - "lzcnt", - "mca", - "mce", - "mmx", - "movbe", - "mpx", - "msr", - "mtrr", - "osxsave", - "pae", - "pat", - "pbe", - "pcid", - "pclmulqdq", - "pge", - "pni", - "popcnt", - "prefetchw", - "pse", - "pse36", - "rdrand", - "rdrnd", - "rdseed", - "rdwrfsgs", - "rtm", - "seglim64", - "sep", - "sgx", - "smap", - "smep", - "ss", - "sse", - "sse2", - "sse3", - "sse4.1", - "sse4.2", - "sse4_1", - "sse4_2", - "ssse3", - "syscall", - "tpr", - "tsc", - "tsc_thread_offset", - "vme", - "vmm", - "vmx", - "x2apic", - "xd", - "xsave", - "xtpr" - ], - "l2_cache_line_size": 256, - "l2_cache_associativity": 6 - } - }, - "commit_info": { - "id": "53c48b1cb9568e544b39d995840c186ee18b16f8", - "time": "2024-04-23T12:23:31+02:00", - "author_time": "2024-04-23T12:23:31+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__mol_tpcr__molecule_PPH3_Z", - "fullname": "tests/functional_tests/cfml/test__Molecules.py::test__mol_tpcr__molecule_PPH3_Z", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 0.012238316000093619, - "max": 0.0212907080003788, - "mean": 0.013493661452371054, - "stddev": 0.0018689365151122646, - "rounds": 84, - "median": 0.012692740499687716, - "iqr": 0.0014133080003375653, - "q1": 0.01248048349975761, - "q3": 0.013893791500095176, - "iqr_outliers": 8, - "stddev_outliers": 10, - "outliers": "10;8", - "ld15iqr": 0.012238316000093619, - "hd15iqr": 0.016075898000053712, - "ops": 74.1088698223034, - "total": 1.1334675619991685, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.8936298630001147, - "max": 3.0242904380002074, - "mean": 2.9704042456000934, - "stddev": 0.05136336115902084, - "rounds": 5, - "median": 2.969504817000143, - "iqr": 0.07334554124986425, - "q1": 2.939790808250109, - "q3": 3.013136349499973, - "iqr_outliers": 0, - "stddev_outliers": 2, - "outliers": "2;0", - "ld15iqr": 2.8936298630001147, - "hd15iqr": 3.0242904380002074, - "ops": 0.3366545147790064, - "total": 14.852021228000467, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T10:26:31.615318", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/gfortran/i386/Darwin-CPython-3.11-64bit/0003_904f83215f95337ba21fba3555ed7382b4554eef_20240423_102602.json b/.benchmarks/github/gfortran/i386/Darwin-CPython-3.11-64bit/0003_904f83215f95337ba21fba3555ed7382b4554eef_20240423_102602.json deleted file mode 100644 index ea4173c..0000000 --- a/.benchmarks/github/gfortran/i386/Darwin-CPython-3.11-64bit/0003_904f83215f95337ba21fba3555ed7382b4554eef_20240423_102602.json +++ /dev/null @@ -1,202 +0,0 @@ -{ - "machine_info": { - "node": "Mac-1713867734877.local", - "processor": "i386", - "machine": "x86_64", - "python_compiler": "Clang 13.0.0 (clang-1300.0.29.30)", - "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", - "python_build": [ - "v3.11.9:de54cf5be3", - "Apr 2 2024 07:12:50" - ], - "release": "21.6.0", - "system": "Darwin", - "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "X86_64", - "bits": 64, - "count": 3, - "arch_string_raw": "x86_64", - "vendor_id_raw": "GenuineIntel", - "brand_raw": "Intel(R) Xeon(R) CPU E5-1650 v2 @ 3.50GHz", - "hz_advertised_friendly": "3.5000 GHz", - "hz_actual_friendly": "3.3370 GHz", - "hz_advertised": [ - 3500000000, - 0 - ], - "hz_actual": [ - 3337000000, - 0 - ], - "l2_cache_size": 262144, - "stepping": 9, - "model": 58, - "family": 6, - "flags": [ - "acapmsr", - "aes", - "apic", - "avx", - "avx1.0", - "clflush", - "clfsh", - "cmov", - "cx16", - "cx8", - "de", - "em64t", - "erms", - "f16c", - "fpu", - "fxsr", - "ht", - "htt", - "hypervisor", - "ibrs", - "l1df", - "lahf", - "lahf_lm", - "mca", - "mce", - "mdclear", - "mmx", - "mon", - "monitor", - "msr", - "mtrr", - "osxsave", - "pae", - "pat", - "pcid", - "pclmulqdq", - "pge", - "pni", - "popcnt", - "pse", - "pse36", - "rdrand", - "rdrnd", - "rdtscp", - "rdwrfsgs", - "sep", - "smep", - "ss", - "ssbd", - "sse", - "sse2", - "sse3", - "sse4.1", - "sse4.2", - "sse4_1", - "sse4_2", - "ssse3", - "stibp", - "syscall", - "tsc", - "tsc_thread_offset", - "tscdeadline", - "tsci", - "tsctmr", - "vme", - "vmm", - "vmx", - "x2apic", - "xd", - "xsave" - ], - "l2_cache_line_size": 256, - "l2_cache_associativity": 6 - } - }, - "commit_info": { - "id": "904f83215f95337ba21fba3555ed7382b4554eef", - "time": "2024-04-23T12:23:40+02:00", - "author_time": "2024-04-23T12:23:40+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__mol_tpcr__molecule_PPH3_Z", - "fullname": "tests/functional_tests/cfml/test__Molecules.py::test__mol_tpcr__molecule_PPH3_Z", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 0.0126616740000145, - "max": 0.07344343900001604, - "mean": 0.013987560378050065, - "stddev": 0.006670553650317419, - "rounds": 82, - "median": 0.013102731000032009, - "iqr": 0.00042011800002228483, - "q1": 0.01296479399996997, - "q3": 0.013384911999992255, - "iqr_outliers": 7, - "stddev_outliers": 1, - "outliers": "1;7", - "ld15iqr": 0.0126616740000145, - "hd15iqr": 0.014018134000025384, - "ops": 71.4920953313093, - "total": 1.1469799510001053, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.8593225650000136, - "max": 2.995756854999968, - "mean": 2.918463701200005, - "stddev": 0.05122592116170178, - "rounds": 5, - "median": 2.916720278000014, - "iqr": 0.06569441749994098, - "q1": 2.881732271750039, - "q3": 2.94742668924998, - "iqr_outliers": 0, - "stddev_outliers": 2, - "outliers": "2;0", - "ld15iqr": 2.8593225650000136, - "hd15iqr": 2.995756854999968, - "ops": 0.3426460296863802, - "total": 14.592318506000026, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T10:26:46.695633", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/gfortran/x86_64/Linux-CPython-3.11-64bit/0001_85b81446abfdc74949b15b099d367c6498146221_20240423_095950.json b/.benchmarks/github/gfortran/x86_64/Linux-CPython-3.11-64bit/0001_85b81446abfdc74949b15b099d367c6498146221_20240423_095950.json deleted file mode 100644 index 761911f..0000000 --- a/.benchmarks/github/gfortran/x86_64/Linux-CPython-3.11-64bit/0001_85b81446abfdc74949b15b099d367c6498146221_20240423_095950.json +++ /dev/null @@ -1,240 +0,0 @@ -{ - "machine_info": { - "node": "fv-az566-74", - "processor": "x86_64", - "machine": "x86_64", - "python_compiler": "GCC 11.4.0", - "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", - "python_build": [ - "main", - "Apr 2 2024 15:19:53" - ], - "release": "6.5.0-1018-azure", - "system": "Linux", - "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "X86_64", - "bits": 64, - "count": 4, - "arch_string_raw": "x86_64", - "vendor_id_raw": "AuthenticAMD", - "brand_raw": "AMD EPYC 7763 64-Core Processor", - "hz_advertised_friendly": "3.2420 GHz", - "hz_actual_friendly": "3.2420 GHz", - "hz_advertised": [ - 3241950000, - 0 - ], - "hz_actual": [ - 3241950000, - 0 - ], - "stepping": 1, - "model": 1, - "family": 25, - "flags": [ - "3dnowext", - "3dnowprefetch", - "abm", - "adx", - "aes", - "aperfmperf", - "apic", - "arat", - "avx", - "avx2", - "bmi1", - "bmi2", - "clflush", - "clflushopt", - "clwb", - "clzero", - "cmov", - "cmp_legacy", - "constant_tsc", - "cpuid", - "cr8_legacy", - "cx16", - "cx8", - "de", - "decodeassists", - "erms", - "extd_apicid", - "f16c", - "flushbyasid", - "fma", - "fpu", - "fsgsbase", - "fsrm", - "fxsr", - "fxsr_opt", - "ht", - "hypervisor", - "invpcid", - "invpcid_single", - "lahf_lm", - "lm", - "mca", - "mce", - "misalignsse", - "mmx", - "mmxext", - "movbe", - "msr", - "mtrr", - "nonstop_tsc", - "nopl", - "npt", - "nrip_save", - "nx", - "osvw", - "osxsave", - "pae", - "pat", - "pausefilter", - "pcid", - "pclmulqdq", - "pdpe1gb", - "pfthreshold", - "pge", - "pni", - "popcnt", - "pse", - "pse36", - "rdpid", - "rdpru", - "rdrand", - "rdrnd", - "rdseed", - "rdtscp", - "rep_good", - "sep", - "sha", - "sha_ni", - "smap", - "smep", - "sse", - "sse2", - "sse4_1", - "sse4_2", - "sse4a", - "ssse3", - "svm", - "syscall", - "topoext", - "tsc", - "tsc_reliable", - "tsc_scale", - "umip", - "v_vmsave_vmload", - "vaes", - "vmcb_clean", - "vme", - "vmmcall", - "vpclmulqdq", - "xgetbv1", - "xsave", - "xsavec", - "xsaveerptr", - "xsaveopt", - "xsaves" - ], - "l3_cache_size": 524288, - "l2_cache_size": 1048576, - "l1_data_cache_size": 65536, - "l1_instruction_cache_size": 65536, - "l2_cache_line_size": 512, - "l2_cache_associativity": 6 - } - }, - "commit_info": { - "id": "85b81446abfdc74949b15b099d367c6498146221", - "time": "2024-04-23T11:58:35+02:00", - "author_time": "2024-04-23T11:58:35+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__mol_tpcr__molecule_PPH3_Z", - "fullname": "tests/functional_tests/cfml/test__Molecules.py::test__mol_tpcr__molecule_PPH3_Z", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 0.003507826000031855, - "max": 0.007019142999979522, - "mean": 0.0036831662727276272, - "stddev": 0.00024113917567150056, - "rounds": 286, - "median": 0.00366013100000373, - "iqr": 0.0001010389999578365, - "q1": 0.0036008900000297217, - "q3": 0.003701928999987558, - "iqr_outliers": 10, - "stddev_outliers": 9, - "outliers": "9;10", - "ld15iqr": 0.003507826000031855, - "hd15iqr": 0.0038815749999798754, - "ops": 271.50552702564636, - "total": 1.0533855540001014, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.4644920889999753, - "max": 2.472402396999996, - "mean": 2.4677917110000065, - "stddev": 0.003230315159364184, - "rounds": 5, - "median": 2.4664370720000193, - "iqr": 0.004931818750009143, - "q1": 2.465506025250008, - "q3": 2.470437844000017, - "iqr_outliers": 0, - "stddev_outliers": 2, - "outliers": "2;0", - "ld15iqr": 2.4644920889999753, - "hd15iqr": 2.472402396999996, - "ops": 0.4052205846800485, - "total": 12.338958555000033, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T10:00:28.508879", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/gfortran/x86_64/Linux-CPython-3.11-64bit/0002_f2feb7460687645f07e2554619af175779f60ea5_20240423_101034.json b/.benchmarks/github/gfortran/x86_64/Linux-CPython-3.11-64bit/0002_f2feb7460687645f07e2554619af175779f60ea5_20240423_101034.json deleted file mode 100644 index f393676..0000000 --- a/.benchmarks/github/gfortran/x86_64/Linux-CPython-3.11-64bit/0002_f2feb7460687645f07e2554619af175779f60ea5_20240423_101034.json +++ /dev/null @@ -1,240 +0,0 @@ -{ - "machine_info": { - "node": "fv-az654-395", - "processor": "x86_64", - "machine": "x86_64", - "python_compiler": "GCC 11.4.0", - "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", - "python_build": [ - "main", - "Apr 2 2024 15:19:53" - ], - "release": "6.5.0-1018-azure", - "system": "Linux", - "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "X86_64", - "bits": 64, - "count": 4, - "arch_string_raw": "x86_64", - "vendor_id_raw": "AuthenticAMD", - "brand_raw": "AMD EPYC 7763 64-Core Processor", - "hz_advertised_friendly": "3.2450 GHz", - "hz_actual_friendly": "3.2450 GHz", - "hz_advertised": [ - 3244990000, - 0 - ], - "hz_actual": [ - 3244990000, - 0 - ], - "stepping": 1, - "model": 1, - "family": 25, - "flags": [ - "3dnowext", - "3dnowprefetch", - "abm", - "adx", - "aes", - "aperfmperf", - "apic", - "arat", - "avx", - "avx2", - "bmi1", - "bmi2", - "clflush", - "clflushopt", - "clwb", - "clzero", - "cmov", - "cmp_legacy", - "constant_tsc", - "cpuid", - "cr8_legacy", - "cx16", - "cx8", - "de", - "decodeassists", - "erms", - "extd_apicid", - "f16c", - "flushbyasid", - "fma", - "fpu", - "fsgsbase", - "fsrm", - "fxsr", - "fxsr_opt", - "ht", - "hypervisor", - "invpcid", - "invpcid_single", - "lahf_lm", - "lm", - "mca", - "mce", - "misalignsse", - "mmx", - "mmxext", - "movbe", - "msr", - "mtrr", - "nonstop_tsc", - "nopl", - "npt", - "nrip_save", - "nx", - "osvw", - "osxsave", - "pae", - "pat", - "pausefilter", - "pcid", - "pclmulqdq", - "pdpe1gb", - "pfthreshold", - "pge", - "pni", - "popcnt", - "pse", - "pse36", - "rdpid", - "rdpru", - "rdrand", - "rdrnd", - "rdseed", - "rdtscp", - "rep_good", - "sep", - "sha", - "sha_ni", - "smap", - "smep", - "sse", - "sse2", - "sse4_1", - "sse4_2", - "sse4a", - "ssse3", - "svm", - "syscall", - "topoext", - "tsc", - "tsc_reliable", - "tsc_scale", - "umip", - "v_vmsave_vmload", - "vaes", - "vmcb_clean", - "vme", - "vmmcall", - "vpclmulqdq", - "xgetbv1", - "xsave", - "xsavec", - "xsaveerptr", - "xsaveopt", - "xsaves" - ], - "l3_cache_size": 524288, - "l2_cache_size": 1048576, - "l1_data_cache_size": 65536, - "l1_instruction_cache_size": 65536, - "l2_cache_line_size": 512, - "l2_cache_associativity": 6 - } - }, - "commit_info": { - "id": "f2feb7460687645f07e2554619af175779f60ea5", - "time": "2024-04-23T12:09:18+02:00", - "author_time": "2024-04-23T12:09:18+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__mol_tpcr__molecule_PPH3_Z", - "fullname": "tests/functional_tests/cfml/test__Molecules.py::test__mol_tpcr__molecule_PPH3_Z", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 0.0035123309999960384, - "max": 0.009268941000016184, - "mean": 0.003785889126315193, - "stddev": 0.0006332944920767572, - "rounds": 285, - "median": 0.0036710469999832185, - "iqr": 0.00010783424999516456, - "q1": 0.0036118085000111932, - "q3": 0.003719642750006358, - "iqr_outliers": 15, - "stddev_outliers": 13, - "outliers": "13;15", - "ld15iqr": 0.0035123309999960384, - "hd15iqr": 0.0040518120000001545, - "ops": 264.13874433066144, - "total": 1.07897840099983, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.469071389999982, - "max": 2.4744945029999883, - "mean": 2.471791575399993, - "stddev": 0.0019213037146248323, - "rounds": 5, - "median": 2.4718089950000035, - "iqr": 0.0016158070000216185, - "q1": 2.4709814539999826, - "q3": 2.472597261000004, - "iqr_outliers": 0, - "stddev_outliers": 2, - "outliers": "2;0", - "ld15iqr": 2.469071389999982, - "hd15iqr": 2.4744945029999883, - "ops": 0.40456485488189947, - "total": 12.358957876999966, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T10:11:11.986999", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/gfortran/x86_64/Linux-CPython-3.11-64bit/0003_53c48b1cb9568e544b39d995840c186ee18b16f8_20240423_102449.json b/.benchmarks/github/gfortran/x86_64/Linux-CPython-3.11-64bit/0003_53c48b1cb9568e544b39d995840c186ee18b16f8_20240423_102449.json deleted file mode 100644 index 0e0d2c5..0000000 --- a/.benchmarks/github/gfortran/x86_64/Linux-CPython-3.11-64bit/0003_53c48b1cb9568e544b39d995840c186ee18b16f8_20240423_102449.json +++ /dev/null @@ -1,240 +0,0 @@ -{ - "machine_info": { - "node": "fv-az1116-273", - "processor": "x86_64", - "machine": "x86_64", - "python_compiler": "GCC 11.4.0", - "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", - "python_build": [ - "main", - "Apr 2 2024 15:19:53" - ], - "release": "6.5.0-1018-azure", - "system": "Linux", - "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "X86_64", - "bits": 64, - "count": 4, - "arch_string_raw": "x86_64", - "vendor_id_raw": "AuthenticAMD", - "brand_raw": "AMD EPYC 7763 64-Core Processor", - "hz_advertised_friendly": "3.2435 GHz", - "hz_actual_friendly": "3.2435 GHz", - "hz_advertised": [ - 3243465000, - 0 - ], - "hz_actual": [ - 3243465000, - 0 - ], - "stepping": 1, - "model": 1, - "family": 25, - "flags": [ - "3dnowext", - "3dnowprefetch", - "abm", - "adx", - "aes", - "aperfmperf", - "apic", - "arat", - "avx", - "avx2", - "bmi1", - "bmi2", - "clflush", - "clflushopt", - "clwb", - "clzero", - "cmov", - "cmp_legacy", - "constant_tsc", - "cpuid", - "cr8_legacy", - "cx16", - "cx8", - "de", - "decodeassists", - "erms", - "extd_apicid", - "f16c", - "flushbyasid", - "fma", - "fpu", - "fsgsbase", - "fsrm", - "fxsr", - "fxsr_opt", - "ht", - "hypervisor", - "invpcid", - "invpcid_single", - "lahf_lm", - "lm", - "mca", - "mce", - "misalignsse", - "mmx", - "mmxext", - "movbe", - "msr", - "mtrr", - "nonstop_tsc", - "nopl", - "npt", - "nrip_save", - "nx", - "osvw", - "osxsave", - "pae", - "pat", - "pausefilter", - "pcid", - "pclmulqdq", - "pdpe1gb", - "pfthreshold", - "pge", - "pni", - "popcnt", - "pse", - "pse36", - "rdpid", - "rdpru", - "rdrand", - "rdrnd", - "rdseed", - "rdtscp", - "rep_good", - "sep", - "sha", - "sha_ni", - "smap", - "smep", - "sse", - "sse2", - "sse4_1", - "sse4_2", - "sse4a", - "ssse3", - "svm", - "syscall", - "topoext", - "tsc", - "tsc_reliable", - "tsc_scale", - "umip", - "v_vmsave_vmload", - "vaes", - "vmcb_clean", - "vme", - "vmmcall", - "vpclmulqdq", - "xgetbv1", - "xsave", - "xsavec", - "xsaveerptr", - "xsaveopt", - "xsaves" - ], - "l3_cache_size": 524288, - "l2_cache_size": 1048576, - "l1_data_cache_size": 65536, - "l1_instruction_cache_size": 65536, - "l2_cache_line_size": 512, - "l2_cache_associativity": 6 - } - }, - "commit_info": { - "id": "53c48b1cb9568e544b39d995840c186ee18b16f8", - "time": "2024-04-23T12:23:31+02:00", - "author_time": "2024-04-23T12:23:31+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__mol_tpcr__molecule_PPH3_Z", - "fullname": "tests/functional_tests/cfml/test__Molecules.py::test__mol_tpcr__molecule_PPH3_Z", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 0.0035044989999732934, - "max": 0.005695035999963238, - "mean": 0.003655544062068484, - "stddev": 0.00017804179527639092, - "rounds": 290, - "median": 0.0036444205000236707, - "iqr": 9.177100002943916e-05, - "q1": 0.003587222999954065, - "q3": 0.003678993999983504, - "iqr_outliers": 7, - "stddev_outliers": 6, - "outliers": "6;7", - "ld15iqr": 0.0035044989999732934, - "hd15iqr": 0.0038175330000171925, - "ops": 273.55709109799415, - "total": 1.0601077779998604, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.461594687999991, - "max": 2.4649790720000055, - "mean": 2.463079261200005, - "stddev": 0.0013176874104739904, - "rounds": 5, - "median": 2.4633447560000263, - "iqr": 0.0018122729999987541, - "q1": 2.461969754750001, - "q3": 2.4637820277499998, - "iqr_outliers": 0, - "stddev_outliers": 2, - "outliers": "2;0", - "ld15iqr": 2.461594687999991, - "hd15iqr": 2.4649790720000055, - "ops": 0.4059958669429107, - "total": 12.315396306000025, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T10:25:27.528365", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/gfortran/x86_64/Linux-CPython-3.11-64bit/0003_904f83215f95337ba21fba3555ed7382b4554eef_20240423_102457.json b/.benchmarks/github/gfortran/x86_64/Linux-CPython-3.11-64bit/0003_904f83215f95337ba21fba3555ed7382b4554eef_20240423_102457.json deleted file mode 100644 index d05b882..0000000 --- a/.benchmarks/github/gfortran/x86_64/Linux-CPython-3.11-64bit/0003_904f83215f95337ba21fba3555ed7382b4554eef_20240423_102457.json +++ /dev/null @@ -1,240 +0,0 @@ -{ - "machine_info": { - "node": "fv-az837-838", - "processor": "x86_64", - "machine": "x86_64", - "python_compiler": "GCC 11.4.0", - "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", - "python_build": [ - "main", - "Apr 2 2024 15:19:53" - ], - "release": "6.5.0-1018-azure", - "system": "Linux", - "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "X86_64", - "bits": 64, - "count": 4, - "arch_string_raw": "x86_64", - "vendor_id_raw": "AuthenticAMD", - "brand_raw": "AMD EPYC 7763 64-Core Processor", - "hz_advertised_friendly": "3.2396 GHz", - "hz_actual_friendly": "3.2396 GHz", - "hz_advertised": [ - 3239616000, - 0 - ], - "hz_actual": [ - 3239616000, - 0 - ], - "stepping": 1, - "model": 1, - "family": 25, - "flags": [ - "3dnowext", - "3dnowprefetch", - "abm", - "adx", - "aes", - "aperfmperf", - "apic", - "arat", - "avx", - "avx2", - "bmi1", - "bmi2", - "clflush", - "clflushopt", - "clwb", - "clzero", - "cmov", - "cmp_legacy", - "constant_tsc", - "cpuid", - "cr8_legacy", - "cx16", - "cx8", - "de", - "decodeassists", - "erms", - "extd_apicid", - "f16c", - "flushbyasid", - "fma", - "fpu", - "fsgsbase", - "fsrm", - "fxsr", - "fxsr_opt", - "ht", - "hypervisor", - "invpcid", - "invpcid_single", - "lahf_lm", - "lm", - "mca", - "mce", - "misalignsse", - "mmx", - "mmxext", - "movbe", - "msr", - "mtrr", - "nonstop_tsc", - "nopl", - "npt", - "nrip_save", - "nx", - "osvw", - "osxsave", - "pae", - "pat", - "pausefilter", - "pcid", - "pclmulqdq", - "pdpe1gb", - "pfthreshold", - "pge", - "pni", - "popcnt", - "pse", - "pse36", - "rdpid", - "rdpru", - "rdrand", - "rdrnd", - "rdseed", - "rdtscp", - "rep_good", - "sep", - "sha", - "sha_ni", - "smap", - "smep", - "sse", - "sse2", - "sse4_1", - "sse4_2", - "sse4a", - "ssse3", - "svm", - "syscall", - "topoext", - "tsc", - "tsc_reliable", - "tsc_scale", - "umip", - "v_vmsave_vmload", - "vaes", - "vmcb_clean", - "vme", - "vmmcall", - "vpclmulqdq", - "xgetbv1", - "xsave", - "xsavec", - "xsaveerptr", - "xsaveopt", - "xsaves" - ], - "l3_cache_size": 524288, - "l2_cache_size": 1048576, - "l1_data_cache_size": 65536, - "l1_instruction_cache_size": 65536, - "l2_cache_line_size": 512, - "l2_cache_associativity": 6 - } - }, - "commit_info": { - "id": "904f83215f95337ba21fba3555ed7382b4554eef", - "time": "2024-04-23T12:23:40+02:00", - "author_time": "2024-04-23T12:23:40+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__mol_tpcr__molecule_PPH3_Z", - "fullname": "tests/functional_tests/cfml/test__Molecules.py::test__mol_tpcr__molecule_PPH3_Z", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 0.0035224629999959234, - "max": 0.006938947000008966, - "mean": 0.0037169609295781805, - "stddev": 0.00028605641927957804, - "rounds": 284, - "median": 0.003680248000009101, - "iqr": 0.00011343699999599721, - "q1": 0.0036179219999894485, - "q3": 0.0037313589999854457, - "iqr_outliers": 15, - "stddev_outliers": 13, - "outliers": "13;15", - "ld15iqr": 0.0035224629999959234, - "hd15iqr": 0.003917204999993373, - "ops": 269.03699526200967, - "total": 1.0556169040002032, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.4637686530000167, - "max": 2.47382580499999, - "mean": 2.469654990800001, - "stddev": 0.004292858446973975, - "rounds": 5, - "median": 2.469421741000019, - "iqr": 0.007223978249989216, - "q1": 2.466559351249998, - "q3": 2.4737833294999874, - "iqr_outliers": 0, - "stddev_outliers": 1, - "outliers": "1;0", - "ld15iqr": 2.4637686530000167, - "hd15iqr": 2.47382580499999, - "ops": 0.4049148580369389, - "total": 12.348274954000004, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T10:25:35.383194", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/gfortran/x86_64/Linux-CPython-3.11-64bit/0004_a35d0b5acf769d4a68794b33d6952117b5ae4ecb_20240423_103137.json b/.benchmarks/github/gfortran/x86_64/Linux-CPython-3.11-64bit/0004_a35d0b5acf769d4a68794b33d6952117b5ae4ecb_20240423_103137.json deleted file mode 100644 index 42c9f24..0000000 --- a/.benchmarks/github/gfortran/x86_64/Linux-CPython-3.11-64bit/0004_a35d0b5acf769d4a68794b33d6952117b5ae4ecb_20240423_103137.json +++ /dev/null @@ -1,240 +0,0 @@ -{ - "machine_info": { - "node": "fv-az849-678", - "processor": "x86_64", - "machine": "x86_64", - "python_compiler": "GCC 11.4.0", - "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", - "python_build": [ - "main", - "Apr 2 2024 15:19:53" - ], - "release": "6.5.0-1018-azure", - "system": "Linux", - "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "X86_64", - "bits": 64, - "count": 4, - "arch_string_raw": "x86_64", - "vendor_id_raw": "AuthenticAMD", - "brand_raw": "AMD EPYC 7763 64-Core Processor", - "hz_advertised_friendly": "2.9853 GHz", - "hz_actual_friendly": "2.9853 GHz", - "hz_advertised": [ - 2985274000, - 0 - ], - "hz_actual": [ - 2985274000, - 0 - ], - "stepping": 1, - "model": 1, - "family": 25, - "flags": [ - "3dnowext", - "3dnowprefetch", - "abm", - "adx", - "aes", - "aperfmperf", - "apic", - "arat", - "avx", - "avx2", - "bmi1", - "bmi2", - "clflush", - "clflushopt", - "clwb", - "clzero", - "cmov", - "cmp_legacy", - "constant_tsc", - "cpuid", - "cr8_legacy", - "cx16", - "cx8", - "de", - "decodeassists", - "erms", - "extd_apicid", - "f16c", - "flushbyasid", - "fma", - "fpu", - "fsgsbase", - "fsrm", - "fxsr", - "fxsr_opt", - "ht", - "hypervisor", - "invpcid", - "invpcid_single", - "lahf_lm", - "lm", - "mca", - "mce", - "misalignsse", - "mmx", - "mmxext", - "movbe", - "msr", - "mtrr", - "nonstop_tsc", - "nopl", - "npt", - "nrip_save", - "nx", - "osvw", - "osxsave", - "pae", - "pat", - "pausefilter", - "pcid", - "pclmulqdq", - "pdpe1gb", - "pfthreshold", - "pge", - "pni", - "popcnt", - "pse", - "pse36", - "rdpid", - "rdpru", - "rdrand", - "rdrnd", - "rdseed", - "rdtscp", - "rep_good", - "sep", - "sha", - "sha_ni", - "smap", - "smep", - "sse", - "sse2", - "sse4_1", - "sse4_2", - "sse4a", - "ssse3", - "svm", - "syscall", - "topoext", - "tsc", - "tsc_reliable", - "tsc_scale", - "umip", - "v_vmsave_vmload", - "vaes", - "vmcb_clean", - "vme", - "vmmcall", - "vpclmulqdq", - "xgetbv1", - "xsave", - "xsavec", - "xsaveerptr", - "xsaveopt", - "xsaves" - ], - "l3_cache_size": 524288, - "l2_cache_size": 1048576, - "l1_data_cache_size": 65536, - "l1_instruction_cache_size": 65536, - "l2_cache_line_size": 512, - "l2_cache_associativity": 6 - } - }, - "commit_info": { - "id": "a35d0b5acf769d4a68794b33d6952117b5ae4ecb", - "time": "2024-04-23T12:30:14+02:00", - "author_time": "2024-04-23T12:30:14+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__mol_tpcr__molecule_PPH3_Z", - "fullname": "tests/functional_tests/cfml/test__Molecules.py::test__mol_tpcr__molecule_PPH3_Z", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 0.003547580999992306, - "max": 0.008406983000014634, - "mean": 0.004080943078014001, - "stddev": 0.0008938867111331238, - "rounds": 282, - "median": 0.0038128314999994473, - "iqr": 0.0003333830000258331, - "q1": 0.003701547999980903, - "q3": 0.004034931000006736, - "iqr_outliers": 25, - "stddev_outliers": 19, - "outliers": "19;25", - "ld15iqr": 0.003547580999992306, - "hd15iqr": 0.0045417830000076265, - "ops": 245.04139873635586, - "total": 1.150825947999948, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.467946259999991, - "max": 2.5275900940000042, - "mean": 2.480909303200002, - "stddev": 0.026127293910870077, - "rounds": 5, - "median": 2.4700439590000087, - "iqr": 0.017093279250012472, - "q1": 2.4680077307499957, - "q3": 2.485101010000008, - "iqr_outliers": 1, - "stddev_outliers": 1, - "outliers": "1;1", - "ld15iqr": 2.467946259999991, - "hd15iqr": 2.5275900940000042, - "ops": 0.4030780160766657, - "total": 12.40454651600001, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T10:32:15.898440", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/gfortran/x86_64/Linux-CPython-3.11-64bit/0005_774a8273e467cce7cc73ef3fc80f580cef85088a_20240423_104359.json b/.benchmarks/github/gfortran/x86_64/Linux-CPython-3.11-64bit/0005_774a8273e467cce7cc73ef3fc80f580cef85088a_20240423_104359.json deleted file mode 100644 index aae4319..0000000 --- a/.benchmarks/github/gfortran/x86_64/Linux-CPython-3.11-64bit/0005_774a8273e467cce7cc73ef3fc80f580cef85088a_20240423_104359.json +++ /dev/null @@ -1,240 +0,0 @@ -{ - "machine_info": { - "node": "fv-az566-74", - "processor": "x86_64", - "machine": "x86_64", - "python_compiler": "GCC 11.4.0", - "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", - "python_build": [ - "main", - "Apr 2 2024 15:19:53" - ], - "release": "6.5.0-1018-azure", - "system": "Linux", - "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "X86_64", - "bits": 64, - "count": 4, - "arch_string_raw": "x86_64", - "vendor_id_raw": "AuthenticAMD", - "brand_raw": "AMD EPYC 7763 64-Core Processor", - "hz_advertised_friendly": "3.2428 GHz", - "hz_actual_friendly": "3.2428 GHz", - "hz_advertised": [ - 3242836000, - 0 - ], - "hz_actual": [ - 3242836000, - 0 - ], - "stepping": 1, - "model": 1, - "family": 25, - "flags": [ - "3dnowext", - "3dnowprefetch", - "abm", - "adx", - "aes", - "aperfmperf", - "apic", - "arat", - "avx", - "avx2", - "bmi1", - "bmi2", - "clflush", - "clflushopt", - "clwb", - "clzero", - "cmov", - "cmp_legacy", - "constant_tsc", - "cpuid", - "cr8_legacy", - "cx16", - "cx8", - "de", - "decodeassists", - "erms", - "extd_apicid", - "f16c", - "flushbyasid", - "fma", - "fpu", - "fsgsbase", - "fsrm", - "fxsr", - "fxsr_opt", - "ht", - "hypervisor", - "invpcid", - "invpcid_single", - "lahf_lm", - "lm", - "mca", - "mce", - "misalignsse", - "mmx", - "mmxext", - "movbe", - "msr", - "mtrr", - "nonstop_tsc", - "nopl", - "npt", - "nrip_save", - "nx", - "osvw", - "osxsave", - "pae", - "pat", - "pausefilter", - "pcid", - "pclmulqdq", - "pdpe1gb", - "pfthreshold", - "pge", - "pni", - "popcnt", - "pse", - "pse36", - "rdpid", - "rdpru", - "rdrand", - "rdrnd", - "rdseed", - "rdtscp", - "rep_good", - "sep", - "sha", - "sha_ni", - "smap", - "smep", - "sse", - "sse2", - "sse4_1", - "sse4_2", - "sse4a", - "ssse3", - "svm", - "syscall", - "topoext", - "tsc", - "tsc_reliable", - "tsc_scale", - "umip", - "v_vmsave_vmload", - "vaes", - "vmcb_clean", - "vme", - "vmmcall", - "vpclmulqdq", - "xgetbv1", - "xsave", - "xsavec", - "xsaveerptr", - "xsaveopt", - "xsaves" - ], - "l3_cache_size": 524288, - "l2_cache_size": 1048576, - "l1_data_cache_size": 65536, - "l1_instruction_cache_size": 65536, - "l2_cache_line_size": 512, - "l2_cache_associativity": 6 - } - }, - "commit_info": { - "id": "774a8273e467cce7cc73ef3fc80f580cef85088a", - "time": "2024-04-23T12:42:42+02:00", - "author_time": "2024-04-23T12:42:42+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.4630952929999808, - "max": 2.468726643999986, - "mean": 2.4663662487999884, - "stddev": 0.0022715585721305677, - "rounds": 5, - "median": 2.4664825609999923, - "iqr": 0.0035398312499737017, - "q1": 2.464780356250003, - "q3": 2.4683201874999767, - "iqr_outliers": 0, - "stddev_outliers": 2, - "outliers": "2;0", - "ld15iqr": 2.4630952929999808, - "hd15iqr": 2.468726643999986, - "ops": 0.40545478616022673, - "total": 12.331831243999943, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__ponsin", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__ponsin", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 3.5525703879999924, - "max": 3.558903326999996, - "mean": 3.5565002815999947, - "stddev": 0.0028708523981824216, - "rounds": 5, - "median": 3.5579621780000252, - "iqr": 0.0048711499999711805, - "q1": 3.553898207499998, - "q3": 3.558769357499969, - "iqr_outliers": 0, - "stddev_outliers": 1, - "outliers": "1;0", - "ld15iqr": 3.5525703879999924, - "hd15iqr": 3.558903326999996, - "ops": 0.2811752905443666, - "total": 17.782501407999973, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T10:45:19.776124", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/gfortran/x86_64/Linux-CPython-3.11-64bit/0006_2e27ea3e143b990c623b2de4195dbfc5fd3068c8_20240423_114307.json b/.benchmarks/github/gfortran/x86_64/Linux-CPython-3.11-64bit/0006_2e27ea3e143b990c623b2de4195dbfc5fd3068c8_20240423_114307.json deleted file mode 100644 index 06f811f..0000000 --- a/.benchmarks/github/gfortran/x86_64/Linux-CPython-3.11-64bit/0006_2e27ea3e143b990c623b2de4195dbfc5fd3068c8_20240423_114307.json +++ /dev/null @@ -1,240 +0,0 @@ -{ - "machine_info": { - "node": "fv-az1490-491", - "processor": "x86_64", - "machine": "x86_64", - "python_compiler": "GCC 11.4.0", - "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", - "python_build": [ - "main", - "Apr 2 2024 15:19:53" - ], - "release": "6.5.0-1018-azure", - "system": "Linux", - "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "X86_64", - "bits": 64, - "count": 4, - "arch_string_raw": "x86_64", - "vendor_id_raw": "AuthenticAMD", - "brand_raw": "AMD EPYC 7763 64-Core Processor", - "hz_advertised_friendly": "3.2430 GHz", - "hz_actual_friendly": "3.2430 GHz", - "hz_advertised": [ - 3243009000, - 0 - ], - "hz_actual": [ - 3243009000, - 0 - ], - "stepping": 1, - "model": 1, - "family": 25, - "flags": [ - "3dnowext", - "3dnowprefetch", - "abm", - "adx", - "aes", - "aperfmperf", - "apic", - "arat", - "avx", - "avx2", - "bmi1", - "bmi2", - "clflush", - "clflushopt", - "clwb", - "clzero", - "cmov", - "cmp_legacy", - "constant_tsc", - "cpuid", - "cr8_legacy", - "cx16", - "cx8", - "de", - "decodeassists", - "erms", - "extd_apicid", - "f16c", - "flushbyasid", - "fma", - "fpu", - "fsgsbase", - "fsrm", - "fxsr", - "fxsr_opt", - "ht", - "hypervisor", - "invpcid", - "invpcid_single", - "lahf_lm", - "lm", - "mca", - "mce", - "misalignsse", - "mmx", - "mmxext", - "movbe", - "msr", - "mtrr", - "nonstop_tsc", - "nopl", - "npt", - "nrip_save", - "nx", - "osvw", - "osxsave", - "pae", - "pat", - "pausefilter", - "pcid", - "pclmulqdq", - "pdpe1gb", - "pfthreshold", - "pge", - "pni", - "popcnt", - "pse", - "pse36", - "rdpid", - "rdpru", - "rdrand", - "rdrnd", - "rdseed", - "rdtscp", - "rep_good", - "sep", - "sha", - "sha_ni", - "smap", - "smep", - "sse", - "sse2", - "sse4_1", - "sse4_2", - "sse4a", - "ssse3", - "svm", - "syscall", - "topoext", - "tsc", - "tsc_reliable", - "tsc_scale", - "umip", - "v_vmsave_vmload", - "vaes", - "vmcb_clean", - "vme", - "vmmcall", - "vpclmulqdq", - "xgetbv1", - "xsave", - "xsavec", - "xsaveerptr", - "xsaveopt", - "xsaves" - ], - "l3_cache_size": 524288, - "l2_cache_size": 1048576, - "l1_data_cache_size": 65536, - "l1_instruction_cache_size": 65536, - "l2_cache_line_size": 512, - "l2_cache_associativity": 6 - } - }, - "commit_info": { - "id": "2e27ea3e143b990c623b2de4195dbfc5fd3068c8", - "time": "2024-04-23T13:41:53+02:00", - "author_time": "2024-04-23T13:41:53+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.4659032109999828, - "max": 2.4753833620000023, - "mean": 2.469547554600001, - "stddev": 0.003557056756700752, - "rounds": 5, - "median": 2.468303944000013, - "iqr": 0.0035686037500113343, - "q1": 2.4676817407499954, - "q3": 2.4712503445000067, - "iqr_outliers": 0, - "stddev_outliers": 2, - "outliers": "2;0", - "ld15iqr": 2.4659032109999828, - "hd15iqr": 2.4753833620000023, - "ops": 0.40493247361740825, - "total": 12.347737773000006, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__ponsin", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__ponsin", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 3.5305680000000166, - "max": 3.559741918000043, - "mean": 3.551488129200004, - "stddev": 0.011999027082850392, - "rounds": 5, - "median": 3.554211914000007, - "iqr": 0.011159226999993166, - "q1": 3.5480536814999937, - "q3": 3.559212908499987, - "iqr_outliers": 1, - "stddev_outliers": 1, - "outliers": "1;1", - "ld15iqr": 3.553882241999986, - "hd15iqr": 3.559741918000043, - "ops": 0.2815721082602229, - "total": 17.75744064600002, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T11:44:28.269691", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/ifort/AMD64/Windows-CPython-3.11-64bit/0001_85b81446abfdc74949b15b099d367c6498146221_20240423_100421.json b/.benchmarks/github/ifort/AMD64/Windows-CPython-3.11-64bit/0001_85b81446abfdc74949b15b099d367c6498146221_20240423_100421.json deleted file mode 100644 index 41b018e..0000000 --- a/.benchmarks/github/ifort/AMD64/Windows-CPython-3.11-64bit/0001_85b81446abfdc74949b15b099d367c6498146221_20240423_100421.json +++ /dev/null @@ -1,205 +0,0 @@ -{ - "machine_info": { - "node": "fv-az1495-940", - "processor": "AMD64 Family 25 Model 1 Stepping 1, AuthenticAMD", - "machine": "AMD64", - "python_compiler": "MSC v.1938 64 bit (AMD64)", - "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", - "python_build": [ - "tags/v3.11.9:de54cf5", - "Apr 2 2024 10:12:12" - ], - "release": "10", - "system": "Windows", - "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "X86_64", - "bits": 64, - "count": 4, - "arch_string_raw": "AMD64", - "vendor_id_raw": "AuthenticAMD", - "brand_raw": "AMD EPYC 7763 64-Core Processor", - "hz_actual_friendly": "2.4450 GHz", - "hz_actual": [ - 2445000000, - 0 - ], - "stepping": 1, - "model": 1, - "family": 25, - "hz_advertised_friendly": "2.4450 GHz", - "hz_advertised": [ - 2445000000, - 0 - ], - "flags": [ - "3dnow", - "3dnowext", - "3dnowprefetch", - "abm", - "adx", - "aes", - "apic", - "avx", - "avx2", - "bmi1", - "bmi2", - "clflush", - "clflushopt", - "clwb", - "cmov", - "cmp_legacy", - "cr8_legacy", - "cx16", - "cx8", - "de", - "dts", - "erms", - "f16c", - "fma", - "fpu", - "fxsr", - "ht", - "hypervisor", - "ia64", - "invpcid", - "lahf_lm", - "mca", - "mce", - "misalignsse", - "mmx", - "movbe", - "msr", - "mtrr", - "osvw", - "osxsave", - "pae", - "pat", - "pcid", - "pclmulqdq", - "pge", - "pni", - "popcnt", - "pse", - "pse36", - "rdpid", - "rdrnd", - "rdseed", - "sep", - "sepamd", - "serial", - "sha", - "smap", - "smep", - "ss", - "sse", - "sse2", - "sse4_1", - "sse4_2", - "sse4a", - "ssse3", - "tm", - "topoext", - "tsc", - "umip", - "vaes", - "vme", - "vpclmulqdq", - "xsave" - ], - "l2_cache_size": 65536, - "l2_cache_line_size": 512, - "l2_cache_associativity": 6 - } - }, - "commit_info": { - "id": "85b81446abfdc74949b15b099d367c6498146221", - "time": "2024-04-23T11:58:35+02:00", - "author_time": "2024-04-23T11:58:35+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__mol_tpcr__molecule_PPH3_Z", - "fullname": "tests/functional_tests/cfml/test__Molecules.py::test__mol_tpcr__molecule_PPH3_Z", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 0.013456299999916155, - "max": 0.014941600000042854, - "mean": 0.013792281333335267, - "stddev": 0.0002507840174964767, - "rounds": 75, - "median": 0.013737399999968147, - "iqr": 0.0002408250000485168, - "q1": 0.013639224999991484, - "q3": 0.01388005000004, - "iqr_outliers": 3, - "stddev_outliers": 10, - "outliers": "10;3", - "ld15iqr": 0.013456299999916155, - "hd15iqr": 0.014528899999959322, - "ops": 72.50432149923226, - "total": 1.034421100000145, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.342799100000093, - "max": 2.34817129999999, - "mean": 2.345809960000042, - "stddev": 0.002401739331781838, - "rounds": 5, - "median": 2.345975899999985, - "iqr": 0.00439652499994736, - "q1": 2.3437118500000906, - "q3": 2.348108375000038, - "iqr_outliers": 0, - "stddev_outliers": 1, - "outliers": "1;0", - "ld15iqr": 2.342799100000093, - "hd15iqr": 2.34817129999999, - "ops": 0.4262919917008034, - "total": 11.729049800000212, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T10:04:58.337805", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/ifort/AMD64/Windows-CPython-3.11-64bit/0002_f2feb7460687645f07e2554619af175779f60ea5_20240423_101451.json b/.benchmarks/github/ifort/AMD64/Windows-CPython-3.11-64bit/0002_f2feb7460687645f07e2554619af175779f60ea5_20240423_101451.json deleted file mode 100644 index 008b131..0000000 --- a/.benchmarks/github/ifort/AMD64/Windows-CPython-3.11-64bit/0002_f2feb7460687645f07e2554619af175779f60ea5_20240423_101451.json +++ /dev/null @@ -1,205 +0,0 @@ -{ - "machine_info": { - "node": "fv-az844-227", - "processor": "AMD64 Family 25 Model 1 Stepping 1, AuthenticAMD", - "machine": "AMD64", - "python_compiler": "MSC v.1938 64 bit (AMD64)", - "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", - "python_build": [ - "tags/v3.11.9:de54cf5", - "Apr 2 2024 10:12:12" - ], - "release": "10", - "system": "Windows", - "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "X86_64", - "bits": 64, - "count": 4, - "arch_string_raw": "AMD64", - "vendor_id_raw": "AuthenticAMD", - "brand_raw": "AMD EPYC 7763 64-Core Processor", - "hz_actual_friendly": "2.4450 GHz", - "hz_actual": [ - 2445000000, - 0 - ], - "stepping": 1, - "model": 1, - "family": 25, - "hz_advertised_friendly": "2.4450 GHz", - "hz_advertised": [ - 2445000000, - 0 - ], - "flags": [ - "3dnow", - "3dnowext", - "3dnowprefetch", - "abm", - "adx", - "aes", - "apic", - "avx", - "avx2", - "bmi1", - "bmi2", - "clflush", - "clflushopt", - "clwb", - "cmov", - "cmp_legacy", - "cr8_legacy", - "cx16", - "cx8", - "de", - "dts", - "erms", - "f16c", - "fma", - "fpu", - "fxsr", - "ht", - "hypervisor", - "ia64", - "invpcid", - "lahf_lm", - "mca", - "mce", - "misalignsse", - "mmx", - "movbe", - "msr", - "mtrr", - "osvw", - "osxsave", - "pae", - "pat", - "pcid", - "pclmulqdq", - "pge", - "pni", - "popcnt", - "pse", - "pse36", - "rdpid", - "rdrnd", - "rdseed", - "sep", - "sepamd", - "serial", - "sha", - "smap", - "smep", - "ss", - "sse", - "sse2", - "sse4_1", - "sse4_2", - "sse4a", - "ssse3", - "tm", - "topoext", - "tsc", - "umip", - "vaes", - "vme", - "vpclmulqdq", - "xsave" - ], - "l2_cache_size": 65536, - "l2_cache_line_size": 512, - "l2_cache_associativity": 6 - } - }, - "commit_info": { - "id": "f2feb7460687645f07e2554619af175779f60ea5", - "time": "2024-04-23T12:09:18+02:00", - "author_time": "2024-04-23T12:09:18+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__mol_tpcr__molecule_PPH3_Z", - "fullname": "tests/functional_tests/cfml/test__Molecules.py::test__mol_tpcr__molecule_PPH3_Z", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 0.01324350000004415, - "max": 0.014264199999956872, - "mean": 0.01355095921052614, - "stddev": 0.00018663095218091408, - "rounds": 76, - "median": 0.013529799999957959, - "iqr": 0.0002349999999182728, - "q1": 0.013410200000066652, - "q3": 0.013645199999984925, - "iqr_outliers": 2, - "stddev_outliers": 23, - "outliers": "23;2", - "ld15iqr": 0.01324350000004415, - "hd15iqr": 0.014139499999942018, - "ops": 73.79551399012537, - "total": 1.0298728999999867, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.3353188999999475, - "max": 2.3423837000000276, - "mean": 2.339503539999987, - "stddev": 0.0026796825489415104, - "rounds": 5, - "median": 2.3399358000000348, - "iqr": 0.00339182499996582, - "q1": 2.337971649999986, - "q3": 2.3413634749999517, - "iqr_outliers": 0, - "stddev_outliers": 2, - "outliers": "2;0", - "ld15iqr": 2.3353188999999475, - "hd15iqr": 2.3423837000000276, - "ops": 0.4274411142801714, - "total": 11.697517699999935, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T10:15:28.339389", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/ifort/AMD64/Windows-CPython-3.11-64bit/0003_904f83215f95337ba21fba3555ed7382b4554eef_20240423_103506.json b/.benchmarks/github/ifort/AMD64/Windows-CPython-3.11-64bit/0003_904f83215f95337ba21fba3555ed7382b4554eef_20240423_103506.json deleted file mode 100644 index b90de7f..0000000 --- a/.benchmarks/github/ifort/AMD64/Windows-CPython-3.11-64bit/0003_904f83215f95337ba21fba3555ed7382b4554eef_20240423_103506.json +++ /dev/null @@ -1,205 +0,0 @@ -{ - "machine_info": { - "node": "fv-az731-743", - "processor": "AMD64 Family 25 Model 1 Stepping 1, AuthenticAMD", - "machine": "AMD64", - "python_compiler": "MSC v.1938 64 bit (AMD64)", - "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", - "python_build": [ - "tags/v3.11.9:de54cf5", - "Apr 2 2024 10:12:12" - ], - "release": "10", - "system": "Windows", - "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "X86_64", - "bits": 64, - "count": 4, - "arch_string_raw": "AMD64", - "vendor_id_raw": "AuthenticAMD", - "brand_raw": "AMD EPYC 7763 64-Core Processor", - "hz_actual_friendly": "2.4450 GHz", - "hz_actual": [ - 2445000000, - 0 - ], - "stepping": 1, - "model": 1, - "family": 25, - "hz_advertised_friendly": "2.4450 GHz", - "hz_advertised": [ - 2445000000, - 0 - ], - "flags": [ - "3dnow", - "3dnowext", - "3dnowprefetch", - "abm", - "adx", - "aes", - "apic", - "avx", - "avx2", - "bmi1", - "bmi2", - "clflush", - "clflushopt", - "clwb", - "cmov", - "cmp_legacy", - "cr8_legacy", - "cx16", - "cx8", - "de", - "dts", - "erms", - "f16c", - "fma", - "fpu", - "fxsr", - "ht", - "hypervisor", - "ia64", - "invpcid", - "lahf_lm", - "mca", - "mce", - "misalignsse", - "mmx", - "movbe", - "msr", - "mtrr", - "osvw", - "osxsave", - "pae", - "pat", - "pcid", - "pclmulqdq", - "pge", - "pni", - "popcnt", - "pse", - "pse36", - "rdpid", - "rdrnd", - "rdseed", - "sep", - "sepamd", - "serial", - "sha", - "smap", - "smep", - "ss", - "sse", - "sse2", - "sse4_1", - "sse4_2", - "sse4a", - "ssse3", - "tm", - "topoext", - "tsc", - "umip", - "vaes", - "vme", - "vpclmulqdq", - "xsave" - ], - "l2_cache_size": 65536, - "l2_cache_line_size": 512, - "l2_cache_associativity": 6 - } - }, - "commit_info": { - "id": "904f83215f95337ba21fba3555ed7382b4554eef", - "time": "2024-04-23T12:23:40+02:00", - "author_time": "2024-04-23T12:23:40+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__mol_tpcr__molecule_PPH3_Z", - "fullname": "tests/functional_tests/cfml/test__Molecules.py::test__mol_tpcr__molecule_PPH3_Z", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 0.013602600000012899, - "max": 0.016097199999876466, - "mean": 0.014144493150668071, - "stddev": 0.00039640665858470817, - "rounds": 73, - "median": 0.014048300000013114, - "iqr": 0.00030319999990524593, - "q1": 0.013937375000068641, - "q3": 0.014240574999973887, - "iqr_outliers": 6, - "stddev_outliers": 11, - "outliers": "11;6", - "ld15iqr": 0.013602600000012899, - "hd15iqr": 0.014698599999974249, - "ops": 70.69889244866778, - "total": 1.0325479999987692, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.339437500000031, - "max": 2.3592111000000386, - "mean": 2.3463059399999566, - "stddev": 0.007550697495488843, - "rounds": 5, - "median": 2.344008899999835, - "iqr": 0.006467399999905865, - "q1": 2.34242445000001, - "q3": 2.348891849999916, - "iqr_outliers": 1, - "stddev_outliers": 1, - "outliers": "1;1", - "ld15iqr": 2.339437500000031, - "hd15iqr": 2.3592111000000386, - "ops": 0.426201878856437, - "total": 11.731529699999783, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T10:35:43.377418", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/ifort/AMD64/Windows-CPython-3.11-64bit/0004_a35d0b5acf769d4a68794b33d6952117b5ae4ecb_20240423_103552.json b/.benchmarks/github/ifort/AMD64/Windows-CPython-3.11-64bit/0004_a35d0b5acf769d4a68794b33d6952117b5ae4ecb_20240423_103552.json deleted file mode 100644 index d954065..0000000 --- a/.benchmarks/github/ifort/AMD64/Windows-CPython-3.11-64bit/0004_a35d0b5acf769d4a68794b33d6952117b5ae4ecb_20240423_103552.json +++ /dev/null @@ -1,205 +0,0 @@ -{ - "machine_info": { - "node": "fv-az1390-498", - "processor": "AMD64 Family 25 Model 1 Stepping 1, AuthenticAMD", - "machine": "AMD64", - "python_compiler": "MSC v.1938 64 bit (AMD64)", - "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", - "python_build": [ - "tags/v3.11.9:de54cf5", - "Apr 2 2024 10:12:12" - ], - "release": "10", - "system": "Windows", - "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "X86_64", - "bits": 64, - "count": 4, - "arch_string_raw": "AMD64", - "vendor_id_raw": "AuthenticAMD", - "brand_raw": "AMD EPYC 7763 64-Core Processor", - "hz_actual_friendly": "2.4450 GHz", - "hz_actual": [ - 2445000000, - 0 - ], - "stepping": 1, - "model": 1, - "family": 25, - "hz_advertised_friendly": "2.4450 GHz", - "hz_advertised": [ - 2445000000, - 0 - ], - "flags": [ - "3dnow", - "3dnowext", - "3dnowprefetch", - "abm", - "adx", - "aes", - "apic", - "avx", - "avx2", - "bmi1", - "bmi2", - "clflush", - "clflushopt", - "clwb", - "cmov", - "cmp_legacy", - "cr8_legacy", - "cx16", - "cx8", - "de", - "dts", - "erms", - "f16c", - "fma", - "fpu", - "fxsr", - "ht", - "hypervisor", - "ia64", - "invpcid", - "lahf_lm", - "mca", - "mce", - "misalignsse", - "mmx", - "movbe", - "msr", - "mtrr", - "osvw", - "osxsave", - "pae", - "pat", - "pcid", - "pclmulqdq", - "pge", - "pni", - "popcnt", - "pse", - "pse36", - "rdpid", - "rdrnd", - "rdseed", - "sep", - "sepamd", - "serial", - "sha", - "smap", - "smep", - "ss", - "sse", - "sse2", - "sse4_1", - "sse4_2", - "sse4a", - "ssse3", - "tm", - "topoext", - "tsc", - "umip", - "vaes", - "vme", - "vpclmulqdq", - "xsave" - ], - "l2_cache_size": 65536, - "l2_cache_line_size": 512, - "l2_cache_associativity": 6 - } - }, - "commit_info": { - "id": "a35d0b5acf769d4a68794b33d6952117b5ae4ecb", - "time": "2024-04-23T12:30:14+02:00", - "author_time": "2024-04-23T12:30:14+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__mol_tpcr__molecule_PPH3_Z", - "fullname": "tests/functional_tests/cfml/test__Molecules.py::test__mol_tpcr__molecule_PPH3_Z", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 0.013458700000001045, - "max": 0.014484299999935502, - "mean": 0.013754563013692435, - "stddev": 0.00019396872421234383, - "rounds": 73, - "median": 0.01373019999994085, - "iqr": 0.00021452500001828412, - "q1": 0.013624099999987038, - "q3": 0.013838625000005322, - "iqr_outliers": 3, - "stddev_outliers": 19, - "outliers": "19;3", - "ld15iqr": 0.013458700000001045, - "hd15iqr": 0.014236200000027566, - "ops": 72.7031457854762, - "total": 1.0040830999995478, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.3410947999999507, - "max": 2.3437818999999536, - "mean": 2.3424199399999908, - "stddev": 0.0009875971916673794, - "rounds": 5, - "median": 2.342450900000017, - "iqr": 0.0012401999999553937, - "q1": 2.3417790250000223, - "q3": 2.3430192249999777, - "iqr_outliers": 0, - "stddev_outliers": 2, - "outliers": "2;0", - "ld15iqr": 2.3410947999999507, - "hd15iqr": 2.3437818999999536, - "ops": 0.4269089341853895, - "total": 11.712099699999953, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T10:36:28.483735", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/ifort/AMD64/Windows-CPython-3.11-64bit/0006_2e27ea3e143b990c623b2de4195dbfc5fd3068c8_20240423_114727.json b/.benchmarks/github/ifort/AMD64/Windows-CPython-3.11-64bit/0006_2e27ea3e143b990c623b2de4195dbfc5fd3068c8_20240423_114727.json deleted file mode 100644 index 9e493fe..0000000 --- a/.benchmarks/github/ifort/AMD64/Windows-CPython-3.11-64bit/0006_2e27ea3e143b990c623b2de4195dbfc5fd3068c8_20240423_114727.json +++ /dev/null @@ -1,205 +0,0 @@ -{ - "machine_info": { - "node": "fv-az653-279", - "processor": "AMD64 Family 25 Model 1 Stepping 1, AuthenticAMD", - "machine": "AMD64", - "python_compiler": "MSC v.1938 64 bit (AMD64)", - "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", - "python_build": [ - "tags/v3.11.9:de54cf5", - "Apr 2 2024 10:12:12" - ], - "release": "10", - "system": "Windows", - "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "X86_64", - "bits": 64, - "count": 4, - "arch_string_raw": "AMD64", - "vendor_id_raw": "AuthenticAMD", - "brand_raw": "AMD EPYC 7763 64-Core Processor", - "hz_actual_friendly": "2.4450 GHz", - "hz_actual": [ - 2445000000, - 0 - ], - "stepping": 1, - "model": 1, - "family": 25, - "hz_advertised_friendly": "2.4450 GHz", - "hz_advertised": [ - 2445000000, - 0 - ], - "flags": [ - "3dnow", - "3dnowext", - "3dnowprefetch", - "abm", - "adx", - "aes", - "apic", - "avx", - "avx2", - "bmi1", - "bmi2", - "clflush", - "clflushopt", - "clwb", - "cmov", - "cmp_legacy", - "cr8_legacy", - "cx16", - "cx8", - "de", - "dts", - "erms", - "f16c", - "fma", - "fpu", - "fxsr", - "ht", - "hypervisor", - "ia64", - "invpcid", - "lahf_lm", - "mca", - "mce", - "misalignsse", - "mmx", - "movbe", - "msr", - "mtrr", - "osvw", - "osxsave", - "pae", - "pat", - "pcid", - "pclmulqdq", - "pge", - "pni", - "popcnt", - "pse", - "pse36", - "rdpid", - "rdrnd", - "rdseed", - "sep", - "sepamd", - "serial", - "sha", - "smap", - "smep", - "ss", - "sse", - "sse2", - "sse4_1", - "sse4_2", - "sse4a", - "ssse3", - "tm", - "topoext", - "tsc", - "umip", - "vaes", - "vme", - "vpclmulqdq", - "xsave" - ], - "l2_cache_size": 65536, - "l2_cache_line_size": 512, - "l2_cache_associativity": 6 - } - }, - "commit_info": { - "id": "2e27ea3e143b990c623b2de4195dbfc5fd3068c8", - "time": "2024-04-23T13:41:53+02:00", - "author_time": "2024-04-23T13:41:53+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.346343300000001, - "max": 2.3484172000000285, - "mean": 2.3473207800000067, - "stddev": 0.0007967456601820338, - "rounds": 5, - "median": 2.347236100000032, - "iqr": 0.0011670000000236769, - "q1": 2.3467392999999817, - "q3": 2.3479063000000053, - "iqr_outliers": 0, - "stddev_outliers": 2, - "outliers": "2;0", - "ld15iqr": 2.346343300000001, - "hd15iqr": 2.3484172000000285, - "ops": 0.4260176148570529, - "total": 11.736603900000034, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__ponsin", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__ponsin", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 3.7807079000000385, - "max": 3.817449500000066, - "mean": 3.7965949200000066, - "stddev": 0.016858440504153496, - "rounds": 5, - "median": 3.789110800000003, - "iqr": 0.0301408499999809, - "q1": 3.783089149999995, - "q3": 3.813229999999976, - "iqr_outliers": 0, - "stddev_outliers": 1, - "outliers": "1;0", - "ld15iqr": 3.7807079000000385, - "hd15iqr": 3.817449500000066, - "ops": 0.2633939150927374, - "total": 18.982974600000034, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T11:48:50.725278", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/ifort/x86_64/Linux-CPython-3.11-64bit/0001_85b81446abfdc74949b15b099d367c6498146221_20240423_100326.json b/.benchmarks/github/ifort/x86_64/Linux-CPython-3.11-64bit/0001_85b81446abfdc74949b15b099d367c6498146221_20240423_100326.json deleted file mode 100644 index e4f9b03..0000000 --- a/.benchmarks/github/ifort/x86_64/Linux-CPython-3.11-64bit/0001_85b81446abfdc74949b15b099d367c6498146221_20240423_100326.json +++ /dev/null @@ -1,240 +0,0 @@ -{ - "machine_info": { - "node": "fv-az1144-406", - "processor": "x86_64", - "machine": "x86_64", - "python_compiler": "GCC 11.4.0", - "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", - "python_build": [ - "main", - "Apr 2 2024 15:19:53" - ], - "release": "6.5.0-1018-azure", - "system": "Linux", - "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "X86_64", - "bits": 64, - "count": 4, - "arch_string_raw": "x86_64", - "vendor_id_raw": "AuthenticAMD", - "brand_raw": "AMD EPYC 7763 64-Core Processor", - "hz_advertised_friendly": "3.2441 GHz", - "hz_actual_friendly": "3.2441 GHz", - "hz_advertised": [ - 3244051000, - 0 - ], - "hz_actual": [ - 3244051000, - 0 - ], - "stepping": 1, - "model": 1, - "family": 25, - "flags": [ - "3dnowext", - "3dnowprefetch", - "abm", - "adx", - "aes", - "aperfmperf", - "apic", - "arat", - "avx", - "avx2", - "bmi1", - "bmi2", - "clflush", - "clflushopt", - "clwb", - "clzero", - "cmov", - "cmp_legacy", - "constant_tsc", - "cpuid", - "cr8_legacy", - "cx16", - "cx8", - "de", - "decodeassists", - "erms", - "extd_apicid", - "f16c", - "flushbyasid", - "fma", - "fpu", - "fsgsbase", - "fsrm", - "fxsr", - "fxsr_opt", - "ht", - "hypervisor", - "invpcid", - "invpcid_single", - "lahf_lm", - "lm", - "mca", - "mce", - "misalignsse", - "mmx", - "mmxext", - "movbe", - "msr", - "mtrr", - "nonstop_tsc", - "nopl", - "npt", - "nrip_save", - "nx", - "osvw", - "osxsave", - "pae", - "pat", - "pausefilter", - "pcid", - "pclmulqdq", - "pdpe1gb", - "pfthreshold", - "pge", - "pni", - "popcnt", - "pse", - "pse36", - "rdpid", - "rdpru", - "rdrand", - "rdrnd", - "rdseed", - "rdtscp", - "rep_good", - "sep", - "sha", - "sha_ni", - "smap", - "smep", - "sse", - "sse2", - "sse4_1", - "sse4_2", - "sse4a", - "ssse3", - "svm", - "syscall", - "topoext", - "tsc", - "tsc_reliable", - "tsc_scale", - "umip", - "v_vmsave_vmload", - "vaes", - "vmcb_clean", - "vme", - "vmmcall", - "vpclmulqdq", - "xgetbv1", - "xsave", - "xsavec", - "xsaveerptr", - "xsaveopt", - "xsaves" - ], - "l3_cache_size": 524288, - "l2_cache_size": 1048576, - "l1_data_cache_size": 65536, - "l1_instruction_cache_size": 65536, - "l2_cache_line_size": 512, - "l2_cache_associativity": 6 - } - }, - "commit_info": { - "id": "85b81446abfdc74949b15b099d367c6498146221", - "time": "2024-04-23T11:58:35+02:00", - "author_time": "2024-04-23T11:58:35+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__mol_tpcr__molecule_PPH3_Z", - "fullname": "tests/functional_tests/cfml/test__Molecules.py::test__mol_tpcr__molecule_PPH3_Z", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 0.005839013000013438, - "max": 0.006414417000030426, - "mean": 0.006007729816095936, - "stddev": 9.232061020298849e-05, - "rounds": 174, - "median": 0.006008875000020453, - "iqr": 0.0001211169999919548, - "q1": 0.005947445000003881, - "q3": 0.006068561999995836, - "iqr_outliers": 1, - "stddev_outliers": 56, - "outliers": "56;1", - "ld15iqr": 0.005839013000013438, - "hd15iqr": 0.006414417000030426, - "ops": 166.45222581761178, - "total": 1.0453449880006929, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.3100750360000006, - "max": 2.3168878530000256, - "mean": 2.312633970800016, - "stddev": 0.0027699304797505933, - "rounds": 5, - "median": 2.312802791000024, - "iqr": 0.0038977927500098986, - "q1": 2.3101980300000093, - "q3": 2.3140958227500192, - "iqr_outliers": 0, - "stddev_outliers": 1, - "outliers": "1;0", - "ld15iqr": 2.3100750360000006, - "hd15iqr": 2.3168878530000256, - "ops": 0.43240738163768616, - "total": 11.56316985400008, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T10:04:01.735911", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/ifort/x86_64/Linux-CPython-3.11-64bit/0002_f2feb7460687645f07e2554619af175779f60ea5_20240423_101411.json b/.benchmarks/github/ifort/x86_64/Linux-CPython-3.11-64bit/0002_f2feb7460687645f07e2554619af175779f60ea5_20240423_101411.json deleted file mode 100644 index 232de45..0000000 --- a/.benchmarks/github/ifort/x86_64/Linux-CPython-3.11-64bit/0002_f2feb7460687645f07e2554619af175779f60ea5_20240423_101411.json +++ /dev/null @@ -1,240 +0,0 @@ -{ - "machine_info": { - "node": "fv-az849-678", - "processor": "x86_64", - "machine": "x86_64", - "python_compiler": "GCC 11.4.0", - "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", - "python_build": [ - "main", - "Apr 2 2024 15:19:53" - ], - "release": "6.5.0-1018-azure", - "system": "Linux", - "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "X86_64", - "bits": 64, - "count": 4, - "arch_string_raw": "x86_64", - "vendor_id_raw": "AuthenticAMD", - "brand_raw": "AMD EPYC 7763 64-Core Processor", - "hz_advertised_friendly": "2.4454 GHz", - "hz_actual_friendly": "2.4454 GHz", - "hz_advertised": [ - 2445435000, - 0 - ], - "hz_actual": [ - 2445435000, - 0 - ], - "stepping": 1, - "model": 1, - "family": 25, - "flags": [ - "3dnowext", - "3dnowprefetch", - "abm", - "adx", - "aes", - "aperfmperf", - "apic", - "arat", - "avx", - "avx2", - "bmi1", - "bmi2", - "clflush", - "clflushopt", - "clwb", - "clzero", - "cmov", - "cmp_legacy", - "constant_tsc", - "cpuid", - "cr8_legacy", - "cx16", - "cx8", - "de", - "decodeassists", - "erms", - "extd_apicid", - "f16c", - "flushbyasid", - "fma", - "fpu", - "fsgsbase", - "fsrm", - "fxsr", - "fxsr_opt", - "ht", - "hypervisor", - "invpcid", - "invpcid_single", - "lahf_lm", - "lm", - "mca", - "mce", - "misalignsse", - "mmx", - "mmxext", - "movbe", - "msr", - "mtrr", - "nonstop_tsc", - "nopl", - "npt", - "nrip_save", - "nx", - "osvw", - "osxsave", - "pae", - "pat", - "pausefilter", - "pcid", - "pclmulqdq", - "pdpe1gb", - "pfthreshold", - "pge", - "pni", - "popcnt", - "pse", - "pse36", - "rdpid", - "rdpru", - "rdrand", - "rdrnd", - "rdseed", - "rdtscp", - "rep_good", - "sep", - "sha", - "sha_ni", - "smap", - "smep", - "sse", - "sse2", - "sse4_1", - "sse4_2", - "sse4a", - "ssse3", - "svm", - "syscall", - "topoext", - "tsc", - "tsc_reliable", - "tsc_scale", - "umip", - "v_vmsave_vmload", - "vaes", - "vmcb_clean", - "vme", - "vmmcall", - "vpclmulqdq", - "xgetbv1", - "xsave", - "xsavec", - "xsaveerptr", - "xsaveopt", - "xsaves" - ], - "l3_cache_size": 524288, - "l2_cache_size": 1048576, - "l1_data_cache_size": 65536, - "l1_instruction_cache_size": 65536, - "l2_cache_line_size": 512, - "l2_cache_associativity": 6 - } - }, - "commit_info": { - "id": "f2feb7460687645f07e2554619af175779f60ea5", - "time": "2024-04-23T12:09:18+02:00", - "author_time": "2024-04-23T12:09:18+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__mol_tpcr__molecule_PPH3_Z", - "fullname": "tests/functional_tests/cfml/test__Molecules.py::test__mol_tpcr__molecule_PPH3_Z", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 0.005840381000041361, - "max": 0.006807606999984728, - "mean": 0.006066035258618482, - "stddev": 0.00016970294978769024, - "rounds": 174, - "median": 0.0060389054999916425, - "iqr": 0.0001772829999708847, - "q1": 0.005946579999999813, - "q3": 0.006123862999970697, - "iqr_outliers": 9, - "stddev_outliers": 37, - "outliers": "37;9", - "ld15iqr": 0.005840381000041361, - "hd15iqr": 0.00639868899997964, - "ops": 164.8523223763369, - "total": 1.0554901349996157, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.313039468999989, - "max": 2.316506077999975, - "mean": 2.3150873183999807, - "stddev": 0.0017230283344993676, - "rounds": 5, - "median": 2.3162377389999733, - "iqr": 0.0030427847499652216, - "q1": 2.31329179075, - "q3": 2.3163345754999654, - "iqr_outliers": 0, - "stddev_outliers": 1, - "outliers": "1;0", - "ld15iqr": 2.313039468999989, - "hd15iqr": 2.316506077999975, - "ops": 0.4319491502770302, - "total": 11.575436591999903, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T10:14:47.220255", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/ifort/x86_64/Linux-CPython-3.11-64bit/0003_904f83215f95337ba21fba3555ed7382b4554eef_20240423_102839.json b/.benchmarks/github/ifort/x86_64/Linux-CPython-3.11-64bit/0003_904f83215f95337ba21fba3555ed7382b4554eef_20240423_102839.json deleted file mode 100644 index 79c92ef..0000000 --- a/.benchmarks/github/ifort/x86_64/Linux-CPython-3.11-64bit/0003_904f83215f95337ba21fba3555ed7382b4554eef_20240423_102839.json +++ /dev/null @@ -1,240 +0,0 @@ -{ - "machine_info": { - "node": "fv-az975-714", - "processor": "x86_64", - "machine": "x86_64", - "python_compiler": "GCC 11.4.0", - "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", - "python_build": [ - "main", - "Apr 2 2024 15:19:53" - ], - "release": "6.5.0-1018-azure", - "system": "Linux", - "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "X86_64", - "bits": 64, - "count": 4, - "arch_string_raw": "x86_64", - "vendor_id_raw": "AuthenticAMD", - "brand_raw": "AMD EPYC 7763 64-Core Processor", - "hz_advertised_friendly": "3.2422 GHz", - "hz_actual_friendly": "3.2422 GHz", - "hz_advertised": [ - 3242178000, - 0 - ], - "hz_actual": [ - 3242178000, - 0 - ], - "stepping": 1, - "model": 1, - "family": 25, - "flags": [ - "3dnowext", - "3dnowprefetch", - "abm", - "adx", - "aes", - "aperfmperf", - "apic", - "arat", - "avx", - "avx2", - "bmi1", - "bmi2", - "clflush", - "clflushopt", - "clwb", - "clzero", - "cmov", - "cmp_legacy", - "constant_tsc", - "cpuid", - "cr8_legacy", - "cx16", - "cx8", - "de", - "decodeassists", - "erms", - "extd_apicid", - "f16c", - "flushbyasid", - "fma", - "fpu", - "fsgsbase", - "fsrm", - "fxsr", - "fxsr_opt", - "ht", - "hypervisor", - "invpcid", - "invpcid_single", - "lahf_lm", - "lm", - "mca", - "mce", - "misalignsse", - "mmx", - "mmxext", - "movbe", - "msr", - "mtrr", - "nonstop_tsc", - "nopl", - "npt", - "nrip_save", - "nx", - "osvw", - "osxsave", - "pae", - "pat", - "pausefilter", - "pcid", - "pclmulqdq", - "pdpe1gb", - "pfthreshold", - "pge", - "pni", - "popcnt", - "pse", - "pse36", - "rdpid", - "rdpru", - "rdrand", - "rdrnd", - "rdseed", - "rdtscp", - "rep_good", - "sep", - "sha", - "sha_ni", - "smap", - "smep", - "sse", - "sse2", - "sse4_1", - "sse4_2", - "sse4a", - "ssse3", - "svm", - "syscall", - "topoext", - "tsc", - "tsc_reliable", - "tsc_scale", - "umip", - "v_vmsave_vmload", - "vaes", - "vmcb_clean", - "vme", - "vmmcall", - "vpclmulqdq", - "xgetbv1", - "xsave", - "xsavec", - "xsaveerptr", - "xsaveopt", - "xsaves" - ], - "l3_cache_size": 524288, - "l2_cache_size": 1048576, - "l1_data_cache_size": 65536, - "l1_instruction_cache_size": 65536, - "l2_cache_line_size": 512, - "l2_cache_associativity": 6 - } - }, - "commit_info": { - "id": "904f83215f95337ba21fba3555ed7382b4554eef", - "time": "2024-04-23T12:23:40+02:00", - "author_time": "2024-04-23T12:23:40+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__mol_tpcr__molecule_PPH3_Z", - "fullname": "tests/functional_tests/cfml/test__Molecules.py::test__mol_tpcr__molecule_PPH3_Z", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 0.005848906000039733, - "max": 0.024348943000006784, - "mean": 0.006285209402367185, - "stddev": 0.0016144936771758911, - "rounds": 169, - "median": 0.006087080999975569, - "iqr": 0.00019531624997171093, - "q1": 0.005993140500009986, - "q3": 0.006188456749981697, - "iqr_outliers": 9, - "stddev_outliers": 3, - "outliers": "3;9", - "ld15iqr": 0.005848906000039733, - "hd15iqr": 0.006511293000016849, - "ops": 159.10368867318442, - "total": 1.0622003890000542, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.3176255380000157, - "max": 2.3391646280000487, - "mean": 2.3229624060000105, - "stddev": 0.009093638228711393, - "rounds": 5, - "median": 2.319242509999981, - "iqr": 0.006069252500026323, - "q1": 2.3186064022499977, - "q3": 2.324675654750024, - "iqr_outliers": 1, - "stddev_outliers": 1, - "outliers": "1;1", - "ld15iqr": 2.3176255380000157, - "hd15iqr": 2.3391646280000487, - "ops": 0.4304847970923191, - "total": 11.614812030000053, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T10:29:15.615463", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/ifort/x86_64/Linux-CPython-3.11-64bit/0004_a35d0b5acf769d4a68794b33d6952117b5ae4ecb_20240423_103518.json b/.benchmarks/github/ifort/x86_64/Linux-CPython-3.11-64bit/0004_a35d0b5acf769d4a68794b33d6952117b5ae4ecb_20240423_103518.json deleted file mode 100644 index 669d21f..0000000 --- a/.benchmarks/github/ifort/x86_64/Linux-CPython-3.11-64bit/0004_a35d0b5acf769d4a68794b33d6952117b5ae4ecb_20240423_103518.json +++ /dev/null @@ -1,240 +0,0 @@ -{ - "machine_info": { - "node": "fv-az1385-776", - "processor": "x86_64", - "machine": "x86_64", - "python_compiler": "GCC 11.4.0", - "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", - "python_build": [ - "main", - "Apr 2 2024 15:19:53" - ], - "release": "6.5.0-1018-azure", - "system": "Linux", - "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "X86_64", - "bits": 64, - "count": 4, - "arch_string_raw": "x86_64", - "vendor_id_raw": "AuthenticAMD", - "brand_raw": "AMD EPYC 7763 64-Core Processor", - "hz_advertised_friendly": "2.6056 GHz", - "hz_actual_friendly": "2.6056 GHz", - "hz_advertised": [ - 2605587000, - 0 - ], - "hz_actual": [ - 2605587000, - 0 - ], - "stepping": 1, - "model": 1, - "family": 25, - "flags": [ - "3dnowext", - "3dnowprefetch", - "abm", - "adx", - "aes", - "aperfmperf", - "apic", - "arat", - "avx", - "avx2", - "bmi1", - "bmi2", - "clflush", - "clflushopt", - "clwb", - "clzero", - "cmov", - "cmp_legacy", - "constant_tsc", - "cpuid", - "cr8_legacy", - "cx16", - "cx8", - "de", - "decodeassists", - "erms", - "extd_apicid", - "f16c", - "flushbyasid", - "fma", - "fpu", - "fsgsbase", - "fsrm", - "fxsr", - "fxsr_opt", - "ht", - "hypervisor", - "invpcid", - "invpcid_single", - "lahf_lm", - "lm", - "mca", - "mce", - "misalignsse", - "mmx", - "mmxext", - "movbe", - "msr", - "mtrr", - "nonstop_tsc", - "nopl", - "npt", - "nrip_save", - "nx", - "osvw", - "osxsave", - "pae", - "pat", - "pausefilter", - "pcid", - "pclmulqdq", - "pdpe1gb", - "pfthreshold", - "pge", - "pni", - "popcnt", - "pse", - "pse36", - "rdpid", - "rdpru", - "rdrand", - "rdrnd", - "rdseed", - "rdtscp", - "rep_good", - "sep", - "sha", - "sha_ni", - "smap", - "smep", - "sse", - "sse2", - "sse4_1", - "sse4_2", - "sse4a", - "ssse3", - "svm", - "syscall", - "topoext", - "tsc", - "tsc_reliable", - "tsc_scale", - "umip", - "v_vmsave_vmload", - "vaes", - "vmcb_clean", - "vme", - "vmmcall", - "vpclmulqdq", - "xgetbv1", - "xsave", - "xsavec", - "xsaveerptr", - "xsaveopt", - "xsaves" - ], - "l3_cache_size": 524288, - "l2_cache_size": 1048576, - "l1_data_cache_size": 65536, - "l1_instruction_cache_size": 65536, - "l2_cache_line_size": 512, - "l2_cache_associativity": 6 - } - }, - "commit_info": { - "id": "a35d0b5acf769d4a68794b33d6952117b5ae4ecb", - "time": "2024-04-23T12:30:14+02:00", - "author_time": "2024-04-23T12:30:14+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__mol_tpcr__molecule_PPH3_Z", - "fullname": "tests/functional_tests/cfml/test__Molecules.py::test__mol_tpcr__molecule_PPH3_Z", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 0.00582490599998664, - "max": 0.0064422629999967285, - "mean": 0.006020273705203338, - "stddev": 0.00011710375803644879, - "rounds": 173, - "median": 0.006008049000001847, - "iqr": 0.0001784142500298458, - "q1": 0.0059216619999915565, - "q3": 0.006100076250021402, - "iqr_outliers": 2, - "stddev_outliers": 56, - "outliers": "56;2", - "ld15iqr": 0.00582490599998664, - "hd15iqr": 0.006414747999997417, - "ops": 166.10540466552166, - "total": 1.0415073510001776, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.314867423999999, - "max": 2.3203665539999747, - "mean": 2.3169215010000017, - "stddev": 0.002063733937573201, - "rounds": 5, - "median": 2.3164991770000256, - "iqr": 0.0019565694999670313, - "q1": 2.3157538437500165, - "q3": 2.3177104132499835, - "iqr_outliers": 0, - "stddev_outliers": 1, - "outliers": "1;0", - "ld15iqr": 2.314867423999999, - "hd15iqr": 2.3203665539999747, - "ops": 0.43160719928076635, - "total": 11.584607505000008, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T10:35:53.995794", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/ifort/x86_64/Linux-CPython-3.11-64bit/0005_774a8273e467cce7cc73ef3fc80f580cef85088a_20240423_104734.json b/.benchmarks/github/ifort/x86_64/Linux-CPython-3.11-64bit/0005_774a8273e467cce7cc73ef3fc80f580cef85088a_20240423_104734.json deleted file mode 100644 index 4f2f570..0000000 --- a/.benchmarks/github/ifort/x86_64/Linux-CPython-3.11-64bit/0005_774a8273e467cce7cc73ef3fc80f580cef85088a_20240423_104734.json +++ /dev/null @@ -1,240 +0,0 @@ -{ - "machine_info": { - "node": "fv-az529-904", - "processor": "x86_64", - "machine": "x86_64", - "python_compiler": "GCC 11.4.0", - "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", - "python_build": [ - "main", - "Apr 2 2024 15:19:53" - ], - "release": "6.5.0-1018-azure", - "system": "Linux", - "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "X86_64", - "bits": 64, - "count": 4, - "arch_string_raw": "x86_64", - "vendor_id_raw": "AuthenticAMD", - "brand_raw": "AMD EPYC 7763 64-Core Processor", - "hz_advertised_friendly": "2.4454 GHz", - "hz_actual_friendly": "2.4454 GHz", - "hz_advertised": [ - 2445427000, - 0 - ], - "hz_actual": [ - 2445427000, - 0 - ], - "stepping": 1, - "model": 1, - "family": 25, - "flags": [ - "3dnowext", - "3dnowprefetch", - "abm", - "adx", - "aes", - "aperfmperf", - "apic", - "arat", - "avx", - "avx2", - "bmi1", - "bmi2", - "clflush", - "clflushopt", - "clwb", - "clzero", - "cmov", - "cmp_legacy", - "constant_tsc", - "cpuid", - "cr8_legacy", - "cx16", - "cx8", - "de", - "decodeassists", - "erms", - "extd_apicid", - "f16c", - "flushbyasid", - "fma", - "fpu", - "fsgsbase", - "fsrm", - "fxsr", - "fxsr_opt", - "ht", - "hypervisor", - "invpcid", - "invpcid_single", - "lahf_lm", - "lm", - "mca", - "mce", - "misalignsse", - "mmx", - "mmxext", - "movbe", - "msr", - "mtrr", - "nonstop_tsc", - "nopl", - "npt", - "nrip_save", - "nx", - "osvw", - "osxsave", - "pae", - "pat", - "pausefilter", - "pcid", - "pclmulqdq", - "pdpe1gb", - "pfthreshold", - "pge", - "pni", - "popcnt", - "pse", - "pse36", - "rdpid", - "rdpru", - "rdrand", - "rdrnd", - "rdseed", - "rdtscp", - "rep_good", - "sep", - "sha", - "sha_ni", - "smap", - "smep", - "sse", - "sse2", - "sse4_1", - "sse4_2", - "sse4a", - "ssse3", - "svm", - "syscall", - "topoext", - "tsc", - "tsc_reliable", - "tsc_scale", - "umip", - "v_vmsave_vmload", - "vaes", - "vmcb_clean", - "vme", - "vmmcall", - "vpclmulqdq", - "xgetbv1", - "xsave", - "xsavec", - "xsaveerptr", - "xsaveopt", - "xsaves" - ], - "l3_cache_size": 524288, - "l2_cache_size": 1048576, - "l1_data_cache_size": 65536, - "l1_instruction_cache_size": 65536, - "l2_cache_line_size": 512, - "l2_cache_associativity": 6 - } - }, - "commit_info": { - "id": "774a8273e467cce7cc73ef3fc80f580cef85088a", - "time": "2024-04-23T12:42:42+02:00", - "author_time": "2024-04-23T12:42:42+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.312082857000007, - "max": 2.317411708999998, - "mean": 2.314252469400003, - "stddev": 0.0019377666290283113, - "rounds": 5, - "median": 2.3139170200000194, - "iqr": 0.0014090257499930203, - "q1": 2.3134263432500006, - "q3": 2.3148353689999936, - "iqr_outliers": 1, - "stddev_outliers": 2, - "outliers": "2;1", - "ld15iqr": 2.312082857000007, - "hd15iqr": 2.317411708999998, - "ops": 0.4321049726520381, - "total": 11.571262347000015, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__ponsin", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__ponsin", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 3.0712561349999987, - "max": 3.0820094939999763, - "mean": 3.0774823949999925, - "stddev": 0.004312904580930364, - "rounds": 5, - "median": 3.077342858999998, - "iqr": 0.006575882999996452, - "q1": 3.074671569749995, - "q3": 3.0812474527499916, - "iqr_outliers": 0, - "stddev_outliers": 2, - "outliers": "2;0", - "ld15iqr": 3.0712561349999987, - "hd15iqr": 3.0820094939999763, - "ops": 0.3249409327652717, - "total": 15.387411974999964, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T10:48:46.809430", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/ifort/x86_64/Linux-CPython-3.11-64bit/0006_2e27ea3e143b990c623b2de4195dbfc5fd3068c8_20240423_114640.json b/.benchmarks/github/ifort/x86_64/Linux-CPython-3.11-64bit/0006_2e27ea3e143b990c623b2de4195dbfc5fd3068c8_20240423_114640.json deleted file mode 100644 index 6672247..0000000 --- a/.benchmarks/github/ifort/x86_64/Linux-CPython-3.11-64bit/0006_2e27ea3e143b990c623b2de4195dbfc5fd3068c8_20240423_114640.json +++ /dev/null @@ -1,240 +0,0 @@ -{ - "machine_info": { - "node": "fv-az1106-393", - "processor": "x86_64", - "machine": "x86_64", - "python_compiler": "GCC 11.4.0", - "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", - "python_build": [ - "main", - "Apr 2 2024 15:19:53" - ], - "release": "6.5.0-1018-azure", - "system": "Linux", - "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "X86_64", - "bits": 64, - "count": 4, - "arch_string_raw": "x86_64", - "vendor_id_raw": "AuthenticAMD", - "brand_raw": "AMD EPYC 7763 64-Core Processor", - "hz_advertised_friendly": "2.4454 GHz", - "hz_actual_friendly": "2.4454 GHz", - "hz_advertised": [ - 2445426000, - 0 - ], - "hz_actual": [ - 2445426000, - 0 - ], - "stepping": 1, - "model": 1, - "family": 25, - "flags": [ - "3dnowext", - "3dnowprefetch", - "abm", - "adx", - "aes", - "aperfmperf", - "apic", - "arat", - "avx", - "avx2", - "bmi1", - "bmi2", - "clflush", - "clflushopt", - "clwb", - "clzero", - "cmov", - "cmp_legacy", - "constant_tsc", - "cpuid", - "cr8_legacy", - "cx16", - "cx8", - "de", - "decodeassists", - "erms", - "extd_apicid", - "f16c", - "flushbyasid", - "fma", - "fpu", - "fsgsbase", - "fsrm", - "fxsr", - "fxsr_opt", - "ht", - "hypervisor", - "invpcid", - "invpcid_single", - "lahf_lm", - "lm", - "mca", - "mce", - "misalignsse", - "mmx", - "mmxext", - "movbe", - "msr", - "mtrr", - "nonstop_tsc", - "nopl", - "npt", - "nrip_save", - "nx", - "osvw", - "osxsave", - "pae", - "pat", - "pausefilter", - "pcid", - "pclmulqdq", - "pdpe1gb", - "pfthreshold", - "pge", - "pni", - "popcnt", - "pse", - "pse36", - "rdpid", - "rdpru", - "rdrand", - "rdrnd", - "rdseed", - "rdtscp", - "rep_good", - "sep", - "sha", - "sha_ni", - "smap", - "smep", - "sse", - "sse2", - "sse4_1", - "sse4_2", - "sse4a", - "ssse3", - "svm", - "syscall", - "topoext", - "tsc", - "tsc_reliable", - "tsc_scale", - "umip", - "v_vmsave_vmload", - "vaes", - "vmcb_clean", - "vme", - "vmmcall", - "vpclmulqdq", - "xgetbv1", - "xsave", - "xsavec", - "xsaveerptr", - "xsaveopt", - "xsaves" - ], - "l3_cache_size": 524288, - "l2_cache_size": 1048576, - "l1_data_cache_size": 65536, - "l1_instruction_cache_size": 65536, - "l2_cache_line_size": 512, - "l2_cache_associativity": 6 - } - }, - "commit_info": { - "id": "2e27ea3e143b990c623b2de4195dbfc5fd3068c8", - "time": "2024-04-23T13:41:53+02:00", - "author_time": "2024-04-23T13:41:53+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.3103676630000223, - "max": 2.3148996950000083, - "mean": 2.3123986636000153, - "stddev": 0.001885256052146363, - "rounds": 5, - "median": 2.312499196000033, - "iqr": 0.003163212999950815, - "q1": 2.3106618497500335, - "q3": 2.3138250627499843, - "iqr_outliers": 0, - "stddev_outliers": 2, - "outliers": "2;0", - "ld15iqr": 2.3103676630000223, - "hd15iqr": 2.3148996950000083, - "ops": 0.4324513829475962, - "total": 11.561993318000077, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__ponsin", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__ponsin", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 3.0744556779999925, - "max": 3.0836341079999556, - "mean": 3.0786380453999755, - "stddev": 0.004538341996340446, - "rounds": 5, - "median": 3.0765499729999988, - "iqr": 0.008548122499988153, - "q1": 3.0749435874999733, - "q3": 3.0834917099999615, - "iqr_outliers": 0, - "stddev_outliers": 2, - "outliers": "2;0", - "ld15iqr": 3.0744556779999925, - "hd15iqr": 3.0836341079999556, - "ops": 0.3248189573614135, - "total": 15.393190226999877, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T11:47:52.557966", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/ifx/x86_64/Linux-CPython-3.11-64bit/0001_85b81446abfdc74949b15b099d367c6498146221_20240423_100332.json b/.benchmarks/github/ifx/x86_64/Linux-CPython-3.11-64bit/0001_85b81446abfdc74949b15b099d367c6498146221_20240423_100332.json deleted file mode 100644 index 798ef93..0000000 --- a/.benchmarks/github/ifx/x86_64/Linux-CPython-3.11-64bit/0001_85b81446abfdc74949b15b099d367c6498146221_20240423_100332.json +++ /dev/null @@ -1,240 +0,0 @@ -{ - "machine_info": { - "node": "fv-az1052-509", - "processor": "x86_64", - "machine": "x86_64", - "python_compiler": "GCC 11.4.0", - "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", - "python_build": [ - "main", - "Apr 2 2024 15:19:53" - ], - "release": "6.5.0-1018-azure", - "system": "Linux", - "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "X86_64", - "bits": 64, - "count": 4, - "arch_string_raw": "x86_64", - "vendor_id_raw": "AuthenticAMD", - "brand_raw": "AMD EPYC 7763 64-Core Processor", - "hz_advertised_friendly": "2.3358 GHz", - "hz_actual_friendly": "2.3358 GHz", - "hz_advertised": [ - 2335763000, - 0 - ], - "hz_actual": [ - 2335763000, - 0 - ], - "stepping": 1, - "model": 1, - "family": 25, - "flags": [ - "3dnowext", - "3dnowprefetch", - "abm", - "adx", - "aes", - "aperfmperf", - "apic", - "arat", - "avx", - "avx2", - "bmi1", - "bmi2", - "clflush", - "clflushopt", - "clwb", - "clzero", - "cmov", - "cmp_legacy", - "constant_tsc", - "cpuid", - "cr8_legacy", - "cx16", - "cx8", - "de", - "decodeassists", - "erms", - "extd_apicid", - "f16c", - "flushbyasid", - "fma", - "fpu", - "fsgsbase", - "fsrm", - "fxsr", - "fxsr_opt", - "ht", - "hypervisor", - "invpcid", - "invpcid_single", - "lahf_lm", - "lm", - "mca", - "mce", - "misalignsse", - "mmx", - "mmxext", - "movbe", - "msr", - "mtrr", - "nonstop_tsc", - "nopl", - "npt", - "nrip_save", - "nx", - "osvw", - "osxsave", - "pae", - "pat", - "pausefilter", - "pcid", - "pclmulqdq", - "pdpe1gb", - "pfthreshold", - "pge", - "pni", - "popcnt", - "pse", - "pse36", - "rdpid", - "rdpru", - "rdrand", - "rdrnd", - "rdseed", - "rdtscp", - "rep_good", - "sep", - "sha", - "sha_ni", - "smap", - "smep", - "sse", - "sse2", - "sse4_1", - "sse4_2", - "sse4a", - "ssse3", - "svm", - "syscall", - "topoext", - "tsc", - "tsc_reliable", - "tsc_scale", - "umip", - "v_vmsave_vmload", - "vaes", - "vmcb_clean", - "vme", - "vmmcall", - "vpclmulqdq", - "xgetbv1", - "xsave", - "xsavec", - "xsaveerptr", - "xsaveopt", - "xsaves" - ], - "l3_cache_size": 524288, - "l2_cache_size": 1048576, - "l1_data_cache_size": 65536, - "l1_instruction_cache_size": 65536, - "l2_cache_line_size": 512, - "l2_cache_associativity": 6 - } - }, - "commit_info": { - "id": "85b81446abfdc74949b15b099d367c6498146221", - "time": "2024-04-23T11:58:35+02:00", - "author_time": "2024-04-23T11:58:35+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__mol_tpcr__molecule_PPH3_Z", - "fullname": "tests/functional_tests/cfml/test__Molecules.py::test__mol_tpcr__molecule_PPH3_Z", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 0.007241378999992776, - "max": 0.008139147000008506, - "mean": 0.007533027123190797, - "stddev": 0.00012997932630134826, - "rounds": 138, - "median": 0.00750772649999476, - "iqr": 0.00014357999998537707, - "q1": 0.007445012000005136, - "q3": 0.007588591999990513, - "iqr_outliers": 5, - "stddev_outliers": 35, - "outliers": "35;5", - "ld15iqr": 0.007241378999992776, - "hd15iqr": 0.007856225000011818, - "ops": 132.74875871898172, - "total": 1.03955774300033, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.3905797099999972, - "max": 2.402486103000001, - "mean": 2.3954127801999903, - "stddev": 0.004843203346599224, - "rounds": 5, - "median": 2.393822325999963, - "iqr": 0.007438354250012935, - "q1": 2.3917299602499895, - "q3": 2.3991683145000025, - "iqr_outliers": 0, - "stddev_outliers": 1, - "outliers": "1;0", - "ld15iqr": 2.3905797099999972, - "hd15iqr": 2.402486103000001, - "ops": 0.4174645840858005, - "total": 11.977063900999951, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T10:04:09.304192", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/ifx/x86_64/Linux-CPython-3.11-64bit/0003_53c48b1cb9568e544b39d995840c186ee18b16f8_20240423_102756.json b/.benchmarks/github/ifx/x86_64/Linux-CPython-3.11-64bit/0003_53c48b1cb9568e544b39d995840c186ee18b16f8_20240423_102756.json deleted file mode 100644 index 0c9beec..0000000 --- a/.benchmarks/github/ifx/x86_64/Linux-CPython-3.11-64bit/0003_53c48b1cb9568e544b39d995840c186ee18b16f8_20240423_102756.json +++ /dev/null @@ -1,240 +0,0 @@ -{ - "machine_info": { - "node": "fv-az1208-789", - "processor": "x86_64", - "machine": "x86_64", - "python_compiler": "GCC 11.4.0", - "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", - "python_build": [ - "main", - "Apr 2 2024 15:19:53" - ], - "release": "6.5.0-1018-azure", - "system": "Linux", - "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "X86_64", - "bits": 64, - "count": 4, - "arch_string_raw": "x86_64", - "vendor_id_raw": "AuthenticAMD", - "brand_raw": "AMD EPYC 7763 64-Core Processor", - "hz_advertised_friendly": "3.2422 GHz", - "hz_actual_friendly": "3.2422 GHz", - "hz_advertised": [ - 3242201000, - 0 - ], - "hz_actual": [ - 3242201000, - 0 - ], - "stepping": 1, - "model": 1, - "family": 25, - "flags": [ - "3dnowext", - "3dnowprefetch", - "abm", - "adx", - "aes", - "aperfmperf", - "apic", - "arat", - "avx", - "avx2", - "bmi1", - "bmi2", - "clflush", - "clflushopt", - "clwb", - "clzero", - "cmov", - "cmp_legacy", - "constant_tsc", - "cpuid", - "cr8_legacy", - "cx16", - "cx8", - "de", - "decodeassists", - "erms", - "extd_apicid", - "f16c", - "flushbyasid", - "fma", - "fpu", - "fsgsbase", - "fsrm", - "fxsr", - "fxsr_opt", - "ht", - "hypervisor", - "invpcid", - "invpcid_single", - "lahf_lm", - "lm", - "mca", - "mce", - "misalignsse", - "mmx", - "mmxext", - "movbe", - "msr", - "mtrr", - "nonstop_tsc", - "nopl", - "npt", - "nrip_save", - "nx", - "osvw", - "osxsave", - "pae", - "pat", - "pausefilter", - "pcid", - "pclmulqdq", - "pdpe1gb", - "pfthreshold", - "pge", - "pni", - "popcnt", - "pse", - "pse36", - "rdpid", - "rdpru", - "rdrand", - "rdrnd", - "rdseed", - "rdtscp", - "rep_good", - "sep", - "sha", - "sha_ni", - "smap", - "smep", - "sse", - "sse2", - "sse4_1", - "sse4_2", - "sse4a", - "ssse3", - "svm", - "syscall", - "topoext", - "tsc", - "tsc_reliable", - "tsc_scale", - "umip", - "v_vmsave_vmload", - "vaes", - "vmcb_clean", - "vme", - "vmmcall", - "vpclmulqdq", - "xgetbv1", - "xsave", - "xsavec", - "xsaveerptr", - "xsaveopt", - "xsaves" - ], - "l3_cache_size": 524288, - "l2_cache_size": 1048576, - "l1_data_cache_size": 65536, - "l1_instruction_cache_size": 65536, - "l2_cache_line_size": 512, - "l2_cache_associativity": 6 - } - }, - "commit_info": { - "id": "53c48b1cb9568e544b39d995840c186ee18b16f8", - "time": "2024-04-23T12:23:31+02:00", - "author_time": "2024-04-23T12:23:31+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__mol_tpcr__molecule_PPH3_Z", - "fullname": "tests/functional_tests/cfml/test__Molecules.py::test__mol_tpcr__molecule_PPH3_Z", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 0.006288030999996863, - "max": 0.007656974000042283, - "mean": 0.006641144563291797, - "stddev": 0.0002062711939204249, - "rounds": 158, - "median": 0.006611785499984535, - "iqr": 0.00022403799999892726, - "q1": 0.006501570000011725, - "q3": 0.006725608000010652, - "iqr_outliers": 7, - "stddev_outliers": 40, - "outliers": "40;7", - "ld15iqr": 0.006288030999996863, - "hd15iqr": 0.007092239000030531, - "ops": 150.57645417438903, - "total": 1.049300841000104, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.3357954290000293, - "max": 2.364725539999995, - "mean": 2.3425712070000144, - "stddev": 0.01242182838711131, - "rounds": 5, - "median": 2.3371443569999997, - "iqr": 0.008537064999970312, - "q1": 2.336493104500036, - "q3": 2.3450301695000064, - "iqr_outliers": 1, - "stddev_outliers": 1, - "outliers": "1;1", - "ld15iqr": 2.3357954290000293, - "hd15iqr": 2.364725539999995, - "ops": 0.42688136736754223, - "total": 11.712856035000073, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T10:28:31.913345", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/ifx/x86_64/Linux-CPython-3.11-64bit/0003_904f83215f95337ba21fba3555ed7382b4554eef_20240423_102831.json b/.benchmarks/github/ifx/x86_64/Linux-CPython-3.11-64bit/0003_904f83215f95337ba21fba3555ed7382b4554eef_20240423_102831.json deleted file mode 100644 index 2bc0d66..0000000 --- a/.benchmarks/github/ifx/x86_64/Linux-CPython-3.11-64bit/0003_904f83215f95337ba21fba3555ed7382b4554eef_20240423_102831.json +++ /dev/null @@ -1,240 +0,0 @@ -{ - "machine_info": { - "node": "fv-az566-74", - "processor": "x86_64", - "machine": "x86_64", - "python_compiler": "GCC 11.4.0", - "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", - "python_build": [ - "main", - "Apr 2 2024 15:19:53" - ], - "release": "6.5.0-1018-azure", - "system": "Linux", - "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "X86_64", - "bits": 64, - "count": 4, - "arch_string_raw": "x86_64", - "vendor_id_raw": "AuthenticAMD", - "brand_raw": "AMD EPYC 7763 64-Core Processor", - "hz_advertised_friendly": "2.6008 GHz", - "hz_actual_friendly": "2.6008 GHz", - "hz_advertised": [ - 2600845000, - 0 - ], - "hz_actual": [ - 2600845000, - 0 - ], - "stepping": 1, - "model": 1, - "family": 25, - "flags": [ - "3dnowext", - "3dnowprefetch", - "abm", - "adx", - "aes", - "aperfmperf", - "apic", - "arat", - "avx", - "avx2", - "bmi1", - "bmi2", - "clflush", - "clflushopt", - "clwb", - "clzero", - "cmov", - "cmp_legacy", - "constant_tsc", - "cpuid", - "cr8_legacy", - "cx16", - "cx8", - "de", - "decodeassists", - "erms", - "extd_apicid", - "f16c", - "flushbyasid", - "fma", - "fpu", - "fsgsbase", - "fsrm", - "fxsr", - "fxsr_opt", - "ht", - "hypervisor", - "invpcid", - "invpcid_single", - "lahf_lm", - "lm", - "mca", - "mce", - "misalignsse", - "mmx", - "mmxext", - "movbe", - "msr", - "mtrr", - "nonstop_tsc", - "nopl", - "npt", - "nrip_save", - "nx", - "osvw", - "osxsave", - "pae", - "pat", - "pausefilter", - "pcid", - "pclmulqdq", - "pdpe1gb", - "pfthreshold", - "pge", - "pni", - "popcnt", - "pse", - "pse36", - "rdpid", - "rdpru", - "rdrand", - "rdrnd", - "rdseed", - "rdtscp", - "rep_good", - "sep", - "sha", - "sha_ni", - "smap", - "smep", - "sse", - "sse2", - "sse4_1", - "sse4_2", - "sse4a", - "ssse3", - "svm", - "syscall", - "topoext", - "tsc", - "tsc_reliable", - "tsc_scale", - "umip", - "v_vmsave_vmload", - "vaes", - "vmcb_clean", - "vme", - "vmmcall", - "vpclmulqdq", - "xgetbv1", - "xsave", - "xsavec", - "xsaveerptr", - "xsaveopt", - "xsaves" - ], - "l3_cache_size": 524288, - "l2_cache_size": 1048576, - "l1_data_cache_size": 65536, - "l1_instruction_cache_size": 65536, - "l2_cache_line_size": 512, - "l2_cache_associativity": 6 - } - }, - "commit_info": { - "id": "904f83215f95337ba21fba3555ed7382b4554eef", - "time": "2024-04-23T12:23:40+02:00", - "author_time": "2024-04-23T12:23:40+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__mol_tpcr__molecule_PPH3_Z", - "fullname": "tests/functional_tests/cfml/test__Molecules.py::test__mol_tpcr__molecule_PPH3_Z", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 0.0067336540000155765, - "max": 0.0077128670000092825, - "mean": 0.007086543226667269, - "stddev": 0.00017684103640646084, - "rounds": 150, - "median": 0.007071773000006942, - "iqr": 0.0002295360000061919, - "q1": 0.006957510999995975, - "q3": 0.007187047000002167, - "iqr_outliers": 3, - "stddev_outliers": 49, - "outliers": "49;3", - "ld15iqr": 0.0067336540000155765, - "hd15iqr": 0.0075545500000089305, - "ops": 141.11252383770332, - "total": 1.0629814840000904, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.3388390110000046, - "max": 2.342521440999974, - "mean": 2.340400914399993, - "stddev": 0.0014785572825178406, - "rounds": 5, - "median": 2.340216006999981, - "iqr": 0.002305298749973872, - "q1": 2.3391779495000122, - "q3": 2.341483248249986, - "iqr_outliers": 0, - "stddev_outliers": 2, - "outliers": "2;0", - "ld15iqr": 2.3388390110000046, - "hd15iqr": 2.342521440999974, - "ops": 0.42727722154234815, - "total": 11.702004571999964, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T10:29:07.028051", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/ifx/x86_64/Linux-CPython-3.11-64bit/0004_a35d0b5acf769d4a68794b33d6952117b5ae4ecb_20240423_103507.json b/.benchmarks/github/ifx/x86_64/Linux-CPython-3.11-64bit/0004_a35d0b5acf769d4a68794b33d6952117b5ae4ecb_20240423_103507.json deleted file mode 100644 index 14438b8..0000000 --- a/.benchmarks/github/ifx/x86_64/Linux-CPython-3.11-64bit/0004_a35d0b5acf769d4a68794b33d6952117b5ae4ecb_20240423_103507.json +++ /dev/null @@ -1,240 +0,0 @@ -{ - "machine_info": { - "node": "fv-az693-392", - "processor": "x86_64", - "machine": "x86_64", - "python_compiler": "GCC 11.4.0", - "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", - "python_build": [ - "main", - "Apr 2 2024 15:19:53" - ], - "release": "6.5.0-1018-azure", - "system": "Linux", - "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "X86_64", - "bits": 64, - "count": 4, - "arch_string_raw": "x86_64", - "vendor_id_raw": "AuthenticAMD", - "brand_raw": "AMD EPYC 7763 64-Core Processor", - "hz_advertised_friendly": "3.0846 GHz", - "hz_actual_friendly": "3.0846 GHz", - "hz_advertised": [ - 3084644000, - 0 - ], - "hz_actual": [ - 3084644000, - 0 - ], - "stepping": 1, - "model": 1, - "family": 25, - "flags": [ - "3dnowext", - "3dnowprefetch", - "abm", - "adx", - "aes", - "aperfmperf", - "apic", - "arat", - "avx", - "avx2", - "bmi1", - "bmi2", - "clflush", - "clflushopt", - "clwb", - "clzero", - "cmov", - "cmp_legacy", - "constant_tsc", - "cpuid", - "cr8_legacy", - "cx16", - "cx8", - "de", - "decodeassists", - "erms", - "extd_apicid", - "f16c", - "flushbyasid", - "fma", - "fpu", - "fsgsbase", - "fsrm", - "fxsr", - "fxsr_opt", - "ht", - "hypervisor", - "invpcid", - "invpcid_single", - "lahf_lm", - "lm", - "mca", - "mce", - "misalignsse", - "mmx", - "mmxext", - "movbe", - "msr", - "mtrr", - "nonstop_tsc", - "nopl", - "npt", - "nrip_save", - "nx", - "osvw", - "osxsave", - "pae", - "pat", - "pausefilter", - "pcid", - "pclmulqdq", - "pdpe1gb", - "pfthreshold", - "pge", - "pni", - "popcnt", - "pse", - "pse36", - "rdpid", - "rdpru", - "rdrand", - "rdrnd", - "rdseed", - "rdtscp", - "rep_good", - "sep", - "sha", - "sha_ni", - "smap", - "smep", - "sse", - "sse2", - "sse4_1", - "sse4_2", - "sse4a", - "ssse3", - "svm", - "syscall", - "topoext", - "tsc", - "tsc_reliable", - "tsc_scale", - "umip", - "v_vmsave_vmload", - "vaes", - "vmcb_clean", - "vme", - "vmmcall", - "vpclmulqdq", - "xgetbv1", - "xsave", - "xsavec", - "xsaveerptr", - "xsaveopt", - "xsaves" - ], - "l3_cache_size": 524288, - "l2_cache_size": 1048576, - "l1_data_cache_size": 65536, - "l1_instruction_cache_size": 65536, - "l2_cache_line_size": 512, - "l2_cache_associativity": 6 - } - }, - "commit_info": { - "id": "a35d0b5acf769d4a68794b33d6952117b5ae4ecb", - "time": "2024-04-23T12:30:14+02:00", - "author_time": "2024-04-23T12:30:14+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__mol_tpcr__molecule_PPH3_Z", - "fullname": "tests/functional_tests/cfml/test__Molecules.py::test__mol_tpcr__molecule_PPH3_Z", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 0.00660661000000573, - "max": 0.007696015000021816, - "mean": 0.006888670751634273, - "stddev": 0.00018793342649198663, - "rounds": 153, - "median": 0.006868187999998554, - "iqr": 0.00023049150000531426, - "q1": 0.006754406499979382, - "q3": 0.006984897999984696, - "iqr_outliers": 5, - "stddev_outliers": 38, - "outliers": "38;5", - "ld15iqr": 0.00660661000000573, - "hd15iqr": 0.007360493000021506, - "ops": 145.16588701278246, - "total": 1.0539666250000437, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.3363505300000043, - "max": 2.3388223839999682, - "mean": 2.337817819599991, - "stddev": 0.0009570281689910958, - "rounds": 5, - "median": 2.3381420169999956, - "iqr": 0.0012776432500061219, - "q1": 2.3371731052499882, - "q3": 2.3384507484999943, - "iqr_outliers": 0, - "stddev_outliers": 2, - "outliers": "2;0", - "ld15iqr": 2.3363505300000043, - "hd15iqr": 2.3388223839999682, - "ops": 0.4277493274352335, - "total": 11.689089097999954, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T10:35:43.435141", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/ifx/x86_64/Linux-CPython-3.11-64bit/0005_774a8273e467cce7cc73ef3fc80f580cef85088a_20240423_104708.json b/.benchmarks/github/ifx/x86_64/Linux-CPython-3.11-64bit/0005_774a8273e467cce7cc73ef3fc80f580cef85088a_20240423_104708.json deleted file mode 100644 index dc97bcd..0000000 --- a/.benchmarks/github/ifx/x86_64/Linux-CPython-3.11-64bit/0005_774a8273e467cce7cc73ef3fc80f580cef85088a_20240423_104708.json +++ /dev/null @@ -1,240 +0,0 @@ -{ - "machine_info": { - "node": "fv-az1198-470", - "processor": "x86_64", - "machine": "x86_64", - "python_compiler": "GCC 11.4.0", - "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", - "python_build": [ - "main", - "Apr 2 2024 15:19:53" - ], - "release": "6.5.0-1018-azure", - "system": "Linux", - "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", - "cpuinfo_version": [ - 9, - 0, - 0 - ], - "cpuinfo_version_string": "9.0.0", - "arch": "X86_64", - "bits": 64, - "count": 4, - "arch_string_raw": "x86_64", - "vendor_id_raw": "AuthenticAMD", - "brand_raw": "AMD EPYC 7763 64-Core Processor", - "hz_advertised_friendly": "2.4454 GHz", - "hz_actual_friendly": "2.4454 GHz", - "hz_advertised": [ - 2445428000, - 0 - ], - "hz_actual": [ - 2445428000, - 0 - ], - "stepping": 1, - "model": 1, - "family": 25, - "flags": [ - "3dnowext", - "3dnowprefetch", - "abm", - "adx", - "aes", - "aperfmperf", - "apic", - "arat", - "avx", - "avx2", - "bmi1", - "bmi2", - "clflush", - "clflushopt", - "clwb", - "clzero", - "cmov", - "cmp_legacy", - "constant_tsc", - "cpuid", - "cr8_legacy", - "cx16", - "cx8", - "de", - "decodeassists", - "erms", - "extd_apicid", - "f16c", - "flushbyasid", - "fma", - "fpu", - "fsgsbase", - "fsrm", - "fxsr", - "fxsr_opt", - "ht", - "hypervisor", - "invpcid", - "invpcid_single", - "lahf_lm", - "lm", - "mca", - "mce", - "misalignsse", - "mmx", - "mmxext", - "movbe", - "msr", - "mtrr", - "nonstop_tsc", - "nopl", - "npt", - "nrip_save", - "nx", - "osvw", - "osxsave", - "pae", - "pat", - "pausefilter", - "pcid", - "pclmulqdq", - "pdpe1gb", - "pfthreshold", - "pge", - "pni", - "popcnt", - "pse", - "pse36", - "rdpid", - "rdpru", - "rdrand", - "rdrnd", - "rdseed", - "rdtscp", - "rep_good", - "sep", - "sha", - "sha_ni", - "smap", - "smep", - "sse", - "sse2", - "sse4_1", - "sse4_2", - "sse4a", - "ssse3", - "svm", - "syscall", - "topoext", - "tsc", - "tsc_reliable", - "tsc_scale", - "umip", - "v_vmsave_vmload", - "vaes", - "vmcb_clean", - "vme", - "vmmcall", - "vpclmulqdq", - "xgetbv1", - "xsave", - "xsavec", - "xsaveerptr", - "xsaveopt", - "xsaves" - ], - "l3_cache_size": 524288, - "l2_cache_size": 1048576, - "l1_data_cache_size": 65536, - "l1_instruction_cache_size": 65536, - "l2_cache_line_size": 512, - "l2_cache_associativity": 6 - } - }, - "commit_info": { - "id": "774a8273e467cce7cc73ef3fc80f580cef85088a", - "time": "2024-04-23T12:42:42+02:00", - "author_time": "2024-04-23T12:42:42+02:00", - "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" - }, - "benchmarks": [ - { - "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 2.3265712990000225, - "max": 2.3337157679999905, - "mean": 2.329953698599991, - "stddev": 0.0029565521434948504, - "rounds": 5, - "median": 2.328732036999952, - "iqr": 0.004695513499967774, - "q1": 2.3279691475000135, - "q3": 2.3326646609999813, - "iqr_outliers": 0, - "stddev_outliers": 2, - "outliers": "2;0", - "ld15iqr": 2.3265712990000225, - "hd15iqr": 2.3337157679999905, - "ops": 0.42919307821476205, - "total": 11.649768492999954, - "iterations": 1 - } - }, - { - "group": null, - "name": "test__Simple_calc_powder__ponsin", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__ponsin", - "params": null, - "param": null, - "extra_info": {}, - "options": { - "disable_gc": false, - "timer": "perf_counter", - "min_rounds": 5, - "max_time": 1.0, - "min_time": 5e-06, - "warmup": 100000 - }, - "stats": { - "min": 3.131231033000006, - "max": 3.184225002000005, - "mean": 3.1635865114000126, - "stddev": 0.02496666590917266, - "rounds": 5, - "median": 3.178463708000038, - "iqr": 0.0431393357499843, - "q1": 3.1393671417500144, - "q3": 3.1825064774999987, - "iqr_outliers": 0, - "stddev_outliers": 1, - "outliers": "1;0", - "ld15iqr": 3.131231033000006, - "hd15iqr": 3.184225002000005, - "ops": 0.31609693504397335, - "total": 15.817932557000063, - "iterations": 1 - } - } - ], - "datetime": "2024-04-23T10:48:22.249165", - "version": "4.0.0" -} \ No newline at end of file diff --git a/.benchmarks/github/gfortran/AMD64/Windows-CPython-3.11-64bit/0002_f2feb7460687645f07e2554619af175779f60ea5_20240423_101101.json b/.benchmarks/pyCFML/github/gfortran/AMD64/Windows-CPython-3.10-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130208.json similarity index 63% rename from .benchmarks/github/gfortran/AMD64/Windows-CPython-3.11-64bit/0002_f2feb7460687645f07e2554619af175779f60ea5_20240423_101101.json rename to .benchmarks/pyCFML/github/gfortran/AMD64/Windows-CPython-3.10-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130208.json index 5941d13..adaf01e 100644 --- a/.benchmarks/github/gfortran/AMD64/Windows-CPython-3.11-64bit/0002_f2feb7460687645f07e2554619af175779f60ea5_20240423_101101.json +++ b/.benchmarks/pyCFML/github/gfortran/AMD64/Windows-CPython-3.10-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130208.json @@ -1,20 +1,20 @@ { "machine_info": { - "node": "fv-az1388-0", + "node": "fv-az980-229", "processor": "AMD64 Family 25 Model 1 Stepping 1, AuthenticAMD", "machine": "AMD64", - "python_compiler": "MSC v.1938 64 bit (AMD64)", + "python_compiler": "MSC v.1929 64 bit (AMD64)", "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", + "python_implementation_version": "3.10.11", + "python_version": "3.10.11", "python_build": [ - "tags/v3.11.9:de54cf5", - "Apr 2 2024 10:12:12" + "tags/v3.10.11:7d4cc5a", + "Apr 5 2023 00:38:17" ], "release": "10", "system": "Windows", "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", + "python_version": "3.10.11.final.0 (64 bit)", "cpuinfo_version": [ 9, 0, @@ -121,18 +121,18 @@ } }, "commit_info": { - "id": "f2feb7460687645f07e2554619af175779f60ea5", - "time": "2024-04-23T12:09:18+02:00", - "author_time": "2024-04-23T12:09:18+02:00", + "id": "7a75bcd61ffc8adc6319ef7f554d092f5c20d299", + "time": "2024-07-26T14:52:09+02:00", + "author_time": "2024-07-26T14:51:49+02:00", "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" + "project": "PyCrysFML", + "branch": "test-rpath-macos" }, "benchmarks": [ { "group": null, - "name": "test__mol_tpcr__molecule_PPH3_Z", - "fullname": "tests/functional_tests/cfml/test__Molecules.py::test__mol_tpcr__molecule_PPH3_Z", + "name": "test__compute_pattern__SrTiO3_Pm3m", + "fullname": "tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/test__powder_pattern_from_json.py::test__compute_pattern__SrTiO3_Pm3m", "params": null, "param": null, "extra_info": {}, @@ -145,29 +145,29 @@ "warmup": 100000 }, "stats": { - "min": 0.017859299999997802, - "max": 0.028637399999979607, - "mean": 0.023896954545450006, - "stddev": 0.004859623830049663, - "rounds": 55, - "median": 0.027703900000005888, - "iqr": 0.009822899999974766, - "q1": 0.01816015000001414, - "q3": 0.027983049999988907, - "iqr_outliers": 0, - "stddev_outliers": 21, - "outliers": "21;0", - "ld15iqr": 0.017859299999997802, - "hd15iqr": 0.028637399999979607, - "ops": 41.84633644835721, - "total": 1.3143324999997503, + "min": 0.04298180000000684, + "max": 0.04623870000000352, + "mean": 0.044449083333319095, + "stddev": 0.0006504553693749771, + "rounds": 24, + "median": 0.0443203000000949, + "iqr": 0.0004048499999953492, + "q1": 0.04421924999996918, + "q3": 0.04462409999996453, + "iqr_outliers": 4, + "stddev_outliers": 5, + "outliers": "5;4", + "ld15iqr": 0.0438666000000012, + "hd15iqr": 0.04569250000008651, + "ops": 22.49765180759979, + "total": 1.0667779999996583, "iterations": 1 } }, { "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", + "name": "test__compute_pattern__SrTiO3_Pnma", + "fullname": "tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/test__powder_pattern_from_json.py::test__compute_pattern__SrTiO3_Pnma", "params": null, "param": null, "extra_info": {}, @@ -180,26 +180,26 @@ "warmup": 100000 }, "stats": { - "min": 2.9718222999999853, - "max": 2.989149999999995, - "mean": 2.9819156999999903, - "stddev": 0.007098001943147003, - "rounds": 5, - "median": 2.9833998000000292, - "iqr": 0.011380874999957769, - "q1": 2.976383499999997, - "q3": 2.987764374999955, - "iqr_outliers": 0, + "min": 0.06105240000010781, + "max": 0.06472949999988487, + "mean": 0.06385352499998476, + "stddev": 0.0008124477800167454, + "rounds": 16, + "median": 0.06397819999995136, + "iqr": 0.0005086999998411557, + "q1": 0.06373330000008082, + "q3": 0.06424199999992197, + "iqr_outliers": 1, "stddev_outliers": 2, - "outliers": "2;0", - "ld15iqr": 2.9718222999999853, - "hd15iqr": 2.989149999999995, - "ops": 0.33535488612236863, - "total": 14.909578499999952, + "outliers": "2;1", + "ld15iqr": 0.06359029999998711, + "hd15iqr": 0.06472949999988487, + "ops": 15.660842529840581, + "total": 1.021656399999756, "iterations": 1 } } ], - "datetime": "2024-04-23T10:11:47.206697", + "datetime": "2024-07-26T13:02:18.760145", "version": "4.0.0" } \ No newline at end of file diff --git a/.benchmarks/github/ifort/AMD64/Windows-CPython-3.11-64bit/0005_774a8273e467cce7cc73ef3fc80f580cef85088a_20240423_104832.json b/.benchmarks/pyCFML/github/gfortran/AMD64/Windows-CPython-3.11-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130211.json similarity index 67% rename from .benchmarks/github/ifort/AMD64/Windows-CPython-3.11-64bit/0005_774a8273e467cce7cc73ef3fc80f580cef85088a_20240423_104832.json rename to .benchmarks/pyCFML/github/gfortran/AMD64/Windows-CPython-3.11-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130211.json index 0c54870..0c3f4e2 100644 --- a/.benchmarks/github/ifort/AMD64/Windows-CPython-3.11-64bit/0005_774a8273e467cce7cc73ef3fc80f580cef85088a_20240423_104832.json +++ b/.benchmarks/pyCFML/github/gfortran/AMD64/Windows-CPython-3.11-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130211.json @@ -1,6 +1,6 @@ { "machine_info": { - "node": "fv-az1212-552", + "node": "fv-az521-683", "processor": "AMD64 Family 25 Model 1 Stepping 1, AuthenticAMD", "machine": "AMD64", "python_compiler": "MSC v.1938 64 bit (AMD64)", @@ -121,18 +121,18 @@ } }, "commit_info": { - "id": "774a8273e467cce7cc73ef3fc80f580cef85088a", - "time": "2024-04-23T12:42:42+02:00", - "author_time": "2024-04-23T12:42:42+02:00", + "id": "7a75bcd61ffc8adc6319ef7f554d092f5c20d299", + "time": "2024-07-26T14:52:09+02:00", + "author_time": "2024-07-26T14:51:49+02:00", "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" + "project": "PyCrysFML", + "branch": "test-rpath-macos" }, "benchmarks": [ { "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", + "name": "test__compute_pattern__SrTiO3_Pm3m", + "fullname": "tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/test__powder_pattern_from_json.py::test__compute_pattern__SrTiO3_Pm3m", "params": null, "param": null, "extra_info": {}, @@ -145,29 +145,29 @@ "warmup": 100000 }, "stats": { - "min": 2.340458900000044, - "max": 2.346897199999944, - "mean": 2.343813360000013, - "stddev": 0.002955550813747884, - "rounds": 5, - "median": 2.343263800000045, - "iqr": 0.0055124999998668045, - "q1": 2.3413308500000767, - "q3": 2.3468433499999435, - "iqr_outliers": 0, + "min": 0.04251469999996971, + "max": 0.044652299999938805, + "mean": 0.043919341666655974, + "stddev": 0.0003844397006096627, + "rounds": 24, + "median": 0.043959499999971285, + "iqr": 0.0002470499999844833, + "q1": 0.043828149999967536, + "q3": 0.04407519999995202, + "iqr_outliers": 2, "stddev_outliers": 3, - "outliers": "3;0", - "ld15iqr": 2.340458900000044, - "hd15iqr": 2.346897199999944, - "ops": 0.4266551326424705, - "total": 11.719066800000064, + "outliers": "3;2", + "ld15iqr": 0.04352449999998953, + "hd15iqr": 0.044652299999938805, + "ops": 22.769011602904115, + "total": 1.0540641999997433, "iterations": 1 } }, { "group": null, - "name": "test__Simple_calc_powder__ponsin", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__ponsin", + "name": "test__compute_pattern__SrTiO3_Pnma", + "fullname": "tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/test__powder_pattern_from_json.py::test__compute_pattern__SrTiO3_Pnma", "params": null, "param": null, "extra_info": {}, @@ -180,26 +180,26 @@ "warmup": 100000 }, "stats": { - "min": 3.7719478999999865, - "max": 3.8416085000000066, - "mean": 3.8063194199999772, - "stddev": 0.032169970718624236, - "rounds": 5, - "median": 3.80256519999989, - "iqr": 0.06108022499998356, - "q1": 3.776957750000008, - "q3": 3.8380379749999918, + "min": 0.06296270000007098, + "max": 0.06523089999996046, + "mean": 0.06426803529410897, + "stddev": 0.0005513755139886913, + "rounds": 17, + "median": 0.06420349999996233, + "iqr": 0.0007576750000453103, + "q1": 0.06402627499997493, + "q3": 0.06478395000002024, "iqr_outliers": 0, - "stddev_outliers": 2, - "outliers": "2;0", - "ld15iqr": 3.7719478999999865, - "hd15iqr": 3.8416085000000066, - "ops": 0.2627209883504748, - "total": 19.031597099999885, + "stddev_outliers": 4, + "outliers": "4;0", + "ld15iqr": 0.06296270000007098, + "hd15iqr": 0.06523089999996046, + "ops": 15.559834611774159, + "total": 1.0925565999998526, "iterations": 1 } } ], - "datetime": "2024-04-23T10:49:55.466341", + "datetime": "2024-07-26T13:02:21.715770", "version": "4.0.0" } \ No newline at end of file diff --git a/.benchmarks/github/ifort/AMD64/Windows-CPython-3.11-64bit/0003_53c48b1cb9568e544b39d995840c186ee18b16f8_20240423_102906.json b/.benchmarks/pyCFML/github/gfortran/AMD64/Windows-CPython-3.12-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130235.json similarity index 63% rename from .benchmarks/github/ifort/AMD64/Windows-CPython-3.11-64bit/0003_53c48b1cb9568e544b39d995840c186ee18b16f8_20240423_102906.json rename to .benchmarks/pyCFML/github/gfortran/AMD64/Windows-CPython-3.12-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130235.json index 23d4cc1..908e282 100644 --- a/.benchmarks/github/ifort/AMD64/Windows-CPython-3.11-64bit/0003_53c48b1cb9568e544b39d995840c186ee18b16f8_20240423_102906.json +++ b/.benchmarks/pyCFML/github/gfortran/AMD64/Windows-CPython-3.12-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130235.json @@ -1,20 +1,20 @@ { "machine_info": { - "node": "fv-az1564-336", + "node": "fv-az1212-782", "processor": "AMD64 Family 25 Model 1 Stepping 1, AuthenticAMD", "machine": "AMD64", - "python_compiler": "MSC v.1938 64 bit (AMD64)", + "python_compiler": "MSC v.1940 64 bit (AMD64)", "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", + "python_implementation_version": "3.12.4", + "python_version": "3.12.4", "python_build": [ - "tags/v3.11.9:de54cf5", - "Apr 2 2024 10:12:12" + "tags/v3.12.4:8e8a4ba", + "Jun 6 2024 19:30:16" ], - "release": "10", + "release": "2022Server", "system": "Windows", "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", + "python_version": "3.12.4.final.0 (64 bit)", "cpuinfo_version": [ 9, 0, @@ -121,18 +121,18 @@ } }, "commit_info": { - "id": "53c48b1cb9568e544b39d995840c186ee18b16f8", - "time": "2024-04-23T12:23:31+02:00", - "author_time": "2024-04-23T12:23:31+02:00", + "id": "7a75bcd61ffc8adc6319ef7f554d092f5c20d299", + "time": "2024-07-26T14:52:09+02:00", + "author_time": "2024-07-26T14:51:49+02:00", "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" + "project": "PyCrysFML", + "branch": "test-rpath-macos" }, "benchmarks": [ { "group": null, - "name": "test__mol_tpcr__molecule_PPH3_Z", - "fullname": "tests/functional_tests/cfml/test__Molecules.py::test__mol_tpcr__molecule_PPH3_Z", + "name": "test__compute_pattern__SrTiO3_Pm3m", + "fullname": "tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/test__powder_pattern_from_json.py::test__compute_pattern__SrTiO3_Pm3m", "params": null, "param": null, "extra_info": {}, @@ -145,29 +145,29 @@ "warmup": 100000 }, "stats": { - "min": 0.01352879999990364, - "max": 0.01960679999990589, - "mean": 0.014125445205489659, - "stddev": 0.0008716113841611496, - "rounds": 73, - "median": 0.013926999999966938, - "iqr": 0.0002856250000036198, - "q1": 0.013767475000037166, - "q3": 0.014053100000040786, - "iqr_outliers": 9, + "min": 0.04319820000000618, + "max": 0.044934799999964525, + "mean": 0.04416563333333556, + "stddev": 0.00040040538225667, + "rounds": 24, + "median": 0.04421084999995628, + "iqr": 0.0005234500000028675, + "q1": 0.04391544999998587, + "q3": 0.044438899999988735, + "iqr_outliers": 0, "stddev_outliers": 5, - "outliers": "5;9", - "ld15iqr": 0.01352879999990364, - "hd15iqr": 0.014611700000045857, - "ops": 70.79422881562444, - "total": 1.0311575000007451, + "outliers": "5;0", + "ld15iqr": 0.04319820000000618, + "hd15iqr": 0.044934799999964525, + "ops": 22.642039172236093, + "total": 1.0599752000000535, "iterations": 1 } }, { "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", + "name": "test__compute_pattern__SrTiO3_Pnma", + "fullname": "tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/test__powder_pattern_from_json.py::test__compute_pattern__SrTiO3_Pnma", "params": null, "param": null, "extra_info": {}, @@ -180,26 +180,26 @@ "warmup": 100000 }, "stats": { - "min": 2.3428930000000037, - "max": 2.347239800000011, - "mean": 2.344889779999994, - "stddev": 0.0017719085958295359, - "rounds": 5, - "median": 2.3448630999999978, - "iqr": 0.002922249999954829, - "q1": 2.3433503500000086, - "q3": 2.3462725999999634, - "iqr_outliers": 0, + "min": 0.0630205999999589, + "max": 0.0680054999999129, + "mean": 0.0647269176470552, + "stddev": 0.0010250836394003141, + "rounds": 17, + "median": 0.06463410000003478, + "iqr": 0.0004817249999007345, + "q1": 0.06437665000004245, + "q3": 0.06485837499994318, + "iqr_outliers": 2, "stddev_outliers": 2, - "outliers": "2;0", - "ld15iqr": 2.3428930000000037, - "hd15iqr": 2.347239800000011, - "ops": 0.4264592769046921, - "total": 11.72444889999997, + "outliers": "2;2", + "ld15iqr": 0.06380599999999959, + "hd15iqr": 0.0680054999999129, + "ops": 15.44952295508383, + "total": 1.1003575999999384, "iterations": 1 } } ], - "datetime": "2024-04-23T10:29:42.996516", + "datetime": "2024-07-26T13:02:46.402969", "version": "4.0.0" } \ No newline at end of file diff --git a/.benchmarks/pyCFML/github/gfortran/arm/Darwin-CPython-3.10-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130228.json b/.benchmarks/pyCFML/github/gfortran/arm/Darwin-CPython-3.10-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130228.json new file mode 100644 index 0000000..c6e241b --- /dev/null +++ b/.benchmarks/pyCFML/github/gfortran/arm/Darwin-CPython-3.10-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130228.json @@ -0,0 +1,113 @@ +{ + "machine_info": { + "node": "Mac-1721998221025.local", + "processor": "arm", + "machine": "arm64", + "python_compiler": "Clang 13.0.0 (clang-1300.0.29.30)", + "python_implementation": "CPython", + "python_implementation_version": "3.10.11", + "python_version": "3.10.11", + "python_build": [ + "v3.10.11:7d4cc5aa85", + "Apr 4 2023 19:05:19" + ], + "release": "23.5.0", + "system": "Darwin", + "cpu": { + "python_version": "3.10.11.final.0 (64 bit)", + "cpuinfo_version": [ + 9, + 0, + 0 + ], + "cpuinfo_version_string": "9.0.0", + "arch": "ARM_8", + "bits": 64, + "count": 3, + "arch_string_raw": "arm64", + "brand_raw": "Apple M1 (Virtual)" + } + }, + "commit_info": { + "id": "7a75bcd61ffc8adc6319ef7f554d092f5c20d299", + "time": "2024-07-26T14:52:09+02:00", + "author_time": "2024-07-26T14:51:49+02:00", + "dirty": false, + "project": "PyCrysFML", + "branch": "test-rpath-macos" + }, + "benchmarks": [ + { + "group": null, + "name": "test__compute_pattern__SrTiO3_Pm3m", + "fullname": "tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/test__powder_pattern_from_json.py::test__compute_pattern__SrTiO3_Pm3m", + "params": null, + "param": null, + "extra_info": {}, + "options": { + "disable_gc": false, + "timer": "perf_counter", + "min_rounds": 5, + "max_time": 1.0, + "min_time": 5e-06, + "warmup": 100000 + }, + "stats": { + "min": 0.015967875000001186, + "max": 0.01989258300000074, + "mean": 0.017650020523081785, + "stddev": 0.001028320109104287, + "rounds": 65, + "median": 0.017956291999894347, + "iqr": 0.0018665309999335022, + "q1": 0.016514531250010123, + "q3": 0.018381062249943625, + "iqr_outliers": 0, + "stddev_outliers": 28, + "outliers": "28;0", + "ld15iqr": 0.015967875000001186, + "hd15iqr": 0.01989258300000074, + "ops": 56.65715791617645, + "total": 1.147251334000316, + "iterations": 1 + } + }, + { + "group": null, + "name": "test__compute_pattern__SrTiO3_Pnma", + "fullname": "tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/test__powder_pattern_from_json.py::test__compute_pattern__SrTiO3_Pnma", + "params": null, + "param": null, + "extra_info": {}, + "options": { + "disable_gc": false, + "timer": "perf_counter", + "min_rounds": 5, + "max_time": 1.0, + "min_time": 5e-06, + "warmup": 100000 + }, + "stats": { + "min": 0.02143324999997276, + "max": 0.035469333000037295, + "mean": 0.023128600749996526, + "stddev": 0.0032754462525434935, + "rounds": 48, + "median": 0.021814062000032663, + "iqr": 0.0007210414999576642, + "q1": 0.021695979500009344, + "q3": 0.022417020999967008, + "iqr_outliers": 8, + "stddev_outliers": 6, + "outliers": "6;8", + "ld15iqr": 0.02143324999997276, + "hd15iqr": 0.02350516699993932, + "ops": 43.236510967925724, + "total": 1.1101728359998333, + "iterations": 1 + } + } + ], + "datetime": "2024-07-26T13:02:36.163650", + "version": "4.0.0" +} \ No newline at end of file diff --git a/.benchmarks/pyCFML/github/gfortran/arm/Darwin-CPython-3.11-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130153.json b/.benchmarks/pyCFML/github/gfortran/arm/Darwin-CPython-3.11-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130153.json new file mode 100644 index 0000000..458bd3d --- /dev/null +++ b/.benchmarks/pyCFML/github/gfortran/arm/Darwin-CPython-3.11-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130153.json @@ -0,0 +1,113 @@ +{ + "machine_info": { + "node": "Mac-1721998199576.local", + "processor": "arm", + "machine": "arm64", + "python_compiler": "Clang 13.0.0 (clang-1300.0.29.30)", + "python_implementation": "CPython", + "python_implementation_version": "3.11.9", + "python_version": "3.11.9", + "python_build": [ + "v3.11.9:de54cf5be3", + "Apr 2 2024 07:12:50" + ], + "release": "23.5.0", + "system": "Darwin", + "cpu": { + "python_version": "3.11.9.final.0 (64 bit)", + "cpuinfo_version": [ + 9, + 0, + 0 + ], + "cpuinfo_version_string": "9.0.0", + "arch": "ARM_8", + "bits": 64, + "count": 3, + "arch_string_raw": "arm64", + "brand_raw": "Apple M1 (Virtual)" + } + }, + "commit_info": { + "id": "7a75bcd61ffc8adc6319ef7f554d092f5c20d299", + "time": "2024-07-26T14:52:09+02:00", + "author_time": "2024-07-26T14:51:49+02:00", + "dirty": false, + "project": "PyCrysFML", + "branch": "test-rpath-macos" + }, + "benchmarks": [ + { + "group": null, + "name": "test__compute_pattern__SrTiO3_Pm3m", + "fullname": "tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/test__powder_pattern_from_json.py::test__compute_pattern__SrTiO3_Pm3m", + "params": null, + "param": null, + "extra_info": {}, + "options": { + "disable_gc": false, + "timer": "perf_counter", + "min_rounds": 5, + "max_time": 1.0, + "min_time": 5e-06, + "warmup": 100000 + }, + "stats": { + "min": 0.01894849999996495, + "max": 0.02776474999996026, + "mean": 0.02134572965306753, + "stddev": 0.002359783538825172, + "rounds": 49, + "median": 0.020285833999992064, + "iqr": 0.00342831200006799, + "q1": 0.019778020999979162, + "q3": 0.023206333000047152, + "iqr_outliers": 0, + "stddev_outliers": 10, + "outliers": "10;0", + "ld15iqr": 0.01894849999996495, + "hd15iqr": 0.02776474999996026, + "ops": 46.847777810972744, + "total": 1.045940753000309, + "iterations": 1 + } + }, + { + "group": null, + "name": "test__compute_pattern__SrTiO3_Pnma", + "fullname": "tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/test__powder_pattern_from_json.py::test__compute_pattern__SrTiO3_Pnma", + "params": null, + "param": null, + "extra_info": {}, + "options": { + "disable_gc": false, + "timer": "perf_counter", + "min_rounds": 5, + "max_time": 1.0, + "min_time": 5e-06, + "warmup": 100000 + }, + "stats": { + "min": 0.029943666000008307, + "max": 0.04663941599994814, + "mean": 0.03280179425000895, + "stddev": 0.0033483085059564017, + "rounds": 32, + "median": 0.03152289600001268, + "iqr": 0.0031288334999430845, + "q1": 0.030733354000062718, + "q3": 0.0338621875000058, + "iqr_outliers": 1, + "stddev_outliers": 5, + "outliers": "5;1", + "ld15iqr": 0.029943666000008307, + "hd15iqr": 0.04663941599994814, + "ops": 30.486137202684485, + "total": 1.0496574160002865, + "iterations": 1 + } + } + ], + "datetime": "2024-07-26T13:02:02.398515", + "version": "4.0.0" +} \ No newline at end of file diff --git a/.benchmarks/pyCFML/github/gfortran/arm/Darwin-CPython-3.12-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130141.json b/.benchmarks/pyCFML/github/gfortran/arm/Darwin-CPython-3.12-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130141.json new file mode 100644 index 0000000..35452cd --- /dev/null +++ b/.benchmarks/pyCFML/github/gfortran/arm/Darwin-CPython-3.12-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130141.json @@ -0,0 +1,113 @@ +{ + "machine_info": { + "node": "Mac-1721998182325.local", + "processor": "arm", + "machine": "arm64", + "python_compiler": "Clang 13.0.0 (clang-1300.0.29.30)", + "python_implementation": "CPython", + "python_implementation_version": "3.12.4", + "python_version": "3.12.4", + "python_build": [ + "v3.12.4:8e8a4baf65", + "Jun 6 2024 17:33:18" + ], + "release": "23.5.0", + "system": "Darwin", + "cpu": { + "python_version": "3.12.4.final.0 (64 bit)", + "cpuinfo_version": [ + 9, + 0, + 0 + ], + "cpuinfo_version_string": "9.0.0", + "arch": "ARM_8", + "bits": 64, + "count": 3, + "arch_string_raw": "arm64", + "brand_raw": "Apple M1 (Virtual)" + } + }, + "commit_info": { + "id": "7a75bcd61ffc8adc6319ef7f554d092f5c20d299", + "time": "2024-07-26T14:52:09+02:00", + "author_time": "2024-07-26T14:51:49+02:00", + "dirty": false, + "project": "PyCrysFML", + "branch": "test-rpath-macos" + }, + "benchmarks": [ + { + "group": null, + "name": "test__compute_pattern__SrTiO3_Pm3m", + "fullname": "tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/test__powder_pattern_from_json.py::test__compute_pattern__SrTiO3_Pm3m", + "params": null, + "param": null, + "extra_info": {}, + "options": { + "disable_gc": false, + "timer": "perf_counter", + "min_rounds": 5, + "max_time": 1.0, + "min_time": 5e-06, + "warmup": 100000 + }, + "stats": { + "min": 0.015619000000015149, + "max": 0.01740304199995535, + "mean": 0.016340930061544266, + "stddev": 0.00034139905664738436, + "rounds": 65, + "median": 0.01633833300002152, + "iqr": 0.00039481225007875764, + "q1": 0.016123551999982055, + "q3": 0.016518364250060813, + "iqr_outliers": 3, + "stddev_outliers": 14, + "outliers": "14;3", + "ld15iqr": 0.015619000000015149, + "hd15iqr": 0.017113249999965774, + "ops": 61.19602716820496, + "total": 1.0621604540003773, + "iterations": 1 + } + }, + { + "group": null, + "name": "test__compute_pattern__SrTiO3_Pnma", + "fullname": "tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/test__powder_pattern_from_json.py::test__compute_pattern__SrTiO3_Pnma", + "params": null, + "param": null, + "extra_info": {}, + "options": { + "disable_gc": false, + "timer": "perf_counter", + "min_rounds": 5, + "max_time": 1.0, + "min_time": 5e-06, + "warmup": 100000 + }, + "stats": { + "min": 0.020015084000078787, + "max": 0.026239874999987478, + "mean": 0.022886975509799876, + "stddev": 0.0024144206299389626, + "rounds": 51, + "median": 0.02454554200005532, + "iqr": 0.004876061999937065, + "q1": 0.02022415650003495, + "q3": 0.025100218499972016, + "iqr_outliers": 0, + "stddev_outliers": 26, + "outliers": "26;0", + "ld15iqr": 0.020015084000078787, + "hd15iqr": 0.026239874999987478, + "ops": 43.69297286886221, + "total": 1.1672357509997937, + "iterations": 1 + } + } + ], + "datetime": "2024-07-26T13:01:49.112768", + "version": "4.0.0" +} \ No newline at end of file diff --git a/.benchmarks/github/gfortran/i386/Darwin-CPython-3.11-64bit/0005_774a8273e467cce7cc73ef3fc80f580cef85088a_20240423_104424.json b/.benchmarks/pyCFML/github/gfortran/i386/Darwin-CPython-3.10-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130156.json similarity index 66% rename from .benchmarks/github/gfortran/i386/Darwin-CPython-3.11-64bit/0005_774a8273e467cce7cc73ef3fc80f580cef85088a_20240423_104424.json rename to .benchmarks/pyCFML/github/gfortran/i386/Darwin-CPython-3.10-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130156.json index 1dc5398..8692c8c 100644 --- a/.benchmarks/github/gfortran/i386/Darwin-CPython-3.11-64bit/0005_774a8273e467cce7cc73ef3fc80f580cef85088a_20240423_104424.json +++ b/.benchmarks/pyCFML/github/gfortran/i386/Darwin-CPython-3.10-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130156.json @@ -1,20 +1,20 @@ { "machine_info": { - "node": "Mac-1713868044236.local", + "node": "Mac-1721998140620.local", "processor": "i386", "machine": "x86_64", - "python_compiler": "Clang 13.0.0 (clang-1300.0.29.30)", + "python_compiler": "Clang 14.0.0 (clang-1400.0.29.202)", "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", + "python_implementation_version": "3.10.14", + "python_version": "3.10.14", "python_build": [ - "v3.11.9:de54cf5be3", - "Apr 2 2024 07:12:50" + "main", + "Jul 16 2024 19:02:43" ], "release": "21.6.0", "system": "Darwin", "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", + "python_version": "3.10.14.final.0 (64 bit)", "cpuinfo_version": [ 9, 0, @@ -136,18 +136,18 @@ } }, "commit_info": { - "id": "774a8273e467cce7cc73ef3fc80f580cef85088a", - "time": "2024-04-23T12:42:42+02:00", - "author_time": "2024-04-23T12:42:42+02:00", + "id": "7a75bcd61ffc8adc6319ef7f554d092f5c20d299", + "time": "2024-07-26T14:52:09+02:00", + "author_time": "2024-07-26T14:51:49+02:00", "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" + "project": "PyCrysFML", + "branch": "test-rpath-macos" }, "benchmarks": [ { "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", + "name": "test__compute_pattern__SrTiO3_Pm3m", + "fullname": "tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/test__powder_pattern_from_json.py::test__compute_pattern__SrTiO3_Pm3m", "params": null, "param": null, "extra_info": {}, @@ -160,29 +160,29 @@ "warmup": 100000 }, "stats": { - "min": 2.700841784999966, - "max": 2.828619290000006, - "mean": 2.7465670886000226, - "stddev": 0.04850663412666781, - "rounds": 5, - "median": 2.7364529710000625, - "iqr": 0.04459946899982015, - "q1": 2.718978423750116, - "q3": 2.763577892749936, - "iqr_outliers": 0, - "stddev_outliers": 1, - "outliers": "1;0", - "ld15iqr": 2.700841784999966, - "hd15iqr": 2.828619290000006, - "ops": 0.3640908697080904, - "total": 13.732835443000113, + "min": 0.03433967700004814, + "max": 0.06518946800008507, + "mean": 0.03800694236666307, + "stddev": 0.006876294056894933, + "rounds": 30, + "median": 0.03529632749996381, + "iqr": 0.003393017999883341, + "q1": 0.034621723000100246, + "q3": 0.03801474099998359, + "iqr_outliers": 3, + "stddev_outliers": 3, + "outliers": "3;3", + "ld15iqr": 0.03433967700004814, + "hd15iqr": 0.05094979099999364, + "ops": 26.310982618720924, + "total": 1.1402082709998922, "iterations": 1 } }, { "group": null, - "name": "test__Simple_calc_powder__ponsin", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__ponsin", + "name": "test__compute_pattern__SrTiO3_Pnma", + "fullname": "tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/test__powder_pattern_from_json.py::test__compute_pattern__SrTiO3_Pnma", "params": null, "param": null, "extra_info": {}, @@ -195,26 +195,26 @@ "warmup": 100000 }, "stats": { - "min": 3.5483465990000695, - "max": 3.6689731419999134, - "mean": 3.583861587800038, - "stddev": 0.048309837285444, - "rounds": 5, - "median": 3.568254928999977, - "iqr": 0.03331123099985689, - "q1": 3.560659328000156, - "q3": 3.593970559000013, + "min": 0.03674943599992275, + "max": 0.08302006999997502, + "mean": 0.04282789499998687, + "stddev": 0.00851735985260089, + "rounds": 29, + "median": 0.04110738199995012, + "iqr": 0.006837148749923472, + "q1": 0.03803844025000558, + "q3": 0.04487558899992905, "iqr_outliers": 1, "stddev_outliers": 1, "outliers": "1;1", - "ld15iqr": 3.5483465990000695, - "hd15iqr": 3.6689731419999134, - "ops": 0.27902863308229836, - "total": 17.91930793900019, + "ld15iqr": 0.03674943599992275, + "hd15iqr": 0.08302006999997502, + "ops": 23.349268041315284, + "total": 1.2420089549996192, "iterations": 1 } } ], - "datetime": "2024-04-23T10:45:50.004319", + "datetime": "2024-07-26T13:02:07.223755", "version": "4.0.0" } \ No newline at end of file diff --git a/.benchmarks/github/gfortran/i386/Darwin-CPython-3.11-64bit/0006_2e27ea3e143b990c623b2de4195dbfc5fd3068c8_20240423_114335.json b/.benchmarks/pyCFML/github/gfortran/i386/Darwin-CPython-3.11-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130428.json similarity index 69% rename from .benchmarks/github/gfortran/i386/Darwin-CPython-3.11-64bit/0006_2e27ea3e143b990c623b2de4195dbfc5fd3068c8_20240423_114335.json rename to .benchmarks/pyCFML/github/gfortran/i386/Darwin-CPython-3.11-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130428.json index 92234b9..ed20d9e 100644 --- a/.benchmarks/github/gfortran/i386/Darwin-CPython-3.11-64bit/0006_2e27ea3e143b990c623b2de4195dbfc5fd3068c8_20240423_114335.json +++ b/.benchmarks/pyCFML/github/gfortran/i386/Darwin-CPython-3.11-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130428.json @@ -1,6 +1,6 @@ { "machine_info": { - "node": "Mac-1713870746215.local", + "node": "Mac-1721998461432.local", "processor": "i386", "machine": "x86_64", "python_compiler": "Clang 13.0.0 (clang-1300.0.29.30)", @@ -136,18 +136,18 @@ } }, "commit_info": { - "id": "2e27ea3e143b990c623b2de4195dbfc5fd3068c8", - "time": "2024-04-23T13:41:53+02:00", - "author_time": "2024-04-23T13:41:53+02:00", + "id": "7a75bcd61ffc8adc6319ef7f554d092f5c20d299", + "time": "2024-07-26T14:52:09+02:00", + "author_time": "2024-07-26T14:51:49+02:00", "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" + "project": "PyCrysFML", + "branch": "test-rpath-macos" }, "benchmarks": [ { "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", + "name": "test__compute_pattern__SrTiO3_Pm3m", + "fullname": "tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/test__powder_pattern_from_json.py::test__compute_pattern__SrTiO3_Pm3m", "params": null, "param": null, "extra_info": {}, @@ -160,29 +160,29 @@ "warmup": 100000 }, "stats": { - "min": 2.7315182320000986, - "max": 2.803611250999893, - "mean": 2.7633738352000363, - "stddev": 0.03084620932660127, - "rounds": 5, - "median": 2.7579464370001006, - "iqr": 0.053808622750011637, - "q1": 2.736409345000027, - "q3": 2.7902179677500385, + "min": 0.03210794699998587, + "max": 0.035659570999996504, + "mean": 0.03386880093549119, + "stddev": 0.0006936731195237281, + "rounds": 31, + "median": 0.03372384700003295, + "iqr": 0.0009216342501190411, + "q1": 0.03339993149995735, + "q3": 0.03432156575007639, "iqr_outliers": 0, - "stddev_outliers": 2, - "outliers": "2;0", - "ld15iqr": 2.7315182320000986, - "hd15iqr": 2.803611250999893, - "ops": 0.3618764813004794, - "total": 13.816869176000182, + "stddev_outliers": 7, + "outliers": "7;0", + "ld15iqr": 0.03210794699998587, + "hd15iqr": 0.035659570999996504, + "ops": 29.525698353026073, + "total": 1.0499328290002268, "iterations": 1 } }, { "group": null, - "name": "test__Simple_calc_powder__ponsin", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__ponsin", + "name": "test__compute_pattern__SrTiO3_Pnma", + "fullname": "tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/test__powder_pattern_from_json.py::test__compute_pattern__SrTiO3_Pnma", "params": null, "param": null, "extra_info": {}, @@ -195,26 +195,26 @@ "warmup": 100000 }, "stats": { - "min": 3.6665675970000393, - "max": 3.736510588000101, - "mean": 3.6978540952000456, - "stddev": 0.025479886863332923, - "rounds": 5, - "median": 3.6987564190001194, - "iqr": 0.02747507874994426, - "q1": 3.681935685750034, - "q3": 3.709410764499978, + "min": 0.033956024999952206, + "max": 0.0379285600000685, + "mean": 0.03563249799999539, + "stddev": 0.0010776551945605257, + "rounds": 30, + "median": 0.03549609049997571, + "iqr": 0.0018081679999113476, + "q1": 0.03467958400005955, + "q3": 0.0364877519999709, "iqr_outliers": 0, - "stddev_outliers": 2, - "outliers": "2;0", - "ld15iqr": 3.6665675970000393, - "hd15iqr": 3.736510588000101, - "ops": 0.2704271110366517, - "total": 18.48927047600023, + "stddev_outliers": 9, + "outliers": "9;0", + "ld15iqr": 0.033956024999952206, + "hd15iqr": 0.0379285600000685, + "ops": 28.064268747033374, + "total": 1.0689749399998618, "iterations": 1 } } ], - "datetime": "2024-04-23T11:45:01.986531", + "datetime": "2024-07-26T13:04:38.084248", "version": "4.0.0" } \ No newline at end of file diff --git a/.benchmarks/github/gfortran/i386/Darwin-CPython-3.11-64bit/0004_a35d0b5acf769d4a68794b33d6952117b5ae4ecb_20240423_103216.json b/.benchmarks/pyCFML/github/gfortran/i386/Darwin-CPython-3.12-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130216.json similarity index 65% rename from .benchmarks/github/gfortran/i386/Darwin-CPython-3.11-64bit/0004_a35d0b5acf769d4a68794b33d6952117b5ae4ecb_20240423_103216.json rename to .benchmarks/pyCFML/github/gfortran/i386/Darwin-CPython-3.12-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130216.json index 9e7b5da..c2d4993 100644 --- a/.benchmarks/github/gfortran/i386/Darwin-CPython-3.11-64bit/0004_a35d0b5acf769d4a68794b33d6952117b5ae4ecb_20240423_103216.json +++ b/.benchmarks/pyCFML/github/gfortran/i386/Darwin-CPython-3.12-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130216.json @@ -1,20 +1,20 @@ { "machine_info": { - "node": "Mac-1713867039133.local", + "node": "Mac-1721998123768.local", "processor": "i386", "machine": "x86_64", "python_compiler": "Clang 13.0.0 (clang-1300.0.29.30)", "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", + "python_implementation_version": "3.12.4", + "python_version": "3.12.4", "python_build": [ - "v3.11.9:de54cf5be3", - "Apr 2 2024 07:12:50" + "v3.12.4:8e8a4baf65", + "Jun 6 2024 17:33:18" ], "release": "21.6.0", "system": "Darwin", "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", + "python_version": "3.12.4.final.0 (64 bit)", "cpuinfo_version": [ 9, 0, @@ -136,18 +136,18 @@ } }, "commit_info": { - "id": "a35d0b5acf769d4a68794b33d6952117b5ae4ecb", - "time": "2024-04-23T12:30:14+02:00", - "author_time": "2024-04-23T12:30:14+02:00", + "id": "7a75bcd61ffc8adc6319ef7f554d092f5c20d299", + "time": "2024-07-26T14:52:09+02:00", + "author_time": "2024-07-26T14:51:49+02:00", "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" + "project": "PyCrysFML", + "branch": "test-rpath-macos" }, "benchmarks": [ { "group": null, - "name": "test__mol_tpcr__molecule_PPH3_Z", - "fullname": "tests/functional_tests/cfml/test__Molecules.py::test__mol_tpcr__molecule_PPH3_Z", + "name": "test__compute_pattern__SrTiO3_Pm3m", + "fullname": "tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/test__powder_pattern_from_json.py::test__compute_pattern__SrTiO3_Pm3m", "params": null, "param": null, "extra_info": {}, @@ -160,29 +160,29 @@ "warmup": 100000 }, "stats": { - "min": 0.008344954999984111, - "max": 0.015999484999838387, - "mean": 0.0087360225583249, - "stddev": 0.000758880798341355, - "rounds": 120, - "median": 0.00855822849996457, - "iqr": 0.0002726345001065056, - "q1": 0.008473082499904194, - "q3": 0.0087457170000107, - "iqr_outliers": 11, - "stddev_outliers": 4, - "outliers": "4;11", - "ld15iqr": 0.008344954999984111, - "hd15iqr": 0.009162736999996923, - "ops": 114.46856888516852, - "total": 1.048322706998988, + "min": 0.042462162999981956, + "max": 0.04861373599999297, + "mean": 0.04429806517390736, + "stddev": 0.001145676339735756, + "rounds": 23, + "median": 0.044218645000000834, + "iqr": 0.0008687294999276673, + "q1": 0.04374883950001163, + "q3": 0.044617568999939294, + "iqr_outliers": 1, + "stddev_outliers": 3, + "outliers": "3;1", + "ld15iqr": 0.042462162999981956, + "hd15iqr": 0.04861373599999297, + "ops": 22.574349377882633, + "total": 1.0188554989998693, "iterations": 1 } }, { "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", + "name": "test__compute_pattern__SrTiO3_Pnma", + "fullname": "tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/test__powder_pattern_from_json.py::test__compute_pattern__SrTiO3_Pnma", "params": null, "param": null, "extra_info": {}, @@ -195,26 +195,26 @@ "warmup": 100000 }, "stats": { - "min": 2.733635318000097, - "max": 2.8680051130002084, - "mean": 2.810717248200035, - "stddev": 0.05042628615725613, - "rounds": 5, - "median": 2.8234460480000507, - "iqr": 0.06284699824999507, - "q1": 2.779468965499973, - "q3": 2.842315963749968, - "iqr_outliers": 0, - "stddev_outliers": 2, - "outliers": "2;0", - "ld15iqr": 2.733635318000097, - "hd15iqr": 2.8680051130002084, - "ops": 0.3557810735464029, - "total": 14.053586241000176, + "min": 0.04503302199998416, + "max": 0.05141394899999341, + "mean": 0.048295316347835265, + "stddev": 0.0014774139284583119, + "rounds": 23, + "median": 0.04821688300000915, + "iqr": 0.0015518204999978025, + "q1": 0.04754092974999935, + "q3": 0.04909275024999715, + "iqr_outliers": 1, + "stddev_outliers": 7, + "outliers": "7;1", + "ld15iqr": 0.0454920280000124, + "hd15iqr": 0.05141394899999341, + "ops": 20.705941603068574, + "total": 1.1107922760002111, "iterations": 1 } } ], - "datetime": "2024-04-23T10:32:58.330248", + "datetime": "2024-07-26T13:02:26.506233", "version": "4.0.0" } \ No newline at end of file diff --git a/.benchmarks/github/ifort/x86_64/Linux-CPython-3.11-64bit/0003_53c48b1cb9568e544b39d995840c186ee18b16f8_20240423_102820.json b/.benchmarks/pyCFML/github/gfortran/x86_64/Linux-CPython-3.10-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130139.json similarity index 65% rename from .benchmarks/github/ifort/x86_64/Linux-CPython-3.11-64bit/0003_53c48b1cb9568e544b39d995840c186ee18b16f8_20240423_102820.json rename to .benchmarks/pyCFML/github/gfortran/x86_64/Linux-CPython-3.10-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130139.json index 604df23..3820de2 100644 --- a/.benchmarks/github/ifort/x86_64/Linux-CPython-3.11-64bit/0003_53c48b1cb9568e544b39d995840c186ee18b16f8_20240423_102820.json +++ b/.benchmarks/pyCFML/github/gfortran/x86_64/Linux-CPython-3.10-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130139.json @@ -1,20 +1,20 @@ { "machine_info": { - "node": "fv-az914-932", + "node": "fv-az1444-406", "processor": "x86_64", "machine": "x86_64", - "python_compiler": "GCC 11.4.0", + "python_compiler": "GCC 13.2.0", "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", + "python_implementation_version": "3.10.14", + "python_version": "3.10.14", "python_build": [ "main", - "Apr 2 2024 15:19:53" + "Jul 16 2024 19:03:14" ], - "release": "6.5.0-1018-azure", + "release": "6.8.0-1010-azure", "system": "Linux", "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", + "python_version": "3.10.14.final.0 (64 bit)", "cpuinfo_version": [ 9, 0, @@ -27,14 +27,14 @@ "arch_string_raw": "x86_64", "vendor_id_raw": "AuthenticAMD", "brand_raw": "AMD EPYC 7763 64-Core Processor", - "hz_advertised_friendly": "3.2432 GHz", - "hz_actual_friendly": "3.2432 GHz", + "hz_advertised_friendly": "3.2790 GHz", + "hz_actual_friendly": "3.2790 GHz", "hz_advertised": [ - 3243235000, + 3279046000, 0 ], "hz_actual": [ - 3243235000, + 3279046000, 0 ], "stepping": 1, @@ -79,7 +79,6 @@ "ht", "hypervisor", "invpcid", - "invpcid_single", "lahf_lm", "lm", "mca", @@ -134,6 +133,7 @@ "tsc_reliable", "tsc_scale", "umip", + "user_shstk", "v_vmsave_vmload", "vaes", "vmcb_clean", @@ -156,18 +156,18 @@ } }, "commit_info": { - "id": "53c48b1cb9568e544b39d995840c186ee18b16f8", - "time": "2024-04-23T12:23:31+02:00", - "author_time": "2024-04-23T12:23:31+02:00", + "id": "7a75bcd61ffc8adc6319ef7f554d092f5c20d299", + "time": "2024-07-26T14:52:09+02:00", + "author_time": "2024-07-26T14:51:49+02:00", "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" + "project": "PyCrysFML", + "branch": "test-rpath-macos" }, "benchmarks": [ { "group": null, - "name": "test__mol_tpcr__molecule_PPH3_Z", - "fullname": "tests/functional_tests/cfml/test__Molecules.py::test__mol_tpcr__molecule_PPH3_Z", + "name": "test__compute_pattern__SrTiO3_Pm3m", + "fullname": "tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/test__powder_pattern_from_json.py::test__compute_pattern__SrTiO3_Pm3m", "params": null, "param": null, "extra_info": {}, @@ -180,29 +180,29 @@ "warmup": 100000 }, "stats": { - "min": 0.005814169999950991, - "max": 0.00808105499999101, - "mean": 0.006053226529069419, - "stddev": 0.00020350645774805585, - "rounds": 172, - "median": 0.0060381094999968354, - "iqr": 0.00016527600004678789, - "q1": 0.005942950999980212, - "q3": 0.006108227000027, - "iqr_outliers": 5, - "stddev_outliers": 17, - "outliers": "17;5", - "ld15iqr": 0.005814169999950991, - "hd15iqr": 0.0063919619999524, - "ops": 165.201152674148, - "total": 1.04115496299994, + "min": 0.020904352999991715, + "max": 0.021667055999984086, + "mean": 0.02114452790000172, + "stddev": 0.00015774079052129541, + "rounds": 60, + "median": 0.021097769000007816, + "iqr": 0.0001851049999999077, + "q1": 0.021041334000017287, + "q3": 0.021226439000017194, + "iqr_outliers": 3, + "stddev_outliers": 12, + "outliers": "12;3", + "ld15iqr": 0.020904352999991715, + "hd15iqr": 0.021519621000010147, + "ops": 47.29356005153081, + "total": 1.2686716740001032, "iterations": 1 } }, { "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", + "name": "test__compute_pattern__SrTiO3_Pnma", + "fullname": "tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/test__powder_pattern_from_json.py::test__compute_pattern__SrTiO3_Pnma", "params": null, "param": null, "extra_info": {}, @@ -215,26 +215,26 @@ "warmup": 100000 }, "stats": { - "min": 2.313195445999952, - "max": 2.319983882000031, - "mean": 2.3169107730000063, - "stddev": 0.002758723155287176, - "rounds": 5, - "median": 2.31820400700002, - "iqr": 0.004141279500061046, - "q1": 2.3145157249999784, - "q3": 2.3186570045000394, - "iqr_outliers": 0, - "stddev_outliers": 2, - "outliers": "2;0", - "ld15iqr": 2.313195445999952, - "hd15iqr": 2.319983882000031, - "ops": 0.4316091977530795, - "total": 11.584553865000032, + "min": 0.031726555000005874, + "max": 0.03324987399997781, + "mean": 0.03209548687500163, + "stddev": 0.0003016274130512886, + "rounds": 32, + "median": 0.03198601350000274, + "iqr": 0.00015600499999379736, + "q1": 0.03193812450000166, + "q3": 0.03209412949999546, + "iqr_outliers": 5, + "stddev_outliers": 5, + "outliers": "5;5", + "ld15iqr": 0.031726555000005874, + "hd15iqr": 0.0323629209999865, + "ops": 31.157028522252293, + "total": 1.0270555800000523, "iterations": 1 } } ], - "datetime": "2024-04-23T10:28:56.454890", + "datetime": "2024-07-26T13:01:48.566294", "version": "4.0.0" } \ No newline at end of file diff --git a/.benchmarks/github/ifx/x86_64/Linux-CPython-3.11-64bit/0002_f2feb7460687645f07e2554619af175779f60ea5_20240423_101404.json b/.benchmarks/pyCFML/github/gfortran/x86_64/Linux-CPython-3.11-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130145.json similarity index 67% rename from .benchmarks/github/ifx/x86_64/Linux-CPython-3.11-64bit/0002_f2feb7460687645f07e2554619af175779f60ea5_20240423_101404.json rename to .benchmarks/pyCFML/github/gfortran/x86_64/Linux-CPython-3.11-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130145.json index 9577bc6..a3867a6 100644 --- a/.benchmarks/github/ifx/x86_64/Linux-CPython-3.11-64bit/0002_f2feb7460687645f07e2554619af175779f60ea5_20240423_101404.json +++ b/.benchmarks/pyCFML/github/gfortran/x86_64/Linux-CPython-3.11-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130145.json @@ -1,17 +1,17 @@ { "machine_info": { - "node": "fv-az849-678", + "node": "fv-az1436-508", "processor": "x86_64", "machine": "x86_64", - "python_compiler": "GCC 11.4.0", + "python_compiler": "GCC 13.2.0", "python_implementation": "CPython", "python_implementation_version": "3.11.9", "python_version": "3.11.9", "python_build": [ "main", - "Apr 2 2024 15:19:53" + "Jul 15 2024 21:50:42" ], - "release": "6.5.0-1018-azure", + "release": "6.8.0-1010-azure", "system": "Linux", "cpu": { "python_version": "3.11.9.final.0 (64 bit)", @@ -27,14 +27,14 @@ "arch_string_raw": "x86_64", "vendor_id_raw": "AuthenticAMD", "brand_raw": "AMD EPYC 7763 64-Core Processor", - "hz_advertised_friendly": "2.4454 GHz", - "hz_actual_friendly": "2.4454 GHz", + "hz_advertised_friendly": "3.2426 GHz", + "hz_actual_friendly": "3.2426 GHz", "hz_advertised": [ - 2445424000, + 3242551000, 0 ], "hz_actual": [ - 2445424000, + 3242551000, 0 ], "stepping": 1, @@ -79,7 +79,6 @@ "ht", "hypervisor", "invpcid", - "invpcid_single", "lahf_lm", "lm", "mca", @@ -134,6 +133,7 @@ "tsc_reliable", "tsc_scale", "umip", + "user_shstk", "v_vmsave_vmload", "vaes", "vmcb_clean", @@ -156,18 +156,18 @@ } }, "commit_info": { - "id": "f2feb7460687645f07e2554619af175779f60ea5", - "time": "2024-04-23T12:09:18+02:00", - "author_time": "2024-04-23T12:09:18+02:00", + "id": "7a75bcd61ffc8adc6319ef7f554d092f5c20d299", + "time": "2024-07-26T14:52:09+02:00", + "author_time": "2024-07-26T14:51:49+02:00", "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" + "project": "PyCrysFML", + "branch": "test-rpath-macos" }, "benchmarks": [ { "group": null, - "name": "test__mol_tpcr__molecule_PPH3_Z", - "fullname": "tests/functional_tests/cfml/test__Molecules.py::test__mol_tpcr__molecule_PPH3_Z", + "name": "test__compute_pattern__SrTiO3_Pm3m", + "fullname": "tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/test__powder_pattern_from_json.py::test__compute_pattern__SrTiO3_Pm3m", "params": null, "param": null, "extra_info": {}, @@ -180,29 +180,29 @@ "warmup": 100000 }, "stats": { - "min": 0.006290189000026203, - "max": 0.009322413999996115, - "mean": 0.0064802734999990005, - "stddev": 0.0002531669574594982, - "rounds": 160, - "median": 0.006444060500001569, - "iqr": 0.00015959699999257282, - "q1": 0.006378893499999094, - "q3": 0.006538490499991667, - "iqr_outliers": 3, + "min": 0.020427928000003703, + "max": 0.02336836000006315, + "mean": 0.020865063499997866, + "stddev": 0.00038810256939518604, + "rounds": 62, + "median": 0.020820205499944677, + "iqr": 0.0003077759999996488, + "q1": 0.020660602000020845, + "q3": 0.020968378000020493, + "iqr_outliers": 1, "stddev_outliers": 4, - "outliers": "4;3", - "ld15iqr": 0.006290189000026203, - "hd15iqr": 0.00681862099997943, - "ops": 154.31447453570505, - "total": 1.0368437599998401, + "outliers": "4;1", + "ld15iqr": 0.020427928000003703, + "hd15iqr": 0.02336836000006315, + "ops": 47.927004871090006, + "total": 1.2936339369998677, "iterations": 1 } }, { "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", + "name": "test__compute_pattern__SrTiO3_Pnma", + "fullname": "tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/test__powder_pattern_from_json.py::test__compute_pattern__SrTiO3_Pnma", "params": null, "param": null, "extra_info": {}, @@ -215,26 +215,26 @@ "warmup": 100000 }, "stats": { - "min": 2.3260437900000284, - "max": 2.33175894499999, - "mean": 2.3286448847999965, - "stddev": 0.0022061395871907225, - "rounds": 5, - "median": 2.3286014470000396, - "iqr": 0.0032328552499762964, - "q1": 2.3269165049999856, - "q3": 2.330149360249962, - "iqr_outliers": 0, - "stddev_outliers": 2, - "outliers": "2;0", - "ld15iqr": 2.3260437900000284, - "hd15iqr": 2.33175894499999, - "ops": 0.42943430598946325, - "total": 11.643224423999982, + "min": 0.02896608700007164, + "max": 0.03803481699992517, + "mean": 0.034244060944451524, + "stddev": 0.0012556835435139034, + "rounds": 54, + "median": 0.03430412900002011, + "iqr": 0.0013710310000760728, + "q1": 0.03354057199999261, + "q3": 0.03491160300006868, + "iqr_outliers": 2, + "stddev_outliers": 11, + "outliers": "11;2", + "ld15iqr": 0.03240608200007955, + "hd15iqr": 0.03803481699992517, + "ops": 29.202144033738712, + "total": 1.8491792910003824, "iterations": 1 } } ], - "datetime": "2024-04-23T10:14:40.729424", + "datetime": "2024-07-26T13:01:56.947280", "version": "4.0.0" } \ No newline at end of file diff --git a/.benchmarks/github/ifx/x86_64/Linux-CPython-3.11-64bit/0006_2e27ea3e143b990c623b2de4195dbfc5fd3068c8_20240423_114617.json b/.benchmarks/pyCFML/github/gfortran/x86_64/Linux-CPython-3.12-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130140.json similarity index 66% rename from .benchmarks/github/ifx/x86_64/Linux-CPython-3.11-64bit/0006_2e27ea3e143b990c623b2de4195dbfc5fd3068c8_20240423_114617.json rename to .benchmarks/pyCFML/github/gfortran/x86_64/Linux-CPython-3.12-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130140.json index 1fd848d..c7ffacb 100644 --- a/.benchmarks/github/ifx/x86_64/Linux-CPython-3.11-64bit/0006_2e27ea3e143b990c623b2de4195dbfc5fd3068c8_20240423_114617.json +++ b/.benchmarks/pyCFML/github/gfortran/x86_64/Linux-CPython-3.12-64bit/0001_7a75bcd61ffc8adc6319ef7f554d092f5c20d299_20240726_130140.json @@ -1,20 +1,20 @@ { "machine_info": { - "node": "fv-az702-396", + "node": "fv-az1781-273", "processor": "x86_64", "machine": "x86_64", - "python_compiler": "GCC 11.4.0", + "python_compiler": "GCC 13.2.0", "python_implementation": "CPython", - "python_implementation_version": "3.11.9", - "python_version": "3.11.9", + "python_implementation_version": "3.12.4", + "python_version": "3.12.4", "python_build": [ "main", - "Apr 2 2024 15:19:53" + "Jul 15 2024 21:50:43" ], - "release": "6.5.0-1018-azure", + "release": "6.8.0-1010-azure", "system": "Linux", "cpu": { - "python_version": "3.11.9.final.0 (64 bit)", + "python_version": "3.12.4.final.0 (64 bit)", "cpuinfo_version": [ 9, 0, @@ -27,14 +27,14 @@ "arch_string_raw": "x86_64", "vendor_id_raw": "AuthenticAMD", "brand_raw": "AMD EPYC 7763 64-Core Processor", - "hz_advertised_friendly": "3.2416 GHz", - "hz_actual_friendly": "3.2416 GHz", + "hz_advertised_friendly": "3.2170 GHz", + "hz_actual_friendly": "3.2170 GHz", "hz_advertised": [ - 3241557000, + 3217047000, 0 ], "hz_actual": [ - 3241557000, + 3217047000, 0 ], "stepping": 1, @@ -79,7 +79,6 @@ "ht", "hypervisor", "invpcid", - "invpcid_single", "lahf_lm", "lm", "mca", @@ -134,6 +133,7 @@ "tsc_reliable", "tsc_scale", "umip", + "user_shstk", "v_vmsave_vmload", "vaes", "vmcb_clean", @@ -156,18 +156,18 @@ } }, "commit_info": { - "id": "2e27ea3e143b990c623b2de4195dbfc5fd3068c8", - "time": "2024-04-23T13:41:53+02:00", - "author_time": "2024-04-23T13:41:53+02:00", + "id": "7a75bcd61ffc8adc6319ef7f554d092f5c20d299", + "time": "2024-07-26T14:52:09+02:00", + "author_time": "2024-07-26T14:51:49+02:00", "dirty": false, - "project": "TEST_PyCrysFML", - "branch": "master" + "project": "PyCrysFML", + "branch": "test-rpath-macos" }, "benchmarks": [ { "group": null, - "name": "test__Simple_calc_powder__SrTiO3s", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__SrTiO3s", + "name": "test__compute_pattern__SrTiO3_Pm3m", + "fullname": "tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/test__powder_pattern_from_json.py::test__compute_pattern__SrTiO3_Pm3m", "params": null, "param": null, "extra_info": {}, @@ -180,29 +180,29 @@ "warmup": 100000 }, "stats": { - "min": 2.3291059929999847, - "max": 2.3327546849999976, - "mean": 2.3309758431999854, - "stddev": 0.0014782427339730512, - "rounds": 5, - "median": 2.3308587909999687, - "iqr": 0.0024288957500004926, - "q1": 2.3298280419999884, - "q3": 2.332256937749989, + "min": 0.020513015999995332, + "max": 0.022191137999982402, + "mean": 0.021253353943395593, + "stddev": 0.00043279003552755074, + "rounds": 53, + "median": 0.021286277999990943, + "iqr": 0.000730096249967005, + "q1": 0.020856130250010096, + "q3": 0.0215862264999771, "iqr_outliers": 0, - "stddev_outliers": 2, - "outliers": "2;0", - "ld15iqr": 2.3291059929999847, - "hd15iqr": 2.3327546849999976, - "ops": 0.42900487489702627, - "total": 11.654879215999927, + "stddev_outliers": 19, + "outliers": "19;0", + "ld15iqr": 0.020513015999995332, + "hd15iqr": 0.022191137999982402, + "ops": 47.051397283615394, + "total": 1.1264277589999665, "iterations": 1 } }, { "group": null, - "name": "test__Simple_calc_powder__ponsin", - "fullname": "tests/functional_tests/cfml/test__PowderPattern.py::test__Simple_calc_powder__ponsin", + "name": "test__compute_pattern__SrTiO3_Pnma", + "fullname": "tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/test__powder_pattern_from_json.py::test__compute_pattern__SrTiO3_Pnma", "params": null, "param": null, "extra_info": {}, @@ -215,26 +215,26 @@ "warmup": 100000 }, "stats": { - "min": 3.1188601160000076, - "max": 3.14316630899998, - "mean": 3.135571614799994, - "stddev": 0.009750336276969349, - "rounds": 5, - "median": 3.139529048999975, - "iqr": 0.01009473175001574, - "q1": 3.1313194122499937, - "q3": 3.1414141440000094, + "min": 0.03257851399996525, + "max": 0.03554066000003786, + "mean": 0.03377694034374912, + "stddev": 0.0010039104822318556, + "rounds": 32, + "median": 0.03331532699996842, + "iqr": 0.0017950295000161987, + "q1": 0.03302733300000682, + "q3": 0.03482236250002302, "iqr_outliers": 0, - "stddev_outliers": 1, - "outliers": "1;0", - "ld15iqr": 3.1188601160000076, - "hd15iqr": 3.14316630899998, - "ops": 0.31892111641780696, - "total": 15.677858073999971, + "stddev_outliers": 15, + "outliers": "15;0", + "ld15iqr": 0.03257851399996525, + "hd15iqr": 0.03554066000003786, + "ops": 29.605997163241092, + "total": 1.0808620909999718, "iterations": 1 } } ], - "datetime": "2024-04-23T11:47:30.720222", + "datetime": "2024-07-26T13:01:49.682278", "version": "4.0.0" } \ No newline at end of file diff --git a/.benchmarks/pyCFML/local/gfortran/arm/Darwin-CPython-3.11-64bit/0001_4c5918320a07e1bd72494d2c13d16afc1ea8c654_20240726_115911_uncommited-changes.json b/.benchmarks/pyCFML/local/gfortran/arm/Darwin-CPython-3.11-64bit/0001_4c5918320a07e1bd72494d2c13d16afc1ea8c654_20240726_115911_uncommited-changes.json new file mode 100644 index 0000000..c5066cc --- /dev/null +++ b/.benchmarks/pyCFML/local/gfortran/arm/Darwin-CPython-3.11-64bit/0001_4c5918320a07e1bd72494d2c13d16afc1ea8c654_20240726_115911_uncommited-changes.json @@ -0,0 +1,113 @@ +{ + "machine_info": { + "node": "CIN-956416", + "processor": "arm", + "machine": "arm64", + "python_compiler": "Clang 15.0.0 (clang-1500.1.0.2.5)", + "python_implementation": "CPython", + "python_implementation_version": "3.11.7", + "python_version": "3.11.7", + "python_build": [ + "main", + "Dec 4 2023 18:10:11" + ], + "release": "23.5.0", + "system": "Darwin", + "cpu": { + "python_version": "3.11.7.final.0 (64 bit)", + "cpuinfo_version": [ + 9, + 0, + 0 + ], + "cpuinfo_version_string": "9.0.0", + "arch": "ARM_8", + "bits": 64, + "count": 12, + "arch_string_raw": "arm64", + "brand_raw": "Apple M2 Max" + } + }, + "commit_info": { + "id": "4c5918320a07e1bd72494d2c13d16afc1ea8c654", + "time": "2024-07-26T12:43:51+02:00", + "author_time": "2024-07-26T12:43:51+02:00", + "dirty": true, + "project": "TEST_PyCrysFML", + "branch": "test-rpath-macos" + }, + "benchmarks": [ + { + "group": null, + "name": "test__compute_pattern__SrTiO3_Pm3m", + "fullname": "tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/test__powder_pattern_from_json.py::test__compute_pattern__SrTiO3_Pm3m", + "params": null, + "param": null, + "extra_info": {}, + "options": { + "disable_gc": false, + "timer": "perf_counter", + "min_rounds": 5, + "max_time": 1.0, + "min_time": 5e-06, + "warmup": 100000 + }, + "stats": { + "min": 0.027375999954529107, + "max": 0.02833691705018282, + "mean": 0.02752962614082404, + "stddev": 0.00018287318527770188, + "rounds": 37, + "median": 0.027478584088385105, + "iqr": 6.759370444342494e-05, + "q1": 0.02744941652053967, + "q3": 0.027517010224983096, + "iqr_outliers": 5, + "stddev_outliers": 3, + "outliers": "3;5", + "ld15iqr": 0.027375999954529107, + "hd15iqr": 0.027706458000466228, + "ops": 36.32450345982313, + "total": 1.0185961672104895, + "iterations": 1 + } + }, + { + "group": null, + "name": "test__compute_pattern__SrTiO3_Pnma", + "fullname": "tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/test__powder_pattern_from_json.py::test__compute_pattern__SrTiO3_Pnma", + "params": null, + "param": null, + "extra_info": {}, + "options": { + "disable_gc": false, + "timer": "perf_counter", + "min_rounds": 5, + "max_time": 1.0, + "min_time": 5e-06, + "warmup": 100000 + }, + "stats": { + "min": 0.020283875055611134, + "max": 0.02087224996648729, + "mean": 0.020533147009032568, + "stddev": 9.214432322480115e-05, + "rounds": 49, + "median": 0.020545291947200894, + "iqr": 9.558277088217437e-05, + "q1": 0.020493198244366795, + "q3": 0.02058878101524897, + "iqr_outliers": 3, + "stddev_outliers": 13, + "outliers": "13;3", + "ld15iqr": 0.020390957943163812, + "hd15iqr": 0.02087224996648729, + "ops": 48.7017406323589, + "total": 1.006124203442596, + "iterations": 1 + } + } + ], + "datetime": "2024-07-26T11:59:19.497848", + "version": "4.0.0" +} \ No newline at end of file diff --git a/.github/workflows/main.yml b/.github/workflows/debug.yml similarity index 54% rename from .github/workflows/main.yml rename to .github/workflows/debug.yml index 70f99e6..925e4f9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/debug.yml @@ -1,18 +1,29 @@ -name: build-and-test +name: debug-build-and-test on: push: + branches: + - "**" + pull_request: + branches: + - "**" #schedule: # - cron: '*/120 8-18 * * *' # every 2 hours from 8:00 to 18:00 every day jobs: - wheel: # the first job + + ############################################################################## + # JOB 1 + ############################################################################## + build: # current job name + + timeout-minutes: 30 + # current job matrix. if modified, remember to UPDATE the strategy in the next job strategy: fail-fast: false matrix: - #os: [ubuntu-22.04, windows-2022, macos-12] - os: [ubuntu-22.04, windows-2022, macos-12, flyci-macos-14-m2] + os: [ubuntu-24.04, windows-2022, macos-12, macos-14] # [ubuntu-22.04, windows-2022, macos-13, flyci-macos-14-m2] toolchain: - { exe: gfortran, compiler: gcc, version: 13 } - { exe: ifort, compiler: intel-classic, version: "2021.10" } @@ -20,15 +31,13 @@ jobs: exclude: - os: macos-12 toolchain: { exe: ifx, compiler: intel, version: "2023.2" } # no support for macOS - - os: flyci-macos-14-m2 + - os: macos-14 toolchain: { exe: ifx, compiler: intel, version: "2023.2" } # no support for macOS on arm64 - - os: flyci-macos-14-m2 + - os: macos-14 toolchain: { exe: ifort, compiler: intel-classic, version: "2021.10" } # no support for macOS on arm64 runs-on: ${{ matrix.os }} - timeout-minutes: 30 - steps: # job steps - name: Check-out repository uses: actions/checkout@v4 @@ -45,130 +54,147 @@ jobs: if: runner.os == 'Windows' uses: ilammy/msvc-dev-cmd@v1 - #- name: debug - # shell: bash - # run: ifort -help - - name: Set up Python environment uses: actions/setup-python@v5 with: - python-version: 3.11 + python-version: '3.11' - name: Upgrade package installer for Python shell: bash - run: python3 -m pip install --upgrade pip + run: pip install --upgrade pip - name: Install Python dependences shell: bash - run: python3 -m pip install '.[ci,test]' # ci extras from pyproject.toml + run: pip install '.[ci,test]' # 'ci' and 'test' extras from pyproject.toml - - name: Fix reinstalling gcc [macOS] # needed because of `brew reinstall gcc` + - name: Fix reinstalling gcc [macOS] # needed because of `brew reinstall gcc` if: runner.os == 'macOS' shell: bash run: echo "MACOSX_DEPLOYMENT_TARGET=$(sw_vers -productVersion)" >> $GITHUB_ENV - - name: Create job scripts + - name: Create build scripts in scripts/scripts shell: bash run: > - python3 scripts.py + python3 pybuild.py + --create-scripts --platform ${{ runner.os }} --compiler ${{ matrix.toolchain.exe }} --mode debug --bash-syntax + --enable-backslash-escapes - - name: Print some debug info + - name: Print build-specific variables shell: bash - run: scripts/print_debug_info.sh # bash -x scripts/print_debug_info.sh for printing commands + run: scripts/print_build_variables.sh # bash -x scripts/print_build_variables.sh for printing commands - - name: Download CFML repository + - name: Create CFML and pyCFML directories shell: bash run: | scripts/create_cfml_repo_dir.sh - scripts/download_cfml_repo.sh + scripts/create_cfml_build_dir.sh + scripts/create_cfml_dist_dir.sh + scripts/create_pycfml_src_dir.sh + scripts/create_pycfml_build_dir.sh + scripts/create_pycfml_dist_dir.sh - - name: Build CFML static library + - name: Download CFML repository + shell: bash + run: scripts/download_cfml_repo.sh + + - name: Build CFML modules shell: bash run: | - scripts/create_cfml_build_dir.sh scripts/rename_global_deps_file.sh - scripts/build_cfml_objs.sh + scripts/build_cfml_modules_obj.sh scripts/delete_renamed_global_deps_file.sh - scripts/build_cfml_static_lib.sh - scripts/create_cfml_dist_dir.sh - scripts/copy_built_to_cfml_dist.sh - - name: Build und run CFML functional test programs (incl. benchmarks) - # 1st combination: this always fails with 'Undefined symbols...' error - # 2nd combination: this randomly fails with test__Simple_calc_powder__SrTiO3s 'forrtl: severe (157): Program Exception - access violation' - if: | - (runner.os != 'macOS' || matrix.toolchain.exe != 'ifort') - && - (runner.os != 'Windows' || matrix.toolchain.exe != 'ifx') + - name: Build CFML static library + shell: bash + run: scripts/build_cfml_static_lib.sh + + - name: Make CFML distribution + shell: bash + run: scripts/move_built_to_cfml_dist.sh + + - name: Build und run CFML functional test programs (without benchmarks) shell: bash run: | scripts/build_cfml_test_programs.sh + scripts/copy_cfml_test_programs_to_tests_dir.sh scripts/run_cfml_functional_tests_no_benchmarks.sh - scripts/run_cfml_functional_tests_with_benchmarks.sh - - - name: Push benchmark results to repository - uses: EndBug/add-and-commit@v9 - with: - add: '.benchmarks' - message: 'Auto push benchmark results by GitHub Action for ${{ runner.os }} + ${{ matrix.toolchain.exe }}' - pull: '--rebase --autostash' - - name: Download PYCFML repository + - name: Create pyCFML source code shell: bash - run: | - scripts/create_pycfml_repo_dir.sh - scripts/download_pycfml_repo.sh + run: scripts/create_pycfml_src.sh - - name: Copy powder_mod from CFML to PYCFML + - name: Build pyCFML modules shell: bash - run: scripts/copy_powder_mod_to_pycfml_repo.sh + run: scripts/build_pycfml_modules_obj.sh - - name: Build some PYCFML modules one by one + - name: Build pyCFML shared obj / dynamic library shell: bash run: | - scripts/create_pycfml_build_dir.sh - scripts/build_pycfml_objs.sh - scripts/build_pycfml_shared_objs_or_dynamic_libs.sh - scripts/create_pycfml_dist_dir.sh - scripts/copy_built_to_pycfml_dist.sh - scripts/change_runpath_for_built_pycfml.sh + scripts/build_pycfml_lib_obj.sh + scripts/build_pycfml_shared_obj_or_dynamic_lib.sh - - name: Copy extra files to PYCFML dist + - name: Make pyCFML distribution shell: bash run: | + scripts/copy_built_to_pycfml_dist.sh + scripts/change_runpath_for_built_pycfml.sh scripts/copy_extra_libs_to_pycfml_dist.sh + scripts/copy_py_api_files_to_pycfml_dist.sh scripts/copy_init_file_to_pycfml_dist.sh scripts/copy_cfml_databases_to_pycfml_dist.sh - - name: Create Python package wheel of PYCFML + - name: Create Python package wheel of pyCFML shell: bash run: | scripts/validate_pyproject_toml.sh scripts/create_pycfml_python_wheel.sh scripts/rename_pycfml_python_wheel.sh + scripts/detect_abi3_violations.sh + scripts/check_wheel_contents.sh + + - name: Install pyCFML from created Python package wheel + shell: bash + run: scripts/install_pycfml_from_wheel.sh + + - name: Run pyCFML unit tests + shell: bash + run: scripts/run_pycfml_unit_tests.sh - - name: Prepare for uploading Python package wheel of PYCFML + - name: Run pyCFML functional tests (without benchmarks) shell: bash - run: echo "WHEEL_DIR=$(python3 scripts.py --print-wheel-dir)" >> $GITHUB_ENV + run: scripts/run_pycfml_functional_tests_no_benchmarks.sh - - name: Upload zipped Python package wheel of PYCFML for next job + - name: Prepare for uploading Python package wheel of pyCFML + shell: bash + run: echo "WHEEL_DIR=$(python3 pybuild.py --print-wheel-dir)" >> $GITHUB_ENV + + - name: Upload zipped Python package wheel of pyCFML for next job uses: actions/upload-artifact@v4 - with: # if name or path modified, remember to UPDATE those in the download step of the next job + with: # if name or path modified, remember to UPDATE those in the download step of the next job name: pycfml-wheel_${{ matrix.os }}_${{ matrix.toolchain.exe }} # name (without .zip) of the zip file to be uploaded - path: ${{ env.WHEEL_DIR }} # all files from this directory are zipped + path: ${{ env.WHEEL_DIR }} # all files from this directory are zipped if-no-files-found: "error" compression-level: 0 - tests: # the second job + ############################################################################## + # JOB 2 + ############################################################################## + test: # current job name + + needs: build # previous job 'build' need to be finished first + + if: always() # start this job even if the previous job failed + + timeout-minutes: 30 + strategy: fail-fast: false matrix: - #os: [ubuntu-22.04, windows-2022, macos-12] - os: [ubuntu-22.04, windows-2022, macos-12, flyci-macos-14-m2] + os: [ubuntu-24.04, windows-2022, macos-12, macos-14] # [ubuntu-22.04, windows-2022, macos-13, flyci-macos-14-m2] toolchain: - { exe: gfortran, compiler: gcc, version: 13 } - { exe: ifort, compiler: intel-classic, version: "2021.10" } @@ -176,25 +202,21 @@ jobs: exclude: - os: macos-12 toolchain: { exe: ifx, compiler: intel, version: "2023.2" } # no support for macOS - - os: flyci-macos-14-m2 + - os: macos-14 toolchain: { exe: ifx, compiler: intel, version: "2023.2" } # no support for macOS on arm64 - - os: flyci-macos-14-m2 + - os: macos-14 toolchain: { exe: ifort, compiler: intel-classic, version: "2021.10" } # no support for macOS on arm64 runs-on: ${{ matrix.os }} - timeout-minutes: 30 - - needs: wheel # previous job need to be finished first - - steps: # job steps + steps: # job steps - name: Check-out repository uses: actions/checkout@v4 - name: Set up python environment uses: actions/setup-python@v5 with: - python-version: 3.11 + python-version: '3.11' - name: Upgrade package installer for Python shell: bash @@ -202,39 +224,37 @@ jobs: - name: Install Python dependences shell: bash - run: python3 -m pip install '.[test]' # test extras from pyproject.toml + run: pip install '.[ci,test]' # 'ci' and 'test' extras from pyproject.toml - name: Create job step scripts shell: bash run: > - python3 scripts.py + python3 pybuild.py + --create-scripts --platform ${{ runner.os }} --compiler ${{ matrix.toolchain.exe }} --mode debug --bash-syntax + --enable-backslash-escapes - - name: Prepare for downloading Python package wheel of PYCFML + - name: Prepare for downloading Python package wheel of pyCFML shell: bash - run: echo "WHEEL_DIR=$(python3 scripts.py --print-wheel-dir)" >> $GITHUB_ENV + run: echo "WHEEL_DIR=$(python3 pybuild.py --print-wheel-dir)" >> $GITHUB_ENV - - name: Download zipped PYCFML wheel from previous job + - name: Download zipped pyCFML wheel from previous job uses: actions/download-artifact@v4 - with: # name or path are taken from the upload step of the previous job - name: pycfml-wheel_${{ matrix.os }}_${{ matrix.toolchain.exe }} # name (without .zip) of the zipped artifact uploaded on the previous jobs - path: ${{ env.WHEEL_DIR }} # directory to extract downloaded zipped artifacts + with: # name or path are taken from the upload step of the previous job + name: pycfml-wheel_${{ matrix.os }}_${{ matrix.toolchain.exe }} # name (without .zip) of the zipped artifact uploaded on the previous jobs + path: ${{ env.WHEEL_DIR }} # directory to extract downloaded zipped artifacts - - name: Install PYCFML from downloaded Python package wheel (with dev extras) + - name: Install pyCFML from downloaded Python package wheel shell: bash run: scripts/install_pycfml_from_wheel.sh - - name: Run PYCFML unit tests + - name: Run pyCFML unit tests shell: bash run: scripts/run_pycfml_unit_tests.sh - - name: Run PYCFML powder_mod tests - shell: bash - run: scripts/run_powder_mod_tests.sh - - - name: Run PYCFML powder_mod main + - name: Run pyCFML functional tests (without benchmarks) shell: bash - run: scripts/run_powder_mod_main.sh + run: scripts/run_pycfml_functional_tests_no_benchmarks.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..0994015 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,300 @@ +name: release-build-and-test + +on: + push: + branches: + - "**" + pull_request: + branches: + - "**" + #schedule: + # - cron: '*/120 8-18 * * *' # every 2 hours from 8:00 to 18:00 every day + +jobs: + + ############################################################################## + # JOB 1 + ############################################################################## + build: # current job name + + timeout-minutes: 30 + + strategy: + fail-fast: false + matrix: + os: [ubuntu-24.04, windows-2022, macos-12, macos-14] # [ubuntu-22.04, windows-2022, macos-13, flyci-macos-14-m2] + python-version: ['3.10', '3.11', '3.12'] + toolchain: + - { exe: gfortran, compiler: gcc, version: 13 } + + runs-on: ${{ matrix.os }} + + steps: # job steps + - name: Check-out repository + uses: actions/checkout@v4 + + - name: Declare env variables on push only + if: github.event_name == 'push' + shell: bash + run: echo "BRANCH_NAME=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV + + - name: Declare env variables on pull_request only + if: github.event_name == 'pull_request' + shell: bash + run: echo "BRANCH_NAME=$GITHUB_HEAD_REF" >> $GITHUB_ENV + + - name: Set up Fortran compiler (FC) [all except Windows + gfortran] # except: use pre-installed gfortran + if: runner.os != 'Windows' || matrix.toolchain.exe != 'gfortran' + uses: fortran-lang/setup-fortran@v1 + id: setup-fortran + with: + compiler: ${{ matrix.toolchain.compiler }} + version: ${{ matrix.toolchain.version }} + + - name: Set up NMake build tool [Windows] + if: runner.os == 'Windows' + uses: ilammy/msvc-dev-cmd@v1 + + - name: Set up Python environment + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Upgrade package installer for Python + shell: bash + run: pip install --upgrade pip + + - name: Install Python dependences + shell: bash + run: pip install '.[ci,test]' # 'ci' and 'test' extras from pyproject.toml + + - name: Fix reinstalling gcc [macOS] # needed because of `brew reinstall gcc` + if: runner.os == 'macOS' + shell: bash + run: echo "MACOSX_DEPLOYMENT_TARGET=$(sw_vers -productVersion)" >> $GITHUB_ENV + + - name: Create build scripts in scripts/scripts + shell: bash + run: > + python3 pybuild.py + --create-scripts + --platform ${{ runner.os }} + --compiler ${{ matrix.toolchain.exe }} + --mode release + --bash-syntax + --enable-backslash-escapes + + - name: Print some build-specific variables + shell: bash + run: scripts/print_build_variables.sh # bash -x scripts/print_build_variables.sh for printing commands + + - name: Create scripts, CFML and pyCFML directories + shell: bash + run: | + scripts/create_cfml_repo_dir.sh + scripts/create_cfml_build_dir.sh + scripts/create_cfml_dist_dir.sh + scripts/create_pycfml_src_dir.sh + scripts/create_pycfml_build_dir.sh + scripts/create_pycfml_dist_dir.sh + + - name: Download CFML repository + shell: bash + run: scripts/download_cfml_repo.sh + + - name: Build CFML modules + shell: bash + run: | + scripts/rename_global_deps_file.sh + scripts/build_cfml_modules_obj.sh + scripts/delete_renamed_global_deps_file.sh + + - name: Build CFML static library + shell: bash + run: scripts/build_cfml_static_lib.sh + + - name: Make CFML distribution + shell: bash + run: scripts/move_built_to_cfml_dist.sh + + - name: Build und run CFML functional test programs (without benchmarks) + shell: bash + run: | + scripts/build_cfml_test_programs.sh + scripts/copy_cfml_test_programs_to_tests_dir.sh + scripts/run_cfml_functional_tests_no_benchmarks.sh + + - name: Create pyCFML source code + shell: bash + run: scripts/create_pycfml_src.sh + + - name: Build pyCFML modules + shell: bash + run: scripts/build_pycfml_modules_obj.sh + + - name: Build pyCFML shared obj / dynamic library + shell: bash + run: | + scripts/build_pycfml_lib_obj.sh + scripts/build_pycfml_shared_obj_or_dynamic_lib.sh + + - name: Make pyCFML distribution + shell: bash + run: | + scripts/copy_built_to_pycfml_dist.sh + scripts/change_runpath_for_built_pycfml.sh + scripts/copy_extra_libs_to_pycfml_dist.sh + scripts/copy_py_api_files_to_pycfml_dist.sh + scripts/copy_init_file_to_pycfml_dist.sh + scripts/copy_cfml_databases_to_pycfml_dist.sh + + - name: Create Python package wheel of pyCFML + shell: bash + run: | + scripts/validate_pyproject_toml.sh + scripts/create_pycfml_python_wheel.sh + scripts/rename_pycfml_python_wheel.sh + + - name: Install pyCFML from created Python package wheel + shell: bash + run: scripts/install_pycfml_from_wheel.sh + + - name: Run pyCFML unit tests + shell: bash + run: scripts/run_pycfml_unit_tests.sh + + - name: Run pyCFML functional tests (without benchmarks) + shell: bash + run: scripts/run_pycfml_functional_tests_no_benchmarks.sh + + - name: Prepare for uploading Python package wheel of pyCFML + shell: bash + run: | + echo "WHEEL_DIR=$(python3 pybuild.py --print-wheel-dir)" >> $GITHUB_ENV + echo "RELEASE_VERSION=$(python3 pybuild.py --print-release-version)" >> $GITHUB_ENV + echo "RELEASE_TITLE=$(python3 pybuild.py --print-release-title)" >> $GITHUB_ENV + + - name: Upload zipped Python package wheel of pyCFML for next job + uses: actions/upload-artifact@v4 + with: # if name or path modified, remember to UPDATE those in the download step of the next job + name: pycfml-wheel_${{ matrix.os }}_${{ matrix.python-version }} # name (without .zip) of the zip file to be uploaded + path: ${{ env.WHEEL_DIR }} # all files from this directory are zipped + if-no-files-found: "error" + compression-level: 0 + + - name: Upload Python package wheel to releases (non-master branch) + if: github.event_name == 'push' && env.BRANCH_NAME != 'master' + uses: ncipollo/release-action@v1 + with: + draft: true + prerelease: true + allowUpdates: true + replacesArtifacts: true + token: ${{ secrets.GITHUB_TOKEN }} + artifacts: "${{ env.WHEEL_DIR }}/*.whl" + tag: ${{ env.BRANCH_NAME }} + name: ${{ env.BRANCH_NAME }} + bodyFile: "RELEASE.md" + + - name: Upload Python package wheel to releases (master branch) + if: github.event_name == 'push' && env.BRANCH_NAME == 'master' + uses: ncipollo/release-action@v1 + with: + draft: true + prerelease: true + allowUpdates: true + replacesArtifacts: true + token: ${{ secrets.GITHUB_TOKEN }} + artifacts: "${{ env.WHEEL_DIR }}/*.whl" + tag: ${{ env.RELEASE_VERSION }} + name: ${{ env.RELEASE_TITLE }} + bodyFile: "RELEASE.md" + + ############################################################################## + # JOB 2 + ############################################################################## + test: # current job name + + needs: build # previous job 'build' need to be finished first + + if: always() # start this job even if the previous job failed + + timeout-minutes: 30 + + strategy: + fail-fast: false + matrix: + os: [ubuntu-24.04, windows-2022, macos-12, macos-14] # [ubuntu-22.04, windows-2022, macos-13, flyci-macos-14-m2] + python-version: ['3.10', '3.11', '3.12'] + toolchain: + - { exe: gfortran, compiler: gcc, version: 13 } + + runs-on: ${{ matrix.os }} + + steps: # job steps + - name: Check-out repository + uses: actions/checkout@v4 + + - name: Set up python environment + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Upgrade package installer for Python + shell: bash + run: python3 -m pip install --upgrade pip + + - name: Install Python dependences + shell: bash + run: pip install '.[ci,test]' # 'ci' and 'test' extras from pyproject.toml + + - name: Create job step scripts + shell: bash + run: > + python3 pybuild.py + --create-scripts + --platform ${{ runner.os }} + --compiler ${{ matrix.toolchain.exe }} + --mode release + --bash-syntax + --enable-backslash-escapes + + - name: Prepare for downloading Python package wheel of pyCFML + shell: bash + run: echo "WHEEL_DIR=$(python3 pybuild.py --print-wheel-dir)" >> $GITHUB_ENV + + - name: Download zipped pyCFML wheel from previous job + uses: actions/download-artifact@v4 + with: # name or path are taken from the upload step of the previous job + name: pycfml-wheel_${{ matrix.os }}_${{ matrix.python-version }} # name (without .zip) of the zipped artifact uploaded on the previous jobs + path: ${{ env.WHEEL_DIR }} # directory to extract downloaded zipped artifacts + + - name: Install pyCFML from downloaded Python package wheel + shell: bash + run: scripts/install_pycfml_from_wheel.sh + + - name: Run pyCFML unit tests + shell: bash + run: scripts/run_pycfml_unit_tests.sh + + - name: Run pyCFML functional tests (without benchmarks) + shell: bash + run: scripts/run_pycfml_functional_tests_no_benchmarks.sh + + - name: Run pyCFML functional tests and compare benchmark results + if: "!contains(github.event.head_commit.message, '[save benchmark results]')" + shell: bash + run: scripts/run_pycfml_functional_tests_with_benchmarks_compare.sh + + - name: Run pyCFML functional tests and save benchmark results + if: "contains(github.event.head_commit.message, '[save benchmark results]')" + shell: bash + run: scripts/run_pycfml_functional_tests_with_benchmarks_save.sh + + - name: Push benchmark results to repository + if: "contains(github.event.head_commit.message, '[save benchmark results]')" + uses: EndBug/add-and-commit@v9 + with: + add: '.benchmarks/pyCFML' + message: 'Auto push pyCFML benchmarks : ${{ github.workflow }} : ${{ matrix.os }} : ${{ matrix.python-version }}' + pull: '--rebase --autostash' diff --git a/.gitignore b/.gitignore index f35c6f5..6c3ced3 100644 --- a/.gitignore +++ b/.gitignore @@ -6,10 +6,23 @@ __pycache__ build *.spec +# Jupyter Notebook +.ipynb_checkpoints + +# PyCharm +.idea + # macOS .DS_Store -# Misc -.benchmarks/local +# Build +.venv crysfml* pycrysfml* +build +dist +repo +scripts + +# Misc +.benchmarks/local diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/COPYING.lesser b/COPYING.lesser new file mode 100644 index 0000000..153d416 --- /dev/null +++ b/COPYING.lesser @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. \ No newline at end of file diff --git a/LICENSE b/LICENSE index 96f1555..eafa644 100644 --- a/LICENSE +++ b/LICENSE @@ -1,19 +1,28 @@ -Copyright (c) 2018 The Python Packaging Authority +---------------------------------------------------- +Crystallographic Fortran Modules Library (CrysFML08) +---------------------------------------------------- -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +The CrysFML08 project is distributed under LGPL. In agreement with the +Intergovernmental Convention of the ILL, this software cannot be used +in military applications. -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +Copyright (C) 2019-2020 Institut Laue-Langevin (ILL), Grenoble, FRANCE + Universidad de La Laguna (ULL), Tenerife, SPAIN + Laboratoire Leon Brillouin(LLB), Saclay, FRANCE -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Authors: Juan Rodriguez-Carvajal (ILL) + Javier Gonzalez-Platas (ULL) + Nebil Ayape Katcho (ILL) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 3.0 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, see . \ No newline at end of file diff --git a/README.md b/README.md index 9662695..a4929fe 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,245 @@ -[![](http://github-actions.40ants.com/AndrewSazonov/TEST_PyCrysFML/matrix.svg)](https://github.com/AndrewSazonov/TEST_PyCrysFML/actions) +## About -This is a repository for testing the build process of both the fortran crystallographic library [CrysFML2008](https://code.ill.fr/rodriguez-carvajal/CrysFML2008) and its python interface [PyCrysFML08](https://code.ill.fr/scientific-software/PyCrysFML08). +This is a repository for creating a python library **pycrysfml** based on the new automatically generated Python API for the crystallographic library CrysFML2008 (Fortran 2008) from https://code.ill.fr/scientific-software/CrysFML2008. -Main steps: -* Clone the [CrysFML2008](https://code.ill.fr/rodriguez-carvajal/CrysFML2008) project. -* Build the CrysFML2008 lybrary with the `gfortran` or `ifort` fortran compiler using the [CMake](https://cmake.org/) or [FPM](https://fpm.fortran-lang.org/) build system. -* Clone the [PyCrysFML08](https://code.ill.fr/scientific-software/PyCrysFML08) project. -* Build selected PyCrysFML08 modules with `gfortran` or `ifort` -* Run tests with `pytest`. +## CI status -More details are in the [CI script](.github/workflows/main.yml). +### Status of CI jobs 'build' and 'tests' + +| Platform / Compiler | gfortran | ifx | ifort | nagfor | +| ------------------------- | -------- | ----------- | ------------- | ---------- | +| Windows 10 | ✅ | ❌1 | ✅ | ⚙️ Testing | +| Ubuntu 22.04 | ✅ | ✅ | ✅ | ⚙️ Testing | +| macOS 12 (Intel) | ✅ | Unsupported | ❌2 | ⚙️ Testing | +| macOS 14 (Apple Silicone) | ✅ | Unsupported | Unsupported | ⚙️ Testing | + +* ❌1 - Failed at the **Run pyCFML functional tests** step (**'tests'** job): + +``` +tests\functional_tests\pyCFML\...\test__powder_pattern_from_json.py . [ 33%] +Windows fatal exception: access violation + +Current thread 0x0000068c (most recent call first): + +... + +scripts/run_pycfml_functional_tests_no_benchmarks.sh: +line 2: 1359 Segmentation fault +``` +* ❌2 - Failed at the **Build pyCFML shared obj / dynamic library** step (**'build'** job): + +``` +Undefined symbols for architecture x86_64: + "_cfml_kvec_symmetry_mp_inlat_", referenced from: + _cfml_kvec_symmetry_mp_latsym_ in libCrysFML08.a(ksym_auxsub.o) + "_cfml_kvec_symmetry_mp_ltr_", referenced from: + _cfml_kvec_symmetry_mp_latsym_ in libCrysFML08.a(ksym_auxsub.o) + "_cfml_kvec_symmetry_mp_nlat_", referenced from: + _cfml_kvec_symmetry_mp_latsym_ in libCrysFML08.a(ksym_auxsub.o) +ld: symbol(s) not found for architecture x86_64 +``` + +## Installing + +### Standard installation + +The pycrysfml python package is currently in beta testing, with pre-releases being published on our own PyPi server. To test it, please install it using the PIP package manager with additional option as shown below. + +* Create and activate a python environment (_optional_) + + ***macOS and Linux*** + + ``` + python3.11 -m venv .venv + source .venv/bin/activate + ``` + + ***Windows*** + + ``` + python3.11 -m venv .venv + .venv\Scripts\activate + ``` + +* Upgrade the package installer for Python (_optional_) + + ``` + pip install --upgrade pip + ``` + +* Install pycrysfml using a link to our own online repository + + ``` + pip install pycrysfml --extra-index-url https://easyscience.github.io/pypi/ + ``` + +### Installation from source + +If the standard installation doesn't work for you, try building pycrysfml locally and installing it from the generated Python wheel. + +* Create and activate a python environment (_optional_) + + ***macOS and Linux*** + + ``` + python3.11 -m venv .venv + source .venv/bin/activate + ``` + + ***Windows*** + + ``` + python3.11 -m venv .venv + .venv\Scripts\activate + ``` + +* Upgrade the package installer for Python (_optional_) + + ``` + pip install --upgrade pip + ``` + +* Install Python dependences, including extras (ci and test) + + ``` + pip install '.[ci,test]' + ``` + +* Print possible options for creating job scripts (_optional_) + + ``` + python pybuild.py --help + ``` + +* Create job scripts with default options + + ``` + python pybuild.py --create-scripts + ``` + +* Print some build-specific variables (_optional_) + + ``` + scripts/print_build_variables.sh + ``` + +* Create CFML and pyCFML directories + + ``` + scripts/create_cfml_repo_dir.sh + scripts/create_cfml_build_dir.sh + scripts/create_cfml_dist_dir.sh + scripts/create_pycfml_src_dir.sh + scripts/create_pycfml_build_dir.sh + scripts/create_pycfml_dist_dir.sh + ``` + +* Download CFML repository + + ``` + scripts/download_cfml_repo.sh + ``` + +* Build CFML modules + + ``` + scripts/rename_global_deps_file.sh + scripts/build_cfml_modules_obj.sh + scripts/delete_renamed_global_deps_file.sh + ``` + +* Build CFML static library + + ``` + scripts/build_cfml_static_lib.sh + ``` + +* Make CFML distribution + + ``` + scripts/move_built_to_cfml_dist.sh + ``` + +* Build und run CFML functional test programs + + ``` + scripts/build_cfml_test_programs.sh + scripts/copy_cfml_test_programs_to_tests_dir.sh + scripts/run_cfml_functional_tests_no_benchmarks.sh + ``` + +* Create pyCFML source code + + ``` + scripts/create_pycfml_src.sh + ``` + +* Build pyCFML modules + + ``` + scripts/build_pycfml_modules_obj.sh + ``` + +* Build pyCFML shared obj / dynamic library + + ``` + scripts/build_pycfml_lib_obj.sh + scripts/build_pycfml_shared_obj_or_dynamic_lib.sh + ``` + +* Make pyCFML distribution + + ``` + scripts/copy_built_to_pycfml_dist.sh + scripts/change_runpath_for_built_pycfml.sh + scripts/copy_extra_libs_to_pycfml_dist.sh + scripts/copy_py_api_files_to_pycfml_dist.sh + scripts/copy_init_file_to_pycfml_dist.sh + scripts/copy_cfml_databases_to_pycfml_dist.sh + ``` + +* Create Python package wheel of pyCFML + + ``` + scripts/validate_pyproject_toml.sh + scripts/create_pycfml_python_wheel.sh + scripts/rename_pycfml_python_wheel.sh + ``` + +* Install pyCFML from Python package wheel (with dev extras) + + ``` + scripts/install_pycfml_from_wheel.sh + ``` + +* Run pyCFML unit tests + + ``` + scripts/run_pycfml_unit_tests.sh + ``` + +* Run pyCFML functional tests + + ``` + scripts/run_pycfml_functional_tests_no_benchmarks.sh + ``` + +## How to use + +### Compute the powder diffraction pattern + +Here is the simplest example of using pycrysfml to calculate a powder diffraction pattern from a Python dictionary, which contains a description of the crystallographic phase as well as parameters related to the instrument and experiment. + +Install the matplotlib package used in the example below: + +``` +pip install matplotlib +``` + +Run this example [srtio3-pattern-simulation.py](examples/pyCFML/cfml_utilities/powder_pattern_from_json/srtio3-pattern-simulation.py) to see the simulated powder diffraction pattern: + +``` +python examples/pyCFML/cfml_utilities/powder_pattern_from_json/srtio3-pattern-simulation.py +``` + +More features will be added as the project develops. diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 0000000..6a2d7ea --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,3 @@ +### Features + +- Performance has been improved as pycrysfml is now built with compiler optimisation level set to 3. diff --git a/tests/functional_tests/pycfml/srtio3-pm3m-pattern_Nebil-ifort.xy b/examples/pyCFML/cfml_utilities/powder_pattern_from_json/desired/srtio3-pm3m-pattern_Nebil-ifort.xy similarity index 100% rename from tests/functional_tests/pycfml/srtio3-pm3m-pattern_Nebil-ifort.xy rename to examples/pyCFML/cfml_utilities/powder_pattern_from_json/desired/srtio3-pm3m-pattern_Nebil-ifort.xy diff --git a/tests/functional_tests/pycfml/srtio3-pmmm-pattern_Andrew-ifort.xy b/examples/pyCFML/cfml_utilities/powder_pattern_from_json/desired/srtio3-pnma-pattern_Andrew-ifort.y similarity index 100% rename from tests/functional_tests/pycfml/srtio3-pmmm-pattern_Andrew-ifort.xy rename to examples/pyCFML/cfml_utilities/powder_pattern_from_json/desired/srtio3-pnma-pattern_Andrew-ifort.y diff --git a/examples/pyCFML/cfml_utilities/powder_pattern_from_json/srtio3-pattern-simulation.ipynb b/examples/pyCFML/cfml_utilities/powder_pattern_from_json/srtio3-pattern-simulation.ipynb new file mode 100644 index 0000000..4ceac23 --- /dev/null +++ b/examples/pyCFML/cfml_utilities/powder_pattern_from_json/srtio3-pattern-simulation.ipynb @@ -0,0 +1,801 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "9ecc4733", + "metadata": { + "ExecuteTime": { + "start_time": "2024-07-24T13:18:00.977161Z" + }, + "jupyter": { + "is_executing": true + }, + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "from bokeh.io import output_notebook\n", + "from bokeh.io import show\n", + "from bokeh.plotting import figure\n", + "import copy\n", + "import os\n", + "import numpy as np\n", + "\n", + "from pycrysfml import cfml_utilities\n", + "#from pycrysfml import crysfml08lib" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "d76d50fc", + "metadata": { + "ExecuteTime": { + "end_time": "2024-07-23T12:12:10.327309Z", + "start_time": "2024-07-23T12:12:10.317495Z" + }, + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + " \n", + "
\n", + " \n", + " Loading BokehJS ...\n", + "
\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "'use strict';\n", + "(function(root) {\n", + " function now() {\n", + " return new Date();\n", + " }\n", + "\n", + " const force = true;\n", + "\n", + " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", + " root._bokeh_onload_callbacks = [];\n", + " root._bokeh_is_loading = undefined;\n", + " }\n", + "\n", + "const JS_MIME_TYPE = 'application/javascript';\n", + " const HTML_MIME_TYPE = 'text/html';\n", + " const EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n", + " const CLASS_NAME = 'output_bokeh rendered_html';\n", + "\n", + " /**\n", + " * Render data to the DOM node\n", + " */\n", + " function render(props, node) {\n", + " const script = document.createElement(\"script\");\n", + " node.appendChild(script);\n", + " }\n", + "\n", + " /**\n", + " * Handle when an output is cleared or removed\n", + " */\n", + " function handleClearOutput(event, handle) {\n", + " function drop(id) {\n", + " const view = Bokeh.index.get_by_id(id)\n", + " if (view != null) {\n", + " view.model.document.clear()\n", + " Bokeh.index.delete(view)\n", + " }\n", + " }\n", + "\n", + " const cell = handle.cell;\n", + "\n", + " const id = cell.output_area._bokeh_element_id;\n", + " const server_id = cell.output_area._bokeh_server_id;\n", + "\n", + " // Clean up Bokeh references\n", + " if (id != null) {\n", + " drop(id)\n", + " }\n", + "\n", + " if (server_id !== undefined) {\n", + " // Clean up Bokeh references\n", + " const cmd_clean = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n", + " cell.notebook.kernel.execute(cmd_clean, {\n", + " iopub: {\n", + " output: function(msg) {\n", + " const id = msg.content.text.trim()\n", + " drop(id)\n", + " }\n", + " }\n", + " });\n", + " // Destroy server and session\n", + " const cmd_destroy = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n", + " cell.notebook.kernel.execute(cmd_destroy);\n", + " }\n", + " }\n", + "\n", + " /**\n", + " * Handle when a new output is added\n", + " */\n", + " function handleAddOutput(event, handle) {\n", + " const output_area = handle.output_area;\n", + " const output = handle.output;\n", + "\n", + " // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n", + " if ((output.output_type != \"display_data\") || (!Object.prototype.hasOwnProperty.call(output.data, EXEC_MIME_TYPE))) {\n", + " return\n", + " }\n", + "\n", + " const toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", + "\n", + " if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n", + " toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n", + " // store reference to embed id on output_area\n", + " output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", + " }\n", + " if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", + " const bk_div = document.createElement(\"div\");\n", + " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", + " const script_attrs = bk_div.children[0].attributes;\n", + " for (let i = 0; i < script_attrs.length; i++) {\n", + " toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n", + " toinsert[toinsert.length - 1].firstChild.textContent = bk_div.children[0].textContent\n", + " }\n", + " // store reference to server id on output_area\n", + " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", + " }\n", + " }\n", + "\n", + " function register_renderer(events, OutputArea) {\n", + "\n", + " function append_mime(data, metadata, element) {\n", + " // create a DOM node to render to\n", + " const toinsert = this.create_output_subarea(\n", + " metadata,\n", + " CLASS_NAME,\n", + " EXEC_MIME_TYPE\n", + " );\n", + " this.keyboard_manager.register_events(toinsert);\n", + " // Render to node\n", + " const props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", + " render(props, toinsert[toinsert.length - 1]);\n", + " element.append(toinsert);\n", + " return toinsert\n", + " }\n", + "\n", + " /* Handle when an output is cleared or removed */\n", + " events.on('clear_output.CodeCell', handleClearOutput);\n", + " events.on('delete.Cell', handleClearOutput);\n", + "\n", + " /* Handle when a new output is added */\n", + " events.on('output_added.OutputArea', handleAddOutput);\n", + "\n", + " /**\n", + " * Register the mime type and append_mime function with output_area\n", + " */\n", + " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", + " /* Is output safe? */\n", + " safe: true,\n", + " /* Index of renderer in `output_area.display_order` */\n", + " index: 0\n", + " });\n", + " }\n", + "\n", + " // register the mime type if in Jupyter Notebook environment and previously unregistered\n", + " if (root.Jupyter !== undefined) {\n", + " const events = require('base/js/events');\n", + " const OutputArea = require('notebook/js/outputarea').OutputArea;\n", + "\n", + " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", + " register_renderer(events, OutputArea);\n", + " }\n", + " }\n", + " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", + " root._bokeh_timeout = Date.now() + 5000;\n", + " root._bokeh_failed_load = false;\n", + " }\n", + "\n", + " const NB_LOAD_WARNING = {'data': {'text/html':\n", + " \"
\\n\"+\n", + " \"

\\n\"+\n", + " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", + " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", + " \"

\\n\"+\n", + " \"
    \\n\"+\n", + " \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n", + " \"
  • use INLINE resources instead, as so:
  • \\n\"+\n", + " \"
\\n\"+\n", + " \"\\n\"+\n", + " \"from bokeh.resources import INLINE\\n\"+\n", + " \"output_notebook(resources=INLINE)\\n\"+\n", + " \"\\n\"+\n", + " \"
\"}};\n", + "\n", + " function display_loaded(error = null) {\n", + " const el = document.getElementById(\"adc76d0c-c512-4ced-96d1-2b116381d8c0\");\n", + " if (el != null) {\n", + " const html = (() => {\n", + " if (typeof root.Bokeh === \"undefined\") {\n", + " if (error == null) {\n", + " return \"BokehJS is loading ...\";\n", + " } else {\n", + " return \"BokehJS failed to load.\";\n", + " }\n", + " } else {\n", + " const prefix = `BokehJS ${root.Bokeh.version}`;\n", + " if (error == null) {\n", + " return `${prefix} successfully loaded.`;\n", + " } else {\n", + " return `${prefix} encountered errors while loading and may not function as expected.`;\n", + " }\n", + " }\n", + " })();\n", + " el.innerHTML = html;\n", + "\n", + " if (error != null) {\n", + " const wrapper = document.createElement(\"div\");\n", + " wrapper.style.overflow = \"auto\";\n", + " wrapper.style.height = \"5em\";\n", + " wrapper.style.resize = \"vertical\";\n", + " const content = document.createElement(\"div\");\n", + " content.style.fontFamily = \"monospace\";\n", + " content.style.whiteSpace = \"pre-wrap\";\n", + " content.style.backgroundColor = \"rgb(255, 221, 221)\";\n", + " content.textContent = error.stack ?? error.toString();\n", + " wrapper.append(content);\n", + " el.append(wrapper);\n", + " }\n", + " } else if (Date.now() < root._bokeh_timeout) {\n", + " setTimeout(() => display_loaded(error), 100);\n", + " }\n", + " }\n", + "\n", + " function run_callbacks() {\n", + " try {\n", + " root._bokeh_onload_callbacks.forEach(function(callback) {\n", + " if (callback != null)\n", + " callback();\n", + " });\n", + " } finally {\n", + " delete root._bokeh_onload_callbacks\n", + " }\n", + " console.debug(\"Bokeh: all callbacks have finished\");\n", + " }\n", + "\n", + " function load_libs(css_urls, js_urls, callback) {\n", + " if (css_urls == null) css_urls = [];\n", + " if (js_urls == null) js_urls = [];\n", + "\n", + " root._bokeh_onload_callbacks.push(callback);\n", + " if (root._bokeh_is_loading > 0) {\n", + " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", + " return null;\n", + " }\n", + " if (js_urls == null || js_urls.length === 0) {\n", + " run_callbacks();\n", + " return null;\n", + " }\n", + " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", + " root._bokeh_is_loading = css_urls.length + js_urls.length;\n", + "\n", + " function on_load() {\n", + " root._bokeh_is_loading--;\n", + " if (root._bokeh_is_loading === 0) {\n", + " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", + " run_callbacks()\n", + " }\n", + " }\n", + "\n", + " function on_error(url) {\n", + " console.error(\"failed to load \" + url);\n", + " }\n", + "\n", + " for (let i = 0; i < css_urls.length; i++) {\n", + " const url = css_urls[i];\n", + " const element = document.createElement(\"link\");\n", + " element.onload = on_load;\n", + " element.onerror = on_error.bind(null, url);\n", + " element.rel = \"stylesheet\";\n", + " element.type = \"text/css\";\n", + " element.href = url;\n", + " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", + " document.body.appendChild(element);\n", + " }\n", + "\n", + " for (let i = 0; i < js_urls.length; i++) {\n", + " const url = js_urls[i];\n", + " const element = document.createElement('script');\n", + " element.onload = on_load;\n", + " element.onerror = on_error.bind(null, url);\n", + " element.async = false;\n", + " element.src = url;\n", + " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", + " document.head.appendChild(element);\n", + " }\n", + " };\n", + "\n", + " function inject_raw_css(css) {\n", + " const element = document.createElement(\"style\");\n", + " element.appendChild(document.createTextNode(css));\n", + " document.body.appendChild(element);\n", + " }\n", + "\n", + " const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.5.0.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.5.0.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.5.0.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.5.0.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-3.5.0.min.js\"];\n", + " const css_urls = [];\n", + "\n", + " const inline_js = [ function(Bokeh) {\n", + " Bokeh.set_log_level(\"info\");\n", + " },\n", + "function(Bokeh) {\n", + " }\n", + " ];\n", + "\n", + " function run_inline_js() {\n", + " if (root.Bokeh !== undefined || force === true) {\n", + " try {\n", + " for (let i = 0; i < inline_js.length; i++) {\n", + " inline_js[i].call(root, root.Bokeh);\n", + " }\n", + "\n", + " } catch (error) {display_loaded(error);throw error;\n", + " }if (force === true) {\n", + " display_loaded();\n", + " }} else if (Date.now() < root._bokeh_timeout) {\n", + " setTimeout(run_inline_js, 100);\n", + " } else if (!root._bokeh_failed_load) {\n", + " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", + " root._bokeh_failed_load = true;\n", + " } else if (force !== true) {\n", + " const cell = $(document.getElementById(\"adc76d0c-c512-4ced-96d1-2b116381d8c0\")).parents('.cell').data().cell;\n", + " cell.output_area.append_execute_result(NB_LOAD_WARNING)\n", + " }\n", + " }\n", + "\n", + " if (root._bokeh_is_loading === 0) {\n", + " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", + " run_inline_js();\n", + " } else {\n", + " load_libs(css_urls, js_urls, function() {\n", + " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", + " run_inline_js();\n", + " });\n", + " }\n", + "}(window));" + ], + "application/vnd.bokehjs_load.v0+json": "'use strict';\n(function(root) {\n function now() {\n return new Date();\n }\n\n const force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n const NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded(error = null) {\n const el = document.getElementById(\"adc76d0c-c512-4ced-96d1-2b116381d8c0\");\n if (el != null) {\n const html = (() => {\n if (typeof root.Bokeh === \"undefined\") {\n if (error == null) {\n return \"BokehJS is loading ...\";\n } else {\n return \"BokehJS failed to load.\";\n }\n } else {\n const prefix = `BokehJS ${root.Bokeh.version}`;\n if (error == null) {\n return `${prefix} successfully loaded.`;\n } else {\n return `${prefix} encountered errors while loading and may not function as expected.`;\n }\n }\n })();\n el.innerHTML = html;\n\n if (error != null) {\n const wrapper = document.createElement(\"div\");\n wrapper.style.overflow = \"auto\";\n wrapper.style.height = \"5em\";\n wrapper.style.resize = \"vertical\";\n const content = document.createElement(\"div\");\n content.style.fontFamily = \"monospace\";\n content.style.whiteSpace = \"pre-wrap\";\n content.style.backgroundColor = \"rgb(255, 221, 221)\";\n content.textContent = error.stack ?? error.toString();\n wrapper.append(content);\n el.append(wrapper);\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(() => display_loaded(error), 100);\n }\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error(url) {\n console.error(\"failed to load \" + url);\n }\n\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.5.0.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.5.0.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.5.0.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.5.0.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-3.5.0.min.js\"];\n const css_urls = [];\n\n const inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {\n }\n ];\n\n function run_inline_js() {\n if (root.Bokeh !== undefined || force === true) {\n try {\n for (let i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n\n } catch (error) {display_loaded(error);throw error;\n }if (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n const cell = $(document.getElementById(\"adc76d0c-c512-4ced-96d1-2b116381d8c0\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "output_notebook()\n", + "FIGURE_WIDTH = 990\n", + "FIGURE_HEIGHT = 300" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "4042fea98af92add", + "metadata": { + "ExecuteTime": { + "end_time": "2024-07-23T12:12:10.779123Z", + "start_time": "2024-07-23T12:12:10.776683Z" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'/Users/andrewsazonov/Development/github.com/EasyScience/TEST_PyCrysFML/.venv/lib/python3.11/site-packages/pycrysfml/Databases'" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "os.environ['CRYSFML_DB']" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "edaa54d891d63ec1", + "metadata": { + "ExecuteTime": { + "end_time": "2024-07-23T12:12:11.331354Z", + "start_time": "2024-07-23T12:12:11.328399Z" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'/Users/andrewsazonov/Development/github.com/EasyScience/TEST_PyCrysFML/examples/pyCFML/cfml_utilities/powder_pattern_from_json'" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "os.getcwd()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "3752d741", + "metadata": { + "ExecuteTime": { + "end_time": "2024-07-23T12:12:11.899990Z", + "start_time": "2024-07-23T12:12:11.896406Z" + } + }, + "outputs": [], + "source": [ + "STUDY_DICT_PM3M = {\n", + " \"phases\": [\n", + " {\n", + " \"SrTiO3\": {\n", + " \"_space_group_name_H-M_alt\": \"P m -3 m\",\n", + " \"_cell_length_a\": 3.9,\n", + " \"_cell_length_b\": 3.9,\n", + " \"_cell_length_c\": 3.9,\n", + " \"_cell_angle_alpha\": 90,\n", + " \"_cell_angle_beta\": 90,\n", + " \"_cell_angle_gamma\": 90,\n", + " \"_atom_site\": [\n", + " {\n", + " \"_label\": \"Sr\",\n", + " \"_type_symbol\": \"Sr\",\n", + " \"_fract_x\": 0.5,\n", + " \"_fract_y\": 0.5,\n", + " \"_fract_z\": 0.5,\n", + " \"_occupancy\": 1,\n", + " \"_adp_type\": \"Biso\",\n", + " \"_B_iso_or_equiv\": 0.40\n", + " },\n", + " {\n", + " \"_label\": \"Ti\",\n", + " \"_type_symbol\": \"Ti\",\n", + " \"_fract_x\": 0,\n", + " \"_fract_y\": 0,\n", + " \"_fract_z\": 0,\n", + " \"_occupancy\": 1,\n", + " \"_adp_type\": \"Biso\",\n", + " \"_B_iso_or_equiv\": 0.50\n", + " },\n", + " {\n", + " \"_label\": \"O\",\n", + " \"_type_symbol\": \"O\",\n", + " \"_fract_x\": 0.5,\n", + " \"_fract_y\": 0,\n", + " \"_fract_z\": 0,\n", + " \"_occupancy\": 1,\n", + " \"_adp_type\": \"Biso\",\n", + " \"_B_iso_or_equiv\": 0.65\n", + " }\n", + " ]\n", + " }\n", + " }\n", + " ],\n", + " \"experiments\": [\n", + " {\n", + " \"NPD\": {\n", + " \"_diffrn_source\": \"nuclear reactor\",\n", + " \"_diffrn_radiation_probe\": \"neutron\",\n", + " \"_diffrn_radiation_wavelength\": 1.27,\n", + " \"_pd_instr_resolution_u\": 0.02,\n", + " \"_pd_instr_resolution_v\": -0.02,\n", + " \"_pd_instr_resolution_w\": 0.12,\n", + " \"_pd_instr_resolution_x\": 0.0015,\n", + " \"_pd_instr_resolution_y\": 0,\n", + " \"_pd_instr_reflex_asymmetry_p1\": 0,\n", + " \"_pd_instr_reflex_asymmetry_p2\": 0,\n", + " \"_pd_instr_reflex_asymmetry_p3\": 0,\n", + " \"_pd_instr_reflex_asymmetry_p4\": 0,\n", + " \"_pd_meas_2theta_offset\": 0,\n", + " \"_pd_meas_2theta_range_min\": 1,\n", + " \"_pd_meas_2theta_range_max\": 140,\n", + " \"_pd_meas_2theta_range_inc\": 0.05\n", + " }\n", + " }\n", + " ]\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "f5f7bb5f040685cc", + "metadata": { + "ExecuteTime": { + "end_time": "2024-07-23T12:12:12.506873Z", + "start_time": "2024-07-23T12:12:12.503786Z" + } + }, + "outputs": [], + "source": [ + "# Help functions\n", + "\n", + "def generated_x_array(study_dict:dict):\n", + " experiment = study_dict['experiments'][0]['NPD']\n", + " start = experiment['_pd_meas_2theta_range_min']\n", + " stop = experiment['_pd_meas_2theta_range_max']\n", + " step = experiment['_pd_meas_2theta_range_inc']\n", + " x = np.arange(start=start, stop=stop+step, step=step)\n", + " return x\n", + "\n", + "def compute_pattern(study_dict:dict):\n", + " _, y = cfml_utilities.powder_pattern_from_json(study_dict) # returns x and y arrays\n", + " #_, y = crysfml08lib.f_powder_pattern_from_json(study_dict) # returns x and y arrays\n", + " return y" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "bfa4e963497909dd", + "metadata": { + "ExecuteTime": { + "end_time": "2024-07-23T12:12:13.146451Z", + "start_time": "2024-07-23T12:12:13.143147Z" + } + }, + "outputs": [], + "source": [ + "def compute_pattern__SrTiO3_Pm3m():\n", + " study_dict = copy.deepcopy(STUDY_DICT_PM3M)\n", + "\n", + " # x array\n", + " x = generated_x_array(study_dict)\n", + "\n", + " # desired y array\n", + " _, desired = np.loadtxt('desired/srtio3-pm3m-pattern_Nebil-ifort.xy', unpack=True)\n", + " desired = desired - 20.0 # remove background\n", + " desired = np.roll(desired, -1) # compensate for a 1-element shift in y data between old Nebil windows build and Andrew current gfortran build\n", + " \n", + " # set space group\n", + " study_dict['phases'][0]['SrTiO3']['_space_group_name_H-M_alt'] = 'P m -3 m'\n", + "\n", + " # actual y array\n", + " actual = compute_pattern(study_dict)\n", + " \n", + " # compare results\n", + " fig = figure(width=FIGURE_WIDTH, height=FIGURE_HEIGHT)\n", + " fig.line(x, desired, legend_label='desired', color='orangered', line_width=5)\n", + " fig.line(x, actual, legend_label='actual', color='steelblue', line_width=2)\n", + " fig.line(x, actual-desired, legend_label='diff', color='green', line_width=1)\n", + " show(fig)" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "7836d8d61ea9f2e6", + "metadata": { + "ExecuteTime": { + "end_time": "2024-07-23T12:12:13.915802Z", + "start_time": "2024-07-23T12:12:13.912942Z" + } + }, + "outputs": [], + "source": [ + "def compute_pattern__SrTiO3_Pnma():\n", + " study_dict = copy.deepcopy(STUDY_DICT_PM3M)\n", + "\n", + " # x array\n", + " x = generated_x_array(study_dict)\n", + "\n", + " # desired y array\n", + " desired = np.loadtxt('desired/srtio3-pnma-pattern_Andrew-ifort.y', unpack=True)\n", + " desired = desired - 20.0 # remove background\n", + " \n", + " # set space group\n", + " study_dict['phases'][0]['SrTiO3']['_space_group_name_H-M_alt'] = 'P n m a'\n", + "\n", + " # actual y array\n", + " actual = compute_pattern(study_dict)\n", + " \n", + " # compare results\n", + " fig = figure(width=FIGURE_WIDTH, height=FIGURE_HEIGHT)\n", + " fig.line(x, desired, legend_label='desired', color='orangered', line_width=5)\n", + " fig.line(x, actual, legend_label='actual', color='steelblue', line_width=2)\n", + " fig.line(x, actual-desired, legend_label='diff', color='green', line_width=1)\n", + " show(fig)" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "753b3bd7336cc49c", + "metadata": { + "ExecuteTime": { + "end_time": "2024-07-23T12:12:18.068406Z", + "start_time": "2024-07-23T12:12:17.988105Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + "
\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "(function(root) {\n", + " function embed_document(root) {\n", + " const docs_json = {\"46a6e200-396c-4469-afde-4130f3a7f2fc\":{\"version\":\"3.5.0\",\"title\":\"Bokeh Application\",\"roots\":[{\"type\":\"object\",\"name\":\"Figure\",\"id\":\"p1285\",\"attributes\":{\"width\":990,\"height\":300,\"x_range\":{\"type\":\"object\",\"name\":\"DataRange1d\",\"id\":\"p1286\"},\"y_range\":{\"type\":\"object\",\"name\":\"DataRange1d\",\"id\":\"p1287\"},\"x_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p1294\"},\"y_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p1295\"},\"title\":{\"type\":\"object\",\"name\":\"Title\",\"id\":\"p1292\"},\"renderers\":[{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p1325\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p1319\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p1320\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p1321\"},\"data\":{\"type\":\"map\",\"entries\":[[\"x\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"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\"},\"shape\":[2781],\"dtype\":\"float64\",\"order\":\"little\"}],[\"y\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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\"},\"shape\":[2781],\"dtype\":\"float64\",\"order\":\"little\"}]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p1326\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p1327\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1322\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"orangered\",\"line_width\":5}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1323\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"orangered\",\"line_alpha\":0.1,\"line_width\":5}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1324\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"orangered\",\"line_alpha\":0.2,\"line_width\":5}}}},{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p1336\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p1330\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p1331\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p1332\"},\"data\":{\"type\":\"map\",\"entries\":[[\"x\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"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\"},\"shape\":[2781],\"dtype\":\"float64\",\"order\":\"little\"}],[\"y\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"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\"},\"shape\":[2781],\"dtype\":\"float32\",\"order\":\"little\"}]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p1337\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p1338\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1333\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"steelblue\",\"line_width\":2}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1334\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"steelblue\",\"line_alpha\":0.1,\"line_width\":2}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1335\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"steelblue\",\"line_alpha\":0.2,\"line_width\":2}}}},{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p1346\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p1340\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p1341\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p1342\"},\"data\":{\"type\":\"map\",\"entries\":[[\"x\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"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\"},\"shape\":[2781],\"dtype\":\"float64\",\"order\":\"little\"}],[\"y\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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\"},\"shape\":[2781],\"dtype\":\"float64\",\"order\":\"little\"}]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p1347\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p1348\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1343\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"green\"}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1344\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"green\",\"line_alpha\":0.1}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1345\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"green\",\"line_alpha\":0.2}}}}],\"toolbar\":{\"type\":\"object\",\"name\":\"Toolbar\",\"id\":\"p1293\",\"attributes\":{\"tools\":[{\"type\":\"object\",\"name\":\"PanTool\",\"id\":\"p1306\"},{\"type\":\"object\",\"name\":\"WheelZoomTool\",\"id\":\"p1307\",\"attributes\":{\"renderers\":\"auto\"}},{\"type\":\"object\",\"name\":\"BoxZoomTool\",\"id\":\"p1308\",\"attributes\":{\"overlay\":{\"type\":\"object\",\"name\":\"BoxAnnotation\",\"id\":\"p1309\",\"attributes\":{\"syncable\":false,\"line_color\":\"black\",\"line_alpha\":1.0,\"line_width\":2,\"line_dash\":[4,4],\"fill_color\":\"lightgrey\",\"fill_alpha\":0.5,\"level\":\"overlay\",\"visible\":false,\"left\":{\"type\":\"number\",\"value\":\"nan\"},\"right\":{\"type\":\"number\",\"value\":\"nan\"},\"top\":{\"type\":\"number\",\"value\":\"nan\"},\"bottom\":{\"type\":\"number\",\"value\":\"nan\"},\"left_units\":\"canvas\",\"right_units\":\"canvas\",\"top_units\":\"canvas\",\"bottom_units\":\"canvas\",\"handles\":{\"type\":\"object\",\"name\":\"BoxInteractionHandles\",\"id\":\"p1315\",\"attributes\":{\"all\":{\"type\":\"object\",\"name\":\"AreaVisuals\",\"id\":\"p1314\",\"attributes\":{\"fill_color\":\"white\",\"hover_fill_color\":\"lightgray\"}}}}}}}},{\"type\":\"object\",\"name\":\"SaveTool\",\"id\":\"p1316\"},{\"type\":\"object\",\"name\":\"ResetTool\",\"id\":\"p1317\"},{\"type\":\"object\",\"name\":\"HelpTool\",\"id\":\"p1318\"}]}},\"left\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p1301\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p1302\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p1303\"},\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1304\"}}}],\"below\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p1296\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p1297\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p1298\"},\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1299\"}}}],\"center\":[{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1300\",\"attributes\":{\"axis\":{\"id\":\"p1296\"}}},{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1305\",\"attributes\":{\"dimension\":1,\"axis\":{\"id\":\"p1301\"}}},{\"type\":\"object\",\"name\":\"Legend\",\"id\":\"p1328\",\"attributes\":{\"items\":[{\"type\":\"object\",\"name\":\"LegendItem\",\"id\":\"p1329\",\"attributes\":{\"label\":{\"type\":\"value\",\"value\":\"desired\"},\"renderers\":[{\"id\":\"p1325\"}]}},{\"type\":\"object\",\"name\":\"LegendItem\",\"id\":\"p1339\",\"attributes\":{\"label\":{\"type\":\"value\",\"value\":\"actual\"},\"renderers\":[{\"id\":\"p1336\"}]}},{\"type\":\"object\",\"name\":\"LegendItem\",\"id\":\"p1349\",\"attributes\":{\"label\":{\"type\":\"value\",\"value\":\"diff\"},\"renderers\":[{\"id\":\"p1346\"}]}}]}}]}}]}};\n", + " const render_items = [{\"docid\":\"46a6e200-396c-4469-afde-4130f3a7f2fc\",\"roots\":{\"p1285\":\"d9add1df-c92b-4783-82b5-e867a42698c6\"},\"root_ids\":[\"p1285\"]}];\n", + " void root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", + " }\n", + " if (root.Bokeh !== undefined) {\n", + " embed_document(root);\n", + " } else {\n", + " let attempts = 0;\n", + " const timer = setInterval(function(root) {\n", + " if (root.Bokeh !== undefined) {\n", + " clearInterval(timer);\n", + " embed_document(root);\n", + " } else {\n", + " attempts++;\n", + " if (attempts > 100) {\n", + " clearInterval(timer);\n", + " console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n", + " }\n", + " }\n", + " }, 10, root)\n", + " }\n", + "})(window);" + ], + "application/vnd.bokehjs_exec.v0+json": "" + }, + "metadata": { + "application/vnd.bokehjs_exec.v0+json": { + "id": "p1285" + } + }, + "output_type": "display_data" + } + ], + "source": [ + "compute_pattern__SrTiO3_Pm3m()" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "452f3b490817c37e", + "metadata": { + "ExecuteTime": { + "end_time": "2024-07-23T12:12:22.123955Z", + "start_time": "2024-07-23T12:12:22.056113Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + "
\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "(function(root) {\n", + " function embed_document(root) {\n", + " const docs_json = {\"438c0aa8-0e21-4c8e-bfe3-7b81ce0b8588\":{\"version\":\"3.5.0\",\"title\":\"Bokeh Application\",\"roots\":[{\"type\":\"object\",\"name\":\"Figure\",\"id\":\"p1356\",\"attributes\":{\"width\":990,\"height\":300,\"x_range\":{\"type\":\"object\",\"name\":\"DataRange1d\",\"id\":\"p1357\"},\"y_range\":{\"type\":\"object\",\"name\":\"DataRange1d\",\"id\":\"p1358\"},\"x_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p1365\"},\"y_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p1366\"},\"title\":{\"type\":\"object\",\"name\":\"Title\",\"id\":\"p1363\"},\"renderers\":[{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p1396\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p1390\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p1391\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p1392\"},\"data\":{\"type\":\"map\",\"entries\":[[\"x\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"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\"},\"shape\":[2781],\"dtype\":\"float64\",\"order\":\"little\"}],[\"y\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABzr4jYqPwAAHOviNio/AAAc6+I2Kj8AABzr4jYqPwAAHOviNio/AAAc6+I2Kj8AABzr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\"},\"shape\":[2781],\"dtype\":\"float64\",\"order\":\"little\"}]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p1397\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p1398\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1393\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"orangered\",\"line_width\":5}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1394\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"orangered\",\"line_alpha\":0.1,\"line_width\":5}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1395\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"orangered\",\"line_alpha\":0.2,\"line_width\":5}}}},{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p1407\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p1401\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p1402\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p1403\"},\"data\":{\"type\":\"map\",\"entries\":[[\"x\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"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\"},\"shape\":[2781],\"dtype\":\"float64\",\"order\":\"little\"}],[\"y\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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\"},\"shape\":[2781],\"dtype\":\"float32\",\"order\":\"little\"}]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p1408\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p1409\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1404\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"steelblue\",\"line_width\":2}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1405\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"steelblue\",\"line_alpha\":0.1,\"line_width\":2}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1406\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"steelblue\",\"line_alpha\":0.2,\"line_width\":2}}}},{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p1417\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p1411\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p1412\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p1413\"},\"data\":{\"type\":\"map\",\"entries\":[[\"x\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"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\"},\"shape\":[2781],\"dtype\":\"float64\",\"order\":\"little\"}],[\"y\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMCxFIbgvgAAgGMVGdi+AAAAxzr/zb4AAACORfu2vgAAAOQUUK0+AAAAOfV3yj4AAICc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\"},\"shape\":[2781],\"dtype\":\"float64\",\"order\":\"little\"}]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p1418\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p1419\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1414\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"green\"}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1415\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"green\",\"line_alpha\":0.1}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1416\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"green\",\"line_alpha\":0.2}}}}],\"toolbar\":{\"type\":\"object\",\"name\":\"Toolbar\",\"id\":\"p1364\",\"attributes\":{\"tools\":[{\"type\":\"object\",\"name\":\"PanTool\",\"id\":\"p1377\"},{\"type\":\"object\",\"name\":\"WheelZoomTool\",\"id\":\"p1378\",\"attributes\":{\"renderers\":\"auto\"}},{\"type\":\"object\",\"name\":\"BoxZoomTool\",\"id\":\"p1379\",\"attributes\":{\"overlay\":{\"type\":\"object\",\"name\":\"BoxAnnotation\",\"id\":\"p1380\",\"attributes\":{\"syncable\":false,\"line_color\":\"black\",\"line_alpha\":1.0,\"line_width\":2,\"line_dash\":[4,4],\"fill_color\":\"lightgrey\",\"fill_alpha\":0.5,\"level\":\"overlay\",\"visible\":false,\"left\":{\"type\":\"number\",\"value\":\"nan\"},\"right\":{\"type\":\"number\",\"value\":\"nan\"},\"top\":{\"type\":\"number\",\"value\":\"nan\"},\"bottom\":{\"type\":\"number\",\"value\":\"nan\"},\"left_units\":\"canvas\",\"right_units\":\"canvas\",\"top_units\":\"canvas\",\"bottom_units\":\"canvas\",\"handles\":{\"type\":\"object\",\"name\":\"BoxInteractionHandles\",\"id\":\"p1386\",\"attributes\":{\"all\":{\"type\":\"object\",\"name\":\"AreaVisuals\",\"id\":\"p1385\",\"attributes\":{\"fill_color\":\"white\",\"hover_fill_color\":\"lightgray\"}}}}}}}},{\"type\":\"object\",\"name\":\"SaveTool\",\"id\":\"p1387\"},{\"type\":\"object\",\"name\":\"ResetTool\",\"id\":\"p1388\"},{\"type\":\"object\",\"name\":\"HelpTool\",\"id\":\"p1389\"}]}},\"left\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p1372\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p1373\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p1374\"},\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1375\"}}}],\"below\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p1367\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p1368\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p1369\"},\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1370\"}}}],\"center\":[{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1371\",\"attributes\":{\"axis\":{\"id\":\"p1367\"}}},{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1376\",\"attributes\":{\"dimension\":1,\"axis\":{\"id\":\"p1372\"}}},{\"type\":\"object\",\"name\":\"Legend\",\"id\":\"p1399\",\"attributes\":{\"items\":[{\"type\":\"object\",\"name\":\"LegendItem\",\"id\":\"p1400\",\"attributes\":{\"label\":{\"type\":\"value\",\"value\":\"desired\"},\"renderers\":[{\"id\":\"p1396\"}]}},{\"type\":\"object\",\"name\":\"LegendItem\",\"id\":\"p1410\",\"attributes\":{\"label\":{\"type\":\"value\",\"value\":\"actual\"},\"renderers\":[{\"id\":\"p1407\"}]}},{\"type\":\"object\",\"name\":\"LegendItem\",\"id\":\"p1420\",\"attributes\":{\"label\":{\"type\":\"value\",\"value\":\"diff\"},\"renderers\":[{\"id\":\"p1417\"}]}}]}}]}}]}};\n", + " const render_items = [{\"docid\":\"438c0aa8-0e21-4c8e-bfe3-7b81ce0b8588\",\"roots\":{\"p1356\":\"d151e1e7-533f-4f6c-a8fe-6c496ac4d711\"},\"root_ids\":[\"p1356\"]}];\n", + " void root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", + " }\n", + " if (root.Bokeh !== undefined) {\n", + " embed_document(root);\n", + " } else {\n", + " let attempts = 0;\n", + " const timer = setInterval(function(root) {\n", + " if (root.Bokeh !== undefined) {\n", + " clearInterval(timer);\n", + " embed_document(root);\n", + " } else {\n", + " attempts++;\n", + " if (attempts > 100) {\n", + " clearInterval(timer);\n", + " console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n", + " }\n", + " }\n", + " }, 10, root)\n", + " }\n", + "})(window);" + ], + "application/vnd.bokehjs_exec.v0+json": "" + }, + "metadata": { + "application/vnd.bokehjs_exec.v0+json": { + "id": "p1356" + } + }, + "output_type": "display_data" + } + ], + "source": [ + "compute_pattern__SrTiO3_Pnma()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "50adfcd5c4bb70ea", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/pyCFML/cfml_utilities/powder_pattern_from_json/srtio3-pattern-simulation.py b/examples/pyCFML/cfml_utilities/powder_pattern_from_json/srtio3-pattern-simulation.py new file mode 100644 index 0000000..4e0a9a6 --- /dev/null +++ b/examples/pyCFML/cfml_utilities/powder_pattern_from_json/srtio3-pattern-simulation.py @@ -0,0 +1,77 @@ +import matplotlib.pyplot as plt +from pycrysfml import cfml_utilities + +EXAMPLE = { + "phases": [ + { + "SrTiO3": { + "_space_group_name_H-M_alt": "P m -3 m", + "_cell_length_a": 3.9, + "_cell_length_b": 3.9, + "_cell_length_c": 3.9, + "_cell_angle_alpha": 90, + "_cell_angle_beta": 90, + "_cell_angle_gamma": 90, + "_atom_site": [ + { + "_label": "Sr", + "_type_symbol": "Sr", + "_fract_x": 0.5, + "_fract_y": 0.5, + "_fract_z": 0.5, + "_occupancy": 1, + "_adp_type": "Biso", + "_B_iso_or_equiv": 0.40 + }, + { + "_label": "Ti", + "_type_symbol": "Ti", + "_fract_x": 0, + "_fract_y": 0, + "_fract_z": 0, + "_occupancy": 1, + "_adp_type": "Biso", + "_B_iso_or_equiv": 0.50 + }, + { + "_label": "O", + "_type_symbol": "O", + "_fract_x": 0.5, + "_fract_y": 0, + "_fract_z": 0, + "_occupancy": 1, + "_adp_type": "Biso", + "_B_iso_or_equiv": 0.65 + } + ] + } + } + ], + "experiments": [ + { + "NPD": { + "_diffrn_source": "nuclear reactor", + "_diffrn_radiation_probe": "neutron", + "_diffrn_radiation_wavelength": 1.27, + "_pd_instr_resolution_u": 0.02, + "_pd_instr_resolution_v": -0.02, + "_pd_instr_resolution_w": 0.12, + "_pd_instr_resolution_x": 0.0015, + "_pd_instr_resolution_y": 0, + "_pd_instr_reflex_asymmetry_p1": 0, + "_pd_instr_reflex_asymmetry_p2": 0, + "_pd_instr_reflex_asymmetry_p3": 0, + "_pd_instr_reflex_asymmetry_p4": 0, + "_pd_meas_2theta_offset": 0, + "_pd_meas_2theta_range_min": 1, + "_pd_meas_2theta_range_max": 140, + "_pd_meas_2theta_range_inc": 0.05 + } + } + ] +} + +if __name__ == '__main__': + x, y = cfml_utilities.powder_pattern_from_json(EXAMPLE) + plt.plot(x, y) + plt.show() diff --git a/issues/pyCFML/cfml_utilities/powder_pattern_from_json/first-calc_vs_second-calc/first-calc_vs_second-calc.png b/issues/pyCFML/cfml_utilities/powder_pattern_from_json/first-calc_vs_second-calc/first-calc_vs_second-calc.png new file mode 100644 index 0000000000000000000000000000000000000000..1f566ce8371050866fd77101cdd3f9001047f81c GIT binary patch literal 38908 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

)&54#I6@o|SW)W+ejy7+O^SKIQ?jnb1dM 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 BU)ulx literal 0 HcmV?d00001 diff --git a/issues/pyCFML/cfml_utilities/powder_pattern_from_json/first-calc_vs_second-calc/script.py b/issues/pyCFML/cfml_utilities/powder_pattern_from_json/first-calc_vs_second-calc/script.py new file mode 100644 index 0000000..8f37d2c --- /dev/null +++ b/issues/pyCFML/cfml_utilities/powder_pattern_from_json/first-calc_vs_second-calc/script.py @@ -0,0 +1,155 @@ +import argparse +import copy +import os +import matplotlib.pyplot as plt +import numpy as np + +from pycrysfml import cfml_utilities +#from pycrysfml import crysfml08lib + + +STUDY_DICT_PM3M = { + "phases": [ + { + "SrTiO3": { + "_space_group_name_H-M_alt": "P m -3 m", + "_cell_length_a": 3.9, + "_cell_length_b": 3.9, + "_cell_length_c": 3.9, + "_cell_angle_alpha": 90, + "_cell_angle_beta": 90, + "_cell_angle_gamma": 90, + "_atom_site": [ + { + "_label": "Sr", + "_type_symbol": "Sr", + "_fract_x": 0.5, + "_fract_y": 0.5, + "_fract_z": 0.5, + "_occupancy": 1, + "_adp_type": "Biso", + "_B_iso_or_equiv": 0.40 + }, + { + "_label": "Ti", + "_type_symbol": "Ti", + "_fract_x": 0, + "_fract_y": 0, + "_fract_z": 0, + "_occupancy": 1, + "_adp_type": "Biso", + "_B_iso_or_equiv": 0.50 + }, + { + "_label": "O", + "_type_symbol": "O", + "_fract_x": 0.5, + "_fract_y": 0, + "_fract_z": 0, + "_occupancy": 1, + "_adp_type": "Biso", + "_B_iso_or_equiv": 0.65 + } + ] + } + } + ], + "experiments": [ + { + "NPD": { + "_diffrn_source": "nuclear reactor", + "_diffrn_radiation_probe": "neutron", + "_diffrn_radiation_wavelength": 1.27, + "_pd_instr_resolution_u": 0.02, + "_pd_instr_resolution_v": -0.02, + "_pd_instr_resolution_w": 0.12, + "_pd_instr_resolution_x": 0.0015, + "_pd_instr_resolution_y": 0, + "_pd_instr_reflex_asymmetry_p1": 0, + "_pd_instr_reflex_asymmetry_p2": 0, + "_pd_instr_reflex_asymmetry_p3": 0, + "_pd_instr_reflex_asymmetry_p4": 0, + "_pd_meas_2theta_offset": 0, + "_pd_meas_2theta_range_min": 1, + "_pd_meas_2theta_range_max": 140, + "_pd_meas_2theta_range_inc": 0.05 + } + } + ] +} + +# Help functions + +def parsed_args(): + parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter) + parser.add_argument("--calc", + default="none", + choices=['none', 'pm3m', 'pnma-then-pm3m'], + type=str.lower, + help="calculation order: only SG Pm-3m, or first SG Pnma and then SG Pm-3m") + parser.add_argument("--plot", + action='store_true', + help="plot simulated patterns after previous runs") + return parser.parse_args() + +def generated_x_array(study_dict:dict): + experiment = study_dict['experiments'][0]['NPD'] + start = experiment['_pd_meas_2theta_range_min'] + stop = experiment['_pd_meas_2theta_range_max'] + step = experiment['_pd_meas_2theta_range_inc'] + x = np.arange(start=start, stop=stop+step, step=step) + return x + +def compute_pattern(study_dict:dict): + _, y = cfml_utilities.powder_pattern_from_json(study_dict) # returns x and y arrays + #_, y = crysfml08lib.f_powder_pattern_from_json(study_dict) # returns x and y arrays + y = y.astype(np.float64) + return y + +# Main + +if __name__ == '__main__': + ARGS = parsed_args() + + if ARGS.calc == 'pm3m': + study_dict = copy.deepcopy(STUDY_DICT_PM3M) + + y_pm3m = compute_pattern(study_dict) + + file_name = 'y-pm3m_first-calc.txt' + np.savetxt(file_name, y_pm3m, fmt='%10.2f') + + sg = study_dict['phases'][0]['SrTiO3']['_space_group_name_H-M_alt'] + print(f"First calculation for SG '{sg}' saved into '{file_name}'") + + if ARGS.calc == 'pnma-then-pm3m': + study_dict = copy.deepcopy(STUDY_DICT_PM3M) + + study_dict['phases'][0]['SrTiO3']['_space_group_name_H-M_alt'] = 'P n m a' + y_pnma = compute_pattern(study_dict) + + study_dict['phases'][0]['SrTiO3']['_space_group_name_H-M_alt'] = 'P m -3 m' + y_pm3m = compute_pattern(study_dict) + + file_name = 'y-pm3m_second-calc.txt' + np.savetxt(file_name, y_pm3m, fmt='%10.2f') + + sg = study_dict['phases'][0]['SrTiO3']['_space_group_name_H-M_alt'] + print(f"Second calculation for SG '{sg}' saved into '{file_name}'") + + if ARGS.plot: + study_dict = copy.deepcopy(STUDY_DICT_PM3M) + + x = generated_x_array(study_dict) + + y_pm3m_1 = np.loadtxt('y-pm3m_first-calc.txt', unpack=True) + y_pm3m_2 = np.loadtxt('y-pm3m_second-calc.txt', unpack=True) + + plt.plot(x, y_pm3m_1, '-', linewidth=3) + plt.plot(x, y_pm3m_2, '-', linewidth=2) + plt.plot(x, y_pm3m_1-y_pm3m_2, '-') + #plt.xlim([31, 35]) + + plt.legend(["Pm-3m, first calc", "Pm-3m, second calc", "diff"]) + + plt.show() diff --git a/issues/pyCFML/cfml_utilities/powder_pattern_from_json/first-calc_vs_second-calc/y-pm3m_first-calc.txt b/issues/pyCFML/cfml_utilities/powder_pattern_from_json/first-calc_vs_second-calc/y-pm3m_first-calc.txt new file mode 100644 index 0000000..d00786d --- /dev/null +++ b/issues/pyCFML/cfml_utilities/powder_pattern_from_json/first-calc_vs_second-calc/y-pm3m_first-calc.txt @@ -0,0 +1,2781 @@ + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.32 + 0.32 + 0.32 + 0.33 + 0.33 + 0.33 + 0.34 + 0.34 + 0.35 + 0.35 + 0.35 + 0.36 + 0.36 + 0.37 + 0.37 + 0.38 + 0.38 + 0.38 + 0.39 + 0.39 + 0.40 + 0.40 + 0.41 + 0.41 + 0.42 + 0.43 + 0.43 + 0.44 + 0.44 + 0.45 + 0.45 + 0.46 + 0.47 + 0.47 + 0.48 + 0.48 + 0.49 + 0.50 + 0.51 + 0.51 + 0.52 + 0.53 + 0.53 + 0.54 + 0.55 + 0.56 + 0.57 + 0.57 + 0.58 + 0.59 + 0.60 + 0.61 + 0.62 + 0.63 + 0.64 + 0.65 + 0.66 + 0.67 + 0.68 + 0.69 + 0.70 + 0.72 + 0.73 + 0.74 + 0.75 + 0.77 + 0.78 + 0.79 + 0.81 + 0.82 + 0.84 + 0.85 + 0.87 + 0.88 + 0.90 + 0.92 + 0.93 + 0.95 + 0.97 + 0.99 + 1.01 + 1.03 + 1.05 + 1.07 + 1.09 + 1.11 + 1.14 + 1.16 + 1.19 + 1.21 + 1.24 + 1.27 + 1.29 + 1.32 + 1.35 + 1.39 + 1.42 + 1.45 + 1.49 + 1.52 + 1.56 + 1.60 + 1.64 + 1.68 + 1.72 + 1.77 + 1.82 + 1.86 + 1.91 + 1.97 + 2.02 + 2.08 + 2.14 + 2.20 + 2.27 + 2.34 + 2.41 + 2.48 + 2.56 + 2.64 + 2.73 + 2.82 + 2.91 + 3.01 + 3.12 + 3.23 + 3.34 + 3.46 + 3.59 + 3.73 + 3.88 + 4.03 + 4.19 + 4.36 + 4.55 + 4.74 + 4.95 + 5.17 + 5.41 + 5.66 + 5.93 + 6.23 + 6.54 + 6.88 + 7.24 + 7.64 + 8.07 + 8.53 + 9.04 + 9.59 + 10.19 + 10.86 + 11.59 + 12.39 + 13.28 + 14.27 + 15.38 + 16.61 + 18.02 + 19.59 + 21.38 + 23.42 + 25.76 + 28.47 + 31.62 + 35.31 + 39.70 + 44.97 + 51.51 + 60.13 + 72.95 + 95.31 + 139.93 + 233.61 + 425.24 + 789.42 + 1415.86 + 2375.31 + 3665.35 + 5158.28 + 6587.53 + 7597.92 + 7873.27 + 7316.11 + 6118.36 + 4629.26 + 3183.44 + 2001.29 + 1162.52 + 637.44 + 343.23 + 192.90 + 120.58 + 85.87 + 67.78 + 56.81 + 49.06 + 43.02 + 38.09 + 33.96 + 30.47 + 27.48 + 24.91 + 22.68 + 20.74 + 19.03 + 17.53 + 16.19 + 15.00 + 13.94 + 12.99 + 12.13 + 11.35 + 10.64 + 10.00 + 9.42 + 8.88 + 8.39 + 7.94 + 7.53 + 7.14 + 6.79 + 6.46 + 6.15 + 5.87 + 5.60 + 5.36 + 5.12 + 4.91 + 4.71 + 4.52 + 4.34 + 4.17 + 4.01 + 3.86 + 3.72 + 3.59 + 3.46 + 3.34 + 3.23 + 3.12 + 3.02 + 2.92 + 2.83 + 2.74 + 2.66 + 2.58 + 2.50 + 2.43 + 2.36 + 2.30 + 2.23 + 2.17 + 2.11 + 2.06 + 2.01 + 1.96 + 1.91 + 1.86 + 1.82 + 1.77 + 1.73 + 1.69 + 1.65 + 1.62 + 1.58 + 1.55 + 1.52 + 1.49 + 1.46 + 1.43 + 1.40 + 1.37 + 1.35 + 1.32 + 1.30 + 1.28 + 1.26 + 1.24 + 1.22 + 1.20 + 1.71 + 1.70 + 1.69 + 1.68 + 1.67 + 1.66 + 1.66 + 1.65 + 1.65 + 1.64 + 1.64 + 1.64 + 1.64 + 1.64 + 1.64 + 1.64 + 1.65 + 1.65 + 1.66 + 1.67 + 1.67 + 1.69 + 1.70 + 1.71 + 1.73 + 1.75 + 1.77 + 1.79 + 1.82 + 1.85 + 1.88 + 1.92 + 1.96 + 2.00 + 2.06 + 2.11 + 2.18 + 2.26 + 2.34 + 2.44 + 2.56 + 2.69 + 2.85 + 3.04 + 3.27 + 3.55 + 3.93 + 4.52 + 5.59 + 7.77 + 12.31 + 21.44 + 38.31 + 66.37 + 107.74 + 161.00 + 219.43 + 271.24 + 302.35 + 302.43 + 271.46 + 219.75 + 161.34 + 108.07 + 66.67 + 38.58 + 21.70 + 12.57 + 8.04 + 5.88 + 4.84 + 4.28 + 3.92 + 3.67 + 3.47 + 3.31 + 3.19 + 3.08 + 3.00 + 2.93 + 2.87 + 2.83 + 2.80 + 2.46 + 2.45 + 2.44 + 2.44 + 2.44 + 2.45 + 2.46 + 2.48 + 2.50 + 2.53 + 2.56 + 2.59 + 2.63 + 2.67 + 2.71 + 2.75 + 2.80 + 2.85 + 2.91 + 2.96 + 3.03 + 3.09 + 3.26 + 3.33 + 3.41 + 3.49 + 3.57 + 3.66 + 3.75 + 3.85 + 3.95 + 4.06 + 4.17 + 4.29 + 4.41 + 4.54 + 4.68 + 4.82 + 4.98 + 5.13 + 5.30 + 5.48 + 5.67 + 5.86 + 6.07 + 6.29 + 6.53 + 6.77 + 7.03 + 7.31 + 7.61 + 7.92 + 8.26 + 8.62 + 9.00 + 9.41 + 9.84 + 10.31 + 10.82 + 11.36 + 11.95 + 12.58 + 13.27 + 14.01 + 14.82 + 15.71 + 16.67 + 17.73 + 18.89 + 20.18 + 21.59 + 23.17 + 24.92 + 26.88 + 29.07 + 31.55 + 34.36 + 37.57 + 41.23 + 45.46 + 50.37 + 56.11 + 62.89 + 70.98 + 80.85 + 93.44 + 110.99 + 139.34 + 192.84 + 303.51 + 533.79 + 987.28 + 1803.13 + 3117.95 + 4988.57 + 7298.56 + 9705.11 + 11671.96 + 12626.53 + 12237.66 + 10645.23 + 8355.85 + 5948.62 + 3860.85 + 2304.51 + 1286.99 + 695.07 + 383.47 + 230.98 + 158.17 + 121.49 + 100.34 + 86.03 + 75.16 + 66.38 + 59.09 + 53.21 + 47.98 + 43.49 + 39.61 + 36.23 + 33.28 + 30.68 + 28.38 + 26.34 + 24.52 + 22.90 + 21.43 + 20.12 + 18.92 + 17.84 + 16.86 + 15.97 + 15.15 + 14.40 + 13.72 + 13.09 + 12.51 + 11.97 + 11.48 + 11.03 + 10.61 + 10.22 + 9.86 + 9.53 + 9.22 + 8.93 + 8.67 + 8.43 + 8.20 + 8.00 + 7.81 + 7.64 + 7.48 + 7.33 + 7.20 + 7.09 + 6.97 + 6.88 + 6.80 + 6.74 + 6.69 + 6.65 + 6.62 + 6.61 + 6.61 + 6.63 + 6.66 + 6.70 + 6.77 + 6.85 + 6.95 + 7.07 + 7.22 + 7.39 + 7.59 + 7.83 + 8.10 + 8.41 + 8.78 + 9.20 + 9.68 + 10.24 + 10.90 + 11.66 + 12.56 + 13.61 + 14.87 + 16.38 + 18.24 + 20.61 + 23.95 + 29.38 + 39.65 + 60.91 + 105.06 + 191.72 + 347.04 + 596.30 + 949.20 + 1382.70 + 1831.01 + 2193.08 + 2362.30 + 2279.54 + 1974.53 + 1543.95 + 1095.53 + 709.39 + 423.27 + 237.19 + 129.44 + 72.91 + 45.29 + 32.06 + 25.35 + 21.45 + 18.78 + 16.76 + 15.12 + 13.76 + 12.62 + 11.66 + 10.83 + 10.13 + 9.52 + 8.99 + 8.53 + 8.13 + 7.78 + 7.48 + 7.21 + 6.98 + 6.78 + 6.61 + 6.46 + 6.33 + 6.23 + 6.14 + 6.07 + 6.02 + 5.98 + 5.96 + 5.95 + 5.96 + 5.98 + 6.01 + 6.06 + 6.12 + 6.20 + 6.29 + 6.39 + 6.51 + 6.65 + 6.81 + 6.98 + 7.17 + 7.39 + 7.62 + 7.88 + 8.17 + 8.49 + 8.84 + 9.23 + 9.66 + 10.13 + 10.66 + 11.24 + 11.88 + 12.60 + 13.41 + 14.30 + 15.31 + 16.45 + 17.74 + 19.21 + 20.89 + 22.82 + 25.05 + 27.65 + 30.18 + 33.79 + 38.13 + 43.44 + 50.29 + 60.01 + 76.08 + 106.88 + 170.70 + 302.31 + 557.44 + 1007.70 + 1717.84 + 2704.16 + 3889.11 + 5080.18 + 5996.65 + 6359.86 + 6040.76 + 5153.35 + 3971.24 + 2778.62 + 1775.35 + 1046.43 + 580.52 + 314.66 + 176.76 + 109.69 + 77.39 + 60.66 + 50.64 + 43.64 + 38.23 + 33.82 + 30.15 + 27.05 + 24.40 + 22.12 + 20.15 + 18.43 + 16.92 + 15.59 + 14.42 + 13.37 + 12.44 + 11.60 + 10.84 + 10.16 + 9.54 + 8.98 + 8.47 + 8.01 + 7.58 + 7.19 + 6.82 + 6.49 + 6.18 + 5.90 + 5.64 + 5.39 + 5.17 + 4.96 + 4.76 + 4.58 + 4.41 + 4.25 + 4.11 + 3.97 + 3.84 + 3.73 + 3.62 + 3.52 + 3.42 + 3.34 + 3.26 + 3.19 + 3.13 + 3.07 + 3.13 + 3.09 + 3.06 + 3.04 + 3.04 + 3.04 + 3.05 + 3.08 + 3.13 + 3.20 + 3.30 + 3.43 + 3.61 + 3.88 + 4.34 + 5.25 + 7.16 + 11.16 + 19.02 + 33.16 + 55.88 + 88.14 + 127.87 + 169.13 + 202.66 + 218.62 + 211.40 + 183.50 + 143.99 + 102.68 + 67.01 + 40.49 + 23.18 + 13.12 + 7.81 + 5.19 + 3.93 + 3.27 + 2.88 + 2.61 + 2.40 + 2.23 + 2.08 + 1.96 + 1.85 + 1.76 + 1.67 + 1.60 + 1.54 + 1.48 + 1.43 + 1.38 + 1.34 + 1.30 + 1.26 + 1.23 + 1.20 + 1.17 + 1.15 + 1.12 + 1.10 + 1.08 + 1.06 + 1.05 + 1.03 + 1.02 + 1.00 + 0.99 + 0.98 + 0.97 + 0.96 + 0.95 + 1.14 + 1.13 + 1.13 + 1.13 + 1.12 + 1.12 + 1.12 + 1.11 + 1.11 + 1.11 + 1.11 + 1.11 + 1.11 + 1.11 + 1.12 + 1.12 + 1.12 + 1.13 + 1.13 + 1.13 + 1.14 + 1.15 + 1.15 + 1.16 + 1.17 + 1.18 + 1.18 + 1.19 + 1.20 + 1.22 + 1.23 + 1.24 + 1.25 + 1.27 + 1.28 + 1.30 + 1.31 + 1.33 + 1.35 + 1.37 + 1.39 + 1.41 + 1.43 + 1.45 + 1.48 + 1.50 + 1.53 + 1.56 + 1.32 + 1.35 + 1.39 + 1.43 + 1.47 + 1.51 + 1.55 + 1.60 + 1.65 + 1.70 + 1.75 + 1.81 + 1.87 + 1.94 + 2.01 + 2.08 + 2.15 + 2.24 + 2.32 + 2.42 + 2.51 + 2.62 + 2.74 + 2.86 + 2.99 + 3.13 + 3.29 + 3.45 + 3.63 + 3.83 + 4.04 + 4.27 + 4.53 + 4.81 + 5.12 + 5.46 + 5.84 + 6.27 + 6.74 + 7.28 + 7.89 + 8.59 + 9.38 + 10.30 + 11.36 + 12.61 + 14.09 + 15.86 + 18.04 + 20.87 + 24.98 + 31.90 + 45.30 + 72.92 + 128.98 + 235.28 + 418.32 + 699.50 + 1079.08 + 1520.76 + 1946.66 + 2251.00 + 2337.41 + 2174.64 + 1820.04 + 1378.61 + 950.11 + 599.73 + 351.05 + 195.17 + 107.59 + 62.61 + 40.74 + 30.06 + 24.38 + 20.86 + 18.36 + 16.42 + 14.84 + 13.54 + 12.45 + 11.54 + 10.77 + 10.12 + 9.57 + 9.11 + 8.72 + 8.38 + 8.11 + 7.90 + 8.21 + 8.08 + 8.00 + 7.94 + 7.93 + 7.95 + 8.00 + 8.08 + 8.19 + 8.34 + 8.53 + 8.75 + 9.01 + 9.32 + 9.67 + 10.07 + 10.53 + 11.05 + 11.64 + 12.32 + 13.09 + 13.96 + 14.96 + 16.11 + 17.43 + 18.96 + 20.74 + 22.83 + 25.28 + 28.22 + 31.76 + 36.20 + 42.11 + 51.03 + 66.70 + 97.76 + 161.80 + 289.64 + 525.97 + 920.71 + 1506.84 + 2268.81 + 3116.77 + 3885.05 + 4369.00 + 4407.92 + 3987.59 + 3251.11 + 2403.17 + 1619.12 + 1001.87 + 577.62 + 318.99 + 176.99 + 105.13 + 70.23 + 52.83 + 43.16 + 36.88 + 32.25 + 28.56 + 25.53 + 22.98 + 20.82 + 18.97 + 17.43 + 16.06 + 14.85 + 13.80 + 12.88 + 12.06 + 11.33 + 10.68 + 10.11 + 9.59 + 9.13 + 8.71 + 8.33 + 7.99 + 7.69 + 7.41 + 7.16 + 6.93 + 6.73 + 6.55 + 6.39 + 6.24 + 6.11 + 6.00 + 5.90 + 5.81 + 5.74 + 5.69 + 5.65 + 5.62 + 5.60 + 5.61 + 5.63 + 5.67 + 5.73 + 5.82 + 5.94 + 6.11 + 6.39 + 6.89 + 7.88 + 9.91 + 13.95 + 21.40 + 33.80 + 52.19 + 76.07 + 102.66 + 126.79 + 142.06 + 143.44 + 130.44 + 107.52 + 81.06 + 56.56 + 37.25 + 23.98 + 15.91 + 11.53 + 9.37 + 8.39 + 7.98 + 7.83 + 7.80 + 7.95 + 8.03 + 8.14 + 8.28 + 8.45 + 8.65 + 8.87 + 9.12 + 9.40 + 9.70 + 10.03 + 10.40 + 10.79 + 11.23 + 11.70 + 12.21 + 12.77 + 13.37 + 14.04 + 14.76 + 15.55 + 16.42 + 17.38 + 18.43 + 19.59 + 20.77 + 22.20 + 23.80 + 25.58 + 27.58 + 29.84 + 32.40 + 35.31 + 38.65 + 42.49 + 46.95 + 52.16 + 58.30 + 65.61 + 74.49 + 85.67 + 100.88 + 124.40 + 166.73 + 251.21 + 423.74 + 761.46 + 1370.65 + 2360.71 + 3789.06 + 5588.65 + 7518.54 + 9177.23 + 10101.30 + 9975.15 + 8844.60 + 7082.46 + 5151.68 + 3423.06 + 2095.10 + 1200.58 + 664.17 + 372.97 + 226.31 + 154.60 + 118.08 + 97.12 + 83.11 + 72.58 + 64.13 + 57.14 + 51.26 + 46.27 + 41.99 + 38.31 + 35.11 + 32.32 + 29.87 + 27.71 + 25.81 + 24.12 + 22.61 + 21.27 + 20.07 + 19.00 + 18.04 + 17.18 + 16.41 + 15.72 + 15.11 + 14.56 + 14.08 + 13.67 + 13.31 + 13.01 + 12.77 + 12.59 + 12.47 + 12.21 + 12.22 + 12.31 + 12.48 + 12.75 + 13.13 + 13.65 + 14.35 + 15.30 + 16.68 + 18.93 + 23.14 + 31.68 + 49.22 + 83.58 + 145.45 + 245.86 + 390.45 + 572.38 + 767.45 + 935.13 + 1028.79 + 1016.45 + 902.58 + 724.61 + 529.30 + 354.00 + 218.97 + 127.72 + 72.75 + 42.78 + 27.60 + 20.14 + 16.32 + 14.13 + 12.66 + 11.57 + 10.70 + 9.98 + 9.39 + 8.90 + 8.49 + 8.14 + 7.86 + 7.62 + 7.43 + 7.29 + 7.17 + 7.09 + 7.05 + 7.03 + 7.05 + 7.09 + 7.16 + 7.27 + 7.40 + 7.58 + 7.78 + 8.03 + 8.33 + 8.67 + 9.07 + 9.54 + 10.08 + 10.71 + 11.44 + 12.29 + 13.28 + 14.45 + 15.83 + 17.47 + 19.46 + 21.92 + 25.13 + 29.75 + 37.43 + 52.00 + 81.48 + 140.40 + 251.09 + 440.66 + 731.54 + 1125.50 + 1587.73 + 2041.13 + 2377.43 + 2493.12 + 2346.73 + 1990.19 + 1530.32 + 1073.01 + 690.45 + 412.42 + 233.76 + 130.68 + 76.30 + 49.20 + 35.73 + 28.51 + 24.07 + 20.92 + 18.46 + 16.46 + 14.79 + 13.38 + 12.17 + 11.13 + 10.23 + 9.44 + 8.76 + 8.15 + 7.61 + 7.14 + 6.71 + 6.34 + 6.00 + 5.69 + 5.42 + 5.17 + 4.95 + 4.76 + 4.58 + 4.42 + 4.28 + 4.16 + 4.06 + 3.97 + 3.89 + 3.84 + 3.80 + 3.78 + 3.78 + 3.81 + 3.86 + 3.94 + 4.06 + 4.25 + 4.53 + 4.53 + 5.47 + 7.39 + 11.31 + 18.89 + 32.34 + 53.85 + 84.37 + 122.22 + 162.17 + 195.98 + 213.80 + 209.70 + 185.17 + 148.12 + 108.04 + 72.34 + 44.96 + 26.47 + 15.33 + 9.22 + 6.10 + 4.55 + 3.74 + 3.26 + 2.93 + 2.68 + 2.48 + 2.31 + 2.17 + 2.05 + 1.94 + 1.85 + 1.76 + 1.69 + 1.63 + 1.57 + 1.52 + 1.48 + 1.43 + 1.40 + 1.36 + 1.33 + 1.31 + 1.28 + 1.26 + 1.24 + 1.22 + 1.20 + 1.19 + 1.17 + 1.16 + 1.15 + 1.14 + 1.13 + 1.12 + 1.12 + 1.11 + 1.11 + 1.10 + 1.10 + 1.10 + 1.10 + 1.10 + 1.10 + 1.10 + 1.10 + 1.06 + 1.06 + 1.07 + 1.08 + 1.09 + 1.09 + 1.10 + 1.11 + 1.12 + 1.13 + 1.14 + 1.16 + 1.17 + 1.18 + 1.20 + 1.22 + 1.24 + 1.26 + 1.28 + 1.30 + 1.32 + 1.35 + 1.37 + 1.40 + 1.43 + 1.46 + 1.50 + 1.53 + 1.57 + 1.62 + 1.66 + 1.71 + 1.76 + 1.82 + 1.88 + 1.94 + 2.01 + 2.09 + 2.17 + 2.26 + 2.36 + 2.47 + 2.59 + 2.72 + 2.87 + 3.04 + 3.22 + 3.43 + 3.66 + 3.93 + 4.23 + 4.59 + 5.00 + 5.49 + 6.08 + 6.81 + 7.78 + 9.25 + 11.80 + 16.72 + 26.50 + 45.29 + 78.78 + 133.25 + 211.41 + 310.49 + 418.68 + 514.87 + 573.68 + 575.77 + 520.41 + 426.05 + 318.06 + 217.91 + 138.30 + 82.75 + 48.19 + 28.76 + 18.67 + 13.67 + 11.16 + 9.80 + 8.97 + 8.40 + 7.98 + 7.68 + 7.46 + 7.30 + 7.21 + 7.17 + 7.18 + 7.24 + 7.33 + 7.46 + 7.64 + 7.85 + 8.10 + 8.39 + 8.73 + 9.12 + 9.56 + 10.06 + 10.63 + 11.26 + 11.98 + 12.80 + 13.73 + 14.78 + 15.98 + 17.36 + 18.95 + 20.80 + 22.95 + 25.48 + 28.49 + 32.12 + 36.63 + 42.61 + 51.44 + 66.42 + 94.91 + 151.42 + 261.00 + 459.16 + 786.12 + 1269.65 + 1901.78 + 2617.53 + 3290.83 + 3756.72 + 3869.18 + 3588.15 + 3010.00 + 2299.20 + 1608.16 + 1037.16 + 624.18 + 358.54 + 204.36 + 122.01 + 80.23 + 58.98 + 47.32 + 40.02 + 34.80 + 30.73 + 27.41 + 24.64 + 22.29 + 20.29 + 18.57 + 17.08 + 15.79 + 14.66 + 13.66 + 12.79 + 12.01 + 11.33 + 10.72 + 10.18 + 9.69 + 9.26 + 8.87 + 8.53 + 8.22 + 7.95 + 7.71 + 7.49 + 7.31 + 7.15 + 7.02 + 6.91 + 6.83 + 6.78 + 6.75 + 6.75 + 6.79 + 6.87 + 7.02 + 7.29 + 7.80 + 8.83 + 11.11 + 15.14 + 22.38 + 34.15 + 51.33 + 73.47 + 98.15 + 120.94 + 136.16 + 139.01 + 128.50 + 108.19 + 83.74 + 60.24 + 40.98 + 27.14 + 18.31 + 13.23 + 10.58 + 9.31 + 8.73 + 8.50 + 8.42 + 8.44 + 8.51 + 8.62 + 8.77 + 8.95 + 9.18 + 9.43 + 9.72 + 10.04 + 10.41 + 10.81 + 11.26 + 11.75 + 12.30 + 12.90 + 13.57 + 14.31 + 15.12 + 16.03 + 17.04 + 18.17 + 19.44 + 20.86 + 22.46 + 24.28 + 26.35 + 28.72 + 31.45 + 34.62 + 38.31 + 42.65 + 47.83 + 54.13 + 62.11 + 73.04 + 89.94 + 119.79 + 177.21 + 289.32 + 499.49 + 864.55 + 1440.43 + 2253.15 + 3263.96 + 4346.25 + 5289.31 + 5845.60 + 5833.30 + 5256.90 + 4303.20 + 3220.40 + 2215.74 + 1412.56 + 846.26 + 488.72 + 283.70 + 174.61 + 118.83 + 89.81 + 73.32 + 62.64 + 54.83 + 48.68 + 43.63 + 39.41 + 35.84 + 32.81 + 30.21 + 27.97 + 26.05 + 24.38 + 22.93 + 21.68 + 20.59 + 19.66 + 18.86 + 18.18 + 17.61 + 17.14 + 16.77 + 16.50 + 16.32 + 16.23 + 16.24 + 16.35 + 16.57 + 16.90 + 17.36 + 17.97 + 18.75 + 19.73 + 20.96 + 22.49 + 24.43 + 27.01 + 30.72 + 36.78 + 47.84 + 69.33 + 110.92 + 187.25 + 316.47 + 514.55 + 785.72 + 1112.28 + 1448.60 + 1725.35 + 1866.53 + 1825.02 + 1615.34 + 1302.63 + 963.14 + 656.79 + 417.16 + 250.87 + 147.20 + 88.22 + 56.92 + 40.83 + 32.35 + 27.43 + 24.20 + 21.82 + 19.94 + 18.42 + 17.17 + 16.13 + 15.27 + 14.57 + 13.99 + 13.52 + 13.15 + 12.87 + 12.67 + 12.54 + 12.49 + 12.51 + 12.59 + 12.75 + 12.98 + 13.28 + 13.66 + 14.14 + 14.70 + 15.38 + 16.18 + 17.11 + 18.21 + 19.50 + 21.02 + 22.81 + 24.92 + 27.44 + 30.49 + 34.25 + 39.15 + 46.12 + 57.45 + 77.78 + 116.83 + 191.45 + 326.88 + 553.70 + 898.13 + 1366.15 + 1926.08 + 2500.13 + 2970.58 + 3209.36 + 3137.52 + 2780.00 + 2246.58 + 1666.20 + 1140.76 + 726.94 + 437.74 + 255.79 + 151.23 + 95.16 + 66.04 + 50.55 + 41.52 + 35.55 + 31.12 + 27.60 + 24.68 + 22.23 + 20.13 + 18.33 + 16.78 + 15.42 + 14.23 + 13.18 + 12.26 + 11.43 + 10.70 + 10.04 + 9.44 + 8.91 + 8.43 + 7.99 + 7.59 + 7.23 + 6.90 + 6.60 + 6.33 + 6.08 + 5.86 + 5.65 + 5.47 + 5.31 + 5.17 + 5.05 + 4.95 + 4.87 + 4.81 + 4.79 + 4.82 + 5.06 + 5.37 + 6.06 + 7.47 + 10.16 + 14.83 + 22.18 + 32.54 + 45.51 + 59.58 + 72.23 + 80.35 + 81.41 + 75.02 + 63.23 + 49.14 + 35.53 + 23.87 + 15.53 + 10.03 + 6.71 + 4.86 + 3.86 + 3.32 + 3.01 + 2.80 + 2.65 + 2.53 + 2.42 + 2.33 + 2.26 + 2.19 + 2.13 + 2.07 + 2.02 + 1.98 + 1.94 + 1.90 + 1.87 + 1.84 + 1.82 + 1.79 + 1.77 + 1.75 + 1.73 + 1.72 + 1.70 + 1.69 + 1.68 + 1.67 + 1.66 + 1.66 + 1.65 + 1.65 + 1.65 + 1.65 + 1.65 + 1.65 + 1.65 + 1.65 + 1.66 + 1.66 + 1.69 + 1.69 + 1.70 + 1.72 + 1.73 + 1.74 + 1.76 + 1.78 + 1.79 + 1.81 + 1.84 + 1.86 + 1.89 + 1.91 + 1.94 + 1.97 + 2.01 + 1.94 + 1.98 + 2.02 + 2.06 + 2.11 + 2.16 + 2.22 + 2.27 + 2.33 + 2.40 + 2.47 + 2.55 + 2.63 + 2.71 + 2.80 + 2.90 + 3.01 + 3.12 + 3.25 + 3.38 + 3.52 + 3.68 + 3.85 + 4.03 + 4.23 + 4.45 + 4.68 + 4.95 + 5.24 + 5.55 + 5.91 + 6.30 + 6.74 + 7.23 + 7.78 + 8.40 + 9.11 + 9.92 + 10.85 + 11.93 + 13.19 + 14.68 + 16.46 + 18.67 + 21.56 + 25.75 + 32.97 + 45.22 + 68.12 + 110.30 + 183.90 + 302.64 + 477.15 + 707.71 + 977.58 + 1249.59 + 1469.67 + 1580.07 + 1545.57 + 1377.69 + 1126.08 + 849.32 + 594.42 + 388.92 + 241.28 + 145.27 + 88.07 + 56.26 + 39.25 + 30.09 + 24.81 + 21.43 + 19.00 + 17.11 + 15.58 + 14.31 + 13.26 + 12.37 + 11.62 + 11.00 + 10.47 + 10.03 + 9.67 + 9.38 + 9.14 + 8.97 + 8.84 + 8.77 + 8.74 + 8.76 + 8.82 + 8.94 + 9.10 + 9.31 + 9.58 + 9.90 + 10.30 + 10.76 + 11.31 + 11.96 + 12.72 + 13.61 + 14.65 + 15.88 + 17.34 + 19.10 + 21.24 + 23.98 + 27.73 + 33.45 + 43.20 + 60.98 + 93.88 + 152.78 + 251.71 + 404.68 + 619.54 + 890.45 + 1191.52 + 1476.06 + 1682.74 + 1754.07 + 1666.97 + 1449.41 + 1160.49 + 860.63 + 594.65 + 386.09 + 239.17 + 144.99 + 89.32 + 58.37 + 41.65 + 32.43 + 26.94 + 23.29 + 20.60 + 18.46 + 16.70 + 15.22 + 13.96 + 12.88 + 11.94 + 11.14 + 10.43 + 9.82 + 9.28 + 8.80 + 8.38 + 8.01 + 7.69 + 7.40 + 7.15 + 6.93 + 6.74 + 6.57 + 6.43 + 6.31 + 6.22 + 6.14 + 6.08 + 6.05 + 6.03 + 6.03 + 6.06 + 6.11 + 6.18 + 6.29 + 6.42 + 6.60 + 6.82 + 7.10 + 7.47 + 7.99 + 8.82 + 10.50 + 13.07 + 17.73 + 25.87 + 39.26 + 59.43 + 87.13 + 121.36 + 158.67 + 193.19 + 217.48 + 224.83 + 212.94 + 185.51 + 149.78 + 112.95 + 80.31 + 54.65 + 36.49 + 24.78 + 17.84 + 14.00 + 11.98 + 10.95 + 10.41 + 10.13 + 10.00 + 9.95 + 9.97 + 10.04 + 10.16 + 10.32 + 10.52 + 10.76 + 11.04 + 11.36 + 11.72 + 12.13 + 12.57 + 13.06 + 13.61 + 14.21 + 14.86 + 15.59 + 16.38 + 17.26 + 18.22 + 19.29 + 20.46 + 21.77 + 23.23 + 24.85 + 26.66 + 28.70 + 31.00 + 33.61 + 36.57 + 39.97 + 43.87 + 48.40 + 53.70 + 59.97 + 67.55 + 77.11 + 90.01 + 109.25 + 140.98 + 197.09 + 298.14 + 475.64 + 770.59 + 1225.61 + 1869.42 + 2694.79 + 3640.87 + 4584.61 + 5351.82 + 5756.05 + 5677.43 + 5140.61 + 4296.79 + 3335.64 + 2417.22 + 1645.42 + 1062.55 + 662.12 + 409.04 + 259.72 + 175.70 + 129.03 + 102.20 + 85.44 + 73.81 + 64.98 + 57.86 + 51.93 + 46.89 + 42.57 + 38.84 + 35.58 + 32.73 + 30.23 + 28.01 + 26.04 + 24.28 + 22.71 + 21.29 + 20.02 + 18.86 + 17.82 + 16.87 + 16.00 + 15.21 + 14.48 + 13.82 + 13.21 + 12.64 + 12.12 + 11.64 + 11.20 + 10.79 + 10.41 + 10.06 + 9.73 + 9.43 + 9.15 + 8.89 + 8.64 + 8.42 + 8.21 + 8.02 + 7.84 + 7.67 + 7.52 + 7.37 + 7.24 + 7.12 + 7.01 + 6.91 + 6.82 + 6.74 + 6.66 + 6.60 + 6.54 + 6.49 + 6.45 + 6.30 + 6.28 + 6.26 + 6.25 + 6.25 + 6.25 + 6.27 + 6.28 + 6.31 + 6.35 + 6.39 + 6.44 + 6.50 + 6.57 + 6.65 + 6.74 + 6.83 + 6.94 + 7.06 + 7.19 + 7.34 + 7.49 + 7.66 + 7.85 + 8.05 + 8.27 + 8.71 + 8.97 + 9.25 + 9.55 + 9.89 + 10.25 + 10.64 + 11.11 + 11.57 + 12.08 + 12.63 + 13.24 + 13.91 + 14.64 + 15.45 + 16.34 + 17.33 + 18.42 + 19.65 + 21.01 + 22.55 + 24.28 + 26.24 + 28.47 + 31.02 + 33.95 + 37.35 + 41.33 + 46.06 + 51.86 + 59.32 + 69.70 + 85.54 + 111.78 + 157.23 + 236.08 + 368.48 + 578.91 + 890.68 + 1316.65 + 1848.29 + 2446.04 + 3036.81 + 3519.42 + 3785.38 + 3761.87 + 3455.79 + 2948.97 + 2350.98 + 1759.55 + 1242.63 + 834.57 + 539.83 + 343.20 + 220.68 + 148.20 + 106.52 + 82.35 + 67.59 + 57.78 + 50.62 + 45.00 + 40.39 + 36.49 + 33.16 + 30.28 + 27.76 + 25.57 + 23.63 + 21.91 + 20.39 + 19.03 + 17.82 + 16.72 + 15.73 + 14.84 + 14.03 + 13.30 + 12.63 + 12.02 + 11.46 + 10.94 + 10.47 + 10.04 + 9.65 + 9.28 + 8.95 + 8.65 + 8.37 + 8.11 + 7.88 + 7.67 + 7.48 + 7.31 + 7.16 + 7.03 + 6.93 + 6.84 + 6.78 + 6.75 + 6.74 + 6.77 + 6.84 + 6.98 + 7.21 + 7.62 + 8.35 + 9.65 + 11.95 + 15.88 + 22.20 + 31.75 + 44.76 + 62.08 + 82.47 + 104.05 + 123.82 + 138.14 + 143.63 + 138.76 + 124.86 + 105.24 + 83.57 + 62.88 + 45.19 + 31.37 + 21.42 + 14.76 + 10.56 + 8.02 + 6.52 + 5.62 + 5.05 + 4.65 + 4.35 + 4.11 + 3.91 + 3.73 + 3.58 + 3.45 + 3.33 + 3.22 + 3.13 + 3.04 + 2.96 + 2.89 + 2.83 + 2.77 + 2.72 + 2.67 + 2.62 + 2.58 + 2.54 + 2.50 + 2.47 + 2.44 + 2.41 + 2.38 + 2.35 + 2.33 + 2.31 + 2.29 + 2.27 + 2.25 + 2.24 + 2.22 + 2.21 + 2.19 + 2.18 + 2.17 + 2.16 + 2.15 + 2.15 + 2.14 + 2.13 + 2.13 + 2.12 + 2.12 + 2.12 + 2.11 + 2.11 + 2.11 + 2.11 + 2.11 + 2.11 + 2.12 + 2.12 + 2.12 + 2.13 + 2.13 + 2.14 + 2.14 + 2.15 + 2.16 + 2.16 + 2.17 + 2.18 + 2.19 + 2.20 + 2.22 + 2.23 + 2.24 + 2.26 + 2.27 + 2.29 + 2.31 + 2.32 + 2.34 + 2.36 + 2.39 + 2.41 + 2.43 + 2.46 + 2.48 + 2.51 + 2.54 + 2.57 + 2.60 + 2.63 + 2.67 + 2.71 + 2.75 + 2.79 + 2.83 + 2.88 + 2.92 + 2.97 + 3.03 + 3.08 + 3.14 + 3.21 + 3.28 + 3.35 + 3.42 + 3.50 + 3.59 + 3.68 + 3.78 + 3.89 + 4.00 + 4.12 + 4.25 + 4.39 + 4.54 + 4.71 + 4.89 + 5.08 + 5.30 + 5.53 + 5.79 + 6.07 + 6.38 + 6.73 + 7.12 + 7.55 + 8.04 + 8.59 + 9.22 + 9.94 + 10.79 + 11.80 + 12.78 + 14.43 + 16.77 + 20.29 + 25.90 + 34.96 + 49.49 + 72.10 + 105.72 + 153.03 + 215.51 + 292.40 + 379.81 + 470.30 + 552.99 + 614.74 + 643.18 + 631.65 + 582.93 + 507.64 + 419.08 + 329.30 + 247.32 + 178.51 + 124.87 + 85.76 + 58.89 + 41.34 + 30.32 + 23.54 + 19.36 + 16.69 + 14.90 + 13.60 + 12.60 + 11.80 + 11.14 + 10.59 + 10.12 + 9.72 + 9.39 + 9.11 + 8.88 + 8.69 + 8.54 + 8.42 + 8.32 + 8.26 + 8.22 + 8.21 + 8.22 + 8.25 + 8.30 + 8.38 + 8.47 + 8.58 + 8.72 + 8.87 + 9.05 + 9.24 + 9.47 + 9.71 + 9.98 + 10.28 + 10.61 + 10.97 + 11.36 + 11.79 + 12.26 + 12.78 + 13.35 + 13.97 + 14.65 + 15.40 + 16.23 + 17.14 + 18.15 + 19.27 + 20.52 + 21.92 + 23.48 + 25.24 + 27.24 + 29.50 + 32.11 + 35.14 + 38.74 + 43.17 + 48.90 + 56.77 + 68.25 + 85.82 + 113.30 + 156.31 + 222.27 + 319.94 + 458.27 + 644.16 + 880.03 + 1160.59 + 1470.94 + 1785.68 + 2069.65 + 2281.94 + 2383.99 + 2354.31 + 2199.38 + 1950.19 + 1647.71 + 1331.14 + 1031.50 + 769.55 + 555.76 + 391.57 + 272.32 + 189.86 + 135.12 + 99.83 + 77.34 + 62.87 + 53.24 + 46.48 + 41.42 + 37.42 + 34.11 + 31.30 + 28.87 + 26.75 + 24.88 + 23.22 + 21.75 + 20.43 + 19.26 + 18.20 diff --git a/issues/pyCFML/cfml_utilities/powder_pattern_from_json/first-calc_vs_second-calc/y-pm3m_second-calc.txt b/issues/pyCFML/cfml_utilities/powder_pattern_from_json/first-calc_vs_second-calc/y-pm3m_second-calc.txt new file mode 100644 index 0000000..4696ab8 --- /dev/null +++ b/issues/pyCFML/cfml_utilities/powder_pattern_from_json/first-calc_vs_second-calc/y-pm3m_second-calc.txt @@ -0,0 +1,2781 @@ + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.00 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.01 + 0.02 + 0.02 + 0.02 + 0.02 + 0.02 + 0.02 + 0.02 + 0.02 + 0.02 + 0.02 + 0.02 + 0.02 + 0.02 + 0.02 + 0.02 + 0.02 + 0.02 + 0.02 + 0.02 + 0.02 + 0.02 + 0.02 + 0.02 + 0.02 + 0.02 + 0.02 + 0.02 + 0.02 + 0.02 + 0.02 + 0.02 + 0.02 + 0.03 + 0.03 + 0.03 + 0.03 + 0.03 + 0.03 + 0.03 + 0.03 + 0.03 + 0.03 + 0.03 + 0.03 + 0.03 + 0.03 + 0.03 + 0.03 + 0.04 + 0.04 + 0.04 + 0.04 + 0.04 + 0.04 + 0.04 + 0.04 + 0.04 + 0.04 + 0.04 + 0.05 + 0.05 + 0.05 + 0.05 + 0.05 + 0.05 + 0.05 + 0.05 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.07 + 0.07 + 0.07 + 0.07 + 0.08 + 0.08 + 0.08 + 0.08 + 0.09 + 0.09 + 0.09 + 0.10 + 0.10 + 0.10 + 0.11 + 0.11 + 0.12 + 0.12 + 0.13 + 0.13 + 0.14 + 0.14 + 0.15 + 0.16 + 0.16 + 0.17 + 0.18 + 0.19 + 0.20 + 0.21 + 0.22 + 0.24 + 0.25 + 0.27 + 0.28 + 0.30 + 0.32 + 0.34 + 0.37 + 0.40 + 0.43 + 0.46 + 0.50 + 0.55 + 0.60 + 0.65 + 0.72 + 0.79 + 0.88 + 0.98 + 1.10 + 1.25 + 1.43 + 1.67 + 2.03 + 2.65 + 3.89 + 6.49 + 11.82 + 21.94 + 39.35 + 66.01 + 101.85 + 143.34 + 183.05 + 211.13 + 218.78 + 203.30 + 170.02 + 128.64 + 88.46 + 55.61 + 32.31 + 17.72 + 9.54 + 5.36 + 3.35 + 2.39 + 1.89 + 1.58 + 1.37 + 1.20 + 1.06 + 0.95 + 0.85 + 0.77 + 0.70 + 0.63 + 0.58 + 0.53 + 0.49 + 0.45 + 0.42 + 0.39 + 0.36 + 0.34 + 0.32 + 0.30 + 0.28 + 0.27 + 0.25 + 0.24 + 0.22 + 0.21 + 0.20 + 0.19 + 0.18 + 0.18 + 0.17 + 0.16 + 0.15 + 0.15 + 0.14 + 0.14 + 0.13 + 0.13 + 0.12 + 0.12 + 0.11 + 0.11 + 0.10 + 0.10 + 0.10 + 0.10 + 0.09 + 0.09 + 0.09 + 0.08 + 0.08 + 0.08 + 0.08 + 0.08 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.05 + 0.05 + 0.05 + 0.05 + 0.05 + 0.05 + 0.05 + 0.05 + 0.05 + 0.05 + 0.05 + 0.05 + 0.05 + 0.05 + 0.05 + 0.05 + 0.05 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.08 + 0.08 + 0.08 + 0.09 + 0.09 + 0.09 + 0.10 + 0.10 + 0.11 + 0.11 + 0.12 + 0.13 + 0.13 + 0.14 + 0.15 + 0.17 + 0.18 + 0.20 + 0.21 + 0.23 + 0.26 + 0.29 + 0.33 + 0.37 + 0.43 + 0.53 + 0.70 + 1.05 + 1.79 + 3.28 + 6.04 + 10.61 + 17.37 + 26.06 + 35.60 + 44.05 + 49.13 + 49.14 + 44.09 + 35.64 + 26.10 + 17.40 + 10.64 + 6.05 + 3.29 + 1.80 + 1.06 + 0.70 + 0.53 + 0.43 + 0.37 + 0.33 + 0.29 + 0.26 + 0.24 + 0.22 + 0.20 + 0.18 + 0.17 + 0.16 + 0.15 + 0.13 + 0.12 + 0.11 + 0.11 + 0.10 + 0.10 + 0.09 + 0.09 + 0.09 + 0.08 + 0.08 + 0.08 + 0.08 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.09 + 0.08 + 0.08 + 0.08 + 0.09 + 0.09 + 0.09 + 0.09 + 0.09 + 0.09 + 0.09 + 0.09 + 0.09 + 0.09 + 0.09 + 0.09 + 0.10 + 0.10 + 0.10 + 0.10 + 0.10 + 0.11 + 0.11 + 0.11 + 0.11 + 0.12 + 0.12 + 0.12 + 0.12 + 0.13 + 0.13 + 0.14 + 0.14 + 0.15 + 0.15 + 0.16 + 0.16 + 0.17 + 0.18 + 0.18 + 0.19 + 0.20 + 0.21 + 0.22 + 0.23 + 0.24 + 0.26 + 0.27 + 0.29 + 0.31 + 0.33 + 0.35 + 0.38 + 0.40 + 0.44 + 0.47 + 0.52 + 0.57 + 0.62 + 0.69 + 0.77 + 0.86 + 0.97 + 1.12 + 1.32 + 1.64 + 2.25 + 3.52 + 6.14 + 11.32 + 20.63 + 35.63 + 56.97 + 83.32 + 110.77 + 133.21 + 144.10 + 139.67 + 121.50 + 95.39 + 67.93 + 44.11 + 26.36 + 14.75 + 8.00 + 4.45 + 2.71 + 1.88 + 1.46 + 1.22 + 1.06 + 0.94 + 0.84 + 0.76 + 0.70 + 0.64 + 0.60 + 0.55 + 0.52 + 0.49 + 0.46 + 0.43 + 0.41 + 0.40 + 0.38 + 0.37 + 0.35 + 0.34 + 0.33 + 0.33 + 0.32 + 0.31 + 0.31 + 0.31 + 0.30 + 0.30 + 0.30 + 0.30 + 0.30 + 0.30 + 0.30 + 0.30 + 0.30 + 0.31 + 0.31 + 0.31 + 0.32 + 0.32 + 0.33 + 0.34 + 0.34 + 0.35 + 0.36 + 0.37 + 0.38 + 0.39 + 0.40 + 0.41 + 0.43 + 0.44 + 0.46 + 0.48 + 0.50 + 0.52 + 0.55 + 0.57 + 0.60 + 0.63 + 0.66 + 0.70 + 0.74 + 0.78 + 0.83 + 0.89 + 0.95 + 1.02 + 1.09 + 1.18 + 1.27 + 1.38 + 1.51 + 1.65 + 1.81 + 2.00 + 2.23 + 2.49 + 2.81 + 3.19 + 3.68 + 4.37 + 5.48 + 7.58 + 11.91 + 20.91 + 38.57 + 70.21 + 120.99 + 192.88 + 281.18 + 372.51 + 446.28 + 480.75 + 463.89 + 401.76 + 314.06 + 222.72 + 144.06 + 85.78 + 47.88 + 25.93 + 14.41 + 8.78 + 6.09 + 4.72 + 3.93 + 3.38 + 2.97 + 2.63 + 2.35 + 2.12 + 1.92 + 1.75 + 1.60 + 1.47 + 1.36 + 1.26 + 1.18 + 1.10 + 1.03 + 0.97 + 0.92 + 0.87 + 0.83 + 0.79 + 0.75 + 0.72 + 0.69 + 0.67 + 0.64 + 0.62 + 0.60 + 0.59 + 0.57 + 0.56 + 0.55 + 0.54 + 0.53 + 0.52 + 0.52 + 0.51 + 0.51 + 0.51 + 0.51 + 0.51 + 0.51 + 0.51 + 0.52 + 0.53 + 0.53 + 0.54 + 0.55 + 0.57 + 0.58 + 0.60 + 0.62 + 0.64 + 0.67 + 0.70 + 0.73 + 0.77 + 0.81 + 0.86 + 0.92 + 0.98 + 1.05 + 1.14 + 1.24 + 1.35 + 1.48 + 1.64 + 1.83 + 2.07 + 2.38 + 2.81 + 3.53 + 4.91 + 7.77 + 13.66 + 25.09 + 45.26 + 77.07 + 121.25 + 174.32 + 227.67 + 268.73 + 284.99 + 270.70 + 230.95 + 178.00 + 124.58 + 79.64 + 46.99 + 26.13 + 14.22 + 8.04 + 5.04 + 3.59 + 2.84 + 2.40 + 2.08 + 1.84 + 1.65 + 1.49 + 1.35 + 1.23 + 1.13 + 1.05 + 0.97 + 0.91 + 0.85 + 0.80 + 0.76 + 0.72 + 0.69 + 0.66 + 0.63 + 0.61 + 0.59 + 0.57 + 0.55 + 0.54 + 0.53 + 0.52 + 0.51 + 0.51 + 0.50 + 0.50 + 0.50 + 0.50 + 0.50 + 0.50 + 0.50 + 0.51 + 0.52 + 0.53 + 0.54 + 0.55 + 0.57 + 0.59 + 0.61 + 0.63 + 0.65 + 0.68 + 0.72 + 0.75 + 0.80 + 0.84 + 0.90 + 0.96 + 1.03 + 1.11 + 1.21 + 1.32 + 1.45 + 1.60 + 1.77 + 1.99 + 2.25 + 2.58 + 3.04 + 3.79 + 5.18 + 8.04 + 13.96 + 25.56 + 46.36 + 79.77 + 127.17 + 185.55 + 246.17 + 295.44 + 318.91 + 308.35 + 267.55 + 209.57 + 148.96 + 96.61 + 57.71 + 32.33 + 17.59 + 9.82 + 6.00 + 4.17 + 3.23 + 2.68 + 2.31 + 2.02 + 1.79 + 1.59 + 1.43 + 1.29 + 1.17 + 1.07 + 0.97 + 0.90 + 0.83 + 0.76 + 0.71 + 0.66 + 0.62 + 0.58 + 0.54 + 0.51 + 0.48 + 0.45 + 0.43 + 0.40 + 0.38 + 0.36 + 0.35 + 0.33 + 0.31 + 0.30 + 0.29 + 0.27 + 0.26 + 0.25 + 0.24 + 0.24 + 0.23 + 0.22 + 0.21 + 0.20 + 0.20 + 0.19 + 0.18 + 0.18 + 0.17 + 0.17 + 0.16 + 0.16 + 0.15 + 0.15 + 0.14 + 0.14 + 0.14 + 0.13 + 0.13 + 0.13 + 0.12 + 0.12 + 0.12 + 0.11 + 0.11 + 0.11 + 0.11 + 0.10 + 0.10 + 0.10 + 0.10 + 0.10 + 0.09 + 0.09 + 0.09 + 0.09 + 0.09 + 0.09 + 0.08 + 0.08 + 0.08 + 0.08 + 0.08 + 0.08 + 0.08 + 0.08 + 0.08 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.06 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.08 + 0.08 + 0.08 + 0.08 + 0.09 + 0.09 + 0.10 + 0.11 + 0.11 + 0.12 + 0.13 + 0.15 + 0.16 + 0.18 + 0.21 + 0.27 + 0.37 + 0.57 + 0.99 + 1.78 + 3.15 + 5.25 + 8.08 + 11.38 + 14.55 + 16.82 + 17.47 + 16.25 + 13.61 + 10.31 + 7.12 + 4.50 + 2.65 + 1.48 + 0.83 + 0.49 + 0.33 + 0.25 + 0.21 + 0.18 + 0.16 + 0.15 + 0.14 + 0.13 + 0.12 + 0.11 + 0.11 + 0.10 + 0.10 + 0.10 + 0.10 + 0.08 + 0.08 + 0.08 + 0.10 + 0.10 + 0.10 + 0.10 + 0.10 + 0.10 + 0.10 + 0.10 + 0.11 + 0.11 + 0.11 + 0.11 + 0.12 + 0.12 + 0.13 + 0.13 + 0.14 + 0.15 + 0.15 + 0.16 + 0.17 + 0.18 + 0.20 + 0.21 + 0.23 + 0.25 + 0.27 + 0.30 + 0.33 + 0.36 + 0.41 + 0.46 + 0.53 + 0.64 + 0.83 + 1.21 + 1.99 + 3.54 + 6.42 + 11.21 + 18.34 + 27.60 + 37.90 + 47.24 + 53.12 + 53.60 + 48.49 + 39.54 + 29.23 + 19.71 + 12.21 + 7.05 + 3.91 + 2.19 + 1.31 + 0.89 + 0.68 + 0.56 + 0.49 + 0.43 + 0.39 + 0.35 + 0.32 + 0.30 + 0.28 + 0.26 + 0.25 + 0.23 + 0.22 + 0.21 + 0.21 + 0.20 + 0.19 + 0.19 + 0.18 + 0.18 + 0.18 + 0.17 + 0.17 + 0.17 + 0.17 + 0.17 + 0.17 + 0.17 + 0.17 + 0.18 + 0.18 + 0.18 + 0.18 + 0.19 + 0.19 + 0.20 + 0.21 + 0.22 + 0.23 + 0.24 + 0.25 + 0.26 + 0.28 + 0.30 + 0.33 + 0.36 + 0.40 + 0.46 + 0.56 + 0.77 + 1.19 + 2.02 + 3.54 + 6.09 + 9.87 + 14.77 + 20.23 + 25.19 + 28.32 + 28.59 + 25.91 + 21.19 + 15.74 + 10.68 + 6.70 + 3.95 + 2.28 + 1.36 + 0.89 + 0.67 + 0.56 + 0.50 + 0.47 + 0.45 + 0.43 + 0.42 + 0.41 + 0.41 + 0.41 + 0.41 + 0.41 + 0.42 + 0.42 + 0.43 + 0.44 + 0.45 + 0.47 + 0.48 + 0.50 + 0.52 + 0.54 + 0.57 + 0.59 + 0.62 + 0.66 + 0.69 + 0.73 + 0.78 + 0.82 + 0.88 + 0.94 + 1.01 + 1.09 + 1.17 + 1.27 + 1.39 + 1.52 + 1.67 + 1.84 + 2.04 + 2.28 + 2.57 + 2.91 + 3.35 + 3.94 + 4.85 + 6.50 + 9.79 + 16.50 + 29.65 + 53.35 + 91.88 + 147.46 + 217.49 + 292.60 + 357.14 + 393.10 + 388.20 + 344.20 + 275.63 + 200.49 + 133.23 + 81.55 + 46.74 + 25.87 + 14.54 + 8.85 + 6.06 + 4.64 + 3.83 + 3.28 + 2.87 + 2.55 + 2.28 + 2.05 + 1.86 + 1.69 + 1.55 + 1.43 + 1.32 + 1.23 + 1.15 + 1.08 + 1.02 + 0.96 + 0.92 + 0.87 + 0.84 + 0.80 + 0.78 + 0.75 + 0.73 + 0.72 + 0.70 + 0.70 + 0.69 + 0.69 + 0.69 + 0.69 + 0.70 + 0.72 + 0.73 + 0.76 + 0.79 + 0.83 + 0.88 + 0.93 + 1.01 + 1.10 + 1.22 + 1.38 + 1.64 + 2.10 + 3.04 + 4.95 + 8.69 + 15.41 + 26.31 + 42.00 + 61.74 + 82.90 + 101.09 + 111.26 + 109.92 + 97.58 + 78.28 + 57.10 + 38.09 + 23.45 + 13.55 + 7.59 + 4.34 + 2.70 + 1.89 + 1.48 + 1.24 + 1.08 + 0.96 + 0.86 + 0.78 + 0.72 + 0.66 + 0.61 + 0.57 + 0.53 + 0.50 + 0.47 + 0.45 + 0.42 + 0.41 + 0.39 + 0.37 + 0.36 + 0.35 + 0.34 + 0.33 + 0.32 + 0.32 + 0.31 + 0.31 + 0.30 + 0.30 + 0.30 + 0.30 + 0.30 + 0.30 + 0.30 + 0.31 + 0.31 + 0.32 + 0.33 + 0.34 + 0.35 + 0.37 + 0.40 + 0.43 + 0.50 + 0.61 + 0.85 + 1.32 + 2.21 + 3.74 + 6.07 + 9.24 + 12.95 + 16.59 + 19.30 + 20.23 + 19.05 + 16.20 + 12.51 + 8.85 + 5.78 + 3.55 + 2.12 + 1.30 + 0.87 + 0.66 + 0.55 + 0.50 + 0.48 + 0.46 + 0.45 + 0.44 + 0.44 + 0.44 + 0.44 + 0.44 + 0.45 + 0.46 + 0.47 + 0.48 + 0.49 + 0.51 + 0.53 + 0.55 + 0.57 + 0.60 + 0.63 + 0.66 + 0.69 + 0.73 + 0.78 + 0.83 + 0.88 + 0.95 + 1.02 + 1.09 + 1.18 + 1.29 + 1.41 + 1.54 + 1.70 + 1.88 + 2.10 + 2.36 + 2.68 + 3.08 + 3.64 + 4.48 + 6.05 + 9.15 + 15.39 + 27.37 + 48.59 + 82.45 + 130.46 + 189.99 + 252.80 + 305.65 + 333.69 + 327.31 + 288.81 + 230.65 + 167.72 + 111.68 + 68.70 + 39.69 + 22.21 + 12.65 + 7.78 + 5.37 + 4.12 + 3.39 + 2.91 + 2.54 + 2.24 + 2.00 + 1.79 + 1.62 + 1.47 + 1.34 + 1.22 + 1.12 + 1.04 + 0.96 + 0.89 + 0.83 + 0.78 + 0.73 + 0.68 + 0.64 + 0.61 + 0.57 + 0.54 + 0.52 + 0.49 + 0.47 + 0.45 + 0.43 + 0.41 + 0.39 + 0.38 + 0.36 + 0.35 + 0.34 + 0.33 + 0.32 + 0.31 + 0.30 + 0.29 + 0.28 + 0.27 + 0.27 + 0.26 + 0.25 + 0.24 + 0.24 + 0.24 + 0.24 + 0.23 + 0.23 + 0.23 + 0.22 + 0.22 + 0.22 + 0.22 + 0.22 + 0.21 + 0.21 + 0.21 + 0.21 + 0.21 + 0.21 + 0.21 + 0.22 + 0.22 + 0.22 + 0.22 + 0.22 + 0.23 + 0.23 + 0.23 + 0.24 + 0.24 + 0.25 + 0.26 + 0.26 + 0.27 + 0.28 + 0.29 + 0.30 + 0.31 + 0.32 + 0.34 + 0.35 + 0.37 + 0.39 + 0.41 + 0.44 + 0.46 + 0.50 + 0.53 + 0.57 + 0.62 + 0.67 + 0.73 + 0.81 + 0.89 + 1.00 + 1.12 + 1.28 + 1.49 + 1.81 + 2.37 + 3.46 + 5.63 + 9.81 + 17.27 + 29.34 + 46.76 + 68.87 + 92.99 + 114.43 + 127.53 + 127.98 + 115.62 + 94.56 + 70.46 + 48.11 + 30.34 + 17.93 + 10.20 + 5.85 + 3.58 + 2.44 + 1.86 + 1.53 + 1.32 + 1.16 + 1.04 + 0.94 + 0.85 + 0.78 + 0.72 + 0.67 + 0.63 + 0.59 + 0.56 + 0.54 + 0.51 + 0.50 + 0.48 + 0.47 + 0.46 + 0.45 + 0.45 + 0.44 + 0.45 + 0.45 + 0.45 + 0.46 + 0.47 + 0.49 + 0.51 + 0.53 + 0.56 + 0.59 + 0.63 + 0.68 + 0.74 + 0.82 + 0.91 + 1.03 + 1.22 + 1.53 + 2.13 + 3.33 + 5.66 + 9.88 + 16.82 + 27.10 + 40.54 + 55.75 + 70.06 + 79.95 + 82.34 + 76.37 + 64.08 + 48.96 + 34.27 + 22.14 + 13.36 + 7.71 + 4.43 + 2.68 + 1.79 + 1.34 + 1.10 + 0.94 + 0.83 + 0.75 + 0.68 + 0.62 + 0.58 + 0.54 + 0.50 + 0.47 + 0.45 + 0.43 + 0.41 + 0.40 + 0.39 + 0.38 + 0.37 + 0.37 + 0.37 + 0.37 + 0.37 + 0.37 + 0.38 + 0.39 + 0.40 + 0.41 + 0.43 + 0.45 + 0.48 + 0.51 + 0.54 + 0.58 + 0.63 + 0.69 + 0.76 + 0.86 + 0.98 + 1.17 + 1.49 + 2.11 + 3.34 + 5.69 + 9.88 + 16.69 + 26.63 + 39.43 + 53.70 + 66.87 + 75.65 + 77.28 + 71.16 + 59.38 + 45.19 + 31.55 + 20.35 + 12.29 + 7.12 + 4.11 + 2.51 + 1.69 + 1.27 + 1.03 + 0.89 + 0.78 + 0.70 + 0.64 + 0.58 + 0.53 + 0.49 + 0.46 + 0.43 + 0.41 + 0.39 + 0.37 + 0.36 + 0.34 + 0.33 + 0.32 + 0.32 + 0.31 + 0.31 + 0.31 + 0.31 + 0.31 + 0.31 + 0.32 + 0.33 + 0.34 + 0.35 + 0.36 + 0.38 + 0.40 + 0.43 + 0.46 + 0.50 + 0.55 + 0.61 + 0.69 + 0.83 + 1.07 + 1.52 + 2.41 + 4.09 + 6.99 + 11.57 + 18.04 + 26.08 + 34.69 + 42.19 + 46.62 + 46.52 + 41.94 + 34.34 + 25.73 + 17.74 + 11.35 + 6.84 + 4.00 + 2.37 + 1.50 + 1.06 + 0.83 + 0.70 + 0.62 + 0.56 + 0.52 + 0.48 + 0.45 + 0.43 + 0.41 + 0.39 + 0.38 + 0.37 + 0.36 + 0.36 + 0.36 + 0.36 + 0.36 + 0.37 + 0.37 + 0.38 + 0.39 + 0.40 + 0.42 + 0.44 + 0.46 + 0.48 + 0.51 + 0.55 + 0.59 + 0.63 + 0.68 + 0.75 + 0.82 + 0.91 + 1.01 + 1.14 + 1.31 + 1.54 + 1.92 + 2.60 + 3.91 + 6.45 + 11.10 + 18.96 + 31.02 + 47.51 + 67.38 + 87.84 + 104.68 + 113.27 + 110.74 + 97.99 + 78.97 + 58.32 + 39.70 + 25.12 + 15.01 + 8.70 + 5.11 + 3.20 + 2.22 + 1.70 + 1.40 + 1.20 + 1.05 + 0.93 + 0.83 + 0.75 + 0.68 + 0.62 + 0.57 + 0.52 + 0.48 + 0.44 + 0.41 + 0.39 + 0.36 + 0.34 + 0.32 + 0.30 + 0.29 + 0.27 + 0.26 + 0.25 + 0.24 + 0.23 + 0.22 + 0.21 + 0.21 + 0.20 + 0.19 + 0.19 + 0.19 + 0.18 + 0.18 + 0.18 + 0.18 + 0.18 + 0.18 + 0.21 + 0.22 + 0.26 + 0.33 + 0.46 + 0.68 + 1.01 + 1.47 + 2.01 + 2.57 + 3.03 + 3.26 + 3.19 + 2.84 + 2.32 + 1.75 + 1.24 + 0.84 + 0.55 + 0.38 + 0.28 + 0.22 + 0.20 + 0.18 + 0.18 + 0.17 + 0.17 + 0.17 + 0.17 + 0.17 + 0.17 + 0.17 + 0.18 + 0.18 + 0.18 + 0.19 + 0.19 + 0.20 + 0.21 + 0.21 + 0.22 + 0.23 + 0.24 + 0.25 + 0.27 + 0.28 + 0.30 + 0.31 + 0.33 + 0.36 + 0.38 + 0.41 + 0.45 + 0.48 + 0.53 + 0.58 + 0.64 + 0.72 + 0.81 + 0.92 + 1.08 + 1.32 + 1.73 + 2.51 + 4.00 + 6.74 + 11.42 + 18.73 + 29.00 + 41.82 + 55.73 + 68.23 + 76.28 + 77.38 + 71.15 + 59.62 + 45.82 + 32.49 + 21.39 + 13.24 + 7.86 + 4.64 + 2.85 + 1.91 + 1.41 + 1.14 + 0.96 + 0.84 + 0.75 + 0.67 + 0.60 + 0.55 + 0.50 + 0.46 + 0.43 + 0.40 + 0.37 + 0.35 + 0.33 + 0.31 + 0.29 + 0.28 + 0.27 + 0.26 + 0.25 + 0.24 + 0.23 + 0.22 + 0.21 + 0.21 + 0.20 + 0.20 + 0.19 + 0.19 + 0.19 + 0.18 + 0.18 + 0.18 + 0.18 + 0.18 + 0.18 + 0.17 + 0.17 + 0.18 + 0.18 + 0.18 + 0.18 + 0.19 + 0.19 + 0.19 + 0.19 + 0.19 + 0.19 + 0.20 + 0.20 + 0.20 + 0.20 + 0.21 + 0.21 + 0.22 + 0.21 + 0.22 + 0.22 + 0.23 + 0.24 + 0.24 + 0.25 + 0.26 + 0.26 + 0.27 + 0.28 + 0.29 + 0.30 + 0.31 + 0.33 + 0.34 + 0.35 + 0.37 + 0.39 + 0.40 + 0.42 + 0.44 + 0.47 + 0.49 + 0.52 + 0.55 + 0.58 + 0.62 + 0.66 + 0.70 + 0.75 + 0.80 + 0.86 + 0.93 + 1.01 + 1.09 + 1.19 + 1.31 + 1.43 + 1.59 + 1.76 + 1.97 + 2.22 + 2.53 + 2.94 + 3.52 + 4.49 + 6.22 + 9.45 + 15.40 + 25.80 + 42.57 + 67.22 + 99.79 + 137.92 + 176.34 + 207.43 + 223.02 + 218.14 + 194.42 + 158.87 + 119.76 + 83.74 + 54.73 + 33.86 + 20.29 + 12.20 + 7.70 + 5.29 + 3.98 + 3.23 + 2.74 + 2.38 + 2.11 + 1.88 + 1.69 + 1.52 + 1.38 + 1.26 + 1.16 + 1.07 + 0.98 + 0.91 + 0.85 + 0.79 + 0.74 + 0.70 + 0.66 + 0.62 + 0.58 + 0.55 + 0.53 + 0.50 + 0.48 + 0.46 + 0.44 + 0.42 + 0.40 + 0.39 + 0.38 + 0.36 + 0.35 + 0.34 + 0.33 + 0.33 + 0.32 + 0.31 + 0.31 + 0.31 + 0.31 + 0.31 + 0.32 + 0.35 + 0.40 + 0.50 + 0.64 + 0.85 + 1.12 + 1.41 + 1.69 + 1.90 + 1.97 + 1.88 + 1.66 + 1.38 + 1.08 + 0.81 + 0.60 + 0.46 + 0.37 + 0.31 + 0.29 + 0.27 + 0.26 + 0.26 + 0.26 + 0.26 + 0.26 + 0.27 + 0.27 + 0.28 + 0.28 + 0.29 + 0.29 + 0.30 + 0.31 + 0.32 + 0.33 + 0.34 + 0.35 + 0.37 + 0.38 + 0.40 + 0.42 + 0.44 + 0.46 + 0.49 + 0.51 + 0.55 + 0.58 + 0.62 + 0.66 + 0.71 + 0.77 + 0.83 + 0.90 + 0.99 + 1.08 + 1.19 + 1.33 + 1.48 + 1.67 + 1.92 + 2.26 + 2.79 + 3.71 + 5.36 + 8.36 + 13.61 + 22.23 + 35.26 + 53.16 + 75.28 + 99.39 + 121.69 + 137.37 + 142.08 + 134.32 + 116.51 + 93.32 + 69.41 + 48.20 + 31.52 + 19.68 + 12.01 + 7.42 + 4.84 + 3.42 + 2.63 + 2.16 + 1.85 + 1.62 + 1.43 + 1.28 + 1.16 + 1.05 + 0.95 + 0.87 + 0.80 + 0.74 + 0.69 + 0.64 + 0.59 + 0.56 + 0.52 + 0.49 + 0.46 + 0.44 + 0.41 + 0.39 + 0.37 + 0.36 + 0.34 + 0.33 + 0.31 + 0.30 + 0.29 + 0.28 + 0.27 + 0.27 + 0.26 + 0.25 + 0.25 + 0.25 + 0.24 + 0.24 + 0.24 + 0.24 + 0.25 + 0.25 + 0.27 + 0.30 + 0.35 + 0.44 + 0.62 + 0.90 + 1.35 + 1.99 + 2.81 + 3.74 + 4.68 + 5.44 + 5.84 + 5.76 + 5.22 + 4.37 + 3.41 + 2.50 + 1.73 + 1.15 + 0.75 + 0.49 + 0.34 + 0.26 + 0.21 + 0.18 + 0.16 + 0.15 + 0.14 + 0.13 + 0.13 + 0.12 + 0.11 + 0.11 + 0.11 + 0.10 + 0.10 + 0.10 + 0.09 + 0.09 + 0.09 + 0.09 + 0.08 + 0.08 + 0.08 + 0.08 + 0.08 + 0.08 + 0.08 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.07 + 0.08 + 0.08 + 0.08 + 0.08 + 0.08 + 0.08 + 0.08 + 0.08 + 0.09 + 0.09 + 0.09 + 0.09 + 0.09 + 0.09 + 0.10 + 0.10 + 0.10 + 0.10 + 0.11 + 0.11 + 0.11 + 0.12 + 0.12 + 0.13 + 0.13 + 0.14 + 0.14 + 0.15 + 0.16 + 0.16 + 0.17 + 0.18 + 0.19 + 0.19 + 0.21 + 0.22 + 0.23 + 0.24 + 0.26 + 0.28 + 0.30 + 0.32 + 0.35 + 0.38 + 0.42 + 0.46 + 0.51 + 0.58 + 0.67 + 0.82 + 1.05 + 1.46 + 2.17 + 3.35 + 5.24 + 8.02 + 11.84 + 16.59 + 21.94 + 27.22 + 31.53 + 33.91 + 33.70 + 30.97 + 26.44 + 21.09 + 15.80 + 11.18 + 7.53 + 4.90 + 3.14 + 2.05 + 1.40 + 1.03 + 0.82 + 0.69 + 0.60 + 0.54 + 0.50 + 0.46 + 0.43 + 0.40 + 0.38 + 0.36 + 0.34 + 0.33 + 0.32 + 0.31 + 0.30 + 0.30 + 0.29 + 0.29 + 0.29 + 0.29 + 0.29 + 0.29 + 0.29 + 0.30 + 0.30 + 0.31 + 0.32 + 0.33 + 0.34 + 0.35 + 0.36 + 0.38 + 0.39 + 0.41 + 0.44 + 0.46 + 0.49 + 0.52 + 0.56 + 0.60 + 0.65 + 0.70 + 0.77 + 0.84 + 0.93 + 1.04 + 1.17 + 1.36 + 1.63 + 2.06 + 2.79 + 4.03 + 6.11 + 9.43 + 14.41 + 21.39 + 30.38 + 40.97 + 52.16 + 62.43 + 69.87 + 72.74 + 70.25 + 63.09 + 52.96 + 41.78 + 31.10 + 21.97 + 14.85 + 9.72 + 6.30 + 4.14 + 2.85 + 2.09 + 1.64 + 1.36 + 1.17 + 1.04 + 0.93 + 0.84 + 0.76 + 0.69 + 0.64 + 0.59 + 0.54 + 0.51 + 0.47 + 0.44 + 0.42 + 0.39 + 0.37 + 0.35 + 0.33 + 0.32 + 0.30 + 0.29 + 0.28 + 0.26 + 0.25 + 0.25 + 0.24 + 0.23 + 0.22 + 0.21 + 0.21 + 0.20 + 0.20 + 0.19 + 0.19 + 0.18 + 0.18 + 0.18 + 0.17 + 0.17 + 0.17 + 0.16 + 0.16 + 0.16 + 0.16 + 0.16 + 0.15 + 0.15 + 0.15 + 0.15 + 0.15 + 0.15 + 0.15 + 0.15 + 0.15 + 0.15 + 0.15 + 0.15 + 0.15 + 0.15 + 0.15 + 0.15 + 0.15 + 0.15 + 0.15 + 0.15 + 0.15 + 0.15 + 0.15 + 0.15 + 0.15 + 0.16 + 0.16 + 0.16 + 0.16 + 0.16 + 0.16 + 0.17 + 0.17 + 0.17 + 0.17 + 0.18 + 0.18 + 0.18 + 0.19 + 0.19 + 0.20 + 0.20 + 0.20 + 0.21 + 0.21 + 0.22 + 0.22 + 0.23 + 0.24 + 0.24 + 0.25 + 0.26 + 0.27 + 0.27 + 0.28 + 0.29 + 0.30 + 0.32 + 0.33 + 0.34 + 0.35 + 0.37 + 0.39 + 0.40 + 0.42 + 0.44 + 0.46 + 0.49 + 0.52 + 0.54 + 0.58 + 0.61 + 0.65 + 0.69 + 0.74 + 0.79 + 0.85 + 0.92 + 1.00 + 1.08 + 1.18 + 1.29 + 1.43 + 1.59 + 1.78 + 2.04 + 2.42 + 2.98 + 3.88 + 5.34 + 7.68 + 11.32 + 16.73 + 24.36 + 34.43 + 46.82 + 60.91 + 75.49 + 88.82 + 98.77 + 103.35 + 101.49 + 93.62 + 81.48 + 67.19 + 52.71 + 39.48 + 28.38 + 19.72 + 13.41 + 9.07 + 6.23 + 4.44 + 3.34 + 2.66 + 2.22 + 1.92 + 1.70 + 1.53 + 1.38 + 1.27 + 1.16 + 1.08 + 1.00 + 0.93 + 0.87 + 0.82 + 0.77 + 0.73 + 0.69 + 0.66 + 0.63 + 0.60 + 0.58 + 0.56 + 0.54 + 0.52 + 0.51 + 0.50 + 0.48 + 0.47 + 0.47 + 0.46 + 0.45 + 0.45 + 0.45 + 0.44 + 0.44 + 0.44 + 0.45 + 0.45 + 0.45 + 0.46 + 0.47 + 0.47 + 0.48 + 0.50 + 0.51 + 0.53 + 0.54 + 0.56 + 0.59 + 0.62 + 0.65 + 0.68 + 0.72 + 0.77 + 0.82 + 0.88 + 0.95 + 1.04 + 1.14 + 1.28 + 1.47 + 1.75 + 2.18 + 2.85 + 3.90 + 5.51 + 7.89 + 11.27 + 15.81 + 21.58 + 28.43 + 36.02 + 43.71 + 50.65 + 55.84 + 58.33 + 57.60 + 53.82 + 47.72 + 40.33 + 32.59 + 25.27 + 18.87 + 13.64 + 9.63 + 6.71 + 4.70 + 3.36 + 2.49 + 1.94 + 1.59 + 1.35 + 1.19 + 1.06 + 0.97 + 0.89 + 0.82 + 0.76 + 0.71 + 0.66 + 0.62 + 0.58 + 0.55 + 0.52 + 0.50 diff --git a/pybuild.py b/pybuild.py new file mode 100644 index 0000000..7aba4ec --- /dev/null +++ b/pybuild.py @@ -0,0 +1,1532 @@ +import argparse +import datetime +import os +import platform +import site +import sys +import sysconfig +import toml +#import tomllib +from colorama import Fore, Back, Style +from pathlib import Path +from pygit2 import Repository + +global ARGS +global CONFIG + +MSG_COLOR = r'\033[0;33m' # orange +ERROR_COLOR = r'\033[0;31m' # red +HEAD_COLOR = r'\033[1;34m' # bold blue +COLOR_OFF = r'\033[0m' + + +def _github_actions(): + if 'GITHUB_ACTIONS' in os.environ: + return True + return False + +def _github_branch(): + return Repository('.').head.shorthand + +def _project_dir(): + return os.path.dirname(__file__) + +def _project_path(): + return os.path.abspath(_project_dir()) + +def _config_path(name: str): + path = os.path.join(_project_dir(), name) + path = os.path.abspath(path) + return path + +def _scripts_path(): + dir = CONFIG['project']['dir']['scripts'] + path = os.path.abspath(dir) + return path + +def _main_script_path(): + name = 'main.sh' + path = os.path.join(_scripts_path(), name) + return path + +def _echo_cmd(): + if _enable_backslash_escapes(): + return 'echo -e' + return 'echo' + +def _echo_msg(msg:str): + return f'{_echo_cmd()} "{MSG_COLOR}:::::: {msg}{COLOR_OFF}"' + +def _echo_progress_msg(current: int, total: int, msg: str): + progress = _compiling_progress(current, total) + msg = f"[{progress:>3}%] {msg}" + return _echo_msg(msg) + +def _echo_header(msg:str): + msg = f'{HEAD_COLOR}:::::: {msg} ::::::{COLOR_OFF}' + sep = ':' * (len(msg) - len(f'{HEAD_COLOR}') - len(f'{COLOR_OFF}')) + lines = [] + lines.append(f'{_echo_cmd()} ""') + lines.append(f'{_echo_cmd()} "{HEAD_COLOR}{sep}{COLOR_OFF}"') + lines.append(f'{_echo_cmd()} "{HEAD_COLOR}{msg}{COLOR_OFF}"') + lines.append(f'{_echo_cmd()} "{HEAD_COLOR}{sep}{COLOR_OFF}"') + return lines + +def _print_msg(msg:str): + print(Fore.GREEN + f':::::: {msg}' + Style.RESET_ALL) + +def _print_error_msg(msg:str): + print(Fore.RED + f':::::: ERROR: {msg}' + Style.RESET_ALL) + +def _processor(): + processor = platform.processor() + processor = processor.split()[0] # get the 1st word from string, such as 'Intel64 Family 6 Model 154 Stepping 3, GenuineIntel' + return processor + +def _platform(): + platform = 'macos' # default + if ARGS.platform: + platform = ARGS.platform.lower() + return platform + +def _platform_tag(): + tag = sysconfig.get_platform() + if _platform() == 'macos': # replaces, e.g., 'macosx-14-arm64' with 'macosx-14_0-arm64' + tag = tag.split('-') # 'macosx-14-arm64' => ['macosx', '14', 'arm64'] + tag[1] = f'{tag[1]}_0' # ['macosx', '14', 'arm64'] => ['macosx', '14_0', 'arm64'] + tag = '-'.join(tag) # ['macosx', '14_0', 'arm64'] => 'macosx-14_0-arm64' + tag = tag.replace('-', '_') + tag = tag.replace('.', '_') + return tag + +def _platform_tag_github_ci(): # sysconf always returns 'macosx_10_9_universal2' on GH macOS... + tag = sysconfig.get_platform() + if _platform() == 'macos': + version = platform.mac_ver()[0] # e.g., '14.5' + version = version.split('.') # '14.5' => ['14', '5'] + version[1] = '0' # ['14', '5'] => ['14', '0'] + version = '.'.join(version[:2]) # ['14', '0'] => '14.0'; ['12', '0', '5'] => '12.0' + machine = platform.mac_ver()[2] # e.g., 'arm64' + tag = f'macosx-{version}-{machine}' + tag = tag.replace('-', '_') + tag = tag.replace('.', '_') + return tag + +def _python_version_full(): # full version, e.g., '3.11.6' + return platform.python_version() + +def _python_version_short(): # short version, e.g., '311' + return sysconfig.get_config_var('py_version_nodot') + +def _python_tag(): # tag, e.g., 'py311' + return f'py{_python_version_short()}' + +def _python_site_packages(): + site_packages = site.getsitepackages() + site_packages = site_packages[0] # get the first location from the list + return site_packages + +def _python_lib(): + if _platform() == 'macos': + #python_lib = '`python3-config --ldflags --embed`' + python_lib = '`pkg-config --libs python3-embed`' + elif _platform() == 'linux': + python_lib = '' + elif _platform() == 'windows': + lib_file = f'python{_python_version_short()}.lib' + python_lib = os.path.join(_python_site_packages(), 'libs', lib_file) + else: + raise Exception(f'Unsupported platform {_platform()}') + return python_lib + +def _ifport_lib(): + try: + ifport_lib = CONFIG['build'][_platform()][_compiler_name()] + except KeyError: + ifport_lib = '' + return ifport_lib + +def _initial_python_wheel_tags(): + return { + 'python_tag': 'py3', + 'abi_tag': 'none', + 'platform_tag': 'any' + } + +def _new_python_wheel_tags(): + return { + 'python_tag': _python_tag(), + 'abi_tag': 'none', + 'platform_tag': _platform_tag_github_ci() + } + +def _initial_wheel_name(): + dist_package_name = PYPROJECT['project']['name'] + dist_package_version = PYPROJECT['project']['version'] + python_tag = _initial_python_wheel_tags()['python_tag'] + abi_tag = _initial_python_wheel_tags()['abi_tag'] + platform_tag = _initial_python_wheel_tags()['platform_tag'] + name = f'{dist_package_name}-{dist_package_version}-{python_tag}-{abi_tag}-{platform_tag}.whl' + return name + +def _new_wheel_name(): + dist_package_name = PYPROJECT['project']['name'] + dist_package_version = PYPROJECT['project']['version'] + python_tag = _new_python_wheel_tags()['python_tag'] + abi_tag = _new_python_wheel_tags()['abi_tag'] + platform_tag = _new_python_wheel_tags()['platform_tag'] + name = f'{dist_package_name}-{dist_package_version}-{python_tag}-{abi_tag}-{platform_tag}.whl' + return name + +def _fix_file_permissions(path: str): + os.chmod(path, 0o777) + +def _write_lines_to_file(lines: list, name: str): + path = os.path.join(_scripts_path(), name) + with open(path, 'w') as file: + for line in lines: + line = _apply_bash_syntax_if_needed(line) + file.write(line + '\n') + _fix_file_permissions(path) + +def _total_src_file_count(modules: str): + count = 0 + for module in CONFIG[modules]: + if 'main-file' in module: + count += 1 + if 'components-dir' in module and 'components-files' in module: + for component_file in module['components-files']: + count += 1 + return count + +def _bash_syntax(): + bash_syntax = False # if '--bash-syntax' is undefined + if ARGS.bash_syntax: + bash_syntax = ARGS.bash_syntax + return bash_syntax + +def _apply_bash_syntax_if_needed(line: str): + if _bash_syntax(): + line = line.replace('\\', '/') # change path separators + line = line.replace('/033', r'\033') # fix colors after previous step + return line + +def _enable_backslash_escapes(): + enable_backslash_escapes = False # if '--enable-backslash-escapes' is undefined + if ARGS.enable_backslash_escapes: + enable_backslash_escapes = ARGS.enable_backslash_escapes + return enable_backslash_escapes + +def _print_wheel_dir(): + wheel_dir = CONFIG['pycfml']['dir']['dist-wheel'] + print(wheel_dir) + +def _print_release_version(): + release_version = PYPROJECT['project']['version'] + release_version = f'v{release_version}' + print(release_version) + +def _print_release_title(): + release_version = PYPROJECT['project']['version'] + dt = datetime.datetime.now() + build_date = f'{dt.day} {dt:%b} {dt.year}' # e.g. 3 Jun 2021 + release_title = f'Version {release_version} ({build_date})' + print(release_title) + +def _compiler_name(): + compiler = 'gfortran' # default + if ARGS.compiler: + compiler = ARGS.compiler.lower() + return compiler + +def _compiler_options(): + compiler = _compiler_name() + mode = _compiling_mode() + options = '' + for build in CONFIG['build-configs']: + if _platform() in build['platforms'] and compiler in build['compilers']: + options = f"{build['modes']['base']}" + if build['modes'][mode]: + options += f" {build['modes'][mode]}" + break + return options + +def _obj_ext(): + compiler = _compiler_name() + ext = '' + for build in CONFIG['build-configs']: + if _platform() in build['platforms'] and compiler in build['compilers']: + ext = build['obj-ext'] + break + return ext + +def _compiler_build_shared_template(): + compiler = _compiler_name() + template = '' + for build in CONFIG['build-configs']: + if _platform() in build['platforms'] and compiler in build['compilers']: + template = build['build-shared'] + break + return template + +def _compiler_build_exe_template(): + compiler = _compiler_name() + template = '' + for build in CONFIG['build-configs']: + if _platform() in build['platforms'] and compiler in build['compilers']: + template = build['build-exe'] + break + return template + +def _compiler_obj_ext(): + compiler = _compiler_name() + obj_ext = '' + for build in CONFIG['build-configs']: + if _platform() in build['platforms'] and compiler in build['compilers']: + obj_ext = build['obj-ext'] + break + return obj_ext + +def _compiling_mode(): + mode = 'debug' # default + if ARGS.mode: + mode = ARGS.mode.lower() + return mode + +def _compiling_progress(current: int, total: int): + progress = round(current / total * 100) + return progress + +def _compile_obj_script_line(src_path: str, + include_path: str=''): + compiler = _compiler_name() + options = _compiler_options() + template_cmd = CONFIG['template']['build-obj'] + if not include_path: + template_cmd = template_cmd.replace(' -I {INCLUDE}', '') + else: + template_cmd = template_cmd.replace('{INCLUDE}', include_path) + cmd = template_cmd + cmd = cmd.replace('{COMPILER}', compiler) + cmd = cmd.replace('{OPTIONS}', options) + cmd = cmd.replace('{PATH}', src_path) + return cmd + +def _compile_pycfml_shared_obj_or_dynamic_lib_script_line(): + src_name = CONFIG['pycfml']['src-name'] + shared_lib_ext = CONFIG['build']['shared-lib-ext'][_platform()] + cfml_lib_name = CONFIG['cfml']['static-lib-name'] + cfml_dist_dir = CONFIG['cfml']['dir']['dist'] + cfml_dist_path = os.path.join(_project_path(), cfml_dist_dir) + cfml_lib_dist_dir = CONFIG['cfml']['dir']['dist-lib'] + cfml_lib_dist_path = os.path.join(_project_path(), cfml_lib_dist_dir) + cmd = _compiler_build_shared_template() + cmd = cmd.replace('{COMPILER}', _compiler_name()) + cmd = cmd.replace('{PATH}', src_name) + cmd = cmd.replace('{OBJ_EXT}', _compiler_obj_ext()) + #cmd = cmd.replace('{PATH}.{OBJ_EXT}', f'*.{obj_ext}') # CFML_Wraps.o Wraps_*.o crysfml08lib.o + cmd = cmd.replace('{EXT}', shared_lib_ext) + cmd = cmd.replace('{CFML_LIB_PATH}', cfml_lib_dist_path) + cmd = cmd.replace('{CFML_LIB_NAME}', cfml_lib_name) + cmd = cmd.replace('{IFPORT_LIB}', _ifport_lib()) + cmd = cmd.replace('{PYTHON_LIB}', _python_lib()) + return cmd + +def _compile_objs_script_lines(modules: str, + src_path: str, + include_path: str=''): + compiler = _compiler_name() + options = _compiler_options() + src_ext = CONFIG['build']['src-ext'] + template_cmd = CONFIG['template']['build-obj'] + if not include_path: + template_cmd = template_cmd.replace(' -I {INCLUDE}', '') + else: + template_cmd = template_cmd.replace('{INCLUDE}', include_path) + total = _total_src_file_count(modules) + current = 0 + lines = [] + for module in CONFIG[modules]: + if 'main-file' in module: + current += 1 + name = f'{module["main-file"]}.{src_ext}' + msg = _echo_progress_msg(current, total, f'{name}') + lines.append(msg) + path = os.path.join(src_path, name) + cmd = template_cmd + cmd = cmd.replace('{COMPILER}', compiler) + cmd = cmd.replace('{OPTIONS}', options) + cmd = cmd.replace('{PATH}', path) + lines.append(cmd) + if 'components-dir' in module and 'components-files' in module: + components_dir = module['components-dir'] + for component_file in module['components-files']: + current += 1 + name = f'{component_file}.{src_ext}' + path = os.path.join(components_dir, name) + msg = _echo_progress_msg(current, total, f'{components_dir}/{name}') + lines.append(msg) + path = os.path.join(src_path, path) + cmd = template_cmd + cmd = cmd.replace('{COMPILER}', compiler) + cmd = cmd.replace('{OPTIONS}', options) + cmd = cmd.replace('{PATH}', path) + cmd = f'{cmd}&' # start this bash command in background for parallel compilation + lines.append(cmd) + if current % 11 == 0: # do not parallelise for more than 10 compilations + lines.append('wait') # wait for all parallel bash commands to finish + lines.append('wait') # wait for all parallel bash commands to finish + return lines + +def _compile_shared_objs_or_dynamic_libs_script_lines(modules: str): + shared_lib_ext = CONFIG['build']['shared-lib-ext'][_platform()] + cfml_lib_name = CONFIG['cfml']['static-lib-name'] + cfml_dist_dir = CONFIG['cfml']['dir']['dist'] + cfml_dist_path = os.path.join(_project_path(), cfml_dist_dir) + cfml_lib_dist_dir = CONFIG['cfml']['dir']['dist-lib'] + cfml_lib_dist_path = os.path.join(_project_path(), cfml_lib_dist_dir) + template_cmd = _compiler_build_shared_template() + total = _total_src_file_count(modules) + current = 0 + lines = [] + for module in CONFIG[modules]: + if 'main-file' in module: + current += 1 + name = f'{module["main-file"]}' + msg = _echo_progress_msg(current, total, f'{name}.{_obj_ext()}') + lines.append(msg) + cmd = template_cmd + cmd = cmd.replace('{COMPILER}', _compiler_name()) + cmd = cmd.replace('{PATH}', name) + cmd = cmd.replace('{OBJ_EXT}', _compiler_obj_ext()) + cmd = cmd.replace('{EXT}', shared_lib_ext) + cmd = cmd.replace('{CFML_LIB_PATH}', cfml_lib_dist_path) + cmd = cmd.replace('{CFML_LIB_NAME}', cfml_lib_name) + cmd = cmd.replace('{IFPORT_LIB}', _ifport_lib()) + cmd = cmd.replace('{PYTHON_LIB}', _python_lib()) + #lines.append(f"echo '>>>>> {cmd}'") + lines.append(cmd) + return lines + +def _compile_executables_script_lines(modules: str, + src_path: str, + include_path: str, + lib_dir: str, + lib_name: str): + src_ext = CONFIG['build']['src-ext'] + lib_ext = CONFIG['build']['static-lib-ext'][_platform()] + template_cmd = _compiler_build_exe_template() + compiler = _compiler_name() + options = _compiler_options() + total = _total_src_file_count(modules) + current = 0 + lines = [] + for test in CONFIG[modules]: + current += 1 + dir = test["main-dir"] + main_name = test["main-file"] + source_name = f'{main_name}.{src_ext}' + msg = _echo_progress_msg(current, total, f"{source_name}") + lines.append(msg) + source_path = os.path.join(src_path, dir, source_name) + cmd = template_cmd + cmd = cmd.replace('{COMPILER}', compiler) + cmd = cmd.replace('{OPTIONS}', options) + cmd = cmd.replace('{EXE_NAME}', main_name) + cmd = cmd.replace('{SOURCE_PATH}', source_path) + cmd = cmd.replace('{CFML_INCLUDE_PATH}', include_path) + cmd = cmd.replace('{CFML_LIB_DIR}', lib_dir) + cmd = cmd.replace('{CFML_LIB_NAME}', lib_name) + cmd = cmd.replace('{LIB_EXT}', lib_ext) + #lines.append(f"echo '>>>>> {cmd}'") + lines.append(cmd) + return lines + +def _run_subprocess(cmd:str): + result = None + p = subprocess.run(cmd, shell=True, text=True, capture_output=True) + result = p.stdout + return result + +def parsed_args(): + parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter) + parser.add_argument("--create-scripts", + action='store_true', + help="create scripts for building and testing") + parser.add_argument("--platform", + default="macos", + choices=['macos', 'linux', 'windows'], + type=str.lower, + help="platform identifier") + parser.add_argument("--compiler", + default="gfortran", + choices=['gfortran', 'nagfor', 'ifx', 'ifort'], + type=str.lower, + help="fortran compiler") + parser.add_argument("--mode", + default="debug", + choices=['debug', 'release'], + type=str.lower, + help="compiling mode") + parser.add_argument("--bash-syntax", + action='store_true', + help="force bash shell syntax") + parser.add_argument("--enable-backslash-escapes", + action='store_true', + help="enable interpret backslash escapes (needed for GitHub CI)") + parser.add_argument("--print-wheel-dir", + action='store_true', + help="print pycfml wheel directory name") + parser.add_argument("--print-release-version", + action='store_true', + help="print pycfml package release version") + parser.add_argument("--print-release-title", + action='store_true', + help="print pycfml package release title") + return parser.parse_args() + +def loaded_pyproject(): + path = os.path.join(_project_dir(), 'pyproject.toml') + #with open(path, 'rb') as f: + #pyproject = tomllib.load(f) + pyproject = toml.load(path) + return pyproject + +def loaded_config(name: str): + path = _config_path(name) + #with open(path, 'rb') as f: + #config = tomllib.load(f) + config = toml.load(path) + if _bash_syntax(): + for idx, build in enumerate(config['build-configs']): + config['build-configs'][idx]['build-shared'] = build['build-shared'].replace('/', '-') + config['build-configs'][idx]['build-exe'] = build['build-exe'].replace('/', '-') + config['build-configs'][idx]['modes']['base'] = build['modes']['base'].replace('/', '-') + config['build-configs'][idx]['modes']['debug'] = build['modes']['debug'].replace('/', '-') + config['build-configs'][idx]['modes']['release'] = build['modes']['release'].replace('/', '-') + return config + +def clear_main_script(): + path = _main_script_path() + if not os.path.isfile(path): + file = Path(path) + file.parent.mkdir(exist_ok=True, parents=True) + with open(path, 'w') as file: + pass + +def append_to_main_script(obj: str | list): + path = _main_script_path() + if isinstance(obj, str): + lines = [obj] + elif isinstance(obj, list): + lines = obj + with open(path, 'a') as file: + for line in lines: + line = _apply_bash_syntax_if_needed(line) + file.write(line + '\n') + _fix_file_permissions(path) + +def add_main_script_header(txt: str): + header = _echo_header(txt) + append_to_main_script(header) + +def print_build_variables(): + lines = [] + msg = _echo_msg(f"Platform: {_platform()}") + lines.append(msg) + msg = _echo_msg(f"Processor: {_processor()}") + lines.append(msg) + msg = _echo_msg(f"Compiling mode: {_compiling_mode()}") + lines.append(msg) + #msg = _echo_msg(f"Compiler options '{_compiler_options()}'") + #lines.append(msg) + msg = _echo_msg(f"Fortran compiler: {_compiler_name()}") + lines.append(msg) + msg = _echo_msg(f"Python version: {_python_version_full()}") + lines.append(msg) + msg = _echo_msg(f"Python tag: {_python_tag()}") + lines.append(msg) + msg = _echo_msg(f"Python site packages: {_python_site_packages()}") + lines.append(msg) + msg = _echo_msg(f"Python lib: {_python_lib()}") + lines.append(msg) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def create_cfml_repo_dir(): + repo_dir = CONFIG['cfml']['dir']['repo'] + repo_path = os.path.join(_project_path(), repo_dir) + lines = [] + msg = _echo_msg(f"Deleting build dir '{repo_dir}'") + lines.append(msg) + cmd = f'rm -rf {repo_path}' + lines.append(cmd) + msg = _echo_msg(f"Creating build dir '{repo_dir}'") + lines.append(msg) + cmd = f'mkdir -p {repo_path}' + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def download_cfml_repo(): + project_name = CONFIG['cfml']['log-name'] + url = CONFIG['cfml']['git']['url'] + branch = CONFIG['cfml']['git']['branch'] + out_dir = CONFIG['cfml']['dir']['repo'] + out_path = os.path.abspath(out_dir) + lines = [] + msg = _echo_msg(f"Downloading {project_name} ('{branch}' branch) to '{out_dir}' from {url}") + lines.append(msg) + cmd = CONFIG['template']['clone-repo'] + cmd = cmd.replace('{BRANCH}', branch) + cmd = cmd.replace('{URL}', url) + cmd = cmd.replace('{OUT_PATH}', out_path) + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def create_cfml_build_dir(): + build_dir = CONFIG['cfml']['dir']['build-obj'] + build_path = os.path.join(_project_path(), build_dir) + lines = [] + msg = _echo_msg(f"Deleting build dir '{build_dir}'") + lines.append(msg) + cmd = f'rm -rf {build_path}' + lines.append(cmd) + msg = _echo_msg(f"Creating build dir '{build_dir}'") + lines.append(msg) + cmd = f'mkdir -p {build_path}' + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def rename_global_deps_file(): + src_ext = CONFIG['build']['src-ext'] + src_dir = CONFIG['cfml']['dir']['repo-src'] + if _platform() == 'macos': + platform_suffix = 'MacOS' + elif _platform() == 'linux': + platform_suffix = 'Linux' + elif _platform() == 'windows': + platform_suffix = 'Windows' + compiler = _compiler_name() + if compiler in ['gfortran', 'nagfor']: + compiler_suffix = 'GFOR' + elif compiler in ['ifort', 'ifx']: + compiler_suffix = 'IFOR' + from_name = f'CFML_GlobalDeps_{platform_suffix}_{compiler_suffix}.{src_ext}' + from_relpath = os.path.join(src_dir, from_name) + from_abspath = os.path.join(_project_path(), from_relpath) + to_name = f'CFML_GlobalDeps.{src_ext}' + to_relpath = os.path.join(src_dir, to_name) + to_abspath = os.path.join(_project_path(), to_relpath) + lines = [] + msg = _echo_msg(f"Copying '{from_relpath}' to '{to_relpath}'") + lines.append(msg) + cmd = f'cp {from_abspath} {to_abspath}' + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def build_cfml_modules_obj(): + project_name = CONFIG['cfml']['log-name'] + src_dir = CONFIG['cfml']['dir']['repo-src'] + src_path = os.path.join(_project_path(), src_dir) + build_dir = CONFIG['cfml']['dir']['build-obj'] + build_path = os.path.join(_project_path(), build_dir) + lines = [] + msg = _echo_msg(f"Entering build dir '{build_dir}'") + lines.append(msg) + cmd = f'cd {build_path}' + lines.append(cmd) + msg = _echo_msg(f"Building fortran objects for {project_name} modules") + lines.append(msg) + compile_lines = _compile_objs_script_lines('src-cfml-modules', + src_path) + lines.extend(compile_lines) + msg = _echo_msg(f"Exiting build dir '{build_dir}'") + lines.append(msg) + cmd = f'cd {_project_path()}' + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def delete_renamed_global_deps_file(): + src_ext = CONFIG['build']['src-ext'] + src_dir = CONFIG['cfml']['dir']['repo-src'] + name = f'CFML_GlobalDeps.{src_ext}' + relpath = os.path.join(src_dir, name) + abspath = os.path.join(_project_path(), relpath) + lines = [] + msg = _echo_msg(f"Deleting previously created '{relpath}'") + lines.append(msg) + cmd = f'rm {abspath}' + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def build_cfml_static_lib(): + lib_ext = CONFIG['build']['static-lib-ext'][_platform()] + static_lib_prefix = CONFIG['build']['static-lib-prefix'][_platform()] + lib_name = CONFIG['cfml']['static-lib-name'] + lib_name = f'{static_lib_prefix}{lib_name}' + build_dir = CONFIG['cfml']['dir']['build-obj'] + build_path = os.path.join(_project_path(), build_dir) + lines = [] + msg = _echo_msg(f"Entering build dir '{build_dir}'") + lines.append(msg) + cmd = f'cd {build_path}' + lines.append(cmd) + msg = _echo_msg(f"Creating fortran static library '{lib_name}.{lib_ext}'") + lines.append(msg) + cmd = CONFIG['template']['build-static'][_platform()] + cmd = cmd.replace('{LIB}', lib_name) + cmd = cmd.replace('{OBJ_EXT}', _obj_ext()) + lines.append(cmd) + msg = _echo_msg(f"Exiting build dir '{build_dir}'") + lines.append(msg) + cmd = f'cd {_project_path()}' + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def create_cfml_dist_dir(): + dist_dir = CONFIG['cfml']['dir']['dist'] + lib_dir = CONFIG['cfml']['dir']['dist-lib'] + include_dir = CONFIG['cfml']['dir']['dist-include'] + progs_dir = CONFIG['cfml']['dir']['dist-progs'] + lines = [] + msg = _echo_msg(f"Deleting dist dir '{dist_dir}'") + lines.append(msg) + cmd = f'rm -rf {dist_dir}' + lines.append(cmd) + msg = _echo_msg(f"Creating dist dir '{dist_dir}'") + lines.append(msg) + cmd = f'mkdir -p {dist_dir}' + lines.append(cmd) + msg = _echo_msg(f"Creating dist dir '{lib_dir}'") + lines.append(msg) + cmd = f'mkdir -p {lib_dir}' + lines.append(cmd) + msg = _echo_msg(f"Creating dist dir '{include_dir}'") + lines.append(msg) + cmd = f'mkdir -p {include_dir}' + lines.append(cmd) + msg = _echo_msg(f"Creating dist dir '{progs_dir}'") + lines.append(msg) + cmd = f'mkdir -p {progs_dir}' + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def move_built_to_cfml_dist(): + lib_ext = CONFIG['build']['static-lib-ext'][_platform()] + static_lib_prefix = CONFIG['build']['static-lib-prefix'][_platform()] + lib_name = CONFIG['cfml']['static-lib-name'] + lib_name = f'{static_lib_prefix}{lib_name}' + build_dir = CONFIG['cfml']['dir']['build-obj'] + build_path = os.path.join(_project_path(), build_dir) + lib_dist_dir = CONFIG['cfml']['dir']['dist-lib'] + lib_dist_path = os.path.join(_project_path(), lib_dist_dir) + include_dist_dir = CONFIG['cfml']['dir']['dist-include'] + include_dist_path = os.path.join(_project_path(), include_dist_dir) + lines = [] + msg = _echo_msg(f"Moving built lib '{lib_name}.{lib_ext}' to dist dir '{lib_dist_dir}'") + lines.append(msg) + from_path = os.path.join(build_path, f'{lib_name}.{lib_ext}') + cmd = f'mv {from_path} {lib_dist_path}' + lines.append(cmd) + msg = _echo_msg(f"Moving built modules '*.*mod' to dist dir '{include_dist_dir}'") + lines.append(msg) + from_path = os.path.join(build_path, '*.*mod') + cmd = f'mv {from_path} {include_dist_path}' + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def build_cfml_test_programs(): + project_name = CONFIG['cfml']['log-name'] + src_dir = CONFIG['cfml']['dir']['repo-tests'] + src_path = os.path.join(_project_path(), src_dir) + #build_dir = os.path.join('tests', 'functional_tests', 'cfml') + build_dir = CONFIG['cfml']['dir']['dist-progs'] + build_path = os.path.join(_project_path(), build_dir) + dist_dir = CONFIG['cfml']['dir']['dist'] + include_dir = CONFIG['cfml']['dir']['dist-include'] + include_path = os.path.join(_project_path(), include_dir) + lib_dir = CONFIG['cfml']['dir']['dist-lib'] + lib_path = os.path.join(_project_path(), lib_dir) + lib_name = CONFIG['cfml']['static-lib-name'] + lines = [] + msg = _echo_msg(f"Entering build dir '{build_dir}'") + lines.append(msg) + cmd = f'cd {build_path}' + lines.append(cmd) + msg = _echo_msg(f"Building test programs for {project_name}") + lines.append(msg) + compile_lines = _compile_executables_script_lines('src-cfml-tests', + src_path, include_path, + lib_path, + lib_name) + lines.extend(compile_lines) + msg = _echo_msg(f"Deleting *.mod/*.smod files in '{build_dir}'") + lines.append(msg) + cmd = f'rm -rf *.*mod' + lines.append(cmd) + msg = _echo_msg(f"Exiting build dir '{build_dir}'") + lines.append(msg) + cmd = f'cd {_project_path()}' + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def copy_cfml_test_programs_to_tests_dir(): + progs_relpath = CONFIG['cfml']['dir']['dist-progs'] + progs_abspath = os.path.join(_project_path(), progs_relpath) + from_path = os.path.join(progs_abspath, '*') + tests_relpath = os.path.join('tests', 'functional_tests', 'CFML') + tests_abspath = os.path.join(_project_path(), tests_relpath) + to_path = tests_abspath + lines = [] + msg = _echo_msg(f"Copying all files from '{progs_relpath}' to '{tests_relpath}'") + lines.append(msg) + cmd = f'cp {from_path} {to_path}' + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def run_cfml_functional_tests_no_benchmarks(): + tests_relpath = os.path.join('tests', 'functional_tests', 'CFML') + tests_abspath = os.path.join(_project_path(), tests_relpath) + lines = [] + msg = _echo_msg(f"Entering tests dir '{tests_relpath}'") + lines.append(msg) + cmd = f'cd {tests_relpath}' + lines.append(cmd) + msg = _echo_msg(f"Running functional tests from '{tests_relpath}'") + lines.append(msg) + cmd = CONFIG['template']['run-tests'] + cmd = cmd.replace('{PATH}', tests_abspath) + lines.append(cmd) + msg = _echo_msg(f"Exiting tests dir '{tests_relpath}'") + lines.append(msg) + cmd = f'cd {_project_path()}' + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def run_cfml_functional_tests_with_benchmarks(): + project_name = CONFIG['cfml']['log-name'] + relpath = os.path.join('tests', 'functional_tests', 'CFML') + abspath = os.path.join(_project_path(), relpath) + lines = [] + msg = _echo_msg(f"Running functional tests with benchmarks from '{relpath}'") + lines.append(msg) + cmd = CONFIG['template']['run-benchmarks']['base'] + if _github_branch() == 'develop': + cmd += ' ' + CONFIG['template']['run-benchmarks']['develop-branch'] + else: + cmd += ' ' + CONFIG['template']['run-benchmarks']['non-develop-branch'] + cmd = cmd.replace('{PATH}', abspath) + cmd = cmd.replace('{PROJECT}', project_name) + if _github_actions(): + cmd = cmd.replace('{RUNNER}', 'github') + else: + cmd = cmd.replace('{RUNNER}', 'local') + cmd = cmd.replace('{COMPILER}', _compiler_name()) + cmd = cmd.replace('{PROCESSOR}', _processor()) + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def copy_powder_mod_to_pycfml_repo(): + CFML = CONFIG['cfml']['log-name'] + cfml_repo_dir = CONFIG['cfml']['dir']['repo'] + cfml_repo_path = os.path.join(_project_path(), cfml_repo_dir) + pyCFML = CONFIG['pycfml']['log-name'] + pycfml_repo_dir = CONFIG['pycfml']['dir2']['repo'] + pycfml_src_dir = CONFIG['pycfml']['dir2']['repo-src'] + pycfml_src_path = os.path.join(_project_path(), pycfml_repo_dir, pycfml_src_dir) + src_ext = CONFIG['build']['src-ext'] + lines = [] + from_relpath = os.path.join('Testing', 'Powder', 'Test_2', 'fortran', 'src', f'powder_mod.{src_ext}') + from_abspath = os.path.join(cfml_repo_path, from_relpath) + msg = _echo_msg(f"Copying '{from_relpath}' to '{pycfml_repo_dir}/{pycfml_src_dir}'") + lines.append(msg) + cmd = f'cp {from_abspath} {pycfml_src_path}' + lines.append(cmd) + from_relpath = os.path.join('Testing', 'Powder', 'Test_3', f'powder_mod_2.{src_ext}') + from_abspath = os.path.join(cfml_repo_path, from_relpath) + msg = _echo_msg(f"Copying '{from_relpath}' to '{pycfml_repo_dir}/{pycfml_src_dir}'") + lines.append(msg) + cmd = f'cp {from_abspath} {pycfml_src_path}' + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def create_pycfml_src_dir(): + src_dir = CONFIG['pycfml']['dir']['build-src'] + lines = [] + msg = _echo_msg(f"Deleting src dir '{src_dir}'") + lines.append(msg) + cmd = f'rm -rf {src_dir}' + lines.append(cmd) + msg = _echo_msg(f"Creating src dir '{src_dir}'") + lines.append(msg) + cmd = f'mkdir -p {src_dir}' + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def create_pycfml_build_dir(): + build_dir = CONFIG['pycfml']['dir']['build-obj'] + lines = [] + msg = _echo_msg(f"Deleting build dir '{build_dir}'") + lines.append(msg) + cmd = f'rm -rf {build_dir}' + lines.append(cmd) + msg = _echo_msg(f"Creating build dir '{build_dir}'") + lines.append(msg) + cmd = f'mkdir -p {build_dir}' + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def create_pycfml_src(): + project_name = CONFIG['pycfml']['log-name'] + apigen_relpath = CONFIG['cfml']['scripts']['pyapigen'] + apigen_parent_relpath = Path(apigen_relpath).parent.as_posix() + apigen_file = Path(apigen_relpath).name + build_relpath = CONFIG['pycfml']['dir']['build-src'] + build_abspath = os.path.join(_project_path(), build_relpath) + lines = [] + msg = _echo_msg(f"Entering Python API gen dir '{apigen_parent_relpath}'") + lines.append(msg) + cmd = f'cd {apigen_parent_relpath}' + lines.append(cmd) + msg = _echo_msg(f"Creating {project_name} source code with '{apigen_file}'") + lines.append(msg) + cmd = CONFIG['template']['run-python'] + cmd = cmd.replace('{PATH}', apigen_file) + cmd = cmd.replace('{OPTIONS}', f'--verbose False --scripts False --build {build_abspath}') + lines.append(cmd) + msg = _echo_msg(f"Exiting build dir '{apigen_parent_relpath}'") + lines.append(msg) + cmd = f'cd {_project_path()}' + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def build_pycfml_modules_obj(): + project_name = CONFIG['cfml']['log-name'] + src_relpath = CONFIG['pycfml']['dir']['build-src-fortran'] + src_abspath = os.path.join(_project_path(), src_relpath) + build_relpath = CONFIG['pycfml']['dir']['build-obj'] + include_relpath = CONFIG['cfml']['dir']['dist-include'] + include_abspath = os.path.join(_project_path(), include_relpath) + lines = [] + msg = _echo_msg(f"Entering build dir '{build_relpath}'") + lines.append(msg) + cmd = f'cd {build_relpath}' + lines.append(cmd) + msg = _echo_msg(f"Building fortran objects for {project_name} modules") + lines.append(msg) + compile_lines = _compile_objs_script_lines('src-cfml-wraps', + src_abspath, + include_abspath) + lines.extend(compile_lines) + msg = _echo_msg(f"Exiting build dir '{build_relpath}'") + lines.append(msg) + cmd = f'cd {_project_path()}' + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def build_pycfml_lib_obj(): + project_name = CONFIG['pycfml']['log-name'] + src_ext = CONFIG['build']['src-ext'] + pycfml_src_name = CONFIG['pycfml']['src-name'] + pycfml_src_file = f'{pycfml_src_name}.{src_ext}' + src_relpath = CONFIG['pycfml']['dir']['build-src-fortran'] + src_abspath = os.path.join(_project_path(), src_relpath, pycfml_src_file) + build_relpath = CONFIG['pycfml']['dir']['build-obj'] + include_relpath = CONFIG['cfml']['dir']['dist-include'] + include_abspath = os.path.join(_project_path(), include_relpath) + lines = [] + msg = _echo_msg(f"Entering build dir '{build_relpath}'") + lines.append(msg) + cmd = f'cd {build_relpath}' + lines.append(cmd) + msg = _echo_msg(f"Building fortran object for {project_name} library") + lines.append(msg) + compile_line = _compile_obj_script_line(src_abspath, include_abspath) + lines.append(compile_line) + msg = _echo_msg(f"Exiting build dir '{build_relpath}'") + lines.append(msg) + cmd = f'cd {_project_path()}' + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def build_pycfml_shared_obj_or_dynamic_lib(): + build_relpath = CONFIG['pycfml']['dir']['build-obj'] + lib_name = CONFIG['pycfml']['src-name'] # NEED FIX: use CONFIG['pycfml']['dynamic-lib-name'] + lib_ext = CONFIG['build']['shared-lib-ext'][_platform()] + lines = [] + msg = _echo_msg(f"Entering build dir '{build_relpath}'") + lines.append(msg) + cmd = f'cd {build_relpath}' + lines.append(cmd) + msg = _echo_msg(f"Building fortran shared obj or dynamic lib '{lib_name}.{lib_ext}'") + lines.append(msg) + compile_line = _compile_pycfml_shared_obj_or_dynamic_lib_script_line() + lines.append(compile_line) + msg = _echo_msg(f"Exiting build dir '{build_relpath}'") + lines.append(msg) + cmd = f'cd {_project_path()}' + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def create_pycfml_dist_dir(): + dist_dir = CONFIG['pycfml']['dir']['dist'] + lib_dist_dir = CONFIG['pycfml']['dir']['dist-lib'] + include_dist_dir = CONFIG['pycfml']['dir']['dist-include'] + package_dist_dir = CONFIG['pycfml']['dir']['dist-package'].replace('{PACKAGE_NAME}', PYPROJECT['project']['name']) + wheel_dist_dir = CONFIG['pycfml']['dir']['dist-wheel'] + lines = [] + msg = _echo_msg(f"Deleting dist dir '{dist_dir}'") + lines.append(msg) + cmd = f'rm -rf {dist_dir}' + lines.append(cmd) + msg = _echo_msg(f"Creating dist dir '{dist_dir}'") + lines.append(msg) + cmd = f'mkdir -p {dist_dir}' + lines.append(cmd) + msg = _echo_msg(f"Creating dist dir '{lib_dist_dir}'") + lines.append(msg) + cmd = f'mkdir -p {lib_dist_dir}' + lines.append(cmd) + msg = _echo_msg(f"Creating dist dir '{include_dist_dir}'") + lines.append(msg) + cmd = f'mkdir -p {include_dist_dir}' + lines.append(cmd) + msg = _echo_msg(f"Creating dist dir '{package_dist_dir}'") + lines.append(msg) + cmd = f'mkdir -p {package_dist_dir}' + lines.append(cmd) + msg = _echo_msg(f"Creating dist dir '{wheel_dist_dir}'") + lines.append(msg) + cmd = f'mkdir -p {wheel_dist_dir}' + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def copy_built_to_pycfml_dist(): + project_name = CONFIG['pycfml']['log-name'] + shared_lib_ext = CONFIG['build']['shared-lib-ext'][_platform()] + build_relpath = CONFIG['pycfml']['dir']['build-obj'] + build_abspath = os.path.join(_project_path(), build_relpath) + package_relpath = CONFIG['pycfml']['dir']['dist-package'].replace('{PACKAGE_NAME}', PYPROJECT['project']['name']) + package_abspath = os.path.join(_project_path(), package_relpath) + lines = [] + msg = _echo_msg(f"Copying built {project_name} shared objects / dynamic libs to '{package_relpath}'") + lines.append(msg) + from_path = os.path.join(build_abspath, f'*.{shared_lib_ext}') + to_path = package_abspath + cmd = f'cp {from_path} {to_path}' + #cmd = cmd + ' || true' # allows to suppress the error message if no files are found + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def change_runpath_for_built_pycfml(): + # Tried to set rpath to $ORIGIN (with -Wl,-rpath,'$ORIGIN') during the build + # shared objects step (CONFIG['build-shared']), but it didn't help :( + # Ubuntu usage examples: + # sudo find / -iname "libif*" + # ls -l dist/pyCFML/pycrysfml + # patchelf --print-rpath dist/pyCFML/pycrysfml/crysfml08lib.so + # patchelf --set-rpath '$ORIGIN' dist/pyCFML/pycrysfml/crysfml08lib.so + # patchelf --print-rpath dist/pyCFML/pycrysfml/crysfml08lib.so + # patchelf --no-default-lib dist/pyCFML/pycrysfml/crysfml08lib.so + # ldd dist/pyCFML/pycrysfml/crysfml08lib.so + # ls -l /opt/hostedtoolcache/Python/3.11.8/x64/lib/python3.11/site-packages/pycrysfml08 + # ldd /opt/hostedtoolcache/Python/3.11.8/x64/lib/python3.11/site-packages/pycrysfml08/py_cfml_metrics.so + # macOS usage example: + # sudo find / -iname "libif*" + # ls -l dist/pyCFML/pycrysfml + # install_name_tool -rpath /opt/intel/oneapi/compiler/2023.2.0/mac/bin/intel64/../../compiler/lib @loader_path dist/pyCFML/pycrysfml/crysfml08lib.so + # install_name_tool -delete_rpath /usr/local/Cellar/gcc/13.2.0/lib/gcc/current dist/pyCFML/pycrysfml/crysfml08lib.so + # install_name_tool -change /usr/local/opt/gcc/lib/gcc/current/libgfortran.5.dylib @rpath/libgfortran.5.dylib dist/pyCFML/pycrysfml/crysfml08lib.so + # otool -l dist/pyCFML/pycrysfml/crysfml08lib.so | grep RPATH -A2 # build.rpaths in in pybuild.toml + # otool -L dist/pyCFML/pycrysfml/crysfml08lib.so # build.dependent-libs in pybuild.toml + try: + rpaths = CONFIG['build']['rpaths'][_platform()][_processor()][_compiler_name()] + except KeyError: + msg = _echo_msg(f"No change of runtime paths are needed for platform '{_platform()} ({_processor()})' and compiler '{_compiler_name()}'") + lines = [msg] + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + return + project_name = CONFIG['pycfml']['log-name'] + shared_lib_ext = CONFIG['build']['shared-lib-ext'][_platform()] + #dist_dir = CONFIG['pycfml']['dir2']['dist'] + #package_dir = CONFIG['pycfml']['dir2']['dist-package'] + #package_relpath = os.path.join(dist_dir, package_dir) + #package_abspath = os.path.join(_project_path(), dist_dir, package_dir) + package_relpath = CONFIG['pycfml']['dir']['dist-package'].replace('{PACKAGE_NAME}', PYPROJECT['project']['name']) + package_abspath = os.path.join(_project_path(), package_relpath) + #total = 1 + #current = 0 + lines = [] + if _platform() == 'linux': + set_rpath_template_cmd = CONFIG['template']['rpath']['set'][_platform()] + no_default_lib_template_cmd = CONFIG['template']['no-default-lib'][_platform()] + msg = _echo_msg(f"Changing runpath(s) for built {project_name} shared object") + lines.append(msg) + name = CONFIG['pycfml']['src-name'] + path = os.path.join(package_abspath, name) + for rpath in rpaths: + old_rpath = rpath['old'] + new_rpath = rpath['new'] + msg = _echo_msg(f"Changing runpath for {name}.{shared_lib_ext} from '{old_rpath}' to '{new_rpath}'") + lines.append(msg) + cmd = set_rpath_template_cmd + cmd = cmd.replace('{NEW}', new_rpath) + cmd = cmd.replace('{PATH}', path) + cmd = cmd.replace('{EXT}', shared_lib_ext) + lines.append(cmd) + cmd = no_default_lib_template_cmd + cmd = cmd.replace('{PATH}', path) + cmd = cmd.replace('{EXT}', shared_lib_ext) + lines.append(cmd) + elif _platform() == 'macos': + try: + dependent_libs = CONFIG['build']['dependent-libs'][_platform()][_processor()][_compiler_name()] + change_lib_template_cmd = CONFIG['template']['dependent-lib']['change'][_platform()] + except KeyError: + dependent_libs = [] + delete_rpath_template_cmd = CONFIG['template']['rpath']['delete'][_platform()] + change_rpath_template_cmd = CONFIG['template']['rpath']['change'][_platform()] + msg = _echo_msg(f"Changing runpath(s) for built {project_name} shared objects") + lines.append(msg) + name = CONFIG['pycfml']['src-name'] + path = os.path.join(package_abspath, name) + for rpath in rpaths: + old_rpath = rpath['old'] + new_rpath = rpath['new'] + msg = _echo_msg(f"Changing runpath for {name}.{shared_lib_ext} from '{old_rpath}' to '{new_rpath}'") + lines.append(msg) + if rpath['new'] == '': # delete this rpath + cmd = delete_rpath_template_cmd + cmd = cmd.replace('{OLD}', old_rpath) + cmd = cmd.replace('{PATH}', path) + cmd = cmd.replace('{EXT}', shared_lib_ext) + else: # change this rpath + cmd = change_rpath_template_cmd + cmd = cmd.replace('{OLD}', old_rpath) + cmd = cmd.replace('{NEW}', new_rpath) + cmd = cmd.replace('{PATH}', path) + cmd = cmd.replace('{EXT}', shared_lib_ext) + #cmd = cmd + ' || true' # allows to suppress the error message if no files are found + lines.append(cmd) + for lib in dependent_libs: + old_lib = lib['old'] + new_lib = lib['new'] + msg = _echo_msg(f"Changing the dependent shared library install name for {name}.{shared_lib_ext} from '{old_lib}' to '{new_lib}'") + lines.append(msg) + cmd = change_lib_template_cmd + cmd = cmd.replace('{OLD}', old_lib) + cmd = cmd.replace('{NEW}', new_lib) + cmd = cmd.replace('{PATH}', path) + cmd = cmd.replace('{EXT}', shared_lib_ext) + #cmd = cmd + ' || true' # allows to suppress the error message if no files are found + lines.append(cmd) + else: + msg = _echo_msg(f"Changing runpath is not needed for platform '{_platform()}'") + lines.append(msg) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def copy_extra_libs_to_pycfml_dist(): + try: + extra_libs = CONFIG['build']['extra-libs'][_platform()][_processor()][_compiler_name()] + except KeyError: + msg = _echo_msg(f"No extra libraries are needed for platform '{_platform()}' and compiler '{_compiler_name()}'") + lines = [msg] + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + return + package_relpath = CONFIG['pycfml']['dir']['dist-package'].replace('{PACKAGE_NAME}', PYPROJECT['project']['name']) + package_abspath = os.path.join(_project_path(), package_relpath) + lines = [] + for lib_path in extra_libs: + msg = _echo_msg(f"Copying {lib_path} to dist dir '{package_relpath}'") + lines.append(msg) + cmd = f'cp {lib_path} {package_abspath}' + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def copy_py_api_files_to_pycfml_dist(): + project_name = CONFIG['pycfml']['log-name'] + py_api_relpath = CONFIG['pycfml']['dir']['build-src-python'] + py_api_abspath = os.path.join(_project_path(), py_api_relpath) + from_path = os.path.join(py_api_abspath, '*.py') + package_relpath = CONFIG['pycfml']['dir']['dist-package'].replace('{PACKAGE_NAME}', PYPROJECT['project']['name']) + package_abspath = os.path.join(_project_path(), package_relpath) + to_path = package_abspath + lines = [] + msg = _echo_msg(f"Copying {project_name} python api files from '{py_api_relpath}' to dist dir '{package_relpath}'") + lines.append(msg) + cmd = f'cp {from_path} {to_path}' + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def copy_init_file_to_pycfml_dist(): + project_name = CONFIG['pycfml']['log-name'] + from_path = os.path.join(_project_path(), 'src', '__init__.py') + package_relpath = CONFIG['pycfml']['dir']['dist-package'].replace('{PACKAGE_NAME}', PYPROJECT['project']['name']) + package_abspath = os.path.join(_project_path(), package_relpath) + to_path = package_abspath + lines = [] + msg = _echo_msg(f"Copying {project_name} 'src/__init__.py' to dist dir '{package_relpath}'") + lines.append(msg) + cmd = f'cp {from_path} {to_path}' + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def copy_cfml_databases_to_pycfml_dist(): + cfml_db_relpath = CONFIG['cfml']['dir']['repo-database'] + cfml_db_abspath = os.path.join(_project_path(), cfml_db_relpath) + from_path = cfml_db_abspath + package_relpath = CONFIG['pycfml']['dir']['dist-package'].replace('{PACKAGE_NAME}', PYPROJECT['project']['name']) + pycfml_db_relpath = os.path.join(package_relpath, 'Databases') + pycfml_db_abspath = os.path.join(_project_path(), pycfml_db_relpath) + to_path = pycfml_db_abspath + lines = [] + msg = _echo_msg(f"Creating dir '{pycfml_db_relpath}'") + lines.append(msg) + cmd = f'mkdir -p {pycfml_db_relpath}' + lines.append(cmd) + msg = _echo_msg(f"Copying '{cfml_db_relpath}' database to dist dir '{pycfml_db_relpath}'") + lines.append(msg) + cmd = f'cp {from_path} {to_path}' + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def validate_pyproject_toml(): + lines = [] + msg = _echo_msg(f"Validating pyproject.toml") + lines.append(msg) + cmd = 'validate-pyproject pyproject.toml' + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def create_pycfml_python_wheel(): + project_name = CONFIG['pycfml']['log-name'] + wheel_dir = CONFIG['pycfml']['dir']['dist-wheel'] + wheel_path = os.path.join(_project_path(), wheel_dir) + lines = [] + msg = _echo_msg(f"Creating {project_name} python wheel in '{wheel_dir}'") + lines.append(msg) + cmd = CONFIG['template']['build-wheel'] + cmd = cmd.replace('{PATH}', wheel_path) + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def rename_pycfml_python_wheel(): + project_name = CONFIG['pycfml']['log-name'] + wheel_dir = CONFIG['pycfml']['dir']['dist-wheel'] + wheel_relpath = os.path.join(wheel_dir, _initial_wheel_name()) + wheel_abspath = os.path.join(_project_path(), wheel_relpath) + lines = [] + msg = _echo_msg(f"Renaming {project_name} python wheel from '{_initial_wheel_name()}' to '{_new_wheel_name()}' in '{wheel_dir}'") + lines.append(msg) + cmd = CONFIG['template']['rename-wheel'] + cmd = cmd.replace('{PYTHON_TAG}', _python_tag()) # https://packaging.python.org/en/latest/specifications/platform-compatibility-tags/ + cmd = cmd.replace('{PLATFORM_TAG}', _platform_tag_github_ci()) + cmd = cmd.replace('{PATH}', wheel_abspath) + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def detect_abi3_violations(): + wheel_dir = CONFIG['pycfml']['dir']['dist-wheel'] + wheel_path = os.path.join(wheel_dir, _new_wheel_name()) + lines = [] + msg = _echo_msg(f"Scanning Python extensions in python wheel '{_new_wheel_name()}' for abi3 violations") + lines.append(msg) + cmd = f'abi3audit {wheel_path}' + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def check_wheel_contents(): + wheel_dir = CONFIG['pycfml']['dir']['dist-wheel'] + wheel_path = os.path.join(wheel_dir, _new_wheel_name()) + lines = [] + msg = _echo_msg(f"Checking content of Python wheel '{_new_wheel_name()}'") + lines.append(msg) + cmd = f'check-wheel-contents {wheel_path}' + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def install_pycfml_from_wheel(): + project_name = CONFIG['pycfml']['log-name'] + package_name = PYPROJECT['project']['name'] + wheel_dir = CONFIG['pycfml']['dir']['dist-wheel'] + wheel_path = os.path.join(_project_path(), wheel_dir) + lines = [] + msg = _echo_msg(f"Installing {project_name} python wheel from '{wheel_dir}'") + lines.append(msg) + cmd = CONFIG['template']['install-wheel'] + cmd = cmd.replace('{PACKAGE}', package_name) + cmd = cmd.replace('{PATH}', wheel_path) + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def run_pycfml_unit_tests(): + relpath = os.path.join('tests', 'unit_tests', 'pyCFML') + abspath = os.path.join(_project_path(), relpath) + lines = [] + msg = _echo_msg(f"Running unit tests from '{relpath}'") + lines.append(msg) + cmd = CONFIG['template']['run-tests'] + cmd = cmd.replace('{PATH}', abspath) + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def run_powder_mod_tests(): + relpath = os.path.join('tests', 'functional_tests', 'pyCFML') + abspath = os.path.join(_project_path(), relpath) + lines = [] + msg = _echo_msg(f"Running powder_mod tests from '{relpath}'") + lines.append(msg) + cmd = CONFIG['template']['run-tests'] + cmd = cmd.replace('{PATH}', abspath) + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def run_powder_mod_main(): + relpath = os.path.join('tests', 'functional_tests', 'pycfml', 'test__powder_mod.py') + abspath = os.path.join(_project_path(), relpath) + lines = [] + msg = _echo_msg(f"Running powder_mod main from '{relpath}'") + lines.append(msg) + cmd = CONFIG['template']['run-python'] + cmd = cmd.replace('{PATH}', abspath) + cmd = cmd.replace('{OPTIONS}', '') + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def run_pycfml_functional_tests_no_benchmarks(): + relpath = os.path.join('tests', 'functional_tests', 'pyCFML') + abspath = os.path.join(_project_path(), relpath) + lines = [] + msg = _echo_msg(f"Running unit tests from '{relpath}'") + lines.append(msg) + cmd = CONFIG['template']['run-tests'] + cmd = cmd.replace('{PATH}', abspath) + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + +def run_pycfml_functional_tests_with_benchmarks_save(): + project_name = CONFIG['pycfml']['log-name'] + relpath = os.path.join('tests', 'functional_tests', 'pyCFML') + abspath = os.path.join(_project_path(), relpath) + lines = [] + msg = _echo_msg(f"Running functional tests with benchmarks from '{relpath}' and saving results") + lines.append(msg) + cmd = CONFIG['template']['run-benchmarks']['base'] + ' ' + CONFIG['template']['run-benchmarks']['save'] + cmd = cmd.replace('{PATH}', abspath) + cmd = cmd.replace('{PROJECT}', project_name) + if _github_actions(): + cmd = cmd.replace('{RUNNER}', 'github') + else: + cmd = cmd.replace('{RUNNER}', 'local') + cmd = cmd.replace('{COMPILER}', _compiler_name()) + cmd = cmd.replace('{PROCESSOR}', _processor()) + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + #append_to_main_script(lines) + +def run_pycfml_functional_tests_with_benchmarks_compare(): + project_name = CONFIG['pycfml']['log-name'] + relpath = os.path.join('tests', 'functional_tests', 'pyCFML') + abspath = os.path.join(_project_path(), relpath) + lines = [] + msg = _echo_msg(f"Running functional tests with benchmarks from '{relpath}' and comparing with previously saved results") + lines.append(msg) + cmd = CONFIG['template']['run-benchmarks']['base'] + ' ' + CONFIG['template']['run-benchmarks']['compare'] + cmd = cmd.replace('{PATH}', abspath) + cmd = cmd.replace('{PROJECT}', project_name) + if _github_actions(): + cmd = cmd.replace('{RUNNER}', 'github') + else: + cmd = cmd.replace('{RUNNER}', 'local') + cmd = cmd.replace('{COMPILER}', _compiler_name()) + cmd = cmd.replace('{PROCESSOR}', _processor()) + lines.append(cmd) + script_name = f'{sys._getframe().f_code.co_name}.sh' + _write_lines_to_file(lines, script_name) + append_to_main_script(lines) + + +if __name__ == '__main__': + ARGS = parsed_args() + PYPROJECT = loaded_pyproject() + CONFIG = loaded_config('pybuild.toml') + + if ARGS.print_wheel_dir: # NEED FIX. Maybe save extras to toml as in EDA? + _print_wheel_dir() + exit(0) + + if ARGS.print_release_version: # NEED FIX. Maybe save extras to toml as in EDA? + _print_release_version() + exit(0) + + if ARGS.print_release_title: # NEED FIX. Maybe save extras to toml as in EDA? + _print_release_title() + exit(0) + + if not ARGS.create_scripts: # NEED FIX. Need proper check if create scripts or print flags are given + _print_error_msg('Incorrect set of command line arguments') + exit(1) + + CFML = CONFIG['cfml']['log-name'] + pyCFML = CONFIG['pycfml']['log-name'] + + ############# + # Preparation + ############# + + clear_main_script() + + add_main_script_header(f"Print some build-specific variables") + print_build_variables() + + add_main_script_header(f"Create scripts, {CFML} and {pyCFML} directories") + create_cfml_repo_dir() + create_cfml_build_dir() + create_cfml_dist_dir() + create_pycfml_src_dir() + create_pycfml_build_dir() + create_pycfml_dist_dir() + + ############ + # Build CFML + ############ + + add_main_script_header(f"Download {CFML} repository") + download_cfml_repo() + + add_main_script_header(f"Build {CFML} modules") + rename_global_deps_file() + build_cfml_modules_obj() + delete_renamed_global_deps_file() + + add_main_script_header(f"Build {CFML} static library") + build_cfml_static_lib() + + add_main_script_header(f"Make {CFML} distribution") + move_built_to_cfml_dist() + + add_main_script_header(f"Create and run {CFML} test programs") + build_cfml_test_programs() + copy_cfml_test_programs_to_tests_dir() + run_cfml_functional_tests_no_benchmarks() + #run_cfml_functional_tests_with_benchmarks() + + ############## + # Build pyCFML + ############## + + add_main_script_header(f"Create {pyCFML} source code") + create_pycfml_src() + + add_main_script_header(f"Build {pyCFML} modules") + build_pycfml_modules_obj() + + add_main_script_header(f"Build {pyCFML} shared obj / dynamic library") + build_pycfml_lib_obj() + build_pycfml_shared_obj_or_dynamic_lib() + + add_main_script_header(f"Make {pyCFML} distribution") + copy_built_to_pycfml_dist() + change_runpath_for_built_pycfml() + copy_extra_libs_to_pycfml_dist() + copy_py_api_files_to_pycfml_dist() + copy_init_file_to_pycfml_dist() + copy_cfml_databases_to_pycfml_dist() + + add_main_script_header(f"Create Python package wheel of {pyCFML}") + validate_pyproject_toml() + create_pycfml_python_wheel() + rename_pycfml_python_wheel() + detect_abi3_violations() + check_wheel_contents() + + add_main_script_header(f"Install {pyCFML} from Python package wheel") + install_pycfml_from_wheel() + + add_main_script_header(f"Run {pyCFML} tests") + run_pycfml_unit_tests() + run_pycfml_functional_tests_no_benchmarks() + run_pycfml_functional_tests_with_benchmarks_save() + run_pycfml_functional_tests_with_benchmarks_compare() + + _print_msg(f'All scripts were successfully created in {_scripts_path()}') diff --git a/pybuild.toml b/pybuild.toml new file mode 100644 index 0000000..5a36eff --- /dev/null +++ b/pybuild.toml @@ -0,0 +1,1053 @@ +[project.dir] +scripts = 'scripts' + +############################## +# CrysFML Fortran 2008 Library +############################## + +[cfml] +log-name = 'CFML' +static-lib-name = 'CrysFML08' # without 'lib' prefix on unix-based platforms + +[cfml.dir] +repo = 'repo/CFML' +repo-src = 'repo/CFML/Src' +repo-tests = 'repo/CFML/Testing' +repo-database = 'repo/CFML/Src/Databases/magnetic_data.txt' +build = 'build/CFML' +build-obj = 'build/CFML/obj' +dist = 'dist/CFML' # Fortran CrysFML2008 +dist-include = 'dist/CFML/include' # for .mod/.smod files +dist-lib = 'dist/CFML/lib' # for static library +dist-progs = 'dist/CFML/progs' # for test programs + +[cfml.git] +url = 'https://code.ill.fr/scientific-software/crysfml2008.git' +#branch = 'powder_mod_fix' +branch = 'master' + +[cfml.scripts] +pyapigen = 'repo/CFML/Scripts/PythonAPI/apigen.py' + +############################################# +# Python API for CrysFML Fortran 2008 Library +############################################# + +[pycfml] +log-name = 'pyCFML' +src-name = 'crysfml08lib' +dynamic-lib-name = 'crysfml08lib' # NEED FIX: currently not in use in pybuild.py + +[pycfml.dir] +build-src = 'build/pyCFML/src' # content will be generated by apigen.py +build-src-fortran = 'build/pyCFML/src/Fortran' +build-src-python = 'build/pyCFML/src/PythonAPI' +build-obj = 'build/pyCFML/obj' +dist = 'dist/pyCFML' # Python API to Fortran CrysFML2008 +dist-include = 'dist/pyCFML/include' # for .mod/.smod files +dist-lib = 'dist/pyCFML/lib' # for static object or dynamic library +dist-package = 'dist/pyCFML/{PACKAGE_NAME}' # for Python package +dist-wheel = 'dist/pyCFML/wheel' # for Python wheel + +######################################################## +# Generic build template commands and related parameters +######################################################## + +[template] +clone-repo = 'git clone --single-branch --branch {BRANCH} {URL} {OUT_PATH}' +build-obj = '{COMPILER} {OPTIONS} -c {PATH} -I {INCLUDE}' +build-static.macos = 'ar -r {LIB}.a *.{OBJ_EXT}' +build-static.linux = 'ar -r {LIB}.a *.{OBJ_EXT}' +build-static.windows = 'lib /out:{LIB}.lib *.{OBJ_EXT}' +rpath.set.linux = 'patchelf --set-rpath {NEW} {PATH}.{EXT}' +rpath.change.macos = 'install_name_tool -rpath {OLD} {NEW} {PATH}.{EXT}' +rpath.add.macos = 'install_name_tool -add_rpath {NEW} {PATH}.{EXT}' +rpath.delete.macos = 'install_name_tool -delete_rpath {OLD} {PATH}.{EXT}' +no-default-lib.linux = 'patchelf --no-default-lib {PATH}.{EXT}' +dependent-lib.change.macos = 'install_name_tool -change {OLD} {NEW} {PATH}.{EXT}' +build-wheel = 'python3 -m build --wheel --outdir {PATH}' +rename-wheel = 'python3 -m wheel tags --python-tag {PYTHON_TAG} --platform-tag {PLATFORM_TAG} --remove {PATH}' +install-wheel = 'python3 -m pip install {PACKAGE} --force-reinstall --find-links={PATH}' # Dependencies "{PACKAGE}[test]" are installed via ci script +run-python = 'python3 {PATH} {OPTIONS}' +run-tests = 'pytest {PATH} --color=yes --benchmark-disable' +run-benchmarks.base = 'pytest {PATH} --color=yes --benchmark-only --benchmark-storage="file://./.benchmarks/{PROJECT}/{RUNNER}/{COMPILER}/{PROCESSOR}" --benchmark-warmup=on --benchmark-columns="median, iqr, ops"' +run-benchmarks.save = '--benchmark-autosave' +run-benchmarks.compare = '--benchmark-compare --benchmark-compare-fail=median:50%' + +###################### +# Build configurations +###################### + +[[build-configs]] +platforms = ['macos', 'linux', 'windows'] +compilers = ['gfortran'] +obj-ext = 'o' +build-shared = '{COMPILER} -shared CFML_Wraps.{OBJ_EXT} Wraps_*.{OBJ_EXT} {PATH}.{OBJ_EXT} -o {PATH}.{EXT} -L{CFML_LIB_PATH} -l{CFML_LIB_NAME} {PYTHON_LIB}' +build-exe = '{COMPILER} {OPTIONS} -o {EXE_NAME} {SOURCE_PATH} -I {CFML_INCLUDE_PATH} -L{CFML_LIB_DIR} -l{CFML_LIB_NAME}' +modes.base = '-cpp -fdec-math -fPIC -fno-stack-arrays -ffree-line-length-none' +modes.debug = '' +modes.release = '-O3' + +[[build-configs]] +platforms = ['macos'] +compilers = ['nagfor'] +obj-ext = 'o' +build-shared = '{COMPILER} -Wl,-shared CFML_Wraps.{OBJ_EXT} Wraps_*.{OBJ_EXT} {PATH}.{OBJ_EXT} -o {PATH}.{EXT} -L{CFML_LIB_PATH} -l{CFML_LIB_NAME} {PYTHON_LIB}' +build-exe = '{COMPILER} {OPTIONS} -o {EXE_NAME} {SOURCE_PATH} -I {CFML_INCLUDE_PATH} -L{CFML_LIB_DIR} -l{CFML_LIB_NAME}' +modes.base = '-f2008 -fpp -PIC -quiet -w=all -colour' +modes.debug = '' +modes.release = '-O3' + +[[build-configs]] +platforms = ['linux', 'macos'] +compilers = ['ifort', 'ifx'] +obj-ext = 'o' +build-shared = "{COMPILER} -shared CFML_Wraps.{OBJ_EXT} Wraps_*.{OBJ_EXT} {PATH}.{OBJ_EXT} -o {PATH}.{EXT} -L{CFML_LIB_PATH} -l{CFML_LIB_NAME} {IFPORT_LIB} {PYTHON_LIB}" +build-exe = '{COMPILER} {OPTIONS} -o {EXE_NAME} {SOURCE_PATH} -I {CFML_INCLUDE_PATH} -L{CFML_LIB_DIR} -l{CFML_LIB_NAME}' +modes.base = '-w -fpp -fPIC -heap-arrays -nologo' +modes.debug = '' # -g3 +modes.release = '-O3' # -O3 + +[[build-configs]] +platforms = ['windows'] +compilers = ['ifort', 'ifx'] +obj-ext = 'obj' +build-shared = 'link CFML_Wraps.{OBJ_EXT} Wraps_*.{OBJ_EXT} {PATH}.{OBJ_EXT} /out:"{PATH}.{EXT}" /libpath:{CFML_LIB_PATH} /dll {CFML_LIB_NAME}.lib {PYTHON_LIB}' +build-exe = '{COMPILER} {OPTIONS} /exe:{EXE_NAME} {SOURCE_PATH} -I {CFML_INCLUDE_PATH} {CFML_LIB_DIR}\{CFML_LIB_NAME}.{LIB_EXT}' +modes.base = '/w /fpp /heap-arrays /nologo -DWIN32=ON' +modes.debug = '' +modes.release = '-O3' + +[build] +src-ext = 'f90' +static-lib-prefix = { macos = 'lib', linux = 'lib', windows = '' } +static-lib-ext = { macos = 'a', linux = 'a', windows = 'lib' } +shared-lib-ext = { macos = 'so', linux = 'so', windows = 'pyd' } # *.dylib doesn't work on macOS, *.dll on Windows? # https://www.cita.utoronto.ca/~merz/intel_f10b/main_for/mergedProjects/bldaps_for/common/bldaps_produce_outfiles.htm +ifport-lib.linux.ifort = '-L/opt/intel/oneapi/compiler/2023.2.0/linux/compiler/lib/intel64_lin -lifport' +ifport-lib.linux.ifx = '-L/opt/intel/oneapi/compiler/2023.2.0/linux/compiler/lib/intel64_lin -lifport' +extra-libs.macos.i386.gfortran = [ + # current gcc + #'/usr/local/opt/gcc/lib/gcc/current/libgfortran.5.dylib', + #'/usr/local/opt/gcc/lib/gcc/current/libgcc_s.1.1.dylib', + #'/usr/local/opt/gcc/lib/gcc/current/libquadmath.0.dylib', + # gcc 13 + '/usr/local/opt/gcc@13/lib/gcc/13/libgfortran.5.dylib', + '/usr/local/opt/gcc@13/lib/gcc/13/libgcc_s.1.1.dylib', + '/usr/local/opt/gcc@13/lib/gcc/13/libquadmath.0.dylib', +] +extra-libs.macos.arm.gfortran = [ + # current gcc + #'/opt/homebrew/opt/gcc/lib/gcc/current/libgfortran.5.dylib', + #'/opt/homebrew/opt/gcc/lib/gcc/current/libgcc_s.1.1.dylib', + #'/opt/homebrew/opt/gcc/lib/gcc/current/libquadmath.0.dylib' + # gcc 13 + '/opt/homebrew/opt/gcc@13/lib/gcc/13/libgfortran.5.dylib', + '/opt/homebrew/opt/gcc@13/lib/gcc/13/libgcc_s.1.1.dylib', + '/opt/homebrew/opt/gcc@13/lib/gcc/13/libquadmath.0.dylib', +] +extra-libs.macos.i386.ifort = [ + '/System/Volumes/Data/opt/intel/oneapi/compiler/2023.2.0/mac/compiler/lib/libifport.dylib', + '/System/Volumes/Data/opt/intel/oneapi/compiler/2023.2.0/mac/compiler/lib/libifcoremt.dylib', + '/System/Volumes/Data/opt/intel/oneapi/compiler/2023.2.0/mac/compiler/lib/libifcore.dylib', + '/System/Volumes/Data/opt/intel/oneapi/compiler/2023.2.0/mac/compiler/lib/libimf.dylib', + '/System/Volumes/Data/opt/intel/oneapi/compiler/2023.2.0/mac/compiler/lib/libsvml.dylib', + '/System/Volumes/Data/opt/intel/oneapi/compiler/2023.2.0/mac/compiler/lib/libintlc.dylib', + '/System/Volumes/Data/opt/intel/oneapi/compiler/2023.2.0/mac/compiler/lib/libirc.dylib', + '/System/Volumes/Data/opt/intel/oneapi/compiler/2023.2.0/mac/compiler/lib/libifdynalloc.dylib', +] +extra-libs.macos.arm.ifort = [ + '/System/Volumes/Data/opt/intel/oneapi/compiler/2023.2.0/mac/compiler/lib/libifport.dylib', + '/System/Volumes/Data/opt/intel/oneapi/compiler/2023.2.0/mac/compiler/lib/libifcoremt.dylib', + '/System/Volumes/Data/opt/intel/oneapi/compiler/2023.2.0/mac/compiler/lib/libifcore.dylib', + '/System/Volumes/Data/opt/intel/oneapi/compiler/2023.2.0/mac/compiler/lib/libimf.dylib', + '/System/Volumes/Data/opt/intel/oneapi/compiler/2023.2.0/mac/compiler/lib/libsvml.dylib', + '/System/Volumes/Data/opt/intel/oneapi/compiler/2023.2.0/mac/compiler/lib/libintlc.dylib', + '/System/Volumes/Data/opt/intel/oneapi/compiler/2023.2.0/mac/compiler/lib/libirc.dylib', + '/System/Volumes/Data/opt/intel/oneapi/compiler/2023.2.0/mac/compiler/lib/libifdynalloc.dylib', +] +extra-libs.linux.x86_64.ifort = [ + '/opt/intel/oneapi/compiler/2023.2.0/linux/compiler/lib/intel64_lin/libifport.so.5', + '/opt/intel/oneapi/compiler/2023.2.0/linux/compiler/lib/intel64_lin/libifcoremt.so.5', + '/opt/intel/oneapi/compiler/2023.2.0/linux/compiler/lib/intel64_lin/libimf.so', + '/opt/intel/oneapi/compiler/2023.2.0/linux/compiler/lib/intel64_lin/libsvml.so', + '/opt/intel/oneapi/compiler/2023.2.0/linux/compiler/lib/intel64_lin/libintlc.so.5', + '/lib/x86_64-linux-gnu/libpthread.so.0', # But still: libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 + '/lib/x86_64-linux-gnu/libm.so.6', + '/lib/x86_64-linux-gnu/libc.so.6', + '/lib/x86_64-linux-gnu/libgcc_s.so.1', +] +extra-libs.linux.x86_64.ifx = [ + '/opt/intel/oneapi/compiler/2023.2.0/linux/compiler/lib/intel64_lin/libifport.so.5', + '/opt/intel/oneapi/compiler/2023.2.0/linux/compiler/lib/intel64_lin/libifcoremt.so.5', + '/opt/intel/oneapi/compiler/2023.2.0/linux/compiler/lib/intel64_lin/libimf.so', + '/opt/intel/oneapi/compiler/2023.2.0/linux/compiler/lib/intel64_lin/libsvml.so', + '/opt/intel/oneapi/compiler/2023.2.0/linux/compiler/lib/intel64_lin/libintlc.so.5', + '/lib/x86_64-linux-gnu/libpthread.so.0', # But still: libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 + '/lib/x86_64-linux-gnu/libm.so.6', + '/lib/x86_64-linux-gnu/libc.so.6', + '/lib/x86_64-linux-gnu/libgcc_s.so.1', +] +extra-libs.linux.x86_64.gfortran = [ + '/lib/x86_64-linux-gnu/libgfortran.so.5', + '/lib/x86_64-linux-gnu/libm.so.6', + '/lib/x86_64-linux-gnu/libc.so.6', + '/lib/x86_64-linux-gnu/libgcc_s.so.1', + '/lib/x86_64-linux-gnu/libmvec.so.1', +] +extra-libs.windows.AMD64.gfortran = [ + 'C:\mingw64\bin\libgcc_s_seh-1.dll', + 'C:\mingw64\bin\libgfortran-5.dll', + 'C:\mingw64\bin\libquadmath-0.dll', + 'C:\mingw64\bin\libwinpthread-1.dll', +] +extra-libs.windows.Intel64.gfortran = [ + 'C:\mingw64\bin\libgcc_s_seh-1.dll', + 'C:\mingw64\bin\libgfortran-5.dll', + 'C:\mingw64\bin\libquadmath-0.dll', + 'C:\mingw64\bin\libwinpthread-1.dll', +] +rpaths.linux.x86_64.gfortran = [ + { old = '', new = "'$ORIGIN'" }, +] # set rpath to point to '$ORIGIN' +rpaths.linux.x86_64.ifort = [ + { old = '', new = "'$ORIGIN'" }, +] # set rpath to point to '$ORIGIN' +rpaths.linux.x86_64.ifx = [ + { old = '', new = "'$ORIGIN'" }, +] # set rpath to point to '$ORIGIN' +rpaths.macos.i386.gfortran = [ + # gcc 13.2.0 + #{ old = '/usr/local/Cellar/gcc/13.2.0/lib/gcc/current/gcc/x86_64-apple-darwin21/13', new = '' }, # delete all rpaths besides @loader_path + #{ old = '/usr/local/Cellar/gcc/13.2.0/lib/gcc/current/gcc', new = '' }, # delete all rpaths besides @loader_path + #{ old = '/usr/local/Cellar/gcc/13.2.0/lib/gcc/current', new = '' }, # delete all rpaths besides @loader_path + # gcc 13.3.0 + { old = '/usr/local/Cellar/gcc@13/13.3.0/lib/gcc/13/gcc/x86_64-apple-darwin21/13', new = '' }, # delete all rpaths besides @loader_path + { old = '/usr/local/Cellar/gcc@13/13.3.0/lib/gcc/13/gcc', new = '' }, # delete all rpaths besides @loader_path + { old = '/usr/local/Cellar/gcc@13/13.3.0/lib/gcc/13', new = '' }, # delete all rpaths besides @loader_path +] +rpaths.macos.arm.gfortran = [ + # gcc 13.2.0 + #{ old = '/opt/homebrew/Cellar/gcc/13.2.0/lib/gcc/current/gcc/aarch64-apple-darwin23/13', new = '' }, # delete all rpaths besides @loader_path + #{ old = '/opt/homebrew/Cellar/gcc/13.2.0/lib/gcc/current/gcc', new = '' }, # delete all rpaths besides @loader_path + #{ old = '/opt/homebrew/Cellar/gcc/13.2.0/lib/gcc/current', new = '' }, # delete all rpaths besides @loader_path + # gcc 13.3.0 + { old = '/opt/homebrew/Cellar/gcc@13/13.3.0/lib/gcc/13/gcc/aarch64-apple-darwin23/13', new = '' }, # delete all rpaths besides @loader_path + { old = '/opt/homebrew/Cellar/gcc@13/13.3.0/lib/gcc/13/gcc', new = '' }, # delete all rpaths besides @loader_path + { old = '/opt/homebrew/Cellar/gcc@13/13.3.0/lib/gcc/13', new = '' }, # delete all rpaths besides @loader_path +] +rpaths.macos.i386.ifort = [ + { old = '/opt/intel/oneapi/compiler/2023.2.0/mac/bin/intel64/../../compiler/lib', new = '@loader_path' }, +] +rpaths.macos.arm.ifort = [ + { old = '/opt/intel/oneapi/compiler/2023.2.0/mac/bin/intel64/../../compiler/lib', new = '@loader_path' }, +] +dependent-libs.macos.i386.gfortran = [ + # current gcc + #{ old = '/usr/local/opt/gcc/lib/gcc/current/libgfortran.5.dylib', new = '@rpath/libgfortran.5.dylib' }, + #{ old = '/usr/local/opt/gcc/lib/gcc/current/libgcc_s.1.1.dylib', new = '@rpath/libgcc_s.1.1.dylib' }, + #{ old = '/usr/local/opt/gcc/lib/gcc/current/libquadmath.0.dylib', new = '@rpath/libquadmath.0.dylib' }, + # gcc 13 + { old = '/usr/local/opt/gcc@13/lib/gcc/13/libgfortran.5.dylib', new = '@rpath/libgfortran.5.dylib' }, + { old = '/usr/local/opt/gcc@13/lib/gcc/13/libgcc_s.1.1.dylib', new = '@rpath/libgcc_s.1.1.dylib' }, + { old = '/usr/local/opt/gcc@13/lib/gcc/13/libquadmath.0.dylib', new = '@rpath/libquadmath.0.dylib' }, +] +dependent-libs.macos.arm.gfortran = [ + # current gcc + #{ old = '/opt/homebrew/opt/gcc/lib/gcc/current/libgfortran.5.dylib', new = '@rpath/libgfortran.5.dylib' }, + #{ old = '/opt/homebrew/opt/gcc/lib/gcc/current/libquadmath.0.dylib', new = '@rpath/libquadmath.0.dylib' }, + # gcc 13 + { old = '/opt/homebrew/opt/gcc@13/lib/gcc/13/libgfortran.5.dylib', new = '@rpath/libgfortran.5.dylib' }, + { old = '/opt/homebrew/opt/gcc@13/lib/gcc/13/libquadmath.0.dylib', new = '@rpath/libquadmath.0.dylib' }, +] +# Examples of GitHub values for Python 3.11 +#python-lib.macos = '`python3-config --ldflags --embed`' +#python-lib.linux = '' +#python-lib.windows = 'C:\hostedtoolcache\windows\Python\3.11.9\x64\libs\python311.lib' +#site-packages.macos = '/Users/runner/hostedtoolcache/Python/3.11.9/x64/lib/python3.11/site-packages' +#site-packages.linux = '/opt/hostedtoolcache/Python/3.11.9/x64/lib/python3.11/site-packages' +#site-packages.windows = 'c:\hostedtoolcache\windows\Python\3.11.9\x64\lib\site-packages' + +############################## +# CrysFML fortran source files +############################## + +[[src-cfml-modules]] +main-file = 'Forpy' + +#[[src-cfml-modules]] +#main-file = 'CFML_Degree_Trigonometric' + +[[src-cfml-modules]] +main-file = 'CFML_GlobalDeps' + +[[src-cfml-modules]] +main-file = 'CFML_FFT' +components-dir = 'CFML_FFT' +components-files = [ + 'FFT_Gen', + 'FFT_Convol' +] + +[[src-cfml-modules]] +main-file = 'CFML_Maths' +components-dir = 'CFML_Maths' +components-files = [ + 'Math_Diagonalize_GEN', + 'Math_Equal_Vector', + 'Math_Determinant', + 'Math_Co_Prime', + 'Math_Cross_Product', + 'Math_Debye', + 'Math_Co_Linear', + 'Math_Erfc_Der', + 'Math_Diagonalize_SH', + 'Math_Factorial', + 'Math_Equal_Matrix', + 'Math_Inverse_Matrix', + 'Math_Is_Diagonal_Matrix', + 'Math_PolynomialFit', + 'Math_Lower_Triangular', + 'Math_Is_Null_Vector', + 'Math_Norm', + 'Math_Locate', + 'Math_Tensor_Product', + 'Math_Linear_Dependent', + 'Math_Polyhedron_Volume', + 'Math_Resolv_System', + 'Math_SistCoord_Changes', + 'Math_Rotation_Axes', + 'Math_Modulo_Lat', + 'Math_Negligible', + 'Math_Trace', + 'Math_Scalar', + 'Math_Outerprod', + 'Math_Smoothing_Interpol', + 'Math_Zbelong', + 'Math_Spher_Harm', + 'Math_Pgcd', + 'Math_Mat_Cross', + 'Math_Poly_Legendre', + 'Math_Upper_Triangular', + 'Math_Points_In_Line2D', + 'Math_RowEchelon', + 'Math_Swap', + 'Math_Rank', + 'Math_Sort', + 'Math_In_Limits' +] + +[[src-cfml-modules]] +main-file = 'CFML_ExtinCorr' +components-dir = 'CFML_ExtinCorr' +components-files = [ + 'Ext_BeckerCoppens', + 'Ext_FlippingRatios', + 'Ext_ShelxCorr' +] + +[[src-cfml-modules]] +main-file = 'CFML_Random' +components-dir = 'CFML_Random' +components-files = [ + 'Random_Beta_Sm', + 'Random_Binomial_Sm', + 'Random_VonMises_Sm', + 'Random_InvGauss_Sm', + 'Random_Poisson_Sm', + 'Random_Gamma_Sm', + 'Random_Normal_Sm', + 'Random_Cauchy_Sm', + 'Random_T_Sm' +] + +[[src-cfml-modules]] +main-file = 'CFML_Messages' +components-dir = 'CFML_Messages' +components-files = [ + 'Con_Print_Message', + 'Con_Info_Message', + 'Con_Err_Message', + 'Con_Write_ScrollMsg', + 'Con_Wait_Message'#, + #'Win_Err_Message', + #'Win_Info_Message', + #'Win_Question_Message', + #'Win_Stop_Message', + #'Win_Warning_Message', + #'Win_Write_ScrollMsg' +] + +[[src-cfml-modules]] +main-file = 'CFML_Strings' +components-dir = 'CFML_Strings' +components-files = [ + 'StringFullp', + 'StringNum', + 'StringReadKey', + 'StringTools' +] + +[[src-cfml-modules]] +main-file = 'CFML_Rational' +components-dir = 'CFML_Rational' +components-files = [ + 'RAT_constructor', + 'RAT_generic', + 'RAT_is_integer', + 'RAT_assignment', + 'RAT_operator_add', + 'RAT_operator_eq', + 'RAT_operator_ge', + 'RAT_Equal_rational', + 'RAT_operator_divisor', + 'RAT_operator_gt', + 'RAT_operator_le', + 'RAT_operator_minus', + 'RAT_rowechelon', + 'RAT_operator_lt', + 'RAT_overloads', + 'RAT_operator_multiply', + 'RAT_operator_neq' +] + +[[src-cfml-modules]] +main-file = 'CFML_SuperSpace_Database' + +[[src-cfml-modules]] +main-file = 'CFML_Magnetic_Database' + +[[src-cfml-modules]] +main-file = 'CFML_BVS_Tables' + +[[src-cfml-modules]] +main-file = 'CFML_Scattering_Tables' + +[[src-cfml-modules]] +main-file = 'CFML_Bonds_Tables' + +[[src-cfml-modules]] +main-file = 'CFML_Symmetry_Tables' + +[[src-cfml-modules]] +components-dir = 'CFML_Tables' +components-files = [ + 'Tab_Del_BVST', + 'Tab_Set_BVST', + 'Tab_Set_ScatterT', + 'Tab_Get_ScatterT', + 'Tab_Del_ScatterT', + 'Tab_Get_SpgT', + 'Tab_Del_SpgT', + 'Tab_Set_SpgT', + 'Tab_Get_SpgSymbols', + 'Tab_Get_BondsT', + 'Tab_Del_BondsT', + 'Tab_Set_BondsT', + 'Tab_Allocating_SuperSpaceDBase', + 'Tab_Read_SSG_DBase', + 'Tab_Allocating_MagneticDBase', + 'Tab_Read_MagneticDBase'#, + #'Tab_Allocating_magSuperSpaceDBase', + #'Tab_Read_magSSG_DBase' +] + +[[src-cfml-modules]] +main-file = 'CFML_Profiles' +components-dir = 'CFML_Profiles' +components-files = [ + 'Profile_BacktoBack', + 'Profile_Exponential', + 'Profile_Finger', + 'Profile_Gaussian', + 'Profile_Init_ProfVal', + 'Profile_IkedaCarpenter', + 'Profile_TCHpVoigt', + 'Profile_Hat', + 'Profile_PseudoVoigt', + 'Profile_Lorentzian', + 'Profile_TOF_Jorgensen', + 'Profile_TOF_Jorg_Vondreele', + 'Profile_TOF_Carpenter' +] + +[[src-cfml-modules]] +main-file = 'CFML_Optimization_LSQ' +components-dir = 'CFML_Optimization_LSQ' +components-files = [ + 'OPT_LSQ_LevebergMarquardt_AnalyDer', + 'OPT_LSQ_Marquardt_Fit', + 'OPT_LSQ_Output', + 'OPT_LSQ_LevebergMarquardt_NumDer' +] + +[[src-cfml-modules]] +main-file = 'CFML_Optimization' +components-dir = 'CFML_Optimization' +components-files = [ + 'OPT_Global_Csendes', + 'OPT_Cg_Quasi_Newton', + 'OPT_Local_Optim', + 'OPT_Simplex' +] + +[[src-cfml-modules]] +main-file = 'CFML_Simulated_Annealing' + +[[src-cfml-modules]] +main-file = 'CFML_Diffpatt' +components-dir = 'CFML_DiffPatt' +components-files = [ + 'DiffP_ReadPatt_ILL', + 'DiffP_ReadPatt_CIF', + 'DiffP_FWHM_Peak', + 'DiffP_BackgPatt', + 'DiffP_ReadPatt_LLB', + 'DiffP_NoisyPoints', + 'DiffP_ReadPatt_GSAS', + 'DiffP_ReadPatt_ISIS', + 'DiffP_ReadPatt_NLS', + 'DiffP_ReadPatt_PAN', + 'DiffP_ReadPatt_FREE', + 'DiffP_ReadPatt_PSI', + 'DiffP_ReadPatt_Socabim', + 'DiffP_ReadPatt_TimeVar', + 'DiffP_ReadPatt_XYSIG', + 'DiffP_WritePatterns', + 'DiffP_ReadPatterns', + 'DiffP_Add_Patterns' +] + +[[src-cfml-modules]] +main-file = 'CFML_Metrics' +components-dir = 'CFML_Metrics' +components-files = [ + 'Metrics_Tensor', + 'Metrics_Gen', + 'Metrics_ThConver', + 'Metrics_IO', + 'Metrics_NiggliCell' +] + +[[src-cfml-modules]] +components-dir = 'CFML_Optimization_SAnn' +components-files = [ + 'SAnn_General', + 'SAnn_LocalOpt', + 'SAnn_MultiConf', + 'SAnn_SetnCheck', + 'SAnn_inout' +] + +[[src-cfml-modules]] +main-file = 'CFML_EoS' +components-dir = 'CFML_EoS' +components-files = [ + 'EoS_Calc', + 'EoS_CopyEDat', + 'EoS_Get_APL', + 'EoS_Get_HeatCap', + 'EoS_CellPar', + 'EoS_PrincipalEoS', + 'Eos_Allocate', + 'EoS_Transform_ESD', + 'EoS_ModDir', + 'Eos_DerivPartial', + 'EoS_Get_Tensor', + 'Eos_Get_Bulk', + 'Eos_Checks', + 'EoS_Get_Angle', + 'Eos_AlphaCalc', + 'Eos_Conlev', + 'Eos_FfCalc', + 'EoS_LinEoS_Allowed', + 'Eos_Get_Pressure', + 'Eos_Get_Temperature', + 'Eos_Get_Tait', + 'Eos_Gruneisen', + 'Eos_NormPressure', + 'Eos_Set', + 'Eos_Get_Properties', + 'Eos_Read', + 'Eos_Get_Volume', + 'Eos_PVT_Table', + 'Eos_Get_Transition', + 'Eos_Init', + 'Eos_K_Cal', + 'Eos_Pthermal', + 'Eos_Strain', + 'Eos_Write', + 'Eos_dKdTCalc' +] + +[[src-cfml-modules]] +main-file = 'CFML_gSpaceGroups' +components-dir = 'CFML_gSpaceGroups' +components-files = [ + 'gS_Allocate_Opers', + 'gS_Allocate_SpaceG', + 'gS_ApplySO', + 'gS_Get_Cosets', + 'gS_CheckGener', + 'gS_Get_CrystalSys', + 'gS_Get_GenerStr', + 'gS_Get_Dimension', + 'gS_Get_Generators', + 'gS_Get_Hall_Gener', + 'gS_Get_HM_Standard', + 'gS_Get_LattType', + 'gS_Get_OriginShift', + 'gS_Is_LattCentring', + 'gS_Get_X_Matrix', + 'gS_Is_InversionCentre', + 'gS_Get_Oper_Symb', + 'gS_Reorder_Oper', + 'gS_Smallest_IntegralVec', + 'gS_Identify_Groups', + 'gS_Get_Mult_OPTable', + 'gS_Get_Orb_Stabilizer_Constr', + 'gS_Get_PseudoStdBase', + 'gS_Match_Spg3D', + 'gS_Get_Mat_Symb', + 'gS_Get_Symb_Mat', + 'gS_Set_SpaceG', + 'gS_Inverse_OP', + 'gS_Get_LauePG', + 'gS_Get_SubGrp', + 'gS_Init_Procedures', + 'gS_Match_Shubnikov_Grp', + 'gS_Get_Rotations', + 'gS_Get_Ops_Gener', + 'gS_Spg_Const_VGen', + 'gS_Rational_RedTraslation', + 'gS_Get_Symb_Oper', + 'gS_operator_equal', + 'gS_Sort_Operator', + 'gS_operator_mult', + 'gS_Write_SpaceG', + 'gS_Is_Antilattice', + 'gS_Spg_Const_Str', + 'gS_Symm_Symbols', + 'gS_OnePrimeOp' +] + +[[src-cfml-modules]] +main-file = 'CFML_BckPeaks' + +[[src-cfml-modules]] +main-file = 'CFML_ILL_Instrm_Data' + +[[src-cfml-modules]] +main-file = 'CFML_Atoms' +components-dir = 'CFML_Atoms' +components-files = [ + 'Atm_ExtendList', + 'Atm_ChangeList', + 'Atm_Allocating_Atoms', + 'Atm_PointList', + 'Atm_RW_Bin_AtmList', + 'Atm_Write_AtmList', + 'Atm_SymmetryConstraints' +] + +[[src-cfml-modules]] +main-file = 'CFML_Propagation_Vectors' + +[[src-cfml-modules]] +main-file = 'CFML_Reflections' +components-dir = 'CFML_Reflections' +components-files = [ + 'Refl_H_Convent', + 'Refl_AsymUnit', + 'Refl_Generate', + 'Refl_H_EquivList', + 'Refl_H_Equal', + 'Refl_Conditions', + 'Refl_H_Equiv', + 'Refl_H_S', + 'Refl_H_Absent', + 'Refl_MaxNum', + 'Refl_Write_List', + 'Refl_UnitaryVec', + 'Refl_Init_RefList', + 'Refl_H_Mult' +] + +[[src-cfml-modules]] +main-file = 'CFML_Structure_Factors' +components-dir = 'CFML_Structure_Factors' +components-files = [ + 'SF_AtomicFactors', + 'SF_Calculations', + 'SF_Scattering_Species', + 'SF_Initialize', + 'SF_Write_SF', + 'SF_Create_Tables', +] + +[[src-cfml-modules]] +main-file = 'CFML_Geom' +components-dir = 'CFML_Geom' +components-files = [ + 'Geom_Angles', + 'Geom_Allocations', + 'Geom_Matrices', + 'Geom_Coordination', + 'Geom_Orbits', + 'Geom_Distances' +] + +[[src-cfml-modules]] +main-file = 'CFML_kvec_Symmetry' +components-dir = 'CFML_kvec_Symmetry' +components-files = [ + 'ksym_auxsub', + 'ksym_init', + 'ksym_functions', + 'ksym_suscept', + 'ksym_read', + 'ksym_write' +] + +[[src-cfml-modules]] +main-file = 'CFML_kvec_Structure_Factors' +components-dir = 'CFML_kvec_Structure_Factors' +components-files = [ + 'kStrf_Init_FxTables', + 'kStrf_MiV', + 'kStrf_MStrT', + 'kStrf_satellites', + 'kStrf_write' +] + +[[src-cfml-modules]] +main-file = 'CFML_Maps' +components-dir = 'CFML_Maps' +components-files = [ + 'Maps_Mapping', + 'Maps_MarchingCubes', + 'Maps_Percolation' +] + +[[src-cfml-modules]] +main-file = 'CFML_Molecules' +components-dir = 'CFML_Molecules' +components-files = [ + 'Mol_Formula', + 'Mol_Cartesian_to', + 'Mol_Fractional_to', + 'Mol_IndexList', + 'Mol_Orientation', + 'Mol_Initialize', + 'Mol_WriteInfo', + 'Mol_Spherical_to', + 'Mol_ReadInfo', + 'Mol_ZMatrix_to', + 'Mol_to_AtList' +] + +[[src-cfml-modules]] +main-file = 'CFML_Keywords_Code_Parser' +components-dir = 'CFML_Keywords_Code_Parser' +components-files = [ + 'KWC_FillCodes_Gen', + 'KWC_Allocation', + 'KWC_Deletion', + 'KWC_WriteRefCodes', + 'KWC_FillCodes_MolX', + 'KWC_FillCodes_FAtm', + 'KWC_SplitOperations', + 'KWC_GetConCodes', + 'KWC_VStateToAtomPar', + 'KWC_ReadCodes', + 'KWC_GetRestrCodes', + 'KWC_RefCodes' +] + +[[src-cfml-modules]] +main-file = 'CFML_IOForm' +components-dir = 'CFML_IOForm' +components-files = [ + 'Format_GEN', + 'Format_MCIF', + 'Format_Blocks', + 'Format_CIF', + 'Format_CFL', + 'Format_FST', + 'Format_SHX' +] + +[[src-cfml-modules]] +main-file = 'CFML_KeyCodes' +components-dir = 'CFML_KeyCodes' +components-files = [ + 'KeyCod_VecRef', + 'KeyCod_RGB', + 'KeyCod_Atm', + 'KeyCod_Patt', + 'KeyCod_GenPar', + 'keyCod_Phas', + 'KeyCod_WriteInfo', + 'KeyCod_Restraints', + 'KeyCod_Molec' +] + +[[src-cfml-modules]] +main-file = 'CFML_Python' +components-dir = 'CFML_Python' +components-files = [ + 'Python_Common', + 'Python_Atoms', + 'Python_DiffPatt', + 'Python_Metrics', + 'Python_Reflections', + 'Python_gSpaceGroups', + 'Python_Ndarray' +] + +[[src-cfml-modules]] +main-file = 'CFML_VTK' +components-dir = 'CFML_VTK' +components-files = [ + 'VTK_Scan_Utils' +] + +[[src-cfml-modules]] +main-file = 'CFML_SXTAL_Geom' +components-dir = 'CFML_SXTAL_Geom' +components-files = [ + 'SXTAL_Angles', + 'SXTAL_IO', + 'SXTAL_Matx_Zvect', + 'SXTAL_PSD', + 'SXTAL_FlatCone', + 'SXTAL_UB' +] + +[[src-cfml-modules]] +main-file = 'CFML_Export_VTK' + +[[src-cfml-modules]] +main-file = 'CFML_EnBVS' +components-dir = 'CFML_EnBVS' +components-files = [ + 'EnBVS_CostF', + 'EnBVS_Energy', + 'EnBVS_Maps', + 'EnBVS_SetTab' +] + +[[src-cfml-modules]] +main-file = 'CFML_Wraps_Utils' +components-dir = 'CFML_Wraps_Utils' +components-files = [ + 'Wraps_Utils' +] + +[[src-cfml-modules]] +main-file = 'CFML_Utilities' +components-dir = 'CFML_Utilities' +components-files = [ + 'Utilities_Patterns' +] + +[[src-cfml-modules]] +main-file = 'CFML_kvec_Polarimetry' +components-dir = 'CFML_kvec_Polarimetry' +components-files = [ + 'Polar_Calculations_Dom', + 'Polar_Calculations', + 'Polar_Functions', + 'Polar_Init', + 'Polar_Write' +] + +#################################### +# CrysFML test programs source files +#################################### + +[[src-cfml-tests]] +main-dir = 'Bond_Str' +main-file = 'Bond_StrN' + +[[src-cfml-tests]] +main-dir = 'CIFs' +main-file = 'io_files' + +[[src-cfml-tests]] +main-dir = 'Grp_230' +main-file = 'groups_230' + +[[src-cfml-tests]] +main-dir = 'hkl_gen' +main-file = 'hkl_gen' + +[[src-cfml-tests]] +main-dir = 'hkl_gen' +main-file = 'simple_hkl_gen' + +[[src-cfml-tests]] +main-dir = 'Molecules' +main-file = 'mol_tpcr' + +[[src-cfml-tests]] +main-dir = 'PowderPattern' +main-file = 'Simple_calc_powder' + +[[src-cfml-tests]] +main-dir = 'PowderPattern' +main-file = 'Simple_calc_Mag_powder' + +[[src-cfml-tests]] +main-dir = 'StructureFactors' +main-file = 'Calc_Sfac' + +################################ +# Python API modules for CrysFML +################################ + +[[src-cfml-wraps]] +main-file = 'CFML_Wraps' +components-dir = 'CFML_Wraps' +components-files = [ + 'Wraps_Atoms', + 'Wraps_Bonds_Tables', + 'Wraps_Strings', + 'Wraps_BckPeaks', + 'Wraps_Scattering_Tables', + 'Wraps_Structure_Factors', + 'Wraps_Geom', + 'Wraps_Metrics', + 'Wraps_ExtinCorr', + 'Wraps_Symmetry_Tables', + 'Wraps_DiffPatt', + 'Wraps_EoS', + 'Wraps_IOForm', + 'Wraps_Molecules', + 'Wraps_Propagation_Vectors', + 'Wraps_ILL_Instrm_Data', + 'Wraps_Reflections', + 'Wraps_BVS_Tables', + 'Wraps_EnBVS', + 'Wraps_SXTAL_Geom', + 'Wraps_Simulated_Annealing', + 'Wraps_Profiles', + 'Wraps_Rational', + 'Wraps_gSpaceGroups', + 'Wraps_kvec_Symmetry', + 'Wraps_Utilities' +] + +################## +################## +# Compiler options +################## +################## + +########## +# gfortran +########## + +#'-cpp', # Enable preprocessing. The preprocessor is automatically invoked if the file extension is .fpp, .FPP, .F, .FOR, .FTN, .F90, .F95, .F03 or .F08. + # Use this option to manually enable preprocessing of any kind of Fortran file. + # To disable preprocessing of files with any of the above listed extensions, use the negative form: -nocpp. + # The preprocessor is run in traditional mode. Any restrictions of the file-format, especially the limits on line length, apply for preprocessed output + # as well, so it might be advisable to use the -ffree-line-length-none or -ffixed-line-length-none options. +#'-fall-intrinsics', # This option causes all intrinsic procedures (including the GNU-specific extensions) to be accepted. This can be useful with -std=f95 to force + # standard-compliance but get access to the full range of intrinsics available with gfortran. As a consequence, -Wintrinsics-std will be ignored + # and no user-defined procedure with the same name as any intrinsic will be called except when it is explicitly declared EXTERNAL +#'-fdec-math', # Enable legacy math intrinsics such as COTAN and degree-valued trigonometric functions (e.g. TAND, ATAND, etc...) for compatability with older code. +#'-ffree-line-length-none', # Set column after which characters are ignored in typical free-form lines in the source file. The default value is 132. n may be ‘none’, meaning + # that the entire line is meaningful. -ffree-line-length-0 means the same thing as -ffree-line-length-none. +#'-fno-stack-arrays', # Enabled: Put all local arrays, even those of unknown size onto stack memory. + # The -fno- form disables the behavior. +#'-fpic', # Generate position-independent code (PIC) suitable for use in a shared library, if supported for the target machine. Such code accesses all constant + # addresses through a global offset table (GOT). The dynamic loader resolves the GOT entries when the program starts (the dynamic loader is not part + # of GCC; it is part of the operating system). If the GOT size for the linked executable exceeds a machine-specific maximum size, you get an error + # message from the linker indicating that -fpic does not work; in that case, recompile with -fPIC instead. (These maximums are 8k on the SPARC, 28k on + # AArch64 and 32k on the m68k and RS/6000. The x86 has no such limit.) + # Position-independent code requires special support, and therefore works only on certain machines. For the x86, GCC supports PIC for System V but not + # for the Sun 386i. Code generated for the IBM RS/6000 is always position-independent. +#'-fPIC', # If supported for the target machine, emit position-independent code, suitable for dynamic linking and avoiding any limit on the size of the global + # offset table. This option makes a difference on AArch64, m68k, PowerPC and SPARC. + # Position-independent code requires special support, and therefore works only on certain machines. +#'-std=f2008' # Specify the standard to which the program is expected to conform, which may be one of ‘f95’, ‘f2003’, ‘f2008’, ‘gnu’, or ‘legacy’. The default + # value for std is ‘gnu’, which specifies a superset of the Fortran 95 standard that includes all of the extensions supported by GNU Fortran, although + # warnings will be given for obsolete extensions not recommended for use in new code. The ‘legacy’ value is equivalent but without the warnings for + # obsolete extensions, and may be useful for old non-standard programs. The ‘f95’, ‘f2003’ and ‘f2008’ values specify strict conformance to the + # Fortran 95, Fortran 2003 and Fortran 2008 standards, respectively; errors are given for all extensions beyond the relevant language standard, and + # warnings are given for the Fortran 77 features that are permitted but obsolescent in later standards. ‘-std=f2008ts’ allows the Fortran 2008 standard + # including the additions of the Technical Specification (TS) 29113 on Further Interoperability of Fortran with C and TS 18508 on Additional Parallel + # Features in Fortran. + +######## +# nagfor +######## + +#'-colour', # Colour the message output from the compiler using ANSI escape sequences and the default foreground colouring scheme which is: red for error messages (including + # fatal errors), blue for warning messages and green for information messages. +#'-compatible', # Make external linkages compatible with other compilers where possible; on Windows this is Microsoft Fortran (32-bit mode) or Intel Fortran (64-bit mode), on MacOS + # and Linux this is g77, g95 and gfortran, and on other systems this is the operating system vendor's compiler. This affects the naming convention and procedure + # calling convention (for example, on Windows it causes use of the "STDCALL" calling convention that is commonly used for most DLLs, and the names are in upper case + # with no added trailing underscore). On Windows in 64-bit mode, -compatible is always in effect. +#'-dusty', # Allows the compilation and execution of "legacy" software by downgrading the category of common errors found in such software from "Error" to "Warning" (which may + # then be suppressed entirely with the -w option). This option disables -C=calls, and also enables Hollerith i/o (see the -hollerith_io option). +#'-f2008', # Specify that the base language is Fortran 2008. This is the default. +#'-fpp', # Preprocess the source files using fpp even if the suffix would normally indicate an ordinary Fortran file. +#'-gline', # Compile code to produce a traceback when a runtime error message is generated. Only routines compiled with this option will appear in such a traceback. This + # option increases both executable file size and execution time. +#'-mismatch_all', # Further downgrade consistency checking of procedure argument lists so that calls to routines in the same file which are incorrect will produce warnings instead of + # error messages. This option disables -C=calls. +#'-mtrace=on', # Trace memory allocation and deallocation. This option is a synonym for -mtrace=on. +#'-no_underflow_warning', # Suppress the warning message that normally appears if a floating-point underflow occurred during execution. This option is only effective if specified when + # compiling the main program. +#'-nonstrict', # Do not check for strict conformance to the Fortran standard +#'-pic', # Produce position-independent code (small model), for use in a shared library. If the shared library is too big for the small model, use -PIC. +#'-PIC', # Produce position-independent code (large model), for use in a shared library. +#'-quiet', # Suppress the compiler banner and the summary line, so that only diagnostic messages will appear, +#'-w=all', # suppresses all warning messages; +#'-Wl,option' # Pass option directly to the host C compiler when linking (producing the executable). Multiple options may be specified in a single -Wl, option by + # separating them with commas. A comma may be included in an option by repeating it, e.g. -Wl,-filelist=file1,,file2,,file3 becomes the linker option + # -filelist=file1,file2,file3. Note that options specified with -Wl, are appended to the linking command; for options that need to be in a specific + # place, the -xldarg option can be used. + +#################### +# ifort / ifx (unix) +#################### + +# -fpic, -fPIC # generate position independent code (-fno-pic/-fno-PIC is DEFAULT) +# -[no]fpp # run Fortran preprocessor on source files prior to compilation +# -g[level] # Produce symbolic debug information. + # Valid [level] values: + # 0 - Disable generation of symbolic debug information. + # 1 - Emit minimal debug information for performing stack traces. + # 2 - Emit complete debug information. (default for -g) + # 3 - Emit extra information which may be useful for some tools. +# -heap-arrays [n] # temporary arrays of minimum size n (in kilobytes) are allocated in + # heap memory rather than on the stack. If n is not specified, + # all temporary arrays are allocated in heap memory. +# -[no]logo # display compiler version information. -nologo disables the output +# -stand [] # specifies level of conformance with ANSI standard to check + # for. If keyword is not specified, level of conformance is f18 + # keywords: f90 (same as -std90), f95 (same as -std95), + # f03 (same as -std03), f08 (same as -std08), + # f18 (same as -std18),none (same as -nostand) +# -w # disable all warnings + +####################### +# ifort / ifx (windows) +####################### + +# -DWIN32=ON + +# /[no]fpp # run Fortran preprocessor on source files prior to compilation +# /heap-arrays # /heap-arrays[:n] + # temporary arrays of minimum size n (in kilobytes) are allocated in + # heap memory rather than on the stack. If n is not specified, + # all temporary arrays are allocated in heap memory. +# /[no]logo # display compiler version information. /nologo disables the output +# /stand[:] # specifies level of conformance with ANSI standard to check + # for. If keyword is not specified, level of conformance is f18 + # keywords: f90 (same as /4Ys), f95, + # f03, f08, f18, + # none (same as /nostand) +# /w # disable all warnings diff --git a/pyproject.toml b/pyproject.toml index 96eb1ec..182b7a2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,36 +1,41 @@ [build-system] -requires = ["hatchling"] -build-backend = "hatchling.build" +requires = ['hatchling'] +build-backend = 'hatchling.build' [project] -name = 'pycrysfml08' -version = '0.0.1-alpha0' -description = "Testing packaging PyCrysFML08 from https://code.ill.fr/scientific-software/PyCrysFML08" +name = 'pycrysfml' +version = '0.1.1' +description = 'Python API to CrysFML2008 from https://code.ill.fr/scientific-software/CrysFML2008' authors = [ - {name = "Juan Rodríguez-Carvajal", email = "jrc@ill.fr"}, - {name = "Nebil Ayape Katcho", email = "katcho@ill.fr"} + {name = 'Juan Rodríguez-Carvajal', email = 'jrc@ill.fr'}, + {name = 'Nebil Ayape Katcho', email = 'katcho@ill.fr'}, + {name = 'Javier Gonzalez-Platas', email = 'jplatas@ull.edu.es' } ] maintainers = [ - {name = "Elisa Rebolini", email = "rebolini@ill.fr"}, - {name = "Andrew Sazonov", email = "andrew.sazonov@ess.eu"} + {name = 'Elisa Rebolini', email = 'rebolini@ill.fr'}, + {name = 'Andrew Sazonov', email = 'andrew.sazonov@ess.eu'} ] -readme = "README.md" -license = {file = "LICENSE"} +readme = 'README.md' +license = {file = 'LICENSE'} classifiers = [ - "Programming Language :: Python :: 3", - "License :: OSI Approved :: MIT License", - "Operating System :: OS Independent" + 'Programming Language :: Python :: 3', + 'License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)', + 'Operating System :: OS Independent' ] -requires-python = ">=3.11" +requires-python = '>=3.9' dependencies = [ - "numpy" + 'numpy<2' ] [project.optional-dependencies] ci = [ + 'toml', # need this, as tomllib is only available for python >=3.11 'validate-pyproject[all]', 'build', - 'wheel' + 'wheel', + 'check-wheel-contents', + 'abi3audit', + 'colorama' ] test = [ 'deepdiff', @@ -40,8 +45,8 @@ test = [ ] [project.urls] -Homepage = "https://github.com/AndrewSazonov/test_pycrysfml08_build" +Homepage = 'https://github.com/easyscience/TEST_PyCrysFML' [tool.hatch.build.targets.wheel] -packages = ["pycrysfml08_dist/pycrysfml08"] -artifacts = ["*.py", "*.so", "*.so.*", "*.dylib", "*.pyd", "*.dll", "*.txt"] +packages = ['dist/pyCFML/pycrysfml'] # NEED FIX: Replace based on scripts.toml - pycfml.dir.dist-package +artifacts = ['*.py', '*.so', '*.so.*', '*.dylib', '*.pyd', '*.dll', '*.txt'] diff --git a/scripts.py b/scripts.py deleted file mode 100644 index 616e59f..0000000 --- a/scripts.py +++ /dev/null @@ -1,1127 +0,0 @@ -import os -import sys -import tomllib -import argparse -import sysconfig -import platform -from pygit2 import Repository - -global ARGS -global CONFIG - -def _github_actions(): - if 'GITHUB_ACTIONS' in os.environ: - return True - return False - -def _github_branch(): - return Repository('.').head.shorthand - -def _project_dir(): - return os.path.dirname(__file__) - -def _project_path(): - return os.path.abspath(_project_dir()) - -def _config_path(name: str): - path = os.path.join(_project_dir(), name) - path = os.path.abspath(path) - return path - -def _scripts_path(): - dir = CONFIG['project']['dir']['scripts'] - path = os.path.abspath(dir) - return path - -def _main_script_path(): - name = 'main_script.sh' - path = os.path.join(_scripts_path(), name) - return path - -def _echo_msg(msg: str): - return f'echo ":::::: {msg}"' - -def _echo_progress_msg(current: int, total: int, msg: str): - progress = _compiling_progress(current, total) - msg = f"[{progress:>3}%] {msg}" - return f'echo "{msg}"' - -def _echo_header(msg: str): - msg = f':::::: {msg} ::::::' - sep = ':' * len(msg) - lines = [] - lines.append(f'echo ""') - lines.append(f'echo "{sep}"') - lines.append(f'echo "{msg}"') - lines.append(f'echo "{sep}"') - return lines - -def _platform(): - platform = 'macos' # default - if ARGS.platform: - platform = ARGS.platform.lower() - return platform - -def _platform_tag(): - tag = sysconfig.get_platform() - tag = tag.replace('-', '_') - tag = tag.replace('.', '_') - return tag - -def _python_tag(): - version = sysconfig.get_config_var('py_version_nodot') - tag = f'py{version}' - return tag - -def _processor(): - processor = platform.processor() - processor = processor.split()[0] # get the 1st word from string, such as 'Intel64 Family 6 Model 154 Stepping 3, GenuineIntel' - return processor - -def _fix_file_permissions(path: str): - os.chmod(path, 0o777) - -def _write_lines_to_file(lines: list, name: str): - path = os.path.join(_scripts_path(), name) - with open(path, 'w') as file: - for line in lines: - if _bash_syntax(): - line = line.replace('\\', '/') - file.write(line + '\n') - _fix_file_permissions(path) - -def _total_src_file_count(modules: str): - count = 0 - for module in CONFIG[modules]: - if 'main-file' in module: - count += 1 - if 'components-dir' in module and 'components-files' in module: - for component_file in module['components-files']: - count += 1 - return count - -def _bash_syntax(): - bash_syntax = False # default - if ARGS.bash_syntax: - bash_syntax = ARGS.bash_syntax - return bash_syntax - -def _print_pcfml_wheel_dir(): - wheel_dir = CONFIG['pycfml']['dir']['wheel'] - print(wheel_dir) - -def _compiler_name(): - compiler = 'gfortran' # default - if ARGS.compiler: - compiler = ARGS.compiler.lower() - return compiler - -def _compiler_options(): - compiler = _compiler_name() - mode = _compiling_mode() - options = '' - for build in CONFIG['build-objs']: - if _platform() in build['platforms'] and compiler in build['compilers']: - options = f"{build['modes']['base']}" - if build['modes'][mode]: - options += f" {build['modes'][mode]}" - break - return options - -def _obj_ext(): - compiler = _compiler_name() - ext = '' - for build in CONFIG['build-objs']: - if _platform() in build['platforms'] and compiler in build['compilers']: - ext = build['obj-ext'] - break - return ext - -def _compiler_build_shared_template(): - compiler = _compiler_name() - template = '' - for build in CONFIG['build-objs']: - if _platform() in build['platforms'] and compiler in build['compilers']: - template = build['build-shared'] - break - return template - -def _compiler_build_exe_template(): - compiler = _compiler_name() - template = '' - for build in CONFIG['build-objs']: - if _platform() in build['platforms'] and compiler in build['compilers']: - template = build['build-exe'] - break - return template - -def _compiling_mode(): - mode = 'debug' # default - if ARGS.mode: - mode = ARGS.mode.lower() - return mode - -def _compiling_progress(current: int, total: int): - progress = round(current / total * 100) - return progress - -def _compile_objs_script_lines(modules: str, - src_path: str, - include_path: str=''): - src_ext = CONFIG['build']['src-ext'][modules] - modules = f'{modules}-modules' - template_cmd = CONFIG['template']['build-obj'] - if not include_path: - template_cmd = template_cmd.replace(' -I {INCLUDE}', '') - else: - template_cmd = template_cmd.replace('{INCLUDE}', include_path) - compiler = _compiler_name() - options = _compiler_options() - total = _total_src_file_count(modules) - current = 0 - lines = [] - for module in CONFIG[modules]: - if 'main-file' in module: - current += 1 - name = f'{module["main-file"]}.{src_ext}' - msg = _echo_progress_msg(current, total, f"{name}") - lines.append(msg) - path = os.path.join(src_path, name) - cmd = template_cmd - cmd = cmd.replace('{COMPILER}', compiler) - cmd = cmd.replace('{OPTIONS}', options) - cmd = cmd.replace('{PATH}', path) - lines.append(cmd) - if 'components-dir' in module and 'components-files' in module: - components_dir = module['components-dir'] - for component_file in module['components-files']: - current += 1 - name = f'{component_file}.{src_ext}' - path = os.path.join(components_dir, name) - msg = _echo_progress_msg(current, total, f"{name}") - lines.append(msg) - path = os.path.join(src_path, path) - cmd = template_cmd - cmd = cmd.replace('{COMPILER}', compiler) - cmd = cmd.replace('{OPTIONS}', options) - cmd = cmd.replace('{PATH}', path) - cmd = f'{cmd}&' # start this bash command in background for parallel compilation - lines.append(cmd) - if current % 11 == 0: # do not parallelise for more than 10 compilations - lines.append('wait') # wait for all parallel bash commands to finish - lines.append('wait') # wait for all parallel bash commands to finish - return lines - -def _compile_shared_objs_or_dynamic_libs_script_lines(modules: str): - obj_ext = _obj_ext() - cfml_lib_name = CONFIG['cfml']['static-lib-name'] - cfml_dist_dir = CONFIG['cfml']['dir']['dist'] - cfml_dist_path = os.path.join(_project_path(), cfml_dist_dir) - cfml_lib_dist_dir = CONFIG['cfml']['dir']['dist-lib'] - cfml_lib_dist_path = os.path.join(cfml_dist_path, cfml_lib_dist_dir) - python_lib = CONFIG['build']['python-lib'][_platform()] - python_lib = python_lib.replace('{PYTHON311_VERSION}', platform.python_version()) - compiler = _compiler_name() - if _platform() == 'linux' and (compiler == 'ifort' or compiler == 'ifx'): - ifc_lib = '-L/opt/intel/oneapi/compiler/2023.2.0/linux/compiler/lib/intel64_lin -lifport' - else: - ifc_lib = '' - template_cmd = _compiler_build_shared_template() - shared_lib_ext = CONFIG['build']['shared-lib-ext'][_platform()] - total = _total_src_file_count(modules) - current = 0 - lines = [] - for module in CONFIG[modules]: - if 'main-file' in module: - current += 1 - name = f'{module["main-file"]}' - msg = _echo_progress_msg(current, total, f'{name}.{obj_ext}') - lines.append(msg) - cmd = template_cmd - cmd = cmd.replace('{COMPILER}', compiler) - cmd = cmd.replace('{PATH}', name) - cmd = cmd.replace('{EXT}', shared_lib_ext) - cmd = cmd.replace('{CFML_LIB_PATH}', cfml_lib_dist_path) - cmd = cmd.replace('{CFML_LIB_NAME}', cfml_lib_name) - cmd = cmd.replace('{IFC_LIB}', ifc_lib) - cmd = cmd.replace('{PYTHON_LIB}', python_lib) - #lines.append(f"echo '>>>>> {cmd}'") - lines.append(cmd) - return lines - -def _compile_executables_script_lines(section_prefix: str, - src_path: str, - include_path: str, - lib_dir: str, - lib_name: str): - src_ext = CONFIG['build']['src-ext'][section_prefix] - lib_ext = CONFIG['build']['static-lib-ext'][_platform()] - tests = f'{section_prefix}-tests' - template_cmd = _compiler_build_exe_template() - compiler = _compiler_name() - options = _compiler_options() - total = _total_src_file_count(tests) - current = 0 - lines = [] - for test in CONFIG[tests]: - current += 1 - dir = test["main-dir"] - main_name = test["main-file"] - source_name = f'{main_name}.{src_ext}' - msg = _echo_progress_msg(current, total, f"{source_name}") - lines.append(msg) - source_path = os.path.join(src_path, dir, source_name) - cmd = template_cmd - cmd = cmd.replace('{COMPILER}', compiler) - cmd = cmd.replace('{OPTIONS}', options) - cmd = cmd.replace('{EXE_NAME}', main_name) - cmd = cmd.replace('{SOURCE_PATH}', source_path) - cmd = cmd.replace('{CFML_INCLUDE_PATH}', include_path) - cmd = cmd.replace('{CFML_LIB_DIR}', lib_dir) - cmd = cmd.replace('{CFML_LIB_NAME}', lib_name) - cmd = cmd.replace('{LIB_EXT}', lib_ext) - #lines.append(f"echo '>>>>> {cmd}'") - lines.append(cmd) - return lines - -def parsed_args(): - parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter) - parser.add_argument("--platform", - default="macos", - choices=['macos', 'linux', 'windows'], - type=str.lower, - help="platform identifier") - parser.add_argument("--compiler", - default="gfortran", - choices=['gfortran', 'nagfor', 'ifx', 'ifort'], - type=str.lower, - help="fortran compiler") - parser.add_argument("--mode", - default="debug", - choices=['debug', 'release'], - type=str.lower, - help="compiling mode") - parser.add_argument("--bash-syntax", - action='store_true', - help="force bash shell syntax") - parser.add_argument("--print-wheel-dir", - action='store_true', - help="print pycfml wheel directory name") - return parser.parse_args() - -def loaded_config(name: str): - path = _config_path(name) - with open(path, 'rb') as f: - config = tomllib.load(f) - if _bash_syntax(): - for idx, build in enumerate(config['build-objs']): - config['build-objs'][idx]['build-shared'] = build['build-shared'].replace('/', '-') - config['build-objs'][idx]['build-exe'] = build['build-exe'].replace('/', '-') - config['build-objs'][idx]['modes']['base'] = build['modes']['base'].replace('/', '-') - config['build-objs'][idx]['modes']['debug'] = build['modes']['debug'].replace('/', '-') - config['build-objs'][idx]['modes']['release'] = build['modes']['release'].replace('/', '-') - return config - -def clear_main_script(): - path = _main_script_path() - with open(path, 'w') as file: - pass - -def append_to_main_script(obj: str | list): - path = _main_script_path() - if isinstance(obj, str): - lines = [obj] - elif isinstance(obj, list): - lines = obj - with open(path, 'a') as file: - for line in lines: - if _bash_syntax(): - line = line.replace('\\', '/') - file.write(line + '\n') - _fix_file_permissions(path) - -def print_debug_info(): - lines = [] - msg = _echo_msg(f"Platform '{_platform()}'") - lines.append(msg) - msg = _echo_msg(f"Processor '{_processor()}'") - lines.append(msg) - msg = _echo_msg(f"Compiling mode '{_compiling_mode()}'") - lines.append(msg) - msg = _echo_msg(f"Fortran compiler '{_compiler_name()}'") - lines.append(msg) - #msg = _echo_msg(f"Compiler options '{_compiler_options()}'") - #lines.append(msg) - script_name = f'{sys._getframe().f_code.co_name}.sh' - _write_lines_to_file(lines, script_name) - append_to_main_script(lines) - -def create_cfml_repo_dir(): - repo_dir = CONFIG['cfml']['dir']['repo'] - repo_path = os.path.join(_project_path(), repo_dir) - lines = [] - msg = _echo_msg(f"Deleting build dir '{repo_dir}'") - lines.append(msg) - cmd = f'rm -rf {repo_path}' - lines.append(cmd) - msg = _echo_msg(f"Creating build dir '{repo_dir}'") - lines.append(msg) - cmd = f'mkdir -p {repo_path}' - lines.append(cmd) - script_name = f'{sys._getframe().f_code.co_name}.sh' - _write_lines_to_file(lines, script_name) - append_to_main_script(lines) - -def download_cfml_repo(): - project_name = CONFIG['cfml']['log-name'] - url = CONFIG['cfml']['git']['url'] - branch = CONFIG['cfml']['git']['branch'] - out_dir = CONFIG['cfml']['dir']['repo'] - out_path = os.path.abspath(out_dir) - lines = [] - msg = _echo_msg(f"Downloading {project_name} branch '{branch}' to '{out_dir}' from '{url}'") - lines.append(msg) - cmd = CONFIG['template']['clone-repo'] - cmd = cmd.replace('{BRANCH}', branch) - cmd = cmd.replace('{URL}', url) - cmd = cmd.replace('{OUT_PATH}', out_path) - lines.append(cmd) - script_name = f'{sys._getframe().f_code.co_name}.sh' - _write_lines_to_file(lines, script_name) - append_to_main_script(lines) - -def create_cfml_build_dir(): - build_dir = CONFIG['cfml']['dir']['build'] - build_path = os.path.join(_project_path(), build_dir) - lines = [] - msg = _echo_msg(f"Deleting build dir '{build_dir}'") - lines.append(msg) - cmd = f'rm -rf {build_path}' - lines.append(cmd) - msg = _echo_msg(f"Creating build dir '{build_dir}'") - lines.append(msg) - cmd = f'mkdir -p {build_path}' - lines.append(cmd) - script_name = f'{sys._getframe().f_code.co_name}.sh' - _write_lines_to_file(lines, script_name) - append_to_main_script(lines) - -def rename_global_deps_file(): - repo_dir = CONFIG['cfml']['dir']['repo'] - src_ext = CONFIG['build']['src-ext']['cfml'] - src_dir = CONFIG['cfml']['dir']['repo-src'] - platform = _platform() - if platform == 'macos': - platform_suffix = 'MacOS' - elif platform == 'linux': - platform_suffix = 'Linux' - elif platform == 'windows': - platform_suffix = 'Windows' - compiler = _compiler_name() - if compiler in ['gfortran', 'nagfor']: - compiler_suffix = 'GFOR' - elif compiler in ['ifort', 'ifx']: - compiler_suffix = 'IFOR' - from_name = f'CFML_GlobalDeps_{platform_suffix}_{compiler_suffix}.{src_ext}' - from_relpath = os.path.join(repo_dir, src_dir, from_name) - from_abspath = os.path.join(_project_path(), from_relpath) - to_name = f'CFML_GlobalDeps.{src_ext}' - to_relpath = os.path.join(repo_dir, src_dir, to_name) - to_abspath = os.path.join(_project_path(), to_relpath) - lines = [] - msg = _echo_msg(f"Copying '{from_relpath}' to '{to_relpath}'") - lines.append(msg) - cmd = f'cp {from_abspath} {to_abspath}' - lines.append(cmd) - script_name = f'{sys._getframe().f_code.co_name}.sh' - _write_lines_to_file(lines, script_name) - append_to_main_script(lines) - -def build_cfml_objs(): - project_name = CONFIG['cfml']['log-name'] - repo_dir = CONFIG['cfml']['dir']['repo'] - src_dir = CONFIG['cfml']['dir']['repo-src'] - src_path = os.path.join(_project_path(), repo_dir, src_dir) - build_dir = CONFIG['cfml']['dir']['build'] - build_path = os.path.join(_project_path(), build_dir) - lines = [] - msg = _echo_msg(f"Entering build dir '{build_dir}'") - lines.append(msg) - cmd = f'cd {build_path}' - lines.append(cmd) - msg = _echo_msg(f"Building fortran objects for {project_name}:") - lines.append(msg) - compile_lines = _compile_objs_script_lines('cfml', src_path) - lines.extend(compile_lines) - msg = _echo_msg(f"Exiting build dir '{build_dir}'") - lines.append(msg) - cmd = f'cd {_project_path()}' - lines.append(cmd) - script_name = f'{sys._getframe().f_code.co_name}.sh' - _write_lines_to_file(lines, script_name) - append_to_main_script(lines) - -def delete_renamed_global_deps_file(): - repo_dir = CONFIG['cfml']['dir']['repo'] - src_ext = CONFIG['build']['src-ext']['cfml'] - src_dir = CONFIG['cfml']['dir']['repo-src'] - name = f'CFML_GlobalDeps.{src_ext}' - relpath = os.path.join(repo_dir, src_dir, name) - abspath = os.path.join(_project_path(), relpath) - lines = [] - msg = _echo_msg(f"Deleting previously created '{relpath}'") - lines.append(msg) - cmd = f'rm {abspath}' - lines.append(cmd) - script_name = f'{sys._getframe().f_code.co_name}.sh' - _write_lines_to_file(lines, script_name) - append_to_main_script(lines) - -def build_cfml_static_lib(): - lib_ext = CONFIG['build']['static-lib-ext'][_platform()] - static_lib_prefix = CONFIG['build']['static-lib-prefix'][_platform()] - lib_name = CONFIG['cfml']['static-lib-name'] - lib_name = f'{static_lib_prefix}{lib_name}' - build_dir = CONFIG['cfml']['dir']['build'] - build_path = os.path.join(_project_path(), build_dir) - lines = [] - msg = _echo_msg(f"Entering build dir '{build_dir}'") - lines.append(msg) - cmd = f'cd {build_path}' - lines.append(cmd) - msg = _echo_msg(f"Creating fortran static library '{lib_name}.{lib_ext}'") - lines.append(msg) - cmd = CONFIG['template']['build-static'][_platform()] - cmd = cmd.replace('{LIB}', lib_name) - cmd = cmd.replace('{OBJ_EXT}', _obj_ext()) - lines.append(cmd) - msg = _echo_msg(f"Exiting build dir '{build_dir}'") - lines.append(msg) - cmd = f'cd {_project_path()}' - lines.append(cmd) - script_name = f'{sys._getframe().f_code.co_name}.sh' - _write_lines_to_file(lines, script_name) - append_to_main_script(lines) - -def create_cfml_dist_dir(): - dist_dir = CONFIG['cfml']['dir']['dist'] - dist_path = os.path.join(_project_path(), dist_dir) - lib_dist_dir = CONFIG['cfml']['dir']['dist-lib'] - include_dist_dir = CONFIG['cfml']['dir']['dist-include'] - lib_dist_path = os.path.join(dist_path, lib_dist_dir) - include_dist_path = os.path.join(dist_path, include_dist_dir) - lines = [] - msg = _echo_msg(f"Deleting dist dir '{dist_dir}'") - lines.append(msg) - cmd = f'rm -rf {dist_path}' - lines.append(cmd) - msg = _echo_msg(f"Creating dist dir '{dist_dir}'") - lines.append(msg) - cmd = f'mkdir -p {dist_path}' - lines.append(cmd) - msg = _echo_msg(f"Creating dist dir '{dist_dir}/{lib_dist_dir}'") - lines.append(msg) - cmd = f'mkdir -p {lib_dist_path}' - lines.append(cmd) - msg = _echo_msg(f"Creating dist dir '{dist_dir}/{include_dist_dir}'") - lines.append(msg) - cmd = f'mkdir -p {include_dist_path}' - lines.append(cmd) - script_name = f'{sys._getframe().f_code.co_name}.sh' - _write_lines_to_file(lines, script_name) - append_to_main_script(lines) - -def copy_built_to_cfml_dist(): - lib_ext = CONFIG['build']['static-lib-ext'][_platform()] - static_lib_prefix = CONFIG['build']['static-lib-prefix'][_platform()] - lib_name = CONFIG['cfml']['static-lib-name'] - lib_name = f'{static_lib_prefix}{lib_name}' - build_dir = CONFIG['cfml']['dir']['build'] - build_path = os.path.join(_project_path(), build_dir) - dist_dir = CONFIG['cfml']['dir']['dist'] - dist_path = os.path.join(_project_path(), dist_dir) - lib_dist_dir = CONFIG['cfml']['dir']['dist-lib'] - include_dist_dir = CONFIG['cfml']['dir']['dist-include'] - lib_dist_path = os.path.join(dist_path, lib_dist_dir) - include_dist_path = os.path.join(dist_path, include_dist_dir) - lines = [] - msg = _echo_msg(f"Copying built lib '{lib_name}.{lib_ext}' to dist dir '{dist_dir}/{lib_dist_dir}'") - lines.append(msg) - from_path = os.path.join(build_path, f'{lib_name}.{lib_ext}') - cmd = f'cp {from_path} {lib_dist_path}' - lines.append(cmd) - msg = _echo_msg(f"Copying built modules to dist dir '{dist_dir}/{include_dist_dir}'") - lines.append(msg) - from_path = os.path.join(build_path, '*.*mod') - cmd = f'cp {from_path} {include_dist_path}' - lines.append(cmd) - script_name = f'{sys._getframe().f_code.co_name}.sh' - _write_lines_to_file(lines, script_name) - append_to_main_script(lines) - -def build_cfml_test_programs(): - project_name = CONFIG['cfml']['log-name'] - repo_dir = CONFIG['cfml']['dir']['repo'] - src_dir = CONFIG['cfml']['dir']['repo-tests'] - src_path = os.path.join(_project_path(), repo_dir, src_dir) - build_dir = os.path.join('tests', 'functional_tests', 'cfml') - build_path = os.path.join(_project_path(), build_dir) - dist_dir = CONFIG['cfml']['dir']['dist'] - include_dir = CONFIG['cfml']['dir']['dist-include'] - include_path = os.path.join(_project_path(), dist_dir, include_dir) - lib_dir = CONFIG['cfml']['dir']['dist-lib'] - lib_path = os.path.join(_project_path(), dist_dir, lib_dir) - lib_name = CONFIG['cfml']['static-lib-name'] - lines = [] - msg = _echo_msg(f"Entering build dir '{build_dir}'") - lines.append(msg) - cmd = f'cd {build_path}' - lines.append(cmd) - msg = _echo_msg(f"Building test programs for {project_name}:") - lines.append(msg) - compile_lines = _compile_executables_script_lines('cfml', src_path, include_path, lib_path, lib_name) - lines.extend(compile_lines) - msg = _echo_msg(f"Exiting build dir '{build_dir}'") - lines.append(msg) - cmd = f'cd {_project_path()}' - lines.append(cmd) - script_name = f'{sys._getframe().f_code.co_name}.sh' - _write_lines_to_file(lines, script_name) - append_to_main_script(lines) - -def run_cfml_functional_tests_no_benchmarks(): - relpath = os.path.join('tests', 'functional_tests', 'cfml') - abspath = os.path.join(_project_path(), relpath) - lines = [] - msg = _echo_msg(f"Running functional tests from '{relpath}'") - lines.append(msg) - cmd = CONFIG['template']['run-tests'] - cmd = cmd.replace('{PATH}', abspath) - lines.append(cmd) - script_name = f'{sys._getframe().f_code.co_name}.sh' - _write_lines_to_file(lines, script_name) - append_to_main_script(lines) - -def run_cfml_functional_tests_with_benchmarks(): - relpath = os.path.join('tests', 'functional_tests', 'cfml') - abspath = os.path.join(_project_path(), relpath) - lines = [] - msg = _echo_msg(f"Running functional tests with benchmarks from '{relpath}'") - lines.append(msg) - cmd = CONFIG['template']['run-benchmarks']['base'] - if _github_branch() == 'master': - cmd += ' ' + CONFIG['template']['run-benchmarks']['master-branch'] - else: - cmd += ' ' + CONFIG['template']['run-benchmarks']['non-master-branch'] - cmd = cmd.replace('{PATH}', abspath) - if _github_actions(): - cmd = cmd.replace('{RUNNER}', 'github') - else: - cmd = cmd.replace('{RUNNER}', 'local') - cmd = cmd.replace('{COMPILER}', _compiler_name()) - cmd = cmd.replace('{PROCESSOR}', _processor()) - lines.append(cmd) - script_name = f'{sys._getframe().f_code.co_name}.sh' - _write_lines_to_file(lines, script_name) - append_to_main_script(lines) - -def create_pycfml_repo_dir(): - repo_dir = CONFIG['pycfml']['dir']['repo'] - repo_path = os.path.join(_project_path(), repo_dir) - lines = [] - msg = _echo_msg(f"Deleting build dir '{repo_dir}'") - lines.append(msg) - cmd = f'rm -rf {repo_path}' - lines.append(cmd) - msg = _echo_msg(f"Creating build dir '{repo_dir}'") - lines.append(msg) - cmd = f'mkdir -p {repo_path}' - lines.append(cmd) - script_name = f'{sys._getframe().f_code.co_name}.sh' - _write_lines_to_file(lines, script_name) - append_to_main_script(lines) - -def download_pycfml_repo(): - project_name = CONFIG['pycfml']['log-name'] - url = CONFIG['pycfml']['git']['url'] - branch = CONFIG['pycfml']['git']['branch'] - out_dir = CONFIG['pycfml']['dir']['repo'] - out_path = os.path.abspath(out_dir) - lines = [] - msg = _echo_msg(f"Downloading {project_name} branch '{branch}' to '{out_dir}' from '{url}'") - lines.append(msg) - cmd = CONFIG['template']['clone-repo'] - cmd = cmd.replace('{BRANCH}', branch) - cmd = cmd.replace('{URL}', url) - cmd = cmd.replace('{OUT_PATH}', out_path) - lines.append(cmd) - script_name = f'{sys._getframe().f_code.co_name}.sh' - _write_lines_to_file(lines, script_name) - append_to_main_script(lines) - -def copy_powder_mod_to_pycfml_repo(): - cfml_project_name = CONFIG['cfml']['log-name'] - cfml_repo_dir = CONFIG['cfml']['dir']['repo'] - cfml_repo_path = os.path.join(_project_path(), cfml_repo_dir) - pycfml_project_name = CONFIG['pycfml']['log-name'] - pycfml_repo_dir = CONFIG['pycfml']['dir']['repo'] - pycfml_src_dir = CONFIG['pycfml']['dir']['repo-src'] - pycfml_src_path = os.path.join(_project_path(), pycfml_repo_dir, pycfml_src_dir) - src_ext = CONFIG['build']['src-ext']['pycfml'] - lines = [] - from_relpath = os.path.join('Testing', 'Powder', 'Test_2', 'fortran', 'src', f'powder_mod.{src_ext}') - from_abspath = os.path.join(cfml_repo_path, from_relpath) - msg = _echo_msg(f"Copying '{from_relpath}' to '{pycfml_repo_dir}/{pycfml_src_dir}'") - lines.append(msg) - cmd = f'cp {from_abspath} {pycfml_src_path}' - lines.append(cmd) - from_relpath = os.path.join('Testing', 'Powder', 'Test_3', f'powder_mod_2.{src_ext}') - from_abspath = os.path.join(cfml_repo_path, from_relpath) - msg = _echo_msg(f"Copying '{from_relpath}' to '{pycfml_repo_dir}/{pycfml_src_dir}'") - lines.append(msg) - cmd = f'cp {from_abspath} {pycfml_src_path}' - lines.append(cmd) - script_name = f'{sys._getframe().f_code.co_name}.sh' - _write_lines_to_file(lines, script_name) - append_to_main_script(lines) - -def create_pycfml_build_dir(): - build_dir = CONFIG['pycfml']['dir']['build'] - build_path = os.path.join(_project_path(), build_dir) - lines = [] - msg = _echo_msg(f"Deleting build dir '{build_dir}'") - lines.append(msg) - cmd = f'rm -rf {build_path}' - lines.append(cmd) - msg = _echo_msg(f"Creating build dir '{build_dir}'") - lines.append(msg) - cmd = f'mkdir -p {build_path}' - lines.append(cmd) - script_name = f'{sys._getframe().f_code.co_name}.sh' - _write_lines_to_file(lines, script_name) - append_to_main_script(lines) - -def build_pycfml_objs(): - project_name = CONFIG['pycfml']['log-name'] - repo_dir = CONFIG['pycfml']['dir']['repo'] - src_dir = CONFIG['pycfml']['dir']['repo-src'] - src_path = os.path.join(_project_path(), repo_dir, src_dir) - build_dir = CONFIG['pycfml']['dir']['build'] - build_path = os.path.join(_project_path(), build_dir) - dist_dir = CONFIG['cfml']['dir']['dist'] - include_dist_dir = CONFIG['cfml']['dir']['dist-include'] - include_dist_path = os.path.join(_project_path(), dist_dir, include_dist_dir) - lines = [] - msg = _echo_msg(f"Entering build dir '{build_dir}'") - lines.append(msg) - cmd = f'cd {build_path}' - lines.append(cmd) - msg = _echo_msg(f"Building fortran objects for {project_name}:") - lines.append(msg) - compile_lines = _compile_objs_script_lines('pycfml', src_path, include_dist_path) - lines.extend(compile_lines) - msg = _echo_msg(f"Exiting build dir '{build_dir}'") - lines.append(msg) - cmd = f'cd {_project_path()}' - lines.append(cmd) - script_name = f'{sys._getframe().f_code.co_name}.sh' - _write_lines_to_file(lines, script_name) - append_to_main_script(lines) - -def build_pycfml_shared_objs_or_dynamic_libs(): - project_name = CONFIG['pycfml']['log-name'] - build_dir = CONFIG['pycfml']['dir']['build'] - build_path = os.path.join(_project_path(), build_dir) - lines = [] - msg = _echo_msg(f"Entering build dir '{build_dir}'") - lines.append(msg) - cmd = f'cd {build_path}' - lines.append(cmd) - msg = _echo_msg(f"Building fortran shared objs or dynamic libs for {project_name}:") - lines.append(msg) - compile_lines = _compile_shared_objs_or_dynamic_libs_script_lines('pycfml-modules') - lines.extend(compile_lines) - msg = _echo_msg(f"Exiting build dir '{build_dir}'") - lines.append(msg) - cmd = f'cd {_project_path()}' - lines.append(cmd) - script_name = f'{sys._getframe().f_code.co_name}.sh' - _write_lines_to_file(lines, script_name) - append_to_main_script(lines) - -def create_pycfml_dist_dir(): - dist_dir = CONFIG['pycfml']['dir']['dist'] - dist_abspath = os.path.join(_project_path(), dist_dir) - package_dir = CONFIG['pycfml']['dir']['dist-package'] - package_relpath = os.path.join(dist_dir, package_dir) - package_abspath = os.path.join(dist_abspath, package_dir) - lines = [] - msg = _echo_msg(f"Deleting dist dir '{dist_dir}'") - lines.append(msg) - cmd = f'rm -rf {dist_abspath}' - lines.append(cmd) - msg = _echo_msg(f"Creating dist dir '{package_relpath}'") - lines.append(msg) - cmd = f'mkdir -p {package_abspath}' - lines.append(cmd) - script_name = f'{sys._getframe().f_code.co_name}.sh' - _write_lines_to_file(lines, script_name) - append_to_main_script(lines) - -def copy_built_to_pycfml_dist(): - shared_lib_ext = CONFIG['build']['shared-lib-ext'][_platform()] - project_name = CONFIG['pycfml']['log-name'] - build_dir = CONFIG['pycfml']['dir']['build'] - build_path = os.path.join(_project_path(), build_dir) - dist_dir = CONFIG['pycfml']['dir']['dist'] - package_dir = CONFIG['pycfml']['dir']['dist-package'] - package_relpath = os.path.join(dist_dir, package_dir) - package_abspath = os.path.join(_project_path(), dist_dir, package_dir) - lines = [] - msg = _echo_msg(f"Copying built {project_name} shared objects or dynamic libs to '{package_relpath}'") - lines.append(msg) - from_path = os.path.join(build_path, f'*.{shared_lib_ext}') - cmd = f'cp {from_path} {package_abspath}' - lines.append(cmd) - script_name = f'{sys._getframe().f_code.co_name}.sh' - _write_lines_to_file(lines, script_name) - append_to_main_script(lines) - -def change_runpath_for_built_pycfml(): - # Tried to set rpath to $ORIGIN (with -Wl,-rpath,'$ORIGIN') during the build - # shared objects step (CONFIG['build-shared']), but it didn't help :( - # Ubuntu usage examples: - # sudo find / -iname "libif*" - # ls -l pycrysfml08_dist/pycrysfml08 - # patchelf --print-rpath pycrysfml08_dist/pycrysfml08/py_cfml_metrics.so - # patchelf --set-rpath '$ORIGIN' pycrysfml08_dist/pycrysfml08/py_cfml_metrics.so - # patchelf --print-rpath pycrysfml08_dist/pycrysfml08/py_cfml_metrics.so - # patchelf --no-default-lib pycrysfml08_dist/pycrysfml08/py_cfml_metrics.so - # ldd pycrysfml08_dist/pycrysfml08/py_cfml_metrics.so - # ls -l /opt/hostedtoolcache/Python/3.11.8/x64/lib/python3.11/site-packages/pycrysfml08 - # ldd /opt/hostedtoolcache/Python/3.11.8/x64/lib/python3.11/site-packages/pycrysfml08/py_cfml_metrics.so - # macOS usage example: - # sudo find / -iname "libif*" - # ls -l pycrysfml08_dist/pycrysfml08 - # install_name_tool -rpath /opt/intel/oneapi/compiler/2023.2.0/mac/bin/intel64/../../compiler/lib @loader_path pycrysfml08_dist/pycrysfml08/py_cfml_metrics.so - # install_name_tool -delete_rpath /usr/local/Cellar/gcc/13.2.0/lib/gcc/current pycrysfml08_dist/pycrysfml08/py_cfml_metrics.so - # install_name_tool -change /usr/local/opt/gcc/lib/gcc/current/libgfortran.5.dylib @rpath/libgfortran.5.dylib pycrysfml08_dist/pycrysfml08/py_cfml_metrics.so - # otool -L pycrysfml08_dist/pycrysfml08/py_cfml_metrics.so - # otool -l pycrysfml08_dist/pycrysfml08/py_cfml_metrics.so | grep RPATH -A2 - try: - rpaths = CONFIG['build']['rpaths'][_platform()][_processor()][_compiler_name()] - except KeyError: - msg = _echo_msg(f"No change of runtime paths are needed for platform '{_platform()} ({_processor()})' and compiler '{_compiler_name()}'") - lines = [msg] - script_name = f'{sys._getframe().f_code.co_name}.sh' - _write_lines_to_file(lines, script_name) - append_to_main_script(lines) - return - modules = 'pycfml-modules' - project_name = CONFIG['pycfml']['log-name'] - shared_lib_ext = CONFIG['build']['shared-lib-ext'][_platform()] - dist_dir = CONFIG['pycfml']['dir']['dist'] - package_dir = CONFIG['pycfml']['dir']['dist-package'] - package_relpath = os.path.join(dist_dir, package_dir) - package_abspath = os.path.join(_project_path(), dist_dir, package_dir) - total = _total_src_file_count(modules) - current = 0 - lines = [] - if _platform() == 'linux': - set_rpath_template_cmd = CONFIG['template']['rpath']['set'][_platform()] - no_default_lib_template_cmd = CONFIG['template']['no-default-lib'][_platform()] - msg = _echo_msg(f"Changing runpath(s) for built {project_name} shared objects") - lines.append(msg) - for module in CONFIG[modules]: - if 'main-file' in module: - for rpath in rpaths: - current += 1 - name = f'{module["main-file"]}' - path = os.path.join(package_abspath, name) - msg = _echo_progress_msg(current, total, f'{name}.{shared_lib_ext}') - lines.append(msg) - cmd = set_rpath_template_cmd - cmd = cmd.replace('{NEW}', rpath['new']) - cmd = cmd.replace('{PATH}', path) - cmd = cmd.replace('{EXT}', shared_lib_ext) - lines.append(cmd) - cmd = no_default_lib_template_cmd - cmd = cmd.replace('{PATH}', path) - cmd = cmd.replace('{EXT}', shared_lib_ext) - lines.append(cmd) - elif _platform() == 'macos': - try: - dependent_libs = CONFIG['build']['dependent-libs'][_platform()][_processor()][_compiler_name()] - change_lib_template_cmd = CONFIG['template']['dependent-lib']['change'][_platform()] - except KeyError: - dependent_libs = [] - delete_rpath_template_cmd = CONFIG['template']['rpath']['delete'][_platform()] - change_rpath_template_cmd = CONFIG['template']['rpath']['change'][_platform()] - msg = _echo_msg(f"Changing runpath(s) for built {project_name} shared objects") - lines.append(msg) - for module in CONFIG[modules]: - if 'main-file' in module: - current += 1 - name = f'{module["main-file"]}' - path = os.path.join(package_abspath, name) - msg = _echo_progress_msg(current, total, f'{name}.{shared_lib_ext}') - lines.append(msg) - for rpath in rpaths: - if rpath['new'] == '': # delete this rpath - cmd = delete_rpath_template_cmd - cmd = cmd.replace('{OLD}', rpath['old']) - cmd = cmd.replace('{PATH}', path) - cmd = cmd.replace('{EXT}', shared_lib_ext) - else: # change this rpath - cmd = change_rpath_template_cmd - cmd = cmd.replace('{OLD}', rpath['old']) - cmd = cmd.replace('{NEW}', rpath['new']) - cmd = cmd.replace('{PATH}', path) - cmd = cmd.replace('{EXT}', shared_lib_ext) - lines.append(cmd) - for lib in dependent_libs: - cmd = change_lib_template_cmd - cmd = cmd.replace('{OLD}', lib['old']) - cmd = cmd.replace('{NEW}', lib['new']) - cmd = cmd.replace('{PATH}', path) - cmd = cmd.replace('{EXT}', shared_lib_ext) - lines.append(cmd) - else: - msg = _echo_msg(f"Changing runpath is not needed for platform '{_platform()}'") - lines.append(msg) - script_name = f'{sys._getframe().f_code.co_name}.sh' - _write_lines_to_file(lines, script_name) - append_to_main_script(lines) - -def copy_extra_libs_to_pycfml_dist(): - try: - extra_libs = CONFIG['build']['extra-libs'][_platform()][_processor()][_compiler_name()] - except KeyError: - msg = _echo_msg(f"No extra libraries are needed for platform '{_platform()}' and compiler '{_compiler_name()}'") - lines = [msg] - script_name = f'{sys._getframe().f_code.co_name}.sh' - _write_lines_to_file(lines, script_name) - append_to_main_script(lines) - return - dist_dir = CONFIG['pycfml']['dir']['dist'] - package_dir = CONFIG['pycfml']['dir']['dist-package'] - package_relpath = os.path.join(dist_dir, package_dir) - package_abspath = os.path.join(_project_path(), package_relpath) - lines = [] - for lib_path in extra_libs: - msg = _echo_msg(f"Copying {lib_path} to dist dir '{package_relpath}'") - lines.append(msg) - cmd = f'cp {lib_path} {package_abspath}' - lines.append(cmd) - script_name = f'{sys._getframe().f_code.co_name}.sh' - _write_lines_to_file(lines, script_name) - append_to_main_script(lines) - -def copy_init_file_to_pycfml_dist(): - project_name = CONFIG['pycfml']['log-name'] - repo_dir = CONFIG['pycfml']['dir']['repo'] - repo_path = os.path.join(_project_path(), repo_dir) - dist_dir = CONFIG['pycfml']['dir']['dist'] - package_dir = CONFIG['pycfml']['dir']['dist-package'] - package_relpath = os.path.join(dist_dir, package_dir) - package_abspath = os.path.join(_project_path(), package_relpath) - lines = [] - msg = _echo_msg(f"Copying {project_name} '__init__.py' to dist dir '{package_relpath}'") - lines.append(msg) - from_path = os.path.join(repo_path, 'pycrysfml08', '__init__.py') - cmd = f'cp {from_path} {package_abspath}' - lines.append(cmd) - script_name = f'{sys._getframe().f_code.co_name}.sh' - _write_lines_to_file(lines, script_name) - append_to_main_script(lines) - -def copy_cfml_databases_to_pycfml_dist(): - cfml_repo_dir = CONFIG['cfml']['dir']['repo'] - cfml_src_dir = CONFIG['cfml']['dir']['repo-src'] - cfml_src_relpath = os.path.join(cfml_repo_dir, cfml_src_dir) - pycfml_dist_dir = CONFIG['pycfml']['dir']['dist'] - pycfml_package_dir = CONFIG['pycfml']['dir']['dist-package'] - pycfml_package_relpath = os.path.join(pycfml_dist_dir, pycfml_package_dir) - database_name = 'magnetic_data.txt' - databases_dir = 'Databases' - cfml_databases_relpath = os.path.join(cfml_src_relpath, databases_dir, database_name) - cfml_databases_abspath = os.path.join(_project_path(), cfml_databases_relpath) - pycfml_databases_relpath = os.path.join(pycfml_package_relpath, databases_dir) - pycfml_databases_abspath = os.path.join(_project_path(), pycfml_databases_relpath) - lines = [] - msg = _echo_msg(f"Creating dir '{pycfml_databases_relpath}'") - lines.append(msg) - cmd = f'mkdir -p {pycfml_databases_abspath}' - lines.append(cmd) - msg = _echo_msg(f"Copying '{cfml_databases_relpath}' database to dist dir '{pycfml_databases_relpath}'") - lines.append(msg) - cmd = f'cp {cfml_databases_abspath} {pycfml_databases_abspath}' - lines.append(cmd) - script_name = f'{sys._getframe().f_code.co_name}.sh' - _write_lines_to_file(lines, script_name) - append_to_main_script(lines) - -def validate_pyproject_toml(): - lines = [] - msg = _echo_msg(f"Validating pyproject.toml") - lines.append(msg) - cmd = 'validate-pyproject pyproject.toml' - lines.append(cmd) - script_name = f'{sys._getframe().f_code.co_name}.sh' - _write_lines_to_file(lines, script_name) - append_to_main_script(lines) - -def create_pycfml_python_wheel(): - project_name = CONFIG['pycfml']['log-name'] - wheel_dir = CONFIG['pycfml']['dir']['wheel'] - wheel_path = os.path.join(_project_path(), wheel_dir) - lines = [] - msg = _echo_msg(f"Creating '{project_name}' python wheel in '{wheel_dir}'") - lines.append(msg) - cmd = CONFIG['template']['build-wheel'] - cmd = cmd.replace('{PATH}', wheel_path) - lines.append(cmd) - script_name = f'{sys._getframe().f_code.co_name}.sh' - _write_lines_to_file(lines, script_name) - append_to_main_script(lines) - -def rename_pycfml_python_wheel(): - project_name = CONFIG['pycfml']['log-name'] - pycfml_package_dir = CONFIG['pycfml']['dir']['dist-package'] - dist_package_version = CONFIG['build']['package-version'] - initial_wheel_name = f'{pycfml_package_dir}-{dist_package_version}-py3-none-any.whl' - wheel_dir = CONFIG['pycfml']['dir']['wheel'] - wheel_relpath = os.path.join(wheel_dir, initial_wheel_name) - wheel_abspath = os.path.join(_project_path(), wheel_relpath) - lines = [] - msg = _echo_msg(f"Renaming '{project_name}' python wheel from '{wheel_relpath}'") - lines.append(msg) - cmd = CONFIG['template']['rename-wheel'] - cmd = cmd.replace('{PYTHON_TAG}', _python_tag()) # https://packaging.python.org/en/latest/specifications/platform-compatibility-tags/ - cmd = cmd.replace('{PLATFORM_TAG}', _platform_tag()) - cmd = cmd.replace('{PATH}', wheel_abspath) - lines.append(cmd) - script_name = f'{sys._getframe().f_code.co_name}.sh' - _write_lines_to_file(lines, script_name) - #append_to_main_script(lines) - -def install_pycfml_from_wheel(): - project_name = CONFIG['pycfml']['log-name'] - package_name = CONFIG['pycfml']['dir']['dist-package'] - wheel_dir = CONFIG['pycfml']['dir']['wheel'] - wheel_path = os.path.join(_project_path(), wheel_dir) - lines = [] - msg = _echo_msg(f"Installing '{project_name}' python wheel from '{wheel_dir}'") - lines.append(msg) - cmd = CONFIG['template']['install-wheel'] - cmd = cmd.replace('{PACKAGE}', package_name) - cmd = cmd.replace('{PATH}', wheel_path) - lines.append(cmd) - script_name = f'{sys._getframe().f_code.co_name}.sh' - _write_lines_to_file(lines, script_name) - append_to_main_script(lines) - -def run_pycfml_unit_tests(): - relpath = os.path.join('tests', 'unit_tests', 'pycfml') - abspath = os.path.join(_project_path(), relpath) - lines = [] - msg = _echo_msg(f"Running unit tests from '{relpath}'") - lines.append(msg) - cmd = CONFIG['template']['run-tests'] - cmd = cmd.replace('{PATH}', abspath) - lines.append(cmd) - script_name = f'{sys._getframe().f_code.co_name}.sh' - _write_lines_to_file(lines, script_name) - append_to_main_script(lines) - -def run_powder_mod_tests(): - relpath = os.path.join('tests', 'functional_tests', 'pycfml') - abspath = os.path.join(_project_path(), relpath) - lines = [] - msg = _echo_msg(f"Running powder_mod tests from '{relpath}'") - lines.append(msg) - cmd = CONFIG['template']['run-tests'] - cmd = cmd.replace('{PATH}', abspath) - lines.append(cmd) - script_name = f'{sys._getframe().f_code.co_name}.sh' - _write_lines_to_file(lines, script_name) - append_to_main_script(lines) - -def run_powder_mod_main(): - relpath = os.path.join('tests', 'functional_tests', 'pycfml', 'test__powder_mod.py') - abspath = os.path.join(_project_path(), relpath) - lines = [] - msg = _echo_msg(f"Running powder_mod main from '{relpath}'") - lines.append(msg) - cmd = CONFIG['template']['run-python'] - cmd = cmd.replace('{PATH}', abspath) - lines.append(cmd) - script_name = f'{sys._getframe().f_code.co_name}.sh' - _write_lines_to_file(lines, script_name) - append_to_main_script(lines) - -if __name__ == '__main__': - ARGS = parsed_args() - CONFIG = loaded_config('scripts.toml') - - if ARGS.print_wheel_dir: # NEED FIX. Maybe save extras to toml as in EDA? - _print_pcfml_wheel_dir() - exit(0) - - cfml_project_name = CONFIG['cfml']['log-name'] - pycfml_project_name = CONFIG['pycfml']['log-name'] - - clear_main_script() - - headers = _echo_header(f"Info") - append_to_main_script(headers) - print_debug_info() - - headers = _echo_header(f"Creating {cfml_project_name} static library") - append_to_main_script(headers) - create_cfml_repo_dir() - download_cfml_repo() - create_cfml_build_dir() - rename_global_deps_file() - build_cfml_objs() - delete_renamed_global_deps_file() - build_cfml_static_lib() - create_cfml_dist_dir() - copy_built_to_cfml_dist() - - headers = _echo_header(f"Creating and running {cfml_project_name} test programs") - append_to_main_script(headers) - build_cfml_test_programs() - run_cfml_functional_tests_no_benchmarks() - run_cfml_functional_tests_with_benchmarks() - - headers = _echo_header(f"Creating {pycfml_project_name} shared objects or dynamic libraries") - append_to_main_script(headers) - create_pycfml_repo_dir() - download_pycfml_repo() - copy_powder_mod_to_pycfml_repo() - create_pycfml_build_dir() - build_pycfml_objs() - build_pycfml_shared_objs_or_dynamic_libs() - create_pycfml_dist_dir() - copy_built_to_pycfml_dist() - change_runpath_for_built_pycfml() - - headers = _echo_header(f"Creating {pycfml_project_name} python package wheel") - append_to_main_script(headers) - copy_extra_libs_to_pycfml_dist() - copy_init_file_to_pycfml_dist() - copy_cfml_databases_to_pycfml_dist() - validate_pyproject_toml() - create_pycfml_python_wheel() - rename_pycfml_python_wheel() - - headers = _echo_header(f"Installing {pycfml_project_name} from python wheel") - append_to_main_script(headers) - install_pycfml_from_wheel() - - headers = _echo_header(f"Running {pycfml_project_name} tests") - append_to_main_script(headers) - run_pycfml_unit_tests() - run_powder_mod_tests() - run_powder_mod_main() diff --git a/scripts.toml b/scripts.toml deleted file mode 100644 index be2136b..0000000 --- a/scripts.toml +++ /dev/null @@ -1,950 +0,0 @@ -# CrysFML related parameters - -[cfml] -log-name = 'CrysFML2008' -static-lib-name = 'CrysFML08' # without 'lib' prefix on unix-based platforms - -[cfml.git] -url = 'https://code.ill.fr/rodriguez-carvajal/crysfml2008.git' -branch = 'nagfor' - -[cfml.dir] -repo = 'crysfml08_repo' -repo-src = 'Src' -repo-tests = 'Testing' -build = 'crysfml08_build' -dist = 'crysfml08_dist' -dist-lib = 'lib' -dist-include = 'include' - -# PyCrysFML related parameters - -[pycfml] -log-name = 'PyCrysFML08' - -[pycfml.git] -url = 'https://code.ill.fr/scientific-software/pycrysfml08.git' -branch = 'master' - -[pycfml.dir] -repo = 'pycrysfml08_repo' -repo-src = 'src' -build = 'pycrysfml08_build' -dist = 'pycrysfml08_dist' -dist-package = 'pycrysfml08' -wheel = 'pycrysfml08_wheel' - -# Generic build template commands and related parameters - -[project.dir] -scripts = 'scripts' - -[template] -clone-repo = 'git clone --single-branch --branch {BRANCH} {URL} {OUT_PATH}' -build-obj = '{COMPILER} {OPTIONS} -c {PATH} -I {INCLUDE}' -build-static.macos = 'ar -r {LIB}.a *.{OBJ_EXT}' -build-static.linux = 'ar -r {LIB}.a *.{OBJ_EXT}' -build-static.windows = 'lib /out:{LIB}.lib *.{OBJ_EXT}' -rpath.set.linux = 'patchelf --set-rpath {NEW} {PATH}.{EXT}' -rpath.change.macos = 'install_name_tool -rpath {OLD} {NEW} {PATH}.{EXT}' -rpath.add.macos = 'install_name_tool -add_rpath {NEW} {PATH}.{EXT}' -rpath.delete.macos = 'install_name_tool -delete_rpath {OLD} {PATH}.{EXT}' -no-default-lib.linux = 'patchelf --no-default-lib {PATH}.{EXT}' -dependent-lib.change.macos = 'install_name_tool -change {OLD} {NEW} {PATH}.{EXT}' -build-wheel = 'python3 -m build --wheel --outdir {PATH}' -rename-wheel = 'python3 -m wheel tags --python-tag {PYTHON_TAG} --platform-tag {PLATFORM_TAG} --remove {PATH}' -install-wheel = 'python3 -m pip install {PACKAGE} --force-reinstall --find-links={PATH}' # Dependencies "{PACKAGE}[test]" are installed via ci script -run-python = 'python3 {PATH}' -run-tests = 'pytest {PATH} --color=yes --benchmark-disable' -run-benchmarks.base = 'pytest {PATH} --color=yes --benchmark-only --benchmark-storage="file://./.benchmarks/{RUNNER}/{COMPILER}/{PROCESSOR}" --benchmark-warmup=on --benchmark-columns="median, iqr, ops"' -run-benchmarks.master-branch = '--benchmark-autosave' -run-benchmarks.non-master-branch = '--benchmark-compare --benchmark-compare-fail=median:10%' - -[build] -package-version = '0.0.1a0' # NEED FIX: get from pyproject.toml (consider merging) or from 'build --wheel ...' -src-ext = { cfml = 'f90', pycfml = 'F90' } -static-lib-prefix = { macos = 'lib', linux = 'lib', windows = '' } -static-lib-ext = { macos = 'a', linux = 'a', windows = 'lib' } -shared-lib-ext = { macos = 'so', linux = 'so', windows = 'pyd' } # *.dylib doesn't work on macOS, *.dll on Windows? # https://www.cita.utoronto.ca/~merz/intel_f10b/main_for/mergedProjects/bldaps_for/common/bldaps_produce_outfiles.htm -python-lib.macos = '`python3-config --ldflags --embed`' -python-lib.linux = '' -python-lib.windows = 'C:\hostedtoolcache\windows\Python\{PYTHON311_VERSION}\x64\libs\python311.lib' -site-packages.macos = '/Users/runner/hostedtoolcache/Python/{PYTHON311_VERSION}/x64/lib/python3.11/site-packages' -site-packages.linux = '/opt/hostedtoolcache/Python/{PYTHON311_VERSION}/x64/lib/python3.11/site-packages' -site-packages.windows = '???' -extra-libs.macos.i386.gfortran = [ - '/usr/local/opt/gcc/lib/gcc/current/libgfortran.5.dylib', - '/usr/local/opt/gcc/lib/gcc/current/libgcc_s.1.1.dylib', - '/usr/local/opt/gcc/lib/gcc/current/libquadmath.0.dylib', -] -extra-libs.macos.arm.gfortran = [ - '/opt/homebrew/opt/gcc/lib/gcc/current/libgfortran.5.dylib', - '/opt/homebrew/opt/gcc/lib/gcc/current/libgcc_s.1.1.dylib', - '/opt/homebrew/opt/gcc/lib/gcc/current/libquadmath.0.dylib' -] -extra-libs.macos.i386.ifort = [ - '/System/Volumes/Data/opt/intel/oneapi/compiler/2023.2.0/mac/compiler/lib/libifport.dylib', - '/System/Volumes/Data/opt/intel/oneapi/compiler/2023.2.0/mac/compiler/lib/libifcoremt.dylib', - '/System/Volumes/Data/opt/intel/oneapi/compiler/2023.2.0/mac/compiler/lib/libifcore.dylib', - '/System/Volumes/Data/opt/intel/oneapi/compiler/2023.2.0/mac/compiler/lib/libimf.dylib', - '/System/Volumes/Data/opt/intel/oneapi/compiler/2023.2.0/mac/compiler/lib/libsvml.dylib', - '/System/Volumes/Data/opt/intel/oneapi/compiler/2023.2.0/mac/compiler/lib/libintlc.dylib', - '/System/Volumes/Data/opt/intel/oneapi/compiler/2023.2.0/mac/compiler/lib/libirc.dylib', - '/System/Volumes/Data/opt/intel/oneapi/compiler/2023.2.0/mac/compiler/lib/libifdynalloc.dylib', -] -extra-libs.macos.arm.ifort = [ - '/System/Volumes/Data/opt/intel/oneapi/compiler/2023.2.0/mac/compiler/lib/libifport.dylib', - '/System/Volumes/Data/opt/intel/oneapi/compiler/2023.2.0/mac/compiler/lib/libifcoremt.dylib', - '/System/Volumes/Data/opt/intel/oneapi/compiler/2023.2.0/mac/compiler/lib/libifcore.dylib', - '/System/Volumes/Data/opt/intel/oneapi/compiler/2023.2.0/mac/compiler/lib/libimf.dylib', - '/System/Volumes/Data/opt/intel/oneapi/compiler/2023.2.0/mac/compiler/lib/libsvml.dylib', - '/System/Volumes/Data/opt/intel/oneapi/compiler/2023.2.0/mac/compiler/lib/libintlc.dylib', - '/System/Volumes/Data/opt/intel/oneapi/compiler/2023.2.0/mac/compiler/lib/libirc.dylib', - '/System/Volumes/Data/opt/intel/oneapi/compiler/2023.2.0/mac/compiler/lib/libifdynalloc.dylib', -] -extra-libs.linux.x86_64.ifort = [ - '/opt/intel/oneapi/compiler/2023.2.0/linux/compiler/lib/intel64_lin/libifport.so.5', - '/opt/intel/oneapi/compiler/2023.2.0/linux/compiler/lib/intel64_lin/libifcoremt.so.5', - '/opt/intel/oneapi/compiler/2023.2.0/linux/compiler/lib/intel64_lin/libimf.so', - '/opt/intel/oneapi/compiler/2023.2.0/linux/compiler/lib/intel64_lin/libsvml.so', - '/opt/intel/oneapi/compiler/2023.2.0/linux/compiler/lib/intel64_lin/libintlc.so.5', - '/lib/x86_64-linux-gnu/libpthread.so.0', # But still: libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 - '/lib/x86_64-linux-gnu/libm.so.6', - '/lib/x86_64-linux-gnu/libc.so.6', - '/lib/x86_64-linux-gnu/libgcc_s.so.1', -] -extra-libs.linux.x86_64.ifx = [ - '/opt/intel/oneapi/compiler/2023.2.0/linux/compiler/lib/intel64_lin/libifport.so.5', - '/opt/intel/oneapi/compiler/2023.2.0/linux/compiler/lib/intel64_lin/libifcoremt.so.5', - '/opt/intel/oneapi/compiler/2023.2.0/linux/compiler/lib/intel64_lin/libimf.so', - '/opt/intel/oneapi/compiler/2023.2.0/linux/compiler/lib/intel64_lin/libsvml.so', - '/opt/intel/oneapi/compiler/2023.2.0/linux/compiler/lib/intel64_lin/libintlc.so.5', - '/lib/x86_64-linux-gnu/libpthread.so.0', # But still: libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 - '/lib/x86_64-linux-gnu/libm.so.6', - '/lib/x86_64-linux-gnu/libc.so.6', - '/lib/x86_64-linux-gnu/libgcc_s.so.1', -] -extra-libs.linux.x86_64.gfortran = [ - '/lib/x86_64-linux-gnu/libgfortran.so.5', - '/lib/x86_64-linux-gnu/libm.so.6', - '/lib/x86_64-linux-gnu/libc.so.6', - '/lib/x86_64-linux-gnu/libgcc_s.so.1', -] -extra-libs.windows.AMD64.gfortran = [ - 'C:\mingw64\bin\libgcc_s_seh-1.dll', - 'C:\mingw64\bin\libgfortran-5.dll', - 'C:\mingw64\bin\libquadmath-0.dll', - 'C:\mingw64\bin\libwinpthread-1.dll', -] -extra-libs.windows.Intel64.gfortran = [ - 'C:\mingw64\bin\libgcc_s_seh-1.dll', - 'C:\mingw64\bin\libgfortran-5.dll', - 'C:\mingw64\bin\libquadmath-0.dll', - 'C:\mingw64\bin\libwinpthread-1.dll', -] -rpaths.linux.x86_64.gfortran = [ - { old = '', new = "'$ORIGIN'" }, -] # set rpath to point to '$ORIGIN' -rpaths.linux.x86_64.ifort = [ - { old = '', new = "'$ORIGIN'" }, -] # set rpath to point to '$ORIGIN' -rpaths.linux.x86_64.ifx = [ - { old = '', new = "'$ORIGIN'" }, -] # set rpath to point to '$ORIGIN' -rpaths.macos.i386.gfortran = [ - { old = '/usr/local/Cellar/gcc/13.2.0/lib/gcc/current/gcc/x86_64-apple-darwin21/13', new = '' }, # delete all rpaths besides @loader_path - { old = '/usr/local/Cellar/gcc/13.2.0/lib/gcc/current/gcc', new = '' }, # delete all rpaths besides @loader_path - { old = '/usr/local/Cellar/gcc/13.2.0/lib/gcc/current', new = '' }, # delete all rpaths besides @loader_path -] -rpaths.macos.arm.gfortran = [ - { old = '/opt/homebrew/Cellar/gcc/13.2.0/lib/gcc/current/gcc/aarch64-apple-darwin23/13', new = '' }, # delete all rpaths besides @loader_path - { old = '/opt/homebrew/Cellar/gcc/13.2.0/lib/gcc/current/gcc', new = '' }, # delete all rpaths besides @loader_path - { old = '/opt/homebrew/Cellar/gcc/13.2.0/lib/gcc/current', new = '' }, # delete all rpaths besides @loader_path -] -rpaths.macos.i386.ifort = [ - { old = '/opt/intel/oneapi/compiler/2023.2.0/mac/bin/intel64/../../compiler/lib', new = '@loader_path' }, -] -rpaths.macos.arm.ifort = [ - { old = '/opt/intel/oneapi/compiler/2023.2.0/mac/bin/intel64/../../compiler/lib', new = '@loader_path' }, -] -dependent-libs.macos.i386.gfortran = [ - { old = '/usr/local/opt/gcc/lib/gcc/current/libgfortran.5.dylib', new = '@rpath/libgfortran.5.dylib' }, - { old = '/usr/local/opt/gcc/lib/gcc/current/libgcc_s.1.1.dylib', new = '@rpath/libgcc_s.1.1.dylib' }, - { old = '/usr/local/opt/gcc/lib/gcc/current/libquadmath.0.dylib', new = '@rpath/libquadmath.0.dylib' }, -] -dependent-libs.macos.arm.gfortran = [ - { old = '/opt/homebrew/opt/gcc/lib/gcc/current/libgfortran.5.dylib', new = '@rpath/libgfortran.5.dylib' }, - { old = '/opt/homebrew/opt/gcc/lib/gcc/current/libquadmath.0.dylib', new = '@rpath/libquadmath.0.dylib' }, -] - -# Build configurations matrix - -[[build-objs]] -platforms = ['macos', 'linux', 'windows'] -compilers = ['gfortran'] -obj-ext = 'o' -build-shared = '{COMPILER} -shared {PATH}.o -o {PATH}.{EXT} -L{CFML_LIB_PATH} -l{CFML_LIB_NAME} {PYTHON_LIB}' -build-exe = '{COMPILER} {OPTIONS} -o {EXE_NAME} {SOURCE_PATH} -I {CFML_INCLUDE_PATH} -L{CFML_LIB_DIR} -l{CFML_LIB_NAME}' -modes.base = '-std=f2008 -cpp -fPIC -fno-stack-arrays -ffree-line-length-none' -modes.debug = '' -modes.release = '' - -[[build-objs]] -platforms = ['macos'] -compilers = ['nagfor'] -obj-ext = 'o' -build-shared = '{COMPILER} -Wl,-shared {PATH}.o -o {PATH}.{EXT} -L{CFML_LIB_PATH} -l{CFML_LIB_NAME} {PYTHON_LIB}' -build-exe = '{COMPILER} {OPTIONS} -o {EXE_NAME} {SOURCE_PATH} -I {CFML_INCLUDE_PATH} -L{CFML_LIB_DIR} -l{CFML_LIB_NAME}' -modes.base = '-f2008 -fpp -PIC -quiet -w=all -colour' -modes.debug = '' -modes.release = '' - -[[build-objs]] -platforms = ['linux', 'macos'] -compilers = ['ifort', 'ifx'] -obj-ext = 'o' -build-shared = "{COMPILER} -shared {PATH}.o -o {PATH}.{EXT} -L{CFML_LIB_PATH} -l{CFML_LIB_NAME} {IFC_LIB} {PYTHON_LIB}" -build-exe = '{COMPILER} {OPTIONS} -o {EXE_NAME} {SOURCE_PATH} -I {CFML_INCLUDE_PATH} -L{CFML_LIB_DIR} -l{CFML_LIB_NAME}' -modes.base = '-fpp -fPIC -heap-arrays -nologo' -modes.debug = '' # -g3 -modes.release = '' # -O3 - -[[build-objs]] -platforms = ['windows'] -compilers = ['ifort', 'ifx'] -obj-ext = 'obj' -build-shared = 'link {PATH}.obj /out:"{PATH}.{EXT}" /libpath:{CFML_LIB_PATH} /dll {CFML_LIB_NAME}.lib {PYTHON_LIB}' -build-exe = '{COMPILER} {OPTIONS} /exe:{EXE_NAME} {SOURCE_PATH} -I {CFML_INCLUDE_PATH} {CFML_LIB_DIR}\{CFML_LIB_NAME}.{LIB_EXT}' -modes.base = '/fpp /heap-arrays /nologo -DWIN32=ON' -modes.debug = '' -modes.release = '' - -# CrysFML fortran source files - -[[cfml-modules]] -main-file = 'Forpy' - -[[cfml-modules]] -main-file = 'CFML_Degree_Trigonometric' - -[[cfml-modules]] -main-file = 'CFML_GlobalDeps' - -[[cfml-modules]] -main-file = 'CFML_FFT' -components-dir = 'CFML_FFT' -components-files = [ - 'FFT_Gen', - 'FFT_Convol' -] - -[[cfml-modules]] -main-file = 'CFML_Maths' -components-dir = 'CFML_Maths' -components-files = [ - 'Math_Diagonalize_GEN', - 'Math_Equal_Vector', - 'Math_Determinant', - 'Math_Co_Prime', - 'Math_Cross_Product', - 'Math_Debye', - 'Math_Co_Linear', - 'Math_Erfc_Der', - 'Math_Diagonalize_SH', - 'Math_Factorial', - 'Math_Equal_Matrix', - 'Math_Inverse_Matrix', - 'Math_Is_Diagonal_Matrix', - 'Math_Equal_Vector', - 'Math_Determinant', - 'Math_PolynomialFit', - 'Math_Lower_Triangular', - 'Math_Is_Null_Vector', - 'Math_Norm', - 'Math_Locate', - 'Math_Tensor_Product', - 'Math_Linear_Dependent', - 'Math_Polyhedron_Volume', - 'Math_Resolv_System', - 'Math_SistCoord_Changes', - 'Math_Rotation_Axes', - 'Math_Modulo_Lat', - 'Math_Negligible', - 'Math_Trace', - 'Math_Scalar', - 'Math_Outerprod', - 'Math_Smoothing_Interpol', - 'Math_Zbelong', - 'Math_Spher_Harm', - 'Math_Pgcd', - 'Math_Mat_Cross', - 'Math_Poly_Legendre', - 'Math_Upper_Triangular', - 'Math_Points_In_Line2D', - 'Math_RowEchelon', - 'Math_Swap', - 'Math_Rank', - 'Math_Sort' -] - -[[cfml-modules]] -main-file = 'CFML_ExtinCorr' -components-dir = 'CFML_ExtinCorr' -components-files = [ - 'Ext_BeckerCoppens', - 'Ext_FlippingRatios', - 'Ext_ShelxCorr' -] - -[[cfml-modules]] -main-file = 'CFML_Random' -components-dir = 'CFML_Random' -components-files = [ - 'Random_Beta_Sm', - 'Random_Binomial_Sm', - 'Random_VonMises_Sm', - 'Random_InvGauss_Sm', - 'Random_Poisson_Sm', - 'Random_Gamma_Sm', - 'Random_Normal_Sm', - 'Random_Cauchy_Sm', - 'Random_T_Sm' -] - -[[cfml-modules]] -main-file = 'CFML_Messages' -components-dir = 'CFML_Messages' -components-files = [ - 'Con_Print_Message', - 'Con_Info_Message', - 'Con_Err_Message', - 'Con_Write_ScrollMsg', - 'Con_Wait_Message' -] - -[[cfml-modules]] -main-file = 'CFML_Strings' -components-dir = 'CFML_Strings' -components-files = [ - 'StringFullp', - 'StringNum', - 'StringReadKey', - 'StringTools' -] - -[[cfml-modules]] -main-file = 'CFML_Rational' -components-dir = 'CFML_Rational' -components-files = [ - 'RAT_constructor', - 'RAT_generic', - 'RAT_is_integer', - 'RAT_assignment', - 'RAT_operator_add', - 'RAT_operator_eq', - 'RAT_operator_ge', - 'RAT_Equal_rational', - 'RAT_operator_divisor', - 'RAT_operator_gt', - 'RAT_operator_le', - 'RAT_operator_minus', - 'RAT_rowechelon', - 'RAT_operator_lt', - 'RAT_overloads', - 'RAT_operator_multiply', - 'RAT_operator_neq' -] - -[[cfml-modules]] -main-file = 'CFML_SuperSpace_Database' - -[[cfml-modules]] -main-file = 'CFML_Magnetic_Database' - -[[cfml-modules]] -main-file = 'CFML_BVS_Tables' - -[[cfml-modules]] -main-file = 'CFML_Scattering_Tables' - -[[cfml-modules]] -main-file = 'CFML_Bonds_Tables' - -[[cfml-modules]] -main-file = 'CFML_Symmetry_Tables' - -[[cfml-modules]] -components-dir = 'CFML_Tables' -components-files = [ - 'Tab_Del_BVST', - 'Tab_Set_BVST', - 'Tab_Set_ScatterT', - 'Tab_Get_ScatterT', - 'Tab_Del_ScatterT', - 'Tab_Get_SpgT', - 'Tab_Del_SpgT', - 'Tab_Set_SpgT', - 'Tab_Get_SpgSymbols', - 'Tab_Get_BondsT', - 'Tab_Del_BondsT', - 'Tab_Set_BondsT', - 'Tab_Allocating_SuperSpaceDBase', - 'Tab_Read_SSG_DBase', - 'Tab_Allocating_MagneticDBase', - 'Tab_Read_MagneticDBase' -] - -[[cfml-modules]] -main-file = 'CFML_Profiles' -components-dir = 'CFML_Profiles' -components-files = [ - 'Profile_BacktoBack', - 'Profile_Exponential', - 'Profile_Finger', - 'Profile_Gaussian', - 'Profile_Init_ProfVal', - 'Profile_IkedaCarpenter', - 'Profile_TCHpVoigt', - 'Profile_Hat', - 'Profile_PseudoVoigt', - 'Profile_Lorentzian', - 'Profile_TOF_Jorgensen', - 'Profile_TOF_Jorg_Vondreele', - 'Profile_TOF_Carpenter' -] - -[[cfml-modules]] -main-file = 'CFML_Optimization_LSQ' -components-dir = 'CFML_Optimization_LSQ' -components-files = [ - 'OPT_LSQ_LevebergMarquardt_AnalyDer', - 'OPT_LSQ_Marquardt_Fit', - 'OPT_LSQ_Output', - 'OPT_LSQ_LevebergMarquardt_NumDer' -] - -[[cfml-modules]] -main-file = 'CFML_Optimization' -components-dir = 'CFML_Optimization' -components-files = [ - 'OPT_Global_Csendes', - 'OPT_Cg_Quasi_Newton', - 'OPT_Local_Optim', - 'OPT_Simplex' -] - -[[cfml-modules]] -main-file = 'CFML_Simulated_Annealing' - -[[cfml-modules]] -main-file = 'CFML_Diffpatt' -components-dir = 'CFML_DiffPatt' -components-files = [ - 'DiffP_ReadPatt_ILL', - 'DiffP_ReadPatt_CIF', - 'DiffP_FWHM_Peak', - 'DiffP_BackgPatt', - 'DiffP_ReadPatt_LLB', - 'DiffP_NoisyPoints', - 'DiffP_ReadPatt_GSAS', - 'DiffP_ReadPatt_ISIS', - 'DiffP_ReadPatt_NLS', - 'DiffP_ReadPatt_PAN', - 'DiffP_ReadPatt_FREE', - 'DiffP_ReadPatt_PSI', - 'DiffP_ReadPatt_Socabim', - 'DiffP_ReadPatt_TimeVar', - 'DiffP_ReadPatt_XYSIG', - 'DiffP_WritePatterns', - 'DiffP_ReadPatterns' -] - -[[cfml-modules]] -main-file = 'CFML_Metrics' -components-dir = 'CFML_Metrics' -components-files = [ - 'Metrics_Tensor', - 'Metrics_Gen', - 'Metrics_ThConver', - 'Metrics_IO', - 'Metrics_NiggliCell' -] - -[[cfml-modules]] -components-dir = 'CFML_Optimization_SAnn' -components-files = [ - 'SAnn_General', - 'SAnn_LocalOpt', - 'SAnn_MultiConf', - 'SAnn_SetnCheck', - 'SAnn_inout' -] - -[[cfml-modules]] -main-file = 'CFML_EoS' -components-dir = 'CFML_EoS' -components-files = [ - 'EoS_Calc', - 'EoS_CopyEDat', - 'EoS_Get_APL', - 'EoS_Get_HeatCap', - 'EoS_CellPar', - 'EoS_PrincipalEoS', - 'Eos_Allocate', - 'EoS_Transform_ESD', - 'EoS_ModDir', - 'Eos_DerivPartial', - 'EoS_Get_Tensor', - 'Eos_Get_Bulk', - 'Eos_Checks', - 'EoS_Get_Angle', - 'Eos_AlphaCalc', - 'Eos_Conlev', - 'Eos_FfCalc', - 'EoS_LinEoS_Allowed', - 'Eos_Get_Pressure', - 'Eos_Get_Temperature', - 'Eos_Get_Tait', - 'Eos_Gruneisen', - 'Eos_NormPressure', - 'Eos_Set', - 'Eos_Get_Properties', - 'Eos_Read', - 'Eos_Get_Volume', - 'Eos_PVT_Table', - 'Eos_Get_Transition', - 'Eos_Init', - 'Eos_K_Cal', - 'Eos_Pthermal', - 'Eos_Strain', - 'Eos_Write', - 'Eos_dKdTCalc' -] - -[[cfml-modules]] -main-file = 'CFML_gSpaceGroups' -components-dir = 'CFML_gSpaceGroups' -components-files = [ - 'gS_Allocate_Opers', - 'gS_Allocate_SpaceG', - 'gS_ApplySO', - 'gS_Get_Cosets', - 'gS_CheckGener', - 'gS_Get_CrystalSys', - 'gS_Get_GenerStr', - 'gS_Get_Dimension', - 'gS_Get_Generators', - 'gS_Get_Hall_Gener', - 'gS_Get_HM_Standard', - 'gS_Get_LattType', - 'gS_Get_OriginShift', - 'gS_Is_LattCentring', - 'gS_Get_X_Matrix', - 'gS_Is_InversionCentre', - 'gS_Get_Oper_Symb', - 'gS_Reorder_Oper', - 'gS_Smallest_IntegralVec', - 'gS_Identify_Groups', - 'gS_Get_Mult_OPTable', - 'gS_Get_Orb_Stabilizer_Constr', - 'gS_Get_PseudoStdBase', - 'gS_Match_Spg3D', - 'gS_Get_Mat_Symb', - 'gS_Get_Symb_Mat', - 'gS_Set_SpaceG', - 'gS_Inverse_OP', - 'gS_Get_LauePG', - 'gS_Get_SubGrp', - 'gS_Init_Procedures', - 'gS_Match_Shubnikov_Grp', - 'gS_Get_Rotations', - 'gS_Get_Ops_Gener', - 'gS_Spg_Const_VGen', - 'gS_Rational_RedTraslation', - 'gS_Get_Symb_Oper', - 'gS_operator_equal', - 'gS_Sort_Operator', - 'gS_operator_mult', - 'gS_Write_SpaceG', - 'gS_Is_Antilattice', - 'gS_Spg_Const_Str', - 'gS_Symm_Symbols', - 'gS_OnePrimeOp' -] - -[[cfml-modules]] -main-file = 'CFML_BckPeaks' - -[[cfml-modules]] -main-file = 'CFML_ILL_Instrm_Data' - -[[cfml-modules]] -main-file = 'CFML_Atoms' -components-dir = 'CFML_Atoms' -components-files = [ - 'Atm_ExtendList', - 'Atm_ChangeList', - 'Atm_Allocating_Atoms', - 'Atm_PointList', - 'Atm_RW_Bin_AtmList', - 'Atm_Write_AtmList', - 'Atm_SymmetryConstraints' -] - -[[cfml-modules]] -main-file = 'CFML_Propagation_Vectors' - -[[cfml-modules]] -main-file = 'CFML_Reflections' -components-dir = 'CFML_Reflections' -components-files = [ - 'Refl_H_Convent', - 'Refl_AsymUnit', - 'Refl_Generate', - 'Refl_H_EquivList', - 'Refl_H_Equal', - 'Refl_Conditions', - 'Refl_H_Equiv', - 'Refl_H_S', - 'Refl_H_Absent', - 'Refl_MaxNum', - 'Refl_Write_List', - 'Refl_UnitaryVec', - 'Refl_Init_RefList', - 'Refl_H_Mult' -] - -[[cfml-modules]] -main-file = 'CFML_Structure_Factors' -components-dir = 'CFML_Structure_Factors' -components-files = [ - 'SF_AtomicFactors', - 'SF_Calculations', - 'SF_Scattering_Species', - 'SF_Initialize', - 'SF_Write_SF', - 'SF_Create_Tables', -] - -[[cfml-modules]] -main-file = 'CFML_Geom' -components-dir = 'CFML_Geom' -components-files = [ - 'Geom_Angles', - 'Geom_Allocations', - 'Geom_Matrices', - 'Geom_Coordination', - 'Geom_Orbits', - 'Geom_Distances' -] - -[[cfml-modules]] -main-file = 'CFML_kvec_Symmetry' -components-dir = 'CFML_kvec_Symmetry' -components-files = [ - 'ksym_auxsub', - 'ksym_init', - 'ksym_functions', - 'ksym_suscept', - 'ksym_read', - 'ksym_write' -] - -[[cfml-modules]] -main-file = 'CFML_kvec_Structure_Factors' -components-dir = 'CFML_kvec_Structure_Factors' -components-files = [ - 'kStrf_Init_FxTables', - 'kStrf_MiV', - 'kStrf_MStrT', - 'kStrf_satellites', - 'kStrf_write' -] - -[[cfml-modules]] -main-file = 'CFML_Maps' -components-dir = 'CFML_Maps' -components-files = [ - 'Maps_Mapping', - 'Maps_MarchingCubes', - 'Maps_Percolation' -] - -[[cfml-modules]] -main-file = 'CFML_Molecules' -components-dir = 'CFML_Molecules' -components-files = [ - 'Mol_Formula', - 'Mol_Cartesian_to', - 'Mol_Fractional_to', - 'Mol_IndexList', - 'Mol_Orientation', - 'Mol_Initialize', - 'Mol_WriteInfo', - 'Mol_Spherical_to', - 'Mol_ReadInfo', - 'Mol_ZMatrix_to', - 'Mol_to_AtList' -] - -[[cfml-modules]] -main-file = 'CFML_Keywords_Code_Parser' -components-dir = 'CFML_Keywords_Code_Parser' -components-files = [ - 'KWC_FillCodes_Gen', - 'KWC_Allocation', - 'KWC_Deletion', - 'KWC_WriteRefCodes', - 'KWC_FillCodes_MolX', - 'KWC_FillCodes_FAtm', - 'KWC_SplitOperations', - 'KWC_GetConCodes', - 'KWC_VStateToAtomPar', - 'KWC_ReadCodes', - 'KWC_GetRestrCodes', - 'KWC_RefCodes' -] - -[[cfml-modules]] -main-file = 'CFML_IOForm' -components-dir = 'CFML_IOForm' -components-files = [ - 'Format_GEN', - 'Format_MCIF', - 'Format_Blocks', - 'Format_CIF', - 'Format_CFL', - 'Format_FST', - 'Format_SHX' -] - -[[cfml-modules]] -main-file = 'CFML_KeyCodes' -components-dir = 'CFML_KeyCodes' -components-files = [ - 'KeyCod_VecRef', - 'KeyCod_RGB', - 'KeyCod_Atm', - 'KeyCod_Patt', - 'KeyCod_GenPar', - 'keyCod_Phas', - 'KeyCod_WriteInfo', - 'KeyCod_Restraints', - 'KeyCod_Molec' -] - -[[cfml-modules]] -main-file = 'CFML_Python' -components-dir = 'CFML_Python' -components-files = [ - 'Python_Common', - 'Python_Atoms', - 'Python_DiffPatt', - 'Python_Metrics', - 'Python_Reflections', - 'Python_gSpaceGroups', - 'Python_Ndarray' -] - -[[cfml-modules]] -main-file = 'CFML_VTK' -components-dir = 'CFML_VTK' -components-files = [ - 'VTK_Scan_Utils' -] - -[[cfml-modules]] -main-file = 'CFML_SXTAL_Geom' -components-dir = 'CFML_SXTAL_Geom' -components-files = [ - 'SXTAL_Angles', - 'SXTAL_IO', - 'SXTAL_Matx_Zvect', - 'SXTAL_PSD', - 'SXTAL_FlatCone', - 'SXTAL_UB' -] - -[[cfml-modules]] -main-file = 'CFML_Export_VTK' - -[[cfml-modules]] -main-file = 'CFML_EnBVS' -components-dir = 'CFML_EnBVS' -components-files = [ - 'EnBVS_CostF', - 'EnBVS_Energy', - 'EnBVS_Maps', - 'EnBVS_SetTab' -] - -# PyCrysFML fortran source files - -[[pycfml-modules]] -main-file = 'py_cfml_metrics' - -[[pycfml-modules]] -main-file = 'py_cfml_profiles' - -[[pycfml-modules]] -main-file = 'py_cfml_sxtal_geom' - -[[pycfml-modules]] -main-file = 'powder_mod' - -[[pycfml-modules]] -main-file = 'powder_mod_2' - -# CrysFML test programs source files - -[[cfml-tests]] -main-dir = 'Bond_Str' -main-file = 'Bond_StrN' - -[[cfml-tests]] -main-dir = 'CIFs' -main-file = 'io_files' - -[[cfml-tests]] -main-dir = 'Grp_230' -main-file = 'groups_230' - -[[cfml-tests]] -main-dir = 'hkl_gen' -main-file = 'hkl_gen' - -[[cfml-tests]] -main-dir = 'hkl_gen' -main-file = 'simple_hkl_gen' - -[[cfml-tests]] -main-dir = 'Molecules' -main-file = 'mol_tpcr' - -[[cfml-tests]] -main-dir = 'PowderPattern' -main-file = 'Simple_calc_powder' - -[[cfml-tests]] -main-dir = 'PowderPattern' -main-file = 'Simple_calc_Mag_powder' - -[[cfml-tests]] -main-dir = 'StructureFactors' -main-file = 'Calc_Sfac' - - -################## -################## -# Compiler options -################## -################## - -########## -# gfortran -########## - -#'-cpp', # Enable preprocessing. The preprocessor is automatically invoked if the file extension is .fpp, .FPP, .F, .FOR, .FTN, .F90, .F95, .F03 or .F08. -# Use this option to manually enable preprocessing of any kind of Fortran file. -# To disable preprocessing of files with any of the above listed extensions, use the negative form: -nocpp. -# The preprocessor is run in traditional mode. Any restrictions of the file-format, especially the limits on line length, apply for preprocessed output -# as well, so it might be advisable to use the -ffree-line-length-none or -ffixed-line-length-none options. -#'-fall-intrinsics', # This option causes all intrinsic procedures (including the GNU-specific extensions) to be accepted. This can be useful with -std=f95 to force -# standard-compliance but get access to the full range of intrinsics available with gfortran. As a consequence, -Wintrinsics-std will be ignored -# and no user-defined procedure with the same name as any intrinsic will be called except when it is explicitly declared EXTERNAL -#'-fdec-math', # Enable legacy math intrinsics such as COTAN and degree-valued trigonometric functions (e.g. TAND, ATAND, etc...) for compatability with older code. -#'-ffree-line-length-none', # Set column after which characters are ignored in typical free-form lines in the source file. The default value is 132. n may be ‘none’, meaning -# that the entire line is meaningful. -ffree-line-length-0 means the same thing as -ffree-line-length-none. -#'-fno-stack-arrays', # Enabled: Put all local arrays, even those of unknown size onto stack memory. -# The -fno- form disables the behavior. -#'-fpic', # Generate position-independent code (PIC) suitable for use in a shared library, if supported for the target machine. Such code accesses all constant -# addresses through a global offset table (GOT). The dynamic loader resolves the GOT entries when the program starts (the dynamic loader is not part -# of GCC; it is part of the operating system). If the GOT size for the linked executable exceeds a machine-specific maximum size, you get an error -# message from the linker indicating that -fpic does not work; in that case, recompile with -fPIC instead. (These maximums are 8k on the SPARC, 28k on -# AArch64 and 32k on the m68k and RS/6000. The x86 has no such limit.) -# Position-independent code requires special support, and therefore works only on certain machines. For the x86, GCC supports PIC for System V but not -# for the Sun 386i. Code generated for the IBM RS/6000 is always position-independent. -#'-fPIC', # If supported for the target machine, emit position-independent code, suitable for dynamic linking and avoiding any limit on the size of the global -# offset table. This option makes a difference on AArch64, m68k, PowerPC and SPARC. -# Position-independent code requires special support, and therefore works only on certain machines. -#'-std=f2008' # Specify the standard to which the program is expected to conform, which may be one of ‘f95’, ‘f2003’, ‘f2008’, ‘gnu’, or ‘legacy’. The default -# value for std is ‘gnu’, which specifies a superset of the Fortran 95 standard that includes all of the extensions supported by GNU Fortran, although -# warnings will be given for obsolete extensions not recommended for use in new code. The ‘legacy’ value is equivalent but without the warnings for -# obsolete extensions, and may be useful for old non-standard programs. The ‘f95’, ‘f2003’ and ‘f2008’ values specify strict conformance to the -# Fortran 95, Fortran 2003 and Fortran 2008 standards, respectively; errors are given for all extensions beyond the relevant language standard, and -# warnings are given for the Fortran 77 features that are permitted but obsolescent in later standards. ‘-std=f2008ts’ allows the Fortran 2008 standard -# including the additions of the Technical Specification (TS) 29113 on Further Interoperability of Fortran with C and TS 18508 on Additional Parallel -# Features in Fortran. - -######## -# nagfor -######## - -#'-colour', # Colour the message output from the compiler using ANSI escape sequences and the default foreground colouring scheme which is: red for error messages (including -# fatal errors), blue for warning messages and green for information messages. -#'-compatible', # Make external linkages compatible with other compilers where possible; on Windows this is Microsoft Fortran (32-bit mode) or Intel Fortran (64-bit mode), on MacOS -# and Linux this is g77, g95 and gfortran, and on other systems this is the operating system vendor's compiler. This affects the naming convention and procedure -# calling convention (for example, on Windows it causes use of the "STDCALL" calling convention that is commonly used for most DLLs, and the names are in upper case -# with no added trailing underscore). On Windows in 64-bit mode, -compatible is always in effect. -#'-dusty', # Allows the compilation and execution of "legacy" software by downgrading the category of common errors found in such software from "Error" to "Warning" (which may -# then be suppressed entirely with the -w option). This option disables -C=calls, and also enables Hollerith i/o (see the -hollerith_io option). -#'-f2008', # Specify that the base language is Fortran 2008. This is the default. -#'-fpp', # Preprocess the source files using fpp even if the suffix would normally indicate an ordinary Fortran file. -#'-gline', # Compile code to produce a traceback when a runtime error message is generated. Only routines compiled with this option will appear in such a traceback. This -# option increases both executable file size and execution time. -#'-mismatch_all', # Further downgrade consistency checking of procedure argument lists so that calls to routines in the same file which are incorrect will produce warnings instead of -# error messages. This option disables -C=calls. -#'-mtrace=on', # Trace memory allocation and deallocation. This option is a synonym for -mtrace=on. -#'-no_underflow_warning', # Suppress the warning message that normally appears if a floating-point underflow occurred during execution. This option is only effective if specified when -# compiling the main program. -#'-nonstrict', # Do not check for strict conformance to the Fortran standard -#'-pic', # Produce position-independent code (small model), for use in a shared library. If the shared library is too big for the small model, use -PIC. -#'-PIC', # Produce position-independent code (large model), for use in a shared library. -#'-quiet', # Suppress the compiler banner and the summary line, so that only diagnostic messages will appear, -#'-w=all', # suppresses all warning messages; -#'-Wl,option' # Pass option directly to the host C compiler when linking (producing the executable). Multiple options may be specified in a single -Wl, option by -# separating them with commas. A comma may be included in an option by repeating it, e.g. -Wl,-filelist=file1,,file2,,file3 becomes the linker option -# -filelist=file1,file2,file3. Note that options specified with -Wl, are appended to the linking command; for options that need to be in a specific -# place, the -xldarg option can be used. - -#################### -# ifort / ifx (unix) -#################### - -# -fpic, -fPIC # generate position independent code (-fno-pic/-fno-PIC is DEFAULT) -# -[no]fpp # run Fortran preprocessor on source files prior to compilation -# -g[level] # Produce symbolic debug information. - # Valid [level] values: - # 0 - Disable generation of symbolic debug information. - # 1 - Emit minimal debug information for performing stack traces. - # 2 - Emit complete debug information. (default for -g) - # 3 - Emit extra information which may be useful for some tools. -# -heap-arrays [n] # temporary arrays of minimum size n (in kilobytes) are allocated in - # heap memory rather than on the stack. If n is not specified, - # all temporary arrays are allocated in heap memory. -# -[no]logo # display compiler version information. -nologo disables the output -# -stand [] # specifies level of conformance with ANSI standard to check - # for. If keyword is not specified, level of conformance is f18 - # keywords: f90 (same as -std90), f95 (same as -std95), - # f03 (same as -std03), f08 (same as -std08), - # f18 (same as -std18),none (same as -nostand) -# -w # disable all warnings - -####################### -# ifort / ifx (windows) -####################### - -# -DWIN32=ON - -# /[no]fpp # run Fortran preprocessor on source files prior to compilation -# /heap-arrays # /heap-arrays[:n] - # temporary arrays of minimum size n (in kilobytes) are allocated in - # heap memory rather than on the stack. If n is not specified, - # all temporary arrays are allocated in heap memory. -# /[no]logo # display compiler version information. /nologo disables the output -# /stand[:] # specifies level of conformance with ANSI standard to check - # for. If keyword is not specified, level of conformance is f18 - # keywords: f90 (same as /4Ys), f95, - # f03, f08, f18, - # none (same as /nostand) -# /w # disable all warnings diff --git a/scripts/empty.txt b/scripts/empty.txt deleted file mode 100644 index e69de29..0000000 diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..280a2f3 --- /dev/null +++ b/src/__init__.py @@ -0,0 +1,37 @@ +import importlib.metadata +import os +import platform +import sys + + +# Set package version +__version__ = importlib.metadata.version("pycrysfml") + +# Add current path to system path +sys.path.append(os.path.dirname(__file__)) + +# Set environment variable CRYSFML_DB to be the path to the Databases directory +os.environ['CRYSFML_DB'] = os.path.join(os.path.dirname(__file__), 'Databases') + +# Fix path to Python +if platform.system() == 'Darwin': # macOS + import sysconfig + python_tag = sysconfig.get_config_var('py_version_short') + old_path = f'/Library/Frameworks/Python.framework/Versions/{python_tag}/Python' + new_path = f'`python3-config --prefix`/Python' + if old_path != new_path: + import subprocess + lib_name = 'crysfml08lib.so' + lib_path = os.path.join(os.path.dirname(__file__), lib_name) + cmd = f'otool -L {lib_path}' + p = subprocess.run(cmd, shell=True, text=True, capture_output=True) + result = p.stdout + if old_path in result: + cmd = f'install_name_tool -change {old_path} {new_path} {lib_path}' + p = subprocess.run(cmd, shell=True, text=True, capture_output=True) + #result = p.stdout + #print(result) + #cmd = f'otool -L {lib_path}' + #p = subprocess.run(cmd, shell=True, text=True, capture_output=True) + #result = p.stdout + #print(result) diff --git a/tests/functional_tests/cfml/D19_instrm.geom b/tests/functional_tests/CFML/D19_instrm.geom similarity index 100% rename from tests/functional_tests/cfml/D19_instrm.geom rename to tests/functional_tests/CFML/D19_instrm.geom diff --git a/tests/functional_tests/cfml/LiFePO4n.cfl b/tests/functional_tests/CFML/LiFePO4n.cfl similarity index 100% rename from tests/functional_tests/cfml/LiFePO4n.cfl rename to tests/functional_tests/CFML/LiFePO4n.cfl diff --git a/tests/functional_tests/cfml/LiFePO4n_sum_desired.bvs b/tests/functional_tests/CFML/LiFePO4n_sum_desired.bvs similarity index 100% rename from tests/functional_tests/cfml/LiFePO4n_sum_desired.bvs rename to tests/functional_tests/CFML/LiFePO4n_sum_desired.bvs diff --git a/tests/functional_tests/cfml/SrTiO3s.cfl b/tests/functional_tests/CFML/SrTiO3s.cfl similarity index 100% rename from tests/functional_tests/cfml/SrTiO3s.cfl rename to tests/functional_tests/CFML/SrTiO3s.cfl diff --git a/tests/functional_tests/cfml/SrTiO3s_desired.dat b/tests/functional_tests/CFML/SrTiO3s_desired.dat similarity index 100% rename from tests/functional_tests/cfml/SrTiO3s_desired.dat rename to tests/functional_tests/CFML/SrTiO3s_desired.dat diff --git a/tests/functional_tests/cfml/test_d19.cfl b/tests/functional_tests/CFML/d19.cfl similarity index 100% rename from tests/functional_tests/cfml/test_d19.cfl rename to tests/functional_tests/CFML/d19.cfl diff --git a/tests/functional_tests/cfml/test_d19_desired.hkl b/tests/functional_tests/CFML/d19_desired.hkl similarity index 100% rename from tests/functional_tests/cfml/test_d19_desired.hkl rename to tests/functional_tests/CFML/d19_desired.hkl diff --git a/tests/functional_tests/cfml/if_ponsin_desired.dat b/tests/functional_tests/CFML/if_ponsin_desired.dat similarity index 100% rename from tests/functional_tests/cfml/if_ponsin_desired.dat rename to tests/functional_tests/CFML/if_ponsin_desired.dat diff --git a/tests/functional_tests/cfml/mfe_msfac.cfl b/tests/functional_tests/CFML/mfe_msfac.cfl similarity index 100% rename from tests/functional_tests/cfml/mfe_msfac.cfl rename to tests/functional_tests/CFML/mfe_msfac.cfl diff --git a/tests/functional_tests/cfml/mfe_sfac.cfl b/tests/functional_tests/CFML/mfe_sfac.cfl similarity index 100% rename from tests/functional_tests/cfml/mfe_sfac.cfl rename to tests/functional_tests/CFML/mfe_sfac.cfl diff --git a/tests/functional_tests/cfml/molecule_PPH3_Z.cfl b/tests/functional_tests/CFML/molecule_PPH3_Z.cfl similarity index 100% rename from tests/functional_tests/cfml/molecule_PPH3_Z.cfl rename to tests/functional_tests/CFML/molecule_PPH3_Z.cfl diff --git a/tests/functional_tests/cfml/molecule_PPH3_Z_fc_desired.cfl b/tests/functional_tests/CFML/molecule_PPH3_Z_fc_desired.cfl similarity index 100% rename from tests/functional_tests/cfml/molecule_PPH3_Z_fc_desired.cfl rename to tests/functional_tests/CFML/molecule_PPH3_Z_fc_desired.cfl diff --git a/tests/functional_tests/cfml/ponsin.cfl b/tests/functional_tests/CFML/ponsin.cfl similarity index 100% rename from tests/functional_tests/cfml/ponsin.cfl rename to tests/functional_tests/CFML/ponsin.cfl diff --git a/tests/functional_tests/cfml/test__Bond_Str.py b/tests/functional_tests/CFML/test__Bond_Str.py similarity index 74% rename from tests/functional_tests/cfml/test__Bond_Str.py rename to tests/functional_tests/CFML/test__Bond_Str.py index cc1490f..761720c 100644 --- a/tests/functional_tests/cfml/test__Bond_Str.py +++ b/tests/functional_tests/CFML/test__Bond_Str.py @@ -1,27 +1,33 @@ import os +import sys import re import filecmp import time import tomllib import subprocess import platform -from io import StringIO import numpy as np +from io import StringIO +from pathlib import Path from numpy.testing import assert_array_equal, assert_almost_equal, assert_allclose +################ # Help functions +################ def set_crysfml_db_path(): """Sets the env variable 'CRYSFML_DB' as the path to the 'Databases' directory containing the file 'magnetic_data.txt'.""" - project_dir = os.getenv('GITHUB_WORKSPACE', default=os.getcwd()) # locally do: export GITHUB_WORKSPACE=`pwd` + default = os.path.join(os.getcwd(), '..', '..', '..') + project_dir = os.getenv('GITHUB_WORKSPACE', default=default) # locally do: export GITHUB_WORKSPACE=`pwd` config_path = os.path.join(project_dir, 'scripts.toml') with open(config_path, 'rb') as f: CONFIG = tomllib.load(f) - repo_dir = CONFIG['cfml']['dir']['repo'] - src_dir = CONFIG['cfml']['dir']['repo-src'] - db_path = os.path.join(project_dir, repo_dir, src_dir, 'Databases') - os.environ['CRYSFML_DB'] = db_path + db_relpath = CONFIG['cfml']['dir']['repo-database'] + db_abspath = os.path.join(project_dir, db_relpath) + db_dir_relpath = os.path.dirname(db_abspath) + db_dir_abspath = os.path.abspath(db_dir_relpath) + os.environ['CRYSFML_DB'] = db_dir_abspath def change_cwd_to_tests(): """Changes the current directory to the directory of this script file.""" @@ -31,13 +37,9 @@ def run_exe_with_args(file_name:str, args:str=''): """Runs the executable with optional arguments.""" if platform.system() == 'Windows': file_name = f'{file_name}.exe' - file_name = os.path.abspath(file_name) - cmd = f'{file_name}' - if args: - cmd = f'{file_name} {args}' - #os.system(f"echo '::::: {cmd}'") - os.system(f'{cmd}') - time.sleep(2) + exe_path = os.path.join(os.getcwd(), file_name) + cmd = f'{exe_path} {args}' + os.system(cmd) def dat_to_ndarray(file_name:str, skip_begin:int=3, skip_end:int=4): """Parses the file to extract an array of data and converts it to a numpy array.""" @@ -50,12 +52,9 @@ def dat_to_ndarray(file_name:str, skip_begin:int=3, skip_end:int=4): data = np.genfromtxt(StringIO(joined), usecols=(1, 2, 3, 4, 5, 6, 7)) # converts string to ndarray return data -# Set up paths - -set_crysfml_db_path() -change_cwd_to_tests() - +####### # Tests +####### def test__Bond_StrN__LiFePO4n(): run_exe_with_args('Bond_StrN', args='LiFePO4n.cfl') @@ -63,10 +62,9 @@ def test__Bond_StrN__LiFePO4n(): actual = dat_to_ndarray('LiFePO4n_sum.bvs') assert_allclose(desired, actual, rtol=1e-02, verbose=True) - +####### # Debug +####### if __name__ == '__main__': - #os.system(f"echo '::::: ls -l'") - #os.system(f'ls -l') test__Bond_StrN__LiFePO4n() diff --git a/tests/functional_tests/cfml/test__Molecules.py b/tests/functional_tests/CFML/test__Molecules.py similarity index 70% rename from tests/functional_tests/cfml/test__Molecules.py rename to tests/functional_tests/CFML/test__Molecules.py index 197a00b..535d49a 100644 --- a/tests/functional_tests/cfml/test__Molecules.py +++ b/tests/functional_tests/CFML/test__Molecules.py @@ -6,24 +6,28 @@ import tomllib import subprocess import platform -from io import StringIO -import pytest import numpy as np -from numpy.testing import assert_allclose, assert_almost_equal +from io import StringIO +from pathlib import Path +from numpy.testing import assert_array_equal, assert_almost_equal, assert_allclose +################ # Help functions +################ def set_crysfml_db_path(): """Sets the env variable 'CRYSFML_DB' as the path to the 'Databases' directory containing the file 'magnetic_data.txt'.""" - project_dir = os.getenv('GITHUB_WORKSPACE', default=os.getcwd()) + default = os.path.join(os.getcwd(), '..', '..', '..') + project_dir = os.getenv('GITHUB_WORKSPACE', default=default) # locally do: export GITHUB_WORKSPACE=`pwd` config_path = os.path.join(project_dir, 'scripts.toml') with open(config_path, 'rb') as f: CONFIG = tomllib.load(f) - repo_dir = CONFIG['cfml']['dir']['repo'] - src_dir = CONFIG['cfml']['dir']['repo-src'] - db_path = os.path.join(project_dir, repo_dir, src_dir, 'Databases') - os.environ['CRYSFML_DB'] = db_path + db_relpath = CONFIG['cfml']['dir']['repo-database'] + db_abspath = os.path.join(project_dir, db_relpath) + db_dir_relpath = os.path.dirname(db_abspath) + db_dir_abspath = os.path.abspath(db_dir_relpath) + os.environ['CRYSFML_DB'] = db_dir_abspath def change_cwd_to_tests(): """Changes the current directory to the directory of this script file.""" @@ -33,13 +37,9 @@ def run_exe_with_args(file_name:str, args:str=''): """Runs the executable with optional arguments.""" if platform.system() == 'Windows': file_name = f'{file_name}.exe' - file_name = os.path.abspath(file_name) - cmd = f'{file_name}' - if args: - cmd = f'{file_name} {args}' - #os.system(f"echo '::::: {cmd}'") - os.system(f'{cmd}') - #time.sleep(2) + exe_path = os.path.join(os.getcwd(), file_name) + cmd = f'{exe_path} {args}' + os.system(cmd) def dat_to_ndarray(file_name:str, skip_begin:int=3, skip_end:int=4): """Parses the file to extract an array of data and converts it to a numpy array.""" @@ -51,12 +51,9 @@ def dat_to_ndarray(file_name:str, skip_begin:int=3, skip_end:int=4): data = np.genfromtxt(StringIO(joined), usecols=(4, 5, 6, 7)) # converts string to ndarray return data -# Set up paths - -set_crysfml_db_path() -change_cwd_to_tests() - +####### # Tests +####### def test__mol_tpcr__molecule_PPH3_Z(): run_exe_with_args('mol_tpcr', args='molecule_PPH3_Z.cfl') @@ -64,7 +61,9 @@ def test__mol_tpcr__molecule_PPH3_Z(): actual = dat_to_ndarray('molecule_PPH3_Z_fc.cfl', skip_begin=7, skip_end=1) assert_allclose(desired, actual, rtol=1e-03, verbose=True) +####### # Debug +####### if __name__ == '__main__': - pass + test__mol_tpcr__molecule_PPH3_Z() diff --git a/tests/functional_tests/cfml/test__PowderPattern.py b/tests/functional_tests/CFML/test__PowderPattern.py similarity index 64% rename from tests/functional_tests/cfml/test__PowderPattern.py rename to tests/functional_tests/CFML/test__PowderPattern.py index 795c638..54efffd 100644 --- a/tests/functional_tests/cfml/test__PowderPattern.py +++ b/tests/functional_tests/CFML/test__PowderPattern.py @@ -7,21 +7,27 @@ import subprocess import platform import numpy as np -from numpy.testing import assert_allclose, assert_almost_equal +from io import StringIO +from pathlib import Path +from numpy.testing import assert_array_equal, assert_almost_equal, assert_allclose +################ # Help functions +################ def set_crysfml_db_path(): """Sets the env variable 'CRYSFML_DB' as the path to the 'Databases' directory containing the file 'magnetic_data.txt'.""" - project_dir = os.getenv('GITHUB_WORKSPACE', default=os.getcwd()) - config_path = os.path.join(project_dir, 'scripts.toml') + default = os.path.join(os.getcwd(), '..', '..', '..') + project_dir = os.getenv('GITHUB_WORKSPACE', default=default) # locally do: export GITHUB_WORKSPACE=`pwd` + config_path = os.path.join(project_dir, 'pybuild.toml') with open(config_path, 'rb') as f: CONFIG = tomllib.load(f) - repo_dir = CONFIG['cfml']['dir']['repo'] - src_dir = CONFIG['cfml']['dir']['repo-src'] - db_path = os.path.join(project_dir, repo_dir, src_dir, 'Databases') - os.environ['CRYSFML_DB'] = db_path + db_relpath = CONFIG['cfml']['dir']['repo-database'] + db_abspath = os.path.join(project_dir, db_relpath) + db_dir_relpath = os.path.dirname(db_abspath) + db_dir_abspath = os.path.abspath(db_dir_relpath) + os.environ['CRYSFML_DB'] = db_dir_abspath def change_cwd_to_tests(): """Changes the current directory to the directory of this script file.""" @@ -31,13 +37,9 @@ def run_exe_with_args(file_name:str, args:str=''): """Runs the executable with optional arguments.""" if platform.system() == 'Windows': file_name = f'{file_name}.exe' - file_name = os.path.abspath(file_name) - cmd = f'{file_name}' - if args: - cmd = f'{file_name} {args}' - #os.system(f"echo '::::: {cmd}'") - os.system(f'{cmd}') - time.sleep(2) + exe_path = os.path.join(os.getcwd(), file_name) + cmd = f'{exe_path} {args}' + os.system(cmd) def dat_to_ndarray(file_name:str, skip_lines:int=0): """Parses the file to extract an array of data and converts it to a numpy array.""" @@ -50,30 +52,27 @@ def dat_to_ndarray(file_name:str, skip_lines:int=0): array = np.array(splitted, dtype=np.float32) # converts list of string numbers into numpy array of floats return array -# Set up paths - -set_crysfml_db_path() -change_cwd_to_tests() - +####### # Tests +####### -def test__Simple_calc_powder__SrTiO3s(benchmark): - @benchmark - def bench(): - run_exe_with_args('Simple_calc_powder', args='SrTiO3s.cfl') +def test__Simple_calc_powder__SrTiO3s(): + set_crysfml_db_path() + run_exe_with_args('Simple_calc_powder', args='SrTiO3s.cfl') desired = dat_to_ndarray('SrTiO3s_desired.dat', skip_lines=2) actual = dat_to_ndarray('SrTiO3s.dat', skip_lines=2) assert_allclose(desired, actual, rtol=1e-03, verbose=True) -def test__Simple_calc_powder__ponsin(benchmark): - @benchmark - def bench(): - run_exe_with_args('Simple_calc_powder', args='ponsin.cfl') +def test__Simple_calc_powder__ponsin(): + set_crysfml_db_path() + run_exe_with_args('Simple_calc_powder', args='ponsin.cfl') desired = dat_to_ndarray('if_ponsin_desired.dat', skip_lines=2) actual = dat_to_ndarray('if_ponsin.dat', skip_lines=2) assert_allclose(desired, actual, rtol=1e-03, verbose=True) +####### # Debug +####### if __name__ == '__main__': test__Simple_calc_powder__SrTiO3s() diff --git a/tests/functional_tests/cfml/test__StructureFactors.py b/tests/functional_tests/CFML/test__StructureFactors.py similarity index 57% rename from tests/functional_tests/cfml/test__StructureFactors.py rename to tests/functional_tests/CFML/test__StructureFactors.py index d083786..35fbe1c 100644 --- a/tests/functional_tests/cfml/test__StructureFactors.py +++ b/tests/functional_tests/CFML/test__StructureFactors.py @@ -7,21 +7,27 @@ import subprocess import platform import numpy as np -from numpy.testing import assert_allclose, assert_almost_equal +from io import StringIO +from pathlib import Path +from numpy.testing import assert_array_equal, assert_almost_equal, assert_allclose +################ # Help functions +################ def set_crysfml_db_path(): """Sets the env variable 'CRYSFML_DB' as the path to the 'Databases' directory containing the file 'magnetic_data.txt'.""" - project_dir = os.getenv('GITHUB_WORKSPACE', default=os.getcwd()) + default = os.path.join(os.getcwd(), '..', '..', '..') + project_dir = os.getenv('GITHUB_WORKSPACE', default=default) # locally do: export GITHUB_WORKSPACE=`pwd` config_path = os.path.join(project_dir, 'scripts.toml') with open(config_path, 'rb') as f: CONFIG = tomllib.load(f) - repo_dir = CONFIG['cfml']['dir']['repo'] - src_dir = CONFIG['cfml']['dir']['repo-src'] - db_path = os.path.join(project_dir, repo_dir, src_dir, 'Databases') - os.environ['CRYSFML_DB'] = db_path + db_relpath = CONFIG['cfml']['dir']['repo-database'] + db_abspath = os.path.join(project_dir, db_relpath) + db_dir_relpath = os.path.dirname(db_abspath) + db_dir_abspath = os.path.abspath(db_dir_relpath) + os.environ['CRYSFML_DB'] = db_dir_abspath def change_cwd_to_tests(): """Changes the current directory to the directory of this script file.""" @@ -31,13 +37,9 @@ def run_exe_with_args(file_name:str, args:str=''): """Runs the executable with optional arguments.""" if platform.system() == 'Windows': file_name = f'{file_name}.exe' - file_name = os.path.abspath(file_name) - cmd = f'{file_name}' - if args: - cmd = f'{file_name} {args}' - #os.system(f"echo '::::: {cmd}'") - os.system(f'{cmd}') - time.sleep(2) + exe_path = os.path.join(os.getcwd(), file_name) + cmd = f'{exe_path} {args}' + os.system(cmd) def dat_to_ndarray(file_name:str, skip_lines:int=0): """Parses the file to extract an array of data and converts it to a numpy array.""" @@ -50,27 +52,25 @@ def dat_to_ndarray(file_name:str, skip_lines:int=0): array = np.array(splitted, dtype=np.float32) # converts list of string numbers into numpy array of floats return array -# Set up paths - -set_crysfml_db_path() -change_cwd_to_tests() - +####### # Tests +####### -def _test__Calc_Sfac__mfe_sfac(): +def test__Calc_Sfac__mfe_sfac(): run_exe_with_args('Calc_Sfac', args='mfe_sfac.cfl 1.0') - #desired = dat_to_ndarray('SrTiO3s_desired.dat', skip_lines=2) - #actual = dat_to_ndarray('SrTiO3s.dat', skip_lines=2) - #assert_allclose(desired, actual, rtol=1e-03, verbose=True) + desired = dat_to_ndarray('SrTiO3s_desired.dat', skip_lines=2) + actual = dat_to_ndarray('SrTiO3s.dat', skip_lines=2) + assert_allclose(desired, actual, rtol=1e-03, verbose=True) -def _test__Calc_Sfac__mfe_msfac(): +def test__Calc_Sfac__mfe_msfac(): run_exe_with_args('Calc_Sfac', args='mfe_msfac.cfl 1.0') - #desired = dat_to_ndarray('SrTiO3s_desired.dat', skip_lines=2) - #actual = dat_to_ndarray('SrTiO3s.dat', skip_lines=2) - #assert_allclose(desired, actual, rtol=1e-03, verbose=True) + desired = dat_to_ndarray('SrTiO3s_desired.dat', skip_lines=2) + actual = dat_to_ndarray('SrTiO3s.dat', skip_lines=2) + assert_allclose(desired, actual, rtol=1e-03, verbose=True) +####### # Debug +####### if __name__ == '__main__': - _test__Calc_Sfac__mfe_sfac() - #test__Calc_Sfac__mfe_msfac() + test__Calc_Sfac__mfe_sfac() diff --git a/tests/functional_tests/cfml/test__hkl_gen.py b/tests/functional_tests/CFML/test__hkl_gen.py similarity index 54% rename from tests/functional_tests/cfml/test__hkl_gen.py rename to tests/functional_tests/CFML/test__hkl_gen.py index b5ffb29..2d5918f 100644 --- a/tests/functional_tests/cfml/test__hkl_gen.py +++ b/tests/functional_tests/CFML/test__hkl_gen.py @@ -6,16 +6,33 @@ import tomllib import subprocess import platform -from io import StringIO import numpy as np -from numpy.testing import assert_allclose, assert_almost_equal +from io import StringIO +from pathlib import Path +from numpy.testing import assert_array_equal, assert_almost_equal, assert_allclose +################ # Help functions +################ + +def set_crysfml_db_path(): + """Sets the env variable 'CRYSFML_DB' as the path to the 'Databases' directory containing the file 'magnetic_data.txt'.""" + default = os.path.join(os.getcwd(), '..', '..', '..') + project_dir = os.getenv('GITHUB_WORKSPACE', default=default) # locally do: export GITHUB_WORKSPACE=`pwd` + config_path = os.path.join(project_dir, 'scripts.toml') + with open(config_path, 'rb') as f: + CONFIG = tomllib.load(f) + db_relpath = CONFIG['cfml']['dir']['repo-database'] + db_abspath = os.path.join(project_dir, db_relpath) + db_dir_relpath = os.path.dirname(db_abspath) + db_dir_abspath = os.path.abspath(db_dir_relpath) + os.environ['CRYSFML_DB'] = db_dir_abspath def set_crysfml_db_path(): """Sets the env variable 'CRYSFML_DB' as the path to the 'Databases' directory containing the file 'magnetic_data.txt'.""" - project_dir = os.getenv('GITHUB_WORKSPACE', default=os.getcwd()) + default = os.path.join(os.getcwd(), '..', '..', '..') + project_dir = os.getenv('GITHUB_WORKSPACE', default=default) # locally do: export GITHUB_WORKSPACE=`pwd` config_path = os.path.join(project_dir, 'scripts.toml') with open(config_path, 'rb') as f: CONFIG = tomllib.load(f) @@ -32,13 +49,9 @@ def run_exe_with_args(file_name:str, args:str=''): """Runs the executable with optional arguments.""" if platform.system() == 'Windows': file_name = f'{file_name}.exe' - file_name = os.path.abspath(file_name) - cmd = f'{file_name}' - if args: - cmd = f'{file_name} {args}' - #os.system(f"echo '::::: {cmd}'") - os.system(f'{cmd}') - time.sleep(2) + exe_path = os.path.join(os.getcwd(), file_name) + cmd = f'{exe_path} {args}' + os.system(cmd) def dat_to_ndarray(file_name:str, skip_begin:int=3, skip_end:int=4): """Parses the file to extract an array of data and converts it to a numpy array.""" @@ -50,20 +63,19 @@ def dat_to_ndarray(file_name:str, skip_begin:int=3, skip_end:int=4): data = np.genfromtxt(StringIO(joined), usecols=(0, 1, 2, 3, 4, 5, 6, 8)) # converts string to ndarray return data -# Set up paths - -set_crysfml_db_path() -change_cwd_to_tests() - +####### # Tests +####### -def test__hkl_gen__test_d19(): - run_exe_with_args('hkl_gen', args='test_d19.cfl') - desired = dat_to_ndarray('test_d19_desired.hkl', skip_begin=1, skip_end=1) - actual = dat_to_ndarray('test_d19.hkl', skip_begin=1, skip_end=1) +def test__hkl_gen__d19(): + run_exe_with_args('hkl_gen', args='d19.cfl') + desired = dat_to_ndarray('d19_desired.hkl', skip_begin=1, skip_end=1) + actual = dat_to_ndarray('d19.hkl', skip_begin=1, skip_end=1) assert_allclose(desired, actual, rtol=1e-03, verbose=True) +####### # Debug +####### if __name__ == '__main__': - test__mol_tpcr__molecule_PPH3_Z() + test__hkl_gen__d19() diff --git a/tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/desired/srtio3-pm3m-pattern_Nebil-ifort.xy b/tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/desired/srtio3-pm3m-pattern_Nebil-ifort.xy new file mode 100644 index 0000000..eac9faa --- /dev/null +++ b/tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/desired/srtio3-pm3m-pattern_Nebil-ifort.xy @@ -0,0 +1,2781 @@ + 1.0000 20.0000 + 1.0500 20.0000 + 1.1000 20.0000 + 1.1500 20.0000 + 1.2000 20.0000 + 1.2500 20.0000 + 1.3000 20.0000 + 1.3500 20.0000 + 1.4000 20.0000 + 1.4500 20.0000 + 1.5000 20.0000 + 1.5500 20.0000 + 1.6000 20.0000 + 1.6500 20.0000 + 1.7000 20.0000 + 1.7500 20.0000 + 1.8000 20.0000 + 1.8500 20.0000 + 1.9000 20.0000 + 1.9500 20.0000 + 2.0000 20.0000 + 2.0500 20.0000 + 2.1000 20.0000 + 2.1500 20.0000 + 2.2000 20.0000 + 2.2500 20.0000 + 2.3000 20.0000 + 2.3500 20.0000 + 2.4000 20.0000 + 2.4500 20.0000 + 2.5000 20.0000 + 2.5500 20.0000 + 2.6000 20.0000 + 2.6500 20.0000 + 2.7000 20.0000 + 2.7500 20.0000 + 2.8000 20.0000 + 2.8500 20.0000 + 2.9000 20.0000 + 2.9500 20.0000 + 3.0000 20.0000 + 3.0500 20.0000 + 3.1000 20.0000 + 3.1500 20.0000 + 3.2000 20.0000 + 3.2500 20.0000 + 3.3000 20.0000 + 3.3500 20.0000 + 3.4000 20.0000 + 3.4500 20.0000 + 3.5000 20.0000 + 3.5500 20.0000 + 3.6000 20.0000 + 3.6500 20.0000 + 3.7000 20.0000 + 3.7500 20.0000 + 3.8000 20.0000 + 3.8500 20.0000 + 3.9000 20.0000 + 3.9500 20.0000 + 4.0000 20.0000 + 4.0500 20.0000 + 4.1000 20.0000 + 4.1500 20.0000 + 4.2000 20.0000 + 4.2500 20.0000 + 4.3000 20.0000 + 4.3500 20.0000 + 4.4000 20.0000 + 4.4500 20.0000 + 4.5000 20.0000 + 4.5500 20.0000 + 4.6000 20.0000 + 4.6500 20.0000 + 4.7000 20.0000 + 4.7500 20.0000 + 4.8000 20.0000 + 4.8500 20.0000 + 4.9000 20.0000 + 4.9500 20.0000 + 5.0000 20.0000 + 5.0500 20.0000 + 5.1000 20.0000 + 5.1500 20.0000 + 5.2000 20.0000 + 5.2500 20.0000 + 5.3000 20.0000 + 5.3500 20.0000 + 5.4000 20.0000 + 5.4500 20.0000 + 5.5000 20.0000 + 5.5500 20.0000 + 5.6000 20.0000 + 5.6500 20.0000 + 5.7000 20.0000 + 5.7500 20.0000 + 5.8000 20.0000 + 5.8500 20.0000 + 5.9000 20.0000 + 5.9500 20.0000 + 6.0000 20.0000 + 6.0500 20.0000 + 6.1000 20.0000 + 6.1500 20.0000 + 6.2000 20.0000 + 6.2500 20.0000 + 6.3000 20.0000 + 6.3500 20.0000 + 6.4000 20.0000 + 6.4500 20.0000 + 6.5000 20.0000 + 6.5500 20.0000 + 6.6000 20.0000 + 6.6500 20.0000 + 6.7000 20.0000 + 6.7500 20.0000 + 6.8000 20.0000 + 6.8500 20.0000 + 6.9000 20.0000 + 6.9500 20.0000 + 7.0000 20.0000 + 7.0500 20.0000 + 7.1000 20.0000 + 7.1500 20.0000 + 7.2000 20.0000 + 7.2500 20.0000 + 7.3000 20.0000 + 7.3500 20.0000 + 7.4000 20.0000 + 7.4500 20.0000 + 7.5000 20.0000 + 7.5500 20.0000 + 7.6000 20.0000 + 7.6500 20.0000 + 7.7000 20.0000 + 7.7500 20.0000 + 7.8000 20.0000 + 7.8500 20.0000 + 7.9000 20.0000 + 7.9500 20.0000 + 8.0000 20.0000 + 8.0500 20.0000 + 8.1000 20.0000 + 8.1500 20.0000 + 8.2000 20.0000 + 8.2500 20.0000 + 8.3000 20.0000 + 8.3500 20.0000 + 8.4000 20.0000 + 8.4500 20.0000 + 8.5000 20.0000 + 8.5500 20.0000 + 8.6000 20.0000 + 8.6500 20.0000 + 8.7000 20.0000 + 8.7500 20.0000 + 8.8000 20.0000 + 8.8500 20.0000 + 8.9000 20.0000 + 8.9500 20.0000 + 9.0000 20.0000 + 9.0500 20.0000 + 9.1000 20.0000 + 9.1500 20.0000 + 9.2000 20.0000 + 9.2500 20.0000 + 9.3000 20.0000 + 9.3500 20.0000 + 9.4000 20.0000 + 9.4500 20.0000 + 9.5000 20.0000 + 9.5500 20.0000 + 9.6000 20.0000 + 9.6500 20.0000 + 9.7000 20.3162 + 9.7500 20.3198 + 9.8000 20.3233 + 9.8500 20.3269 + 9.9000 20.3306 + 9.9500 20.3344 + 10.0000 20.3382 + 10.0500 20.3421 + 10.1000 20.3460 + 10.1500 20.3500 + 10.2000 20.3541 + 10.2500 20.3583 + 10.3000 20.3625 + 10.3500 20.3668 + 10.4000 20.3712 + 10.4500 20.3756 + 10.5000 20.3802 + 10.5500 20.3848 + 10.6000 20.3895 + 10.6500 20.3943 + 10.7000 20.3992 + 10.7500 20.4042 + 10.8000 20.4093 + 10.8500 20.4144 + 10.9000 20.4197 + 10.9500 20.4251 + 11.0000 20.4305 + 11.0500 20.4361 + 11.1000 20.4418 + 11.1500 20.4476 + 11.2000 20.4535 + 11.2500 20.4595 + 11.3000 20.4657 + 11.3500 20.4719 + 11.4000 20.4783 + 11.4500 20.4849 + 11.5000 20.4916 + 11.5500 20.4984 + 11.6000 20.5053 + 11.6500 20.5124 + 11.7000 20.5197 + 11.7500 20.5271 + 11.8000 20.5346 + 11.8500 20.5423 + 11.9000 20.5502 + 11.9500 20.5583 + 12.0000 20.5665 + 12.0500 20.5750 + 12.1000 20.5836 + 12.1500 20.5924 + 12.2000 20.6014 + 12.2500 20.6106 + 12.3000 20.6201 + 12.3500 20.6297 + 12.4000 20.6396 + 12.4500 20.6497 + 12.5000 20.6601 + 12.5500 20.6707 + 12.6000 20.6816 + 12.6500 20.6927 + 12.7000 20.7041 + 12.7500 20.7158 + 12.8000 20.7278 + 12.8500 20.7401 + 12.9000 20.7527 + 12.9500 20.7656 + 13.0000 20.7789 + 13.0500 20.7925 + 13.1000 20.8065 + 13.1500 20.8208 + 13.2000 20.8355 + 13.2500 20.8507 + 13.3000 20.8662 + 13.3500 20.8822 + 13.4000 20.8986 + 13.4500 20.9155 + 13.5000 20.9329 + 13.5500 20.9507 + 13.6000 20.9691 + 13.6500 20.9880 + 13.7000 21.0075 + 13.7500 21.0275 + 13.8000 21.0482 + 13.8500 21.0695 + 13.9000 21.0914 + 13.9500 21.1141 + 14.0000 21.1374 + 14.0500 21.1615 + 14.1000 21.1863 + 14.1500 21.2120 + 14.2000 21.2385 + 14.2500 21.2659 + 14.3000 21.2942 + 14.3500 21.3234 + 14.4000 21.3537 + 14.4500 21.3850 + 14.5000 21.4174 + 14.5500 21.4510 + 14.6000 21.4857 + 14.6500 21.5217 + 14.7000 21.5591 + 14.7500 21.5978 + 14.8000 21.6380 + 14.8500 21.6798 + 14.9000 21.7231 + 14.9500 21.7682 + 15.0000 21.8150 + 15.0500 21.8637 + 15.1000 21.9144 + 15.1500 21.9672 + 15.2000 22.0223 + 15.2500 22.0796 + 15.3000 22.1394 + 15.3500 22.2019 + 15.4000 22.2671 + 15.4500 22.3353 + 15.5000 22.4065 + 15.5500 22.4811 + 15.6000 22.5592 + 15.6500 22.6411 + 15.7000 22.7269 + 15.7500 22.8170 + 15.8000 22.9116 + 15.8500 23.0111 + 15.9000 23.1157 + 15.9500 23.2259 + 16.0000 23.3420 + 16.0500 23.4645 + 16.1000 23.5938 + 16.1500 23.7305 + 16.2000 23.8751 + 16.2500 24.0283 + 16.3000 24.1908 + 16.3500 24.3632 + 16.4000 24.5466 + 16.4500 24.7417 + 16.5000 24.9496 + 16.5500 25.1714 + 16.6000 25.4084 + 16.6500 25.6622 + 16.7000 25.9341 + 16.7500 26.2260 + 16.8000 26.5400 + 16.8500 26.8783 + 16.9000 27.2434 + 16.9500 27.6383 + 17.0000 28.0662 + 17.0500 28.5311 + 17.1000 29.0371 + 17.1500 29.5893 + 17.2000 30.1935 + 17.2500 30.8564 + 17.3000 31.5858 + 17.3500 32.3908 + 17.4000 33.2822 + 17.4500 34.2727 + 17.5000 35.3775 + 17.5500 36.6148 + 17.6000 38.0189 + 17.6500 39.5914 + 17.7000 41.3772 + 17.7500 43.4163 + 17.8000 45.7582 + 17.8500 48.4654 + 17.9000 51.6167 + 17.9500 55.3146 + 18.0000 59.6976 + 18.0500 64.9714 + 18.1000 71.5069 + 18.1500 80.1312 + 18.2000 92.9448 + 18.2500 115.3085 + 18.3000 159.9261 + 18.3500 253.6057 + 18.4000 445.2269 + 18.4500 809.3969 + 18.5000 1435.8254 + 18.5500 2395.2651 + 18.6000 3685.2996 + 18.6500 5178.2241 + 18.7000 6607.4844 + 18.7500 7617.8960 + 18.8000 7893.2759 + 18.8500 7336.1411 + 18.9000 6138.4165 + 18.9500 4649.3218 + 19.0000 3203.4905 + 19.0500 2021.3304 + 19.1000 1182.5496 + 19.1500 657.4590 + 19.2000 363.2409 + 19.2500 212.9089 + 19.3000 140.5825 + 19.3500 105.8664 + 19.4000 87.7807 + 19.4500 76.8073 + 19.5000 69.0575 + 19.5500 63.0226 + 19.6000 58.0896 + 19.6500 53.9646 + 19.7000 50.4710 + 19.7500 47.4849 + 19.8000 44.9135 + 19.8500 42.6838 + 19.9000 40.7385 + 19.9500 39.0315 + 20.0000 37.5257 + 20.0500 36.1910 + 20.1000 35.0024 + 20.1500 33.9397 + 20.2000 32.9856 + 20.2500 32.1260 + 20.3000 31.3489 + 20.3500 30.6441 + 20.4000 30.0028 + 20.4500 29.4179 + 20.5000 28.8828 + 20.5500 28.3921 + 20.6000 27.9410 + 20.6500 27.5254 + 20.7000 27.1417 + 20.7500 26.7868 + 20.8000 26.4577 + 20.8500 26.1522 + 20.9000 25.8679 + 20.9500 25.6031 + 21.0000 25.3559 + 21.0500 25.1249 + 21.1000 24.9086 + 21.1500 24.7059 + 21.2000 24.5156 + 21.2500 24.3368 + 21.3000 24.1686 + 21.3500 24.0101 + 21.4000 23.8606 + 21.4500 23.7195 + 21.5000 23.5862 + 21.5500 23.4600 + 21.6000 23.3406 + 21.6500 23.2274 + 21.7000 23.1200 + 21.7500 23.0181 + 21.8000 22.9212 + 21.8500 22.8291 + 21.9000 22.7415 + 21.9500 22.6580 + 22.0000 22.5785 + 22.0500 22.5026 + 22.1000 22.4303 + 22.1500 22.3612 + 22.2000 22.2952 + 22.2500 22.2321 + 22.3000 22.1718 + 22.3500 22.1141 + 22.4000 22.0589 + 22.4500 22.0060 + 22.5000 21.9553 + 22.5500 21.9067 + 22.6000 21.8601 + 22.6500 21.8155 + 22.7000 21.7726 + 22.7500 21.7315 + 22.8000 21.6920 + 22.8500 21.6541 + 22.9000 21.6177 + 22.9500 21.5828 + 23.0000 21.5492 + 23.0500 21.5170 + 23.1000 21.4860 + 23.1500 21.4563 + 23.2000 21.4277 + 23.2500 21.4003 + 23.3000 21.3740 + 23.3500 21.3487 + 23.4000 21.3245 + 23.4500 21.3013 + 23.5000 21.2790 + 23.5500 21.2577 + 23.6000 21.2373 + 23.6500 21.2178 + 23.7000 21.1992 + 23.7500 21.7076 + 23.8000 21.6966 + 23.8500 21.6865 + 23.9000 21.6773 + 23.9500 21.6691 + 24.0000 21.6618 + 24.0500 21.6554 + 24.1000 21.6500 + 24.1500 21.6455 + 24.2000 21.6420 + 24.2500 21.6395 + 24.3000 21.6379 + 24.3500 21.6374 + 24.4000 21.6379 + 24.4500 21.6395 + 24.5000 21.6423 + 24.5500 21.6462 + 24.6000 21.6514 + 24.6500 21.6578 + 24.7000 21.6656 + 24.7500 21.6749 + 24.8000 21.6857 + 24.8500 21.6982 + 24.9000 21.7125 + 24.9500 21.7287 + 25.0000 21.7471 + 25.0500 21.7677 + 25.1000 21.7910 + 25.1500 21.8170 + 25.2000 21.8462 + 25.2500 21.8789 + 25.3000 21.9156 + 25.3500 21.9568 + 25.4000 22.0031 + 25.4500 22.0552 + 25.5000 22.1142 + 25.5500 22.1810 + 25.6000 22.2572 + 25.6500 22.3442 + 25.7000 22.4443 + 25.7500 22.5601 + 25.8000 22.6949 + 25.8500 22.8532 + 25.9000 23.0409 + 25.9500 23.2676 + 26.0000 23.5512 + 26.0500 23.9337 + 26.1000 24.5235 + 26.1500 25.5923 + 26.2000 27.7658 + 26.2500 32.3133 + 26.3000 41.4400 + 26.3500 58.3083 + 26.4000 86.3672 + 26.4500 127.7394 + 26.5000 180.9950 + 26.5500 239.4291 + 26.6000 291.2333 + 26.6500 322.3478 + 26.7000 322.4344 + 26.7500 291.4650 + 26.8000 239.7499 + 26.8500 181.3405 + 26.9000 128.0722 + 26.9500 86.6678 + 27.0000 58.5792 + 27.0500 41.6968 + 27.1000 32.5707 + 27.1500 28.0365 + 27.2000 25.8839 + 27.2500 24.8401 + 27.3000 24.2775 + 27.3500 23.9232 + 27.4000 23.6685 + 27.4500 23.4712 + 27.5000 23.3132 + 27.5500 23.1853 + 27.6000 23.0813 + 27.6500 22.9969 + 27.7000 22.9287 + 27.7500 22.8741 + 27.8000 22.8312 + 27.8500 22.7981 + 27.9000 22.4587 + 27.9500 22.4452 + 28.0000 22.4383 + 28.0500 22.4374 + 28.1000 22.4418 + 28.1500 22.4510 + 28.2000 22.4647 + 28.2500 22.4826 + 28.3000 22.5043 + 28.3500 22.5298 + 28.4000 22.5587 + 28.4500 22.5910 + 28.5000 22.6266 + 28.5500 22.6654 + 28.6000 22.7074 + 28.6500 22.7525 + 28.7000 22.8007 + 28.7500 22.8521 + 28.8000 22.9067 + 28.8500 22.9645 + 28.9000 23.0256 + 28.9500 23.0900 + 29.0000 23.2579 + 29.0500 23.3304 + 29.1000 23.4068 + 29.1500 23.4869 + 29.2000 23.5711 + 29.2500 23.6594 + 29.3000 23.7521 + 29.3500 23.8494 + 29.4000 23.9514 + 29.4500 24.0585 + 29.5000 24.1710 + 29.5500 24.2890 + 29.6000 24.4129 + 29.6500 24.5432 + 29.7000 24.6800 + 29.7500 24.8240 + 29.8000 24.9754 + 29.8500 25.1348 + 29.9000 25.3027 + 29.9500 25.4797 + 30.0000 25.6664 + 30.0500 25.8635 + 30.1000 26.0718 + 30.1500 26.2921 + 30.2000 26.5252 + 30.2500 26.7722 + 30.3000 27.0342 + 30.3500 27.3123 + 30.4000 27.6079 + 30.4500 27.9225 + 30.5000 28.2577 + 30.5500 28.6153 + 30.6000 28.9973 + 30.6500 29.4060 + 30.7000 29.8438 + 30.7500 30.3137 + 30.8000 30.8187 + 30.8500 31.3624 + 30.9000 31.9489 + 30.9500 32.5828 + 31.0000 33.2692 + 31.0500 34.0141 + 31.1000 34.8243 + 31.1500 35.7076 + 31.2000 36.6730 + 31.2500 37.7311 + 31.3000 38.8938 + 31.3500 40.1755 + 31.4000 41.5928 + 31.4500 43.1655 + 31.5000 44.9170 + 31.5500 46.8752 + 31.6000 49.0738 + 31.6500 51.5533 + 31.7000 54.3633 + 31.7500 57.5649 + 31.8000 61.2331 + 31.8500 65.4625 + 31.9000 70.3718 + 31.9500 76.1135 + 32.0000 82.8893 + 32.0500 90.9820 + 32.1000 100.8540 + 32.1500 113.4354 + 32.2000 130.9913 + 32.2500 159.3381 + 32.3000 212.8298 + 32.3500 323.4958 + 32.4000 553.7704 + 32.4500 1007.2343 + 32.5000 1823.0455 + 32.5500 3137.8271 + 32.6000 5008.4102 + 32.6500 7318.3779 + 32.7000 9724.9336 + 32.7500 11691.8408 + 32.8000 12646.5029 + 32.8500 12257.7363 + 32.9000 10665.3838 + 32.9500 8376.0381 + 33.0000 5968.7969 + 33.0500 3880.9871 + 33.1000 2324.6077 + 33.1500 1307.0460 + 33.2000 715.1052 + 33.2500 403.4827 + 33.3000 250.9928 + 33.3500 178.1756 + 33.4000 141.4922 + 33.4500 120.3384 + 33.5000 106.0280 + 33.5500 95.1578 + 33.6000 86.3811 + 33.6500 79.0889 + 33.7000 73.2142 + 33.7500 67.9814 + 33.8000 63.4902 + 33.8500 59.6082 + 33.9000 56.2314 + 33.9500 53.2771 + 34.0000 50.6786 + 34.0500 48.3817 + 34.1000 46.3422 + 34.1500 44.5235 + 34.2000 42.8958 + 34.2500 41.4335 + 34.3000 40.1156 + 34.3500 38.9241 + 34.4000 37.8437 + 34.4500 36.8617 + 34.5000 35.9668 + 34.5500 35.1496 + 34.6000 34.4017 + 34.6500 33.7158 + 34.7000 33.0860 + 34.7500 32.5066 + 34.8000 31.9729 + 34.8500 31.4807 + 34.9000 31.0263 + 34.9500 30.6064 + 35.0000 30.2182 + 35.0500 29.8590 + 35.1000 29.5268 + 35.1500 29.2193 + 35.2000 28.9349 + 35.2500 28.6719 + 35.3000 28.4290 + 35.3500 28.2049 + 35.4000 27.9985 + 35.4500 27.8088 + 35.5000 27.6351 + 35.5500 27.4765 + 35.6000 27.3325 + 35.6500 27.2024 + 35.7000 27.0860 + 35.7500 26.9703 + 35.8000 26.8801 + 35.8500 26.8028 + 35.9000 26.7382 + 35.9500 26.6863 + 36.0000 26.6472 + 36.0500 26.6212 + 36.1000 26.6085 + 36.1500 26.6097 + 36.2000 26.6251 + 36.2500 26.6557 + 36.3000 26.7021 + 36.3500 26.7655 + 36.4000 26.8471 + 36.4500 26.9484 + 36.5000 27.0712 + 36.5500 27.2177 + 36.6000 27.3904 + 36.6500 27.5923 + 36.7000 27.8270 + 36.7500 28.0988 + 36.8000 28.4131 + 36.8500 28.7760 + 36.9000 29.1952 + 36.9500 29.6802 + 37.0000 30.2424 + 37.0500 30.8962 + 37.1000 31.6595 + 37.1500 32.5552 + 37.2000 33.6122 + 37.2500 34.8692 + 37.3000 36.3806 + 37.3500 38.2352 + 37.4000 40.6137 + 37.4500 43.9531 + 37.5000 49.3774 + 37.5500 59.6490 + 37.6000 80.9036 + 37.6500 125.0565 + 37.7000 211.7124 + 37.7500 367.0287 + 37.8000 616.2742 + 37.8500 969.1702 + 37.9000 1402.6671 + 37.9500 1850.9779 + 38.0000 2213.0596 + 38.0500 2382.3005 + 38.1000 2299.5542 + 38.1500 1994.5563 + 38.2000 1563.9817 + 38.2500 1115.5626 + 38.3000 729.4142 + 38.3500 443.2852 + 38.4000 257.2047 + 38.4500 149.4503 + 38.5000 92.9171 + 38.5500 65.2885 + 38.6000 52.0635 + 38.6500 45.3532 + 38.7000 41.4462 + 38.7500 38.7839 + 38.8000 36.7560 + 38.8500 35.1194 + 38.9000 33.7629 + 38.9500 32.6232 + 39.0000 31.6572 + 39.0500 30.8328 + 39.1000 30.1253 + 39.1500 29.5151 + 39.2000 28.9869 + 39.2500 28.5282 + 39.3000 28.1288 + 39.3500 27.7805 + 39.4000 27.4767 + 39.4500 27.2117 + 39.5000 26.9810 + 39.5500 26.7808 + 39.6000 26.6077 + 39.6500 26.4592 + 39.7000 26.3330 + 39.7500 26.2272 + 39.8000 26.1404 + 39.8500 26.0711 + 39.9000 26.0183 + 39.9500 25.9812 + 40.0000 25.9590 + 40.0500 25.9514 + 40.1000 25.9578 + 40.1500 25.9781 + 40.2000 26.0121 + 40.2500 26.0598 + 40.3000 26.1215 + 40.3500 26.1973 + 40.4000 26.2876 + 40.4500 26.3929 + 40.5000 26.5139 + 40.5500 26.6512 + 40.6000 26.8060 + 40.6500 26.9791 + 40.7000 27.1720 + 40.7500 27.3861 + 40.8000 27.6230 + 40.8500 27.8849 + 40.9000 28.1739 + 40.9500 28.4927 + 41.0000 28.8443 + 41.0500 29.2322 + 41.1000 29.6605 + 41.1500 30.1339 + 41.2000 30.6579 + 41.2500 31.2388 + 41.3000 31.8843 + 41.3500 32.6030 + 41.4000 33.4057 + 41.4500 34.3047 + 41.5000 35.3149 + 41.5500 36.4544 + 41.6000 37.7450 + 41.6500 39.2134 + 41.7000 40.8922 + 41.7500 42.8223 + 41.8000 45.0546 + 41.8500 47.6536 + 41.9000 50.1796 + 41.9500 53.7940 + 42.0000 58.1260 + 42.0500 63.4398 + 42.1000 70.2853 + 42.1500 80.0138 + 42.2000 96.0815 + 42.2500 126.8780 + 42.3000 190.7036 + 42.3500 322.3127 + 42.4000 577.4407 + 42.4500 1027.6990 + 42.5000 1737.8419 + 42.5500 2724.1558 + 42.6000 3909.1108 + 42.6500 5100.1816 + 42.7000 6016.6479 + 42.7500 6379.8613 + 42.8000 6060.7559 + 42.8500 5173.3462 + 42.9000 3991.2451 + 42.9500 2798.6208 + 43.0000 1795.3497 + 43.0500 1066.4253 + 43.1000 600.5209 + 43.1500 334.6621 + 43.2000 196.7573 + 43.2500 129.6901 + 43.3000 97.3880 + 43.3500 80.6605 + 43.4000 70.6360 + 43.4500 63.6383 + 43.5000 58.2283 + 43.5500 53.8245 + 43.6000 50.1512 + 43.6500 47.0459 + 43.7000 44.3965 + 43.7500 42.1182 + 43.8000 40.1454 + 43.8500 38.4262 + 43.9000 36.9193 + 43.9500 35.5915 + 44.0000 34.4158 + 44.0500 33.3699 + 44.1000 32.4355 + 44.1500 31.5975 + 44.2000 30.8432 + 44.2500 30.1619 + 44.3000 29.5447 + 44.3500 28.9838 + 44.4000 28.4726 + 44.4500 28.0056 + 44.5000 27.5780 + 44.5500 27.1855 + 44.6000 26.8246 + 44.6500 26.4919 + 44.7000 26.1849 + 44.7500 25.9010 + 44.8000 25.6381 + 44.8500 25.3944 + 44.9000 25.1681 + 44.9500 24.9579 + 45.0000 24.7624 + 45.0500 24.5805 + 45.1000 24.4112 + 45.1500 24.2535 + 45.2000 24.1068 + 45.2500 23.9702 + 45.3000 23.8433 + 45.3500 23.7254 + 45.4000 23.6162 + 45.4500 23.5152 + 45.5000 23.4222 + 45.5500 23.3370 + 45.6000 23.2593 + 45.6500 23.1893 + 45.7000 23.1267 + 45.7500 23.0719 + 45.8000 23.1303 + 45.8500 23.0928 + 45.9000 23.0640 + 45.9500 23.0446 + 46.0000 23.0356 + 46.0500 23.0381 + 46.1000 23.0537 + 46.1500 23.0843 + 46.2000 23.1325 + 46.2500 23.2019 + 46.3000 23.2976 + 46.3500 23.4275 + 46.4000 23.6085 + 46.4500 23.8802 + 46.5000 24.3449 + 46.5500 25.2535 + 46.6000 27.1632 + 46.6500 31.1576 + 46.7000 39.0240 + 46.7500 53.1555 + 46.8000 75.8812 + 46.8500 108.1334 + 46.9000 147.8680 + 46.9500 189.1243 + 47.0000 222.6598 + 47.0500 238.6180 + 47.1000 231.3999 + 47.1500 203.5050 + 47.2000 163.9900 + 47.2500 122.6859 + 47.3000 87.0084 + 47.3500 60.4891 + 47.4000 43.1824 + 47.4500 33.1186 + 47.5000 27.8096 + 47.5500 25.1941 + 47.6000 23.9264 + 47.6500 23.2713 + 47.7000 22.8813 + 47.7500 22.6099 + 47.8000 22.3993 + 47.8500 22.2266 + 47.9000 22.0810 + 47.9500 21.9565 + 48.0000 21.8489 + 48.0500 21.7552 + 48.1000 21.6729 + 48.1500 21.6002 + 48.2000 21.5355 + 48.2500 21.4777 + 48.3000 21.4257 + 48.3500 21.3788 + 48.4000 21.3362 + 48.4500 21.2975 + 48.5000 21.2622 + 48.5500 21.2298 + 48.6000 21.2001 + 48.6500 21.1727 + 48.7000 21.1475 + 48.7500 21.1241 + 48.8000 21.1025 + 48.8500 21.0825 + 48.9000 21.0640 + 48.9500 21.0467 + 49.0000 21.0307 + 49.0500 21.0158 + 49.1000 21.0020 + 49.1500 20.9891 + 49.2000 20.9772 + 49.2500 20.9661 + 49.3000 20.9559 + 49.3500 20.9464 + 49.4000 21.1404 + 49.4500 21.1346 + 49.5000 21.1295 + 49.5500 21.1251 + 49.6000 21.1213 + 49.6500 21.1182 + 49.7000 21.1157 + 49.7500 21.1137 + 49.8000 21.1124 + 49.8500 21.1117 + 49.9000 21.1115 + 49.9500 21.1119 + 50.0000 21.1128 + 50.0500 21.1143 + 50.1000 21.1163 + 50.1500 21.1189 + 50.2000 21.1220 + 50.2500 21.1257 + 50.3000 21.1300 + 50.3500 21.1347 + 50.4000 21.1401 + 50.4500 21.1460 + 50.5000 21.1525 + 50.5500 21.1596 + 50.6000 21.1673 + 50.6500 21.1756 + 50.7000 21.1845 + 50.7500 21.1940 + 50.8000 21.2043 + 50.8500 21.2151 + 50.9000 21.2267 + 50.9500 21.2390 + 51.0000 21.2520 + 51.0500 21.2658 + 51.1000 21.2804 + 51.1500 21.2958 + 51.2000 21.3121 + 51.2500 21.3293 + 51.3000 21.3474 + 51.3500 21.3664 + 51.4000 21.3865 + 51.4500 21.4076 + 51.5000 21.4299 + 51.5500 21.4533 + 51.6000 21.4780 + 51.6500 21.5039 + 51.7000 21.5312 + 51.7500 21.5600 + 51.8000 21.3163 + 51.8500 21.3512 + 51.9000 21.3878 + 51.9500 21.4261 + 52.0000 21.4663 + 52.0500 21.5085 + 52.1000 21.5528 + 52.1500 21.5994 + 52.2000 21.6485 + 52.2500 21.7002 + 52.3000 21.7547 + 52.3500 21.8123 + 52.4000 21.8731 + 52.4500 21.9374 + 52.5000 22.0056 + 52.5500 22.0779 + 52.6000 22.1546 + 52.6500 22.2363 + 52.7000 22.3232 + 52.7500 22.4158 + 52.8000 22.5148 + 52.8500 22.6207 + 52.9000 22.7407 + 52.9500 22.8626 + 53.0000 22.9937 + 53.0500 23.1350 + 53.1000 23.2875 + 53.1500 23.4527 + 53.2000 23.6319 + 53.2500 23.8267 + 53.3000 24.0392 + 53.3500 24.2716 + 53.4000 24.5265 + 53.4500 24.8068 + 53.5000 25.1164 + 53.5500 25.4592 + 53.6000 25.8406 + 53.6500 26.2664 + 53.7000 26.7440 + 53.7500 27.2822 + 53.8000 27.8918 + 53.8500 28.5860 + 53.9000 29.3816 + 53.9500 30.2991 + 54.0000 31.3648 + 54.0500 32.6126 + 54.1000 34.0881 + 54.1500 35.8580 + 54.2000 38.0371 + 54.2500 40.8731 + 54.3000 44.9781 + 54.3500 51.8989 + 54.4000 65.2984 + 54.4500 92.9219 + 54.5000 148.9707 + 54.5500 255.2654 + 54.6000 438.2985 + 54.6500 719.4734 + 54.7000 1099.0514 + 54.7500 1540.7247 + 54.8000 1966.6317 + 54.8500 2270.9844 + 54.9000 2357.4138 + 54.9500 2194.6570 + 55.0000 1840.0751 + 55.0500 1398.6477 + 55.1000 970.1396 + 55.1500 619.7548 + 55.2000 371.0628 + 55.2500 215.1765 + 55.3000 127.5973 + 55.3500 82.6087 + 55.4000 60.7402 + 55.4500 50.0640 + 55.5000 44.3776 + 55.5500 40.8633 + 55.6000 38.3624 + 55.6500 36.4189 + 55.7000 34.8431 + 55.7500 33.5403 + 55.8000 32.4528 + 55.8500 31.5396 + 55.9000 30.7698 + 55.9500 30.1197 + 56.0000 29.5703 + 56.0500 29.1067 + 56.1000 28.7169 + 56.1500 28.3820 + 56.2000 28.1134 + 56.2500 27.8952 + 56.3000 28.2078 + 56.3500 28.0822 + 56.4000 27.9952 + 56.4500 27.9445 + 56.5000 27.9284 + 56.5500 27.9457 + 56.6000 27.9960 + 56.6500 28.0789 + 56.7000 28.1950 + 56.7500 28.3450 + 56.8000 28.5302 + 56.8500 28.7526 + 56.9000 29.0144 + 56.9500 29.3189 + 57.0000 29.6697 + 57.0500 30.0714 + 57.1000 30.5297 + 57.1500 31.0513 + 57.2000 31.6443 + 57.2500 32.3186 + 57.3000 33.0860 + 57.3500 33.9611 + 57.4000 34.9617 + 57.4500 36.1093 + 57.5000 37.4311 + 57.5500 38.9608 + 57.6000 40.7407 + 57.6500 42.8253 + 57.7000 45.2847 + 57.7500 48.2153 + 57.8000 51.7630 + 57.8500 56.1954 + 57.9000 62.1149 + 57.9500 71.0298 + 58.0000 86.6985 + 58.0500 117.7583 + 58.1000 181.7990 + 58.1500 309.6379 + 58.2000 545.9686 + 58.2500 940.7129 + 58.3000 1526.8403 + 58.3500 2288.8142 + 58.4000 3136.7659 + 58.4500 3905.0481 + 58.5000 4389.0024 + 58.5500 4427.9189 + 58.6000 4007.5847 + 58.6500 3271.1118 + 58.7000 2423.1733 + 58.7500 1639.1224 + 58.8000 1021.8662 + 58.8500 597.6169 + 58.9000 338.9924 + 58.9500 196.9944 + 59.0000 125.1313 + 59.0500 90.2325 + 59.1000 72.8327 + 59.1500 63.1572 + 59.2000 56.8802 + 59.2500 52.2476 + 59.3000 48.5640 + 59.3500 45.5281 + 59.4000 42.9810 + 59.4500 40.8211 + 59.5000 38.9741 + 59.5500 37.4333 + 59.6000 36.0554 + 59.6500 34.8543 + 59.7000 33.8022 + 59.7500 32.8761 + 59.8000 32.0575 + 59.8500 31.3312 + 59.9000 30.6844 + 59.9500 30.1068 + 60.0000 29.5896 + 60.0500 29.1253 + 60.1000 28.7077 + 60.1500 28.3316 + 60.2000 27.9923 + 60.2500 27.6861 + 60.3000 27.4096 + 60.3500 27.1599 + 60.4000 26.9346 + 60.4500 26.7316 + 60.5000 26.5492 + 60.5500 26.3856 + 60.6000 26.2397 + 60.6500 26.1104 + 60.7000 25.9967 + 60.7500 25.8980 + 60.8000 25.8138 + 60.8500 25.7436 + 60.9000 25.6874 + 60.9500 25.6452 + 61.0000 25.6174 + 61.0500 25.6045 + 61.1000 25.6075 + 61.1500 25.6276 + 61.2000 25.6669 + 61.2500 25.7281 + 61.3000 25.8156 + 61.3500 25.9377 + 61.4000 26.1135 + 61.4500 26.3906 + 61.5000 26.8877 + 61.5500 27.8767 + 61.6000 29.9096 + 61.6500 33.9507 + 61.7000 41.3955 + 61.7500 53.7993 + 61.8000 72.1869 + 61.8500 96.0728 + 61.9000 122.6587 + 61.9500 146.7843 + 62.0000 162.0592 + 62.0500 163.4393 + 62.1000 150.4435 + 62.1500 127.5219 + 62.2000 101.0660 + 62.2500 76.5644 + 62.3000 57.2546 + 62.3500 43.9829 + 62.4000 35.9147 + 62.4500 31.5275 + 62.5000 29.3667 + 62.5500 28.3889 + 62.6000 27.9790 + 62.6500 27.8270 + 62.7000 27.7953 + 62.7500 27.9506 + 62.8000 28.0281 + 62.8500 28.1398 + 62.9000 28.2817 + 62.9500 28.4516 + 63.0000 28.6483 + 63.0500 28.8712 + 63.1000 29.1205 + 63.1500 29.3967 + 63.2000 29.7006 + 63.2500 30.0336 + 63.3000 30.3974 + 63.3500 30.7940 + 63.4000 31.2260 + 63.4500 31.6962 + 63.5000 32.2080 + 63.5500 32.7654 + 63.6000 33.3729 + 63.6500 34.0358 + 63.7000 34.7601 + 63.7500 35.5527 + 63.8000 36.4217 + 63.8500 37.3767 + 63.9000 38.4286 + 63.9500 39.5900 + 64.0000 40.7712 + 64.0500 42.2012 + 64.1000 43.7950 + 64.1500 45.5778 + 64.2000 47.5796 + 64.2500 49.8373 + 64.3000 52.3960 + 64.3500 55.3101 + 64.4000 58.6473 + 64.4500 62.4916 + 64.5000 66.9498 + 64.5500 72.1589 + 64.6000 78.2966 + 64.6500 85.6103 + 64.7000 94.4862 + 64.7500 105.6677 + 64.8000 120.8729 + 64.8500 144.3964 + 64.9000 186.7190 + 64.9500 271.1920 + 65.0000 443.7038 + 65.0500 781.3958 + 65.1000 1390.5258 + 65.1500 2380.5273 + 65.2000 3808.8052 + 65.2500 5608.3545 + 65.3000 7538.2495 + 65.3500 9197.0254 + 65.4000 10121.2324 + 65.4500 9995.2539 + 65.5000 8864.8350 + 65.5500 7102.7568 + 65.6000 5171.9697 + 65.6500 3443.2974 + 65.7000 2115.2686 + 65.7500 1220.6891 + 65.8000 684.2318 + 65.8500 393.0017 + 65.9000 246.3245 + 65.9500 174.6118 + 66.0000 138.0882 + 66.0500 117.1197 + 66.1000 103.1072 + 66.1500 92.5790 + 66.2000 84.1326 + 66.2500 77.1423 + 66.3000 71.2645 + 66.3500 66.2701 + 66.4000 61.9938 + 66.4500 58.3059 + 66.5000 55.1064 + 66.5500 52.3156 + 66.6000 49.8684 + 66.6500 47.7137 + 66.7000 45.8084 + 66.7500 44.1180 + 66.8000 42.6142 + 66.8500 41.2725 + 66.9000 40.0735 + 66.9500 39.0002 + 67.0000 38.0388 + 67.0500 37.1778 + 67.1000 36.4070 + 67.1500 35.7186 + 67.2000 35.1054 + 67.2500 34.5621 + 67.3000 34.0843 + 67.3500 33.6685 + 67.4000 33.3123 + 67.4500 33.0143 + 67.5000 32.7741 + 67.5500 32.5923 + 67.6000 32.4707 + 67.6500 32.2094 + 67.7000 32.2217 + 67.7500 32.3088 + 67.8000 32.4801 + 67.8500 32.7481 + 67.9000 33.1298 + 67.9500 33.6496 + 68.0000 34.3466 + 68.0500 35.2967 + 68.1000 36.6775 + 68.1500 38.9312 + 68.2000 43.1344 + 68.2500 51.6748 + 68.3000 69.2172 + 68.3500 103.5730 + 68.4000 165.4420 + 68.4500 265.8394 + 68.5000 410.4237 + 68.5500 592.3492 + 68.6000 787.4179 + 68.6500 955.1053 + 68.7000 1048.7876 + 68.7500 1036.4567 + 68.8000 922.5986 + 68.8500 744.6356 + 68.9000 549.3271 + 68.9500 374.0201 + 69.0000 238.9880 + 69.0500 147.7265 + 69.1000 92.7576 + 69.1500 62.7833 + 69.2000 47.6001 + 69.2500 40.1381 + 69.3000 36.3213 + 69.3500 34.1260 + 69.4000 32.6624 + 69.4500 31.5678 + 69.5000 30.6963 + 69.5500 29.9825 + 69.6000 29.3904 + 69.6500 28.8970 + 69.7000 28.4851 + 69.7500 28.1419 + 69.8000 27.8573 + 69.8500 27.6235 + 69.9000 27.4346 + 69.9500 27.2858 + 70.0000 27.1734 + 70.0500 27.0949 + 70.1000 27.0482 + 70.1500 27.0320 + 70.2000 27.0457 + 70.2500 27.0892 + 70.3000 27.1627 + 70.3500 27.2673 + 70.4000 27.4043 + 70.4500 27.5758 + 70.5000 27.7846 + 70.5500 28.0339 + 70.6000 28.3282 + 70.6500 28.6726 + 70.7000 29.0738 + 70.7500 29.5398 + 70.8000 30.0802 + 70.8500 30.7075 + 70.9000 31.4364 + 70.9500 32.2861 + 71.0000 33.2802 + 71.0500 34.4486 + 71.1000 35.8305 + 71.1500 37.4714 + 71.2000 39.4609 + 71.2500 41.9229 + 71.3000 45.1320 + 71.3500 49.7541 + 71.4000 57.4331 + 71.4500 72.0038 + 71.5000 101.4758 + 71.5500 160.4005 + 71.6000 271.0894 + 71.6500 460.6552 + 71.7000 751.5424 + 71.7500 1145.5017 + 71.8000 1607.7345 + 71.8500 2061.1294 + 71.9000 2397.4292 + 71.9500 2513.1223 + 72.0000 2366.7302 + 72.0500 2010.1917 + 72.1000 1550.3192 + 72.1500 1093.0087 + 72.2000 710.4498 + 72.2500 432.4242 + 72.3000 253.7569 + 72.3500 150.6785 + 72.4000 96.2983 + 72.4500 69.1991 + 72.5000 55.7293 + 72.5500 48.5115 + 72.6000 44.0658 + 72.6500 40.9159 + 72.7000 38.4649 + 72.7500 36.4643 + 72.8000 34.7931 + 72.8500 33.3784 + 72.9000 32.1701 + 72.9500 31.1301 + 73.0000 30.2290 + 73.0500 29.4438 + 73.1000 28.7556 + 73.1500 28.1497 + 73.2000 27.6138 + 73.2500 27.1380 + 73.3000 26.7143 + 73.3500 26.3357 + 73.4000 25.9967 + 73.4500 25.6927 + 73.5000 25.4196 + 73.5500 25.1743 + 73.6000 24.9539 + 73.6500 24.7563 + 73.7000 24.5794 + 73.7500 24.4220 + 73.8000 24.2826 + 73.8500 24.1606 + 73.9000 24.0552 + 73.9500 23.9662 + 74.0000 23.8936 + 74.0500 23.8378 + 74.1000 23.7996 + 74.1500 23.7801 + 74.2000 23.7813 + 74.2500 23.8056 + 74.3000 23.8566 + 74.3500 23.9398 + 74.4000 24.0637 + 74.4500 24.2462 + 74.5000 24.5286 + 74.5500 24.5294 + 74.6000 25.4677 + 74.6500 27.3867 + 74.7000 31.3057 + 74.7500 38.8862 + 74.8000 52.3409 + 74.8500 73.8503 + 74.9000 104.3672 + 74.9500 142.2180 + 75.0000 182.1620 + 75.0500 215.9737 + 75.1000 233.7940 + 75.1500 229.7046 + 75.2000 205.1740 + 75.2500 168.1267 + 75.3000 128.0459 + 75.3500 92.3457 + 75.4000 64.9627 + 75.4500 46.4746 + 75.5000 35.3263 + 75.5500 29.2208 + 75.6000 26.1023 + 75.6500 24.5483 + 75.7000 23.7370 + 75.7500 23.2591 + 75.8000 22.9332 + 75.8500 22.6844 + 75.9000 22.4825 + 75.9500 22.3136 + 76.0000 22.1699 + 76.0500 22.0465 + 76.1000 21.9397 + 76.1500 21.8465 + 76.2000 21.7648 + 76.2500 21.6926 + 76.3000 21.6287 + 76.3500 21.5717 + 76.4000 21.5208 + 76.4500 21.4752 + 76.5000 21.4341 + 76.5500 21.3970 + 76.6000 21.3635 + 76.6500 21.3332 + 76.7000 21.3058 + 76.7500 21.2809 + 76.8000 21.2583 + 76.8500 21.2378 + 76.9000 21.2192 + 76.9500 21.2024 + 77.0000 21.1871 + 77.0500 21.1734 + 77.1000 21.1611 + 77.1500 21.1501 + 77.2000 21.1404 + 77.2500 21.1318 + 77.3000 21.1242 + 77.3500 21.1178 + 77.4000 21.1123 + 77.4500 21.1077 + 77.5000 21.1041 + 77.5500 21.1014 + 77.6000 21.0995 + 77.6500 21.0985 + 77.7000 21.0983 + 77.7500 21.0989 + 77.8000 21.1003 + 77.8500 21.1025 + 77.9000 21.0558 + 77.9500 21.0601 + 78.0000 21.0652 + 78.0500 21.0784 + 78.1000 21.0851 + 78.1500 21.0927 + 78.2000 21.1011 + 78.2500 21.1103 + 78.3000 21.1204 + 78.3500 21.1313 + 78.4000 21.1432 + 78.4500 21.1560 + 78.5000 21.1698 + 78.5500 21.1847 + 78.6000 21.2005 + 78.6500 21.2175 + 78.7000 21.2357 + 78.7500 21.2550 + 78.8000 21.2757 + 78.8500 21.2977 + 78.9000 21.3212 + 78.9500 21.3462 + 79.0000 21.3728 + 79.0500 21.4012 + 79.1000 21.4314 + 79.1500 21.4637 + 79.2000 21.4982 + 79.2500 21.5350 + 79.3000 21.5743 + 79.3500 21.6164 + 79.4000 21.6614 + 79.4500 21.7098 + 79.5000 21.7618 + 79.5500 21.8177 + 79.6000 21.8779 + 79.6500 21.9430 + 79.7000 22.0135 + 79.7500 22.0900 + 79.8000 22.1732 + 79.8500 22.2639 + 79.9000 22.3631 + 79.9500 22.4720 + 80.0000 22.5920 + 80.0500 22.7245 + 80.1000 22.8717 + 80.1500 23.0358 + 80.2000 23.2196 + 80.2500 23.4266 + 80.3000 23.6610 + 80.3500 23.9282 + 80.4000 24.2348 + 80.4500 24.5893 + 80.5000 25.0028 + 80.5500 25.4905 + 80.6000 26.0766 + 80.6500 26.8060 + 80.7000 27.7809 + 80.7500 29.2489 + 80.8000 31.7989 + 80.8500 36.7191 + 80.9000 46.4981 + 80.9500 65.2828 + 81.0000 98.7732 + 81.0500 153.2399 + 81.1000 231.4011 + 81.1500 330.4732 + 81.2000 438.6680 + 81.2500 534.8599 + 81.3000 593.6719 + 81.3500 595.7720 + 81.4000 540.4263 + 81.4500 446.0697 + 81.5000 338.0718 + 81.5500 237.9261 + 81.6000 158.3102 + 81.6500 102.7560 + 81.7000 68.1969 + 81.7500 48.7602 + 81.8000 38.6719 + 81.8500 33.6687 + 81.9000 31.1634 + 81.9500 29.8048 + 82.0000 28.9712 + 82.0500 28.4003 + 82.1000 27.9848 + 82.1500 27.6782 + 82.2000 27.4564 + 82.2500 27.3049 + 82.3000 27.2135 + 82.3500 27.1749 + 82.4000 27.1836 + 82.4500 27.2360 + 82.5000 27.3296 + 82.5500 27.4628 + 82.6000 27.6351 + 82.6500 27.8469 + 82.7000 28.0991 + 82.7500 28.3937 + 82.8000 28.7332 + 82.8500 29.1212 + 82.9000 29.5621 + 82.9500 30.0613 + 83.0000 30.6256 + 83.0500 31.2630 + 83.1000 31.9837 + 83.1500 32.7996 + 83.2000 33.7254 + 83.2500 34.7790 + 83.3000 35.9823 + 83.3500 37.3629 + 83.4000 38.9542 + 83.4500 40.7995 + 83.5000 42.9528 + 83.5500 45.4844 + 83.6000 48.4916 + 83.6500 52.1195 + 83.7000 56.6341 + 83.7500 62.6115 + 83.8000 71.4359 + 83.8500 86.4204 + 83.9000 114.9003 + 83.9500 171.4128 + 84.0000 280.9821 + 84.0500 479.1216 + 84.1000 806.0579 + 84.1500 1289.5646 + 84.2000 1921.6733 + 84.2500 2637.4226 + 84.3000 3310.7351 + 84.3500 3776.6721 + 84.4000 3889.1963 + 84.4500 3608.2214 + 84.5000 3030.1050 + 84.5500 2319.3066 + 84.6000 1628.2560 + 84.6500 1057.2388 + 84.7000 644.2310 + 84.7500 378.5686 + 84.8000 224.3755 + 84.8500 142.0156 + 84.9000 100.2371 + 84.9500 78.9813 + 85.0000 67.3199 + 85.0500 60.0172 + 85.1000 54.8000 + 85.1500 50.7320 + 85.2000 47.4100 + 85.2500 44.6357 + 85.3000 42.2895 + 85.3500 40.2875 + 85.4000 38.5672 + 85.4500 37.0795 + 85.5000 35.7858 + 85.5500 34.6554 + 85.6000 33.6629 + 85.6500 32.7884 + 85.7000 32.0149 + 85.7500 31.3289 + 85.8000 30.7190 + 85.8500 30.1756 + 85.9000 29.6909 + 85.9500 29.2581 + 86.0000 28.8717 + 86.0500 28.5269 + 86.1000 28.2198 + 86.1500 27.9472 + 86.2000 27.7061 + 86.2500 27.4945 + 86.3000 27.3106 + 86.3500 27.1532 + 86.4000 27.0213 + 86.4500 26.9147 + 86.5000 26.8334 + 86.5500 26.7783 + 86.6000 26.7508 + 86.6500 26.7536 + 86.7000 26.7913 + 86.7500 26.8733 + 86.8000 27.0214 + 86.8500 27.2888 + 86.9000 27.8013 + 86.9500 28.8343 + 87.0000 31.1077 + 87.0500 35.1433 + 87.1000 42.3764 + 87.1500 54.1527 + 87.2000 71.3328 + 87.2500 93.4707 + 87.3000 118.1535 + 87.3500 140.9396 + 87.4000 156.1562 + 87.4500 159.0092 + 87.5000 148.4967 + 87.5500 128.1914 + 87.6000 103.7355 + 87.6500 80.2419 + 87.7000 60.9801 + 87.7500 47.1441 + 87.8000 38.3088 + 87.8500 33.2346 + 87.9000 30.5846 + 87.9500 29.3078 + 88.0000 28.7341 + 88.0500 28.4979 + 88.1000 28.4240 + 88.1500 28.4369 + 88.2000 28.5059 + 88.2500 28.6184 + 88.3000 28.7689 + 88.3500 28.9548 + 88.4000 29.1752 + 88.4500 29.4297 + 88.5000 29.7190 + 88.5500 30.0442 + 88.6000 30.4073 + 88.6500 30.8107 + 88.7000 31.2576 + 88.7500 31.7518 + 88.8000 32.2976 + 88.8500 32.9007 + 88.9000 33.5674 + 88.9500 34.3052 + 89.0000 35.1231 + 89.0500 36.0314 + 89.1000 37.0429 + 89.1500 38.1720 + 89.2000 39.4369 + 89.2500 40.8586 + 89.3000 42.4628 + 89.3500 44.2813 + 89.4000 46.3518 + 89.4500 48.7226 + 89.5000 51.4525 + 89.5500 54.6155 + 89.6000 58.3078 + 89.6500 62.6541 + 89.7000 67.8334 + 89.7500 74.1322 + 89.8000 82.1089 + 89.8500 93.0358 + 89.9000 109.9379 + 89.9500 139.7871 + 90.0000 197.1939 + 90.0500 309.2948 + 90.1000 519.4438 + 90.1500 884.4768 + 90.2000 1460.3242 + 90.2500 2273.0063 + 90.3000 3283.7947 + 90.3500 4366.0928 + 90.4000 5309.1890 + 90.4500 5865.5601 + 90.5000 5853.3486 + 90.5500 5277.0186 + 90.6000 4323.3608 + 90.6500 3240.5637 + 90.7000 2235.8789 + 90.7500 1432.6656 + 90.8000 866.3328 + 90.8500 508.7572 + 90.9000 303.7236 + 90.9500 194.6210 + 91.0000 138.8333 + 91.0500 109.8098 + 91.1000 93.3237 + 91.1500 82.6407 + 91.2000 74.8327 + 91.2500 68.6759 + 91.3000 63.6283 + 91.3500 59.4083 + 91.4000 55.8429 + 91.4500 52.8075 + 91.5000 50.2090 + 91.5500 47.9746 + 91.6000 46.0458 + 91.6500 44.3773 + 91.7000 42.9313 + 91.7500 41.6783 + 91.8000 40.5944 + 91.8500 39.6595 + 91.9000 38.8583 + 91.9500 38.1780 + 92.0000 37.6086 + 92.0500 37.1428 + 92.1000 36.7750 + 92.1500 36.5018 + 92.2000 36.3215 + 92.2500 36.2344 + 92.3000 36.2428 + 92.3500 36.3511 + 92.4000 36.5662 + 92.4500 36.8979 + 92.5000 37.3595 + 92.5500 37.9685 + 92.6000 38.7485 + 92.6500 39.7300 + 92.7000 40.9555 + 92.7500 42.4871 + 92.8000 44.4314 + 92.8500 47.0081 + 92.9000 50.7232 + 92.9500 56.7745 + 93.0000 67.8377 + 93.0500 89.3290 + 93.1000 130.9086 + 93.1500 207.2345 + 93.2000 336.4469 + 93.2500 534.5162 + 93.3000 805.6783 + 93.3500 1132.2295 + 93.4000 1468.5529 + 93.4500 1745.3170 + 93.5000 1886.5212 + 93.5500 1845.0427 + 93.6000 1635.3866 + 93.6500 1322.6855 + 93.7000 983.1868 + 93.7500 676.8361 + 93.8000 437.1873 + 93.8500 270.8917 + 93.9000 167.2146 + 93.9500 108.2257 + 94.0000 76.9224 + 94.0500 60.8366 + 94.1000 52.3481 + 94.1500 47.4339 + 94.2000 44.1971 + 94.2500 41.8164 + 94.3000 39.9443 + 94.3500 38.4231 + 94.4000 37.1704 + 94.4500 36.1332 + 94.5000 35.2743 + 94.5500 34.5658 + 94.6000 33.9856 + 94.6500 33.5171 + 94.7000 33.1473 + 94.7500 32.8661 + 94.8000 32.6660 + 94.8500 32.5415 + 94.9000 32.4889 + 94.9500 32.5061 + 95.0000 32.5923 + 95.0500 32.7484 + 95.1000 32.9763 + 95.1500 33.2797 + 95.2000 33.6637 + 95.2500 34.1352 + 95.3000 34.7031 + 95.3500 35.3788 + 95.4000 36.1765 + 95.4500 37.1143 + 95.5000 38.2143 + 95.5500 39.5044 + 95.6000 41.0202 + 95.6500 42.8061 + 95.7000 44.9210 + 95.7500 47.4429 + 95.8000 50.4870 + 95.8500 54.2533 + 95.9000 59.1497 + 95.9500 66.1187 + 96.0000 77.4515 + 96.0500 97.7772 + 96.1000 136.8216 + 96.1500 211.4323 + 96.2000 346.8510 + 96.2500 573.6592 + 96.3000 918.0681 + 96.3500 1386.0687 + 96.4000 1945.9869 + 96.4500 2520.0469 + 96.5000 2990.5217 + 96.5500 3229.3489 + 96.6000 3157.5593 + 96.6500 2800.0706 + 96.7000 2266.6702 + 96.7500 1686.2845 + 96.8000 1160.8308 + 96.8500 746.9929 + 96.9000 457.7791 + 96.9500 275.8068 + 97.0000 171.2446 + 97.0500 115.1662 + 97.1000 86.0423 + 97.1500 70.5498 + 97.2000 61.5258 + 97.2500 55.5518 + 97.3000 51.1236 + 97.3500 47.5972 + 97.4000 44.6830 + 97.4500 42.2272 + 97.5000 40.1341 + 97.5500 38.3351 + 97.6000 36.7774 + 97.6500 35.4205 + 97.7000 34.2312 + 97.7500 33.1836 + 97.8000 32.2564 + 97.8500 31.4319 + 97.9000 30.6959 + 97.9500 30.0364 + 98.0000 29.4435 + 98.0500 28.9091 + 98.1000 28.4259 + 98.1500 27.9881 + 98.2000 27.5907 + 98.2500 27.2295 + 98.3000 26.9008 + 98.3500 26.6016 + 98.4000 26.3294 + 98.4500 26.0820 + 98.5000 25.8576 + 98.5500 25.6550 + 98.6000 25.4730 + 98.6500 25.3110 + 98.7000 25.1689 + 98.7500 25.0466 + 98.8000 24.9451 + 98.8500 24.8658 + 98.9000 24.8123 + 98.9500 24.7919 + 99.0000 24.8223 + 99.0500 25.0570 + 99.1000 25.3675 + 99.1500 26.0565 + 99.2000 27.4726 + 99.2500 30.1614 + 99.3000 34.8307 + 99.3500 42.1772 + 99.4000 52.5421 + 99.4500 65.5062 + 99.5000 79.5820 + 99.5500 92.2322 + 99.6000 100.3503 + 99.6500 101.4074 + 99.7000 95.0184 + 99.7500 83.2320 + 99.8000 69.1463 + 99.8500 55.5320 + 99.9000 43.8730 + 99.9500 35.5358 + 100.0000 30.0265 + 100.0500 26.7106 + 100.1000 24.8563 + 100.1500 23.8623 + 100.2000 23.3246 + 100.2500 23.0112 + 100.3000 22.8050 + 100.3500 22.6519 + 100.4000 22.5285 + 100.4500 22.4245 + 100.5000 22.3348 + 100.5500 22.2566 + 100.6000 22.1876 + 100.6500 22.1266 + 100.7000 22.0721 + 100.7500 22.0234 + 100.8000 21.9796 + 100.8500 21.9402 + 100.9000 21.9046 + 100.9500 21.8723 + 101.0000 21.8432 + 101.0500 21.8167 + 101.1000 21.7928 + 101.1500 21.7712 + 101.2000 21.7517 + 101.2500 21.7342 + 101.3000 21.7186 + 101.3500 21.7046 + 101.4000 21.6924 + 101.4500 21.6816 + 101.5000 21.6724 + 101.5500 21.6646 + 101.6000 21.6582 + 101.6500 21.6531 + 101.7000 21.6493 + 101.7500 21.6468 + 101.8000 21.6455 + 101.8500 21.6456 + 101.9000 21.6468 + 101.9500 21.6493 + 102.0000 21.6529 + 102.0500 21.6579 + 102.1000 21.6640 + 102.1500 21.6859 + 102.2000 21.6947 + 102.2500 21.7048 + 102.3000 21.7163 + 102.3500 21.7291 + 102.4000 21.7433 + 102.4500 21.7589 + 102.5000 21.7760 + 102.5500 21.7946 + 102.6000 21.8148 + 102.6500 21.8367 + 102.7000 21.8603 + 102.7500 21.8857 + 102.8000 21.9129 + 102.8500 21.9422 + 102.9000 21.9735 + 102.9500 22.0070 + 103.0000 21.9368 + 103.0500 21.9762 + 103.1000 22.0181 + 103.1500 22.0628 + 103.2000 22.1105 + 103.2500 22.1613 + 103.3000 22.2154 + 103.3500 22.2731 + 103.4000 22.3346 + 103.4500 22.4003 + 103.5000 22.4705 + 103.5500 22.5455 + 103.6000 22.6257 + 103.6500 22.7116 + 103.7000 22.8037 + 103.7500 22.9025 + 103.8000 23.0086 + 103.8500 23.1228 + 103.9000 23.2458 + 103.9500 23.3785 + 104.0000 23.5220 + 104.0500 23.6773 + 104.1000 23.8458 + 104.1500 24.0289 + 104.2000 24.2285 + 104.2500 24.4464 + 104.3000 24.6849 + 104.3500 24.9468 + 104.4000 25.2350 + 104.4500 25.5533 + 104.5000 25.9060 + 104.5500 26.2979 + 104.6000 26.7354 + 104.6500 27.2256 + 104.7000 27.7774 + 104.7500 28.4013 + 104.8000 29.1104 + 104.8500 29.9210 + 104.9000 30.8531 + 104.9500 31.9324 + 105.0000 33.1920 + 105.0500 34.6774 + 105.1000 36.4594 + 105.1500 38.6646 + 105.2000 41.5612 + 105.2500 45.7516 + 105.3000 52.9668 + 105.3500 65.2182 + 105.4000 88.1161 + 105.4500 130.2932 + 105.5000 203.8840 + 105.5500 322.6150 + 105.6000 497.1157 + 105.6500 727.6741 + 105.7000 997.5397 + 105.7500 1269.5514 + 105.8000 1489.6477 + 105.8500 1600.0642 + 105.9000 1565.5863 + 105.9500 1397.7278 + 106.0000 1146.1263 + 106.0500 869.3638 + 106.1000 614.4551 + 106.1500 408.9476 + 106.2000 261.2967 + 106.2500 165.2839 + 106.3000 108.0804 + 106.3500 76.2620 + 106.4000 59.2512 + 106.4500 50.0872 + 106.5000 44.8143 + 106.5500 41.4274 + 106.6000 38.9958 + 106.6500 37.1088 + 106.7000 35.5797 + 106.7500 34.3146 + 106.8000 33.2577 + 106.8500 32.3702 + 106.9000 31.6239 + 106.9500 30.9962 + 107.0000 30.4700 + 107.0500 30.0316 + 107.1000 29.6698 + 107.1500 29.3763 + 107.2000 29.1440 + 107.2500 28.9678 + 107.3000 28.8436 + 107.3500 28.7686 + 107.4000 28.7410 + 107.4500 28.7597 + 107.5000 28.8247 + 107.5500 28.9367 + 107.6000 29.0974 + 107.6500 29.3094 + 107.7000 29.5763 + 107.7500 29.9030 + 107.8000 30.2957 + 107.8500 30.7624 + 107.9000 31.3127 + 107.9500 31.9592 + 108.0000 32.7174 + 108.0500 33.6064 + 108.1000 34.6512 + 108.1500 35.8830 + 108.2000 37.3446 + 108.2500 39.0969 + 108.3000 41.2411 + 108.3500 43.9751 + 108.4000 47.7263 + 108.4500 53.4512 + 108.5000 63.1938 + 108.5500 80.9734 + 108.6000 113.8780 + 108.6500 172.7695 + 108.7000 271.6924 + 108.7500 424.6530 + 108.8000 639.5063 + 108.8500 910.4066 + 108.9000 1211.4700 + 108.9500 1496.0165 + 109.0000 1702.7145 + 109.0500 1774.0679 + 109.1000 1686.9918 + 109.1500 1469.4475 + 109.2000 1180.5348 + 109.2500 880.6739 + 109.3000 614.6836 + 109.3500 406.1129 + 109.4000 259.1873 + 109.4500 164.9999 + 109.5000 109.3297 + 109.5500 78.3779 + 109.6000 61.6514 + 109.6500 52.4321 + 109.7000 46.9452 + 109.7500 43.2942 + 109.8000 40.5981 + 109.8500 38.4609 + 109.9000 36.6998 + 109.9500 35.2183 + 110.0000 33.9579 + 110.0500 32.8772 + 110.1000 31.9447 + 110.1500 31.1361 + 110.2000 30.4317 + 110.2500 29.8159 + 110.3000 29.2760 + 110.3500 28.8012 + 110.4000 28.3832 + 110.4500 28.0147 + 110.5000 27.6898 + 110.5500 27.4037 + 110.6000 27.1521 + 110.6500 26.9318 + 110.7000 26.7399 + 110.7500 26.5739 + 110.8000 26.4322 + 110.8500 26.3131 + 110.9000 26.2154 + 110.9500 26.1385 + 111.0000 26.0818 + 111.0500 26.0451 + 111.1000 26.0287 + 111.1500 26.0332 + 111.2000 26.0594 + 111.2500 26.1090 + 111.3000 26.1840 + 111.3500 26.2874 + 111.4000 26.4229 + 111.4500 26.5962 + 111.5000 26.8156 + 111.5500 27.0958 + 111.6000 27.4666 + 111.6500 27.9926 + 111.7000 28.8155 + 111.7500 30.5015 + 111.8000 33.0659 + 111.8500 37.7248 + 111.9000 45.8709 + 111.9500 59.2241 + 112.0000 79.3893 + 112.0500 107.0953 + 112.1000 141.3230 + 112.1500 178.6290 + 112.2000 213.1540 + 112.2500 237.4459 + 112.3000 244.7965 + 112.3500 232.9061 + 112.4000 205.4857 + 112.4500 169.7559 + 112.5000 132.9182 + 112.5500 100.2760 + 112.6000 74.6163 + 112.6500 56.4545 + 112.7000 44.7482 + 112.7500 37.8074 + 112.8000 33.9691 + 112.8500 31.9493 + 112.9000 30.9113 + 112.9500 30.3761 + 113.0000 30.0981 + 113.0500 29.9614 + 113.1000 29.9137 + 113.1500 29.9313 + 113.2000 30.0025 + 113.2500 30.1208 + 113.3000 30.2823 + 113.3500 30.4846 + 113.4000 30.7263 + 113.4500 31.0072 + 113.5000 31.3274 + 113.5500 31.6877 + 113.6000 32.0900 + 113.6500 32.5363 + 113.7000 33.0294 + 113.7500 33.5729 + 113.8000 34.1708 + 113.8500 34.8282 + 113.9000 35.5508 + 113.9500 36.3456 + 114.0000 37.2206 + 114.0500 38.1850 + 114.1000 39.2501 + 114.1500 40.4284 + 114.2000 41.7355 + 114.2500 43.1892 + 114.3000 44.8105 + 114.3500 46.6255 + 114.4000 48.6642 + 114.4500 50.9641 + 114.5000 53.5697 + 114.5500 56.5356 + 114.6000 59.9305 + 114.6500 63.8381 + 114.7000 68.3679 + 114.7500 73.6633 + 114.8000 79.9313 + 114.8500 87.5164 + 114.9000 97.0709 + 114.9500 109.9770 + 115.0000 129.2097 + 115.0500 160.9403 + 115.1000 217.0507 + 115.1500 318.1064 + 115.2000 495.6005 + 115.2500 790.5482 + 115.3000 1245.5764 + 115.3500 1889.3816 + 115.4000 2714.7546 + 115.4500 3660.8359 + 115.5000 4604.5752 + 115.5500 5371.7856 + 115.6000 5776.0117 + 115.6500 5697.3950 + 115.7000 5160.5767 + 115.7500 4316.7510 + 115.8000 3355.6006 + 115.8500 2437.1843 + 115.9000 1665.3851 + 115.9500 1082.5109 + 116.0000 682.0852 + 116.0500 429.0060 + 116.1000 279.6788 + 116.1500 195.6658 + 116.2000 148.9953 + 116.2500 122.1591 + 116.3000 105.3997 + 116.3500 93.7725 + 116.4000 84.9425 + 116.4500 77.8231 + 116.5000 71.8894 + 116.5500 66.8540 + 116.6000 62.5325 + 116.6500 58.7954 + 116.7000 55.5415 + 116.7500 52.6925 + 116.8000 50.1852 + 116.8500 47.9673 + 116.9000 45.9973 + 116.9500 44.2397 + 117.0000 42.6658 + 117.0500 41.2516 + 117.1000 39.9764 + 117.1500 38.8232 + 117.2000 37.7772 + 117.2500 36.8260 + 117.3000 35.9590 + 117.3500 35.1667 + 117.4000 34.4414 + 117.4500 33.7758 + 117.5000 33.1642 + 117.5500 32.6012 + 117.6000 32.0820 + 117.6500 31.6028 + 117.7000 31.1597 + 117.7500 30.7497 + 117.8000 30.3699 + 117.8500 30.0177 + 117.9000 29.6911 + 117.9500 29.3878 + 118.0000 29.1062 + 118.0500 28.8447 + 118.1000 28.6017 + 118.1500 28.3798 + 118.2000 28.1703 + 118.2500 27.9758 + 118.3000 27.7956 + 118.3500 27.6286 + 118.4000 27.4742 + 118.4500 27.3316 + 118.5000 27.2002 + 118.5500 27.0795 + 118.6000 26.9690 + 118.6500 26.8682 + 118.7000 26.7766 + 118.7500 26.6941 + 118.8000 26.6202 + 118.8500 26.5546 + 118.9000 26.4973 + 118.9500 26.4479 + 119.0000 26.4062 + 119.0500 26.2606 + 119.1000 26.2353 + 119.1500 26.2175 + 119.2000 26.2071 + 119.2500 26.2041 + 119.3000 26.2086 + 119.3500 26.2206 + 119.4000 26.2401 + 119.4500 26.2674 + 119.5000 26.3025 + 119.5500 26.3457 + 119.6000 26.3971 + 119.6500 26.4571 + 119.7000 26.5258 + 119.7500 26.6038 + 119.8000 26.6913 + 119.8500 26.7888 + 119.9000 26.8968 + 119.9500 27.0158 + 120.0000 27.1466 + 120.0500 27.2898 + 120.1000 27.4462 + 120.1500 27.6166 + 120.2000 27.8022 + 120.2500 28.0039 + 120.3000 28.2230 + 120.3500 28.4609 + 120.4000 28.7191 + 120.4500 28.9994 + 120.5000 29.3037 + 120.5500 29.6343 + 120.6000 29.9936 + 120.6500 30.3843 + 120.7000 30.8099 + 120.7500 31.2738 + 120.8000 31.7802 + 120.8500 32.3338 + 120.9000 32.9401 + 120.9500 33.6055 + 121.0000 34.3371 + 121.0500 35.1432 + 121.1000 36.0340 + 121.1500 37.0207 + 121.2000 38.1172 + 121.2500 39.3394 + 121.3000 40.7062 + 121.3500 42.2409 + 121.4000 43.9707 + 121.4500 45.9295 + 121.5000 48.1579 + 121.5500 50.7060 + 121.6000 53.6382 + 121.6500 57.0359 + 121.7000 61.0140 + 121.7500 65.7471 + 121.8000 71.5416 + 121.8500 79.0034 + 121.9000 89.3779 + 121.9500 105.2178 + 122.0000 131.4586 + 122.0500 176.9015 + 122.1000 255.7507 + 122.1500 388.1522 + 122.2000 598.5859 + 122.2500 910.3555 + 122.3000 1336.3193 + 122.3500 1867.9612 + 122.4000 2465.7100 + 122.4500 3056.4800 + 122.5000 3539.0876 + 122.5500 3805.0447 + 122.6000 3781.5366 + 122.6500 3475.4568 + 122.7000 2968.6294 + 122.7500 2370.6357 + 122.8000 1779.2118 + 122.8500 1262.2839 + 122.9000 854.2248 + 122.9500 559.4836 + 123.0000 362.8519 + 123.0500 240.3284 + 123.1000 167.8511 + 123.1500 126.1686 + 123.2000 101.9948 + 123.2500 87.2381 + 123.3000 77.4250 + 123.3500 70.2656 + 123.4000 64.6486 + 123.4500 60.0313 + 123.5000 56.1355 + 123.5500 52.7993 + 123.6000 49.9142 + 123.6500 47.4022 + 123.7000 45.2013 + 123.7500 43.2631 + 123.8000 41.5483 + 123.8500 40.0239 + 123.9000 38.6637 + 123.9500 37.4450 + 124.0000 36.3494 + 124.0500 35.3615 + 124.1000 34.4678 + 124.1500 33.6574 + 124.2000 32.9205 + 124.2500 32.2489 + 124.3000 31.6359 + 124.3500 31.0750 + 124.4000 30.5614 + 124.4500 30.0903 + 124.5000 29.6579 + 124.5500 29.2608 + 124.6000 28.8959 + 124.6500 28.5610 + 124.7000 28.2536 + 124.7500 27.9719 + 124.8000 27.7146 + 124.8500 27.4801 + 124.9000 27.2677 + 124.9500 27.0764 + 125.0000 26.9060 + 125.0500 26.7562 + 125.1000 26.6272 + 125.1500 26.5195 + 125.2000 26.4340 + 125.2500 26.3721 + 125.3000 26.3361 + 125.3500 26.3291 + 125.4000 26.3564 + 125.4500 26.4274 + 125.5000 26.5603 + 125.5500 26.7924 + 125.6000 27.1986 + 125.6500 27.9235 + 125.7000 29.2259 + 125.7500 31.5284 + 125.8000 35.4477 + 125.8500 41.7707 + 125.9000 51.3216 + 125.9500 64.3298 + 126.0000 81.6409 + 126.0500 102.0346 + 126.1000 123.6054 + 126.1500 143.3788 + 126.2000 157.7020 + 126.2500 163.1872 + 126.3000 158.3195 + 126.3500 144.4192 + 126.4000 124.7947 + 126.4500 103.1208 + 126.5000 82.4365 + 126.5500 64.7377 + 126.6000 50.9171 + 126.6500 40.9692 + 126.7000 34.3026 + 126.7500 30.0979 + 126.8000 27.5604 + 126.8500 26.0575 + 126.9000 25.1531 + 126.9500 24.5775 + 127.0000 24.1791 + 127.0500 23.8786 + 127.1000 23.6363 + 127.1500 23.4325 + 127.2000 23.2566 + 127.2500 23.1027 + 127.3000 22.9667 + 127.3500 22.8457 + 127.4000 22.7373 + 127.4500 22.6398 + 127.5000 22.5516 + 127.5500 22.4715 + 127.6000 22.3985 + 127.6500 22.3316 + 127.7000 22.2703 + 127.7500 22.2138 + 127.8000 22.1616 + 127.8500 22.1133 + 127.9000 22.0686 + 127.9500 22.0270 + 128.0000 21.9882 + 128.0500 21.9521 + 128.1000 21.9185 + 128.1500 21.8870 + 128.2000 21.8576 + 128.2500 21.8300 + 128.3000 21.8042 + 128.3500 21.7801 + 128.4000 21.7575 + 128.4500 21.7363 + 128.5000 21.7164 + 128.5500 21.6979 + 128.6000 21.6805 + 128.6500 21.6643 + 128.7000 21.6492 + 128.7500 21.6350 + 128.8000 21.6219 + 128.8500 21.6098 + 128.9000 21.5985 + 128.9500 21.5881 + 129.0000 21.5786 + 129.0500 21.5699 + 129.1000 21.5620 + 129.1500 21.5548 + 129.2000 21.5484 + 129.2500 21.5428 + 129.3000 21.5378 + 129.3500 21.5336 + 129.4000 21.5301 + 129.4500 21.5273 + 129.5000 21.5251 + 129.5500 21.5236 + 129.6000 21.5228 + 129.6500 21.5227 + 129.7000 21.5232 + 129.7500 21.5244 + 129.8000 21.5263 + 129.8500 21.5288 + 129.9000 21.5320 + 129.9500 21.5359 + 130.0000 21.5405 + 130.0500 21.5458 + 130.1000 21.5517 + 130.1500 21.5584 + 130.2000 21.5659 + 130.2500 21.5740 + 130.3000 21.5830 + 130.3500 21.5927 + 130.4000 21.6032 + 130.4500 21.6145 + 130.5000 21.6267 + 130.5500 21.6398 + 130.6000 21.6538 + 130.6500 21.6687 + 130.7000 21.6845 + 130.7500 21.7014 + 130.8000 21.7194 + 130.8500 21.7384 + 130.9000 21.7586 + 130.9500 21.7800 + 131.0000 21.8026 + 131.0500 21.8265 + 131.1000 21.8519 + 131.1500 21.8786 + 131.2000 21.9069 + 131.2500 21.9368 + 131.3000 21.9685 + 131.3500 22.0019 + 131.4000 22.0373 + 131.4500 22.0747 + 131.5000 22.1142 + 131.5500 22.1561 + 131.6000 22.2005 + 131.6500 22.2474 + 131.7000 22.2973 + 131.7500 22.3501 + 131.8000 22.4063 + 131.8500 22.4659 + 131.9000 22.5294 + 131.9500 22.5970 + 132.0000 22.6690 + 132.0500 22.7459 + 132.1000 22.8280 + 132.1500 22.9159 + 132.2000 23.0101 + 132.2500 23.1112 + 132.3000 23.2199 + 132.3500 23.3369 + 132.4000 23.4632 + 132.4500 23.5997 + 132.5000 23.7475 + 132.5500 23.9080 + 132.6000 24.0827 + 132.6500 24.2733 + 132.7000 24.4818 + 132.7500 24.7104 + 132.8000 24.9621 + 132.8500 25.2401 + 132.9000 25.5480 + 132.9500 25.8904 + 133.0000 26.2725 + 133.0500 26.7012 + 133.1000 27.1843 + 133.1500 27.7315 + 133.2000 28.3557 + 133.2500 29.0742 + 133.3000 29.9137 + 133.3500 30.9182 + 133.4000 31.8959 + 133.4500 33.5445 + 133.5000 35.8725 + 133.5500 39.3956 + 133.6000 44.9907 + 133.6500 54.0473 + 133.7000 68.5761 + 133.7500 91.1765 + 133.8000 124.7974 + 133.8500 172.0994 + 133.9000 234.5695 + 133.9500 311.4611 + 134.0000 398.8615 + 134.0500 489.3489 + 134.1000 572.0252 + 134.1500 633.7772 + 134.2000 662.2105 + 134.2500 650.6696 + 134.3000 601.9482 + 134.3500 526.6481 + 134.4000 438.0787 + 134.4500 348.2933 + 134.5000 266.3137 + 134.5500 197.4901 + 134.6000 143.8490 + 134.6500 104.7320 + 134.7000 77.8526 + 134.7500 60.3012 + 134.8000 49.2691 + 134.8500 42.4818 + 134.9000 38.2923 + 134.9500 35.6216 + 135.0000 33.8185 + 135.0500 32.5137 + 135.1000 31.5096 + 135.1500 30.7014 + 135.2000 30.0326 + 135.2500 29.4713 + 135.3000 28.9966 + 135.3500 28.5945 + 135.4000 28.2544 + 135.4500 27.9679 + 135.5000 27.7282 + 135.5500 27.5297 + 135.6000 27.3680 + 135.6500 27.2393 + 135.7000 27.1406 + 135.7500 27.0695 + 135.8000 27.0238 + 135.8500 27.0020 + 135.9000 27.0028 + 135.9500 27.0253 + 136.0000 27.0687 + 136.0500 27.1325 + 136.1000 27.2165 + 136.1500 27.3207 + 136.2000 27.4453 + 136.2500 27.5905 + 136.3000 27.7570 + 136.3500 27.9455 + 136.4000 28.1570 + 136.4500 28.3927 + 136.5000 28.6538 + 136.5500 28.9423 + 136.6000 29.2601 + 136.6500 29.6093 + 136.7000 29.9927 + 136.7500 30.4132 + 136.8000 30.8745 + 136.8500 31.3804 + 136.9000 31.9358 + 136.9500 32.5459 + 137.0000 33.2167 + 137.0500 33.9558 + 137.1000 34.7715 + 137.1500 35.6734 + 137.2000 36.6731 + 137.2500 37.7837 + 137.3000 39.0217 + 137.3500 40.4059 + 137.4000 41.9588 + 137.4500 43.7082 + 137.5000 45.6877 + 137.5500 47.9425 + 137.6000 50.5327 + 137.6500 53.5484 + 137.7000 57.1371 + 137.7500 61.5548 + 137.8000 67.2706 + 137.8500 75.1256 + 137.9000 86.5955 + 137.9500 104.1421 + 138.0000 131.6089 + 138.0500 174.6036 + 138.1000 240.5324 + 138.1500 338.1808 + 138.2000 476.4785 + 138.2500 662.3423 + 138.3000 898.1772 + 138.3500 1178.7104 + 138.4000 1489.0452 + 138.4500 1803.7666 + 138.5000 2087.7422 + 138.5500 2300.0420 + 138.6000 2402.1152 + 138.6500 2372.4587 + 138.7000 2217.5454 + 138.7500 1968.3562 + 138.8000 1665.8689 + 138.8500 1349.2795 + 138.9000 1049.6167 + 138.9500 787.6341 + 139.0000 573.8102 + 139.0500 409.5863 + 139.1000 290.3079 + 139.1500 207.8216 + 139.2000 153.0538 + 139.2500 117.7346 + 139.3000 95.2198 + 139.3500 80.7316 + 139.4000 71.0823 + 139.4500 64.2953 + 139.5000 59.2149 + 139.5500 55.1883 + 139.6000 51.8590 + 139.6500 49.0271 + 139.7000 46.5754 + 139.7500 44.4295 + 139.8000 42.5359 + 139.8500 40.8561 + 139.9000 39.3591 + 139.9500 38.0194 + 140.0000 36.8165 diff --git a/tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/desired/srtio3-pnma-pattern_Andrew-ifort.y b/tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/desired/srtio3-pnma-pattern_Andrew-ifort.y new file mode 100644 index 0000000..0ffd11e --- /dev/null +++ b/tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/desired/srtio3-pnma-pattern_Andrew-ifort.y @@ -0,0 +1,2781 @@ +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0000 +20.0002 +20.0002 +20.0002 +20.0002 +20.0002 +20.0002 +20.0002 +20.0002 +20.0002 +20.0002 +20.0002 +20.0002 +20.0002 +20.0002 +20.0002 +20.0002 +20.0002 +20.0002 +20.0002 +20.0002 +20.0002 +20.0002 +20.0002 +20.0003 +20.0003 +20.0003 +20.0003 +20.0003 +20.0003 +20.0003 +20.0003 +20.0003 +20.0003 +20.0003 +20.0003 +20.0003 +20.0003 +20.0003 +20.0003 +20.0003 +20.0003 +20.0003 +20.0003 +20.0003 +20.0003 +20.0003 +20.0003 +20.0003 +20.0004 +20.0004 +20.0004 +20.0004 +20.0004 +20.0004 +20.0004 +20.0004 +20.0004 +20.0004 +20.0004 +20.0004 +20.0004 +20.0004 +20.0004 +20.0005 +20.0005 +20.0005 +20.0005 +20.0005 +20.0005 +20.0005 +20.0005 +20.0005 +20.0005 +20.0005 +20.0005 +20.0006 +20.0006 +20.0006 +20.0006 +20.0006 +20.0006 +20.0006 +20.0006 +20.0007 +20.0007 +20.0007 +20.0007 +20.0007 +20.0007 +20.0007 +20.0008 +20.0008 +20.0008 +20.0008 +20.0008 +20.0008 +20.0009 +20.0009 +20.0009 +20.0009 +20.0010 +20.0010 +20.0010 +20.0010 +20.0011 +20.0011 +20.0011 +20.0011 +20.0012 +20.0012 +20.0012 +20.0013 +20.0013 +20.0013 +20.0014 +20.0014 +20.0015 +20.0015 +20.0016 +20.0016 +20.0017 +20.0017 +20.0018 +20.0018 +20.0019 +20.0020 +20.0020 +20.0021 +20.0022 +20.0023 +20.0024 +20.0025 +20.0026 +20.0027 +20.0028 +20.0029 +20.0030 +20.0032 +20.0033 +20.0035 +20.0036 +20.0038 +20.0040 +20.0042 +20.0045 +20.0047 +20.0050 +20.0053 +20.0056 +20.0059 +20.0063 +20.0067 +20.0072 +20.0077 +20.0082 +20.0088 +20.0095 +20.0103 +20.0112 +20.0122 +20.0133 +20.0146 +20.0161 +20.0178 +20.0198 +20.0222 +20.0250 +20.0284 +20.0327 +20.0385 +20.0475 +20.0638 +20.0973 +20.1673 +20.3080 +20.5682 +21.0011 +21.6394 +22.4612 +23.3628 +24.1621 +24.6421 +24.6433 +24.1651 +23.3667 +22.4651 +21.6427 +21.0034 +20.5697 +20.3089 +20.1677 +20.0975 +20.0639 +20.0475 +20.0385 +20.0327 +20.0284 +20.0250 +20.0222 +20.0198 +20.0178 +20.0161 +20.0146 +20.0133 +20.0122 +20.0112 +20.0103 +20.0095 +20.0089 +20.0082 +20.0077 +20.0072 +20.0067 +20.0063 +20.0059 +20.0056 +20.0053 +20.0050 +20.0047 +20.0045 +20.0042 +20.0040 +20.0038 +20.0036 +20.0035 +20.0033 +20.0032 +20.0030 +20.0057 +20.0056 +20.0055 +20.0054 +20.0054 +20.0053 +20.0053 +20.0052 +20.0052 +20.0051 +20.0051 +20.0051 +20.0050 +20.0050 +20.0050 +20.0050 +20.0050 +20.0049 +20.0049 +20.0049 +20.0049 +20.0049 +20.0049 +20.0049 +20.0050 +20.0050 +20.0050 +20.0050 +20.0050 +20.0050 +20.0051 +20.0051 +20.0051 +20.0051 +20.0052 +20.0052 +20.0052 +20.0053 +20.0053 +20.0054 +20.0054 +20.0055 +20.0055 +20.0056 +20.0056 +20.0057 +20.0057 +20.0058 +20.0058 +20.0059 +20.0060 +20.0060 +20.0061 +20.0062 +20.0063 +20.0063 +20.0064 +20.0065 +20.0066 +20.0067 +20.0068 +20.0069 +20.0069 +20.0070 +20.0071 +20.0073 +20.0074 +20.0075 +20.0076 +20.0077 +20.0078 +20.0080 +20.0081 +20.0082 +20.0084 +20.0085 +20.0086 +20.0088 +20.0090 +20.0091 +20.0093 +20.0095 +20.0096 +20.0098 +20.0100 +20.0102 +20.0104 +20.0106 +20.0108 +20.0111 +20.0113 +20.0115 +20.0118 +20.0120 +20.0123 +20.0126 +20.0128 +20.0131 +20.0134 +20.0138 +20.0141 +20.0144 +20.0148 +20.0152 +20.0155 +20.0159 +20.0164 +20.0168 +20.0172 +20.0177 +20.0182 +20.0187 +20.0192 +20.0198 +20.0204 +20.0210 +20.0216 +20.0223 +20.0230 +20.0237 +20.0245 +20.0253 +20.0261 +20.0270 +20.0280 +20.0290 +20.0300 +20.0311 +20.0323 +20.0335 +20.0348 +20.0362 +20.0377 +20.0392 +20.0409 +20.0425 +20.0444 +20.0464 +20.0485 +20.0508 +20.0533 +20.0560 +20.0589 +20.0620 +20.0653 +20.0689 +20.0729 +20.0771 +20.0818 +20.0869 +20.0925 +20.0986 +20.1054 +20.1129 +20.1212 +20.1305 +20.1408 +20.1525 +20.1656 +20.1805 +20.1974 +20.2168 +20.2392 +20.2653 +20.2957 +20.3316 +20.3746 +20.4270 +20.4940 +20.5875 +20.7390 +21.0250 +21.6160 +22.8431 +25.2508 +29.5657 +36.4896 +46.2927 +58.3347 +70.7881 +80.8461 +85.5475 +83.2492 +74.7772 +62.8169 +50.3609 +39.6346 +31.6866 +26.5176 +23.5244 +21.9538 +21.1862 +20.8186 +20.6319 +20.5231 +20.4488 +20.3920 +20.3461 +20.3079 +20.2756 +20.2481 +20.2245 +20.2041 +20.1864 +20.1708 +20.1571 +20.1450 +20.1342 +20.1245 +20.1159 +20.1081 +20.1011 +20.0948 +20.0890 +20.0837 +20.0789 +20.0745 +20.0705 +20.0667 +20.0633 +20.0601 +20.0572 +20.0545 +20.0519 +20.0495 +20.0473 +20.0453 +20.0433 +20.0415 +20.0398 +20.0382 +20.0368 +20.0353 +20.0340 +20.0328 +20.0316 +20.0304 +20.0294 +20.0284 +20.0274 +20.0265 +20.0256 +20.0248 +20.0240 +20.0233 +20.0226 +20.0219 +20.0213 +20.0207 +20.0201 +20.0195 +20.0190 +20.0185 +20.0180 +20.0175 +20.0170 +20.0166 +20.0162 +20.0158 +20.0154 +20.0150 +20.0147 +20.0143 +20.0140 +20.0137 +20.0134 +20.0131 +20.0128 +20.0125 +20.0123 +20.0120 +20.0118 +20.0115 +20.0113 +20.0111 +20.0109 +20.0107 +20.0105 +20.0103 +20.0101 +20.0099 +20.0098 +20.0096 +20.0094 +20.0093 +20.0091 +20.0090 +20.0089 +20.0087 +20.0086 +20.0085 +20.0084 +20.0083 +20.0081 +20.0080 +20.0079 +20.0079 +20.0078 +20.0077 +20.0076 +20.0075 +20.0075 +20.0074 +20.0073 +20.0073 +20.0072 +20.0072 +20.0071 +20.0071 +20.0071 +20.0070 +20.0070 +20.0070 +20.0070 +20.0070 +20.0070 +20.0070 +20.0070 +20.0070 +20.0071 +20.0071 +20.0071 +20.0072 +20.0073 +20.0074 +20.0075 +20.0076 +20.0077 +20.0079 +20.0080 +20.0082 +20.0084 +20.0087 +20.0090 +20.0093 +20.0096 +20.0130 +20.0135 +20.0141 +20.0147 +20.0154 +20.0163 +20.0173 +20.0184 +20.0198 +20.0214 +20.0233 +20.0256 +20.0285 +20.0326 +20.0392 +20.0516 +20.0769 +20.1292 +20.2317 +20.4155 +20.7107 +21.1296 +21.6454 +22.1810 +22.6164 +22.8238 +22.7306 +22.3676 +21.8554 +21.3199 +20.8574 +20.5138 +20.2896 +20.1593 +20.0908 +20.0571 +20.0410 +20.0328 +20.0280 +20.0247 +20.0223 +20.0203 +20.0187 +20.0173 +20.0161 +20.0152 +20.0143 +20.0136 +20.0130 +20.0125 +20.0120 +20.0116 +20.0113 +20.0110 +20.0107 +20.0105 +20.0103 +20.0102 +20.0100 +20.0099 +20.0098 +20.0098 +20.0097 +20.0097 +20.0096 +20.0096 +20.0096 +20.0096 +20.0097 +20.0097 +20.0097 +20.0098 +20.0099 +20.0099 +20.0100 +20.0101 +20.0102 +20.0103 +20.0104 +20.0105 +20.0107 +20.0108 +20.0110 +20.0111 +20.0113 +20.0114 +20.0116 +20.0118 +20.0120 +20.0122 +20.0124 +20.0126 +20.0129 +20.0131 +20.0134 +20.0136 +20.0139 +20.0142 +20.0145 +20.0148 +20.0152 +20.0155 +20.0158 +20.0162 +20.0166 +20.0170 +20.0174 +20.0179 +20.0183 +20.0188 +20.0193 +20.0198 +20.0203 +20.0209 +20.0215 +20.0221 +20.0228 +20.0234 +20.0242 +20.0249 +20.0257 +20.0265 +20.0274 +20.0283 +20.0292 +20.0303 +20.0313 +20.0324 +20.0336 +20.0349 +20.0362 +20.0376 +20.0391 +20.0407 +20.0424 +20.0442 +20.0461 +20.0482 +20.0504 +20.0527 +20.0552 +20.0579 +20.0609 +20.0640 +20.0674 +20.0710 +20.0750 +20.0793 +20.0839 +20.0890 +20.0946 +20.1008 +20.1075 +20.1149 +20.1232 +20.1323 +20.1425 +20.1540 +20.1668 +20.1814 +20.1979 +20.2167 +20.2383 +20.2633 +20.2924 +20.3266 +20.3671 +20.4157 +20.4756 +20.5538 +20.6672 +20.8589 +21.2304 +21.9971 +23.5533 +26.5052 +31.5887 +39.3983 +49.9413 +62.2092 +74.0390 +82.4923 +84.8922 +80.3702 +70.5197 +58.2567 +46.3526 +36.6185 +29.7091 +25.3776 +22.9435 +21.6924 +21.0835 +20.7854 +20.6258 +20.5264 +20.4551 +20.3993 +20.3535 +20.3152 +20.2827 +20.2550 +20.2311 +20.2104 +20.1924 +20.1765 +20.1626 +20.1501 +20.1390 +20.1292 +20.1203 +20.1124 +20.1051 +20.0986 +20.0927 +20.0872 +20.0823 +20.0777 +20.0735 +20.0697 +20.0661 +20.0628 +20.0598 +20.0570 +20.0543 +20.0519 +20.0496 +20.0474 +20.0454 +20.0435 +20.0418 +20.0401 +20.0386 +20.0371 +20.0357 +20.0344 +20.0332 +20.0320 +20.0309 +20.0298 +20.0288 +20.0279 +20.0270 +20.0262 +20.0253 +20.0246 +20.0238 +20.0231 +20.0225 +20.0218 +20.0212 +20.0206 +20.0201 +20.0195 +20.0190 +20.0185 +20.0181 +20.0176 +20.0172 +20.0168 +20.0164 +20.0160 +20.0156 +20.0153 +20.0150 +20.0146 +20.0143 +20.0140 +20.0138 +20.0135 +20.0132 +20.0130 +20.0127 +20.0125 +20.0123 +20.0135 +20.0133 +20.0131 +20.0130 +20.0128 +20.0127 +20.0125 +20.0124 +20.0123 +20.0122 +20.0121 +20.0120 +20.0120 +20.0119 +20.0119 +20.0119 +20.0118 +20.0118 +20.0119 +20.0119 +20.0119 +20.0120 +20.0121 +20.0123 +20.0124 +20.0126 +20.0128 +20.0131 +20.0134 +20.0138 +20.0143 +20.0148 +20.0155 +20.0163 +20.0173 +20.0184 +20.0199 +20.0219 +20.0250 +20.0304 +20.0410 +20.0630 +20.1068 +20.1875 +20.3221 +20.5218 +20.7813 +21.0700 +21.3320 +21.4976 +21.5119 +21.3697 +21.1194 +20.8306 +20.5630 +20.3519 +20.2063 +20.1173 +20.0682 +20.0433 +20.0311 +20.0251 +20.0217 +20.0195 +20.0179 +20.0166 +20.0155 +20.0147 +20.0139 +20.0133 +20.0127 +20.0123 +20.0119 +20.0115 +20.0112 +20.0110 +20.0107 +20.0105 +20.0104 +20.0102 +20.0101 +20.0100 +20.0099 +20.0098 +20.0098 +20.0097 +20.0097 +20.0097 +20.0096 +20.0067 +20.0068 +20.0068 +20.0069 +20.0069 +20.0070 +20.0071 +20.0072 +20.0073 +20.0074 +20.0075 +20.0076 +20.0077 +20.0079 +20.0080 +20.0082 +20.0083 +20.0085 +20.0087 +20.0089 +20.0091 +20.0093 +20.0095 +20.0097 +20.0100 +20.0102 +20.0105 +20.0107 +20.0110 +20.0114 +20.0117 +20.0120 +20.0124 +20.0128 +20.0131 +20.0136 +20.0140 +20.0145 +20.0151 +20.0156 +20.0161 +20.0167 +20.0173 +20.0180 +20.0187 +20.0194 +20.0202 +20.0210 +20.0219 +20.0229 +20.0239 +20.0249 +20.0261 +20.0273 +20.0287 +20.0301 +20.0317 +20.0333 +20.0352 +20.0371 +20.0393 +20.0416 +20.0442 +20.0469 +20.0500 +20.0534 +20.0571 +20.0613 +20.0659 +20.0711 +20.0768 +20.0834 +20.0907 +20.0991 +20.1088 +20.1198 +20.1327 +20.1477 +20.1654 +20.1864 +20.2120 +20.2442 +20.2880 +20.3557 +20.4772 +20.7189 +21.2104 +22.1686 +23.8909 +26.6832 +30.7026 +35.7591 +41.1805 +45.8411 +48.4458 +48.1055 +44.9448 +40.0033 +34.5797 +29.7116 +25.9621 +23.4283 +21.9025 +21.0708 +20.6498 +20.4431 +20.3376 +20.2769 +20.2363 +20.2059 +20.1815 +20.1612 +20.1442 +20.1297 +20.1173 +20.1066 +20.0972 +20.0891 +20.0819 +20.0756 +20.0699 +20.0649 +20.0604 +20.0564 +20.0527 +20.0494 +20.0464 +20.0437 +20.0412 +20.0389 +20.0368 +20.0348 +20.0331 +20.0314 +20.0299 +20.0285 +20.0272 +20.0260 +20.0248 +20.0238 +20.0228 +20.0219 +20.0210 +20.0201 +20.0193 +20.0186 +20.0179 +20.0173 +20.0167 +20.0161 +20.0156 +20.0151 +20.0146 +20.0142 +20.0138 +20.0133 +20.0130 +20.0126 +20.0123 +20.0119 +20.0116 +20.0122 +20.0119 +20.0117 +20.0114 +20.0112 +20.0110 +20.0108 +20.0106 +20.0104 +20.0103 +20.0101 +20.0100 +20.0098 +20.0097 +20.0096 +20.0095 +20.0094 +20.0093 +20.0093 +20.0092 +20.0092 +20.0091 +20.0091 +20.0091 +20.0091 +20.0091 +20.0092 +20.0092 +20.0093 +20.0094 +20.0095 +20.0096 +20.0098 +20.0100 +20.0102 +20.0105 +20.0108 +20.0111 +20.0115 +20.0120 +20.0125 +20.0132 +20.0139 +20.0148 +20.0158 +20.0170 +20.0185 +20.0203 +20.0226 +20.0258 +20.0308 +20.0398 +20.0577 +20.0938 +20.1632 +20.2861 +20.4823 +20.7604 +21.1052 +21.4691 +21.7753 +21.9378 +21.9008 +21.6778 +21.3408 +20.9762 +20.6515 +20.4025 +20.2344 +20.1331 +20.0777 +20.0495 +20.0355 +20.0283 +20.0241 +20.0213 +20.0192 +20.0175 +20.0161 +20.0149 +20.0139 +20.0130 +20.0123 +20.0117 +20.0111 +20.0107 +20.0102 +20.0099 +20.0096 +20.0093 +20.0090 +20.0088 +20.0086 +20.0085 +20.0083 +20.0082 +20.0081 +20.0080 +20.0079 +20.0079 +20.0078 +20.0078 +20.0078 +20.0078 +20.0078 +20.0078 +20.0078 +20.0078 +20.0078 +20.0079 +20.0079 +20.0080 +20.0081 +20.0082 +20.0083 +20.0084 +20.0085 +20.0072 +20.0074 +20.0075 +20.0077 +20.0079 +20.0081 +20.0083 +20.0085 +20.0087 +20.0090 +20.0092 +20.0095 +20.0098 +20.0101 +20.0104 +20.0108 +20.0112 +20.0115 +20.0120 +20.0124 +20.0129 +20.0134 +20.0139 +20.0145 +20.0151 +20.0158 +20.0165 +20.0172 +20.0180 +20.0189 +20.0199 +20.0209 +20.0220 +20.0232 +20.0245 +20.0259 +20.0275 +20.0292 +20.0311 +20.0331 +20.0354 +20.0380 +20.0408 +20.0439 +20.0475 +20.0515 +20.0560 +20.0611 +20.0669 +20.0737 +20.0815 +20.0906 +20.1013 +20.1140 +20.1295 +20.1489 +20.1750 +20.2148 +20.2847 +20.4203 +20.6908 +21.2115 +22.1406 +23.6432 +25.8129 +28.5668 +31.5706 +34.2409 +35.8729 +35.9294 +34.3901 +31.7671 +28.7650 +25.9810 +23.7671 +22.2215 +21.2589 +20.7162 +20.4331 +20.2911 +20.2183 +20.1771 +20.1503 +20.1306 +20.1149 +20.1020 +20.0912 +20.0820 +20.0741 +20.0673 +20.0614 +20.0562 +20.0517 +20.0477 +20.0441 +20.0409 +20.0381 +20.0355 +20.0332 +20.0311 +20.0292 +20.0275 +20.0259 +20.0245 +20.0232 +20.0220 +20.0208 +20.0198 +20.0188 +20.0180 +20.0171 +20.0164 +20.0157 +20.0150 +20.0144 +20.0138 +20.0132 +20.0127 +20.0122 +20.0118 +20.0114 +20.0110 +20.0135 +20.0132 +20.0129 +20.0126 +20.0124 +20.0121 +20.0119 +20.0116 +20.0114 +20.0112 +20.0110 +20.0108 +20.0107 +20.0105 +20.0104 +20.0103 +20.0102 +20.0101 +20.0100 +20.0099 +20.0098 +20.0098 +20.0097 +20.0097 +20.0096 +20.0096 +20.0096 +20.0096 +20.0095 +20.0095 +20.0096 +20.0096 +20.0096 +20.0097 +20.0097 +20.0098 +20.0099 +20.0100 +20.0101 +20.0102 +20.0103 +20.0105 +20.0107 +20.0109 +20.0111 +20.0114 +20.0117 +20.0120 +20.0124 +20.0129 +20.0134 +20.0140 +20.0148 +20.0156 +20.0167 +20.0180 +20.0197 +20.0222 +20.0265 +20.0347 +20.0509 +20.0817 +20.1368 +20.2262 +20.3566 +20.5246 +20.7118 +20.8845 +20.9998 +21.0212 +20.9411 +20.7867 +20.6007 +20.4220 +20.2752 +20.1696 +20.1019 +20.0626 +20.0417 +20.0310 +20.0256 +20.0227 +20.0209 +20.0197 +20.0187 +20.0180 +20.0174 +20.0170 +20.0166 +20.0163 +20.0161 +20.0159 +20.0158 +20.0158 +20.0157 +20.0157 +20.0158 +20.0158 +20.0159 +20.0160 +20.0162 +20.0163 +20.0165 +20.0167 +20.0169 +20.0172 +20.0174 +20.0177 +20.0180 +20.0183 +20.0186 +20.0190 +20.0194 +20.0198 +20.0202 +20.0206 +20.0211 +20.0215 +20.0220 +20.0226 +20.0231 +20.0237 +20.0243 +20.0250 +20.0257 +20.0264 +20.0271 +20.0279 +20.0287 +20.0296 +20.0305 +20.0315 +20.0316 +20.0327 +20.0338 +20.0350 +20.0363 +20.0376 +20.0391 +20.0406 +20.0422 +20.0438 +20.0456 +20.0476 +20.0496 +20.0518 +20.0541 +20.0566 +20.0592 +20.0621 +20.0652 +20.0685 +20.0720 +20.0759 +20.0801 +20.0846 +20.0895 +20.0949 +20.1007 +20.1072 +20.1142 +20.1220 +20.1306 +20.1401 +20.1508 +20.1626 +20.1760 +20.1910 +20.2080 +20.2274 +20.2495 +20.2751 +20.3047 +20.3393 +20.3801 +20.4289 +20.4887 +20.5657 +20.6738 +20.8464 +21.1579 +21.7587 +22.9173 +25.0406 +28.6328 +34.1374 +41.6721 +50.7451 +60.0893 +67.7789 +71.7027 +70.5517 +64.7290 +56.0436 +46.6136 +38.1099 +31.4531 +26.8336 +23.9533 +22.3141 +21.4438 +20.9959 +20.7588 +20.6207 +20.5289 +20.4607 +20.4062 +20.3612 +20.3233 +20.2910 +20.2633 +20.2393 +20.2185 +20.2002 +20.1841 +20.1698 +20.1572 +20.1459 +20.1358 +20.1266 +20.1184 +20.1110 +20.1042 +20.0980 +20.0924 +20.0872 +20.0825 +20.0781 +20.0741 +20.0703 +20.0669 +20.0637 +20.0607 +20.0579 +20.0553 +20.0529 +20.0507 +20.0486 +20.0466 +20.0447 +20.0457 +20.0441 +20.0425 +20.0411 +20.0397 +20.0384 +20.0372 +20.0361 +20.0350 +20.0340 +20.0330 +20.0321 +20.0312 +20.0304 +20.0296 +20.0288 +20.0281 +20.0274 +20.0267 +20.0261 +20.0255 +20.0250 +20.0245 +20.0240 +20.0235 +20.0230 +20.0226 +20.0222 +20.0218 +20.0214 +20.0211 +20.0207 +20.0204 +20.0201 +20.0198 +20.0196 +20.0193 +20.0191 +20.0189 +20.0187 +20.0185 +20.0183 +20.0182 +20.0180 +20.0179 +20.0178 +20.0177 +20.0177 +20.0176 +20.0176 +20.0177 +20.0177 +20.0178 +20.0179 +20.0181 +20.0183 +20.0186 +20.0190 +20.0194 +20.0201 +20.0210 +20.0225 +20.0251 +20.0300 +20.0395 +20.0570 +20.0869 +20.1336 +20.1994 +20.2815 +20.3705 +20.4506 +20.5021 +20.5091 +20.4693 +20.3954 +20.3071 +20.2217 +20.1507 +20.0985 +20.0640 +20.0434 +20.0320 +20.0260 +20.0229 +20.0212 +20.0202 +20.0194 +20.0189 +20.0185 +20.0182 +20.0179 +20.0177 +20.0176 +20.0174 +20.0174 +20.0173 +20.0173 +20.0173 +20.0174 +20.0174 +20.0175 +20.0176 +20.0177 +20.0178 +20.0180 +20.0181 +20.0183 +20.0185 +20.0187 +20.0189 +20.0191 +20.0194 +20.0196 +20.0199 +20.0202 +20.0205 +20.0209 +20.0212 +20.0216 +20.0220 +20.0224 +20.0228 +20.0233 +20.0238 +20.0243 +20.0248 +20.0254 +20.0259 +20.0265 +20.0272 +20.0278 +20.0285 +20.0293 +20.0300 +20.0308 +20.0317 +20.0326 +20.0335 +20.0346 +20.0327 +20.0338 +20.0350 +20.0363 +20.0377 +20.0391 +20.0406 +20.0422 +20.0439 +20.0457 +20.0476 +20.0497 +20.0519 +20.0542 +20.0567 +20.0594 +20.0623 +20.0653 +20.0687 +20.0722 +20.0761 +20.0803 +20.0848 +20.0898 +20.0952 +20.1011 +20.1075 +20.1146 +20.1224 +20.1310 +20.1406 +20.1512 +20.1631 +20.1765 +20.1915 +20.2086 +20.2280 +20.2501 +20.2757 +20.3053 +20.3399 +20.3808 +20.4299 +20.4907 +20.5707 +20.6866 +20.8756 +21.2153 +21.8507 +23.0215 +25.0649 +28.3622 +33.2086 +39.6121 +47.1074 +54.6624 +60.7754 +63.8417 +62.8832 +58.2195 +51.2295 +43.5405 +36.4583 +30.7536 +26.6505 +23.9819 +22.3913 +21.5058 +21.0315 +20.7750 +20.6266 +20.5304 +20.4607 +20.4059 +20.3610 +20.3232 +20.2911 +20.2634 +20.2395 +20.2187 +20.2005 +20.1844 +20.1702 +20.1576 +20.1463 +20.1361 +20.1270 +20.1188 +20.1114 +20.1046 +20.0984 +20.0928 +20.0876 +20.0829 +20.0785 +20.0744 +20.0707 +20.0673 +20.0641 +20.0611 +20.0583 +20.0557 +20.0533 +20.0511 +20.0490 +20.0470 +20.0451 +20.0434 +20.0417 +20.0401 +20.0387 +20.0373 +20.0360 +20.0348 +20.0336 +20.0325 +20.0314 +20.0304 +20.0295 +20.0286 +20.0277 +20.0269 +20.0261 +20.0254 +20.0247 +20.0240 +20.0234 +20.0227 +20.0222 +20.0216 +20.0211 +20.0206 +20.0201 +20.0196 +20.0192 +20.0188 +20.0184 +20.0180 +20.0177 +20.0173 +20.0170 +20.0167 +20.0164 +20.0161 +20.0159 +20.0157 +20.0154 +20.0152 +20.0151 +20.0149 +20.0148 +20.0146 +20.0145 +20.0144 +20.0144 +20.0143 +20.0143 +20.0143 +20.0144 +20.0145 +20.0146 +20.0148 +20.0150 +20.0153 +20.0156 +20.0160 +20.0165 +20.0171 +20.0179 +20.0188 +20.0199 +20.0213 +20.0231 +20.0258 +20.0299 +20.0371 +20.0502 +20.0742 +20.1162 +20.1854 +20.2899 +20.4335 +20.6111 +20.8046 +20.9836 +21.1094 +21.1471 +21.0851 +20.9420 +20.7557 +20.5636 +20.3932 +20.2591 +20.1639 +20.1023 +20.0654 +20.0445 +20.0331 +20.0266 +20.0228 +20.0202 +20.0183 +20.0167 +20.0155 +20.0144 +20.0134 +20.0126 +20.0119 +20.0113 +20.0107 +20.0102 +20.0098 +20.0094 +20.0090 +20.0087 +20.0084 +20.0081 +20.0078 +20.0076 +20.0074 +20.0072 +20.0070 +20.0068 +20.0066 +20.0065 +20.0063 +20.0062 +20.0061 +20.0059 +20.0058 +20.0057 +20.0056 +20.0055 +20.0054 +20.0053 +20.0052 +20.0051 +20.0051 +20.0050 +20.0049 +20.0048 +20.0048 +20.0047 +20.0046 +20.0046 +20.0045 +20.0045 +20.0044 +20.0044 +20.0043 +20.0043 +20.0042 +20.0042 +20.0041 +20.0041 +20.0013 +20.0013 +20.0013 +20.0013 +20.0012 +20.0012 +20.0012 +20.0012 +20.0012 +20.0012 +20.0012 +20.0012 +20.0012 +20.0012 +20.0012 +20.0012 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0011 +20.0012 +20.0012 +20.0012 +20.0012 +20.0012 +20.0012 +20.0012 +20.0012 +20.0012 +20.0012 +20.0012 +20.0012 +20.0012 +20.0012 +20.0012 +20.0012 +20.0012 +20.0012 +20.0012 +20.0012 +20.0013 +20.0013 +20.0013 +20.0013 +20.0013 +20.0013 +20.0013 +20.0013 +20.0013 +20.0013 +20.0013 +20.0013 +20.0013 +20.0014 +20.0014 +20.0014 +20.0014 +20.0014 +20.0014 +20.0014 +20.0014 +20.0014 +20.0014 +20.0014 +20.0015 +20.0015 +20.0015 +20.0015 +20.0015 +20.0015 +20.0015 +20.0015 +20.0016 +20.0016 +20.0016 +20.0016 +20.0016 +20.0016 +20.0016 +20.0016 +20.0017 +20.0017 +20.0017 +20.0017 +20.0017 +20.0017 +20.0018 +20.0018 +20.0018 +20.0018 +20.0018 +20.0018 +20.0019 +20.0019 +20.0019 +20.0019 +20.0019 +20.0019 +20.0019 +20.0019 +20.0020 +20.0020 +20.0020 +20.0020 +20.0021 +20.0021 +20.0021 +20.0022 +20.0022 +20.0022 +20.0023 +20.0023 +20.0023 +20.0024 +20.0024 +20.0024 +20.0025 +20.0025 +20.0026 +20.0026 +20.0026 +20.0027 +20.0027 +20.0028 +20.0028 +20.0029 +20.0030 +20.0030 +20.0031 +20.0032 +20.0032 +20.0033 +20.0034 +20.0035 +20.0036 +20.0037 +20.0038 +20.0039 +20.0040 +20.0041 +20.0042 +20.0044 +20.0046 +20.0047 +20.0049 +20.0051 +20.0053 +20.0056 +20.0059 +20.0062 +20.0065 +20.0069 +20.0073 +20.0078 +20.0084 +20.0090 +20.0098 +20.0107 +20.0119 +20.0134 +20.0157 +20.0193 +20.0254 +20.0356 +20.0528 +20.0802 +20.1213 +20.1789 +20.2531 +20.3404 +20.4327 +20.5173 +20.5787 +20.6023 +20.5819 +20.5229 +20.4394 +20.3473 +20.2594 +20.1842 +20.1255 +20.0833 +20.0551 +20.0374 +20.0268 +20.0206 +20.0170 +20.0147 +20.0132 +20.0121 +20.0113 +20.0106 +20.0100 +20.0096 +20.0092 +20.0088 +20.0085 +20.0083 +20.0081 +20.0079 +20.0077 +20.0076 +20.0075 +20.0074 +20.0073 +20.0073 +20.0072 +20.0072 +20.0072 +20.0072 +20.0072 +20.0072 +20.0072 +20.0072 +20.0073 +20.0073 +20.0073 +20.0074 +20.0075 +20.0075 +20.0076 +20.0077 +20.0078 +20.0079 +20.0079 +20.0081 +20.0082 +20.0083 +20.0084 +20.0085 +20.0086 +20.0088 +20.0089 +20.0091 +20.0092 +20.0094 +20.0095 +20.0097 +20.0099 +20.0101 +20.0103 +20.0105 +20.0107 +20.0109 +20.0111 +20.0113 +20.0116 +20.0118 +20.0121 +20.0124 +20.0126 +20.0129 +20.0132 +20.0136 +20.0139 +20.0142 +20.0146 +20.0150 +20.0154 +20.0158 +20.0162 +20.0166 +20.0171 +20.0176 +20.0181 +20.0186 +20.0191 +20.0197 +20.0203 +20.0209 +20.0216 +20.0223 +20.0230 +20.0238 +20.0246 +20.0254 +20.0263 +20.0273 +20.0283 +20.0293 +20.0304 +20.0316 +20.0328 +20.0342 +20.0356 +20.0371 +20.0387 +20.0404 +20.0422 +20.0441 +20.0462 +20.0484 +20.0508 +20.0534 +20.0561 +20.0591 +20.0624 +20.0659 +20.0697 +20.0739 +20.0784 +20.0834 +20.0888 +20.0948 +20.1014 +20.1088 +20.1169 +20.1261 +20.1363 +20.1477 +20.1607 +20.1754 +20.1923 +20.2117 +20.2345 +20.2619 +20.2961 +20.3412 +20.4052 +20.5024 +20.6571 +20.9080 +21.3108 +21.9378 +22.8710 +24.1841 +25.9185 +28.0535 +30.4804 +32.9930 +35.2886 +37.0029 +37.7917 +37.4701 +36.1156 +34.0228 +31.5614 +29.0661 +26.7876 +24.8745 +23.3831 +22.2951 +21.5470 +21.0580 +20.7499 +20.5597 +20.4416 +20.3657 +20.3137 +20.2755 +20.2456 +20.2210 +20.2003 +20.1824 +20.1668 +20.1531 +20.1410 +20.1303 +20.1207 +20.1122 +20.1045 +20.0976 +20.0913 +20.0856 +20.0805 +20.0757 +20.0714 +20.0675 +20.0638 +20.0605 +20.0574 +20.0545 +20.0519 +20.0494 +20.0471 +20.0450 +20.0430 +20.0411 +20.0394 +20.0377 +20.0362 +20.0347 +20.0334 +20.0321 +20.0309 +20.0298 +20.0287 +20.0277 +20.0267 +20.0258 +20.0249 +20.0241 +20.0233 +20.0226 +20.0219 +20.0212 +20.0205 +20.0199 +20.0193 +20.0188 +20.0182 +20.0177 +20.0172 +20.0168 +20.0163 +20.0159 +20.0155 +20.0151 +20.0147 +20.0143 +20.0140 +20.0136 +20.0133 +20.0130 +20.0127 +20.0124 +20.0121 +20.0119 +20.0116 +20.0114 +20.0111 +20.0109 +20.0107 +20.0104 +20.0102 +20.0100 +20.0098 +20.0096 +20.0095 +20.0093 +20.0091 +20.0090 +20.0088 +20.0086 +20.0085 +20.0084 +20.0082 +20.0081 +20.0079 +20.0078 +20.0077 +20.0076 +20.0075 +20.0074 +20.0073 +20.0072 +20.0071 +20.0070 +20.0069 +20.0068 diff --git a/tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/test__powder_pattern_from_json.py b/tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/test__powder_pattern_from_json.py new file mode 100644 index 0000000..82c0567 --- /dev/null +++ b/tests/functional_tests/pyCFML/cfml_utilities/powder_pattern_from_json/test__powder_pattern_from_json.py @@ -0,0 +1,132 @@ +import argparse +import copy +import os +import numpy as np +from numpy.testing import assert_almost_equal + +#import cfml_utilities +#import pycrysfml +#from pycrysfml import crysfml08lib +from pycrysfml import cfml_utilities + + +STUDY_DICT_PM3M = { + "phases": [ + { + "SrTiO3": { + "_space_group_name_H-M_alt": "P m -3 m", + "_cell_length_a": 3.9, + "_cell_length_b": 3.9, + "_cell_length_c": 3.9, + "_cell_angle_alpha": 90, + "_cell_angle_beta": 90, + "_cell_angle_gamma": 90, + "_atom_site": [ + { + "_label": "Sr", + "_type_symbol": "Sr", + "_fract_x": 0.5, + "_fract_y": 0.5, + "_fract_z": 0.5, + "_occupancy": 1, + "_adp_type": "Biso", + "_B_iso_or_equiv": 0.40 + }, + { + "_label": "Ti", + "_type_symbol": "Ti", + "_fract_x": 0, + "_fract_y": 0, + "_fract_z": 0, + "_occupancy": 1, + "_adp_type": "Biso", + "_B_iso_or_equiv": 0.50 + }, + { + "_label": "O", + "_type_symbol": "O", + "_fract_x": 0.5, + "_fract_y": 0, + "_fract_z": 0, + "_occupancy": 1, + "_adp_type": "Biso", + "_B_iso_or_equiv": 0.65 + } + ] + } + } + ], + "experiments": [ + { + "NPD": { + "_diffrn_source": "nuclear reactor", + "_diffrn_radiation_probe": "neutron", + "_diffrn_radiation_wavelength": 1.27, + "_pd_instr_resolution_u": 0.02, + "_pd_instr_resolution_v": -0.02, + "_pd_instr_resolution_w": 0.12, + "_pd_instr_resolution_x": 0.0015, + "_pd_instr_resolution_y": 0, + "_pd_instr_reflex_asymmetry_p1": 0, + "_pd_instr_reflex_asymmetry_p2": 0, + "_pd_instr_reflex_asymmetry_p3": 0, + "_pd_instr_reflex_asymmetry_p4": 0, + "_pd_meas_2theta_offset": 0, + "_pd_meas_2theta_range_min": 1, + "_pd_meas_2theta_range_max": 140, + "_pd_meas_2theta_range_inc": 0.05 + } + } + ] +} + +# Help functions + +def path_to_desired(file_name:str): + return os.path.join(os.path.dirname(__file__), 'desired', file_name) + +def compute_pattern(study_dict:dict): + #_, y = crysfml08lib.f_powder_pattern_from_json(study_dict) # returns x and y arrays + _, y = cfml_utilities.powder_pattern_from_json(study_dict) # returns x and y arrays + return y + +# Tests + +# Workaround to set env variable CRYSFML_DB for all the tests below +# If running this with python instead of pytest, CRYSFML_DB is set automatically +# from the pycrysfml __init__.py, when importing pycrysfml +def test__crysfml_db_path(): + #os.environ['CRYSFML_DB'] = os.path.join(os.path.dirname(crysfml08lib.__file__), 'Databases') + os.environ['CRYSFML_DB'] = os.path.join(os.path.dirname(cfml_utilities.__file__), 'Databases') + actual = os.getenv('CRYSFML_DB', default='') + desired = os.environ['CRYSFML_DB'] + assert desired == actual + +def test__compute_pattern__SrTiO3_Pm3m(benchmark): + study_dict = copy.deepcopy(STUDY_DICT_PM3M) + norm = 120 + _, desired = np.loadtxt(path_to_desired('srtio3-pm3m-pattern_Nebil-ifort.xy'), unpack=True) + desired = desired - 20.0 # remove background + desired = np.roll(desired, -1) # compensate for a 1-element horizontal shift in y data between old Nebil windows build and Andrew current gfortran build + desired = desired / norm + actual = benchmark(compute_pattern, study_dict) + actual = actual / norm + assert_almost_equal(desired, actual, decimal=0, verbose=True) + +def test__compute_pattern__SrTiO3_Pnma(benchmark): + study_dict = copy.deepcopy(STUDY_DICT_PM3M) + study_dict['phases'][0]['SrTiO3']['_space_group_name_H-M_alt'] = 'P n m a' + norm = 0.65 + desired = np.loadtxt(path_to_desired('srtio3-pnma-pattern_Andrew-ifort.y'), unpack=True) + desired = desired - 20.0 # remove background + desired = desired / norm + actual = benchmark(compute_pattern, study_dict) + actual = actual / norm + assert_almost_equal(desired, actual, decimal=2, verbose=True) + +# Debug + +if __name__ == '__main__': + print(f":::::: os.environ['CRYSFML_DB']: {os.environ['CRYSFML_DB']}") + print(f':::::: os.getcwd(): {os.getcwd()}') + test__compute_pattern__SrTiO3_Pm3m() diff --git a/tests/functional_tests/pycfml/test__powder_mod.py b/tests/functional_tests/pycfml/test__powder_mod.py deleted file mode 100644 index e866ae0..0000000 --- a/tests/functional_tests/pycfml/test__powder_mod.py +++ /dev/null @@ -1,185 +0,0 @@ -import os -import sys -import math -import copy -import numpy as np -from deepdiff import DeepDiff -from numpy.testing import assert_almost_equal - -from pycrysfml08 import powder_mod - - -os.environ['CRYSFML_DB'] = os.path.join(os.path.dirname(powder_mod.__file__), 'Databases') # access to Databases/magnetic_data.txt - -STUDY_DICT = { - "phases": [ - { - "SrTiO3": { - "_space_group_name_H-M_alt": "P m -3 m", - #"_space_group_name_H-M_alt": "P n m a", - "_cell_length_a": 3.9, - "_cell_length_b": 3.9, - "_cell_length_c": 3.9, - "_cell_angle_alpha": 90, - "_cell_angle_beta": 90, - "_cell_angle_gamma": 90, - "_atom_site": [ - { - "_label": "Sr", - "_type_symbol": "Sr", - "_fract_x": 0.5, - "_fract_y": 0.5, - "_fract_z": 0.5, - "_occupancy": 1, - "_adp_type": "Biso", - "_B_iso_or_equiv": 0.40 - }, - { - "_label": "Ti", - "_type_symbol": "Ti", - "_fract_x": 0, - "_fract_y": 0, - "_fract_z": 0, - "_occupancy": 1, - "_adp_type": "Biso", - "_B_iso_or_equiv": 0.50 - }, - { - "_label": "O", - "_type_symbol": "O", - "_fract_x": 0.5, - "_fract_y": 0, - "_fract_z": 0, - "_occupancy": 1, - "_adp_type": "Biso", - "_B_iso_or_equiv": 0.65 - } - ] - } - } - ], - "experiments": [ - { - "NPD": { - "_diffrn_source": "nuclear reactor", - "_diffrn_radiation_probe": "neutron", - "_diffrn_radiation_wavelength": 1.27, - "_pd_instr_resolution_u": 0.02, - "_pd_instr_resolution_v": -0.02, - "_pd_instr_resolution_w": 0.12, - "_pd_instr_resolution_x": 0.0015, - "_pd_instr_resolution_y": 0, - "_pd_instr_reflex_asymmetry_p1": 0, - "_pd_instr_reflex_asymmetry_p2": 0, - "_pd_instr_reflex_asymmetry_p3": 0, - "_pd_instr_reflex_asymmetry_p4": 0, - "_pd_meas_2theta_offset": 0, - "_pd_meas_2theta_range_min": 1, - "_pd_meas_2theta_range_max": 140, - "_pd_meas_2theta_range_inc": 0.05, - "_phase": [ - { - "_label": "SrTiO3", - "_scale": 1 - } - ], - "_pd_background": [ - { - "_2theta": 1, - "_intensity": 20 - }, - { - "_2theta": 140, - "_intensity": 20 - } - ] - } - } - ] -} - -# Help functions - -def phase_name_by_idx(study_dict:dict, phase_idx:int=0): - return list(study_dict['phases'][phase_idx].keys())[phase_idx] - -def space_group_by_phase_idx(study_dict:dict, phase_idx:int=0): - phase_name = phase_name_by_idx(study_dict, phase_idx) - return study_dict['phases'][phase_idx][phase_name]['_space_group_name_H-M_alt'] - -def set_space_group_by_phase_idx(study_dict:dict, phase_idx:int, space_group:str): - phase_name = phase_name_by_idx(study_dict, phase_idx) - study_dict['phases'][phase_idx][phase_name]['_space_group_name_H-M_alt'] = space_group - -def clean_after_compute(study_dict:dict): - files = ['powder_pattern.dat', 'fort.77', f'{phase_name_by_idx(study_dict)}.powder'] - for f in files: - try: - print(f':: Deleting tmp file: {os.path.abspath(f)}') - os.remove(f) - except: - pass - -def compute_pattern(study_dict:dict): - res = powder_mod.simulation(study_dict) - clean_after_compute(study_dict) - return res - -# Tests - -def test__magnetic_data_txt_exists(): - fpath = os.path.abspath(os.path.join(os.path.dirname(powder_mod.__file__), 'Databases', 'magnetic_data.txt')) - assert os.path.isfile(fpath) == True - -def test__phase_name__SrTiO3(): - assert phase_name_by_idx(STUDY_DICT, phase_idx=0) == 'SrTiO3' - -def test__space_group__Pm3m(): - assert space_group_by_phase_idx(STUDY_DICT, phase_idx=0) == 'P m -3 m' - -def test__set_space_group__Pm3m(): - new_study_dict = copy.deepcopy(STUDY_DICT) - set_space_group_by_phase_idx(new_study_dict, phase_idx=0, space_group='P m -3 m') - assert DeepDiff(STUDY_DICT, new_study_dict) == {} - -def test__set_space_group__Pnma(): - new_study_dict = copy.deepcopy(STUDY_DICT) - set_space_group_by_phase_idx(new_study_dict, phase_idx=0, space_group='P n m a') - assert space_group_by_phase_idx(new_study_dict, phase_idx=0) == 'P n m a' - -def _test__compute_pattern__SrTiO3_Pm3m(): - _, desired = np.loadtxt(os.path.join(os.path.dirname(__file__), 'srtio3-pm3m-pattern_Nebil-ifort.xy'), unpack=True) - study_dict = copy.deepcopy(STUDY_DICT) - set_space_group_by_phase_idx(study_dict, phase_idx=0, space_group='P m -3 m') - pattern = compute_pattern(study_dict) - actual = pattern[1].astype(np.float64) - # compensate for a 1-element shift in y data between Nebil windows build and my gfortran build - desired = desired[1:] - actual = actual[:-1] - assert_almost_equal(desired, actual, decimal=0, verbose=True) - -def test__compute_pattern__SrTiO3_Pnma(): - desired = np.loadtxt(os.path.join(os.path.dirname(__file__), 'srtio3-pmmm-pattern_Andrew-ifort.xy'), unpack=True) - study_dict = copy.deepcopy(STUDY_DICT) - set_space_group_by_phase_idx(study_dict, phase_idx=0, space_group='P n m a') - pattern = compute_pattern(study_dict) - actual = pattern[1].astype(np.float64) - assert_almost_equal(desired, actual, decimal=2, verbose=True) - -# Debug - -if __name__ == '__main__': - #np.set_printoptions(precision=5, threshold = np.inf) - study_dict = copy.deepcopy(STUDY_DICT) - - study_dict["phases"][0]["SrTiO3"]["_space_group_name_H-M_alt"] = 'P n m a' - _, ycalc = powder_mod.simulation(study_dict) - print() - print(':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::') - print('::') - clean_after_compute(study_dict) - print('::') - print(f':: Y calculated (P n m a) array: {ycalc}',) - print(f':: Y calculated (P n m a) array size: {np.size(ycalc)}, min: {np.min(ycalc)}, max: {np.max(ycalc)}') - print('::') - print(':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::') diff --git a/tests/functional_tests/pycfml/test__powder_mod_2.py b/tests/functional_tests/pycfml/test__powder_mod_2.py deleted file mode 100644 index 305888b..0000000 --- a/tests/functional_tests/pycfml/test__powder_mod_2.py +++ /dev/null @@ -1,187 +0,0 @@ -import os -import sys -import math -import copy -import numpy as np -from deepdiff import DeepDiff -from numpy.testing import assert_almost_equal - -from pycrysfml08 import powder_mod_2 - - -os.environ['CRYSFML_DB'] = os.path.join(os.path.dirname(powder_mod_2.__file__), 'Databases') # access to Databases/magnetic_data.txt - -STUDY_DICT = { - "phases": [ - { - "SrTiO3": { - "_space_group_name_H-M_alt": "P m -3 m", - #"_space_group_name_H-M_alt": "P n m a", - "_cell_length_a": 3.9, - "_cell_length_b": 3.9, - "_cell_length_c": 3.9, - "_cell_angle_alpha": 90, - "_cell_angle_beta": 90, - "_cell_angle_gamma": 90, - "_atom_site": [ - { - "_label": "Sr", - "_type_symbol": "Sr", - "_fract_x": 0.5, - "_fract_y": 0.5, - "_fract_z": 0.5, - "_occupancy": 1, - "_adp_type": "Biso", - "_B_iso_or_equiv": 0.40 - }, - { - "_label": "Ti", - "_type_symbol": "Ti", - "_fract_x": 0, - "_fract_y": 0, - "_fract_z": 0, - "_occupancy": 1, - "_adp_type": "Biso", - "_B_iso_or_equiv": 0.50 - }, - { - "_label": "O", - "_type_symbol": "O", - "_fract_x": 0.5, - "_fract_y": 0, - "_fract_z": 0, - "_occupancy": 1, - "_adp_type": "Biso", - "_B_iso_or_equiv": 0.65 - } - ] - } - } - ], - "experiments": [ - { - "NPD": { - "_diffrn_source": "nuclear reactor", - "_diffrn_radiation_probe": "neutron", - "_diffrn_radiation_wavelength": 1.27, - "_pd_instr_resolution_u": 0.02, - "_pd_instr_resolution_v": -0.02, - "_pd_instr_resolution_w": 0.12, - "_pd_instr_resolution_x": 0.0015, - "_pd_instr_resolution_y": 0, - "_pd_instr_reflex_asymmetry_p1": 0, - "_pd_instr_reflex_asymmetry_p2": 0, - "_pd_instr_reflex_asymmetry_p3": 0, - "_pd_instr_reflex_asymmetry_p4": 0, - "_pd_meas_2theta_offset": 0, - "_pd_meas_2theta_range_min": 1, - "_pd_meas_2theta_range_max": 140, - "_pd_meas_2theta_range_inc": 0.05, - "_phase": [ - { - "_label": "SrTiO3", - "_scale": 1 - } - ], - "_pd_background": [ - { - "_2theta": 1, - "_intensity": 20 - }, - { - "_2theta": 140, - "_intensity": 20 - } - ] - } - } - ] -} - -# Help functions - -def phase_name_by_idx(study_dict:dict, phase_idx:int=0): - return list(study_dict['phases'][phase_idx].keys())[phase_idx] - -def space_group_by_phase_idx(study_dict:dict, phase_idx:int=0): - phase_name = phase_name_by_idx(study_dict, phase_idx) - return study_dict['phases'][phase_idx][phase_name]['_space_group_name_H-M_alt'] - -def set_space_group_by_phase_idx(study_dict:dict, phase_idx:int, space_group:str): - phase_name = phase_name_by_idx(study_dict, phase_idx) - study_dict['phases'][phase_idx][phase_name]['_space_group_name_H-M_alt'] = space_group - -def compute_pattern(study_dict:dict): - return powder_mod_2.simulation(study_dict) - -def clean_after_compute(study_dict:dict): - files = ['powder_pattern.dat', 'fort.77', f'{phase_name_by_idx(study_dict)}.powder'] - for f in files: - try: - os.remove(f) - except: - pass - -# Tests - -def test__magnetic_data_txt_exists(): - fpath = os.path.abspath(os.path.join(os.path.dirname(powder_mod_2.__file__), 'Databases', 'magnetic_data.txt')) - assert os.path.isfile(fpath) == True - -def test__phase_name__SrTiO3(): - assert phase_name_by_idx(STUDY_DICT, phase_idx=0) == 'SrTiO3' - -def test_space_group__Pm3m(): - assert space_group_by_phase_idx(STUDY_DICT, phase_idx=0) == 'P m -3 m' - -def test_set_space_group__Pm3m(): - new_study_dict = copy.deepcopy(STUDY_DICT) - set_space_group_by_phase_idx(new_study_dict, phase_idx=0, space_group='P m -3 m') - assert DeepDiff(STUDY_DICT, new_study_dict) == {} - -def test__set_space_group__Pnma(): - new_study_dict = copy.deepcopy(STUDY_DICT) - set_space_group_by_phase_idx(new_study_dict, phase_idx=0, space_group='P n m a') - assert space_group_by_phase_idx(new_study_dict, phase_idx=0) == 'P n m a' - -def _test__compute_pattern__SrTiO3_Pm3m(): - _, desired = np.loadtxt(os.path.join(os.path.dirname(__file__), 'srtio3-pm3m-pattern_Nebil-ifort.xy'), unpack=True) - desired = desired - 20.0 # remove background - study_dict = copy.deepcopy(STUDY_DICT) - set_space_group_by_phase_idx(study_dict, phase_idx=0, space_group='P m -3 m') - pattern = compute_pattern(study_dict) - actual = pattern[0].astype(np.float64) - # compensate for a 1-element shift in y data between Nebil windows build and my gfortran build - desired = desired[1:] - actual = actual[:-1] - assert_almost_equal(desired, actual, decimal=0, verbose=True) - -def test__compute_pattern__SrTiO3_Pnma(): - desired = np.loadtxt(os.path.join(os.path.dirname(__file__), 'srtio3-pmmm-pattern_Andrew-ifort.xy'), unpack=True) - desired = desired - 20.0 # remove background - study_dict = copy.deepcopy(STUDY_DICT) - set_space_group_by_phase_idx(study_dict, phase_idx=0, space_group='P n m a') - pattern = compute_pattern(study_dict) - actual = pattern[0].astype(np.float64) - assert_almost_equal(desired, actual, decimal=2, verbose=True) - -# Debug - -if __name__ == '__main__': - np.set_printoptions(precision=5, threshold = np.inf) - study_dict = copy.deepcopy(STUDY_DICT) - - #clean_after_compute(study_dict) - study_dict["phases"][0]["SrTiO3"]["_space_group_name_H-M_alt"] = 'P m -3 m' - ycalc = powder_mod_2.simulation(study_dict) - print('::::: Y calculated (P m -3 m):', ycalc) - - study_dict["phases"][0]["SrTiO3"]["_space_group_name_H-M_alt"] = 'P n m a' - ycalc = powder_mod_2.simulation(study_dict) - print('::::: Y calculated (P n m a):', ycalc) - #np.savetxt('ycalc.dat', ycalc, fmt='%12.6f') - - study_dict["phases"][0]["SrTiO3"]["_space_group_name_H-M_alt"] = 'I 4 3 2' - ycalc = powder_mod_2.simulation(study_dict) - print('::::: Y calculated (I 4 3 2):', ycalc) - #np.savetxt('ycalc.dat', ycalc, fmt='%12.6f') diff --git a/tests/unit_tests/pyCFML/_old/_test__cfml_metrics__debug.py b/tests/unit_tests/pyCFML/_old/_test__cfml_metrics__debug.py new file mode 100644 index 0000000..7e5ec04 --- /dev/null +++ b/tests/unit_tests/pyCFML/_old/_test__cfml_metrics__debug.py @@ -0,0 +1,66 @@ +import os +import sys +import copy +import math +import json +from deepdiff import DeepDiff +import numpy as np +from numpy.testing import assert_almost_equal + + +# Tests + +def test__get_u_from_b__crysfml08lib_f_get_u_from_b(): + try: + from pycrysfml import crysfml08lib + print('SUCCESS: from pycrysfml import crysfml08lib') + nd_b = np.array([1.5, 1.6, 1.7, 1.0, 1.1, 1.2], dtype='f') + desired = np.array([0.019, 0.0203, 0.0215, 0.0127, 0.0139, 0.0152], dtype='f') + code, message, actual = crysfml08lib.f_get_u_from_b(nd_b) + assert code == 0 + assert message == '' + assert_almost_equal(desired, actual, decimal=4, verbose=True) + except Exception as e: + print('::::: Run test__get_u_from_b__crysfml08lib_f_get_u_from_b() :::::') + print('ERROR:', e) + print() + return + +def test__get_u_from_b__crysfml08lib_get_u_from_b(): + try: + from pycrysfml import crysfml08lib + print('SUCCESS: from pycrysfml import crysfml08lib') + nd_b = np.array([1.5, 1.6, 1.7, 1.0, 1.1, 1.2], dtype='f') + desired = np.array([0.019, 0.0203, 0.0215, 0.0127, 0.0139, 0.0152], dtype='f') + code, message, actual = crysfml08lib.get_u_from_b(nd_b) + assert code == 0 + assert message == '' + assert_almost_equal(desired, actual, decimal=4, verbose=True) + except Exception as e: + print('::::: Run test__get_u_from_b__crysfml08lib_get_u_from_b() :::::') + print('ERROR:', e) + print() + return + +def test__get_u_from_b__cfml_metrics_get_u_from_b(): + try: + from pycrysfml import cfml_metrics + print('SUCCESS: from pycrysfml import cfml_metrics') + nd_b = np.array([1.5, 1.6, 1.7, 1.0, 1.1, 1.2], dtype='f') + desired = np.array([0.019, 0.0203, 0.0215, 0.0127, 0.0139, 0.0152], dtype='f') + code, message, actual = cfml_metrics.get_u_from_b(nd_b) + assert code == 0 + assert message == '' + assert_almost_equal(desired, actual, decimal=4, verbose=True) + except Exception as e: + print('::::: Run test__get_u_from_b__cfml_metrics_get_u_from_b() :::::') + print('ERROR:', e) + print() + return + +# Debug + +if __name__ == '__main__': + test__get_u_from_b__crysfml08lib_f_get_u_from_b() + test__get_u_from_b__crysfml08lib_get_u_from_b() + test__get_u_from_b__cfml_metrics_get_u_from_b() diff --git a/tests/unit_tests/pycfml/test__py_cfml_metrics.py b/tests/unit_tests/pyCFML/_old/_test__py_cfml_metrics.py similarity index 92% rename from tests/unit_tests/pycfml/test__py_cfml_metrics.py rename to tests/unit_tests/pyCFML/_old/_test__py_cfml_metrics.py index ccfb7e4..33ded67 100644 --- a/tests/unit_tests/pycfml/test__py_cfml_metrics.py +++ b/tests/unit_tests/pyCFML/_old/_test__py_cfml_metrics.py @@ -7,7 +7,7 @@ import numpy as np from numpy.testing import assert_almost_equal -from pycrysfml08 import py_cfml_metrics +from pycrysfml08 import cfml_metrics DI_CELL = {'fortran_type': 'cell_g_type', 'cell': np.array([10., 10., 10.], dtype='f'), @@ -31,7 +31,7 @@ def test__get_u_from_b(): nd_b = np.array([1.5, 1.6, 1.7, 1.0, 1.1, 1.2], dtype='f') desired = np.array([0.019, 0.0203, 0.0215, 0.0127, 0.0139, 0.0152], dtype='f') - code, message, actual = py_cfml_metrics.get_u_from_b(nd_b) + code, message, actual = cfml_metrics.get_u_from_b(nd_b) assert code == 0 assert message == '' assert_almost_equal(desired, actual, decimal=4, verbose=True) @@ -40,7 +40,7 @@ def test__get_betas_from_biso(): biso = 1.0 di_cell = copy.deepcopy(DI_CELL) desired = np.array([0.0025, 0.0025, 0.0025, 0.0, 0.0, 0.0], dtype='f') - code, message, actual = py_cfml_metrics.get_betas_from_biso(biso, di_cell) + code, message, actual = cfml_metrics.get_betas_from_biso(biso, di_cell) assert code == 0 assert message == '' assert_almost_equal(desired, actual, decimal=4, verbose=True) @@ -49,7 +49,7 @@ def test__get_betas_from_u(): u = np.array([0.0127, 0.0127, 0.0127, 0.0, 0.0, 0.0], dtype='f') di_cell = copy.deepcopy(DI_CELL) desired = np.array([0.0025, 0.0025, 0.0025, 0.0, 0.0, 0.0], dtype='f') - code, message, actual = py_cfml_metrics.get_betas_from_u(u, di_cell) + code, message, actual = cfml_metrics.get_betas_from_u(u, di_cell) assert code == 0 assert message == '' assert_almost_equal(desired, actual, decimal=4, verbose=True) @@ -58,7 +58,7 @@ def test__get_u_from_betas(): betas = np.array([0.0025, 0.0025, 0.0025, 0.0, 0.0, 0.0], dtype='f') di_cell = copy.deepcopy(DI_CELL) desired = np.array([0.0127, 0.0127, 0.0127, 0.0, 0.0, 0.0], dtype='f') - code, message, actual = py_cfml_metrics.get_u_from_betas(betas, di_cell) + code, message, actual = cfml_metrics.get_u_from_betas(betas, di_cell) assert code == 0 assert message == '' assert_almost_equal(desired, actual, decimal=4, verbose=True) @@ -67,7 +67,7 @@ def test__set_crystal_cell(): nd_abc = np.array([10.0, 10.0, 10.0], dtype='f') nd_albega = np.array([90.0, 90.0, 90.0], dtype='f') desired = copy.deepcopy(DI_CELL) - code, message, actual = py_cfml_metrics.set_crystal_cell(nd_abc, nd_albega) + code, message, actual = cfml_metrics.set_crystal_cell(nd_abc, nd_albega) assert code == 0 assert message == '' for key in desired.keys(): @@ -104,7 +104,7 @@ def test__get_twofold_axes(): 'a': np.array([10., -0., 0.], dtype=np.float32), 'b': np.array([0., 10., 0.], dtype=np.float32), 'c': np.array([0., 0., 10.], dtype=np.float32)} - code, message, actual = py_cfml_metrics.get_twofold_axes(DI_CELL, 1.0) + code, message, actual = cfml_metrics.get_twofold_axes(DI_CELL, 1.0) assert code == 0 assert message == '' for key in desired.keys(): @@ -142,7 +142,7 @@ def _test__get_conventional_cell(): 'b': np.array([0., 10., 0.], dtype=np.float32), 'c': np.array([0., 0., 10.], dtype=np.float32)} - code, message, actual = py_cfml_metrics.get_twofold_axes(di_cell, 10.0) + code, message, actual = cfml_metrics.get_twofold_axes(di_cell, 10.0) assert code == 0 assert message == '' assert DeepDiff(desired, actual) == {} @@ -181,7 +181,7 @@ def _test__get_conventional_cell(): print(desired) print() di_cell = copy.deepcopy(DI_CELL) - code, message, actual = py_cfml_metrics.get_twofold_axes(di_cell, 1.0) + code, message, actual = cfml_metrics.get_twofold_axes(di_cell, 1.0) print(f'CODE: {code}') print(f'MESSAGE: {message}') print('ACTUAL:') diff --git a/tests/unit_tests/pycfml/test__py_cfml_profiles.py b/tests/unit_tests/pyCFML/_old/_test__py_cfml_profiles.py similarity index 100% rename from tests/unit_tests/pycfml/test__py_cfml_profiles.py rename to tests/unit_tests/pyCFML/_old/_test__py_cfml_profiles.py diff --git a/tests/unit_tests/pycfml/test__py_cfml_sxtal_geom.py b/tests/unit_tests/pyCFML/_old/_test__py_cfml_sxtal_geom.py similarity index 100% rename from tests/unit_tests/pycfml/test__py_cfml_sxtal_geom.py rename to tests/unit_tests/pyCFML/_old/_test__py_cfml_sxtal_geom.py diff --git a/tests/unit_tests/pyCFML/import/test__import.py b/tests/unit_tests/pyCFML/import/test__import.py new file mode 100644 index 0000000..c2cf961 --- /dev/null +++ b/tests/unit_tests/pyCFML/import/test__import.py @@ -0,0 +1,40 @@ +import os +import sys + +# Tests + +def test__import_pycrysfml(): + msg = 'import pycrysfml' + try: + from pycrysfml import crysfml08lib + print(f"::::: Succeeded to '{msg}'") + assert True + except Exception as e: + print(f"::::: Failed to '{msg}': {e}") + assert False + +def test__from_pycrysfml_import_crysfml08lib(): + msg = 'from pycrysfml import crysfml08lib' + try: + from pycrysfml import crysfml08lib + print(f"::::: Succeeded to '{msg}'") + assert True + except Exception as e: + print(f"::::: Failed to '{msg}': {e}") + assert False + +def _test__from_pycrysfml_import_cfml_utilities(): + msg = 'from pycrysfml import cfml_utilities' + try: + from pycrysfml import cfml_utilities + print(f"::::: Succeeded to '{msg}'") + assert True + except Exception as e: + print(f"::::: Failed to '{msg}': {e}") + assert False + +# Debug + +if __name__ == '__main__': + test__import_pycrysfml() + test__from_pycrysfml_import_crysfml08lib()