Skip to content

Commit

Permalink
Added m_def to the PhysicalProperties and fix testing
Browse files Browse the repository at this point in the history
  • Loading branch information
JosePizarro3 committed Apr 29, 2024
1 parent a7412b2 commit 62227a6
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 76 deletions.
33 changes: 7 additions & 26 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 Down Expand Up @@ -196,7 +176,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 +201,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
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
55 changes: 40 additions & 15 deletions tests/test_physical_properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

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

from . import logger

Expand All @@ -30,6 +30,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 +42,11 @@ class DummyPhysicalProperty(PhysicalProperty):
""",
)

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


class TestPhysicalProperty:
"""
Expand Down Expand Up @@ -84,10 +93,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 +108,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 +124,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 +145,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 @@ -146,15 +163,23 @@ def test_is_derived(self):
Test the `normalize` and `_is_derived` methods.
"""
# Testing a directly parsed physical property
not_derived_physical_property = PhysicalProperty(source='simulation')
not_derived_physical_property = PhysicalProperty(
m_def=Section(
iri='http://fairmat-nfdi.eu/taxonomy/PhysicalProperty', rank=[]
)
)
not_derived_physical_property.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
# Testing a derived physical property
derived_physical_property = PhysicalProperty(
source='analysis',
physical_property_ref=not_derived_physical_property,
m_def=Section(
iri='http://fairmat-nfdi.eu/taxonomy/PhysicalProperty', rank=[]
)
)
derived_physical_property.source = 'analysis'
derived_physical_property.physical_property_ref = not_derived_physical_property
assert derived_physical_property._is_derived() is True
derived_physical_property.normalize(EntryArchive(), logger)
assert derived_physical_property.is_derived is True
10 changes: 4 additions & 6 deletions tests/test_spectral_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,10 @@ def test_default_quantities(self):
"""
electronic_dos = ElectronicDensityOfStates()
assert (
electronic_dos.iri
electronic_dos.m_def.iri
== 'http://fairmat-nfdi.eu/taxonomy/ElectronicDensityOfStates'
)
assert electronic_dos.name == 'ElectronicDensityOfStates'
assert electronic_dos.rank == []
assert electronic_dos.m_def.rank == []

def test_get_energy_points(self):
"""
Expand Down Expand Up @@ -262,9 +261,8 @@ def test_default_quantities(self):
Test the default quantities assigned when creating an instance of the `XASSpectra` class.
"""
xas_spectra = XASSpectra()
assert xas_spectra.iri is None # Add iri when available
assert xas_spectra.name == 'XASSpectra'
assert xas_spectra.rank == []
assert xas_spectra.m_def.iri is None # TODO add iri when available
assert xas_spectra.m_def.rank == []

@pytest.mark.parametrize(
'xanes_energies, exafs_energies, xas_values',
Expand Down

0 comments on commit 62227a6

Please sign in to comment.