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

Extend data info #75

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
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
166 changes: 131 additions & 35 deletions micromagneticdata/data.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
import glob
import os
from pathlib import Path

import ipywidgets
import pandas as pd
import ubermagutil.typesystem as ts

import micromagneticdata as md


@ts.typesystem(name=ts.Typed(expected_type=str), dirname=ts.Typed(expected_type=str))
class Data:
"""Computational magnetism data class.

It requires the name of the system to be passed. If `dirname` was used when
the system was driven, it can be passed here via ``dirname``.
It requires the name of the system to be passed and optionally accepts
a directory `dirname` or a full path `path` to locate the system's data.

Parameters
----------
Expand All @@ -25,33 +24,67 @@ class Data:

Directory in which system's data is saved. Defults to ``'./'``.

path : pathlib.Path

Full path to where the data is stored. Defaults to `None`.

Raises
------
IOError
TypeError

If the system's directory cannot be found.
If the system's name or path cannot be found.

Examples
--------
1. Creating data object.
1. Creating data object using `dirname`
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
1. Creating data object using `dirname`
1. Creating data object using `path`


>>> import micromagneticdata as mdata
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
>>> import micromagneticdata as mdata
>>> import micromagneticdata as mdata
>>> from pathlib import Path

...
>>> data = mdata.Data(
path="/home/zulfigak/ubermag_devtools/repos/micromagneticdata/micromagneticdata/tests/test_sample/rectangle"
Comment on lines +43 to +44
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
>>> data = mdata.Data(
path="/home/zulfigak/ubermag_devtools/repos/micromagneticdata/micromagneticdata/tests/test_sample/rectangle"
>>> path = Path(__file__).parent / 'tests' / 'test_sample'
>>> data = mdata.Data(path=path)

)

2. Creating data object using `name` and `dirname`

>>> import os
>>> import micromagneticdata as md
...
>>> dirname = os.path.join(os.path.dirname(__file__), 'tests', 'test_sample')
>>> data = md.Data(name='rectangle', dirname=dirname)
>>> data = mdata.Data(name='rectangle', dirname=dirname)
...
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
...


"""

def __init__(self, name, dirname="./"):
self.name = name
self.dirname = dirname
self.path = os.path.join(dirname, name)

def __init__(self, name=None, dirname="./", path=None):
if path is not None:
if name is not None:
raise TypeError("No other arguments can be passed with `path`.")
self.path = path
else:
if name is None:
raise TypeError("`name` must be provided if `path` is not given.")
self.path = Path(dirname) / name
if not os.path.exists(self.path):
msg = f"Directory {self.path=} cannot be found."
msg = f"Directory {self.path} cannot be found."
raise OSError(msg)

@property
def path(self):
return self._path

@path.setter
def path(self, path):
if not isinstance(path, (str, Path)):
raise TypeError(f"Unsupported {type(path)=}; expected str or pathlib.Path")
self._path = Path(path).absolute()

@property
def name(self):
return self.path.name

@property
def dirname(self):
return self.path.parent

def __repr__(self):
"""Representation string.

Expand All @@ -63,18 +96,27 @@ def __repr__(self):

Examples
--------
1. Representation string.
1. Representation string using `path`

>>> import micromagneticdata as mdata
...
>>> data = mdata.Data(
path="/home/zulfigak/ubermag_devtools/repos/micromagneticdata/micromagneticdata/tests/test_sample/rectangle"
)
>>> data
Data(...)

2. Representation string using `name` and `dirname`
Comment on lines +99 to +109
Copy link
Member

Choose a reason for hiding this comment

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

Two comments for all examples:

  • Do not (!) use an absolute path corresponding to the directory structure on your laptop. Instead use Path(__file__) as proposed as a change in one of my previous comments.
  • Showing the two different initialisation methods in all example is in my opinion not required. I would lean towards only showing path. Opinion @samjrholt ?


>>> import os
>>> import micromagneticdata as md
...
>>> dirname = os.path.join(os.path.dirname(__file__), 'tests', 'test_sample')
>>> data = md.Data(name='rectangle', dirname=dirname)
>>> data = mdata.Data(name='rectangle', dirname=dirname)
>>> data
Data(...)

"""
return f"Data(name='{self.name}', dirname='{self.dirname}')"
return f"Data(path='{self.path}')"

@property
def info(self):
Expand All @@ -92,13 +134,22 @@ def info(self):

Examples
--------
1. Getting information about data.
1. Getting information about data using `path`.

>>> import micromagneticdata as mdata
...
>>> data = mdata.Data(
path="/home/zulfigak/ubermag_devtools/repos/micromagneticdata/micromagneticdata/tests/test_sample/rectangle"
)
>>> data.info
drive_number...

2. Getting information about data using `name` and `dirname`.

>>> import os
>>> import micromagneticdata as md
...
>>> dirname = os.path.join(os.path.dirname(__file__), 'tests', 'test_sample')
>>> data = md.Data(name='rectangle', dirname=dirname)
>>> data = mdata.Data(name='rectangle', dirname=dirname)
>>> data.info
drive_number...
"""
Expand All @@ -116,13 +167,22 @@ def n(self):

Examples
--------
1. Getting the number of drives.
1. Getting the number of drives using 'path'.

>>> import micromagneticdata as mdata
...
>>> data = mdata.Data(
path="/home/zulfigak/ubermag_devtools/repos/micromagneticdata/micromagneticdata/tests/test_sample/rectangle"
)
>>> data.n
7

1. Getting the number of drives using `name` and 'dirname'.

>>> import os
>>> import micromagneticdata as md
...
>>> dirname = os.path.join(os.path.dirname(__file__), 'tests', 'test_sample')
>>> data = md.Data(name='rectangle', dirname=dirname)
>>> data = mdata.Data(name='rectangle', dirname=dirname)
>>> data.n
7

Expand All @@ -149,13 +209,28 @@ def __getitem__(self, item):

Examples
--------
1. Getting drive.
1. Getting drive using `path`

>>> import micromagneticdata as mdata
...
>>> data = mdata.Data(
path="/home/zulfigak/ubermag_devtools/repos/micromagneticdata/micromagneticdata/tests/test_sample/rectangle"
)
>>> data.n
7
>>> data[0] # first (0th) drive
OOMMFDrive(...)
>>> data[1] # second (1th) drive
Mumax3Drive(...)
>>> data[-1] # last (6th) drive
OOMMFDrive(...)

2. Getting drive using `name` and `dirname`

>>> import os
>>> import micromagneticdata as md
...
>>> dirname = os.path.join(os.path.dirname(__file__), 'tests', 'test_sample')
>>> data = md.Data(name='rectangle', dirname=dirname)
>>> data = mdata.Data(name='rectangle', dirname=dirname)
>>> data.n
7
>>> data[0] # first (0th) drive
Expand All @@ -169,7 +244,7 @@ def __getitem__(self, item):
return md.Drive(
name=self.name,
number=range(self.n)[item],
dirname=self.dirname,
dirname=str(self.dirname),
Copy link
Member

Choose a reason for hiding this comment

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

I would prefer to allow pathlib.Path for dirname in Drive.

)

def __iter__(self):
Expand All @@ -185,13 +260,25 @@ def __iter__(self):

Examples
--------
1. Iterating data object.

1. Iterating data object using `path`

>>> import micromagneticdata as mdata
...
>>> data = mdata.Data(
path="/home/zulfigak/ubermag_devtools/repos/micromagneticdata/micromagneticdata/tests/test_sample/rectangle"
)
>>> data.n
7
>>> len(list(data))
7

2. Iterating data object using `name` and `dirname`

>>> import os
>>> import micromagneticdata as md
...
>>> dirname = os.path.join(os.path.dirname(__file__), 'tests', 'test_sample')
>>> data = md.Data(name='rectangle', dirname=dirname)
>>> data = mdata.Data(name='rectangle', dirname=dirname)
>>> data.n
7
>>> len(list(data))
Expand Down Expand Up @@ -221,13 +308,22 @@ def selector(self, description="drive", **kwargs):

Examples
--------
1. Selection widget.
1. Selection widget using `path`

>>> import micromagneticdata as mdata
...
>>> data = mdata.Data(
path="/home/zulfigak/ubermag_devtools/repos/micromagneticdata/micromagneticdata/tests/test_sample/rectangle"
)
>>> data.selector()
BoundedIntText(...)

2. Selection widget using `name` and `dirname`

>>> import os
>>> import micromagneticdata as md
...
>>> dirname = os.path.join(os.path.dirname(__file__), 'tests', 'test_sample')
>>> data = md.Data(name='rectangle', dirname=dirname)
>>> data = mdata.Data(name='rectangle', dirname=dirname)
>>> data.selector()
BoundedIntText(...)

Expand Down
5 changes: 4 additions & 1 deletion micromagneticdata/tests/test_data.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
from pathlib import Path

import ipywidgets
import pandas as pd
Expand All @@ -17,7 +18,9 @@ def setup_method(self):
def test_init(self):
assert isinstance(self.data, md.Data)

# Exception
with pytest.raises(IOError):
md.Data(path=Path(self.dirname) / "nonexistent")

with pytest.raises(IOError):
md.Data(name="wrong", dirname=self.dirname)

Expand Down
Loading