Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

csv file time history #115

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CITATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ A BibTeX entry for LaTeX users is
```TeX
@misc{PyKED,
author = {Kyle E Niemeyer and Bryan W Weber},
year = 2017,
year = 2018,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is now 2019

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
year = 2018,
year = 2020,

title = {PyKED v0.4.1},
doi = {10.5281/zenodo.597935},
url = {https://github.com/pr-omethe-us/PyKED},
Expand Down
24 changes: 24 additions & 0 deletions pyked/chemked.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
import xml.etree.ElementTree as etree
import xml.dom.minidom as minidom
from itertools import chain
from pathlib import Path
from distutils.version import LooseVersion
import sys

import numpy as np

Expand Down Expand Up @@ -78,6 +81,15 @@
Composition.amount.__doc__ = '(`~pint.Quantity`) The amount of this species'


if LooseVersion(sys.version) < '3.6':
# Allow old version of python to open Path objects.
oldopen = open

def open(file, mode='r', buffering=-1, encoding=None, errors=None,
newline=None, closefd=True, opener=None):
return oldopen(str(file), mode, buffering, encoding, errors, newline, closefd, opener)


class ChemKED(object):
"""Main ChemKED class.

Expand Down Expand Up @@ -109,6 +121,7 @@ class ChemKED(object):
"""
def __init__(self, yaml_file=None, dict_input=None, *, skip_validation=False):
if yaml_file is not None:
yaml_file = Path(yaml_file)
with open(yaml_file, 'r') as f:
self._properties = yaml.safe_load(f)
elif dict_input is not None:
Expand All @@ -121,6 +134,17 @@ def __init__(self, yaml_file=None, dict_input=None, *, skip_validation=False):

self.datapoints = []
for point in self._properties['datapoints']:
if 'time-histories' in point:
for th in point['time-histories']:
try:
filename = Path(th['values']['filename'])
except TypeError:
pass
else:
if yaml_file is not None:
th['values']['filename'] = (yaml_file.parent / filename).resolve()
else:
th['values']['filename'] = filename.resolve()
self.datapoints.append(DataPoint(point))

self.reference = Reference(
Expand Down
21 changes: 21 additions & 0 deletions pyked/tests/test_chemked.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,27 @@ def test_missing_input(self, capfd):
with pytest.raises(ValueError):
ChemKED(dict_input=properties)

def test_csv_time_history(self):
file_path = os.path.join('testfile_rcm3.yaml')
filename = pkg_resources.resource_filename(__name__, file_path)
csv_filename = pkg_resources.resource_filename(__name__, 'rcm_history.csv')
from_file = ChemKED(filename)

with open(filename, 'r') as f:
properties = yaml.safe_load(f)
properties['datapoints'][0]['time-histories'][0]['values']['filename'] = csv_filename
from_dict = ChemKED(dict_input=properties)

for exp in [from_file, from_dict]:
exp_fname = exp._properties['datapoints'][0]['time-histories'][0]['values']['filename']
assert(str(exp_fname) == csv_filename)

# Test case where 'values' is a dict, but doesn't contain 'filename'
del properties['datapoints'][0]['time-histories'][0]['values']['filename']
with pytest.raises(NotImplementedError):
ChemKED(dict_input=properties)



class TestDataFrameOutput(object):
"""
Expand Down
2 changes: 1 addition & 1 deletion pyked/tests/test_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ def properties(self, request):

@pytest.mark.parametrize("properties", [
'testfile_st.yaml', 'testfile_st2.yaml', 'testfile_rcm.yaml', 'testfile_required.yaml',
'testfile_uncertainty.yaml', 'testfile_rcm2.yaml',
'testfile_uncertainty.yaml', 'testfile_rcm2.yaml', 'testfile_rcm3.yaml'
], indirect=['properties'])
def test_valid_yaml(self, properties):
"""Ensure ChemKED YAML is validated
Expand Down
66 changes: 66 additions & 0 deletions pyked/tests/testfile_rcm3.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
file-authors:
- name: Kyle E Niemeyer
ORCID: 0000-0003-4425-7097
file-version: 0
chemked-version: 0.0.1
reference:
doi: 10.1002/kin.20180
authors:
- name: Gaurav Mittal
- name: Chih-Jen Sung
ORCID: 0000-0003-2046-8076
- name: Richard A Yetter
journal: International Journal of Chemical Kinetics
year: 2006
volume: 38
pages: 516-529
detail: Fig. 6, open circle
experiment-type: ignition delay
apparatus:
kind: rapid compression machine
institution: Case Western Reserve University
facility: CWRU RCM
datapoints:
- temperature:
- 297.4 kelvin
ignition-delay:
- 1.0 ms
pressure:
- 958.0 torr
composition:
kind: mole fraction
species:
- species-name: H2
InChI: 1S/H2/h1H
amount:
- 0.12500
- species-name: O2
InChI: 1S/O2/c1-2
amount:
- 0.06250
- species-name: N2
InChI: 1S/N2/c1-2
amount:
- 0.18125
- species-name: Ar
InChI: 1S/Ar
amount:
- 0.63125
ignition-type:
target: pressure
type: d/dt max
rcm-data:
compression-time:
- 38.0 ms
time-histories:
- type: volume
time:
units: s
column: 0
quantity:
units: cm3
column: 1
values:
filename: rcm_history.csv
...
24 changes: 15 additions & 9 deletions pyked/validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,15 +251,21 @@ def _validate_isvalid_history(self, isvalid_history, field, value):
self._error(field, 'incompatible units; should be consistent '
'with ' + property_units['time'])

# Check that the values have the right number of columns
n_cols = len(value['values'][0])
max_cols = max(value['time']['column'],
value['quantity']['column'],
value.get('uncertainty', {}).get('column', 0)) + 1
if n_cols > max_cols:
self._error(field, 'too many columns in the values')
elif n_cols < max_cols:
self._error(field, 'not enough columns in the values')
try:
if 'filename' not in value['values'].keys():
self._error(field, 'must include filename or list of values')
# If reading from a file, the file will not be validated.
# A file can have an arbitrary number of columns, and the columns
# to be used are specified.
except AttributeError:
n_cols = len(value['values'][0])
max_cols = max(value['time']['column'],
value['quantity']['column'],
value.get('uncertainty', {}).get('column', 0)) + 1
if n_cols > max_cols:
self._error(field, 'too many columns in the values')
elif n_cols < max_cols:
self._error(field, 'not enough columns in the values')

def _validate_isvalid_quantity(self, isvalid_quantity, field, value):
"""Checks for valid given value and appropriate units.
Expand Down