├── pyked ├── tests │ ├── __init__.py │ ├── test_version.py │ ├── testfile_st2.yaml │ ├── testfile_many_species.yaml │ ├── dataframe_st.csv │ ├── testfile_st_thermo.yaml │ ├── testfile_st_p5.yaml │ ├── testfile_required.yaml │ ├── testfile_st.yaml │ ├── testfile_st.xml │ ├── testfile_bad.yaml │ ├── rcm_history.csv │ ├── testfile_uncertainty.yaml │ ├── testfile_rcm_old.yaml │ ├── testfile_rcm.yaml │ ├── testfile_rcm2.yaml │ └── testfile_rcm.xml ├── __init__.py ├── _version.py ├── orcid.py ├── schemas │ ├── value_unit_schema.yaml │ ├── chemked_schema.yaml │ ├── composition_schema.yaml │ └── ignition_delay_schema.yaml ├── validation.py └── converters.py ├── docs ├── _static │ ├── README │ └── pyked-logo.png ├── _templates │ └── README ├── orcid.rst ├── chemked.rst ├── converters.rst ├── validation.rst ├── pyked-examples.rst ├── Makefile ├── make.bat ├── install.rst ├── index.rst ├── releases.rst ├── conf.py ├── schema-docs.rst └── ck-tutorial.rst ├── logo ├── pyked-logo.pdf ├── pyked-logo.png └── README.md ├── AUTHORS.md ├── MANIFEST.in ├── .github ├── PULL_REQUEST_TEMPLATE.md ├── ISSUE_TEMPLATE.md └── workflows │ └── gh-pages.yml ├── requirements.txt ├── .coveragerc ├── setup.cfg ├── test-environment.yaml ├── codemeta.json ├── appveyor.yml ├── conda.recipe └── meta.yaml ├── .gitignore ├── LICENSE ├── CITATION.md ├── README.md ├── CONTRIBUTING.md ├── setup.py ├── .travis.yml ├── CODE_OF_CONDUCT.md ├── github_deploy_key.enc └── CHANGELOG.md /pyked/tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/_static/README: -------------------------------------------------------------------------------- 1 | This is here so it can be added to git 2 | -------------------------------------------------------------------------------- /docs/_templates/README: -------------------------------------------------------------------------------- 1 | This is here so it can be added to git 2 | -------------------------------------------------------------------------------- /docs/orcid.rst: -------------------------------------------------------------------------------- 1 | ===== 2 | ORCID 3 | ===== 4 | 5 | .. automodule:: pyked.orcid 6 | -------------------------------------------------------------------------------- /docs/chemked.rst: -------------------------------------------------------------------------------- 1 | ======= 2 | ChemKED 3 | ======= 4 | 5 | .. automodule:: pyked.chemked 6 | -------------------------------------------------------------------------------- /logo/pyked-logo.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pr-omethe-us/PyKED/HEAD/logo/pyked-logo.pdf -------------------------------------------------------------------------------- /logo/pyked-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pr-omethe-us/PyKED/HEAD/logo/pyked-logo.png -------------------------------------------------------------------------------- /docs/_static/pyked-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pr-omethe-us/PyKED/HEAD/docs/_static/pyked-logo.png -------------------------------------------------------------------------------- /docs/converters.rst: -------------------------------------------------------------------------------- 1 | ========== 2 | Converters 3 | ========== 4 | 5 | .. automodule:: pyked.converters 6 | -------------------------------------------------------------------------------- /docs/validation.rst: -------------------------------------------------------------------------------- 1 | ========== 2 | Validation 3 | ========== 4 | 5 | .. automodule:: pyked.validation 6 | -------------------------------------------------------------------------------- /pyked/__init__.py: -------------------------------------------------------------------------------- 1 | from .chemked import ChemKED # noqa: F401 2 | from ._version import __version__ # noqa: F401 3 | -------------------------------------------------------------------------------- /pyked/_version.py: -------------------------------------------------------------------------------- 1 | __version_info__ = (0, 4, 2, 'a1') 2 | __version__ = '.'.join(map(str, __version_info__[:3])) 3 | if len(__version_info__) == 4: 4 | __version__ += __version_info__[-1] 5 | -------------------------------------------------------------------------------- /AUTHORS.md: -------------------------------------------------------------------------------- 1 | # Credits 2 | 3 | ## Development Leads 4 | 5 | * Kyle Niemeyer 6 | * Bryan Weber 7 | 8 | ## Contributors 9 | 10 | None yet. Why not be the first? 11 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include LICENSE 2 | include AUTHORS.md 3 | include CODE_OF_CONDUCT.md 4 | include CONTRIBUTING.md 5 | include pyked/tests/*.yaml 6 | include pyked/tests/*.csv 7 | include pyked/tests/*.xml 8 | include pyked/schemas/*.yaml 9 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | - [ ] Fixes # 2 | - [ ] Tests added 3 | - [ ] Added entry into `CHANGELOG.md` 4 | - [ ] Documentation updated 5 | 6 | Changes proposed in this pull request: 7 | - 8 | - 9 | - 10 | 11 | @pr-omethe-us/chemked 12 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### Code sample, preferably able to be copy-pasted and run with no changes 2 | 3 | 4 | ### Expected behavior 5 | 6 | 7 | ### Actual behavior, including any error messages 8 | 9 | 10 | ### PyKED/ChemKED version, Python version, OS version 11 | -------------------------------------------------------------------------------- /pyked/tests/test_version.py: -------------------------------------------------------------------------------- 1 | """ 2 | Test for _version.py 3 | """ 4 | # Standard Libraries 5 | import pkg_resources 6 | 7 | # Local imports 8 | from .._version import __version__ 9 | 10 | 11 | def test_semantic_version(): 12 | pkg_resources.parse_version(__version__) 13 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # Required python packages 2 | 3 | numpy>=1.11.0,<2.0 4 | pyyaml>=3.12,<4.0 5 | cerberus>=1.0.0,<1.2 6 | ipython 7 | pint>=0.7.2,<0.9 8 | pandas >=0.22.0,<0.23 9 | uncertainties >=3.0.1,<3.1 10 | habanero>=0.6.0 11 | nbconvert 12 | flake8 13 | pytest 14 | requests 15 | nbsphinx 16 | sphinx 17 | -------------------------------------------------------------------------------- /.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | branch = True 3 | source = pyked 4 | 5 | [report] 6 | exclude_lines = 7 | if self.debug: 8 | pragma: no cover 9 | raise NotImplementedError 10 | if __name__ == .__main__.: 11 | ignore_errors = True 12 | omit = 13 | pyked/tests/* 14 | setup.py 15 | pyked/_version.py 16 | -------------------------------------------------------------------------------- /docs/pyked-examples.rst: -------------------------------------------------------------------------------- 1 | .. Examples of using PyKED 2 | 3 | Usage examples 4 | ============== 5 | 6 | The following usage examples provide a guide to the use of PyKED. They are by no means an exhaustive 7 | treatment, and are meant to demonstrate the basic capabilities of the software. 8 | 9 | .. toctree:: 10 | :maxdepth: 1 11 | 12 | shock-tube-example 13 | rcm-example 14 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | license_file = LICENSE 3 | 4 | [aliases] 5 | test=pytest 6 | 7 | [tool:pytest] 8 | addopts = -vv --cov=./ 9 | filterwarnings = 10 | ignore::ResourceWarning 11 | 12 | [flake8] 13 | exclude = 14 | .git, 15 | __pycache__, 16 | build, 17 | dist, 18 | htmlcov, 19 | docs, 20 | pyked/tests, 21 | setup.py 22 | max-line-length = 100 23 | -------------------------------------------------------------------------------- /test-environment.yaml: -------------------------------------------------------------------------------- 1 | name: py${PYTHON} 2 | channels: 3 | - defaults 4 | - conda-forge 5 | dependencies: 6 | - numpy>=1.11.0,<2.0 7 | - pyyaml>=3.12,<4.0 8 | - pytest>=3.2.0 9 | - pytest-cov>=2.3.1 10 | - python=${PYTHON} 11 | - cerberus>=1.0.0,<1.2 12 | - pint>=0.7.2,<0.9 13 | - pandas >=0.22.0,<0.23 14 | - uncertainties >=3.0.1,<3.1 15 | - habanero>=0.6.0 16 | - codecov 17 | - flake8 18 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | SPHINXPROJ = PyKED 8 | SOURCEDIR = . 9 | BUILDDIR = _build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /logo/README.md: -------------------------------------------------------------------------------- 1 | # Logo 2 | 3 | 4 | This directory contains the logo files for PyKED. 5 | 6 | The logo combines images used under license from Shutterstock.com: 7 | - 398666929, Sarawut Padungkwan/Shutterstock.com 8 | - 336731069, La Gorda/Shutterstock.com 9 | 10 | Creative Commons License
PyKED Logo by Kyle Niemeyer is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License. 11 | -------------------------------------------------------------------------------- /pyked/orcid.py: -------------------------------------------------------------------------------- 1 | """ 2 | Module for ORCID interaction 3 | """ 4 | import requests 5 | headers = {'Accept': 'application/json'} 6 | 7 | 8 | def search_orcid(orcid): 9 | """ 10 | Search the ORCID public API 11 | 12 | Specfically, return a dictionary with the personal details 13 | (name, etc.) of the person associated with the given ORCID 14 | 15 | Args: 16 | orcid (`str`): The ORCID to be searched 17 | 18 | Returns: 19 | `dict`: Dictionary with the JSON response from the API 20 | 21 | Raises: 22 | `~requests.HTTPError`: If the given ORCID cannot be found, an `~requests.HTTPError` 23 | is raised with status code 404 24 | """ 25 | url = 'https://pub.orcid.org/v2.1/{orcid}/person'.format(orcid=orcid) 26 | r = requests.get(url, headers=headers) 27 | if r.status_code != 200: 28 | r.raise_for_status() 29 | return r.json() 30 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=. 11 | set BUILDDIR=_build 12 | set SPHINXPROJ=PyKED 13 | 14 | if "%1" == "" goto help 15 | 16 | %SPHINXBUILD% >NUL 2>NUL 17 | if errorlevel 9009 ( 18 | echo. 19 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 20 | echo.installed, then set the SPHINXBUILD environment variable to point 21 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 22 | echo.may add the Sphinx directory to PATH. 23 | echo. 24 | echo.If you don't have Sphinx installed, grab it from 25 | echo.http://sphinx-doc.org/ 26 | exit /b 1 27 | ) 28 | 29 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 30 | goto end 31 | 32 | :help 33 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 34 | 35 | :end 36 | popd 37 | -------------------------------------------------------------------------------- /codemeta.json: -------------------------------------------------------------------------------- 1 | { 2 | "@context": "http://schema.org", 3 | "@type": "Code", 4 | "author": [ 5 | { 6 | "@id": "http://orcid.org/0000-0003-4425-7097", 7 | "@type": "Person", 8 | "email": "kyle.niemeyer@gmail.com", 9 | "name": "Kyle Niemeyer" 10 | }, 11 | { 12 | "@id": "http://orcid.org//0000-0003-0815-9270", 13 | "@type": "Person", 14 | "email": "bryan.w.weber@gmail.com", 15 | "name": "Bryan Weber" 16 | } 17 | ], 18 | "citation": "https://doi.org/10.5281/zenodo.597935", 19 | "codeRepository": "https://github.com/pr-omethe-us/PyKED", 20 | "dateCreated": "2018-03-09", 21 | "description": "Python interface to the ChemKED database format https://pr-omethe-us.github.io/PyKED/", 22 | "keywords": "combustion, experimental data, YAML, data standard", 23 | "license": "https://opensource.org/licenses/BSD-3-Clause", 24 | "name": "PyKED" 25 | } 26 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 1.0.{build} 2 | environment: 3 | PYTHON_LOC: "C:\\Miniconda36-x64" 4 | 5 | skip_tags: true 6 | 7 | install: 8 | - cmd: call %PYTHON_LOC%\Scripts\activate.bat 9 | - cmd: conda config --set always_yes yes --set changeps1 no 10 | - cmd: conda config --append channels conda-forge 11 | - cmd: conda update conda 12 | - cmd: conda update -q --all 13 | - ps: (get-content test-environment.yaml) | %{$_ -replace "\$\{PYTHON\}","3.5"} | set-content test-environment.yaml 14 | - cmd: conda env create -qf test-environment.yaml 15 | - cmd: git checkout -- test-environment.yaml 16 | - ps: (get-content test-environment.yaml) | %{$_ -replace "\$\{PYTHON\}","3.6"} | set-content test-environment.yaml 17 | - cmd: conda env create -qf test-environment.yaml 18 | - cmd: conda info -a 19 | - ps: Write-Host "Packages in py3.5 Environment:" 20 | - cmd: conda list -n py3.5 21 | - ps: Write-Host "Packages in py3.6 Environment:" 22 | - cmd: conda list -n py3.6 23 | 24 | build_script: 25 | - cmd: call %PYTHON_LOC%\Scripts\activate.bat py3.5 26 | - cmd: pytest -vv --cov=./ --cov-append 27 | - cmd: call %PYTHON_LOC%\Scripts\activate.bat py3.6 28 | - cmd: pytest -vv --cov=./ --cov-append 29 | - cmd: flake8 . 30 | - cmd: codecov -X gcov 31 | -------------------------------------------------------------------------------- /docs/install.rst: -------------------------------------------------------------------------------- 1 | .. Installation documentation 2 | 3 | Installation 4 | ============ 5 | 6 | Stable 7 | ------ 8 | 9 | PyKED is available for Python 3.5 and 3.6 on Linux, macOS, and Windows via ``conda`` and ``pip``. 10 | For ``conda`` installation, use the ``pr-omethe-us`` channel:: 11 | 12 | conda install -c pr-omethe-us pyked 13 | 14 | Note that you might need to include the ``conda-forge`` channel by editing your conda 15 | configuration:: 16 | 17 | conda config --append channels conda-forge 18 | conda install -c pr-omethe-us pyked 19 | 20 | You can also install with ``pip``:: 21 | 22 | pip install pyked 23 | 24 | Development 25 | ----------- 26 | 27 | PyKED can be installed from source by cloning the git repository and changing into that directory:: 28 | 29 | git clone https://github.com/pr-omethe-us/PyKED 30 | cd PyKED 31 | 32 | Then run:: 33 | 34 | conda develop . 35 | 36 | if you're using ``conda`` (you may need to install ``conda-build`` first). To uninstall, run:: 37 | 38 | conda develop . --uninstall 39 | 40 | Note that this doesn't install the standalone converter scripts. With ``pip``, installing 41 | is done by:: 42 | 43 | pip install -e . 44 | 45 | To uninstall with ``pip``:: 46 | 47 | pip uninstall pyked 48 | 49 | ``pip`` does install the standalone scripts. 50 | -------------------------------------------------------------------------------- /conda.recipe/meta.yaml: -------------------------------------------------------------------------------- 1 | {% set data = load_setup_py_data() %} 2 | 3 | package: 4 | name: pyked 5 | version: {{ data['version'] }} 6 | 7 | source: 8 | path: .. 9 | 10 | build: 11 | number: 0 12 | script: python -m pip install --no-deps --ignore-installed . 13 | noarch: python 14 | entry_points: 15 | - ck2respth = pyked.converters:ck2respth 16 | - convert_ck = pyked.converters:main 17 | - respth2ck = pyked.converters:respth2ck 18 | 19 | requirements: 20 | build: 21 | - python >=3.5 22 | - setuptools 23 | - pip 24 | 25 | run: 26 | - python 27 | - pyyaml >=3.12,<4.0 28 | - cerberus >=1.0.0,<1.2 29 | - pint >=0.7.2,<0.9 30 | - numpy >=1.11.0,<2.0 31 | - habanero >=0.6.0,<0.7 32 | - uncertainties >=3.0.1,<3.1 33 | - pandas >=0.22.0,<0.23 34 | 35 | test: 36 | imports: 37 | - pyked 38 | 39 | requires: 40 | - pytest >=3.2.0 41 | - pytest-cov >=2.3.1 42 | 43 | commands: 44 | - pytest -vv --pyargs pyked 45 | - ck2respth --help 46 | - respth2ck --help 47 | - convert_ck --help 48 | 49 | about: 50 | home: data['url'] 51 | license: BSD 3-Clause 52 | license_file: LICENSE 53 | license_family: BSD 54 | 55 | summary: data['description'] 56 | description: data['long_description'] 57 | doc_url: https://pr-omethe-us.github.io/PyKED 58 | dev_url: data['url'] 59 | -------------------------------------------------------------------------------- /.github/workflows/gh-pages.yml: -------------------------------------------------------------------------------- 1 | name: github pages 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | - docs_deploy 8 | 9 | jobs: 10 | deploy: 11 | runs-on: ubuntu-18.04 12 | steps: 13 | - run: sudo apt-get install pandoc 14 | - uses: actions/checkout@v2 15 | 16 | - name: Setup Python 17 | uses: actions/setup-python@v2 18 | with: 19 | python-version: '3.6' 20 | 21 | - name: Upgrade pip 22 | run: | 23 | # install pip=>20.1 to use "pip cache dir" 24 | python3 -m pip install --upgrade pip 25 | 26 | - name: Get pip cache dir 27 | id: pip-cache 28 | run: echo "::set-output name=dir::$(pip cache dir)" 29 | 30 | - name: Cache dependencies 31 | uses: actions/cache@v2 32 | with: 33 | path: ${{ steps.pip-cache.outputs.dir }} 34 | key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} 35 | restore-keys: | 36 | ${{ runner.os }}-pip- 37 | 38 | - name: Install dependencies 39 | run: python3 -m pip install -r ./requirements.txt 40 | 41 | - run: export PYTHONPATH=$PYTHONPATH:$(pwd); cd docs; make html SPHINXOPTS="-W" 42 | 43 | - name: Deploy 44 | uses: peaceiris/actions-gh-pages@v3.7.3 45 | with: 46 | github_token: ${{ secrets.GITHUB_TOKEN }} 47 | publish_dir: ./site 48 | -------------------------------------------------------------------------------- /pyked/tests/testfile_st2.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | file-authors: 3 | - name: Kyle E Niemeyer 4 | ORCID: 0000-0003-4425-7097 5 | file-version: 0 6 | chemked-version: 0.0.1 7 | reference: 8 | doi: 10.1016/j.ijhydene.2007.04.008 9 | authors: 10 | - name: N. Chaumeix 11 | - name: S. Pichon 12 | - name: F. Lafosse 13 | - name: C.-E. Paillard 14 | journal: International Journal of Hydrogen Energy 15 | year: 2007 16 | volume: 32 17 | pages: 2216-2226 18 | detail: Artificial pressure rise and ignition target 19 | experiment-type: ignition delay 20 | apparatus: 21 | kind: shock tube 22 | institution: CNRS-ICARE 23 | facility: stainless steel shock tube 24 | common-properties: 25 | pressure: &pres 26 | - 2.18 atm 27 | composition: &comp 28 | kind: mole fraction 29 | species: 30 | - species-name: H2 31 | InChI: 1S/H2/h1H 32 | amount: 33 | - 0.00444 34 | - species-name: O2 35 | InChI: 1S/O2/c1-2 36 | amount: 37 | - 0.00556 38 | - species-name: Ar 39 | InChI: 1S/Ar 40 | amount: 41 | - 0.99 42 | pressure-rise: &pres-rise 43 | - 0.10 1/ms 44 | ignition-type: &ign 45 | target: OH 46 | type: max 47 | datapoints: 48 | - temperature: 49 | - 1264.2 kelvin 50 | ignition-delay: 51 | - 291.57 us 52 | pressure: *pres 53 | composition: *comp 54 | pressure-rise: *pres-rise 55 | ignition-type: *ign 56 | equivalence-ratio: 0.4 57 | ... 58 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | README.rst 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *,cover 47 | .hypothesis/ 48 | .pytest_cache/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | local_settings.py 57 | 58 | # Flask stuff: 59 | instance/ 60 | .webassets-cache 61 | 62 | # Scrapy stuff: 63 | .scrapy 64 | 65 | # Sphinx documentation 66 | docs/_build/ 67 | 68 | # PyBuilder 69 | target/ 70 | 71 | # IPython Notebook 72 | .ipynb_checkpoints 73 | 74 | # pyenv 75 | .python-version 76 | 77 | # celery beat schedule file 78 | celerybeat-schedule 79 | 80 | # dotenv 81 | .env 82 | 83 | # virtualenv 84 | venv/ 85 | ENV/ 86 | 87 | # Spyder project settings 88 | .spyderproject 89 | 90 | # Rope project settings 91 | .ropeproject 92 | 93 | # Mac stuff 94 | .DS_Store 95 | -------------------------------------------------------------------------------- /pyked/tests/testfile_many_species.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | file-authors: 3 | - name: B. Author 4 | file-version: 0 5 | chemked-version: 0.0.1 6 | reference: 7 | authors: 8 | - name: A. Author 9 | journal: Testing Journal 10 | year: 1600 11 | experiment-type: ignition delay 12 | apparatus: 13 | kind: shock tube 14 | datapoints: 15 | - temperature: 16 | - 1164.48 kelvin 17 | ignition-delay: 18 | - 471.54 us 19 | pressure: 20 | - 220 kilopascal 21 | composition: 22 | kind: mole fraction 23 | species: 24 | - species-name: H2 25 | InChI: 1S/H2/h1H 26 | amount: 27 | - 0.00444 28 | - species-name: O2 29 | InChI: 1S/O2/c1-2 30 | amount: 31 | - 0.00556 32 | - species-name: Ar 33 | InChI: 1S/Ar 34 | amount: 35 | - 0.99 36 | ignition-type: 37 | target: pressure 38 | type: d/dt max 39 | - temperature: 40 | - 1164.48 kelvin 41 | ignition-delay: 42 | - 471.54 us 43 | pressure: 44 | - 220 kilopascal 45 | composition: 46 | kind: mass fraction 47 | species: 48 | - species-name: new-species-1 49 | InChI: no-inchi 50 | amount: 51 | - 2.25252818E-4 52 | - species-name: new-species-2 53 | InChI: no-inchi 54 | amount: 55 | - 4.47745336E-3 56 | - species-name: Ar 57 | InChI: 1S/Ar 58 | amount: 59 | - 9.95297294E-1 60 | ignition-type: 61 | target: pressure 62 | type: d/dt max 63 | ... 64 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2016, Kyle E. Niemeyer, Bryan W. Weber 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /pyked/schemas/value_unit_schema.yaml: -------------------------------------------------------------------------------- 1 | # Common reference for value-unit schema 2 | value-with-uncertainty: &value-with-uncertainty 3 | isvalid_uncertainty: true 4 | items: 5 | - anyof_type: 6 | - string 7 | - float 8 | - type: dict 9 | schema: 10 | uncertainty-type: 11 | required: true 12 | type: string 13 | allowed: 14 | - absolute 15 | - relative 16 | uncertainty: 17 | required: true 18 | anyof_type: 19 | - string 20 | - float 21 | excludes: 22 | - upper-uncertainty 23 | - lower-uncertainty 24 | upper-uncertainty: 25 | required: true 26 | anyof_type: 27 | - string 28 | - float 29 | excludes: 30 | - uncertainty 31 | dependencies: 32 | - lower-uncertainty 33 | lower-uncertainty: 34 | required: true 35 | anyof_type: 36 | - string 37 | - float 38 | excludes: 39 | - uncertainty 40 | dependencies: 41 | - upper-uncertainty 42 | value-without-uncertainty: &value-without-uncertainty 43 | isvalid_quantity: true 44 | items: 45 | - anyof_type: 46 | - string 47 | - float 48 | value-unit-required: &value-unit-required 49 | type: list 50 | required: true 51 | oneof: 52 | - *value-with-uncertainty 53 | - *value-without-uncertainty 54 | value-unit-optional: &value-unit-optional 55 | type: list 56 | oneof: 57 | - *value-with-uncertainty 58 | - *value-without-uncertainty 59 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. PyKED documentation master file, created by 2 | sphinx-quickstart on Fri Mar 31 13:06:52 2017. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | PyKED |release| 7 | =============== 8 | 9 | .. image:: /_static/pyked-logo.png 10 | :width: 25 % 11 | :align: right 12 | :alt: PyKED logo 13 | 14 | PyKED is a Python package that provides the reference implementation of the interface to ChemKED 15 | files. PyKED reads ChemKED files, validates their structure and content, and allows the user to 16 | interact with the data contained in the ChemKED file. PyKED is licensed under the permissive, 17 | open-source BSD 3-clause license. The source code is publicly available on GitHub at 18 | https://github.com/pr-omethe-us/PyKED. 19 | 20 | This is the documentation for the |release| version of PyKED. The documentation 21 | for the unreleased, developers' version of PyKED is available at 22 | https://pr-omethe-us.github.io/PyKED/devel, and documentation for old releases 23 | is available on the `Releases page `__. 24 | The stable version of the documentation is always available at https://pr-omethe-us.github.io/PyKED/ 25 | 26 | (This is a testing line, please ignore) 27 | 28 | User's Guide 29 | ------------ 30 | 31 | .. toctree:: 32 | :maxdepth: 1 33 | 34 | install 35 | ck-tutorial 36 | schema-docs 37 | pyked-examples 38 | releases 39 | 40 | Code API 41 | -------- 42 | 43 | .. toctree:: 44 | :maxdepth: 2 45 | 46 | chemked 47 | converters 48 | validation 49 | orcid 50 | 51 | 52 | 53 | Indices and tables 54 | ================== 55 | 56 | * :ref:`genindex` 57 | * :ref:`modindex` 58 | * :ref:`search` 59 | -------------------------------------------------------------------------------- /pyked/tests/dataframe_st.csv: -------------------------------------------------------------------------------- 1 | ,File Version,File Authors,Experiment Type,Apparatus:Kind,Apparatus:Institution,Apparatus:Facility,Chemked Version,Reference:Volume,Reference:Journal,Reference:Doi,Reference:Authors,Reference:Detail,Reference:Year,Reference:Pages,Ar,H2,O2,Ignition Delay,Temperature,Pressure,Equivalence Ratio,Composition:Kind 2 | 0,0,Kyle E Niemeyer,ignition delay,shock tube,CNRS-ICARE,stainless steel shock tube,0.0.1,32,International Journal of Hydrogen Energy,10.1016/j.ijhydene.2007.04.008,N. Chaumeix,"Fig. 12., right, open diamond",2007,2216-2226,0.99,0.00444,0.00556,471.54 microsecond,1164.48 kelvin,220 kilopascal,0.4,mole fraction 3 | 1,0,Kyle E Niemeyer,ignition delay,shock tube,CNRS-ICARE,stainless steel shock tube,0.0.1,32,International Journal of Hydrogen Energy,10.1016/j.ijhydene.2007.04.008,N. Chaumeix,"Fig. 12., right, open diamond",2007,2216-2226,0.99,0.00444,0.00556,448.03 microsecond,1164.97 kelvin,220 kilopascal,0.4,mole fraction 4 | 2,0,Kyle E Niemeyer,ignition delay,shock tube,CNRS-ICARE,stainless steel shock tube,0.0.1,32,International Journal of Hydrogen Energy,10.1016/j.ijhydene.2007.04.008,N. Chaumeix,"Fig. 12., right, open diamond",2007,2216-2226,0.99,0.00444,0.00556,291.57 microsecond,1264.2 kelvin,220 kilopascal,0.4,mole fraction 5 | 3,0,Kyle E Niemeyer,ignition delay,shock tube,CNRS-ICARE,stainless steel shock tube,0.0.1,32,International Journal of Hydrogen Energy,10.1016/j.ijhydene.2007.04.008,N. Chaumeix,"Fig. 12., right, open diamond",2007,2216-2226,0.99,0.00444,0.00556,205.93 microsecond,1332.57 kelvin,220 kilopascal,0.4,mole fraction 6 | 4,0,Kyle E Niemeyer,ignition delay,shock tube,CNRS-ICARE,stainless steel shock tube,0.0.1,32,International Journal of Hydrogen Energy,10.1016/j.ijhydene.2007.04.008,N. Chaumeix,"Fig. 12., right, open diamond",2007,2216-2226,0.99,0.00444,0.00556,88.11 microsecond,1519.18 kelvin,220 kilopascal,0.4,mole fraction 7 | -------------------------------------------------------------------------------- /CITATION.md: -------------------------------------------------------------------------------- 1 | # Citation of PyKED 2 | 3 | [![DOI](https://zenodo.org/badge/66023863.svg)](https://zenodo.org/badge/latestdoi/66023863) 4 | 5 | To cite PyKED in a scholarly article, please use 6 | 7 | > K. E. Niemeyer and B. W. Weber. (2018) PyKED v0.4.1 [software]. Zenodo. https://doi.org/10.5281/zenodo.597935 8 | 9 | A BibTeX entry for LaTeX users is 10 | 11 | ```TeX 12 | @misc{PyKED, 13 | author = {Kyle E Niemeyer and Bryan W Weber}, 14 | year = 2018, 15 | title = {PyKED v0.4.1}, 16 | doi = {10.5281/zenodo.597935}, 17 | url = {https://github.com/pr-omethe-us/PyKED}, 18 | } 19 | ``` 20 | 21 | In both cases, please update the entry with the version used. The DOI for the latest version is 22 | given in the badge at the top, or alternately will 23 | take you to the latest version (and generally represents all versions). 24 | If you would like to cite a specific, older version, the DOIs for each release are: 25 | 26 | * v0.4.1: [10.5281/zenodo.1194920](https://doi.org/10.5281/zenodo.1194920) 27 | * v0.4.0: [10.5281/zenodo.1193936](https://doi.org/10.5281/zenodo.1193936) 28 | * v0.3.0: [10.5281/zenodo.1006722](https://doi.org/10.5281/zenodo.1006722) 29 | * v0.2.1: [10.5281/zenodo.858441](https://doi.org/10.5281/zenodo.858441) 30 | * v0.2.0: [10.5281/zenodo.841303](https://doi.org/10.5281/zenodo.841303) 31 | * v0.1.6: [10.5281/zenodo.831332](https://doi.org/10.5281/zenodo.831332) 32 | * v0.1.5: [10.5281/zenodo.582345](https://doi.org/10.5281/zenodo.582345) 33 | * v0.1.4: [10.5281/zenodo.582338](https://doi.org/10.5281/zenodo.582338) 34 | * v0.1.3: [10.5281/zenodo.439720](https://doi.org/10.5281/zenodo.546143) 35 | * v0.1.2: [10.5281/zenodo.439720](https://doi.org/10.5281/zenodo.546141) 36 | * v0.1.1: [10.5281/zenodo.439720](https://doi.org/10.5281/zenodo.439720) 37 | * v0.1.0: [10.5281/zenodo.439716](https://doi.org/10.5281/zenodo.439716) 38 | -------------------------------------------------------------------------------- /pyked/tests/testfile_st_thermo.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | file-authors: 3 | - name: Kyle E Niemeyer 4 | ORCID: 0000-0003-4425-7097 5 | file-version: 0 6 | chemked-version: 0.0.1 7 | reference: 8 | doi: 10.1016/j.ijhydene.2007.04.008 9 | authors: 10 | - name: N. Chaumeix 11 | - name: S. Pichon 12 | - name: F. Lafosse 13 | - name: C.-E. Paillard 14 | journal: International Journal of Hydrogen Energy 15 | year: 2007 16 | volume: 32 17 | pages: 2216-2226 18 | detail: Fig. 12., right, open diamond 19 | experiment-type: ignition delay 20 | apparatus: 21 | kind: shock tube 22 | institution: CNRS-ICARE 23 | facility: stainless steel shock tube 24 | common-properties: 25 | pressure: &pres 26 | - 220 kilopascal 27 | composition: &comp 28 | kind: mole fraction 29 | species: 30 | - species-name: H2 31 | thermo: 32 | T_ranges: [200.0, 1000.0, 5000.0] 33 | data: [1.0, 2.0, 3.0, 4.0, 5.0, 6, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0] 34 | note: This data is made up 35 | InChI: 1S/H2/h1H 36 | amount: 37 | - 0.00444 38 | - species-name: O2 39 | thermo: 40 | T_ranges: [200 K, 1000 K, 5000 K] 41 | data: [1.0, 2.0, 3.0, 4.0, 5.0, 6, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0] 42 | note: This data is made up 43 | InChI: 1S/O2/c1-2 44 | amount: 45 | - 0.00556 46 | - species-name: Ar 47 | thermo: 48 | T_ranges: [200, 1000, 5000] 49 | data: [1.0, 2.0, 3.0, 4.0, 5.0, 6, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0] 50 | note: This data is made up 51 | InChI: 1S/Ar 52 | amount: 53 | - 0.99 54 | ignition-type: &ign 55 | target: pressure 56 | type: d/dt max 57 | datapoints: 58 | - temperature: 59 | - 1164.48 kelvin 60 | ignition-delay: 61 | - 471.54 us 62 | pressure: *pres 63 | composition: *comp 64 | ignition-type: *ign 65 | equivalence-ratio: 0.4 66 | ... 67 | -------------------------------------------------------------------------------- /pyked/tests/testfile_st_p5.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | file-authors: 3 | - name: Morgan Mayer 4 | ORCID: 0000-0001-7137-5721 5 | file-version: 0 6 | chemked-version: 0.0.1 7 | reference: 8 | doi: 10.1016/j.combustflame.2011.08.014 9 | authors: 10 | - name: Ivo Stranic 11 | - name: Deanna P. Chase 12 | - name: Joseph T. Harmon 13 | - name: Sheng Yang 14 | - name: David F. Davidson 15 | - name: Ronald K. Hanson 16 | journal: Combustion and Flame 17 | year: 2012 18 | volume: 159 19 | pages: 516-527 20 | experiment-type: ignition delay 21 | apparatus: 22 | kind: shock tube 23 | institution: High Temperature Gasdynamics Laboratory, Stanford University 24 | facility: stainless steel shock tube 25 | common-properties: 26 | composition: &comp 27 | kind: mole fraction 28 | species: 29 | - species-name: t-butanol 30 | InChI: 1S/C4H10O/c1-4(2,3)5/h5H,1-3H3 31 | amount: 32 | - 0.003333333 33 | - species-name: O2 34 | InChI: 1S/O2/c1-2 35 | amount: 36 | - 0.04 37 | - species-name: Ar 38 | InChI: 1S/Ar 39 | amount: 40 | - 0.956666667 41 | ignition-type: &ign 42 | target: OH* 43 | type: 1/2 max 44 | datapoints: 45 | - temperature: 46 | - 1459 kelvin 47 | ignition-delay: 48 | - 347 us 49 | pressure: 50 | - 1.60 atm 51 | composition: *comp 52 | ignition-type: *ign 53 | equivalence-ratio: 0.5 54 | - temperature: 55 | - 1389 kelvin 56 | ignition-delay: 57 | - 756 us 58 | pressure: 59 | - 1.67 atm 60 | composition: *comp 61 | ignition-type: *ign 62 | equivalence-ratio: 0.5 63 | - temperature: 64 | - 1497 kelvin 65 | ignition-delay: 66 | - 212 us 67 | pressure: 68 | - 1.55 atm 69 | composition: *comp 70 | ignition-type: *ign 71 | equivalence-ratio: 0.5 72 | - temperature: 73 | - 1562 kelvin 74 | ignition-delay: 75 | - 105 us 76 | pressure: 77 | - 1.50 atm 78 | composition: *comp 79 | ignition-type: *ign 80 | equivalence-ratio: 0.5 81 | ... 82 | -------------------------------------------------------------------------------- /pyked/tests/testfile_required.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | file-authors: 3 | - name: B. Author 4 | file-version: 0 5 | chemked-version: 0.0.1 6 | reference: 7 | authors: 8 | - name: A. Author 9 | year: 1600 10 | experiment-type: ignition delay 11 | apparatus: 12 | kind: shock tube 13 | datapoints: 14 | - temperature: 15 | - 1164.48 kelvin 16 | ignition-delay: 17 | - 471.54 us 18 | pressure: 19 | - 220 kilopascal 20 | composition: 21 | kind: mole fraction 22 | species: 23 | - species-name: H2 24 | InChI: 1S/H2/h1H 25 | amount: 26 | - 0.00444 27 | - species-name: O2 28 | InChI: 1S/O2/c1-2 29 | amount: 30 | - 0.00556 31 | - species-name: Ar 32 | InChI: 1S/Ar 33 | amount: 34 | - 0.99 35 | ignition-type: 36 | target: CH 37 | type: min 38 | - temperature: 39 | - 1164.48 kelvin 40 | ignition-delay: 41 | - 471.54 us 42 | pressure: 43 | - 220 kilopascal 44 | composition: 45 | kind: mass fraction 46 | species: 47 | - species-name: H2 48 | InChI: 1S/H2/h1H 49 | amount: 50 | - 2.25252818E-4 51 | - species-name: O2 52 | InChI: 1S/O2/c1-2 53 | amount: 54 | - 4.47745336E-3 55 | - species-name: Ar 56 | InChI: 1S/Ar 57 | amount: 58 | - 9.95297294E-1 59 | ignition-type: 60 | target: CH* 61 | type: d/dt max extrapolated 62 | - temperature: 63 | - 1164.48 kelvin 64 | ignition-delay: 65 | - 471.54 us 66 | pressure: 67 | - 220 kilopascal 68 | composition: 69 | kind: mole percent 70 | species: 71 | - species-name: H2 72 | InChI: 1S/H2/h1H 73 | amount: 74 | - 0.444 75 | - species-name: O2 76 | InChI: 1S/O2/c1-2 77 | amount: 78 | - 0.556 79 | - species-name: Ar 80 | InChI: 1S/Ar 81 | amount: 82 | - 99.0 83 | ignition-type: 84 | target: pressure 85 | type: d/dt max 86 | ... 87 | -------------------------------------------------------------------------------- /pyked/tests/testfile_st.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | file-authors: 3 | - name: Kyle E Niemeyer 4 | ORCID: 0000-0003-4425-7097 5 | file-version: 0 6 | chemked-version: 0.0.1 7 | reference: 8 | doi: 10.1016/j.ijhydene.2007.04.008 9 | authors: 10 | - name: N. Chaumeix 11 | - name: S. Pichon 12 | - name: F. Lafosse 13 | - name: C.-E. Paillard 14 | journal: International Journal of Hydrogen Energy 15 | year: 2007 16 | volume: 32 17 | pages: 2216-2226 18 | detail: Fig. 12., right, open diamond 19 | experiment-type: ignition delay 20 | apparatus: 21 | kind: shock tube 22 | institution: CNRS-ICARE 23 | facility: stainless steel shock tube 24 | common-properties: 25 | pressure: &pres 26 | - 220 kilopascal 27 | composition: &comp 28 | kind: mole fraction 29 | species: 30 | - species-name: H2 31 | InChI: 1S/H2/h1H 32 | amount: 33 | - 0.00444 34 | - species-name: O2 35 | InChI: 1S/O2/c1-2 36 | amount: 37 | - 0.00556 38 | - species-name: Ar 39 | InChI: 1S/Ar 40 | amount: 41 | - 0.99 42 | ignition-type: &ign 43 | target: pressure 44 | type: d/dt max 45 | datapoints: 46 | - temperature: 47 | - 1164.48 kelvin 48 | ignition-delay: 49 | - 471.54 us 50 | pressure: *pres 51 | composition: *comp 52 | ignition-type: *ign 53 | equivalence-ratio: 0.4 54 | - temperature: 55 | - 1164.97 kelvin 56 | ignition-delay: 57 | - 448.03 us 58 | pressure: *pres 59 | composition: *comp 60 | ignition-type: *ign 61 | equivalence-ratio: 0.4 62 | - temperature: 63 | - 1264.2 kelvin 64 | ignition-delay: 65 | - 291.57 us 66 | pressure: *pres 67 | composition: *comp 68 | ignition-type: *ign 69 | equivalence-ratio: 0.4 70 | - temperature: 71 | - 1332.57 kelvin 72 | ignition-delay: 73 | - 205.93 us 74 | pressure: *pres 75 | composition: *comp 76 | ignition-type: *ign 77 | equivalence-ratio: 0.4 78 | - temperature: 79 | - 1519.18 kelvin 80 | ignition-delay: 81 | - 88.11 us 82 | pressure: *pres 83 | composition: *comp 84 | ignition-type: *ign 85 | equivalence-ratio: 0.4 86 | ... 87 | -------------------------------------------------------------------------------- /pyked/tests/testfile_st.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Kyle E Niemeyer 4 | 5 | 1 6 | 0 7 | 8 | 9 | 1 10 | 0 11 | 12 | Ignition delay measurement 13 | 15 | 16 | shock tube 17 | 18 | 19 | 20 | 2.18 21 | 22 | 23 | 24 | 25 | 0.00444 26 | 27 | 28 | 29 | 0.00566 30 | 31 | 32 | 33 | 0.9899 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 1164.48 43 | 471.54 44 | 45 | 46 | 1164.97 47 | 448.03 48 | 49 | 50 | 1264.2 51 | 291.57 52 | 53 | 54 | 1332.57 55 | 205.93 56 | 57 | 58 | 1519.18 59 | 88.11 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /pyked/schemas/chemked_schema.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ###################################################### 3 | # Put extra schema files to include here. All included 4 | # files must go at the top of this file. 5 | # value_unit_schema.yaml and composition_schema.yaml 6 | # must be the first two includes. 7 | !include value_unit_schema.yaml 8 | !include composition_schema.yaml 9 | !include ignition_delay_schema.yaml 10 | ###################################################### 11 | 12 | # Common reference for authors' information 13 | author: &author 14 | type: dict 15 | required: true 16 | isvalid_orcid: true 17 | schema: 18 | ORCID: 19 | type: string 20 | name: 21 | required: true 22 | type: string 23 | 24 | # Start the ChemKED schema 25 | common-properties: 26 | type: dict 27 | schema: 28 | pressure: *value-unit-optional 29 | ignition-type: *ignition-type 30 | composition: *composition 31 | pressure-rise: *value-unit-optional 32 | 33 | apparatus: 34 | required: true 35 | type: dict 36 | schema: 37 | kind: 38 | allowed: 39 | - shock tube 40 | - rapid compression machine 41 | required: true 42 | type: string 43 | institution: 44 | type: string 45 | facility: 46 | type: string 47 | datapoints: 48 | required: true 49 | oneof: 50 | - *ignition-delay-schema 51 | reference: 52 | required: true 53 | type: dict 54 | isvalid_reference: true 55 | schema: 56 | volume: 57 | min: 0 58 | type: integer 59 | journal: 60 | type: string 61 | doi: 62 | type: string 63 | authors: 64 | type: list 65 | required: true 66 | minlength: 1 67 | schema: *author 68 | detail: 69 | type: string 70 | year: 71 | min: 1600 72 | required: true 73 | type: integer 74 | pages: 75 | type: string 76 | chemked-version: # TODO: Implement proper version comparison 77 | allowed: 78 | - 0.0.1 79 | - 0.1.0 80 | - 0.1.1 81 | - 0.1.2 82 | - 0.1.3 83 | - 0.1.4 84 | - 0.1.5 85 | - 0.1.6 86 | - 0.2.0 87 | - 0.2.1 88 | - 0.3.0 89 | - 0.4.0 90 | - 0.4.1 91 | required: true 92 | type: string 93 | experiment-type: 94 | allowed: 95 | - ignition delay 96 | required: true 97 | type: string 98 | file-authors: 99 | type: list 100 | required: true 101 | minlength: 1 102 | schema: *author 103 | file-version: 104 | required: true 105 | type: integer 106 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PyKED 2 | 3 | 4 | [![DOI](https://zenodo.org/badge/66023863.svg)](https://zenodo.org/badge/latestdoi/66023863) 5 | [![Travis Build Status](https://travis-ci.org/pr-omethe-us/PyKED.svg?branch=master)](https://travis-ci.org/pr-omethe-us/PyKED) 6 | [![Appveyor Build status](https://ci.appveyor.com/api/projects/status/0paym07iygcfwoy7?svg=true)](https://ci.appveyor.com/project/Prometheus/pyked) 7 | [![codecov](https://codecov.io/gh/pr-omethe-us/PyKED/branch/master/graph/badge.svg)](https://codecov.io/gh/pr-omethe-us/PyKED) 8 | [![Dependency Status](https://dependencyci.com/github/pr-omethe-us/PyKED/badge)](https://dependencyci.com/github/pr-omethe-us/PyKED) 9 | [![Code of Conduct](https://img.shields.io/badge/code%20of%20conduct-contributor%20covenant-green.svg)](http://contributor-covenant.org/version/1/4/) 10 | [![License](https://img.shields.io/badge/license-BSD-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) 11 | [![Anaconda-Server Badge](https://anaconda.org/pr-omethe-us/pyked/badges/version.svg)](https://anaconda.org/pr-omethe-us/pyked) 12 | 13 | PyKED is a Python-based software package for validating and interacting with ChemKED (Chemical Kinetics Experimental Data format) files that describe fundamental experimental measurements of combustion phenomena. 14 | 15 | An installation guide, usage examples, and API docs are provided in the online documentation: https://pr-omethe-us.github.io/PyKED/ 16 | 17 | ## Code of Conduct 18 | 19 | In order to have a more open and welcoming community, PyKED adheres to a code of conduct adapted from the [Contributor Covenant](http://contributor-covenant.org) code of conduct. The code of conduct for PyKED is available in the GitHub Repository in the [CODE_OF_CONDUCT.md](https://github.com/pr-omethe-us/PyKED/blob/master/CODE_OF_CONDUCT.md) file. 20 | 21 | Please adhere to this code of conduct in any interactions you have in the PyKED community. It is strictly enforced on all official PyKED repositories, websites, and resources. If you encounter someone violating these terms, please let a maintainer ([@kyleniemeyer](https://github.com/kyleniemeyer), [@bryanwweber](https://github.com/bryanwweber), or via email at chemked@googlegroups.com) know and we will address it as soon as possible. 22 | 23 | ## License 24 | 25 | PyKED is released under the BSD-3 clause license, see [LICENSE](https://github.com/pr-omethe-us/PyKED/blob/master/LICENSE) for details. 26 | 27 | If you use this package as part of a scholarly work, please refer to [CITATION.md](https://github.com/pr-omethe-us/PyKED/blob/master/CITATION.md) for guidance on citing this resource. 28 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | We welcome contributions in the form of bug reports, bug fixes, improvements to the documentation, ideas for enhancements, or the enhancements themselves! 4 | 5 | You can find a [list of current issues](https://github.com/pr-omethe-us/PyKED/issues) in the project's GitHub repository. Feel free to tackle any existing bugs or enhancement ideas by submitting a [pull request](https://github.com/pr-omethe-us/PyKED/pulls). Some issues are marked as `beginner-friendly`. These issues are a great place to start working with PyKED and ChemKED, if you're new here. 6 | 7 | ## Bug Reports 8 | 9 | * Please include a short (but detailed) Python snippet or explanation for reproducing the problem. Attach or include a link to any input files that will be needed to reproduce the error. 10 | * Explain the behavior you expected, and how what you got differed. 11 | * Include the full text of any error messages that are printed on the screen. 12 | 13 | ## Pull Requests 14 | 15 | * If you're unfamiliar with Pull Requests, please take a look at the [GitHub documentation for them](https://help.github.com/articles/proposing-changes-to-a-project-with-pull-requests/). 16 | * **Make sure the test suite passes** on your computer, and that test coverage doesn't go down. To do this, run `pytest -vv --cov=./` from the top-level directory. 17 | * *Always* add tests and docs for your code. 18 | * The use of emoji in Pull Requests is encouraged with the format ":emoji: Commit summary". See [this list of suggested emoji.](https://github.com/slashsBin/styleguide-git-commit-message#suggested-emojis) 19 | * Please reference relevant GitHub issues in your commit messages using `GH123` or `#123`. 20 | * Changes should be [PEP8](https://www.python.org/dev/peps/pep-0008/) and [PEP257](https://www.python.org/dev/peps/pep-0257/) compatible. 21 | * Keep style fixes to a separate commit to make your pull request more readable. 22 | * Add your changes into the [`CHANGELOG`](https://github.com/pr-omethe-us/PyKED/blob/master/CHANGELOG.md) 23 | * Docstrings are required and should follow the [Google style](http://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html). 24 | * When you start working on a pull request, start by creating a new branch pointing at the latest commit on [GitHub master](https://github.com/pr-omethe-us/PyKED/tree/master). 25 | * The copyright policy is detailed in the [`LICENSE`](https://github.com/pr-omethe-us/PyKED/blob/master/LICENSE). 26 | 27 | ## Meta 28 | 29 | Thanks to the useful [contributing guide of pyrk](https://github.com/pyrk/pyrk/blob/master/CONTRIBUTING.md), which served as an inspiration and starting point for this guide. 30 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | from codecs import open 3 | from os import path 4 | import sys 5 | 6 | here = path.abspath(path.dirname(__file__)) 7 | 8 | with open(path.join(here, 'pyked', '_version.py')) as version_file: 9 | exec(version_file.read()) 10 | 11 | with open(path.join(here, 'README.md')) as readme_file: 12 | readme = readme_file.read() 13 | 14 | with open(path.join(here, 'CHANGELOG.md')) as changelog_file: 15 | changelog = changelog_file.read() 16 | 17 | with open(path.join(here, 'CITATION.md')) as citation_file: 18 | citation = citation_file.read() 19 | 20 | long_description = readme + '\n\n' + changelog + '\n\n' + citation 21 | 22 | install_requires = [ 23 | 'pyyaml>=3.12,<4.0', 24 | 'cerberus>=1.0.0,<1.2', 25 | 'pint>=0.7.2,<0.9', 26 | 'numpy>=1.11.0,<2.0', 27 | 'habanero>=0.6.0', 28 | 'uncertainties>=3.0.1,<3.1', 29 | ] 30 | 31 | tests_require = [ 32 | 'pytest>=3.2.0', 33 | 'pytest-cov', 34 | ] 35 | 36 | extras_require = { 37 | 'dataframes': ['pandas >=0.22.0,<0.23'], 38 | } 39 | 40 | needs_pytest = {'pytest', 'test', 'ptr'}.intersection(sys.argv) 41 | setup_requires = ['pytest-runner'] if needs_pytest else [] 42 | 43 | setup( 44 | name='pyked', 45 | version=__version__, 46 | description='Package for manipulating Chemical Kinetics Experimental Data (ChemKED) files.', 47 | long_description=long_description, 48 | long_description_content_type='text/markdown', 49 | author='Kyle Niemeyer', 50 | author_email='kyle.niemeyer@gmail.com', 51 | url='https://github.com/pr-omethe-us/PyKED', 52 | packages=['pyked', 'pyked.tests'], 53 | package_dir={'pyked': 'pyked'}, 54 | include_package_data=True, 55 | install_requires=install_requires, 56 | license='BSD-3-Clause', 57 | zip_safe=False, 58 | keywords=['chemical kinetics'], 59 | classifiers=[ 60 | 'Development Status :: 3 - Alpha', 61 | 'Intended Audience :: Developers', 62 | 'Intended Audience :: Science/Research', 63 | 'License :: OSI Approved :: BSD License', 64 | 'Natural Language :: English', 65 | 'Programming Language :: Python :: 3', 66 | 'Programming Language :: Python :: 3.5', 67 | 'Programming Language :: Python :: 3.6', 68 | 'Topic :: Scientific/Engineering :: Chemistry', 69 | ], 70 | tests_require=tests_require, 71 | extras_require=extras_require, 72 | setup_requires=setup_requires, 73 | python_requires='~=3.5', 74 | entry_points={ 75 | 'console_scripts': ['convert_ck=pyked.converters:main', 76 | 'respth2ck=pyked.converters:respth2ck', 77 | 'ck2respth=pyked.converters:ck2respth', 78 | ], 79 | } 80 | ) 81 | -------------------------------------------------------------------------------- /pyked/tests/testfile_bad.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | file-authors: 3 | - name: B. Author 4 | file-version: 0 5 | chemked-version: 0.0.1 6 | reference: 7 | authors: 8 | - name: A. Author 9 | journal: Testing Journal 10 | year: 1600 11 | experiment-type: ignition delay 12 | apparatus: 13 | kind: shock tube 14 | datapoints: 15 | # Mole fractions don't sum to 1 16 | - temperature: 17 | - 1164.48 kelvin 18 | ignition-delay: 19 | - 471.54 us 20 | pressure: 21 | - 220 kilopascal 22 | composition: 23 | kind: mole fraction 24 | species: 25 | - species-name: H2 26 | InChI: 1S/H2/h1H 27 | amount: 28 | - 0.1 29 | - species-name: O2 30 | InChI: 1S/O2/c1-2 31 | amount: 32 | - 0.1 33 | - species-name: Ar 34 | InChI: 1S/Ar 35 | amount: 36 | - 0.1 37 | ignition-type: 38 | target: pressure 39 | type: d/dt max 40 | # Mass fractions don't sum to 1 41 | - temperature: 42 | - 1164.48 kelvin 43 | ignition-delay: 44 | - 471.54 us 45 | pressure: 46 | - 220 kilopascal 47 | composition: 48 | kind: mass fraction 49 | species: 50 | - species-name: H2 51 | InChI: 1S/H2/h1H 52 | amount: 53 | - 0.1 54 | - species-name: O2 55 | InChI: 1S/O2/c1-2 56 | amount: 57 | - 0.1 58 | - species-name: Ar 59 | InChI: 1S/Ar 60 | amount: 61 | - 0.1 62 | ignition-type: 63 | target: pressure 64 | type: d/dt max 65 | # Mole percents don't sum to 100 66 | - temperature: 67 | - 1164.48 kelvin 68 | ignition-delay: 69 | - 471.54 us 70 | pressure: 71 | - 220 kilopascal 72 | composition: 73 | kind: mole percent 74 | species: 75 | - species-name: H2 76 | InChI: 1S/H2/h1H 77 | amount: 78 | - 10.0 79 | - species-name: O2 80 | InChI: 1S/O2/c1-2 81 | amount: 82 | - 10.0 83 | - species-name: Ar 84 | InChI: 1S/Ar 85 | amount: 86 | - 10.0 87 | ignition-type: 88 | target: pressure 89 | type: d/dt max 90 | # Mulitiple types of quantity specification 91 | - temperature: 92 | - 1164.48 kelvin 93 | ignition-delay: 94 | - 471.54 us 95 | pressure: 96 | - 220 kilopascal 97 | composition: 98 | kind: mole fraction 99 | species: 100 | - species-name: H2 101 | InChI: 1S/H2/h1H 102 | amount: 103 | - 10.0 104 | - species-name: O2 105 | InChI: 1S/O2/c1-2 106 | amount: 107 | - 0.1 108 | - species-name: Ar 109 | InChI: 1S/Ar 110 | amount: 111 | - 0.1 112 | ignition-type: 113 | target: pressure 114 | type: d/dt max 115 | ... 116 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | env: 3 | global: 4 | - secure: "BJScAQqZ93wF2MTL/52lsz9NN7einCoKC5SvdOzQ+MBGO6DOdEql3DqHPrys5xUHX0bejvdVbknS4GP5lRM+iv0+TF7jGz1FGCOA33WocOXMM7GxGAZq3Arnk9R2efNc0RplnF0kVQqOKa1hYtLmFCf9SZRltKCScewr1vKKf8k4R9egciSK+QTFZa+njCxFEVYJAOyifCukqcPRx1L7hJn2od0oaRctSRWhdWl8gPKAP4JLMdWqgmXEuDG3pTm8vq6JM2W7fhEXdlNr8P+txowGKBDw47m0LJc9q6ReH7FnqcpWMXdsIxGEeBd1nzvpqeNbBSKFwcEjqWKMqeImaySaVvSbcnLFZzU2MPb20sWRGiqP1oN8scQDnTG57hL/DeVY6gM7SFXZxD3akpvl865zNO9PlG4sCdANZv/ZEwSqAcMEQAXa32R1//iP+36HB6PHcNbDsi3o17/kfJRBnG7EFeLMfapyM1WiD5FJ39nS7MaLAIDFYus68J+VK/szpUjpL0623l2+RbmcQ660WGR+RV5mL/n6xtcCOTKnGRiVhvnYpqTAvU+jg2DBXlXWGTztZCqPoOHBtlVA+vwO7SYTl3W1/2ECPP6ogx6YRYjcasD/sj8Z8P8cbtpqSmPwR0D7J+vz+DX8qf01aG3NETcgGXhFq6i/WpRbUEXpK1U=" 5 | - secure: "xO8U5JnHh+suRr0sSY7blEzyYPbO0SlzrMosKEq7Ohn3FBKV3FH51OfplG6vDI3FWs6q7mmTABsAnEq+ExypqOLPGno2xdEOs3isq0JV+OvoUVtSTyBE+DaM6kTEM7O1hLN361J+VKoKJ5c9SG9rv1+GtT2FNeONy86zC/nKyowe3ywMBUQBp+wm6g/OWsdsOlYm1n8f6U5E8AEdMWGuXe+BfjGsl1rUJdfLpl9H0Xyb7q1kFQcffZSls2vjmoTxvdmD3mLz6JsC+hBX3wGPD6929eC4puAffuTwFtlufJSvYYOYm36/gakzgpPATWlpCqXCKNUR/gj/dkesUcRqUJTKS0riy+7+OpeOI3y5UT+/bXuTA1+J/w6oRyg85jLMxrnSOBOV6kVQfbLHqSSmup2N/8chlPlAz66Cg7j4NqdZ9yvz9hQCgv0KzXmzefHcXqNrQ9tCSwbpO0xyItcHAXAuMRXk4mNeweIaisrXMbnnbclM5PVyRSpHDMwAURzxZ7bkw9qq4CH1gh6Uxso4ARy7aojItwZCJydUDDJqTx5BwooKcalIJzpExij+sBjTwjY6qAsb2cDiPJ4hS/pjMdmr9ZeN6JrfuVjMrqb2jHS9M0ZRfYm6KDLoR04ZPF/pOncWSs8DYft+6P+24hZ6AXvp2xlU5dYw+N6r+PPF4nY=" 6 | 7 | language: generic 8 | 9 | matrix: 10 | include: 11 | - os: linux 12 | env: PYTHON="3.5" 13 | 14 | - os: linux 15 | env: PYTHON="3.6" 16 | 17 | - os: osx 18 | env: PYTHON="3.5" 19 | 20 | - os: osx 21 | env: PYTHON="3.6" 22 | 23 | install: 24 | - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then 25 | wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh; 26 | elif [[ "$TRAVIS_OS_NAME" == "osx" ]]; then 27 | wget https://repo.continuum.io/miniconda/Miniconda3-latest-MacOSX-x86_64.sh -O miniconda.sh; 28 | fi 29 | - bash miniconda.sh -b -p $HOME/miniconda 30 | - rm miniconda.sh 31 | - source $HOME/miniconda/etc/profile.d/conda.sh && conda activate 32 | - conda config --set always_yes yes --set changeps1 no 33 | - conda update -q conda 34 | - conda update -q --all 35 | - conda config --append channels conda-forge 36 | - if [[ -z "$TRAVIS_TAG" ]]; then 37 | sed -i -e "s/\${PYTHON}/"${PYTHON}"/" test-environment.yaml; 38 | conda env create -qf test-environment.yaml; 39 | conda activate py${PYTHON}; 40 | else 41 | if [[ "$PYTHON" == "3.6" && "$TRAVIS_OS_NAME" == "linux" ]]; then 42 | conda env update -qn base -f build-environment.yaml; 43 | fi 44 | fi 45 | # Useful for debugging any issues with conda 46 | - conda info -a 47 | - conda list 48 | 49 | # command to run tests 50 | script: 51 | - set -e 52 | - if [[ -z "$TRAVIS_TAG" ]]; then 53 | pytest -vv --cov=./; 54 | flake8 .; 55 | fi 56 | - set +e 57 | 58 | after_success: 59 | - if [[ -z "$TRAVIS_TAG" ]]; then 60 | bash <(curl -s https://codecov.io/bash); 61 | fi 62 | -------------------------------------------------------------------------------- /docs/releases.rst: -------------------------------------------------------------------------------- 1 | .. _releases: 2 | 3 | ======== 4 | Releases 5 | ======== 6 | 7 | v0.4.1 - 2018-03-09 8 | ------------------- 9 | * `Documentation `__ 10 | * `Changelog `__ 11 | * `Zenodo `__ 12 | 13 | v0.4.0 - 2018-03-07 14 | ------------------- 15 | * `Documentation `__ 16 | * `Changelog `__ 17 | * `Zenodo `__ 18 | 19 | v0.3.0 - 2017-10-09 20 | ------------------- 21 | * `Documentation `__ 22 | * `Changelog `__ 23 | * `Zenodo `__ 24 | 25 | v0.2.1 - 2017-08-31 26 | ------------------- 27 | * `Documentation `__ 28 | * `Changelog `__ 29 | * `Zenodo `__ 30 | 31 | v0.2.0 - 2017-08-10 32 | ------------------- 33 | * `Documentation `__ 34 | * `Changelog `__ 35 | * `Zenodo `__ 36 | 37 | v0.1.6 - 2017-07-17 38 | ------------------- 39 | * `Documentation `__ 40 | * `Changelog `__ 41 | * `Zenodo `__ 42 | 43 | v0.1.5 - 2017-05-22 44 | ------------------- 45 | * `Documentation `__ 46 | * `Changelog `__ 47 | * `Zenodo `__ 48 | 49 | v0.1.4 - 2017-04-21 50 | ------------------- 51 | * `Documentation `__ 52 | * `Changelog `__ 53 | * `Zenodo `__ 54 | 55 | v0.1.3 - 2017-04-13 56 | ------------------- 57 | * `Documentation `__ 58 | * `Changelog `__ 59 | * `Zenodo `__ 60 | 61 | v0.1.2 - 2017-04-13 62 | ------------------- 63 | * `Documentation `__ 64 | * `Changelog `__ 65 | * `Zenodo `__ 66 | 67 | v0.1.1 - 2017-04-02 68 | ------------------- 69 | * `Documentation `__ 70 | * `Changelog `__ 71 | * `Zenodo `__ 72 | 73 | v0.1.0 - 2017-04-02 74 | ------------------- 75 | * `Documentation `__ 76 | * `Changelog `__ 77 | * `Zenodo `__ 78 | -------------------------------------------------------------------------------- /pyked/tests/rcm_history.csv: -------------------------------------------------------------------------------- 1 | 0.00E+000, 5.47669375000E+002 2 | 1.00E-003, 5.46608789894E+002 3 | 2.00E-003, 5.43427034574E+002 4 | 3.00E-003, 5.38124109043E+002 5 | 4.00E-003, 5.30700013298E+002 6 | 5.00E-003, 5.21154747340E+002 7 | 6.00E-003, 5.09488311170E+002 8 | 7.00E-003, 4.95700704787E+002 9 | 8.00E-003, 4.79791928191E+002 10 | 9.00E-003, 4.61761981383E+002 11 | 1.00E-002, 4.41610864362E+002 12 | 1.10E-002, 4.20399162234E+002 13 | 1.20E-002, 3.99187460106E+002 14 | 1.30E-002, 3.77975757979E+002 15 | 1.40E-002, 3.56764055851E+002 16 | 1.50E-002, 3.35552353723E+002 17 | 1.60E-002, 3.14340651596E+002 18 | 1.70E-002, 2.93128949468E+002 19 | 1.80E-002, 2.71917247340E+002 20 | 1.90E-002, 2.50705545213E+002 21 | 2.00E-002, 2.29493843085E+002 22 | 2.10E-002, 2.08282140957E+002 23 | 2.20E-002, 1.87070438830E+002 24 | 2.30E-002, 1.65858736702E+002 25 | 2.40E-002, 1.44647034574E+002 26 | 2.50E-002, 1.23435332447E+002 27 | 2.60E-002, 1.02223630319E+002 28 | 2.70E-002, 8.10119281915E+001 29 | 2.80E-002, 6.33355097518E+001 30 | 2.90E-002, 5.27296586879E+001 31 | 3.00E-002, 4.91943750000E+001 32 | 3.10E-002, 4.97137623933E+001 33 | 3.20E-002, 5.02063762048E+001 34 | 3.30E-002, 5.06454851923E+001 35 | 3.40E-002, 5.10218564529E+001 36 | 3.50E-002, 5.13374097598E+001 37 | 3.60E-002, 5.16004693977E+001 38 | 3.70E-002, 5.18223244382E+001 39 | 3.80E-002, 5.20148449242E+001 40 | 3.90E-002, 5.21889350372E+001 41 | 4.00E-002, 5.23536351113E+001 42 | 4.10E-002, 5.25157124459E+001 43 | 4.20E-002, 5.26796063730E+001 44 | 4.30E-002, 5.28476160610E+001 45 | 4.40E-002, 5.30202402028E+001 46 | 4.50E-002, 5.31965961563E+001 47 | 4.60E-002, 5.33748623839E+001 48 | 4.70E-002, 5.35527022996E+001 49 | 4.80E-002, 5.37276399831E+001 50 | 4.90E-002, 5.38973687732E+001 51 | 5.00E-002, 5.40599826225E+001 52 | 5.10E-002, 5.42141273988E+001 53 | 5.20E-002, 5.43590751578E+001 54 | 5.30E-002, 5.44947289126E+001 55 | 5.40E-002, 5.46215686913E+001 56 | 5.50E-002, 5.47405518236E+001 57 | 5.60E-002, 5.48529815402E+001 58 | 5.70E-002, 5.49603582190E+001 59 | 5.80E-002, 5.50642270863E+001 60 | 5.90E-002, 5.51660349836E+001 61 | 6.00E-002, 5.52670070646E+001 62 | 6.10E-002, 5.53680520985E+001 63 | 6.20E-002, 5.54697025392E+001 64 | 6.30E-002, 5.55720927915E+001 65 | 6.40E-002, 5.56749762728E+001 66 | 6.50E-002, 5.57777790517E+001 67 | 6.60E-002, 5.58796851466E+001 68 | 6.70E-002, 5.59797461155E+001 69 | 6.80E-002, 5.60770054561E+001 70 | 6.90E-002, 5.61706266985E+001 71 | 7.00E-002, 5.62600130036E+001 72 | 7.10E-002, 5.63449057053E+001 73 | 7.20E-002, 5.64254496625E+001 74 | 7.30E-002, 5.65022146282E+001 75 | 7.40E-002, 5.65761642150E+001 76 | 7.50E-002, 5.66485675508E+001 77 | 7.60E-002, 5.67208534842E+001 78 | 7.70E-002, 5.67944133373E+001 79 | 7.80E-002, 5.68703658198E+001 80 | 7.90E-002, 5.69493069272E+001 81 | 8.00E-002, 5.70310785669E+001 82 | 8.10E-002, 5.71146023893E+001 83 | 8.20E-002, 5.71978399741E+001 84 | 8.30E-002, 5.72779572372E+001 85 | 8.40E-002, 5.73517897984E+001 86 | 8.50E-002, 5.74167271960E+001 87 | 8.60E-002, 5.74721573687E+001 88 | 8.70E-002, 5.75216388520E+001 89 | 8.80E-002, 5.75759967785E+001 90 | 8.90E-002, 5.76575701358E+001 91 | 9.00E-002, 5.78058719368E+001 92 | 9.10E-002, 5.80849611077E+001 93 | 9.20E-002, 5.85928651155E+001 94 | 9.30E-002, 5.94734357453E+001 95 | 9.40E-002, 6.09310671165E+001 96 | 9.50E-002, 6.32487551103E+001 97 | 9.60E-002, 6.68100309742E+001 98 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | nationality, personal appearance, race, religion, or sexual identity and 10 | orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at chemked@googlegroups.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at [http://contributor-covenant.org/version/1/4][version] 72 | 73 | [homepage]: http://contributor-covenant.org 74 | [version]: http://contributor-covenant.org/version/1/4/ 75 | -------------------------------------------------------------------------------- /pyked/schemas/composition_schema.yaml: -------------------------------------------------------------------------------- 1 | # Common reference for composition schema 2 | composition: &composition 3 | isvalid_composition: true 4 | type: dict 5 | schema: 6 | kind: 7 | type: string 8 | allowed: ['mass fraction', 'mole fraction', 'mole percent'] 9 | species: 10 | type: list 11 | required: true 12 | minlength: 1 13 | schema: 14 | type: dict 15 | required: true 16 | schema: 17 | species-name: 18 | type: string 19 | required: true 20 | thermo: 21 | type: dict 22 | schema: 23 | T_ranges: 24 | type: list 25 | required: true 26 | isvalid_t_range: true 27 | items: 28 | - oneof_type: 29 | - number 30 | - string 31 | - oneof_type: 32 | - number 33 | - string 34 | - oneof_type: 35 | - number 36 | - string 37 | data: 38 | type: list 39 | required: true 40 | items: 41 | - type: number 42 | - type: number 43 | - type: number 44 | - type: number 45 | - type: number 46 | - type: number 47 | - type: number 48 | - type: number 49 | - type: number 50 | - type: number 51 | - type: number 52 | - type: number 53 | - type: number 54 | - type: number 55 | note: 56 | type: string 57 | InChI: 58 | type: string 59 | required: true 60 | excludes: 61 | - atomic-composition 62 | - SMILES 63 | SMILES: 64 | type: string 65 | required: true 66 | excludes: 67 | - atomic-composition 68 | - InChI 69 | atomic-composition: 70 | type: list 71 | minlength: 1 72 | required: true 73 | excludes: 74 | - InChI 75 | - SMILES 76 | schema: 77 | type: dict 78 | schema: 79 | element: 80 | type: string 81 | amount: 82 | type: float 83 | min: 0.0 84 | # TODO: option for float or int? 85 | amount: 86 | required: true 87 | type: list 88 | oneof: 89 | - items: 90 | - type: float 91 | - items: 92 | - type: float 93 | - type: dict 94 | schema: 95 | uncertainty-type: 96 | required: true 97 | type: string 98 | allowed: 99 | - absolute 100 | - relative 101 | uncertainty: 102 | required: true 103 | type: float 104 | excludes: 105 | - upper-uncertainty 106 | - lower-uncertainty 107 | upper-uncertainty: 108 | required: true 109 | type: float 110 | excludes: uncertainty 111 | dependencies: lower-uncertainty 112 | lower-uncertainty: 113 | required: true 114 | type: float 115 | excludes: uncertainty 116 | dependencies: upper-uncertainty 117 | -------------------------------------------------------------------------------- /pyked/tests/testfile_uncertainty.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | file-authors: 3 | - name: B. Author 4 | file-version: 0 5 | chemked-version: 0.0.1 6 | reference: 7 | authors: 8 | - name: A. Author 9 | journal: Testing Journal 10 | year: 1600 11 | experiment-type: ignition delay 12 | apparatus: 13 | kind: shock tube 14 | datapoints: 15 | - temperature: 16 | - 1164.48 kelvin 17 | - uncertainty-type: absolute 18 | uncertainty: 10 kelvin 19 | ignition-delay: 20 | - 471.54 us 21 | pressure: 22 | - 220 kilopascal 23 | composition: 24 | kind: mole percent 25 | species: 26 | - species-name: H2 27 | InChI: 1S/H2/h1H 28 | amount: 29 | - 0.444 30 | - uncertainty-type: relative 31 | uncertainty: 0.01 32 | - species-name: O2 33 | InChI: 1S/O2/c1-2 34 | amount: 35 | - 0.556 36 | - uncertainty-type: absolute 37 | uncertainty: 0.002 38 | - species-name: Ar 39 | InChI: 1S/Ar 40 | amount: 41 | - 99.0 42 | - uncertainty-type: absolute 43 | upper-uncertainty: 1.0 44 | lower-uncertainty: 0.2 45 | ignition-type: 46 | target: pressure 47 | type: d/dt max 48 | - temperature: 49 | - 1164.48 kelvin 50 | ignition-delay: 51 | - 471.54 us 52 | - uncertainty-type: relative 53 | uncertainty: 0.1 54 | pressure: 55 | - 220 kilopascal 56 | composition: 57 | kind: mole percent 58 | species: 59 | - species-name: H2 60 | InChI: 1S/H2/h1H 61 | amount: 62 | - 0.444 63 | - uncertainty-type: relative 64 | upper-uncertainty: 0.01 65 | lower-uncertainty: 0.1 66 | - species-name: O2 67 | InChI: 1S/O2/c1-2 68 | amount: 69 | - 0.556 70 | - uncertainty-type: relative 71 | upper-uncertainty: 0.1 72 | lower-uncertainty: 0.01 73 | - species-name: Ar 74 | InChI: 1S/Ar 75 | amount: 76 | - 99.0 77 | - uncertainty-type: absolute 78 | upper-uncertainty: 0.2 79 | lower-uncertainty: 1.0 80 | ignition-type: 81 | target: pressure 82 | type: d/dt max 83 | - temperature: 84 | - 1164.48 kelvin 85 | - uncertainty-type: absolute 86 | upper-uncertainty: 10 kelvin 87 | lower-uncertainty: 5 kelvin 88 | ignition-delay: 89 | - 471.54 us 90 | - uncertainty-type: absolute 91 | upper-uncertainty: 3 us 92 | lower-uncertainty: 10 us 93 | pressure: 94 | - 220 kilopascal 95 | composition: 96 | kind: mole percent 97 | species: 98 | - species-name: H2 99 | InChI: 1S/H2/h1H 100 | amount: 101 | - 0.444 102 | - species-name: O2 103 | InChI: 1S/O2/c1-2 104 | amount: 105 | - 0.556 106 | - species-name: Ar 107 | InChI: 1S/Ar 108 | amount: 109 | - 99.0 110 | ignition-type: 111 | target: pressure 112 | type: d/dt max 113 | - temperature: 114 | - 1164.48 kelvin 115 | - uncertainty-type: relative 116 | upper-uncertainty: 0.05 117 | lower-uncertainty: 0.1 118 | ignition-delay: 119 | - 471.54 us 120 | - uncertainty-type: relative 121 | upper-uncertainty: 0.1 122 | lower-uncertainty: 0.05 123 | pressure: 124 | - 220 kilopascal 125 | composition: 126 | kind: mole percent 127 | species: 128 | - species-name: H2 129 | InChI: 1S/H2/h1H 130 | amount: 131 | - 0.444 132 | - species-name: O2 133 | InChI: 1S/O2/c1-2 134 | amount: 135 | - 0.556 136 | - species-name: Ar 137 | InChI: 1S/Ar 138 | amount: 139 | - 99.0 140 | ignition-type: 141 | target: pressure 142 | type: d/dt max 143 | ... 144 | -------------------------------------------------------------------------------- /github_deploy_key.enc: -------------------------------------------------------------------------------- 1 | gAAAAABY3rNQV4qexf9uoWy7axyMsA-YEcji084VFbHacLHh5Wy17a_m_HBfQIWdGHb-JBSVFt8CaTyKpCuGGwDHwPYcSWn0vC5WNTod__p_Q0GUnjLU85o1lJS8eVSRu248jAJD2F6XcQiMT07z4da62WLERZ_B-IINPYP8dv1N8I51LhiCvgMcLnNWM7_qt70iNIXnG3-TFb7-qSwhNTPmNpEAgvAR1RU83nRVK8OBJvHkYm7GdeEJMyJT4hI4Q6bi-iY-6uNDQ998KgKW2CZu0wgbzLaFF81K7d6H4UEIwfxLyU1no1mq6dR_cgw4FHmUzj55mOq7u6cpU7sw0RgJHXn25uP-EtJkwEuIghyGSE1PtPhGQzkElG9T5zJWRX0RIMQxP3LS6lp2VvdgffugKUqJts-otX9orA5X7uX_AXr04rqWuskYJgtj3SCG2lhlnODkY5kriNLRL_QSmr26MQajC11Xj2pzF1gwOgWwqZOvyl6_LBTInWmlS1pm_wCMpKQtF156KzBS9x8CVJbRjA0HhrmUk5vRWNaIrv2wNjMmqYwqfQkm5wxxXowQXz0upkOoXYoP-4RA5rgpjIy_BzfPsEaeRR9CiK5JbKjnHAEDo_pgSStKsRf1Kh52Tg_q0BN7e0o18YtwscR7s0FIHqQLgY1TgG5IFTnwZLyRevGAdxMtvs1b4rEdEHRM_f6MAwLWazGEKvJ-QDIq8tRqMg9lxmo-eCM51XK17ePMVv-yj2omY9pnq_DQOBb-2Rs6cEOgjjN0q4n-pPcRqWxKxhZUbg3apUSLSzfV8DsOlqUOxTk3aYocOuw7DQYR5yea7ZiP4srv9Q73I3ua71HfyyF9TT5weyfAOV6cfruz72pjugQaAqy-XtS6QY5CTJ2tL7r1qY4OD76IZ_YUJ1-ix1yiGejfZUjQknHZgAHJ5ZMeR8AOCYHKToyF90dyyU4g2iGpENCDZMJhWaviOqYR7jsWRuiGkMDw2dVKhFn_Tou_Xsm8Sr-6TdiYWS91mL-FpLy_bVI2vKMHKYBdEpRH2n-W0ucD6qyDi1V4zqlRSo38UbZXza03EgtDzy-wXs1P9kIvLiyRtARoe4IpnXRu335_rls5CmFDLM0nZRf8QMP13Ddq0nEYj8PZBmYIJ2n78grtz26WJxZlisSbTe576AZv2BgLUy029DoVdssyTgrSaZjSLwD2zrghL_T8vAcB2SjRNo73mm4vL2YueQt_qvwdiQIfTkkxNMJQW8t8K33vnW9RE8bBPcAhwlcy3tc790-TD2Zz1I1_IDaJmNVujE1Wt-fGS8nP8VWZLZ6fx8RIkMl3zPEx-lygsxJRkGgocoi4B9I6XIDpI9V_9ObmpAH0UXUIpaVnVOx7blLWC3rryS5SozbqchUN6DK-VHtPc9dTnfaeaoWuqp4uCX1mJ_WKgFifgTqvP2h93vgpIbNZtGPbQohSV2WEamfmrPeLOscNR4NSJCQUPkDNZYDRWjGlGmi1yr2ivIlNn-HWIp9tDbMJoN1iGifuPROTezojq1sGlehpoobhRrYFwReSS8Vzwnqb5hNxbK7nosU-IsGi22Kr_38ONGKsd0qE0hH9nzyGUZE00Q5XpHox4MldeB4xRGHhUq5Z233IyG6s0LSoxOBU_InXTj2CXJEnIurjN5KMzpmTWzt4s26jTs-MIQrFOlfY4uqR9e63V--Em6DO6OEHL5zjYIelS2NZqaWxOMC0GLfyk5kwUsRGIVtYkGqLp2wS71QNNV-hx6GybpsQKXJDSjwRGZzL74W6MZWn92sH5eeyua4buqDIL6RtkqzR1AA1Q8gW8_h7TQuGcQnIO7pt2_RODvXxyqv7hZVZApvToJr6dgVnSpFjhxyVie1nqjdybanWjMopffTJq7pNR4UciBTt-uFaPsaUP6C7MJSlQ9hrE-a1O9XX7BhkC2y0HBCevebFUAmXpXba5dXkCMY8K_m_cH03VmqR1_TDj2AI87toLTSiu9WblVM833Y6YNkAGrv5ELvwLHwyfa52Ar4HaFRYyF6_udNq7YdK9pzhfyuRkzyFbcAatyXwLiLRgHNn_sBF0_7Yq6tDCdas-0crmjyAkX1COg8P31c1oua3hlk6Ptv1Fqzb7ey5EpfBsA9ydXhOoRFIVJqCAoZXRBc-IvGCPgjEDtmALpvxAvFd84ouO_hBaWrOTfwZyTi1iZ0yw7WgBCXfb9nFYrkD1Lx9GCWAs-6BcN8JVvurxVyAaREmGCk1KfNXQ6Gw9eVYAK79XV2SHnDy4odNxEYqK1gMWZBtv18dZBu_31tZDb7VexZDbwh6sZegnKG-_QxKKx39TdAOMhwL_iyVdc_KwpwUTI6xXidlxU4DWea5uso12_NDIowySbuil2I67IzmnEL4g5ZeMyHLBpGO8EtdrS2Hmj7ac40j5zH3GZy6JZ9yzwohmKJ727_sMRrotpCzY4xycAITrFizmTZeBnliHXZzQTnt0_T21j8qir4cRm1ipkpev1RfS9R7oewAXxZ9dVnI3CS7hKxomKS9kNg9dL1drolJZvSE7qMppfNaJkPf3JqbVeE24Pfq-ejO8io9GITZaPAwG7cPqKe1Q7wZEM4k2q6JkA-yetHzToBx9GaFbd4ZL5La9jLygnvBtqIyv687NA6LztC73tvTnEIhwy9DCjlqyu5rrgNB_u0FElTIFsIGCZNXZ58dlGY_gY5x9ciQwa80SleY4X_Z6MQcmBlcBLy1cNCQDhHJuPxf-ZDGm6xIoNrcLLZj7rnTkl_On16YJrQ1xu4Q_VxiaFLit9TcFXXzpbBqzBDkEpUSuY4kF4lnR3GCqpAZqtBPgjmZIf_89zkqqolIdX4vAbZ-XCByrkCJCpEuvXCpt5kfAmUyLUwDunInLqjxEH47c-YkCqaFqUp7vJaSTEomcE1Fb9HfAkrQsP6BA1q2QkrgjeGuSg9gt0ZsTHZ5x4L-u0fOb-i112JnA3w9zRCb40QByFb-yg_PgUT97QUjNqUgiFZVZ14KPwjhq3_sE0o9L0Lwm0w6brDnrGkt0cOWnqu2UNxfgIU7LDtDIO1N7OrOl3v3kypRYTAMhpkHAbnqJJI130VJpScYp8RIGoqE2CvObV78aYLi6B4RSHQQy5hPbo7SorjDmr_RsQWKyH8HIJl5xqdpTkn-yn-rL8PW4xqUBdPIAcMglKpfhFdEcblPx3Cd3JkaElWoLQX6V3tAa539vKbGY6LhU0ddWiXIPdUGGtMw1kKmuovRDdqwpLCfJr_HsmSaM41SVbQTNU4WNEWi1rRKw1kGsyAUSCyW3XFdXozOIyjra2fA8ndNdLWgWCUfi3we7wsqxeBUQl0IZ8iWJEL4CU0upgFRzkdO7Tf27A_3x6Rfj_GJcB_uLdCscNyrvAUL-2jv75RxSJYCfnnLs9DDVFInCRpgDlenVerMkGkyQy0WtMwxKKHeKweEx1TutHvFYdpDvyIqD2UMEdvcdjjUDIFZZVQZ2WEPDh7RCK3YXO-y8txxQMIIsi772e4wtzLfwU-zagHBluq59-utc7vB16BhsiOu1jn7Wgi7DpzIfTe0A85wOE7TmsLnciLrKGrnwl0rU4xKbNh4WAFYeUh63vUhW-Ls2CFdnE0Ji2coK-YBOxNSsA21N2r9UB005Fh3i9BeCkcXfI33jjrZe1Sx5nGNxdm2wfJNy3GHr9aCCYrgVVp0JWPs2qbh-10KSKnkr_xyXEVgIV0l_UGCnBH6zTQ3cHZy94dc44NyDc-Ck2lsvsqNpEt_1MPQ5p-Oatezb9Gp3DkMu4IE1fiVd4an7QxOIi1qLNn3SboTl2dd-D5n3_jLHaq1ebm1_8lxLkSeuDh60hC6MY8EXwFB7gVPkIt6jipxKO0l6HaJEzK6tHAp7xhZ1IIDERlY4AbedvZZzhXLH9atjmGNIibMtG7sgdRgZVdrcO-OmyZPXcKVgxSzQa8oFAvoHIQPMrNzLJwvExkTjIPe0k7CKwKen0XOgbOics0hqltk9Q7y__1OLbh4kixCJDRYs6KhFGuBKcfuOXLJm8xdue4Yvd3h6O6j-qBO8iEo1VGt_isTeUeADaU8DZErx0HJHjPfgFjv-nULmyyPJ9KVeH-_21LZbhsv6nWPjxNpRRwpABTioOEjXSX_xRMbvtjfavF9cxcQ_wKo5JEux9zMDQ-rI7h12NhgUMsfUO_8VvfrIJ9hEZRTM59iQElf9MkTg1ibwvawCpCKOkqkPfNZkfzEIdNmIBKfrk9bxF1qCZo0VelXU4MzBPQs_55vVsRBh-LsuiA2g75y6DLuXk4yIWPlFDKZ9b1aWhP-nIsMuAgYuDtn2I74pS5hE4-I0I7jWd_lxRaVapepalgWFH_uixa9FSnZiWXhj5H2dh0TRL305WMHjaC01FE= -------------------------------------------------------------------------------- /pyked/schemas/ignition_delay_schema.yaml: -------------------------------------------------------------------------------- 1 | # Common reference for ignition-type 2 | ignition-type: &ignition-type 3 | type: dict 4 | required: true 5 | schema: 6 | target: 7 | required: true 8 | type: string 9 | allowed: 10 | - temperature 11 | - pressure 12 | - OH 13 | - OH* 14 | - CH 15 | - CH* 16 | type: 17 | allowed: 18 | - d/dt max 19 | - max 20 | - 1/2 max 21 | - min 22 | - d/dt max extrapolated 23 | required: true 24 | type: string 25 | 26 | time-history: &time-history 27 | type: dict 28 | isvalid_history: true 29 | schema: 30 | type: 31 | required: true 32 | type: string 33 | allowed: 34 | - volume 35 | - temperature 36 | - pressure 37 | - piston position 38 | - light emission 39 | - OH emission 40 | - absorption 41 | quantity: 42 | required: true 43 | type: dict 44 | schema: 45 | units: 46 | required: true 47 | type: string 48 | column: 49 | required: true 50 | type: integer 51 | uncertainty: 52 | type: dict 53 | oneof_schema: 54 | - type: 55 | required: true 56 | type: string 57 | allowed: 58 | - relative 59 | - absolute 60 | value: 61 | required: true 62 | type: string 63 | - type: 64 | required: true 65 | type: string 66 | allowed: 67 | - relative 68 | - absolute 69 | column: 70 | required: true 71 | type: integer 72 | units: 73 | required: true 74 | type: string 75 | time: 76 | required: true 77 | type: dict 78 | schema: 79 | units: 80 | required: true 81 | type: string 82 | column: 83 | required: true 84 | type: integer 85 | values: 86 | required: true 87 | oneof: 88 | - type: list 89 | minlength: 2 90 | schema: 91 | type: list 92 | oneof_items: 93 | - - type: float 94 | - type: float 95 | - - type: float 96 | - type: float 97 | - type: float 98 | - type: dict 99 | schema: 100 | filename: 101 | type: string 102 | 103 | ignition-delay-schema: &ignition-delay-schema 104 | type: list 105 | minlength: 1 106 | schema: 107 | type: dict 108 | schema: 109 | pressure-rise: *value-unit-optional 110 | pressure: *value-unit-required 111 | ignition-type: *ignition-type 112 | ignition-delay: *value-unit-required 113 | first-stage-ignition-delay: *value-unit-optional 114 | rcm-data: 115 | type: dict 116 | schema: 117 | compressed-pressure: *value-unit-optional 118 | compressed-temperature: *value-unit-optional 119 | compression-time: *value-unit-optional 120 | stroke: *value-unit-optional 121 | clearance: *value-unit-optional 122 | compression-ratio: *value-unit-optional 123 | temperature: *value-unit-required 124 | composition: *composition 125 | equivalence-ratio: 126 | type: float 127 | min: 0.0 128 | time-histories: 129 | type: list 130 | minlength: 1 131 | schema: *time-history 132 | volume-history: 133 | type: dict 134 | schema: 135 | volume: 136 | required: true 137 | type: dict 138 | isvalid_unit: true 139 | schema: 140 | units: 141 | required: true 142 | type: string 143 | column: 144 | required: true 145 | type: integer 146 | allowed: [0, 1] 147 | time: 148 | required: true 149 | type: dict 150 | isvalid_unit: true 151 | schema: 152 | units: 153 | required: true 154 | type: string 155 | column: 156 | required: true 157 | type: integer 158 | allowed: [0, 1] 159 | values: 160 | required: true 161 | type: list 162 | schema: 163 | type: list 164 | items: 165 | - type: float 166 | - type: float 167 | -------------------------------------------------------------------------------- /pyked/tests/testfile_rcm_old.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | file-authors: 3 | - name: Kyle E Niemeyer 4 | ORCID: 0000-0003-4425-7097 5 | file-version: 0 6 | chemked-version: 0.0.1 7 | reference: 8 | doi: 10.1002/kin.20180 9 | authors: 10 | - name: Gaurav Mittal 11 | - name: Chih-Jen Sung 12 | ORCID: 0000-0003-2046-8076 13 | - name: Richard A Yetter 14 | journal: International Journal of Chemical Kinetics 15 | year: 2006 16 | volume: 38 17 | pages: 516-529 18 | detail: Fig. 6, open circle 19 | experiment-type: ignition delay 20 | apparatus: 21 | kind: rapid compression machine 22 | institution: Case Western Reserve University 23 | facility: CWRU RCM 24 | datapoints: 25 | - temperature: 26 | - 297.4 kelvin 27 | ignition-delay: 28 | - 1.0 ms 29 | pressure: 30 | - 958.0 torr 31 | composition: 32 | kind: mole fraction 33 | species: 34 | - species-name: H2 35 | InChI: 1S/H2/h1H 36 | amount: 37 | - 0.12500 38 | - species-name: O2 39 | InChI: 1S/O2/c1-2 40 | amount: 41 | - 0.06250 42 | - species-name: N2 43 | InChI: 1S/N2/c1-2 44 | amount: 45 | - 0.18125 46 | - species-name: Ar 47 | InChI: 1S/Ar 48 | amount: 49 | - 0.63125 50 | ignition-type: 51 | target: pressure 52 | type: d/dt max 53 | compression-time: 54 | - 38.0 ms 55 | volume-history: 56 | time: 57 | units: s 58 | column: 0 59 | volume: 60 | units: cm3 61 | column: 1 62 | values: 63 | - [0.00E+000, 5.47669375000E+002] 64 | - [1.00E-003, 5.46608789894E+002] 65 | - [2.00E-003, 5.43427034574E+002] 66 | - [3.00E-003, 5.38124109043E+002] 67 | - [4.00E-003, 5.30700013298E+002] 68 | - [5.00E-003, 5.21154747340E+002] 69 | - [6.00E-003, 5.09488311170E+002] 70 | - [7.00E-003, 4.95700704787E+002] 71 | - [8.00E-003, 4.79791928191E+002] 72 | - [9.00E-003, 4.61761981383E+002] 73 | - [1.00E-002, 4.41610864362E+002] 74 | - [1.10E-002, 4.20399162234E+002] 75 | - [1.20E-002, 3.99187460106E+002] 76 | - [1.30E-002, 3.77975757979E+002] 77 | - [1.40E-002, 3.56764055851E+002] 78 | - [1.50E-002, 3.35552353723E+002] 79 | - [1.60E-002, 3.14340651596E+002] 80 | - [1.70E-002, 2.93128949468E+002] 81 | - [1.80E-002, 2.71917247340E+002] 82 | - [1.90E-002, 2.50705545213E+002] 83 | - [2.00E-002, 2.29493843085E+002] 84 | - [2.10E-002, 2.08282140957E+002] 85 | - [2.20E-002, 1.87070438830E+002] 86 | - [2.30E-002, 1.65858736702E+002] 87 | - [2.40E-002, 1.44647034574E+002] 88 | - [2.50E-002, 1.23435332447E+002] 89 | - [2.60E-002, 1.02223630319E+002] 90 | - [2.70E-002, 8.10119281915E+001] 91 | - [2.80E-002, 6.33355097518E+001] 92 | - [2.90E-002, 5.27296586879E+001] 93 | - [3.00E-002, 4.91943750000E+001] 94 | - [3.10E-002, 4.97137623933E+001] 95 | - [3.20E-002, 5.02063762048E+001] 96 | - [3.30E-002, 5.06454851923E+001] 97 | - [3.40E-002, 5.10218564529E+001] 98 | - [3.50E-002, 5.13374097598E+001] 99 | - [3.60E-002, 5.16004693977E+001] 100 | - [3.70E-002, 5.18223244382E+001] 101 | - [3.80E-002, 5.20148449242E+001] 102 | - [3.90E-002, 5.21889350372E+001] 103 | - [4.00E-002, 5.23536351113E+001] 104 | - [4.10E-002, 5.25157124459E+001] 105 | - [4.20E-002, 5.26796063730E+001] 106 | - [4.30E-002, 5.28476160610E+001] 107 | - [4.40E-002, 5.30202402028E+001] 108 | - [4.50E-002, 5.31965961563E+001] 109 | - [4.60E-002, 5.33748623839E+001] 110 | - [4.70E-002, 5.35527022996E+001] 111 | - [4.80E-002, 5.37276399831E+001] 112 | - [4.90E-002, 5.38973687732E+001] 113 | - [5.00E-002, 5.40599826225E+001] 114 | - [5.10E-002, 5.42141273988E+001] 115 | - [5.20E-002, 5.43590751578E+001] 116 | - [5.30E-002, 5.44947289126E+001] 117 | - [5.40E-002, 5.46215686913E+001] 118 | - [5.50E-002, 5.47405518236E+001] 119 | - [5.60E-002, 5.48529815402E+001] 120 | - [5.70E-002, 5.49603582190E+001] 121 | - [5.80E-002, 5.50642270863E+001] 122 | - [5.90E-002, 5.51660349836E+001] 123 | - [6.00E-002, 5.52670070646E+001] 124 | - [6.10E-002, 5.53680520985E+001] 125 | - [6.20E-002, 5.54697025392E+001] 126 | - [6.30E-002, 5.55720927915E+001] 127 | - [6.40E-002, 5.56749762728E+001] 128 | - [6.50E-002, 5.57777790517E+001] 129 | - [6.60E-002, 5.58796851466E+001] 130 | - [6.70E-002, 5.59797461155E+001] 131 | - [6.80E-002, 5.60770054561E+001] 132 | - [6.90E-002, 5.61706266985E+001] 133 | - [7.00E-002, 5.62600130036E+001] 134 | - [7.10E-002, 5.63449057053E+001] 135 | - [7.20E-002, 5.64254496625E+001] 136 | - [7.30E-002, 5.65022146282E+001] 137 | - [7.40E-002, 5.65761642150E+001] 138 | - [7.50E-002, 5.66485675508E+001] 139 | - [7.60E-002, 5.67208534842E+001] 140 | - [7.70E-002, 5.67944133373E+001] 141 | - [7.80E-002, 5.68703658198E+001] 142 | - [7.90E-002, 5.69493069272E+001] 143 | - [8.00E-002, 5.70310785669E+001] 144 | - [8.10E-002, 5.71146023893E+001] 145 | - [8.20E-002, 5.71978399741E+001] 146 | - [8.30E-002, 5.72779572372E+001] 147 | - [8.40E-002, 5.73517897984E+001] 148 | - [8.50E-002, 5.74167271960E+001] 149 | - [8.60E-002, 5.74721573687E+001] 150 | - [8.70E-002, 5.75216388520E+001] 151 | - [8.80E-002, 5.75759967785E+001] 152 | - [8.90E-002, 5.76575701358E+001] 153 | - [9.00E-002, 5.78058719368E+001] 154 | - [9.10E-002, 5.80849611077E+001] 155 | - [9.20E-002, 5.85928651155E+001] 156 | - [9.30E-002, 5.94734357453E+001] 157 | - [9.40E-002, 6.09310671165E+001] 158 | - [9.50E-002, 6.32487551103E+001] 159 | - [9.60E-002, 6.68100309742E+001] 160 | ... 161 | -------------------------------------------------------------------------------- /pyked/tests/testfile_rcm.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | file-authors: 3 | - name: Kyle E Niemeyer 4 | ORCID: 0000-0003-4425-7097 5 | file-version: 0 6 | chemked-version: 0.0.1 7 | reference: 8 | doi: 10.1002/kin.20180 9 | authors: 10 | - name: Gaurav Mittal 11 | - name: Chih-Jen Sung 12 | ORCID: 0000-0003-2046-8076 13 | - name: Richard A Yetter 14 | journal: International Journal of Chemical Kinetics 15 | year: 2006 16 | volume: 38 17 | pages: 516-529 18 | detail: Fig. 6, open circle 19 | experiment-type: ignition delay 20 | apparatus: 21 | kind: rapid compression machine 22 | institution: Case Western Reserve University 23 | facility: CWRU RCM 24 | datapoints: 25 | - temperature: 26 | - 297.4 kelvin 27 | ignition-delay: 28 | - 1.0 ms 29 | pressure: 30 | - 958.0 torr 31 | composition: 32 | kind: mole fraction 33 | species: 34 | - species-name: H2 35 | InChI: 1S/H2/h1H 36 | amount: 37 | - 0.12500 38 | - species-name: O2 39 | InChI: 1S/O2/c1-2 40 | amount: 41 | - 0.06250 42 | - species-name: N2 43 | InChI: 1S/N2/c1-2 44 | amount: 45 | - 0.18125 46 | - species-name: Ar 47 | InChI: 1S/Ar 48 | amount: 49 | - 0.63125 50 | ignition-type: 51 | target: pressure 52 | type: d/dt max 53 | rcm-data: 54 | compression-time: 55 | - 38.0 ms 56 | time-histories: 57 | - type: volume 58 | time: 59 | units: s 60 | column: 0 61 | quantity: 62 | units: cm3 63 | column: 1 64 | values: 65 | - [0.00E+000, 5.47669375000E+002] 66 | - [1.00E-003, 5.46608789894E+002] 67 | - [2.00E-003, 5.43427034574E+002] 68 | - [3.00E-003, 5.38124109043E+002] 69 | - [4.00E-003, 5.30700013298E+002] 70 | - [5.00E-003, 5.21154747340E+002] 71 | - [6.00E-003, 5.09488311170E+002] 72 | - [7.00E-003, 4.95700704787E+002] 73 | - [8.00E-003, 4.79791928191E+002] 74 | - [9.00E-003, 4.61761981383E+002] 75 | - [1.00E-002, 4.41610864362E+002] 76 | - [1.10E-002, 4.20399162234E+002] 77 | - [1.20E-002, 3.99187460106E+002] 78 | - [1.30E-002, 3.77975757979E+002] 79 | - [1.40E-002, 3.56764055851E+002] 80 | - [1.50E-002, 3.35552353723E+002] 81 | - [1.60E-002, 3.14340651596E+002] 82 | - [1.70E-002, 2.93128949468E+002] 83 | - [1.80E-002, 2.71917247340E+002] 84 | - [1.90E-002, 2.50705545213E+002] 85 | - [2.00E-002, 2.29493843085E+002] 86 | - [2.10E-002, 2.08282140957E+002] 87 | - [2.20E-002, 1.87070438830E+002] 88 | - [2.30E-002, 1.65858736702E+002] 89 | - [2.40E-002, 1.44647034574E+002] 90 | - [2.50E-002, 1.23435332447E+002] 91 | - [2.60E-002, 1.02223630319E+002] 92 | - [2.70E-002, 8.10119281915E+001] 93 | - [2.80E-002, 6.33355097518E+001] 94 | - [2.90E-002, 5.27296586879E+001] 95 | - [3.00E-002, 4.91943750000E+001] 96 | - [3.10E-002, 4.97137623933E+001] 97 | - [3.20E-002, 5.02063762048E+001] 98 | - [3.30E-002, 5.06454851923E+001] 99 | - [3.40E-002, 5.10218564529E+001] 100 | - [3.50E-002, 5.13374097598E+001] 101 | - [3.60E-002, 5.16004693977E+001] 102 | - [3.70E-002, 5.18223244382E+001] 103 | - [3.80E-002, 5.20148449242E+001] 104 | - [3.90E-002, 5.21889350372E+001] 105 | - [4.00E-002, 5.23536351113E+001] 106 | - [4.10E-002, 5.25157124459E+001] 107 | - [4.20E-002, 5.26796063730E+001] 108 | - [4.30E-002, 5.28476160610E+001] 109 | - [4.40E-002, 5.30202402028E+001] 110 | - [4.50E-002, 5.31965961563E+001] 111 | - [4.60E-002, 5.33748623839E+001] 112 | - [4.70E-002, 5.35527022996E+001] 113 | - [4.80E-002, 5.37276399831E+001] 114 | - [4.90E-002, 5.38973687732E+001] 115 | - [5.00E-002, 5.40599826225E+001] 116 | - [5.10E-002, 5.42141273988E+001] 117 | - [5.20E-002, 5.43590751578E+001] 118 | - [5.30E-002, 5.44947289126E+001] 119 | - [5.40E-002, 5.46215686913E+001] 120 | - [5.50E-002, 5.47405518236E+001] 121 | - [5.60E-002, 5.48529815402E+001] 122 | - [5.70E-002, 5.49603582190E+001] 123 | - [5.80E-002, 5.50642270863E+001] 124 | - [5.90E-002, 5.51660349836E+001] 125 | - [6.00E-002, 5.52670070646E+001] 126 | - [6.10E-002, 5.53680520985E+001] 127 | - [6.20E-002, 5.54697025392E+001] 128 | - [6.30E-002, 5.55720927915E+001] 129 | - [6.40E-002, 5.56749762728E+001] 130 | - [6.50E-002, 5.57777790517E+001] 131 | - [6.60E-002, 5.58796851466E+001] 132 | - [6.70E-002, 5.59797461155E+001] 133 | - [6.80E-002, 5.60770054561E+001] 134 | - [6.90E-002, 5.61706266985E+001] 135 | - [7.00E-002, 5.62600130036E+001] 136 | - [7.10E-002, 5.63449057053E+001] 137 | - [7.20E-002, 5.64254496625E+001] 138 | - [7.30E-002, 5.65022146282E+001] 139 | - [7.40E-002, 5.65761642150E+001] 140 | - [7.50E-002, 5.66485675508E+001] 141 | - [7.60E-002, 5.67208534842E+001] 142 | - [7.70E-002, 5.67944133373E+001] 143 | - [7.80E-002, 5.68703658198E+001] 144 | - [7.90E-002, 5.69493069272E+001] 145 | - [8.00E-002, 5.70310785669E+001] 146 | - [8.10E-002, 5.71146023893E+001] 147 | - [8.20E-002, 5.71978399741E+001] 148 | - [8.30E-002, 5.72779572372E+001] 149 | - [8.40E-002, 5.73517897984E+001] 150 | - [8.50E-002, 5.74167271960E+001] 151 | - [8.60E-002, 5.74721573687E+001] 152 | - [8.70E-002, 5.75216388520E+001] 153 | - [8.80E-002, 5.75759967785E+001] 154 | - [8.90E-002, 5.76575701358E+001] 155 | - [9.00E-002, 5.78058719368E+001] 156 | - [9.10E-002, 5.80849611077E+001] 157 | - [9.20E-002, 5.85928651155E+001] 158 | - [9.30E-002, 5.94734357453E+001] 159 | - [9.40E-002, 6.09310671165E+001] 160 | - [9.50E-002, 6.32487551103E+001] 161 | - [9.60E-002, 6.68100309742E+001] 162 | ... 163 | -------------------------------------------------------------------------------- /pyked/tests/testfile_rcm2.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | file-authors: 3 | - name: Kyle E Niemeyer 4 | ORCID: 0000-0003-4425-7097 5 | file-version: 0 6 | chemked-version: 0.0.1 7 | reference: 8 | doi: 10.1002/kin.20180 9 | authors: 10 | - name: Gaurav Mittal 11 | - name: Chih-Jen Sung 12 | ORCID: 0000-0003-2046-8076 13 | - name: Richard A Yetter 14 | journal: International Journal of Chemical Kinetics 15 | year: 2006 16 | volume: 38 17 | pages: 516-529 18 | detail: Fig. 6, open circle 19 | experiment-type: ignition delay 20 | apparatus: 21 | kind: rapid compression machine 22 | institution: Case Western Reserve University 23 | facility: CWRU RCM 24 | datapoints: 25 | - temperature: 26 | - 297.4 kelvin 27 | ignition-delay: 28 | - 1.0 ms 29 | first-stage-ignition-delay: 30 | - 0.5 ms 31 | - uncertainty-type: relative 32 | uncertainty: 0.01 33 | pressure: 34 | - 958.0 torr 35 | rcm-data: 36 | compressed-pressure: 37 | - 7.1 bar 38 | compressed-temperature: 39 | - 765 K 40 | - uncertainty: 0.01 41 | uncertainty-type: relative 42 | compression-time: 43 | - 38.0 ms 44 | stroke: 45 | - 10.0 inch 46 | clearance: 47 | - 2.5 cm 48 | compression-ratio: 49 | - 12.0 50 | composition: 51 | kind: mole fraction 52 | species: 53 | - species-name: H2 54 | InChI: 1S/H2/h1H 55 | amount: 56 | - 0.12500 57 | - species-name: O2 58 | InChI: 1S/O2/c1-2 59 | amount: 60 | - 0.06250 61 | - species-name: N2 62 | InChI: 1S/N2/c1-2 63 | amount: 64 | - 0.18125 65 | - species-name: Ar 66 | InChI: 1S/Ar 67 | amount: 68 | - 0.63125 69 | ignition-type: 70 | target: pressure 71 | type: d/dt max 72 | time-histories: 73 | - type: volume 74 | time: 75 | units: s 76 | column: 0 77 | quantity: 78 | units: cm3 79 | column: 1 80 | values: 81 | - [0.00E+000, 5.47669375000E+002] 82 | - [1.00E-003, 5.46608789894E+002] 83 | - [2.00E-003, 5.43427034574E+002] 84 | - [3.00E-003, 5.38124109043E+002] 85 | - [4.00E-003, 5.30700013298E+002] 86 | - [5.00E-003, 5.21154747340E+002] 87 | - [6.00E-003, 5.09488311170E+002] 88 | - [7.00E-003, 4.95700704787E+002] 89 | - [8.00E-003, 4.79791928191E+002] 90 | - [9.00E-003, 4.61761981383E+002] 91 | - [1.00E-002, 4.41610864362E+002] 92 | - [1.10E-002, 4.20399162234E+002] 93 | - [1.20E-002, 3.99187460106E+002] 94 | - [1.30E-002, 3.77975757979E+002] 95 | - [1.40E-002, 3.56764055851E+002] 96 | - [1.50E-002, 3.35552353723E+002] 97 | - [1.60E-002, 3.14340651596E+002] 98 | - [1.70E-002, 2.93128949468E+002] 99 | - [1.80E-002, 2.71917247340E+002] 100 | - [1.90E-002, 2.50705545213E+002] 101 | - [2.00E-002, 2.29493843085E+002] 102 | - [2.10E-002, 2.08282140957E+002] 103 | - [2.20E-002, 1.87070438830E+002] 104 | - [2.30E-002, 1.65858736702E+002] 105 | - [2.40E-002, 1.44647034574E+002] 106 | - [2.50E-002, 1.23435332447E+002] 107 | - [2.60E-002, 1.02223630319E+002] 108 | - [2.70E-002, 8.10119281915E+001] 109 | - [2.80E-002, 6.33355097518E+001] 110 | - [2.90E-002, 5.27296586879E+001] 111 | - [3.00E-002, 4.91943750000E+001] 112 | - [3.10E-002, 4.97137623933E+001] 113 | - [3.20E-002, 5.02063762048E+001] 114 | - [3.30E-002, 5.06454851923E+001] 115 | - [3.40E-002, 5.10218564529E+001] 116 | - [3.50E-002, 5.13374097598E+001] 117 | - [3.60E-002, 5.16004693977E+001] 118 | - [3.70E-002, 5.18223244382E+001] 119 | - [3.80E-002, 5.20148449242E+001] 120 | - [3.90E-002, 5.21889350372E+001] 121 | - [4.00E-002, 5.23536351113E+001] 122 | - [4.10E-002, 5.25157124459E+001] 123 | - [4.20E-002, 5.26796063730E+001] 124 | - [4.30E-002, 5.28476160610E+001] 125 | - [4.40E-002, 5.30202402028E+001] 126 | - [4.50E-002, 5.31965961563E+001] 127 | - [4.60E-002, 5.33748623839E+001] 128 | - [4.70E-002, 5.35527022996E+001] 129 | - [4.80E-002, 5.37276399831E+001] 130 | - [4.90E-002, 5.38973687732E+001] 131 | - [5.00E-002, 5.40599826225E+001] 132 | - [5.10E-002, 5.42141273988E+001] 133 | - [5.20E-002, 5.43590751578E+001] 134 | - [5.30E-002, 5.44947289126E+001] 135 | - [5.40E-002, 5.46215686913E+001] 136 | - [5.50E-002, 5.47405518236E+001] 137 | - [5.60E-002, 5.48529815402E+001] 138 | - [5.70E-002, 5.49603582190E+001] 139 | - [5.80E-002, 5.50642270863E+001] 140 | - [5.90E-002, 5.51660349836E+001] 141 | - [6.00E-002, 5.52670070646E+001] 142 | - [6.10E-002, 5.53680520985E+001] 143 | - [6.20E-002, 5.54697025392E+001] 144 | - [6.30E-002, 5.55720927915E+001] 145 | - [6.40E-002, 5.56749762728E+001] 146 | - [6.50E-002, 5.57777790517E+001] 147 | - [6.60E-002, 5.58796851466E+001] 148 | - [6.70E-002, 5.59797461155E+001] 149 | - [6.80E-002, 5.60770054561E+001] 150 | - [6.90E-002, 5.61706266985E+001] 151 | - [7.00E-002, 5.62600130036E+001] 152 | - [7.10E-002, 5.63449057053E+001] 153 | - [7.20E-002, 5.64254496625E+001] 154 | - [7.30E-002, 5.65022146282E+001] 155 | - [7.40E-002, 5.65761642150E+001] 156 | - [7.50E-002, 5.66485675508E+001] 157 | - [7.60E-002, 5.67208534842E+001] 158 | - [7.70E-002, 5.67944133373E+001] 159 | - [7.80E-002, 5.68703658198E+001] 160 | - [7.90E-002, 5.69493069272E+001] 161 | - [8.00E-002, 5.70310785669E+001] 162 | - [8.10E-002, 5.71146023893E+001] 163 | - [8.20E-002, 5.71978399741E+001] 164 | - [8.30E-002, 5.72779572372E+001] 165 | - [8.40E-002, 5.73517897984E+001] 166 | - [8.50E-002, 5.74167271960E+001] 167 | - [8.60E-002, 5.74721573687E+001] 168 | - [8.70E-002, 5.75216388520E+001] 169 | - [8.80E-002, 5.75759967785E+001] 170 | - [8.90E-002, 5.76575701358E+001] 171 | - [9.00E-002, 5.78058719368E+001] 172 | - [9.10E-002, 5.80849611077E+001] 173 | - [9.20E-002, 5.85928651155E+001] 174 | - [9.30E-002, 5.94734357453E+001] 175 | - [9.40E-002, 6.09310671165E+001] 176 | - [9.50E-002, 6.32487551103E+001] 177 | - [9.60E-002, 6.68100309742E+001] 178 | ... 179 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](http://keepachangelog.com/) 5 | and this project adheres to [Semantic Versioning](http://semver.org/). 6 | 7 | ## [Unreleased] 8 | ### Added 9 | - Add codemeta file 10 | 11 | ### Changed 12 | - Directly use the Markdown formatting of the README on pypi, rather than converting to reST 13 | - Remove unnecessary `orcid` package from the test environment 14 | - Specify versions of all package dependencies 15 | - Use pip to install package in conda build 16 | - Composition type is included in the pandas data-frame resulting from `to_dataframe()` 17 | 18 | ### Fixed 19 | 20 | ## [0.4.1] - 2018-03-09 21 | ### Added 22 | - Documentation for old versions is available on the Releases page of the docs 23 | 24 | ### Changed 25 | 26 | ### Fixed 27 | - Doctr deploys on tags now 28 | - Syntax changes for example files in the documentation 29 | 30 | ## [0.4.0] - 2018-03-07 31 | ### Added 32 | - New method to instantiate a `ChemKED` class directly from a ReSpecTh XML file 33 | - The `__version__` attribute can be imported from the top-level module 34 | - New `time-histories` field to replace the `volume-history`. This field allows specification of several other relevant parameters besides volume. 35 | - Added `rcm-data` field and moved `compressed-temperature`, `compressed-pressure`, and `compression-time` to this field 36 | - Added `stroke`, `clearance`, and `compression-ratio` to the `rcm-data` field 37 | - Added conda-forge instructions to the installation documentation 38 | - Allow alpha versions to be specified during testing 39 | 40 | ### Changed 41 | - Crossref lookups via Habanero now comply with the "be-nice" policy 42 | - Removed `UnboundLocalError` from error processing for reference validation 43 | - Switch to flake8 for style checking in CI services 44 | - `file-author` field is now a list called `file-authors` 45 | - ReSpecTh->ChemKED converter function now returns a dictionary, while the command-line entry points write out files 46 | - Require Habanero>=0.6.0 to support the `mailto` argument 47 | - Require pytest>=3.2.0 to support the `pytest.mark.filterwarnings` decorator 48 | - Deprecate the `volume-history` field in the ChemKED YAML file and replace with `time-histories` 49 | - ORCID lookups are now done by a function in the local `orcid.py` module, removing an external dependency 50 | - Composition in a `DataPoint` is now stored in a dictionary of `namedtuple`s (called `Composition`) rather than a list of dictionaries 51 | 52 | ### Fixed 53 | - Crossref lookups in the converters use the common API instance from validation 54 | - `d/dt max extrapolated` ignition type can be converted to/from ReSpecTh 55 | - Tests now check for appropriate warnings and ignore unrelated warnings 56 | 57 | ## [0.3.0] - 2017-10-09 58 | ### Added 59 | - New extrapolated ignition type, where the maximum slope is extrapolated to the baseline 60 | - Tests that the composition type is stored properly in the `DataPoint` 61 | - `species_conversion` dictionary can be passed to the `get_cantera_mole_fraction` and `get_cantera_mass_fraction` functions to change the name of a species in the output string 62 | - Jupyter Notebook examples of usage 63 | 64 | ### Removed 65 | - Removes `elemental-composition` as a synonym for `atomic-composition` 66 | 67 | ### Fixed 68 | - Fixes `test_incorrect_doi_period_at_end` docstring 69 | 70 | ### Changed 71 | - Conda builds are now noarch - one package for all Pythons! 72 | - pip installs now require Python compatible with 3.5 73 | - Appveyor runs a single job and no longer builds conda packages 74 | - Remove journal from required fields in the reference 75 | 76 | ## [0.2.1] - 2017-08-31 77 | ### Fixed 78 | - Fixes Cantera convenience output functions 79 | 80 | ## [0.2.0] - 2017-08-10 81 | ### Added 82 | - Adds ChemKED method to write new file, with tests 83 | - Adds converters to and from ReSpecTh files, with tests 84 | - Adds command-line entry points for converter scripts 85 | - Add docs for converters 86 | 87 | ### Fixed 88 | - `ignition_type` dictionary in `DataPoint` is now `deepcopy`d 89 | 90 | ## [0.1.6] - 2017-07-17 91 | ### Added 92 | - Added logo files to repo 93 | - Added `first_stage_ignition_delay`, `compressed_pressure`, and `compressed_temperature` as properties 94 | 95 | ### Changed 96 | - Added Zenodo collection DOI to CITATION.md 97 | 98 | ## [0.1.5] - 2017-05-22 99 | ### Added 100 | - Schema can now be split into multiple files via `!include` directive 101 | 102 | ### Fixed 103 | - Remove Python 2.7 classifier from `setup.py` 104 | - DataFrame output for datapoints lists with multiple compositions (i.e., a species not in all compositions) 105 | 106 | ### Changed 107 | - Improved tests with no internet 108 | - Improved tests with no warning 109 | 110 | ## [0.1.4] - 2017-04-21 111 | ### Added 112 | - Add `skip_validation` keyword argument to the `ChemKED` initializer 113 | 114 | ### Removed 115 | - Python 2.7 support is removed again 116 | 117 | ## [0.1.3] - 2017-04-13 118 | ### Added 119 | - Add back Python 2.7 support 120 | - Add Appveyor builds for Windows conda packages 121 | 122 | ## [0.1.2] - 2017-04-13 123 | ### Added 124 | - Tests of the composition uncertainty in the DataPoint 125 | - Tests of the values in the references 126 | - Packaging for conda and PyPI 127 | - Add Anaconda-Server badge to README 128 | 129 | ### Changed 130 | - All fixed DOIs in CITATION.md are now specified with placeholders 131 | 132 | ## [0.1.1] - 2017-04-02 133 | ### Added 134 | - Added Zenodo DOI badge to README 135 | - Added CITATION file, and mention of license to README 136 | 137 | ### Fixed 138 | - Fixed chemked-version bug in schema introduced in 0.1.0 139 | 140 | ## [0.1.0] - 2017-04-02 141 | ### Added 142 | - First minor release of PyKED, supporting autoignition experiments. 143 | - Basic API documentation is available via https://pr-omethe-us.github.io/PyKED/ 144 | 145 | [Unreleased]: https://github.com/pr-omethe-us/PyKED/compare/v0.4.0...HEAD 146 | [0.4.1]: https://github.com/pr-omethe-us/PyKED/compare/v0.4.0...v0.4.1 147 | [0.4.0]: https://github.com/pr-omethe-us/PyKED/compare/v0.3.0...v0.4.0 148 | [0.3.0]: https://github.com/pr-omethe-us/PyKED/compare/v0.2.1...v0.3.0 149 | [0.2.1]: https://github.com/pr-omethe-us/PyKED/compare/v0.2.0...v0.2.1 150 | [0.2.0]: https://github.com/pr-omethe-us/PyKED/compare/v0.1.6...v0.2.0 151 | [0.1.6]: https://github.com/pr-omethe-us/PyKED/compare/v0.1.5...v0.1.6 152 | [0.1.5]: https://github.com/pr-omethe-us/PyKED/compare/v0.1.4...v0.1.5 153 | [0.1.4]: https://github.com/pr-omethe-us/PyKED/compare/v0.1.3...v0.1.4 154 | [0.1.3]: https://github.com/pr-omethe-us/PyKED/compare/v0.1.2...v0.1.3 155 | [0.1.2]: https://github.com/pr-omethe-us/PyKED/compare/v0.1.1...v0.1.2 156 | [0.1.1]: https://github.com/pr-omethe-us/PyKED/compare/v0.1.0...v0.1.1 157 | [0.1.0]: https://github.com/pr-omethe-us/PyKED/compare/75ecf67766a0be2a80e2377391fd9eca420f152c...v0.1.0 158 | -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # 4 | # PyKED documentation build configuration file, created by 5 | # sphinx-quickstart on Fri Mar 31 13:06:52 2017. 6 | # 7 | # This file is execfile()d with the current directory set to its 8 | # containing dir. 9 | # 10 | # Note that not all possible configuration values are present in this 11 | # autogenerated file. 12 | # 13 | # All configuration values have a default; values that are commented out 14 | # serve to show the default. 15 | 16 | import sys 17 | import os 18 | import pkg_resources 19 | import datetime 20 | 21 | # If extensions (or modules to document with autodoc) are in another directory, 22 | # add these directories to sys.path here. If the directory is relative to the 23 | # documentation root, use os.path.abspath to make it absolute, like shown here. 24 | on_travis = os.environ.get('TRAVIS') == 'True' 25 | if not on_travis: 26 | sys.path.insert(0, os.path.abspath('..')) 27 | 28 | # -- General configuration ------------------------------------------------ 29 | 30 | # If your documentation needs a minimal Sphinx version, state it here. 31 | # 32 | # needs_sphinx = '1.0' 33 | 34 | # Add any Sphinx extension module names here, as strings. They can be 35 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 36 | # ones. 37 | extensions = [ 38 | 'sphinx.ext.autodoc', 39 | 'sphinx.ext.doctest', 40 | 'sphinx.ext.intersphinx', 41 | 'sphinx.ext.napoleon', 42 | 'sphinx.ext.todo', 43 | 'sphinx.ext.coverage', 44 | 'sphinx.ext.mathjax', 45 | 'sphinx.ext.viewcode', 46 | 'nbsphinx', 47 | # This line is a workaround for https://github.com/spatialaudio/nbsphinx/issues/24 48 | 'IPython.sphinxext.ipython_console_highlighting', 49 | ] 50 | 51 | autodoc_default_flags = ['members'] 52 | autoclass_content = 'class' 53 | napoleon_numpy_docstring = False 54 | napoleon_google_docstring = True 55 | intersphinx_mapping = { 56 | 'python': ('https://docs.python.org/3.6', None), 57 | 'pandas': ('http://pandas.pydata.org/pandas-docs/stable/', None), 58 | 'numpy': ('https://docs.scipy.org/doc/numpy/', None), 59 | 'requests': ('http://docs.python-requests.org/en/master/', None), 60 | } 61 | 62 | # Make the module index more useful by sorting on the module name 63 | # instead of the package name 64 | modindex_common_prefix = ['pyked.'] 65 | 66 | # Suppress duplicate citation warnings. 67 | # WARNING: Also suppresses undefined citation warnings and unused 68 | # reference warnings. 69 | suppress_warnings = ['ref.citation'] 70 | 71 | # Add any paths that contain templates here, relative to this directory. 72 | templates_path = ['_templates'] 73 | 74 | # The suffix(es) of source filenames. 75 | # You can specify multiple suffix as a list of string: 76 | # 77 | # source_suffix = ['.rst', '.md'] 78 | source_suffix = '.rst' 79 | 80 | # The master toctree document. 81 | master_doc = 'index' 82 | 83 | # General information about the project. 84 | project = 'PyKED' 85 | author = 'Kyle E. Niemeyer and Bryan W. Weber' 86 | this_year = datetime.date.today().year 87 | copyright = '{}, {}'.format(this_year, author) 88 | 89 | # The version info for the project you're documenting, acts as replacement for 90 | # |version| and |release|, also used in various other places throughout the 91 | # built documents. 92 | # 93 | # The full version, including alpha/beta/rc tags. 94 | try: 95 | release = pkg_resources.get_distribution(project).version 96 | except: 97 | release = 'unknown' 98 | # The short X.Y version. 99 | version = '.'.join(release.split('.')[:1]) 100 | 101 | # The language for content autogenerated by Sphinx. Refer to documentation 102 | # for a list of supported languages. 103 | # 104 | # This is also used if you do content translation via gettext catalogs. 105 | # Usually you set "language" from the command line for these cases. 106 | language = None 107 | 108 | # List of patterns, relative to source directory, that match files and 109 | # directories to ignore when looking for source files. 110 | # This patterns also effect to html_static_path and html_extra_path 111 | exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', '.ipynb_checkpoints'] 112 | 113 | # The name of the Pygments (syntax highlighting) style to use. 114 | pygments_style = 'sphinx' 115 | 116 | # If true, `todo` and `todoList` produce output, else they produce nothing. 117 | todo_include_todos = True 118 | 119 | # The reST default role (used for this markup: `text`) to use for all 120 | # documents. 121 | default_role = 'py:obj' 122 | 123 | # -- Options for HTML output ---------------------------------------------- 124 | 125 | # The theme to use for HTML and HTML Help pages. See the documentation for 126 | # a list of builtin themes. 127 | # 128 | html_theme = 'alabaster' 129 | 130 | # Theme options are theme-specific and customize the look and feel of a theme 131 | # further. For a list of options available for each theme, see the 132 | # documentation. 133 | html_theme_options = { 134 | 'github_user': 'pr-omethe-us', 135 | 'github_repo': 'PyKED', 136 | 'github_banner': True, 137 | 'github_button': True, 138 | 'show_powered_by': True, 139 | } 140 | 141 | # Add any paths that contain custom static files (such as style sheets) here, 142 | # relative to this directory. They are copied after the builtin static files, 143 | # so a file named "default.css" will overwrite the builtin "default.css". 144 | html_static_path = ['_static'] 145 | 146 | 147 | # -- Options for HTMLHelp output ------------------------------------------ 148 | 149 | # Output file base name for HTML help builder. 150 | htmlhelp_basename = 'PyKEDdoc' 151 | 152 | 153 | # -- Options for LaTeX output --------------------------------------------- 154 | 155 | latex_elements = { 156 | # The paper size ('letterpaper' or 'a4paper'). 157 | # 158 | # 'papersize': 'letterpaper', 159 | 160 | # The font size ('10pt', '11pt' or '12pt'). 161 | # 162 | # 'pointsize': '10pt', 163 | 164 | # Additional stuff for the LaTeX preamble. 165 | # 166 | # 'preamble': '', 167 | 168 | # Latex figure (float) alignment 169 | # 170 | # 'figure_align': 'htbp', 171 | } 172 | 173 | # Grouping the document tree into LaTeX files. List of tuples 174 | # (source start file, target name, title, 175 | # author, documentclass [howto, manual, or own class]). 176 | latex_documents = [ 177 | (master_doc, 'PyKED.tex', 'PyKED Documentation', 178 | 'Kyle E. Niemeyer and Bryan W. Weber', 'manual'), 179 | ] 180 | 181 | 182 | # -- Options for manual page output --------------------------------------- 183 | 184 | # One entry per manual page. List of tuples 185 | # (source start file, name, description, authors, manual section). 186 | man_pages = [ 187 | (master_doc, 'pyked', 'PyKED Documentation', 188 | [author], 1) 189 | ] 190 | 191 | 192 | # -- Options for Texinfo output ------------------------------------------- 193 | 194 | # Grouping the document tree into Texinfo files. List of tuples 195 | # (source start file, target name, title, author, 196 | # dir menu entry, description, category) 197 | texinfo_documents = [ 198 | (master_doc, 'PyKED', 'PyKED Documentation', 199 | author, 'PyKED', 'One line description of project.', 200 | 'Miscellaneous'), 201 | ] 202 | -------------------------------------------------------------------------------- /pyked/tests/testfile_rcm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Kyle E. Niemeyer 4 | 5 | 1 6 | 0 7 | 8 | 9 | 1 10 | 0 11 | 12 | Ignition delay measurement 13 | 15 | 16 | rapid compression machine 17 | 18 | 19 | 20 | 21 | 22 | 0.12500 23 | 24 | 25 | 26 | 0.06250 27 | 28 | 29 | 30 | 0.18125 31 | 32 | 33 | 34 | 0.63125 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 1. 45 | 297.4 46 | 958. 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 0.00E+000 55 | 5.47669375000E+002 56 | 57 | 58 | 1.00E-003 59 | 5.46608789894E+002 60 | 61 | 62 | 2.00E-003 63 | 5.43427034574E+002 64 | 65 | 66 | 3.00E-003 67 | 5.38124109043E+002 68 | 69 | 70 | 4.00E-003 71 | 5.30700013298E+002 72 | 73 | 74 | 5.00E-003 75 | 5.21154747340E+002 76 | 77 | 78 | 6.00E-003 79 | 5.09488311170E+002 80 | 81 | 82 | 7.00E-003 83 | 4.95700704787E+002 84 | 85 | 86 | 8.00E-003 87 | 4.79791928191E+002 88 | 89 | 90 | 9.00E-003 91 | 4.61761981383E+002 92 | 93 | 94 | 1.00E-002 95 | 4.41610864362E+002 96 | 97 | 98 | 1.10E-002 99 | 4.20399162234E+002 100 | 101 | 102 | 1.20E-002 103 | 3.99187460106E+002 104 | 105 | 106 | 1.30E-002 107 | 3.77975757979E+002 108 | 109 | 110 | 1.40E-002 111 | 3.56764055851E+002 112 | 113 | 114 | 1.50E-002 115 | 3.35552353723E+002 116 | 117 | 118 | 1.60E-002 119 | 3.14340651596E+002 120 | 121 | 122 | 1.70E-002 123 | 2.93128949468E+002 124 | 125 | 126 | 1.80E-002 127 | 2.71917247340E+002 128 | 129 | 130 | 1.90E-002 131 | 2.50705545213E+002 132 | 133 | 134 | 2.00E-002 135 | 2.29493843085E+002 136 | 137 | 138 | 2.10E-002 139 | 2.08282140957E+002 140 | 141 | 142 | 2.20E-002 143 | 1.87070438830E+002 144 | 145 | 146 | 2.30E-002 147 | 1.65858736702E+002 148 | 149 | 150 | 2.40E-002 151 | 1.44647034574E+002 152 | 153 | 154 | 2.50E-002 155 | 1.23435332447E+002 156 | 157 | 158 | 2.60E-002 159 | 1.02223630319E+002 160 | 161 | 162 | 2.70E-002 163 | 8.10119281915E+001 164 | 165 | 166 | 2.80E-002 167 | 6.33355097518E+001 168 | 169 | 170 | 2.90E-002 171 | 5.27296586879E+001 172 | 173 | 174 | 3.00E-002 175 | 4.91943750000E+001 176 | 177 | 178 | 3.10E-002 179 | 4.97137623933E+001 180 | 181 | 182 | 3.20E-002 183 | 5.02063762048E+001 184 | 185 | 186 | 3.30E-002 187 | 5.06454851923E+001 188 | 189 | 190 | 3.40E-002 191 | 5.10218564529E+001 192 | 193 | 194 | 3.50E-002 195 | 5.13374097598E+001 196 | 197 | 198 | 3.60E-002 199 | 5.16004693977E+001 200 | 201 | 202 | 3.70E-002 203 | 5.18223244382E+001 204 | 205 | 206 | 3.80E-002 207 | 5.20148449242E+001 208 | 209 | 210 | 3.90E-002 211 | 5.21889350372E+001 212 | 213 | 214 | 4.00E-002 215 | 5.23536351113E+001 216 | 217 | 218 | 4.10E-002 219 | 5.25157124459E+001 220 | 221 | 222 | 4.20E-002 223 | 5.26796063730E+001 224 | 225 | 226 | 4.30E-002 227 | 5.28476160610E+001 228 | 229 | 230 | 4.40E-002 231 | 5.30202402028E+001 232 | 233 | 234 | 4.50E-002 235 | 5.31965961563E+001 236 | 237 | 238 | 4.60E-002 239 | 5.33748623839E+001 240 | 241 | 242 | 4.70E-002 243 | 5.35527022996E+001 244 | 245 | 246 | 4.80E-002 247 | 5.37276399831E+001 248 | 249 | 250 | 4.90E-002 251 | 5.38973687732E+001 252 | 253 | 254 | 5.00E-002 255 | 5.40599826225E+001 256 | 257 | 258 | 5.10E-002 259 | 5.42141273988E+001 260 | 261 | 262 | 5.20E-002 263 | 5.43590751578E+001 264 | 265 | 266 | 5.30E-002 267 | 5.44947289126E+001 268 | 269 | 270 | 5.40E-002 271 | 5.46215686913E+001 272 | 273 | 274 | 5.50E-002 275 | 5.47405518236E+001 276 | 277 | 278 | 5.60E-002 279 | 5.48529815402E+001 280 | 281 | 282 | 5.70E-002 283 | 5.49603582190E+001 284 | 285 | 286 | 5.80E-002 287 | 5.50642270863E+001 288 | 289 | 290 | 5.90E-002 291 | 5.51660349836E+001 292 | 293 | 294 | 6.00E-002 295 | 5.52670070646E+001 296 | 297 | 298 | 6.10E-002 299 | 5.53680520985E+001 300 | 301 | 302 | 6.20E-002 303 | 5.54697025392E+001 304 | 305 | 306 | 6.30E-002 307 | 5.55720927915E+001 308 | 309 | 310 | 6.40E-002 311 | 5.56749762728E+001 312 | 313 | 314 | 6.50E-002 315 | 5.57777790517E+001 316 | 317 | 318 | 6.60E-002 319 | 5.58796851466E+001 320 | 321 | 322 | 6.70E-002 323 | 5.59797461155E+001 324 | 325 | 326 | 6.80E-002 327 | 5.60770054561E+001 328 | 329 | 330 | 6.90E-002 331 | 5.61706266985E+001 332 | 333 | 334 | 7.00E-002 335 | 5.62600130036E+001 336 | 337 | 338 | 7.10E-002 339 | 5.63449057053E+001 340 | 341 | 342 | 7.20E-002 343 | 5.64254496625E+001 344 | 345 | 346 | 7.30E-002 347 | 5.65022146282E+001 348 | 349 | 350 | 7.40E-002 351 | 5.65761642150E+001 352 | 353 | 354 | 7.50E-002 355 | 5.66485675508E+001 356 | 357 | 358 | 7.60E-002 359 | 5.67208534842E+001 360 | 361 | 362 | 7.70E-002 363 | 5.67944133373E+001 364 | 365 | 366 | 7.80E-002 367 | 5.68703658198E+001 368 | 369 | 370 | 7.90E-002 371 | 5.69493069272E+001 372 | 373 | 374 | 8.00E-002 375 | 5.70310785669E+001 376 | 377 | 378 | 8.10E-002 379 | 5.71146023893E+001 380 | 381 | 382 | 8.20E-002 383 | 5.71978399741E+001 384 | 385 | 386 | 8.30E-002 387 | 5.72779572372E+001 388 | 389 | 390 | 8.40E-002 391 | 5.73517897984E+001 392 | 393 | 394 | 8.50E-002 395 | 5.74167271960E+001 396 | 397 | 398 | 8.60E-002 399 | 5.74721573687E+001 400 | 401 | 402 | 8.70E-002 403 | 5.75216388520E+001 404 | 405 | 406 | 8.80E-002 407 | 5.75759967785E+001 408 | 409 | 410 | 8.90E-002 411 | 5.76575701358E+001 412 | 413 | 414 | 9.00E-002 415 | 5.78058719368E+001 416 | 417 | 418 | 9.10E-002 419 | 5.80849611077E+001 420 | 421 | 422 | 9.20E-002 423 | 5.85928651155E+001 424 | 425 | 426 | 9.30E-002 427 | 5.94734357453E+001 428 | 429 | 430 | 9.40E-002 431 | 6.09310671165E+001 432 | 433 | 434 | 9.50E-002 435 | 6.32487551103E+001 436 | 437 | 438 | 9.60E-002 439 | 6.68100309742E+001 440 | 441 | 442 | 443 | 444 | -------------------------------------------------------------------------------- /docs/schema-docs.rst: -------------------------------------------------------------------------------- 1 | .. Complete documentation for the schema 2 | 3 | Schema Documentation 4 | ==================== 5 | 6 | This document contains the complete specification for the ChemKED schema. The schema is broken into 7 | several files for ease of maintenance. These files are combined with the custom ``!include`` 8 | directive that has been added for this purpose. Note that ``!include`` should only be used in the 9 | main schema file (``chemked_schema.yaml``) and must appear at the top of the file. The ``!include`` 10 | directive is **not** supported in any actual ChemKED files. 11 | 12 | Examples of constructing a ChemKED format file, as well as examples of files themselves, are located 13 | in :doc:`ck-tutorial`. The sections laid out in this file roughly correspond to the sections 14 | discussed in the tutorial. 15 | 16 | .. contents:: 17 | :local: 18 | 19 | .. _meta-keys: 20 | 21 | Meta Keys 22 | --------- 23 | 24 | The keys in this section encode the "meta" information about the ChemKED file. All of the keys in 25 | this section are required in every ChemKED file. 26 | 27 | .. _meta-chemked-version: 28 | 29 | * ``chemked-version``: string, required 30 | A string with the version of the ChemKED schema that this file targets. 31 | 32 | .. _meta-datapoints: 33 | 34 | * ``datapoints``: sequence, required 35 | A sequence of mappings representing the data encoded in the file. Each element of the sequence 36 | must conform to the schema described in :ref:`ignition-delay-keys` (for now). 37 | 38 | .. _meta-file-version: 39 | 40 | * ``file-version``: integer, required 41 | An integer that represents the version of the file. Should be incremented every time a change is 42 | committed to a file in the database. 43 | 44 | .. _meta-file-authors: 45 | 46 | * ``file-authors``: sequence, required 47 | The author(s) of the ChemKED file, which may be different from the authors of the referenced 48 | work. Elements of the sequence must be mappings that conform to the 49 | :ref:`author ` schema. 50 | 51 | .. _reference-keys: 52 | 53 | Reference Keys 54 | -------------- 55 | 56 | The keys in this section are related to the reference for the experiment, the article where the data 57 | is published, and the apparatus used to conduct the experiment. All the top-level keys in this 58 | section are required, although some of the sub-keys are optional. 59 | 60 | .. _reference-apparatus: 61 | 62 | * ``apparatus``: mapping, required 63 | This mapping provides information about the apparatus used to conduct the experiments. Fields: 64 | 65 | - ``kind``: string, required 66 | Must be one of ``shock tube`` or ``rapid compression machine``. Values are case-sensitive. 67 | 68 | - ``institution``: string, optional 69 | The institution where the experimental apparatus is located 70 | 71 | - ``facility``: string, optional 72 | A unique name or identifier for the apparatus, if the institution has several that are 73 | similar 74 | 75 | .. _reference-experiment-type: 76 | 77 | * ``experiment-type``: string, required 78 | The type of experiment encoded in this file. Currently, the only allowed value is 79 | ``ignition delay``, which is case sensitive. 80 | 81 | .. _reference-reference: 82 | 83 | * ``reference``: mapping, required 84 | The reference contains the information about the article where the data in the file are 85 | published. Fields: 86 | 87 | - ``journal``: string, optional 88 | The journal where the data are published 89 | 90 | - ``year``: integer, required 91 | The year of publication. Must be greater than 1600. 92 | 93 | - ``authors``: sequence, required 94 | A sequence of all the authors of the article, where the elements of the sequence are 95 | mappings that must conform to the :ref:`author ` type. 96 | 97 | - ``volume``: integer, optional 98 | The volume of the publication. Must be greater than 0. 99 | 100 | - ``doi``: string, optional 101 | A DOI, if available. 102 | 103 | - ``detail``: string, optional 104 | A description of where in the article the data in this file are from, for instance, a figure 105 | or table number. 106 | 107 | - ``pages``: string, optional 108 | The pages in the journal where the article is published (not the pages where the data are 109 | located, that would go in the ``detail`` field.) 110 | 111 | .. _common-property-keys: 112 | 113 | Common Property Keys 114 | -------------------- 115 | 116 | The keys in this section can be specified as sub-keys of the the ``common-properties`` top-level 117 | key, and reused in many different data points within a single ChemKED file. All of the keys in the 118 | ``common-properties`` section are optional, although some of their values may be required in a 119 | particular experiment type. 120 | 121 | .. _common-pressure-rise: 122 | 123 | * ``pressure-rise``: sequence, optional 124 | Has the same format as :ref:`pressure-rise ` 125 | 126 | .. _common-pressure: 127 | 128 | * ``pressure``: sequence, optional 129 | The pressure of the experiment, with dimensions of mass per length per time squared. Must 130 | conform to :ref:`value-unit-optional ` 131 | 132 | .. _common-ignition-type: 133 | 134 | * ``ignition-type``: mapping, optional 135 | Has the same schema as :ref:`ignition-type ` 136 | 137 | .. _common-composition: 138 | 139 | * ``composition``: mapping, optional 140 | This mapping provides the specification of the initial composition of the mixture. Fields: 141 | 142 | - ``kind``: string, required 143 | The ``kind`` can be ``mole fraction``, ``mass fraction``, or ``mole percent`` 144 | 145 | - ``species``: sequence, required 146 | The elements of this sequence specify the species and their amounts in the mixture. Each 147 | element of the sequence is a mapping with the following keys: 148 | 149 | * ``species-name``: string, required 150 | The name of the species 151 | 152 | * ``InChI``: string, required, excludes ``SMILES``, ``atomic-composition`` 153 | The InChI string for the species 154 | 155 | * ``SMILES``: string, required, excludes ``InChI``, ``atomic-composition`` 156 | The SMILES string for the species 157 | 158 | * ``atomic-composition``: sequence, required, excludes ``InChI``, ``SMILES`` 159 | A sequence of mappings representing the atoms that make up the species. Useful for 160 | species without SMILES or InChI representations, such as real hydrocarbon fuels. Each 161 | element of the sequence is a mapping with the following keys: 162 | 163 | - ``element``: string, required 164 | The name of the element 165 | 166 | - ``amount``: float, required, must be greater than 0.0 167 | The amount of the element 168 | 169 | * ``amount``: sequence, required 170 | A sequence representing the amount of the species. Must conform to either 171 | :ref:`value-with-uncertainty ` or 172 | :ref:`value-without-uncertainty `. 173 | 174 | .. _ignition-delay-keys: 175 | 176 | Ignition Delay Keys 177 | ------------------- 178 | 179 | This section details the schema for an autoignition delay measurement. This is one of the options 180 | for the :ref:`datapoints ` schema. 181 | 182 | .. _ignition-temperature: 183 | 184 | * ``temperature``: sequence, required 185 | The temperature of the experiment, with dimensions of temperature. Must conform to 186 | :ref:`value-unit-required ` 187 | 188 | .. _ignition-composition: 189 | 190 | * ``composition``: mapping, required 191 | The composition of the experiment. Must conform to :ref:`composition ` 192 | 193 | .. _ignition-pressure: 194 | 195 | * ``pressure``: sequence, required 196 | The pressure of the experiment, with dimensions of mass per length per time squared. Must 197 | conform to :ref:`value-unit-required ` 198 | 199 | .. _ignition-ignition-type: 200 | 201 | * ``ignition-type``: mapping, required 202 | A mapping describing how the ignition delay is defined in the experiments. Fields: 203 | 204 | - ``target``: string, required 205 | Describes the target measurement to define ignition. Can be one of: 206 | 207 | * ``temperature`` 208 | * ``pressure`` 209 | * ``OH`` 210 | * ``OH*`` 211 | * ``CH`` 212 | * ``CH*`` 213 | 214 | - ``type``: string, required 215 | Describes the type of ignition delay measurement. Can be one of: 216 | 217 | * ``d/dt max``: maximum of the time derivative of the ``target`` 218 | * ``max``: maximum of the ``target`` 219 | * ``1/2 max``: half-maximum of the ``target`` 220 | * ``min``: minimum of the ``target`` 221 | * ``d/dt max extrapolated``: maximum slope of the target extrapolated to the baseline 222 | 223 | .. _ignition-ignition-delay: 224 | 225 | * ``ignition-delay``: sequence, required 226 | The ignition delay measurement, with dimensions of time. Must conform to 227 | :ref:`value-unit-required ` 228 | 229 | .. _ignition-first-stage-ignition-delay: 230 | 231 | * ``first-stage-ignition-delay``: sequence, optional 232 | If two stages of ignition are present, this is the value of the first stage of ignition, with 233 | dimensions of time. Must conform to :ref:`value-unit-optional ` 234 | 235 | .. _ignition-pressure-rise: 236 | 237 | * ``pressure-rise``: sequence, optional 238 | The pressure rise after the passage of the reflected shock, with dimensions of inverse time. 239 | Must conform to :ref:`value-unit-optional ` 240 | 241 | .. _ignition-equivalence-ratio: 242 | 243 | * ``equivalence-ratio``: float, optional 244 | The equivalence ratio of the experiment, dimensionless. Minimum value is 0.0. 245 | 246 | .. _ignition-rcm-data: 247 | 248 | * ``rcm-data``: mapping, optional 249 | Data related to rapid compression machine (RCM) experiments. The keys of the mapping are 250 | detailed in the :ref:`Rapid Compression Machine Data Keys ` section. 251 | 252 | .. _ignition-time-histories: 253 | 254 | * ``time-histories``: sequence, optional 255 | A sequence of mappings conforming to the :ref:`time-history ` 256 | schema. Used to specify a time-varying history of values during an experiment. 257 | 258 | .. _rcm-data-keys: 259 | 260 | Rapid Compression Machine Data Keys 261 | ----------------------------------- 262 | 263 | This section details the keys specific to rapid compression machine (RCM) experiments, which are 264 | subkeys of the :ref:`rcm-data ` key. 265 | 266 | .. _rcm-data-compression-time: 267 | 268 | * ``compression-time``: sequence, optional 269 | The time taken during the compression stroke of a rapid compression machine experiment, with 270 | dimensions of time. Must conform to :ref:`value-unit-optional ` 271 | 272 | .. _rcm-data-compressed-pressure: 273 | 274 | * ``compressed-pressure``: sequence, optional 275 | The pressure at the end of the compression stroke for a rapid compression machine experiment, 276 | with dimensions of mass per length per time squared. Must conform to 277 | :ref:`value-unit-optional ` 278 | 279 | .. _rcm-data-compressed-temperature: 280 | 281 | * ``compressed-temperature``: sequence, optional 282 | The temperature at the end of the compression stroke for a rapid compression machine experiment, 283 | with dimensions of temperature. Must conform to 284 | :ref:`value-unit-optional ` 285 | 286 | .. _rcm-data-compression-ratio: 287 | 288 | * ``compression-ratio``: sequence, optional 289 | The dimensionless volumetric compression ratio for a rapid compression machine experiment. Must 290 | conform to :ref:`value-unit-optional ` 291 | 292 | .. _rcm-data-stroke: 293 | 294 | * ``stroke``: sequence, optional 295 | The length of the stroke in a rapid compression machine experiment, with dimensions of length. 296 | Must conform to :ref:`value-unit-optional ` 297 | 298 | .. _rcm-data-clearance: 299 | 300 | * ``clearance``: sequence, optional 301 | The clearance from the piston face to the end wall of the reaction chamber at the end of 302 | compression, with dimensions of length. Must conform to 303 | :ref:`value-unit-optional ` 304 | 305 | .. _schema-only-keys: 306 | 307 | Schema-Only Keys 308 | ---------------- 309 | 310 | The schema files contain several keys that are used purely as references within the schema and 311 | should not be used in actual ChemKED files. These keys are documented in this section. 312 | 313 | .. _schema-author: 314 | 315 | * ``author``: mapping 316 | Information about a single author, used in several contexts. Fields: 317 | 318 | - ``name``: string, required 319 | The author's full name 320 | 321 | - ``ORCID``: string, optional 322 | The author's ORCID identifier. Validated to be a valid ORCID and that the ``name`` matches 323 | 324 | .. _schema-value-with-uncertainty: 325 | 326 | * ``value-with-uncertainty``: sequence 327 | A combination of a value and unit with uncertainty. Sequence elements: 328 | 329 | - 0: string, required 330 | The first element of the sequence should be the value and its associated 331 | units. The units are validated to have appropriate dimensions for the particular quantity 332 | under consideration 333 | 334 | - 1: mapping, optional 335 | The second element of the sequence should be a mapping representing the uncertainty. Fields: 336 | 337 | * ``uncertainty-type``: string, required 338 | The type of uncertainty. Options are ``absolute`` or ``relative``. 339 | 340 | * ``uncertainty``: string, required, excludes ``upper-uncertainty`` and ``lower-uncertainty`` 341 | The value of the uncertainty. If ``uncertainty-type`` is ``absolute``, must include 342 | units whose dimensions match the units of the value in the first element of the 343 | sequence. 344 | 345 | * ``upper-uncertainty``: string, required, excludes ``uncertainty``, requires ``lower-uncertainty`` 346 | The upper value of an asymmetrical uncertainty. Due to limitations in the Python 347 | library, asymmetrical uncertainties aren't supported in PyKED, so the larger of 348 | ``upper-uncertainty`` and ``lower-uncertainty`` is used. 349 | 350 | * ``lower-uncertainty``: string, required, excludes ``uncertainty``, requires ``upper-uncertainty`` 351 | The lower value of an asymmetrical uncertainty. Due to limitations in the Python 352 | library, asymmetrical uncertainties aren't supported in PyKED, so the larger of 353 | ``upper-uncertainty`` and ``lower-uncertainty`` is used. 354 | 355 | .. _schema-value-without-uncertainty: 356 | 357 | * ``value-without-uncertainty``: sequence 358 | A combination of a value and unit without uncertainty. Sequence elements: 359 | 360 | - 0: string, required 361 | The first element of the sequence should be the value and its associated 362 | units. The units are validated to have appropriate dimensions for the particular quantity 363 | under consideration 364 | 365 | .. _schema-value-unit-required: 366 | 367 | * ``value-unit-required``: sequence, required 368 | A sequence conforming to either :ref:`value-with-uncertainty ` or 369 | :ref:`value-without-uncertainty `. Must be included in the 370 | ChemKED file. 371 | 372 | .. _schema-value-unit-optional: 373 | 374 | * ``value-unit-optional``: sequence, optional 375 | A sequence conforming to either :ref:`value-with-uncertainty ` or 376 | :ref:`value-without-uncertainty `. May or may not be included 377 | in the ChemKED file. 378 | 379 | .. _ignition-time-history: 380 | 381 | * ``time-history``: mapping, optional 382 | Specify the time history of a quantity during an experiment. Fields: 383 | 384 | - ``quantity``: mapping, required 385 | A mapping describing the volume in the history. Fields: 386 | 387 | * ``units``: string, required 388 | The units of the volume, with dimensions of length cubed 389 | 390 | * ``column``: integer, required 391 | The 0-based index of the column containing the volume information in the ``values`` 392 | array. Must be 0 or 1 393 | 394 | - ``time``: mapping, required 395 | A mapping describing the time in the history. Fields: 396 | 397 | * ``units``: string, required 398 | The units of the time, with dimensions of time 399 | 400 | * ``column``: integer, required 401 | The 0-based index of the column containing the time information in the ``values`` 402 | array. Must be 0 or 1 403 | 404 | - ``uncertainty``: mapping, optional 405 | The uncertainty of the values in the ``quantity`` column. Can be specified either globally 406 | by a single value in the sequence or by specifying a column that must be present in the 407 | values array. Mapping keys: 408 | 409 | * ``type``: string, required 410 | Either ``absolute`` or ``relative`` to indicate the type of uncertainty 411 | 412 | * ``value``: string, optional 413 | A global value for the uncertainty applied to all points in the ``values`` array, 414 | specified as a string with units. Either this key must be present, or the ``column`` and 415 | ``units`` keys must be present 416 | 417 | * ``column``: integer, optional 418 | The column in the ``values`` array containing the uncertainty of each point. Either this 419 | key and the ``units`` key must be specified, or the ``value`` key must be specified. 420 | 421 | * ``units``: string, optional 422 | The units of the uncertainty in the ``column`` array. IF the ``type`` is relative, this 423 | should be ``dimensionless``. Either this key and the ``column`` key must be specified, 424 | or the ``value`` key must be specified. 425 | 426 | - ``values``: sequence or mapping, required 427 | Must be a sequence or mapping. If a mapping, the only key should be ``filename`` whose value 428 | should be the filename of a comma-separated value file containing the values for the 429 | history. If a sequence, should be a sequence of sequences describing the values of the 430 | volume at the time points. Can be entered in any supported syntax, including: 431 | 432 | .. code-block:: yaml 433 | 434 | - [0.0, 0.0] 435 | - [1.0, 1.0] 436 | - - 2.0 437 | - 2.0 438 | - - 3.0 439 | - 3.0 440 | -------------------------------------------------------------------------------- /docs/ck-tutorial.rst: -------------------------------------------------------------------------------- 1 | .. Tutorial on creating ChemKED files 2 | 3 | Creating ChemKED files 4 | ====================== 5 | 6 | ChemKED Overview 7 | ---------------- 8 | 9 | ChemKED (**Chem**\ ical **K**\ inetics **E**\ xperimental **D**\ atabase) files use the YAML data 10 | serialization format [yaml12]_. This format offers the advantages of being human readable, written 11 | in plain text, and having parsers in most common programming languages, including Python, C++, Java, 12 | Perl, MATLAB, and many others. The YAML syntax is quite simple: the basic file structure is made of 13 | mappings, delimited by a colon. The key for the mapping is on the left of the colon, and the value 14 | on the right can be a single value, a sequence of values, a nested mapping, or some combination of 15 | these: 16 | 17 | .. code-block:: yaml 18 | 19 | key1: value # Single-value mapping 20 | key2: # Sequence format 21 | - value 22 | - value 23 | key3: # Nested mapping 24 | key4: 0 25 | key5: # Sequence of mappings 26 | - key-s1: 0 27 | key-s2: value 28 | - key-s2: value 29 | key-s1: 0 30 | 31 | The ``value`` can be a string, integer, or floating point number. The ChemKED format is designed to 32 | include all of the information necessary to simulate a given experiment and can be thought of 33 | conceptually in three main sections, a "meta" section that contains information about the ChemKED 34 | file itself, a "reference" section that contains information about the type of experiment and the 35 | article where the data is published, and a "data" section that contains the actual data for the 36 | experiment. A full listing of the keys and their associated meanings can be found in the 37 | :doc:`schema-docs`. 38 | 39 | ChemKED files have the extension ``.yaml``. Within the file, indentation must be by spaces only, and 40 | each level should be indented by two spaces relative to the previous level. Please set your text 41 | editor to produce UNIX-style line endings (``\n``), not DOS style (``\r\n``). Note that all keys and 42 | values are case-sensitive and should be written entirely in lower case (except author names, journal 43 | names, and apparatus institution and facility, where standard case conventions may be used). 44 | 45 | The Meta Section 46 | ---------------- 47 | 48 | ChemKED files require some information about the file itself to be stored in the file. This helps 49 | ensure the integrity of the data encoded in the file. The meta information required for a ChemKED 50 | format file includes: 51 | 52 | * the author of the file (which could be different from the author of the study where the 53 | experiment is published) 54 | * the version of the file 55 | * the version of the ChemKED database format targeted by the file 56 | 57 | A typical meta section might look something like: 58 | 59 | .. code-block:: yaml 60 | 61 | file-authors: 62 | - name: Kyle E Niemeyer 63 | ORCID: 0000-0003-4425-7097 64 | file-version: 0 65 | chemked-version: 0.4.0 66 | 67 | The Reference Section 68 | --------------------- 69 | 70 | In the reference section, information about the experimental facility and the article where the data 71 | is published is collected. This information typically includes: 72 | 73 | * the type of experiment (for now, only autoignition experiments are supported) 74 | * the type and location of the experimental apparatus (rapid compression machine or shock tube) 75 | * the article authors and the journal, DOI, volume, and issue where the data was published 76 | * a note about where in the paper the data was collected from, if multiple data sets are 77 | presented in the same work 78 | 79 | As an example, the following is the reference section from the work of Mittal et al. [Mittal2006]_: 80 | 81 | .. code-block:: yaml 82 | 83 | reference: 84 | doi: 10.1002/kin.20180 85 | authors: 86 | - name: Gaurav Mittal 87 | - name: Chih-Jen Sung 88 | ORCID: 0000-0003-2046-8076 89 | - name: Richard A Yetter 90 | journal: International Journal of Chemical Kinetics 91 | year: 2006 92 | volume: 38 93 | pages: 516-529 94 | detail: Fig. 6, open circle 95 | experiment-type: ignition delay 96 | apparatus: 97 | kind: rapid compression machine 98 | institution: Case Western Reserve University 99 | facility: CWRU RCM 100 | 101 | The Data Section 102 | ---------------- 103 | 104 | In the data section, the actual data from the reference is represented. The data section contains a 105 | single top-level key, ``datapoints``, which contains a sequence whose elements represent the actual 106 | data encoded in the file. The sequence can contain a single data point from the work, or it can 107 | contain many data points. We have found that it is often convenient to represent only a single rapid 108 | compression machine autoignition experiment in a single ChemKED file, but shock tube autoignition 109 | experiments can often include multiple experiments in a file. 110 | 111 | Each single data point in the sequence of ``datapoints`` has a number of required and optional 112 | fields, depending on what type of data is being encoded. The typical information included will be: 113 | 114 | * temperature 115 | * pressure 116 | * initial composition 117 | * measured quantity (ignition delay, product composition, etc.) 118 | 119 | As an example, the following data is taken from the work of Stranic et al. [Stranic2012]_. This 120 | example shows the inclusion of multiple experiments in the ``datapoints`` key. 121 | 122 | .. code-block:: yaml 123 | 124 | datapoints: 125 | - temperature: 126 | - 1459 kelvin 127 | ignition-delay: 128 | - 347 us 129 | pressure: 130 | - 1.60 atm 131 | composition: *comp 132 | ignition-type: *ign 133 | equivalence-ratio: 0.5 134 | - temperature: 135 | - 1389 kelvin 136 | ignition-delay: 137 | - 756 us 138 | pressure: 139 | - 1.67 atm 140 | composition: *comp 141 | ignition-type: *ign 142 | equivalence-ratio: 0.5 143 | - temperature: 144 | - 1497 kelvin 145 | ignition-delay: 146 | - 212 us 147 | pressure: 148 | - 1.55 atm 149 | composition: *comp 150 | ignition-type: *ign 151 | equivalence-ratio: 0.5 152 | - temperature: 153 | - 1562 kelvin 154 | ignition-delay: 155 | - 105 us 156 | pressure: 157 | - 1.50 atm 158 | composition: *comp 159 | ignition-type: *ign 160 | equivalence-ratio: 0.5 161 | 162 | Note that units are required for all quantities with units, and the units are validated to have the 163 | appropriate dimensions for the particular quantity. 164 | 165 | In cases where the same value should be specified multiple times, ChemKED files have a special key 166 | called ``common-properties`` that stores any properties that are shared among multiple data points. 167 | Properties are stored in the ``common-properties`` section as **anchors** and filled into a data 168 | point with a **reference**. The reference syntax is shown in the example above in the 169 | ``composition`` and ``ignition-type`` keys, with the ``*comp`` and ``*ign`` as the values. 170 | References are denoted by the ``*``. An example of the ``common-properties`` key is shown below: 171 | 172 | .. code-block:: yaml 173 | 174 | common-properties: 175 | composition: &comp 176 | kind: mole fraction 177 | species: 178 | - species-name: t-butanol 179 | InChI: 1S/C4H10O/c1-4(2,3)5/h5H,1-3H3 180 | amount: 181 | - 0.003333333 182 | - species-name: O2 183 | InChI: 1S/O2/c1-2 184 | amount: 185 | - 0.04 186 | - species-name: Ar 187 | InChI: 1S/Ar 188 | amount: 189 | - 0.956666667 190 | ignition-type: &ign 191 | target: OH* 192 | type: 1/2 max 193 | 194 | In the ``common-properties`` section, the **anchor** is created by the ``&`` followed by the name of 195 | the anchor. This syntax stores the ``composition`` and ``ignition-type`` in the anchors ``comp`` and 196 | ``ign``, respectively, and in the ``datapoints`` section, these anchors are referenced by the ``*``. 197 | 198 | Use of the ``common-properties`` key is strongly encouraged when there are multiple data points with 199 | repeated values, to avoid typos and ensure consistency of the data. Note that if a field is required 200 | in a data point, it must be included in the data point (by referencing) even if it has already been 201 | included in the ``common-properties`` key. This is an intentional decision, and the user should use 202 | the anchor and reference syntax to avoid having to write the same value multiple times. 203 | 204 | Values in data points can also have an associated uncertainty. This uncertainty can be absolute or 205 | relative, and is specified in the following way (the values in this example are arbitrary, and don't 206 | represent actual experimental results): 207 | 208 | .. code-block:: yaml 209 | 210 | datapoints: 211 | - temperature: 212 | - 1459 kelvin 213 | - uncertainty-type: absolute 214 | uncertainty: 10 kelvin 215 | ignition-delay: 216 | - 347 us 217 | - uncertainty-type: relative 218 | uncertainty: 0.01 219 | pressure: 220 | - 1.60 atm 221 | composition: *comp 222 | ignition-type: *ign 223 | equivalence-ratio: 0.5 224 | 225 | Note that if the absolute uncertainty is specified, its units must have the same dimensions as the 226 | quantity. 227 | 228 | Examples 229 | -------- 230 | 231 | The following are complete examples of ChemKED files for autoignition experiments. 232 | 233 | Single Data Point with Volume History 234 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 235 | 236 | The following example encodes an experiment from the work of Mittal et al. [Mittal2006]_ in a rapid 237 | compression machine. 238 | 239 | .. code-block:: yaml 240 | 241 | --- 242 | file-authors: 243 | - name: Kyle E Niemeyer 244 | ORCID: 0000-0003-4425-7097 245 | file-version: 0 246 | chemked-version: 0.4.0 247 | reference: 248 | doi: 10.1002/kin.20180 249 | authors: 250 | - name: Gaurav Mittal 251 | - name: Chih-Jen Sung 252 | ORCID: 0000-0003-2046-8076 253 | - name: Richard A Yetter 254 | journal: International Journal of Chemical Kinetics 255 | year: 2006 256 | volume: 38 257 | pages: 516-529 258 | detail: Fig. 6, open circle 259 | experiment-type: ignition delay 260 | apparatus: 261 | kind: rapid compression machine 262 | institution: Case Western Reserve University 263 | facility: CWRU RCM 264 | datapoints: 265 | - temperature: 266 | - 297.4 kelvin 267 | ignition-delay: 268 | - 1.0 ms 269 | pressure: 270 | - 958.0 torr 271 | composition: 272 | kind: mole fraction 273 | species: 274 | - species-name: H2 275 | InChI: 1S/H2/h1H 276 | amount: 277 | - 0.12500 278 | - species-name: O2 279 | InChI: 1S/O2/c1-2 280 | amount: 281 | - 0.06250 282 | - species-name: N2 283 | InChI: 1S/N2/c1-2 284 | amount: 285 | - 0.18125 286 | - species-name: Ar 287 | InChI: 1S/Ar 288 | amount: 289 | - 0.63125 290 | ignition-type: 291 | target: pressure 292 | type: d/dt max 293 | rcm-data: 294 | compression-time: 295 | - 38.0 ms 296 | time-histories: 297 | - type: volume 298 | time: 299 | units: s 300 | column: 0 301 | volume: 302 | units: cm3 303 | column: 1 304 | values: 305 | - [0.00E+000, 5.47669375000E+002] 306 | - [1.00E-003, 5.46608789894E+002] 307 | - [2.00E-003, 5.43427034574E+002] 308 | - [3.00E-003, 5.38124109043E+002] 309 | - [4.00E-003, 5.30700013298E+002] 310 | - [5.00E-003, 5.21154747340E+002] 311 | - [6.00E-003, 5.09488311170E+002] 312 | - [7.00E-003, 4.95700704787E+002] 313 | - [8.00E-003, 4.79791928191E+002] 314 | - [9.00E-003, 4.61761981383E+002] 315 | - [1.00E-002, 4.41610864362E+002] 316 | - [1.10E-002, 4.20399162234E+002] 317 | - [1.20E-002, 3.99187460106E+002] 318 | - [1.30E-002, 3.77975757979E+002] 319 | - [1.40E-002, 3.56764055851E+002] 320 | - [1.50E-002, 3.35552353723E+002] 321 | - [1.60E-002, 3.14340651596E+002] 322 | - [1.70E-002, 2.93128949468E+002] 323 | - [1.80E-002, 2.71917247340E+002] 324 | - [1.90E-002, 2.50705545213E+002] 325 | - [2.00E-002, 2.29493843085E+002] 326 | - [2.10E-002, 2.08282140957E+002] 327 | - [2.20E-002, 1.87070438830E+002] 328 | - [2.30E-002, 1.65858736702E+002] 329 | - [2.40E-002, 1.44647034574E+002] 330 | - [2.50E-002, 1.23435332447E+002] 331 | - [2.60E-002, 1.02223630319E+002] 332 | - [2.70E-002, 8.10119281915E+001] 333 | - [2.80E-002, 6.33355097518E+001] 334 | - [2.90E-002, 5.27296586879E+001] 335 | - [3.00E-002, 4.91943750000E+001] 336 | - [3.10E-002, 4.97137623933E+001] 337 | - [3.20E-002, 5.02063762048E+001] 338 | - [3.30E-002, 5.06454851923E+001] 339 | - [3.40E-002, 5.10218564529E+001] 340 | - [3.50E-002, 5.13374097598E+001] 341 | - [3.60E-002, 5.16004693977E+001] 342 | - [3.70E-002, 5.18223244382E+001] 343 | - [3.80E-002, 5.20148449242E+001] 344 | - [3.90E-002, 5.21889350372E+001] 345 | - [4.00E-002, 5.23536351113E+001] 346 | - [4.10E-002, 5.25157124459E+001] 347 | - [4.20E-002, 5.26796063730E+001] 348 | - [4.30E-002, 5.28476160610E+001] 349 | - [4.40E-002, 5.30202402028E+001] 350 | - [4.50E-002, 5.31965961563E+001] 351 | - [4.60E-002, 5.33748623839E+001] 352 | - [4.70E-002, 5.35527022996E+001] 353 | - [4.80E-002, 5.37276399831E+001] 354 | - [4.90E-002, 5.38973687732E+001] 355 | - [5.00E-002, 5.40599826225E+001] 356 | - [5.10E-002, 5.42141273988E+001] 357 | - [5.20E-002, 5.43590751578E+001] 358 | - [5.30E-002, 5.44947289126E+001] 359 | - [5.40E-002, 5.46215686913E+001] 360 | - [5.50E-002, 5.47405518236E+001] 361 | - [5.60E-002, 5.48529815402E+001] 362 | - [5.70E-002, 5.49603582190E+001] 363 | - [5.80E-002, 5.50642270863E+001] 364 | - [5.90E-002, 5.51660349836E+001] 365 | - [6.00E-002, 5.52670070646E+001] 366 | - [6.10E-002, 5.53680520985E+001] 367 | - [6.20E-002, 5.54697025392E+001] 368 | - [6.30E-002, 5.55720927915E+001] 369 | - [6.40E-002, 5.56749762728E+001] 370 | - [6.50E-002, 5.57777790517E+001] 371 | - [6.60E-002, 5.58796851466E+001] 372 | - [6.70E-002, 5.59797461155E+001] 373 | - [6.80E-002, 5.60770054561E+001] 374 | - [6.90E-002, 5.61706266985E+001] 375 | - [7.00E-002, 5.62600130036E+001] 376 | - [7.10E-002, 5.63449057053E+001] 377 | - [7.20E-002, 5.64254496625E+001] 378 | - [7.30E-002, 5.65022146282E+001] 379 | - [7.40E-002, 5.65761642150E+001] 380 | - [7.50E-002, 5.66485675508E+001] 381 | - [7.60E-002, 5.67208534842E+001] 382 | - [7.70E-002, 5.67944133373E+001] 383 | - [7.80E-002, 5.68703658198E+001] 384 | - [7.90E-002, 5.69493069272E+001] 385 | - [8.00E-002, 5.70310785669E+001] 386 | - [8.10E-002, 5.71146023893E+001] 387 | - [8.20E-002, 5.71978399741E+001] 388 | - [8.30E-002, 5.72779572372E+001] 389 | - [8.40E-002, 5.73517897984E+001] 390 | - [8.50E-002, 5.74167271960E+001] 391 | - [8.60E-002, 5.74721573687E+001] 392 | - [8.70E-002, 5.75216388520E+001] 393 | - [8.80E-002, 5.75759967785E+001] 394 | - [8.90E-002, 5.76575701358E+001] 395 | - [9.00E-002, 5.78058719368E+001] 396 | - [9.10E-002, 5.80849611077E+001] 397 | - [9.20E-002, 5.85928651155E+001] 398 | - [9.30E-002, 5.94734357453E+001] 399 | - [9.40E-002, 6.09310671165E+001] 400 | - [9.50E-002, 6.32487551103E+001] 401 | - [9.60E-002, 6.68100309742E+001] 402 | ... 403 | 404 | Multiple Experiments 405 | ^^^^^^^^^^^^^^^^^^^^ 406 | 407 | The following example encodes some of the data from the work of Stranic et al. [Stranic2012]_ in the 408 | shock tube at Stanford. 409 | 410 | .. code-block:: yaml 411 | 412 | --- 413 | file-authors: 414 | - name: Morgan Mayer 415 | ORCID: 0000-0001-7137-5721 416 | file-version: 0 417 | chemked-version: 0.4.0 418 | reference: 419 | doi: 10.1016/j.combustflame.2011.08.014 420 | authors: 421 | - name: Ivo Stranic 422 | - name: Deanna P. Chase 423 | - name: Joseph T. Harmon 424 | - name: Sheng Yang 425 | - name: David F. Davidson 426 | - name: Ronald K. Hanson 427 | journal: Combustion and Flame 428 | year: 2012 429 | volume: 159 430 | pages: 516-527 431 | experiment-type: ignition delay 432 | apparatus: 433 | kind: shock tube 434 | institution: High Temperature Gasdynamics Laboratory, Stanford University 435 | facility: stainless steel shock tube 436 | common-properties: 437 | composition: &comp 438 | kind: mole fraction 439 | species: 440 | - species-name: t-butanol 441 | InChI: 1S/C4H10O/c1-4(2,3)5/h5H,1-3H3 442 | amount: 443 | - 0.003333333 444 | - species-name: O2 445 | InChI: 1S/O2/c1-2 446 | amount: 447 | - 0.04 448 | - species-name: Ar 449 | InChI: 1S/Ar 450 | amount: 451 | - 0.956666667 452 | ignition-type: &ign 453 | target: OH* 454 | type: 1/2 max 455 | datapoints: 456 | - temperature: 457 | - 1459 kelvin 458 | ignition-delay: 459 | - 347 us 460 | pressure: 461 | - 1.60 atm 462 | composition: *comp 463 | ignition-type: *ign 464 | equivalence-ratio: 0.5 465 | - temperature: 466 | - 1389 kelvin 467 | ignition-delay: 468 | - 756 us 469 | pressure: 470 | - 1.67 atm 471 | composition: *comp 472 | ignition-type: *ign 473 | equivalence-ratio: 0.5 474 | - temperature: 475 | - 1497 kelvin 476 | ignition-delay: 477 | - 212 us 478 | pressure: 479 | - 1.55 atm 480 | composition: *comp 481 | ignition-type: *ign 482 | equivalence-ratio: 0.5 483 | - temperature: 484 | - 1562 kelvin 485 | ignition-delay: 486 | - 105 us 487 | pressure: 488 | - 1.50 atm 489 | composition: *comp 490 | ignition-type: *ign 491 | equivalence-ratio: 0.5 492 | ... 493 | 494 | 495 | Converting from ReSpecTh 496 | ------------------------ 497 | 498 | PyKED provides converter functions from (and to) the ReSpecTh XML format 499 | [Varga2015a]_, [Varga2015b]_, though ChemKED files created in this manner may 500 | require manual edits to fully satisfy our schema. 501 | 502 | Given a ReSpecTh XML file ``file.xml``, a corresponding ChemKED file can be created 503 | either from the command line 504 | 505 | .. code-block:: bash 506 | 507 | respth2ck -i file.xml -o file.yaml 508 | 509 | or via Python: 510 | 511 | .. code-block:: Python 512 | 513 | from pyked.converters import ReSpecTh_to_ChemKED 514 | ReSpecTh_to_ChemKED('file.xml', 'file.yaml') 515 | 516 | Information about the person creating this new ChemKED file (e.g., file author name 517 | and their ORCID) may also be added via the ``file_author`` and ``file_author_orcid`` 518 | arguments in Python or the corresponding command-line options ``-fa`` and ``-fo``. More 519 | details can be found via ``respth2ck --help`` or 520 | ``help(pyked.converters.ReSpecTh_to_ChemKED)``, respectively. 521 | 522 | PyKED also provides a converter to generate ReSpecTh files based on ChemKED records. 523 | Given a ChemKED file ``file.yaml``, a corresponding ReSpecTh file can be created 524 | from the command line via 525 | 526 | .. code-block:: bash 527 | 528 | ck2respth -i file.yaml -o file.xml 529 | 530 | or from inside Python with 531 | 532 | .. code-block:: Python 533 | 534 | from pyked import ChemKED 535 | c = ChemKED('file.yaml') 536 | c.convert_to_ReSpecTh('file.xml') 537 | 538 | Note that some information, or granularity of details, may be lost in this conversion. 539 | 540 | 541 | Works Cited 542 | ----------- 543 | 544 | .. [yaml12] Ben-Kiki, Oren, Clark Evans, and Ingy döt Net. 2009. "YAML Ain't Markup 545 | Language (Yaml™) Version 1.2." http://www.yaml.org/spec/1.2/spec.html. 546 | 547 | .. [Mittal2006] Mittal, Gaurav, Chih-Jen Sung, and Richard A. Yetter. 2006. 548 | "Autoignition of H2/CO at Elevated Pressures in a Rapid Compression 549 | Machine." *International Journal of Chemical Kinetics* 38 (8): 516–29. 550 | doi:\ `10.1002/kin.20180 `__. 551 | 552 | .. [Stranic2012] Stranic, Ivo, Deanna P. Chase, Joseph T. Harmon, Sheng Yang, David F. 553 | Davidson, and Ronald K. Hanson. 2012. "Shock Tube Measurements of 554 | Ignition Delay Times for the Butanol Isomers." *Combustion and Flame* 555 | 159 (2): 516–27. 556 | doi:\ `10.1016/j.combustflame.2011.08.014 `__. 557 | 558 | .. [Varga2015a] Varga, Tamás, Tamás Turányi, Eszter Czinki, Tibor Furtenbacher, Attila G. Császár, 559 | "ReSpecTh: a joint reaction kinetics, spectroscopy, and thermochemistry information 560 | system." 2015. Proceedings of the 7th European Combustion Meeting, 561 | Budapest, Hungary. 562 | 563 | .. [Varga2015b] Varga, Tamás. "ReSpecTh Kinetics Data Format Specification v1.0." 2015. 564 | http://respecth.hu/ 565 | -------------------------------------------------------------------------------- /pyked/validation.py: -------------------------------------------------------------------------------- 1 | """Validation class for ChemKED schema. 2 | """ 3 | from warnings import warn 4 | import re 5 | 6 | from pkg_resources import resource_filename 7 | import yaml 8 | 9 | import numpy as np 10 | import pint 11 | from requests.exceptions import HTTPError, ConnectionError 12 | from cerberus import Validator, SchemaError 13 | import habanero 14 | from .orcid import search_orcid 15 | 16 | units = pint.UnitRegistry() 17 | """Unit registry to contain the units used in PyKED""" 18 | 19 | units.define('cm3 = centimeter**3') 20 | Q_ = units.Quantity 21 | 22 | crossref_api = habanero.Crossref(mailto='prometheus@pr.omethe.us') 23 | 24 | # Load the ChemKED schema definition file 25 | schema_file = resource_filename(__name__, 'schemas/chemked_schema.yaml') 26 | with open(schema_file, 'r') as f: 27 | schema_list = f.readlines() 28 | 29 | inc_start = None 30 | inc_end = None 31 | inc_list = [] 32 | no_includes = False 33 | for l_num, l in enumerate(schema_list): 34 | if l.startswith('!include'): 35 | if no_includes: # pragma: no cover 36 | raise SchemaError('All included files must be first in the main schema') 37 | 38 | if inc_start is None: 39 | inc_start = l_num 40 | 41 | if inc_end is not None: # pragma: no cover 42 | raise SchemaError('All included files must be first in the main schema') 43 | 44 | inc_fname = l.split('!include')[1].strip() 45 | inc_fname = resource_filename(__name__, 'schemas/' + inc_fname) 46 | with open(inc_fname, 'r') as f: 47 | inc_list.extend(f.readlines()) 48 | else: 49 | if not l.strip() or l.startswith('#') or l.startswith('---'): 50 | continue 51 | 52 | if inc_start is None: # pragma: no cover 53 | no_includes = True 54 | 55 | if inc_start is not None and inc_end is None: 56 | inc_end = l_num 57 | 58 | schema_list[inc_start:inc_end] = inc_list 59 | schema = yaml.safe_load(''.join(schema_list)) 60 | 61 | # These top-level keys in the schema serve as references for lower-level keys. 62 | # They are removed to prevent conflicts due to required variables, etc. 63 | for key in ['author', 'value-unit-required', 'value-unit-optional', 64 | 'composition', 'ignition-type', 'value-with-uncertainty', 65 | 'value-without-uncertainty', 66 | ]: 67 | del schema[key] 68 | 69 | # SI units for available value-type properties 70 | property_units = { 71 | 'temperature': 'kelvin', 72 | 'compressed-temperature': 'kelvin', 73 | 'pressure': 'pascal', 74 | 'compressed-pressure': 'pascal', 75 | 'ignition-delay': 'second', 76 | 'first-stage-ignition-delay': 'second', 77 | 'pressure-rise': '1.0 / second', 78 | 'compression-time': 'second', 79 | 'volume': 'meter**3', 80 | 'time': 'second', 81 | 'piston position': 'meter', 82 | 'emission': 'dimensionless', 83 | 'absorption': 'dimensionless', 84 | 'concentration': 'mole/meter**3', 85 | 'stroke': 'meter', 86 | 'clearance': 'meter', 87 | 'compression-ratio': 'dimensionless', 88 | } 89 | 90 | 91 | def compare_name(given_name, family_name, question_name): 92 | """Compares a name in question to a specified name separated into given and family. 93 | 94 | The name in question ``question_name`` can be of varying format, including 95 | "Kyle E. Niemeyer", "Kyle Niemeyer", "K. E. Niemeyer", "KE Niemeyer", and 96 | "K Niemeyer". Other possibilities include names with hyphens such as 97 | "Chih-Jen Sung", "C. J. Sung", "C-J Sung". 98 | 99 | Examples: 100 | >>> compare_name('Kyle', 'Niemeyer', 'Kyle E Niemeyer') 101 | True 102 | >>> compare_name('Chih-Jen', 'Sung', 'C-J Sung') 103 | True 104 | 105 | Args: 106 | given_name (`str`): Given (or first) name to be checked against. 107 | family_name (`str`): Family (or last) name to be checked against. 108 | question_name (`str`): The whole name in question. 109 | 110 | Returns: 111 | `bool`: The return value. True for successful comparison, False otherwise. 112 | """ 113 | # lowercase everything 114 | given_name = given_name.lower() 115 | family_name = family_name.lower() 116 | question_name = question_name.lower() 117 | 118 | # rearrange names given as "last, first middle" 119 | if ',' in question_name: 120 | name_split = question_name.split(',') 121 | name_split.reverse() 122 | question_name = ' '.join(name_split).strip() 123 | 124 | # remove periods 125 | question_name = question_name.replace('.', '') 126 | given_name = given_name.replace('.', '') 127 | family_name = family_name.replace('.', '') 128 | 129 | # split names by , - . 130 | given_name = list(filter(None, re.split(r"[, \-.]+", given_name))) 131 | num_family_names = len(list(filter(None, re.split("[, .]+", family_name)))) 132 | 133 | # split name in question by , - . 134 | name_split = list(filter(None, re.split(r"[, \-.]+", question_name))) 135 | first_name = [name_split[0]] 136 | if len(name_split) > 2: 137 | first_name += [n for n in name_split[1:-num_family_names]] 138 | 139 | if len(first_name) > 1 and len(given_name) == len(first_name): 140 | # both have same number of first and middle names/initials 141 | for i in range(1, len(first_name)): 142 | first_name[i] = first_name[i][0] 143 | given_name[i] = given_name[i][0] 144 | elif len(given_name) != len(first_name): 145 | min_names = min(len(given_name), len(first_name)) 146 | first_name = first_name[:min_names] 147 | given_name = given_name[:min_names] 148 | 149 | # first initial 150 | if len(first_name[0]) == 1 or len(given_name[0]) == 1: 151 | given_name[0] = given_name[0][0] 152 | first_name[0] = first_name[0][0] 153 | 154 | # first and middle initials combined 155 | if len(first_name[0]) > 1 or len(given_name[0]) > 1: 156 | given_name[0] = given_name[0][0] 157 | first_name[0] = name_split[0][0] 158 | 159 | # Hyphenated last name may need to be reconnected 160 | if num_family_names == 1 and '-' in family_name: 161 | num_hyphen = family_name.count('-') 162 | family_name_compare = '-'.join(name_split[-(num_hyphen + 1):]) 163 | else: 164 | family_name_compare = ' '.join(name_split[-num_family_names:]) 165 | 166 | return given_name == first_name and family_name == family_name_compare 167 | 168 | 169 | class OurValidator(Validator): 170 | """Custom validator with rules for Quantities and references. 171 | """ 172 | def _validate_isvalid_t_range(self, isvalid_t_range, field, values): 173 | """Checks that the temperature ranges given for thermo data are valid 174 | Args: 175 | isvalid_t_range (`bool`): flag from schema indicating T range is to be checked 176 | field (`str`): T_range 177 | values (`list`): List of temperature values indicating low, middle, and high ranges 178 | 179 | The rule's arguments are validated against this schema: 180 | {'isvalid_t_range': {'type': 'bool'}, 'field': {'type': 'str'}, 181 | 'value': {'type': 'list'}} 182 | """ 183 | if all([isinstance(v, (float, int)) for v in values]): 184 | # If no units given, assume Kelvin 185 | T_low = Q_(values[0], 'K') 186 | T_mid = Q_(values[1], 'K') 187 | T_hi = Q_(values[2], 'K') 188 | elif all([isinstance(v, str) for v in values]): 189 | T_low = Q_(values[0]) 190 | T_mid = Q_(values[1]) 191 | T_hi = Q_(values[2]) 192 | else: 193 | self._error(field, 'The temperatures in the range must all be either with units or ' 194 | 'without units, they cannot be mixed') 195 | return False 196 | 197 | if min([T_low, T_mid, T_hi]) != T_low: 198 | self._error(field, 'The first element of the T_range must be the lower limit') 199 | if max([T_low, T_mid, T_hi]) != T_hi: 200 | self._error(field, 'The last element of the T_range must be the upper limit') 201 | 202 | def _validate_isvalid_unit(self, isvalid_unit, field, value): 203 | """Checks for appropriate units using Pint unit registry. 204 | Args: 205 | isvalid_unit (`bool`): flag from schema indicating units to be checked. 206 | field (`str`): property associated with units in question. 207 | value (`dict`): dictionary of values from file associated with this property. 208 | 209 | The rule's arguments are validated against this schema: 210 | {'isvalid_unit': {'type': 'bool'}, 'field': {'type': 'str'}, 211 | 'value': {'type': 'dict'}} 212 | """ 213 | quantity = 1.0 * units(value['units']) 214 | try: 215 | quantity.to(property_units[field]) 216 | except pint.DimensionalityError: 217 | self._error(field, 'incompatible units; should be consistent ' 218 | 'with ' + property_units[field] 219 | ) 220 | 221 | def _validate_isvalid_history(self, isvalid_history, field, value): 222 | """Checks that the given time history is properly formatted. 223 | 224 | Args: 225 | isvalid_history (`bool`): flag from schema indicating units to be checked. 226 | field (`str`): property associated with history in question. 227 | value (`dict`): dictionary of values from file associated with this property. 228 | 229 | The rule's arguments are validated against this schema: 230 | {'isvalid_history': {'type': 'bool'}, 'field': {'type': 'str'}, 231 | 'value': {'type': 'dict'}} 232 | """ 233 | # Check the type has appropriate units 234 | history_type = value['type'] 235 | if history_type.endswith('emission'): 236 | history_type = 'emission' 237 | elif history_type.endswith('absorption'): 238 | history_type = 'absorption' 239 | quantity = 1.0*(units(value['quantity']['units'])) 240 | try: 241 | quantity.to(property_units[history_type]) 242 | except pint.DimensionalityError: 243 | self._error(field, 'incompatible units; should be consistent ' 244 | 'with ' + property_units[history_type]) 245 | 246 | # Check that time has appropriate units 247 | time = 1.0*(units(value['time']['units'])) 248 | try: 249 | time.to(property_units['time']) 250 | except pint.DimensionalityError: 251 | self._error(field, 'incompatible units; should be consistent ' 252 | 'with ' + property_units['time']) 253 | 254 | # Check that the values have the right number of columns 255 | n_cols = len(value['values'][0]) 256 | max_cols = max(value['time']['column'], 257 | value['quantity']['column'], 258 | value.get('uncertainty', {}).get('column', 0)) + 1 259 | if n_cols > max_cols: 260 | self._error(field, 'too many columns in the values') 261 | elif n_cols < max_cols: 262 | self._error(field, 'not enough columns in the values') 263 | 264 | def _validate_isvalid_quantity(self, isvalid_quantity, field, value): 265 | """Checks for valid given value and appropriate units. 266 | 267 | Args: 268 | isvalid_quantity (`bool`): flag from schema indicating quantity to be checked. 269 | field (`str`): property associated with quantity in question. 270 | value (`list`): list whose first element is a string representing a value with units 271 | 272 | The rule's arguments are validated against this schema: 273 | {'isvalid_quantity': {'type': 'bool'}, 'field': {'type': 'str'}, 274 | 'value': {'type': 'list'}} 275 | """ 276 | quantity = Q_(value[0]) 277 | low_lim = 0.0 * units(property_units[field]) 278 | 279 | try: 280 | if quantity <= low_lim: 281 | self._error( 282 | field, 'value must be greater than 0.0 {}'.format(property_units[field]), 283 | ) 284 | except pint.DimensionalityError: 285 | self._error(field, 'incompatible units; should be consistent ' 286 | 'with ' + property_units[field] 287 | ) 288 | 289 | def _validate_isvalid_uncertainty(self, isvalid_uncertainty, field, value): 290 | """Checks for valid given value and appropriate units with uncertainty. 291 | 292 | Args: 293 | isvalid_uncertainty (`bool`): flag from schema indicating uncertainty to be checked 294 | field (`str`): property associated with the quantity in question. 295 | value (`list`): list with the string of the value of the quantity and a dictionary of 296 | the uncertainty 297 | 298 | The rule's arguments are validated against this schema: 299 | {'isvalid_uncertainty': {'type': 'bool'}, 'field': {'type': 'str'}, 300 | 'value': {'type': 'list'}} 301 | """ 302 | self._validate_isvalid_quantity(True, field, value) 303 | 304 | # This len check is necessary for reasons that aren't quite clear to me 305 | # Cerberus calls this validation method even when lists have only one element 306 | # and should therefore be validated only by isvalid_quantity 307 | if len(value) > 1 and value[1]['uncertainty-type'] != 'relative': 308 | if value[1].get('uncertainty') is not None: 309 | self._validate_isvalid_quantity(True, field, [value[1]['uncertainty']]) 310 | 311 | if value[1].get('upper-uncertainty') is not None: 312 | self._validate_isvalid_quantity(True, field, [value[1]['upper-uncertainty']]) 313 | 314 | if value[1].get('lower-uncertainty') is not None: 315 | self._validate_isvalid_quantity(True, field, [value[1]['lower-uncertainty']]) 316 | 317 | def _validate_isvalid_reference(self, isvalid_reference, field, value): 318 | """Checks valid reference metadata using DOI (if present). 319 | 320 | Args: 321 | isvalid_reference (`bool`): flag from schema indicating reference to be checked. 322 | field (`str`): 'reference' 323 | value (`dict`): dictionary of reference metadata. 324 | 325 | The rule's arguments are validated against this schema: 326 | {'isvalid_reference': {'type': 'bool'}, 'field': {'type': 'str'}, 327 | 'value': {'type': 'dict'}} 328 | 329 | """ 330 | if 'doi' in value: 331 | try: 332 | ref = crossref_api.works(ids=value['doi'])['message'] 333 | except (HTTPError, habanero.RequestError): 334 | self._error(field, 'DOI not found') 335 | return 336 | except ConnectionError: 337 | warn('network not available, DOI not validated.') 338 | return 339 | 340 | # Assume that the reference returned by the DOI lookup always has a container-title 341 | ref_container = ref.get('container-title')[0] 342 | # TODO: Add other container types: value.get('journal') or value.get('report') or ... 343 | # note that there's a type field in the ref that is journal-article, proceedings-article 344 | container = value.get('journal') 345 | if container is None or container != ref_container: 346 | self._error(field, 'journal should be {}'.format(ref_container)) 347 | 348 | # Assume that the reference returned by DOI lookup always has a year 349 | ref_year = ref.get('published-print') or ref.get('published-online') 350 | ref_year = ref_year['date-parts'][0][0] 351 | year = value.get('year') 352 | if year is None or year != ref_year: 353 | self._error(field, 'year should be {}'.format(ref_year)) 354 | 355 | # Volume number might not be in the reference 356 | ref_volume = ref.get('volume') 357 | volume = value.get('volume') 358 | if ref_volume is None: 359 | if volume is not None: 360 | self._error(field, 'Volume was specified in the YAML but is not present in the ' 361 | 'DOI reference.') 362 | else: 363 | if volume is None or int(volume) != int(ref_volume): 364 | self._error(field, 'volume should be {}'.format(ref_volume)) 365 | 366 | # Pages might not be in the reference 367 | ref_pages = ref.get('page') 368 | pages = value.get('pages') 369 | if ref_pages is None: 370 | if pages is not None: 371 | self._error(field, 'Pages were specified in the YAML but are not present in ' 372 | 'the DOI reference.') 373 | else: 374 | if pages is None or pages != ref_pages: 375 | self._error(field, 'pages should be {}'.format(ref_pages)) 376 | 377 | # check that all authors present 378 | authors = value['authors'][:] 379 | author_names = [a['name'] for a in authors] 380 | for author in ref['author']: 381 | # find using family name 382 | author_match = next( 383 | (a for a in authors if 384 | compare_name(author['given'], author['family'], a['name']) 385 | ), 386 | None 387 | ) 388 | # error if missing author in given reference information 389 | if author_match is None: 390 | self._error(field, 'Missing author: ' + 391 | ' '.join([author['given'], author['family']]) 392 | ) 393 | else: 394 | author_names.remove(author_match['name']) 395 | 396 | # validate ORCID if given 397 | orcid = author.get('ORCID') 398 | if orcid: 399 | # Crossref may give ORCID as http://orcid.org/####-####-####-#### 400 | # so need to strip the leading URL 401 | orcid = orcid[orcid.rfind('/') + 1:] 402 | 403 | if 'ORCID' in author_match: 404 | if author_match['ORCID'] != orcid: 405 | self._error( 406 | field, author_match['name'] + ' ORCID does ' + 407 | 'not match that in reference. Reference: ' + 408 | orcid + '. Given: ' + author_match['ORCID'] 409 | ) 410 | else: 411 | # ORCID not given, suggest adding it 412 | warn('ORCID ' + orcid + ' missing for ' + author_match['name']) 413 | 414 | # check for extra names given 415 | if len(author_names) > 0: 416 | self._error(field, 'Extra author(s) given: ' + 417 | ', '.join(author_names) 418 | ) 419 | 420 | def _validate_isvalid_orcid(self, isvalid_orcid, field, value): 421 | """Checks for valid ORCID if given. 422 | 423 | Args: 424 | isvalid_orcid (`bool`): flag from schema indicating ORCID to be checked. 425 | field (`str`): 'author' 426 | value (`dict`): dictionary of author metadata. 427 | 428 | The rule's arguments are validated against this schema: 429 | {'isvalid_orcid': {'type': 'bool'}, 'field': {'type': 'str'}, 430 | 'value': {'type': 'dict'}} 431 | 432 | """ 433 | if isvalid_orcid and 'ORCID' in value: 434 | try: 435 | res = search_orcid(value['ORCID']) 436 | except ConnectionError: 437 | warn('network not available, ORCID not validated.') 438 | return 439 | except HTTPError: 440 | self._error(field, 'ORCID incorrect or invalid for ' + 441 | value['name'] 442 | ) 443 | return 444 | 445 | family_name = res['name']['family-name']['value'] 446 | given_name = res['name']['given-names']['value'] 447 | if not compare_name(given_name, family_name, value['name']): 448 | self._error(field, 'Name and ORCID do not match. Name supplied: ' + 449 | value['name'] + '. Name associated with ORCID: ' + 450 | ' '.join([given_name, family_name]) 451 | ) 452 | 453 | def _validate_isvalid_composition(self, isvalid_composition, field, value): 454 | """Checks for valid specification of composition. 455 | 456 | Args: 457 | isvalid_composition (bool): flag from schema indicating 458 | composition to be checked. 459 | field (str): 'composition' 460 | value (dict): dictionary of composition 461 | 462 | The rule's arguments are validated against this schema: 463 | {'isvalid_composition': {'type': 'bool'}, 'field': {'type': 'str'}, 464 | 'value': {'type': 'dict'}} 465 | """ 466 | sum_amount = 0.0 467 | if value['kind'] in ['mass fraction', 'mole fraction']: 468 | low_lim = 0.0 469 | up_lim = 1.0 470 | total_amount = 1.0 471 | elif value['kind'] in ['mole percent']: 472 | low_lim = 0.0 473 | up_lim = 100.0 474 | total_amount = 100.0 475 | else: 476 | self._error(field, 'composition kind must be "mole percent", "mass fraction", or ' 477 | '"mole fraction"') 478 | return False 479 | 480 | for sp in value['species']: 481 | amount = sp['amount'][0] 482 | sum_amount += amount 483 | 484 | # Check that amount within bounds, based on kind specified 485 | if amount < low_lim: 486 | self._error(field, 'Species ' + sp['species-name'] + ' ' + 487 | value['kind'] + ' must be greater than {:.1f}'.format(low_lim) 488 | ) 489 | elif amount > up_lim: 490 | self._error(field, 'Species ' + sp['species-name'] + ' ' + 491 | value['kind'] + ' must be less than {:.1f}'.format(up_lim) 492 | ) 493 | 494 | # Make sure mole/mass fraction sum to 1 495 | if not np.isclose(total_amount, sum_amount): 496 | self._error(field, 'Species ' + value['kind'] + 497 | 's do not sum to {:.1f}: '.format(total_amount) + 498 | '{:f}'.format(sum_amount) 499 | ) 500 | # TODO: validate InChI, SMILES, or atomic-composition 501 | -------------------------------------------------------------------------------- /pyked/converters.py: -------------------------------------------------------------------------------- 1 | """Module with converters from other formats. 2 | """ 3 | 4 | # Standard libraries 5 | import os 6 | from argparse import ArgumentParser 7 | from warnings import warn 8 | import xml.etree.ElementTree as etree 9 | 10 | from requests.exceptions import HTTPError, ConnectionError 11 | import habanero 12 | import pint 13 | 14 | # Local imports 15 | from .validation import yaml, property_units, crossref_api 16 | from .validation import units as unit_registry 17 | from ._version import __version__ 18 | from . import chemked 19 | 20 | # Valid properties for ReSpecTh dataGroup 21 | datagroup_properties = ['temperature', 'pressure', 'ignition delay', 22 | 'pressure rise', 23 | ] 24 | """`list`: Valid properties for a ReSpecTh dataGroup""" 25 | 26 | 27 | class ParseError(Exception): 28 | """Base class for errors.""" 29 | pass 30 | 31 | 32 | class KeywordError(ParseError): 33 | """Raised for errors in keyword parsing.""" 34 | 35 | def __init__(self, *keywords): 36 | self.keywords = keywords 37 | 38 | def __str__(self): 39 | return repr('Error: {}.'.format(self.keywords[0])) 40 | 41 | 42 | class MissingElementError(KeywordError): 43 | """Raised for missing required elements.""" 44 | 45 | def __str__(self): 46 | return repr('Error: required element {} is missing.'.format( 47 | self.keywords[0])) 48 | 49 | 50 | class MissingAttributeError(KeywordError): 51 | """Raised for missing required attribute.""" 52 | 53 | def __str__(self): 54 | return repr('Error: required attribute {} of {} is missing.'.format( 55 | self.keywords[0], self.keywords[1]) 56 | ) 57 | 58 | 59 | def get_file_metadata(root): 60 | """Read and parse ReSpecTh XML file metadata (file author, version, etc.) 61 | 62 | Args: 63 | root (`~xml.etree.ElementTree.Element`): Root of ReSpecTh XML file 64 | 65 | Returns: 66 | properties (`dict`): Dictionary with file metadata 67 | """ 68 | properties = {} 69 | 70 | file_author = getattr(root.find('fileAuthor'), 'text', False) 71 | # Test for missing attribute or empty string in the same statement 72 | if not file_author: 73 | raise MissingElementError('fileAuthor') 74 | else: 75 | properties['file-authors'] = [{'name': file_author}] 76 | 77 | # Default version is 0 for the ChemKED file 78 | properties['file-version'] = 0 79 | 80 | # Default ChemKED version 81 | properties['chemked-version'] = __version__ 82 | 83 | return properties 84 | 85 | 86 | def get_reference(root): 87 | """Read reference info from root of ReSpecTh XML file. 88 | 89 | Args: 90 | root (`~xml.etree.ElementTree.Element`): Root of ReSpecTh XML file 91 | 92 | Returns: 93 | properties (`dict`): Dictionary with reference information 94 | """ 95 | reference = {} 96 | elem = root.find('bibliographyLink') 97 | if elem is None: 98 | raise MissingElementError('bibliographyLink') 99 | 100 | # Try to get reference info via DOI, fall back on preferredKey if necessary. 101 | ref_doi = elem.get('doi', None) 102 | ref_key = elem.get('preferredKey', None) 103 | 104 | if ref_doi is not None: 105 | try: 106 | ref = crossref_api.works(ids=ref_doi)['message'] 107 | except (HTTPError, habanero.RequestError, ConnectionError): 108 | if ref_key is None: 109 | raise KeywordError('DOI not found and preferredKey attribute not set') 110 | else: 111 | warn('Missing doi attribute in bibliographyLink or lookup failed. ' 112 | 'Setting "detail" key as a fallback; please update to the appropriate fields.' 113 | ) 114 | reference['detail'] = ref_key 115 | if reference['detail'][-1] != '.': 116 | reference['detail'] += '.' 117 | else: 118 | if ref_key is not None: 119 | warn('Using DOI to obtain reference information, rather than preferredKey.') 120 | reference['doi'] = elem.attrib['doi'] 121 | # Now get elements of the reference data 122 | # Assume that the reference returned by the DOI lookup always has a container-title 123 | reference['journal'] = ref.get('container-title')[0] 124 | ref_year = ref.get('published-print') or ref.get('published-online') 125 | reference['year'] = int(ref_year['date-parts'][0][0]) 126 | reference['volume'] = int(ref.get('volume')) 127 | reference['pages'] = ref.get('page') 128 | reference['authors'] = [] 129 | for author in ref['author']: 130 | auth = {} 131 | auth['name'] = ' '.join([author['given'], author['family']]) 132 | # Add ORCID if available 133 | orcid = author.get('ORCID') 134 | if orcid: 135 | auth['ORCID'] = orcid.lstrip('http://orcid.org/') 136 | reference['authors'].append(auth) 137 | 138 | elif ref_key is not None: 139 | warn('Missing doi attribute in bibliographyLink. ' 140 | 'Setting "detail" key as a fallback; please update to the appropriate fields.' 141 | ) 142 | reference['detail'] = ref_key 143 | if reference['detail'][-1] != '.': 144 | reference['detail'] += '.' 145 | else: 146 | # Need one of DOI or preferredKey 147 | raise MissingAttributeError('preferredKey', 'bibliographyLink') 148 | 149 | return reference 150 | 151 | 152 | def get_experiment_kind(root): 153 | """Read common properties from root of ReSpecTh XML file. 154 | 155 | Args: 156 | root (`~xml.etree.ElementTree.Element`): Root of ReSpecTh XML file 157 | 158 | Returns: 159 | properties (`dict`): Dictionary with experiment type and apparatus information. 160 | """ 161 | properties = {} 162 | if root.find('experimentType').text == 'Ignition delay measurement': 163 | properties['experiment-type'] = 'ignition delay' 164 | else: 165 | raise NotImplementedError(root.find('experimentType').text + ' not (yet) supported') 166 | 167 | properties['apparatus'] = {'kind': '', 'institution': '', 'facility': ''} 168 | kind = getattr(root.find('apparatus/kind'), 'text', False) 169 | # Test for missing attribute or empty string 170 | if not kind: 171 | raise MissingElementError('apparatus/kind') 172 | elif kind in ['shock tube', 'rapid compression machine']: 173 | properties['apparatus']['kind'] = kind 174 | else: 175 | raise NotImplementedError(kind + ' experiment not (yet) supported') 176 | 177 | return properties 178 | 179 | 180 | def get_common_properties(root): 181 | """Read common properties from root of ReSpecTh XML file. 182 | 183 | Args: 184 | root (`~xml.etree.ElementTree.Element`): Root of ReSpecTh XML file 185 | 186 | Returns: 187 | properties (`dict`): Dictionary with common properties 188 | """ 189 | properties = {} 190 | 191 | for elem in root.iterfind('commonProperties/property'): 192 | name = elem.attrib['name'] 193 | 194 | if name == 'initial composition': 195 | properties['composition'] = {'species': [], 'kind': None} 196 | 197 | for child in elem.iter('component'): 198 | spec = {} 199 | spec['species-name'] = child.find('speciesLink').attrib['preferredKey'] 200 | units = child.find('amount').attrib['units'] 201 | 202 | # use InChI for unique species identifier (if present) 203 | try: 204 | spec['InChI'] = child.find('speciesLink').attrib['InChI'] 205 | except KeyError: 206 | # TODO: add InChI validator/search 207 | warn('Missing InChI for species ' + spec['species-name']) 208 | pass 209 | 210 | # If mole or mass fraction, just set value 211 | if units in ['mole fraction', 'mass fraction', 'mole percent']: 212 | spec['amount'] = [float(child.find('amount').text)] 213 | elif units == 'percent': 214 | # assume this means mole percent 215 | warn('Assuming percent in composition means mole percent') 216 | spec['amount'] = [float(child.find('amount').text)] 217 | units = 'mole percent' 218 | elif units == 'ppm': 219 | # assume molar ppm, convert to mole fraction 220 | warn('Assuming molar ppm in composition and converting to mole fraction') 221 | spec['amount'] = [float(child.find('amount').text) * 1.e-6] 222 | units = 'mole fraction' 223 | elif units == 'ppb': 224 | # assume molar ppb, convert to mole fraction 225 | warn('Assuming molar ppb in composition and converting to mole fraction') 226 | spec['amount'] = [float(child.find('amount').text) * 1.e-9] 227 | units = 'mole fraction' 228 | else: 229 | raise KeywordError('Composition units need to be one of: mole fraction, ' 230 | 'mass fraction, mole percent, percent, ppm, or ppb.' 231 | ) 232 | 233 | properties['composition']['species'].append(spec) 234 | 235 | # check consistency of composition type 236 | if properties['composition']['kind'] is None: 237 | properties['composition']['kind'] = units 238 | elif properties['composition']['kind'] != units: 239 | raise KeywordError('composition units ' + units + 240 | ' not consistent with ' + 241 | properties['composition']['kind'] 242 | ) 243 | 244 | elif name in datagroup_properties: 245 | field = name.replace(' ', '-') 246 | units = elem.attrib['units'] 247 | if units == 'Torr': 248 | units = 'torr' 249 | quantity = 1.0 * unit_registry(units) 250 | try: 251 | quantity.to(property_units[field]) 252 | except pint.DimensionalityError: 253 | raise KeywordError('units incompatible for property ' + name) 254 | 255 | properties[field] = [' '.join([elem.find('value').text, units])] 256 | 257 | else: 258 | raise KeywordError('Property ' + name + ' not supported as common property') 259 | 260 | return properties 261 | 262 | 263 | def get_ignition_type(root): 264 | """Gets ignition type and target. 265 | 266 | Args: 267 | root (`~xml.etree.ElementTree.Element`): Root of ReSpecTh XML file 268 | 269 | Returns: 270 | properties (`dict`): Dictionary with ignition type/target information 271 | """ 272 | properties = {} 273 | elem = root.find('ignitionType') 274 | 275 | if elem is None: 276 | raise MissingElementError('ignitionType') 277 | elem = elem.attrib 278 | 279 | if 'target' in elem: 280 | ign_target = elem['target'].rstrip(';').upper() 281 | else: 282 | raise MissingAttributeError('target', 'ignitionType') 283 | 284 | if 'type' in elem: 285 | ign_type = elem['type'] 286 | if ign_type == 'baseline max intercept from d/dt': 287 | ign_type = 'd/dt max extrapolated' 288 | else: 289 | raise MissingAttributeError('type', 'ignitionType') 290 | 291 | # ReSpecTh allows multiple ignition targets 292 | if len(ign_target.split(';')) > 1: 293 | raise NotImplementedError('Multiple ignition targets not supported.') 294 | 295 | # Acceptable ignition targets include pressure, temperature, and species 296 | # concentrations 297 | if ign_target == 'OHEX': 298 | ign_target = 'OH*' 299 | elif ign_target == 'CHEX': 300 | ign_target = 'CH*' 301 | elif ign_target == 'P': 302 | ign_target = 'pressure' 303 | elif ign_target == 'T': 304 | ign_target = 'temperature' 305 | 306 | if ign_target not in ['pressure', 'temperature', 'OH', 'OH*', 'CH*', 'CH']: 307 | raise KeywordError(ign_target + ' not valid ignition target') 308 | 309 | if ign_type not in ['max', 'd/dt max', '1/2 max', 'min', 'd/dt max extrapolated']: 310 | raise KeywordError(ign_type + ' not valid ignition type') 311 | 312 | properties['type'] = ign_type 313 | properties['target'] = ign_target 314 | 315 | return properties 316 | 317 | 318 | def get_datapoints(root): 319 | """Parse datapoints with ignition delay from file. 320 | 321 | Args: 322 | root (`~xml.etree.ElementTree.Element`): Root of ReSpecTh XML file 323 | 324 | Returns: 325 | properties (`dict`): Dictionary with ignition delay data 326 | """ 327 | # Shock tube experiment will have one data group, while RCM may have one 328 | # or two (one for ignition delay, one for volume-history) 329 | dataGroups = root.findall('dataGroup') 330 | if not dataGroups: 331 | raise MissingElementError('dataGroup') 332 | 333 | # all situations will have main experimental data in first dataGroup 334 | dataGroup = dataGroups[0] 335 | property_id = {} 336 | unit_id = {} 337 | species_id = {} 338 | # get properties of dataGroup 339 | for prop in dataGroup.findall('property'): 340 | unit_id[prop.attrib['id']] = prop.attrib['units'] 341 | temp_prop = prop.attrib['name'] 342 | if temp_prop not in datagroup_properties + ['composition']: 343 | raise KeyError(temp_prop + ' not valid dataPoint property') 344 | property_id[prop.attrib['id']] = temp_prop 345 | 346 | if temp_prop == 'composition': 347 | spec = {'species-name': prop.find('speciesLink').attrib['preferredKey']} 348 | # use InChI for unique species identifier (if present) 349 | try: 350 | spec['InChI'] = prop.find('speciesLink').attrib['InChI'] 351 | except KeyError: 352 | # TODO: add InChI validator/search 353 | warn('Missing InChI for species ' + spec['species-name']) 354 | pass 355 | species_id[prop.attrib['id']] = spec 356 | 357 | if not property_id: 358 | raise MissingElementError('property') 359 | 360 | # now get data points 361 | datapoints = [] 362 | for dp in dataGroup.findall('dataPoint'): 363 | datapoint = {} 364 | if 'composition' in property_id.values(): 365 | datapoint['composition'] = {'species': [], 'kind': None} 366 | 367 | for val in dp: 368 | # handle "regular" properties differently than composition 369 | if property_id.get(val.tag) in datagroup_properties: 370 | units = unit_id[val.tag] 371 | if units == 'Torr': 372 | units = 'torr' 373 | datapoint[property_id[val.tag].replace(' ', '-')] = [val.text + ' ' + units] 374 | elif property_id.get(val.tag) == 'composition': 375 | spec = {} 376 | spec['species-name'] = species_id[val.tag]['species-name'] 377 | spec['InChI'] = species_id[val.tag].get('InChI') 378 | 379 | units = unit_id[val.tag] 380 | # If mole or mass fraction, just set value 381 | if units in ['mole fraction', 'mass fraction', 'mole percent']: 382 | spec['amount'] = [float(val.text)] 383 | elif units == 'percent': 384 | # assume this means mole percent 385 | warn('Assuming percent in composition means mole percent') 386 | spec['amount'] = [float(val.text)] 387 | units = 'mole percent' 388 | elif units == 'ppm': 389 | # assume molar ppm, convert to mole fraction 390 | warn('Assuming molar ppm in composition and converting to mole fraction') 391 | spec['amount'] = [float(val.text) * 1.e-6] 392 | units = 'mole fraction' 393 | elif units == 'ppb': 394 | # assume molar ppb, convert to mole fraction 395 | warn('Assuming molar ppb in composition and converting to mole fraction') 396 | spec['amount'] = [float(val.text) * 1.e-9] 397 | units = 'mole fraction' 398 | else: 399 | raise KeywordError('composition units need to be one of: mole fraction, ' 400 | 'mass fraction, mole percent, percent, ppm, or ppb.' 401 | ) 402 | 403 | # check consistency of composition type 404 | if datapoint['composition']['kind'] is None: 405 | datapoint['composition']['kind'] = units 406 | elif datapoint['composition']['kind'] != units: 407 | raise KeywordError( 408 | 'composition units ' + units + 409 | ' not consistent with ' + datapoint['composition']['kind'] 410 | ) 411 | 412 | datapoint['composition']['species'].append(spec) 413 | else: 414 | raise KeywordError('value missing from properties: ' + val.tag) 415 | 416 | datapoints.append(datapoint) 417 | 418 | if len(datapoints) == 0: 419 | raise MissingElementError('dataPoint') 420 | 421 | # ReSpecTh files can have other dataGroups with pressure, volume, or temperature histories 422 | if len(dataGroups) > 1: 423 | datapoints[0]['time-histories'] = [] 424 | for dataGroup in dataGroups[1:]: 425 | time_tag = None 426 | quant_tags = [] 427 | quant_dicts = [] 428 | quant_types = [] 429 | for prop in dataGroup.findall('property'): 430 | if prop.attrib['name'] == 'time': 431 | time_dict = {'units': prop.attrib['units'], 'column': 0} 432 | time_tag = prop.attrib['id'] 433 | elif prop.attrib['name'] in ['volume', 'temperature', 'pressure']: 434 | quant_types.append(prop.attrib['name']) 435 | quant_dicts.append({'units': prop.attrib['units'], 'column': 1}) 436 | quant_tags.append(prop.attrib['id']) 437 | else: 438 | raise KeywordError('Only volume, temperature, pressure, and time are allowed ' 439 | 'in a time-history dataGroup.') 440 | 441 | if time_tag is None or len(quant_tags) == 0: 442 | raise KeywordError('Both time and quantity properties required for time-history.') 443 | 444 | time_histories = [ 445 | {'time': time_dict, 'quantity': q, 'type': t, 'values': []} 446 | for (q, t) in zip(quant_dicts, quant_types) 447 | ] 448 | # collect volume-time history 449 | for dp in dataGroup.findall('dataPoint'): 450 | time = None 451 | quants = {} 452 | for val in dp: 453 | if val.tag == time_tag: 454 | time = float(val.text) 455 | elif val.tag in quant_tags: 456 | quant = float(val.text) 457 | tag_idx = quant_tags.index(val.tag) 458 | quant_type = quant_types[tag_idx] 459 | quants[quant_type] = quant 460 | else: 461 | raise KeywordError('Value tag {} not found in dataGroup tags: ' 462 | '{}'.format(val.tag, quant_tags)) 463 | if time is None or len(quants) == 0: 464 | raise KeywordError('Both time and quantity values required in each ' 465 | 'time-history dataPoint.') 466 | for t in time_histories: 467 | t['values'].append([time, quants[t['type']]]) 468 | 469 | datapoints[0]['time-histories'].extend(time_histories) 470 | 471 | return datapoints 472 | 473 | 474 | def ReSpecTh_to_ChemKED(filename_xml, file_author='', file_author_orcid='', *, validate=False): 475 | """Convert ReSpecTh XML file to ChemKED-compliant dictionary. 476 | 477 | Args: 478 | filename_xml (`str`): Name of ReSpecTh XML file to be converted. 479 | file_author (`str`, optional): Name to override original file author 480 | file_author_orcid (`str`, optional): ORCID of file author 481 | validate (`bool`, optional, keyword-only): Set to `True` to validate the resulting 482 | property dictionary with `ChemKED`. Set to `False` if the file is being loaded and will 483 | be validated at some other point before use. 484 | """ 485 | # get all information from XML file 486 | tree = etree.parse(filename_xml) 487 | root = tree.getroot() 488 | 489 | # get file metadata 490 | properties = get_file_metadata(root) 491 | 492 | # get reference info 493 | properties['reference'] = get_reference(root) 494 | # Save name of original data filename 495 | properties['reference']['detail'] = (properties['reference'].get('detail', '') + 496 | 'Converted from ReSpecTh XML file ' + 497 | os.path.basename(filename_xml) 498 | ) 499 | 500 | # Ensure ignition delay, and get which kind of experiment 501 | properties.update(get_experiment_kind(root)) 502 | 503 | # Get properties shared across the file 504 | properties['common-properties'] = get_common_properties(root) 505 | 506 | # Determine definition of ignition delay 507 | properties['common-properties']['ignition-type'] = get_ignition_type(root) 508 | 509 | # Now parse ignition delay datapoints 510 | properties['datapoints'] = get_datapoints(root) 511 | 512 | # Ensure inclusion of pressure rise or volume history matches apparatus. 513 | has_pres_rise = ('pressure-rise' in properties['common-properties'] or 514 | any([True for dp in properties['datapoints'] if 'pressure-rise' in dp]) 515 | ) 516 | if has_pres_rise and properties['apparatus']['kind'] == 'rapid compression machine': 517 | raise KeywordError('Pressure rise cannot be defined for RCM.') 518 | 519 | has_vol_hist = any( 520 | [t.get('type') == 'volume' for dp in properties['datapoints'] 521 | for t in dp.get('time-histories', [{}])] 522 | ) 523 | if has_vol_hist and properties['apparatus']['kind'] == 'shock tube': 524 | raise KeywordError('Volume history cannot be defined for shock tube.') 525 | 526 | # add any additional file authors 527 | if file_author_orcid and not file_author: 528 | raise KeywordError('If file_author_orcid is specified, file_author must be as well') 529 | 530 | if file_author: 531 | temp_author = {'name': file_author} 532 | if file_author_orcid: 533 | temp_author['ORCID'] = file_author_orcid 534 | properties['file-authors'].append(temp_author) 535 | 536 | # Now go through datapoints and apply common properties 537 | for idx in range(len(properties['datapoints'])): 538 | for prop in properties['common-properties']: 539 | properties['datapoints'][idx][prop] = properties['common-properties'][prop] 540 | 541 | if validate: 542 | chemked.ChemKED(dict_input=properties) 543 | 544 | return properties 545 | 546 | 547 | def respth2ck(argv=None): 548 | """Command-line entry point for converting a ReSpecTh XML file to a ChemKED YAML file. 549 | """ 550 | parser = ArgumentParser( 551 | description='Convert a ReSpecTh XML file to a ChemKED YAML file.' 552 | ) 553 | parser.add_argument('-i', '--input', 554 | type=str, 555 | required=True, 556 | help='Input filename (e.g., "file1.yaml")' 557 | ) 558 | parser.add_argument('-o', '--output', 559 | type=str, 560 | required=False, 561 | default='', 562 | help='Output filename (e.g., "file1.xml")' 563 | ) 564 | parser.add_argument('-fa', '--file-author', 565 | dest='file_author', 566 | type=str, 567 | required=False, 568 | default='', 569 | help='File author name to override original' 570 | ) 571 | parser.add_argument('-fo', '--file-author-orcid', 572 | dest='file_author_orcid', 573 | type=str, 574 | required=False, 575 | default='', 576 | help='File author ORCID' 577 | ) 578 | 579 | args = parser.parse_args(argv) 580 | 581 | filename_ck = args.output 582 | filename_xml = args.input 583 | 584 | properties = ReSpecTh_to_ChemKED(filename_xml, args.file_author, args.file_author_orcid, 585 | validate=True) 586 | 587 | # set output filename and path 588 | if not filename_ck: 589 | filename_ck = os.path.join(os.path.dirname(filename_xml), 590 | os.path.splitext(os.path.basename(filename_xml))[0] + '.yaml' 591 | ) 592 | 593 | with open(filename_ck, 'w') as outfile: 594 | yaml.dump(properties, outfile, default_flow_style=False) 595 | print('Converted to ' + filename_ck) 596 | 597 | 598 | def ck2respth(argv=None): 599 | """Command-line entry point for converting a ChemKED YAML file to a ReSpecTh XML file. 600 | """ 601 | parser = ArgumentParser( 602 | description='Convert a ChemKED YAML file to a ReSpecTh XML file.' 603 | ) 604 | parser.add_argument('-i', '--input', 605 | type=str, 606 | required=True, 607 | help='Input filename (e.g., "file1.xml")' 608 | ) 609 | parser.add_argument('-o', '--output', 610 | type=str, 611 | required=False, 612 | default='', 613 | help='Output filename (e.g., "file1.yaml")' 614 | ) 615 | 616 | args = parser.parse_args(argv) 617 | 618 | c = chemked.ChemKED(yaml_file=args.input) 619 | c.convert_to_ReSpecTh(args.output) 620 | 621 | 622 | def main(argv=None): 623 | """General function for converting between ReSpecTh and ChemKED files based on extension. 624 | """ 625 | parser = ArgumentParser( 626 | description='Convert between ReSpecTh XML file and ChemKED YAML file ' 627 | 'automatically based on file extension.' 628 | ) 629 | parser.add_argument('-i', '--input', 630 | type=str, 631 | required=True, 632 | help='Input filename (e.g., "file1.yaml" or "file2.xml")' 633 | ) 634 | parser.add_argument('-o', '--output', 635 | type=str, 636 | required=False, 637 | default='', 638 | help='Output filename (e.g., "file1.xml" or "file2.yaml")' 639 | ) 640 | parser.add_argument('-fa', '--file-author', 641 | dest='file_author', 642 | type=str, 643 | required=False, 644 | default='', 645 | help='File author name to override original' 646 | ) 647 | parser.add_argument('-fo', '--file-author-orcid', 648 | dest='file_author_orcid', 649 | type=str, 650 | required=False, 651 | default='', 652 | help='File author ORCID' 653 | ) 654 | 655 | args = parser.parse_args(argv) 656 | 657 | if os.path.splitext(args.input)[1] == '.xml' and os.path.splitext(args.output)[1] == '.yaml': 658 | respth2ck(['-i', args.input, '-o', args.output, '-fa', args.file_author, 659 | '-fo', args.file_author_orcid]) 660 | 661 | elif os.path.splitext(args.input)[1] == '.yaml' and os.path.splitext(args.output)[1] == '.xml': 662 | c = chemked.ChemKED(yaml_file=args.input) 663 | c.convert_to_ReSpecTh(args.output) 664 | 665 | elif os.path.splitext(args.input)[1] == '.xml' and os.path.splitext(args.output)[1] == '.xml': 666 | raise KeywordError('Cannot convert .xml to .xml') 667 | 668 | elif os.path.splitext(args.input)[1] == '.yaml' and os.path.splitext(args.output)[1] == '.yaml': 669 | raise KeywordError('Cannot convert .yaml to .yaml') 670 | 671 | else: 672 | raise KeywordError('Input/output args need to be .xml/.yaml') 673 | 674 | 675 | if __name__ == '__main__': 676 | main() 677 | --------------------------------------------------------------------------------