Skip to content
Merged
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ The following instructions are currently supported by picometer:
- `load` model from a cif file, given `filename` or mapping syntax:
`{path: filename.cif, block: cif_block}`.
- `write` table with all evaluations to a csv file.
- `read` table with previous evaluation (to append further).
- **Selection instructions**
- `select` atoms, groups, or shapes to be used; use raw element names
or provide symmetry relation / recenter using mapping syntax, for example:
Expand Down
26 changes: 26 additions & 0 deletions picometer/instructions.py
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,32 @@ def handle_one(self, instruction: Instruction, ms_key: str, ms: ModelState) -> N
logger.info(f'Evaluated dihedral {label}: {dihedral} for model state {ms_key}')


class ReadInstructionHandler(BaseInstructionHandler):
name = 'read'
kwargs = dict(path=Path)

def handle(self, instruction: Instruction) -> None:
path = Path(instruction.kwargs['path'])
paths = [path] if path.is_file() else sorted(glob(str(path)))
for path in paths:
self._read_table(str(path))

def _read_table(self, path: str) -> None:
old = self.processor.evaluation_table
new = pd.read_csv(path, index_col=0)

if old.empty:
self.processor.evaluation_table = new
else:
index = old.index.union(new.index)
columns = old.columns.union(new.columns)
old = old.reindex(index=index, columns=columns)
old.update(new)
self.processor.evaluation_table = old

logger.info(f'Loaded evaluation table from {path}')


class WriteInstructionHandler(BaseInstructionHandler):
name = 'write'
kwargs = dict(path=Path)
Expand Down
40 changes: 40 additions & 0 deletions tests/test_instructions.py
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,46 @@ def test_write(self):
assert_frame_equal(correct, results, check_exact=False,
rtol=1e-13, atol=1e-12)

def test_read(self):
with importlib.resources.path('tests', 'test_ferrocene.yaml') as yaml_path:
tests_path = yaml_path.parent
routine_tmp = 'instructions:\n - read: {}/ferrocene_correct.csv\n'
routine_text = routine_tmp.format(tests_path)
p = process(Routine.from_string(routine_text))
correct_path = tests_path / 'ferrocene_correct.csv'
correct = pd.read_csv(correct_path, index_col=0)
results = p.evaluation_table
results.index = correct.index # index is env-dependent so ignore it
assert_frame_equal(correct, results, check_exact=False,
rtol=1e-13, atol=1e-12)

def test_read_twice(self):
with importlib.resources.path('tests', 'test_ferrocene.yaml') as yaml_path:
tests_path = yaml_path.parent
routine_tmp = 'instructions:\n - read: {}/ferrocene_correct.csv\n'
routine_tmp += ' - read: {}/ferrocene_correct.csv\n'
routine_text = routine_tmp.format(tests_path, tests_path)
p = process(Routine.from_string(routine_text))
correct_path = tests_path / 'ferrocene_correct.csv'
correct = pd.read_csv(correct_path, index_col=0)
results = p.evaluation_table
results.index = correct.index # index is env-dependent so ignore it
assert_frame_equal(correct, results, check_exact=False,
rtol=1e-13, atol=1e-12)

def test_read_many(self):
with importlib.resources.path('tests', 'test_ferrocene.yaml') as yaml_path:
tests_path = yaml_path.parent
routine_tmp = 'instructions:\n - read: {}/ferrocene_corr*.csv\n'
routine_text = routine_tmp.format(tests_path)
p = process(Routine.from_string(routine_text))
correct_path = tests_path / 'ferrocene_correct.csv'
correct = pd.read_csv(correct_path, index_col=0)
results = p.evaluation_table
results.index = correct.index # index is env-dependent so ignore it
assert_frame_equal(correct, results, check_exact=False,
rtol=1e-13, atol=1e-12)

def test_document_history(self):
routine_text = get_yaml('test_ferrocene.yaml')
original_routine = Routine.from_string(routine_text)
Expand Down
Loading