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

Moving iri and rank to m_def #59

Closed
wants to merge 2 commits into from
Closed
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
38 changes: 10 additions & 28 deletions src/nomad_simulations/physical_property.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,18 +54,12 @@ class PhysicalProperty(ArchiveSection):
# TODO add `errors`
# TODO add `smearing`

m_def = Section() # modify `m_def` adding `iri` and `rank`

name = Quantity(
type=str,
description="""
Name of the physical property. Example: `'ElectronicBandGap'`.
""",
)

iri = Quantity(
type=URL,
description="""
Internationalized Resource Identifier (IRI) of the physical property defined in the FAIRmat
taxonomy, https://fairmat-nfdi.github.io/fairmat-taxonomy/.
Name of the physical property.
""",
)

Expand Down Expand Up @@ -96,20 +90,6 @@ class PhysicalProperty(ArchiveSection):
# ! add more examples in the description to improve the understanding of this quantity
)

rank = DirectQuantity(
type=Dimension,
shape=['0..*'],
default=[],
name='rank',
description="""
Rank of the tensor describing the physical property. This quantity is stored as a Dimension:
- scalars (tensor rank 0) have `rank=[]` (`len(rank) = 0`),
- vectors (tensor rank 1) have `rank=[a]` (`len(rank) = 1`),
- matrices (tensor rank 2), have `rank=[a, b]` (`len(rank) = 2`),
- etc.
""",
)

variables = SubSection(sub_section=Variables.m_def, repeats=True)

# * `value` must be overwritten in the derived classes defining its type, unit, and description
Expand All @@ -125,12 +105,13 @@ class PhysicalProperty(ArchiveSection):
""",
)

physical_property_ref = Quantity(
type=Reference(SectionProxy('PhysicalProperty')),
physical_property_ref = SubSection(
section_def=SectionProxy('PhysicalProperty'),
description="""
Reference to the `PhysicalProperty` section from which the physical property was derived. If `physical_property_ref`
is populated, the quantity `is_derived` is set to True via normalization.
""",
repeats=False,
)

is_derived = Quantity(
Expand Down Expand Up @@ -196,7 +177,7 @@ def full_shape(self) -> list:
Returns:
(list): The full shape of the physical property.
"""
return self.variables_shape + self.rank
return self.variables_shape + self.m_def.rank

@property
def _new_value(self) -> Quantity:
Expand All @@ -221,9 +202,10 @@ def __init__(
self, m_def: Section = None, m_context: Context = None, **kwargs
) -> None:
super().__init__(m_def, m_context, **kwargs)
if self.iri is None:
if self.m_def.iri is None:
logger.warning(
'The used property is not defined in the FAIRmat taxonomy (https://fairmat-nfdi.github.io/fairmat-taxonomy/). You can contribute there if you want to extend the list of available materials properties.'
'The used property is not defined in the FAIRmat taxonomy (http://fairmat-nfdi.eu/taxonomy/). '
'You can contribute there if you want to extend the list of available materials properties.'
)

def __setattr__(self, name: str, val: Any) -> None:
Expand Down
6 changes: 1 addition & 5 deletions src/nomad_simulations/properties/band_gap.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,7 @@ class ElectronicBandGap(PhysicalProperty):
Energy difference between the highest occupied electronic state and the lowest unoccupied electronic state.
"""

# ! implement `iri` and `rank` as part of `m_def = Section()`

iri = 'http://fairmat-nfdi.eu/taxonomy/ElectronicBandGap'
m_def = Section(iri='http://fairmat-nfdi.eu/taxonomy/ElectronicBandGap', rank=[])

type = Quantity(
type=MEnum('direct', 'indirect'),
Expand Down Expand Up @@ -80,8 +78,6 @@ def __init__(
self, m_def: Section = None, m_context: Context = None, **kwargs
) -> None:
super().__init__(m_def, m_context, **kwargs)
self.name = self.m_def.name
self.rank = []

def _check_negative_values(self, logger: BoundLogger) -> Optional[pint.Quantity]:
"""
Expand Down
12 changes: 2 additions & 10 deletions src/nomad_simulations/properties/energies.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,7 @@ class FermiLevel(PhysicalProperty):
Energy required to add or extract a charge from a material at zero temperature. It can be also defined as the chemical potential at zero temperature.
"""

# ! implement `iri` and `rank` as part of `m_def = Section()`

iri = 'http://fairmat-nfdi.eu/taxonomy/FermiLevel'
m_def = Section(iri='http://fairmat-nfdi.eu/taxonomy/FermiLevel', rank=[])

value = Quantity(
type=np.float64,
Expand All @@ -44,8 +42,6 @@ def __init__(
self, m_def: Section = None, m_context: Context = None, **kwargs
) -> None:
super().__init__(m_def, m_context, **kwargs)
self.rank = []
self.name = self.m_def.name

def normalize(self, archive, logger) -> None:
super().normalize(archive, logger)
Expand All @@ -56,9 +52,7 @@ class ChemicalPotential(PhysicalProperty):
Free energy cost of adding or extracting a particle from a thermodynamic system.
"""

# ! implement `iri` and `rank` as part of `m_def = Section()`

iri = 'http://fairmat-nfdi.eu/taxonomy/ChemicalPotential'
m_def = Section(iri='http://fairmat-nfdi.eu/taxonomy/ChemicalPotential', rank=[])

value = Quantity(
type=np.float64,
Expand All @@ -72,8 +66,6 @@ def __init__(
self, m_def: Section = None, m_context: Context = None, **kwargs
) -> None:
super().__init__(m_def, m_context, **kwargs)
self.rank = []
self.name = self.m_def.name

def normalize(self, archive, logger) -> None:
super().normalize(archive, logger)
10 changes: 6 additions & 4 deletions src/nomad_simulations/properties/spectral_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ class SpectralProfile(PhysicalProperty):
A base section used to define the spectral profile.
"""

m_def = Section(rank=[])

value = Quantity(
type=np.float64,
description="""
Expand All @@ -47,7 +49,6 @@ def __init__(
self, m_def: Section = None, m_context: Context = None, **kwargs
) -> None:
super().__init__(m_def, m_context, **kwargs)
self.rank = []

def _get_energy_points(self, logger: BoundLogger) -> Optional[pint.Quantity]:
"""
Expand Down Expand Up @@ -145,8 +146,9 @@ class ElectronicDensityOfStates(DOSProfile):
Number of electronic states accessible for the charges per energy and per volume.
"""

# ! implement `iri` and `rank` as part of `m_def = Section()`
iri = 'http://fairmat-nfdi.eu/taxonomy/ElectronicDensityOfStates'
m_def = Section(
iri='http://fairmat-nfdi.eu/taxonomy/ElectronicDensityOfStates', rank=[]
)

spin_channel = Quantity(
type=np.int32,
Expand Down Expand Up @@ -533,7 +535,7 @@ class XASSpectra(SpectralProfile):
X-ray Absorption Spectra (XAS).
"""

# ! implement `iri` and `rank` as part of `m_def = Section()`
m_def = Section(rank=[]) # TODO add XASSpectra to taxonomy

xanes_spectra = SubSection(
sub_section=SpectralProfile.m_def,
Expand Down
3 changes: 3 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@

from nomad.units import ureg
from nomad.datamodel import EntryArchive
from nomad.datamodel.data import ArchiveSection
from nomad.metainfo import Quantity, Section, Context, SubSection

from . import logger

Expand All @@ -31,6 +33,7 @@
from nomad_simulations.model_method import ModelMethod
from nomad_simulations.numerical_settings import SelfConsistency
from nomad_simulations.outputs import Outputs, SCFOutputs
from nomad_simulations.physical_property import PhysicalProperty
from nomad_simulations.variables import Energy2 as Energy
from nomad_simulations.properties import (
ElectronicBandGap,
Expand Down
5 changes: 2 additions & 3 deletions tests/test_band_gap.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,10 @@ def test_default_quantities(self):
"""
electronic_band_gap = ElectronicBandGap()
assert (
electronic_band_gap.iri
electronic_band_gap.m_def.iri
== 'http://fairmat-nfdi.eu/taxonomy/ElectronicBandGap'
)
assert electronic_band_gap.name == 'ElectronicBandGap'
assert electronic_band_gap.rank == []
assert electronic_band_gap.m_def.rank == []

@pytest.mark.parametrize(
'value, result',
Expand Down
10 changes: 4 additions & 6 deletions tests/test_energies.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,8 @@ def test_default_quantities(self):
Test the default quantities assigned when creating an instance of the `FermiLevel` class.
"""
fermi_level = FermiLevel()
assert fermi_level.iri == 'http://fairmat-nfdi.eu/taxonomy/FermiLevel'
assert fermi_level.name == 'FermiLevel'
assert fermi_level.rank == []
assert fermi_level.m_def.iri == 'http://fairmat-nfdi.eu/taxonomy/FermiLevel'
assert fermi_level.m_def.rank == []


class TestChemicalPotential:
Expand All @@ -47,8 +46,7 @@ def test_default_quantities(self):
"""
chemical_potential = ChemicalPotential()
assert (
chemical_potential.iri
chemical_potential.m_def.iri
== 'http://fairmat-nfdi.eu/taxonomy/ChemicalPotential'
)
assert chemical_potential.name == 'ChemicalPotential'
assert chemical_potential.rank == []
assert chemical_potential.m_def.rank == []
3 changes: 2 additions & 1 deletion tests/test_outputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
from . import logger
from .conftest import generate_scf_electronic_band_gap_template

from nomad_simulations.outputs import Outputs, ElectronicBandGap
from nomad_simulations.outputs import Outputs
from nomad_simulations.properties import ElectronicBandGap


class TestOutputs:
Expand Down
79 changes: 57 additions & 22 deletions tests/test_physical_properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@

from nomad.units import ureg
from nomad.datamodel import EntryArchive
from nomad.metainfo import Quantity
from nomad.datamodel.data import ArchiveSection
from nomad.metainfo import Quantity, Section, Context, SubSection

from . import logger

Expand All @@ -30,6 +31,10 @@


class DummyPhysicalProperty(PhysicalProperty):
m_def = Section(
iri='http://fairmat-nfdi.eu/taxonomy/DummyPhysicalProperty', rank=[3, 3]
)

value = Quantity(
type=np.float64,
unit='eV',
Expand All @@ -38,6 +43,17 @@ class DummyPhysicalProperty(PhysicalProperty):
""",
)

def __init__(
self, m_def: Section = None, m_context: Context = None, **kwargs
) -> None:
super().__init__(m_def, m_context, **kwargs)


class SectionWithProperties(ArchiveSection):
m_def = Section()

physical_property = SubSection(sub_section=PhysicalProperty.m_def, repeats=True)


class TestPhysicalProperty:
"""
Expand Down Expand Up @@ -84,10 +100,12 @@ def test_static_properties(
Test the static properties of the `PhysicalProperty` class, `variables_shape` and `full_shape`.
"""
physical_property = PhysicalProperty(
source='simulation',
rank=rank,
variables=variables,
m_def=Section(
iri='http://fairmat-nfdi.eu/taxonomy/PhysicalProperty', rank=rank
)
)
physical_property.source = 'simulation'
physical_property.variables = variables
assert physical_property.variables_shape == result_variables_shape
assert physical_property.full_shape == result_full_shape

Expand All @@ -97,8 +115,10 @@ def test_setattr_value(self):
"""
physical_property = DummyPhysicalProperty(
source='simulation',
rank=[3, 3],
variables=[Variables(n_grid_points=4), Variables(n_grid_points=10)],
variables=[
Variables(n_grid_points=4),
Variables(n_grid_points=10),
],
)
# `physical_property.value` must have full_shape=[4, 10, 3, 3]
value = np.ones((4, 10, 3, 3)) * ureg.eV
Expand All @@ -111,10 +131,12 @@ def test_setattr_value_wrong_shape(self):
Test the `__setattr__` method when the `value` has a wrong shape.
"""
physical_property = PhysicalProperty(
source='simulation',
rank=[],
variables=[],
m_def=Section(
iri='http://fairmat-nfdi.eu/taxonomy/PhysicalProperty', rank=[]
)
)
physical_property.source = 'simulation'
physical_property.variables = []
# `physical_property.value` must have shape=[]
value = np.ones((3, 3))
wrong_shape = list(value.shape)
Expand All @@ -130,10 +152,12 @@ def test_setattr_none(self):
Test the `__setattr__` method when setting the `value` to `None`.
"""
physical_property = PhysicalProperty(
source='simulation',
rank=[],
variables=[],
m_def=Section(
iri='http://fairmat-nfdi.eu/taxonomy/PhysicalProperty', rank=[]
)
)
physical_property.source = 'simulation'
physical_property.variables = []
with pytest.raises(ValueError) as exc_info:
physical_property.value = None
assert (
Expand All @@ -145,16 +169,27 @@ def test_is_derived(self):
"""
Test the `normalize` and `_is_derived` methods.
"""
section = SectionWithProperties()
# Testing a directly parsed physical property
not_derived_physical_property = PhysicalProperty(source='simulation')
assert not_derived_physical_property._is_derived() is False
not_derived_physical_property.normalize(EntryArchive(), logger)
assert not_derived_physical_property.is_derived is False
not_derived_property = PhysicalProperty(
m_def=Section(
iri='http://fairmat-nfdi.eu/taxonomy/PhysicalProperty', rank=[]
)
)
not_derived_property.source = 'simulation'
section.physical_property.append(not_derived_property)
assert not_derived_property._is_derived() is False
not_derived_property.normalize(EntryArchive(), logger)
assert not_derived_property.is_derived is False
# Testing a derived physical property
derived_physical_property = PhysicalProperty(
source='analysis',
physical_property_ref=not_derived_physical_property,
derived_property = PhysicalProperty(
m_def=Section(
iri='http://fairmat-nfdi.eu/taxonomy/PhysicalProperty', rank=[]
)
)
assert derived_physical_property._is_derived() is True
derived_physical_property.normalize(EntryArchive(), logger)
assert derived_physical_property.is_derived is True
section.physical_property.append(derived_property)
derived_property.source = 'analysis'
derived_property.physical_property_ref = not_derived_property
assert derived_property._is_derived() is True
derived_property.normalize(EntryArchive(), logger)
assert derived_property.is_derived is True
Loading
Loading