Skip to content
Open
Show file tree
Hide file tree
Changes from 9 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
Copy Markdown
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
Copy Markdown
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
14 changes: 10 additions & 4 deletions pyked/chemked.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Main ChemKED module
"""
# Standard libraries
from os.path import exists
from os.path import exists, isabs, dirname, join
from collections import namedtuple
from warnings import warn
from copy import deepcopy
Expand Down Expand Up @@ -111,8 +111,10 @@ def __init__(self, yaml_file=None, dict_input=None, *, skip_validation=False):
if yaml_file is not None:
with open(yaml_file, 'r') as f:
self._properties = yaml.safe_load(f)
directory = dirname(yaml_file)
elif dict_input is not None:
self._properties = dict_input
directory = None
else:
raise NameError("ChemKED needs either a YAML filename or dictionary as input.")

Expand All @@ -121,7 +123,7 @@ def __init__(self, yaml_file=None, dict_input=None, *, skip_validation=False):

self.datapoints = []
for point in self._properties['datapoints']:
self.datapoints.append(DataPoint(point))
self.datapoints.append(DataPoint(point, directory))

self.reference = Reference(
volume=self._properties['reference'].get('volume'),
Expand Down Expand Up @@ -589,6 +591,7 @@ class DataPoint(object):

Arguments:
properties (`dict`): Dictionary adhering to the ChemKED format for ``datapoints``
directory (`str`, optional): Directory to look for auxiliary files

Attributes:
composition (`list`): List of dictionaries representing the species and their quantities
Expand Down Expand Up @@ -631,7 +634,7 @@ class DataPoint(object):
'compression-ratio'
]

def __init__(self, properties):
def __init__(self, properties, directory=''):
for prop in self.value_unit_props:
if prop in properties:
quant = self.process_quantity(properties[prop])
Expand Down Expand Up @@ -685,7 +688,10 @@ def __init__(self, properties):
values = np.array(hist['values'])
else:
# Load the values from a file
values = np.genfromtxt(hist['values']['filename'], delimiter=',')
filename = hist['values']['filename']
if not isabs(filename):
filename = join(directory, filename)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think this will fail if the input is a dict and therefore directory is None

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Changing the default directory to '' would fix that. But, if the input is a dict, then the filename must be specified as an absolute path, right? Since there's no yaml file, a path relative to a yaml file wouldn't make sense. So, line 693 won't be run anyway.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't think that change will fix the problem on this line, because the directory argument gets set to None if yaml_file is None, so this line will join None and filename, which won't work. Actually, I think that if people provide a dictionary input, the CSV file has to be specified relative to the PWD of the Python process, or as an absolute file name, but we don't need to check for that case.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Good catch. I just pushed another commit so that directory will never be set to None. Now, if yaml_file is None, then directory will be ''

values = np.genfromtxt(filename, delimiter=',')

time_history = TimeHistory(
time=Q_(values[:, time_col], time_units),
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