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

update_info_json method is added to update and add the additional inf… #92

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
50 changes: 44 additions & 6 deletions micromagneticmodel/driver.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import abc
import datetime
import importlib.metadata
import json
import math
import pathlib
import subprocess as sp
import sys
Expand Down Expand Up @@ -124,23 +126,35 @@
If system directory already exists and append=False.

"""
drive_kwargs = kwargs.copy()
# This method is implemented in the derived driver class. It raises
# exception if any of the arguments are not valid.
self.drive_kwargs_setup(kwargs)
self._check_system(system)
workingdir = self._setup_working_directory(
system=system, dirname=dirname, mode="drive", append=append
)
start_time = datetime.datetime.now()

with uu.changedir(workingdir):
self._write_input_files(
system=system,
ovf_format=ovf_format,
**kwargs,
)
self._call(system=system, runner=runner, verbose=verbose, **kwargs)
self._read_data(system)

self._write_info_json(system, start_time, **drive_kwargs)
try:
self._call(system=system, runner=runner, verbose=verbose, **kwargs)
except Exception:
success = False
raise

Check warning on line 151 in micromagneticmodel/driver.py

View check run for this annotation

Codecov / codecov/patch

micromagneticmodel/driver.py#L149-L151

Added lines #L149 - L151 were not covered by tests
else:
success = True
finally:
end_time = datetime.datetime.now()
self._update_info_json(start_time, end_time, success)
self._read_data(system)
system.drive_number += 1

def schedule(
Expand Down Expand Up @@ -234,6 +248,7 @@
If system directory already exists and append=False.

"""
schedule_kwargs = kwargs.copy()
# This method is implemented in the derived driver class. It raises
# exception if any of the arguments are not valid.
self.schedule_kwargs_setup(kwargs)
Expand All @@ -247,6 +262,8 @@
if pathlib.Path(header).exists():
header = pathlib.Path(header).absolute()

start_time = datetime.datetime.now()

with uu.changedir(workingdir):
self._write_input_files(
system=system,
Expand All @@ -256,6 +273,7 @@
self._write_schedule_script(
system=system, header=header, script_name=script_name, runner=runner
)
self._write_info_json(system, start_time, **schedule_kwargs)

stdout = stderr = sp.PIPE
if sys.platform == "win32":
Expand Down Expand Up @@ -292,15 +310,19 @@
f.write("\n")
f.write("\n".join(run_commands))

def _write_info_json(self, system, **kwargs):
def _write_info_json(self, system, start_time, **kwargs):
info = {}
info["drive_number"] = system.drive_number
info["date"] = datetime.datetime.now().strftime("%Y-%m-%d")
info["time"] = datetime.datetime.now().strftime("%H:%M:%S")
info["driver"] = self.__class__.__name__
info["date"] = start_time.strftime("%Y-%m-%d")
info["time"] = start_time.strftime("%H:%M:%S")
info["start_time"] = start_time.isoformat(timespec="seconds")
# "adapter" is the ubermag package (e.g. oommfc) that communicates with the
# calculator (e.g. OOMMF)
info["adapter"] = self.__module__.split(".")[0]
info["adapter_version"] = importlib.metadata.version(
self.__module__.split(".")[0]
)
info["driver"] = self.__class__.__name__
for k, v in kwargs.items():
info[k] = v
with open("info.json", "w", encoding="utf-8") as jsonfile:
Expand All @@ -325,3 +347,19 @@
workingdir = system_dir / f"{mode}-{next_number}"
workingdir.mkdir(parents=True)
return workingdir

@staticmethod
def _conversion_to_hms(time_difference):
total_seconds = math.ceil(time_difference.total_seconds())
hours, remainder = divmod(total_seconds, 3600)
minutes, seconds = divmod(remainder, 60)
return f"{hours:02}:{minutes:02}:{seconds:02}"
kzqureshi marked this conversation as resolved.
Show resolved Hide resolved

def _update_info_json(self, start_time, end_time, success):
lang-m marked this conversation as resolved.
Show resolved Hide resolved
with open("info.json", encoding="utf-8") as jsonfile:
info = json.load(jsonfile)
info["end_time"] = end_time.isoformat(timespec="seconds")
info["elapsed_time"] = self._conversion_to_hms(end_time - start_time)
info["success"] = success
with open("info.json", "w", encoding="utf-8") as jsonfile:
json.dump(info, jsonfile)
18 changes: 13 additions & 5 deletions micromagneticmodel/tests/test_driver.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import datetime
import json

import discretisedfield as df
Expand Down Expand Up @@ -37,7 +36,6 @@ def _check_system(self, system):
def _write_input_files(self, system, **kwargs):
with open(f"{system.name}.input", "w", encoding="utf-8") as f:
f.write(str(-1)) # factor -1 used to invert magnetisation direction in call
self._write_info_json(system, **kwargs)

def _call(self, system, runner, **kwargs):
with open(f"{system.name}.input", encoding="utf-8") as f:
Expand Down Expand Up @@ -79,10 +77,20 @@ def test_external_driver(tmp_path):
assert info["driver"] == "MyExternalDriver"
assert info["drive_number"] == 0

info_time = datetime.datetime.fromisoformat(f"{info['date']}T{info['time']}")
now = datetime.datetime.now()
assert "start_time" in info
assert "end_time" in info
assert "elapsed_time" in info
assert "success" in info
assert info["success"] is True

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
assert info["success"] is True
assert info["success"]

def _parse_time_str_to_seconds(time_str):
h, m, s = map(int, time_str.split(":"))
return h * 3600 + m * 60 + s

elapsed_time = info["elapsed_time"]
elapsed_seconds = _parse_time_str_to_seconds(elapsed_time)
# assumption: this test runs in under one minute
assert (now - info_time).total_seconds() < 60
assert elapsed_seconds < 60

with pytest.raises(FileExistsError):
driver.drive(system, dirname=str(tmp_path), append=False)
Expand Down
Loading