Entities#

Some definitions#

import mammos_entity as me
import mammos_units as u

Creating entities#

For entities that are important in MaMMoS, there are convenient attributes to define those. For example for the :

Ms = me.Ms(800e3, "A/m")  # defines Ms = 8e5 A/m
Ms
SpontaneousMagnetization(value=800000.0, unit=A / m)

If no units are provided, then default units are inferred from the ontology (A/m in the example above). These are typically SI units without numerical prefactors (such as kilo, milli, etc.). Inferring units from the ontology is fragile and the inferred units can change between different releases of mammos-entity without notice. Therefore, it is highly recommended to always pass units explicitly.

If units are provided, these are compared with the units expected for that entity. An error is raised if they do not match.

M1 = me.Ms(800e3, "A/m")
M1
SpontaneousMagnetization(value=800000.0, unit=A / m)

Providing units can be also useful, if numerical prefactors are used (such as kilo):

M2 = me.Ms(800, "kA/m")
M2
SpontaneousMagnetization(value=800.0, unit=kA / m)
M1 == M2
True

We can create an entity from a Quantity as well:

Ms_quantity = 800 * u.kA / u.m  # or equivalently: Ms_quantity = u.Quantity(800, "kA/m")
Ms_quantity
\[800 \; \mathrm{\frac{kA}{m}}\]
me.Ms(Ms_quantity)
SpontaneousMagnetization(value=800.0, unit=kA / m)

Entities can also have an optional attribute, description, storing a string. This description will appear in the string representation:

me.Ms(Ms_quantity, description="Evaluated using UppASD with 70000 Monte Carlo steps.")
SpontaneousMagnetization(value=800.0, unit=kA / m, description='Evaluated using UppASD with 70000 Monte Carlo steps.')

If we like to express spontaneous magnetization in Tesla, we can convert it to the required A/m. To allow that conversion we must explicitely enable the magnetic_flux_field equivalency (\(B=\mu_0H\)):

# enable implicit conversion between A/m and T in the rest of the notebook:
u.set_enabled_equivalencies(u.magnetic_flux_field())

a = 1.2 * u.T  # Quantity in Tesla

Ms = me.Ms(a.to("A/m"))  # Convert Quantity to A/m and create entity
Ms
SpontaneousMagnetization(value=954929.6580315315, unit=A / m)

As a cross-check we can access the quantity attribute and convert that back to Tesla. This operation does not modify Ms.

Ms.q.to("T")
\[1.2 \; \mathrm{T}\]

Initializing with incompatible units fails with an error. In particular, implicit conversion via equivalencies is not supported. Convert to the required units first, as shown above.

me.Ms(1.2, "T")  # Tesla not compatible with A/m
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[11], line 1
----> 1 me.Ms(1.2, "T")  # Tesla not compatible with A/m

File ~/work/mammos/mammos/.pixi/envs/docs/lib/python3.11/site-packages/mammos_entity/_factory.py:311, in Ms(value, unit, **kwargs)
    292 def Ms(
    293     value: int | float | numpy.typing.ArrayLike = 0,
    294     unit: None | str = None,
    295     **kwargs,
    296 ) -> mammos_entity.Entity:
    297     """Create an Entity representing the spontaneous magnetization (Ms).
    298 
    299     Args:
   (...)    309 
    310     """
--> 311     return Entity("SpontaneousMagnetization", value, unit, **kwargs)

File ~/work/mammos/mammos/.pixi/envs/docs/lib/python3.11/site-packages/mammos_entity/_entity.py:340, in Entity.__init__(self, ontology_label, value, unit, description)
    338 with u.set_enabled_equivalencies(mammos_equivalencies):
    339     if not any(unit.is_equivalent(ou) for ou in ontology_units):
--> 340         raise ValueError(
    341             f"Given unit: {unit} incompatible with ontology. "
    342             f"Allowed units for entity {label} are: {ontology_units}."
    343         )
    345     self._quantity = u.Quantity(value=value, unit=unit)
    346 self._ontology_label = label

ValueError: Given unit: T incompatible with ontology. Allowed units for entity SpontaneousMagnetization are: [Unit("A / m")].

For more details about unit conversion and equivalencies refer to the documentation of mammos-units.

Access to ontology#

Each entity object knows its label in the ontology:

Ms.ontology_label
'SpontaneousMagnetization'

and its unique identifier of the ontology entry, the so-called IRI (Internationalized Resource Identifier):

Ms.ontology_iri
'https://w3id.org/emmo/domain/magnetic-materials#EMMO_032731f8-874d-5efb-9c9d-6dafaa17ef25'

When saving data to a file, the property ontology_label_with_iri might be useful to save in the metadata as it returns a string containing the ontology label together with the IRI.

Ms.ontology_label_with_iri
'SpontaneousMagnetization https://w3id.org/emmo/domain/magnetic-materials#EMMO_032731f8-874d-5efb-9c9d-6dafaa17ef25'

The ontology attribute links to an owlready2 object created by the EMMOntoPy package. We can use all attributes of the ontology object through Ms.ontology:

Ms.ontology.get_annotations()
{'elucidation': [locstr('The spontaneous magnetization, Ms, of a ferromagnet is the result\nof alignment of the magnetic moments of individual atoms. Ms exists\nwithin a domain of a ferromagnet.', 'en')],
 'prefLabel': [locstr('SpontaneousMagnetization', 'en-US')],
 'altLabel': [locstr('Ms', ''), locstr('SpontaneousMagnetisation', 'en-GB')],
 'wikipediaReference': [locstr('https://en.wikipedia.org/wiki/Spontaneous_magnetization', '')],
 'IECEntry': [locstr('https://www.electropedia.org/iev/iev.nsf/display?openform&ievref=221-02-41', '')]}
Ms.ontology.get_class_properties()
{core.prefLabel,
 emmo.hasMeasurementUnit,
 emmo.elucidation,
 core.altLabel,
 magnetic-materials.wikipediaReference,
 magnetic-materials.IECEntry}
print(Ms.ontology.elucidation[0])
The spontaneous magnetization, Ms, of a ferromagnet is the result
of alignment of the magnetic moments of individual atoms. Ms exists
within a domain of a ferromagnet.

Entities contain Quantities#

Each entity has a quantity attribute containing the mammos_units.Quantity object. See mammos_units examples for details.

Ms.quantity
\[954929.66 \; \mathrm{\frac{A}{m}}\]

There is also the shorthand q for the quantity attribute:

Ms.q
\[954929.66 \; \mathrm{\frac{A}{m}}\]

The attributes value and unit provide direct access to value and unit of the quantity:

Ms.value
954929.6580315315
Ms.unit
\[\mathrm{\frac{A}{m}}\]

Entities do not support numerical operations. To perform these operations, we first need to extract the quantity:

Ms.q**2
\[9.1189065 \times 10^{11} \; \mathrm{\frac{A^{2}}{m^{2}}}\]
Ms.quantity.to("kA/m")
\[954.92966 \; \mathrm{\frac{kA}{m}}\]
Ms.quantity.to("T")
\[1.2 \; \mathrm{T}\]

Defining vector entities (Example Zeeman field)#

H = me.H([1e4, 1e4, 1e4], "A/m")
H
ExternalMagneticField(value=[10000. 10000. 10000.], unit=A / m)
H.ontology
magnetic-materials.ExternalMagneticField
print(H.ontology.elucidation[0])
The external field H′, acting on a sample that is produced by
electric currents or the stray field of magnets outside the sample
volume, is often called the applied field.

Extending an Entity#

Entities are immutable and adding additional values is not directly possible. Instead a new entity with the combined values has to be created. This can be conveniently done with the following function:

T1 = me.T([1, 2], "K")
T2 = me.T([3, 4], "K")

me.operations.concat_flat(T1, T2)
ThermodynamicTemperature(value=[1. 2. 3. 4.], unit=K)

concat_flat is not limited to entities. You can also pass mammos_units.Quantity or other scalar or array-like data. concat_flat will check that all elements are compatible (same ontology_label if they are entities, compatible units for entities and quantities) and convert everything into a single entity:

me.operations.concat_flat(me.T([1, 2]), 3 * u.K, [4, 5])
ThermodynamicTemperature(value=
[1. 2. 3. 4. 5.],
 unit=K)

Does mammos_entity not provide your preferred entity?#

The list of convenience attributes is at https://mammos-project.github.io/mammos/api/mammos_entity.html

If the desired entity is not available, we can search the EMMO ontology (including the magnetic_material_mammos additions), for example for entity labels containing the string “Magnetization”:

me.search_labels("Magnetization")
['MagneticMomentPerUnitMass',
 'Magnetization',
 'MassMagnetizationUnit',
 'Remanence',
 'SaturationMagnetization',
 'SpontaneousMagnetization']

The function searches for the given substring in all labels (prefLabel, altLabel). If any label contains the substring the prefLabel is returned. Therefore, we see “MagneticMomentPerUnitMass” in the example above.

We can also search for exact matches only:

me.search_labels("Magnetization", auto_wildcard=False)
['Magnetization']

The function search_labels is a wrapper around get_by_label_all from emmontopy. If you need any of the additional options use the function directly. Note that the return type of the elements changes from strings (prefLabel) to owlready2.Thing classes.

me.mammos_ontology.get_by_label_all("*Field*")
{emmo.ElectricDisplacementFieldUnit,
 emmo.ElectricFieldStrength,
 emmo.ElectricFieldStrengthUnit,
 emmo.MagneticFieldStrength,
 emmo.MagneticFieldStrengthUnit,
 magnetic-materials.AnisotropyField,
 magnetic-materials.CoercivityHc,
 magnetic-materials.DemagnetizingField,
 magnetic-materials.ExternalMagneticField,
 magnetic-materials.InternalMagneticField,
 magnetic-materials.KneeField,
 magnetic-materials.KneeFieldExternal,
 magnetic-materials.MokeAppliedField,
 magnetic-materials.SwitchingFieldCoercivity,
 magnetic-materials.SwitchingFieldCoercivityExternal}
me.mammos_ontology.get_by_label_all("*Field*", prefix="magnetic-materials")
{magnetic-materials.AnisotropyField,
 magnetic-materials.CoercivityHc,
 magnetic-materials.DemagnetizingField,
 magnetic-materials.ExternalMagneticField,
 magnetic-materials.InternalMagneticField,
 magnetic-materials.KneeField,
 magnetic-materials.KneeFieldExternal,
 magnetic-materials.MokeAppliedField,
 magnetic-materials.SwitchingFieldCoercivity,
 magnetic-materials.SwitchingFieldCoercivityExternal}

Once identified the right label, we create an entity like this:

me.Entity("AnisotropyField", value=230, unit="A/m")
AnisotropyField(value=230.0, unit=A / m)

To search in fields other than labels, e.g. in all elucidations, use the following function:

me.mammos_ontology.search(elucidation="*magnetization*")
[emmo.Permeability, emmo.Coercivity, emmo.AmperePerMetre, emmo.AmpereTurnPerMetre, emmo.MagneticPolarisation, magnetic-materials.KneeField, magnetic-materials.DemagnetizingFactor, magnetic-materials.SpontaneousMagnetization, magnetic-materials.KneeFieldExternal, magnetic-materials.ExternalSusceptibility, magnetic-materials.DemagnetizingField, magnetic-materials.MagneticHysteresisProperties, magnetic-materials.UniaxialMagneticAnisotropy, magnetic-materials.SaturationMagnetization, magnetic-materials.UniaxialMagnetocrystallineAnisotropy, magnetic-materials.CoercivityHc, magnetic-materials.MassMagnetizationUnit, magnetic-materials.UniaxialAnisotropyConstant, magnetic-materials.ShapeAnisotropyConstant, magnetic-materials.AnisotropyField, magnetic-materials.InternalSusceptibility, magnetic-materials.CoercivityHcExternal]