Skip to content

Add ovf functions and tests#142

Open
DiegoDeGusem wants to merge 7 commits intodevfrom
ovf
Open

Add ovf functions and tests#142
DiegoDeGusem wants to merge 7 commits intodevfrom
ovf

Conversation

@DiegoDeGusem
Copy link
Copy Markdown
Contributor

This PR adds save_ovf and load_ovf methods to FieldQuantities. This allows users to save and load FieldQuantities via OVF files.
The save_ovf method uses pyovf and provides it with all available metadata. However, some metadata appears to be ignored (e.g. simulation time) and some fields are hard-coded in pyovf (e.g. units).
pyovf expects arrays with shape (nz, ny, nx, ncomp), while mumax⁺ uses (ncomp, nz, ny, nx). The save function reorders the axis, while the load function reverses this. To notify users of this reordering, the save function has a warning in the docstring.

@DiegoDeGusem DiegoDeGusem self-assigned this Apr 10, 2026
@DiegoDeGusem DiegoDeGusem added the enhancement New feature or request label Apr 10, 2026
Comment thread mumaxplus/fieldquantity.py Outdated
Comment thread mumaxplus/fieldquantity.py Outdated
Comment thread mumaxplus/fieldquantity.py Outdated
Comment thread src/bindings/wrap_system.cpp Outdated
Comment thread test/test_ovf.py Outdated
Comment thread test/test_ovf.py Outdated
Comment thread test/test_ovf.py Outdated
Comment thread test/test_ovf.py Outdated
Comment thread test/test_ovf.py Outdated
Comment thread test/test_ovf.py
Comment thread mumaxplus/fieldquantity.py Outdated
Comment thread mumaxplus/fieldquantity.py Outdated
Comment thread mumaxplus/fieldquantity.py
Comment thread test/test_ovf.py
@ilateur ilateur added this to the v1.2.0 milestone Apr 15, 2026
Comment thread mumaxplus/fieldquantity.py Outdated
@DiegoDeGusem DiegoDeGusem requested a review from ilateur April 15, 2026 12:39
Comment thread mumaxplus/fieldquantity.py Outdated
name_replace = self.name.replace(":", "_")
files = Path(".").glob(f"{name_replace}*.ovf")
try:
name = str(max(files, key=lambda f: int(f.stem[-6:])))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This throws an error when at least 1 file whose name starts with name_replace but doesn't have 6 digits at the end exists in the current directory. This can be alleviated by, e.g.,

name = str(max(filter(lambda f: f.stem[-6:].isnumeric(), files), key=lambda f: int(f.stem[-6:])))

Copy link
Copy Markdown
Collaborator

@ilateur ilateur left a comment

Choose a reason for hiding this comment

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

It's a bit funny and sad that we now have nice functionality to save and load ovf files... but not npy files. Would it be nice to also have a save_npy() function? Or make it one save() function and decide the type based on the given string (or default if not given)? Or is this useless (just call np.save(field_quantity.eval())) or outside the scope of this pull request?

name = self.name + ".ovf"
count = self._ovf_counts.get(self.name, 0)
name = self.name.replace(":", "_") + f"{count:06d}.ovf"
self._ovf_counts[self.name] = count + 1
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

that's pretty clever

Maybe also add an underscore between name and count (+ f"_{count:06d}.ovf")? This is not the mumax3 way though, so what do you think?

----------
name : str (default="")
The name of the OVF file. If the name is empty (the default), the name of the FieldQuantity will be used.
The name of the OVF file. If the name is empty (the default), the name of the FieldQuantity will be used appended with an integer of 6 digits.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Maybe if the name is not empty, it should be checked whether it ends with ".ovf" and append it if needed?

if name == "":
name = self.name + ".ovf"
name_replace = self.name.replace(":", "_")
files = Path(".").glob(f"{name_replace}*.ovf")
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'm worried this might be a bit slow when you have saved a lot of files during your simulation. Also having a default behavior for load at all is a bit strange to me 🤔 I would take the simple option and just make name a necessary variable.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If a situation arises where glob somehow becomes a performance concern, the user can always specify name explicitly, thereby avoiding this entire block of code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants