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

First working implementation of plugin #6

Merged
merged 33 commits into from
Aug 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
5b86395
First simple definition of battery sample & state data nodes
lorisercole Jan 28, 2022
ccd1745
Implement script to emulate Aurora lab server API
lorisercole Jan 28, 2022
f00156b
First implementation of experiment specs, calculation, parser
lorisercole Jan 31, 2022
3cf5748
Fix entry points
lorisercole Jan 31, 2022
88f8ace
Use pydantic data & cycling schemas
lorisercole May 18, 2022
32b85c5
Deactivate annoying pylint pre-commit
lorisercole Jun 26, 2022
389584b
Move calculations to folder
lorisercole Jun 26, 2022
4addd6b
Add get_yaml method to data nodes
lorisercole Jun 26, 2022
c117dc4
Implement tomato scheduler
lorisercole Jun 23, 2022
655dbe4
Remove -t flag from ketchup commands
lorisercole Jun 26, 2022
1eac0ba
Fix data nodes
lorisercole Jun 26, 2022
6472b16
Fix job resources __init__ and submit method
lorisercole Jun 26, 2022
c371725
Merge branch 'tomato_scheduler' into cycling
lorisercole Jun 26, 2022
ca1bb4b
Add `BatteryCycler` calculation
lorisercole Jun 26, 2022
b61a46e
Make payload.yml compatible with tomato
lorisercole Jun 28, 2022
94215e7
Fix scheduler get and parse job list
lorisercole Jun 28, 2022
b65ee20
Scheduler: add job title, improve joblist parser
lorisercole Jul 4, 2022
cf1c8b6
`BatteryCyclerExperiment` CalcJob now working
lorisercole Jul 6, 2022
8bcb7c6
Implement `TomatoParser`
lorisercole Jul 6, 2022
8cf942a
Fix scheduler bugs, hard-code ketchup path on lab pc
lorisercole Jul 8, 2022
38fd3d5
Set submit script filename to `_aiidasubmit.ps1`
lorisercole Jul 8, 2022
ac1e91a
Fix tomato parser
lorisercole Jul 8, 2022
750944a
Fix last bugs in scheduler
lorisercole Jul 12, 2022
ca6abad
Add TomatoSettings data node, update schema to 0.2
lorisercole Aug 3, 2022
380c825
Merge branch 'cycling' into windows
lorisercole Aug 4, 2022
22a1f4f
Direct import of tomato schema in BatteryCyclerExperiment
lorisercole Aug 4, 2022
bcf23bc
Set submit script filename according to computer transport type
lorisercole Aug 4, 2022
4787db6
Scheduler: use `JobTemplate.shell_type` as shell command
lorisercole Aug 4, 2022
af01f37
Remove hard-coded `ketchup` command in scheduler
lorisercole Aug 5, 2022
b8fa019
scheduler: fix bug with `_shell_cmd` and logger
lorisercole Aug 5, 2022
afbc634
Fix bug: submit script filename for PowerShell
lorisercole Aug 9, 2022
cce4db7
Cleanup
lorisercole Aug 9, 2022
48e8745
Update package
lorisercole Aug 9, 2022
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
35 changes: 0 additions & 35 deletions .github/check_version.py

This file was deleted.

2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
timeout-minutes: 30
strategy:
matrix:
python-version: [3.8]
python-version: ["3.8"]
backend: ['django']

services:
Expand Down
23 changes: 8 additions & 15 deletions .github/workflows/publish-on-pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,14 @@ jobs:
with:
python-version: 3.8

- name: Upgrade setuptools and install package
- name: Install flit
run: |
python -m pip install --upgrade pip setuptools
python -m pip install -e .
python -m pip install --upgrade pip
python -m pip install flit~=3.4

- name: Assert package version
- name: Build and publish
run: |
flit publish
env:
TAG_VERSION: ${{ github.ref }}
run: python ./.github/check_version.py

- name: Build source distribution
run: python ./setup.py sdist

- name: Publish package to PyPI
uses: pypa/gh-action-pypi-publish@master
with:
user: __token__
password: ${{ secrets.pypi_token }}
FLIT_USERNAME: __token__
FLIT_PASSWORD: ${{ secrets.pypi_token }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@
build/
dist/
pip-wheel-metadata/
fake_aurora_server/exp.out
30 changes: 15 additions & 15 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,28 @@
# pre-commit install
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.4.0
rev: v4.1.0
hooks:
- id: double-quote-string-fixer
- id: end-of-file-fixer
- id: fix-encoding-pragma
- id: mixed-line-ending
- id: trailing-whitespace
- id: check-json

# yapf = yet another python formatter
- repo: https://github.com/pre-commit/mirrors-yapf
rev: v0.30.0
- repo: https://github.com/asottile/pyupgrade
rev: v2.31.0
hooks:
- id: yapf
name: yapf
args: ["-i"]
- id: pyupgrade
args: ["--py37-plus"]

- repo: https://github.com/PyCQA/isort
rev: 5.10.1
hooks:
- id: isort

- repo: https://github.com/psf/black
rev: 22.3.0
hooks:
- id: black

- repo: local
hooks:
Expand All @@ -31,9 +37,3 @@ repos:
docs/.*|
)$
entry: pylint

- id: version-number
name: Check version numbers
entry: python ./.github/check_version.py
language: system
files: '^(setup.json)|(aiida_aurora/__init__.py)'
3 changes: 1 addition & 2 deletions aiida_aurora/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
"""
aiida_aurora

AiiDA plugin for the Aurora platform.
"""

__version__ = '0.1.0a0'
__version__ = "0.2.0"
70 changes: 0 additions & 70 deletions aiida_aurora/calculations.py

This file was deleted.

2 changes: 2 additions & 0 deletions aiida_aurora/calculations/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from .cycler import BatteryCyclerExperiment
from .fake import BatteryFakeExperiment
117 changes: 117 additions & 0 deletions aiida_aurora/calculations/cycler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
"""
Calculations provided by aiida_aurora.

Register calculations via the "aiida.calculations" entry point in setup.json.
"""
from importlib import import_module

import yaml

from aiida.common import datastructures
from aiida.engine import CalcJob
from aiida.orm import ArrayData, SinglefileData

from aiida_aurora.data.battery import BatterySample, BatteryState
from aiida_aurora.data.control import TomatoSettings
from aiida_aurora.data.experiment import CyclingSpecs


class BatteryCyclerExperiment(CalcJob):
"""
AiiDA calculation plugin for the tomato instrument automation package.
https://github.com/dgbowl/tomato
"""
_INPUT_PAYLOAD_YAML_FILE = 'payload.yaml'
_INPUT_PAYLOAD_VERSION = '0.2'
_OUTPUT_FILE_PREFIX = 'results'

@classmethod
def define(cls, spec):
"""Define inputs and outputs of the calculation."""
# yapf: disable
super().define(spec)

# set default values for AiiDA options
spec.inputs['metadata']['options']['resources'].default = { # REQUIRED?
'num_machines': 1,
}
spec.inputs['metadata']['options']['parser_name'].default = 'aurora'
spec.inputs['metadata']['options']['withmpi'].default = False
spec.inputs['metadata']['options']['input_filename'].default = cls._INPUT_PAYLOAD_YAML_FILE
# spec.inputs['metadata']['options']['scheduler_stderr'].default = ''
# spec.inputs['metadata']['options']['scheduler_stdout'].default = ''

# new ports
spec.input('metadata.options.output_filename', valid_type=str, default=cls._OUTPUT_FILE_PREFIX)
spec.input('battery_sample', valid_type=BatterySample, help='Battery sample used.')
spec.input('technique', valid_type=CyclingSpecs, help='Experiment specifications.')
spec.input('control_settings', valid_type=TomatoSettings, help='Experiment control settings.')
spec.output('results', valid_type=ArrayData, help='Results of the experiment.')
spec.output('raw_data', valid_type=SinglefileData, help='Raw data retrieved.')
# spec.output('battery_state', valid_type=BatteryState, help='State of the battery after the experiment.')

spec.exit_code(300, 'ERROR_MISSING_OUTPUT_FILES', message='Experiment did not produce any kind of output file.')
spec.exit_code(301, 'ERROR_MISSING_JSON_FILE', message='Experiment did not produce an output json file.')
spec.exit_code(302, 'ERROR_MISSING_ZIP_FILE', message='Experiment did not produce a zip file with raw data.')
spec.exit_code(311, 'ERROR_COMPLETED_ERROR', message='The tomato job was marked as completed with an error.')
spec.exit_code(312, 'ERROR_COMPLETED_CANCELLED', message='The tomato job was marked as cancelled.')
spec.exit_code(400, 'ERROR_PARSING_JSON_FILE', message='Parsing of json file failed.')

def prepare_for_submission(self, folder):
"""
Create input files.

:param folder: an `aiida.common.folders.Folder` where the plugin should temporarily place all files
needed by the calculation.
:return: `aiida.common.datastructures.CalcInfo` instance
"""

# if connecting to a Windows PowerShell computer, change the extension of the submit script to '.ps1'
if self.inputs.code.computer.transport_type == 'sshtowin':
submit_script_filename = self.node.get_option('submit_script_filename')
if not submit_script_filename.endswith('.ps1'):
if submit_script_filename.endswith('.sh'):
submit_script_filename = submit_script_filename[:-3] + '.ps1'
else:
submit_script_filename(submit_script_filename + '.ps1')
self.node.backend_entity.set_attribute('submit_script_filename', submit_script_filename)

# prepare the payload
# TODO: use dgbowl_schemas module
## from dgbowl_schemas.tomato.payload_0_1.tomato import Tomato
## - should 'version: "0.1"' be written in the submit script?
## - name of the file containing the sample and method
tomato_schema_module = import_module(f"aurora.schemas.tomato_{self._INPUT_PAYLOAD_VERSION.replace('.', 'p')}")
TomatoSchema = tomato_schema_module.tomato.Tomato

tomato_dict = self.inputs.control_settings.get_dict()
if tomato_dict['output']['prefix'] is None:
tomato_dict['output']['prefix'] = self._OUTPUT_FILE_PREFIX
else:
self._OUTPUT_FILE_PREFIX = tomato_dict['output']['prefix']
payload = tomato_schema_module.TomatoPayload(
version = self._INPUT_PAYLOAD_VERSION,
sample = tomato_schema_module.sample.convert_batterysample_to_sample(self.inputs.battery_sample.get_dict()),
method = tomato_schema_module.method.convert_electrochemsequence_to_method_list(
self.inputs.technique.get_dict()),
tomato = TomatoSchema(**tomato_dict),
)
with folder.open(self.options.input_filename, 'w', encoding='utf8') as handle:
handle.write(yaml.dump(payload.dict()))

codeinfo = datastructures.CodeInfo()

# the calculation code should be 'ketchup', so we add the following `cmdline_params`
# in order to submit the payload to tomato
codeinfo.cmdline_params = ['submit', '--jobname', '$JOB_TITLE', self._INPUT_PAYLOAD_YAML_FILE]
codeinfo.code_uuid = self.inputs.code.uuid
codeinfo.withmpi = self.inputs.metadata.options.withmpi

# Prepare a `CalcInfo` to be returned to the engine
calcinfo = datastructures.CalcInfo()
calcinfo.codes_info = [codeinfo]
calcinfo.local_copy_list = []
calcinfo.retrieve_list = [f'{self._OUTPUT_FILE_PREFIX}.json']
calcinfo.retrieve_temporary_list = [f'{self._OUTPUT_FILE_PREFIX}.zip']

return calcinfo
Loading