diff --git a/src/nomad_simulations/model_method.py b/src/nomad_simulations/model_method.py index 323b8af6..64825c61 100644 --- a/src/nomad_simulations/model_method.py +++ b/src/nomad_simulations/model_method.py @@ -15,24 +15,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # -# -# Copyright The NOMAD Authors. -# -# This file is part of NOMAD. -# See https://nomad-lab.eu for further info. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# import numpy as np import pint @@ -71,7 +53,6 @@ class NumericalSettings(ArchiveSection): `NumericalSettings` section. Possible values: "KMesh", "FrequencyMesh", "TimeMesh", "SelfConsistency", "BasisSet". """, - a_eln=ELNAnnotation(component='StringEditQuantity'), ) def normalize(self, archive, logger) -> None: @@ -317,6 +298,11 @@ class KMesh(Mesh): # TODO add extraction of `high_symmetry_points` using BandStructureNormalizer idea (left for later when defining outputs.py) + def __init__(self, m_def: Section = None, m_context: Context = None, **kwargs): + super().__init__(m_def, m_context, **kwargs) + # Set the name of the section + self.name = self.m_def.name + def resolve_points_and_offset( self, logger: BoundLogger ) -> Tuple[Optional[List[np.ndarray]], Optional[np.ndarray]]: @@ -420,9 +406,6 @@ def resolve_k_line_density( def normalize(self, archive, logger) -> None: super().normalize(archive, logger) - # Set the name of the section - self.name = self.m_def.name if self.name is None else self.name - # If `grid` is not defined, we do not normalize the KMesh if self.grid is None: logger.warning('Could not find `KMesh.grid`.') @@ -452,12 +435,14 @@ class QuasiparticlesFrequencyMesh(Mesh): """, ) + def __init__(self, m_def: Section = None, m_context: Context = None, **kwargs): + super().__init__(m_def, m_context, **kwargs) + # Set the name of the section + self.name = self.m_def.name + def normalize(self, archive, logger) -> None: super().normalize(archive, logger) - # Set the name of the section - self.name = self.m_def.name if self.name is None else self.name - class SelfConsistency(NumericalSettings): """ @@ -511,22 +496,27 @@ class SelfConsistency(NumericalSettings): """, ) + def __init__(self, m_def: Section = None, m_context: Context = None, **kwargs): + super().__init__(m_def, m_context, **kwargs) + # Set the name of the section + self.name = self.m_def.name + def normalize(self, archive, logger) -> None: super().normalize(archive, logger) - # Set the name of the section - self.name = self.m_def.name if self.name is None else self.name - class BasisSet(NumericalSettings): """""" # TODO work on this base section (@ndaelman-hu) - def normalize(self, archive, logger) -> None: - super().normalize(archive, logger) + def __init__(self, m_def: Section = None, m_context: Context = None, **kwargs): + super().__init__(m_def, m_context, **kwargs) # Set the name of the section - self.name = self.m_def.name if self.name is None else self.name + self.name = self.m_def.name + + def normalize(self, archive, logger) -> None: + super().normalize(archive, logger) class ModelMethod(ArchiveSection): diff --git a/src/nomad_simulations/model_system.py b/src/nomad_simulations/model_system.py index 8f11ed77..c505eef2 100644 --- a/src/nomad_simulations/model_system.py +++ b/src/nomad_simulations/model_system.py @@ -55,7 +55,7 @@ from nomad.units import ureg from nomad.atomutils import Formula, get_normalized_wyckoff, search_aflow_prototype -from nomad.metainfo import Quantity, SubSection, SectionProxy, MEnum +from nomad.metainfo import Quantity, SubSection, SectionProxy, MEnum, Section, Context from nomad.datamodel.data import ArchiveSection from nomad.datamodel.metainfo.basesections import Entity, System from nomad.datamodel.metainfo.annotations import ELNAnnotation @@ -224,6 +224,14 @@ class Cell(GeometricSpace): A base section used to specify the cell quantities of a system at a given moment in time. """ + name = Quantity( + type=str, + description=""" + Name of the specific cell section. This is typically used to easy identification of the + `Cell` section. Possible values: "AtomicCell". + """, + ) + type = Quantity( type=MEnum('original', 'primitive', 'conventional'), description=""" @@ -327,6 +335,11 @@ class AtomicCell(Cell): """, ) + def __init__(self, m_def: Section = None, m_context: Context = None, **kwargs): + super().__init__(m_def, m_context, **kwargs) + # Set the name of the section + self.name = self.m_def.name + def to_ase_atoms(self, logger: BoundLogger) -> Optional[ase.Atoms]: """ Generates an ASE Atoms object with the most basic information from the parsed `AtomicCell` @@ -373,6 +386,9 @@ def to_ase_atoms(self, logger: BoundLogger) -> Optional[ase.Atoms]: def normalize(self, archive, logger) -> None: super().normalize(archive, logger) + # Set the name of the section + self.name = self.m_def.name if self.name is None else self.name + class Symmetry(ArchiveSection): """ @@ -629,7 +645,7 @@ def resolve_bulk_symmetry( def normalize(self, archive, logger) -> None: atomic_cell = get_sibling_section( - section=self, sibling_section_name='atomic_cell', logger=logger + section=self, sibling_section_name='cell', logger=logger ) if self.m_parent.type == 'bulk': # Adding the newly calculated primitive and conventional cells to the ModelSystem @@ -637,14 +653,10 @@ def normalize(self, archive, logger) -> None: primitive_atomic_cell, conventional_atomic_cell, ) = self.resolve_bulk_symmetry(atomic_cell, logger) - self.m_parent.m_add_sub_section( - ModelSystem.atomic_cell, primitive_atomic_cell - ) - self.m_parent.m_add_sub_section( - ModelSystem.atomic_cell, conventional_atomic_cell - ) + self.m_parent.m_add_sub_section(ModelSystem.cell, primitive_atomic_cell) + self.m_parent.m_add_sub_section(ModelSystem.cell, conventional_atomic_cell) # Reference to the standarized cell, and if not, fallback to the originally parsed one - self.atomic_cell_ref = self.m_parent.atomic_cell[-1] + self.atomic_cell_ref = self.m_parent.cell[-1] class ChemicalFormula(ArchiveSection): @@ -718,7 +730,7 @@ def resolve_chemical_formulas(self, formula: Formula) -> None: def normalize(self, archive, logger) -> None: atomic_cell = get_sibling_section( - section=self, sibling_section_name='atomic_cell', logger=logger + section=self, sibling_section_name='cell', logger=logger ) ase_atoms = atomic_cell.to_ase_atoms(logger) formula = None @@ -858,7 +870,7 @@ class ModelSystem(System): """, ) - atomic_cell = SubSection(sub_section=AtomicCell.m_def, repeats=True) + cell = SubSection(sub_section=Cell.m_def, repeats=True) symmetry = SubSection(sub_section=Symmetry.m_def, repeats=True) @@ -966,29 +978,30 @@ def normalize(self, archive, logger) -> None: return # Extracting ASE Atoms object from the originally parsed AtomicCell section - if self.atomic_cell is None: + if self.cell is None: self.logger.warning( 'Could not find the originally parsed atomic system. `Symmetry` and `ChemicalFormula` extraction is thus not run.' ) return - self.atomic_cell[0].type = 'original' - ase_atoms = self.atomic_cell[0].to_ase_atoms(logger) - if not ase_atoms: - return - - # Resolving system `type`, `dimensionality`, and Symmetry section (if this last - # one does not exists already) - original_atom_positions = self.atomic_cell[0].positions - if original_atom_positions is not None: - self.type = 'unavailable' if not self.type else self.type - ( - self.type, - self.dimensionality, - ) = self.resolve_system_type_and_dimensionality(ase_atoms, logger) - # Creating and normalizing Symmetry section - if self.type == 'bulk' and self.symmetry is not None: - sec_symmetry = self.m_create(Symmetry) - sec_symmetry.normalize(archive, logger) + if self.cell[0].name == 'AtomicCell': + self.cell[0].type = 'original' + ase_atoms = self.cell[0].to_ase_atoms(logger) + if not ase_atoms: + return + + # Resolving system `type`, `dimensionality`, and Symmetry section (if this last + # one does not exists already) + original_atom_positions = self.cell[0].positions + if original_atom_positions is not None: + self.type = 'unavailable' if not self.type else self.type + ( + self.type, + self.dimensionality, + ) = self.resolve_system_type_and_dimensionality(ase_atoms, logger) + # Creating and normalizing Symmetry section + if self.type == 'bulk' and self.symmetry is not None: + sec_symmetry = self.m_create(Symmetry) + sec_symmetry.normalize(archive, logger) # Creating and normalizing ChemicalFormula section # TODO add support for fractional formulas (possibly add `AtomicCell.concentrations` for each species)