diff --git a/nomad/cli/dev.py b/nomad/cli/dev.py
index 2494ae42b64d93f2e220dc687c08b1a064bf2940..82a73709e7f63eca511bd44b9fcc47cbd9fe2457 100644
--- a/nomad/cli/dev.py
+++ b/nomad/cli/dev.py
@@ -42,3 +42,12 @@ def qa(skip_tests: bool, exitfirst: bool):
     ret_code += os.system('python -m mypy --ignore-missing-imports --follow-imports=silent --no-strict-optional nomad tests')
 
     sys.exit(ret_code)
+
+
+@dev.command(help='Generates source-code for the new metainfo from .json files of the old.')
+@click.argument('package', nargs=1)
+def legacy_metainfo(package):
+    from nomad.metainfo.legacy import convert, generate_metainfo_code
+
+    env = convert(package)
+    generate_metainfo_code(env)
diff --git a/nomad/cli/parse.py b/nomad/cli/parse.py
index e1b7e2206fab9e240ab3ce8f07de25f0736e3cc6..a1433f11950e4ff434dc4e05d59ce6058b29b2fa 100644
--- a/nomad/cli/parse.py
+++ b/nomad/cli/parse.py
@@ -119,6 +119,11 @@ def _parse(
     if metainfo:
 
         def backend_factory(env, logger):
+            # from vaspparser.metainfo import m_env
+            # from nomad.metainfo import Section
+            # m_env.resolve_definition('section_basis_set_atom_centered', Section)
+            # return MetainfoBackend(m_env, logger=logger)
+
             return MetainfoBackend(convert(env), logger=logger)
 
         kwargs.update(backend_factory=backend_factory)
diff --git a/nomad/datamodel/metainfo/__init__.py b/nomad/datamodel/metainfo/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..ca3964e9949df137a0beafd4034c74e304c4c2bf
--- /dev/null
+++ b/nomad/datamodel/metainfo/__init__.py
@@ -0,0 +1,11 @@
+import sys
+from nomad.metainfo import Environment
+from nomad.metainfo.legacy import LegacyMetainfoEnvironment
+import nomad.datamodel.metainfo.common
+import nomad.datamodel.metainfo.public
+import nomad.datamodel.metainfo.general
+
+m_env = LegacyMetainfoEnvironment()
+m_env.m_add_sub_section(Environment.packages, sys.modules['nomad.datamodel.metainfo.common'].m_package)  # type: ignore
+m_env.m_add_sub_section(Environment.packages, sys.modules['nomad.datamodel.metainfo.public'].m_package)  # type: ignore
+m_env.m_add_sub_section(Environment.packages, sys.modules['nomad.datamodel.metainfo.general'].m_package)  # type: ignore
diff --git a/nomad/datamodel/metainfo/common.py b/nomad/datamodel/metainfo/common.py
new file mode 100644
index 0000000000000000000000000000000000000000..c01bbe1758f6eee2d12fedc9685780de1df59fca
--- /dev/null
+++ b/nomad/datamodel/metainfo/common.py
@@ -0,0 +1,1190 @@
+import numpy as np            # pylint: disable=unused-import
+import typing                 # pylint: disable=unused-import
+from nomad.metainfo import (  # pylint: disable=unused-import
+    MSection, MCategory, Category, Package, Quantity, Section, SubSection, SectionProxy,
+    Reference
+)
+
+from nomad.datamodel.metainfo import public
+
+m_package = Package(name='common', description='None')
+
+
+class settings_atom_in_molecule(MCategory):
+    '''
+    Parameters of an atom within a molecule.
+    '''
+
+
+class settings_constraint(MCategory):
+    '''
+    Some parameters that describe a constraint
+    '''
+
+
+class settings_interaction(MCategory):
+    '''
+    Some parameters that describe a bonded interaction.
+    '''
+
+
+class soap_parameter(MCategory):
+    '''
+    A soap parameter
+    '''
+
+
+class response_context(MSection):
+    '''
+    The top level context containing the reponse to an api query, when using jsonAPI they
+    are tipically in the meta part
+    '''
+
+    m_def = Section(validate=False)
+
+    shortened_meta_info = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        A meta info whose corresponding data has been shortened
+        ''')
+
+    section_response_message = SubSection(
+        sub_section=SectionProxy('section_response_message'),
+        repeats=True)
+
+
+class section_atom_type(MSection):
+    '''
+    Section describing a type of atom in the system.
+    '''
+
+    m_def = Section(validate=False)
+
+    atom_type_charge = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='coulomb',
+        description='''
+        Charge of the atom type.
+        ''')
+
+    atom_type_mass = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='kilogram',
+        description='''
+        Mass of the atom type.
+        ''')
+
+    atom_type_name = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Name (label) of the atom type.
+        ''')
+
+
+class section_constraint(MSection):
+    '''
+    Section describing a constraint between arbitrary atoms.
+    '''
+
+    m_def = Section(validate=False)
+
+    constraint_atoms = Quantity(
+        type=np.dtype(np.int32),
+        shape=['number_of_constraints', 'number_of_atoms_per_constraint'],
+        description='''
+        List of the indexes involved in this constraint. The fist atom has index 1, the
+        last number_of_topology_atoms.
+        ''')
+
+    constraint_kind = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Short and unique name for this constraint type. Valid names are described in the
+        [constraint\\_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-
+        info/wikis/metainfo/constraint-kind).
+        ''')
+
+    constraint_parameters = Quantity(
+        type=typing.Any,
+        shape=[],
+        description='''
+        Explicit constraint parameters for this kind of constraint (depending on the
+        constraint type, some might be given implicitly through other means).
+        ''')
+
+    number_of_atoms_per_constraint = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Number of atoms involved in this constraint.
+        ''')
+
+    number_of_constraints = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Number of constraints of this type.
+        ''')
+
+
+class section_dft_plus_u_orbital(MSection):
+    '''
+    Section for DFT+U-settings of a single orbital
+    '''
+
+    m_def = Section(validate=False)
+
+    dft_plus_u_orbital_atom = Quantity(
+        type=np.dtype(np.int32),
+        shape=[],
+        description='''
+        DFT+U-orbital setting: atom index (references index of atom_labels/atom_positions)
+        ''')
+
+    dft_plus_u_orbital_J = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        description='''
+        DFT+U-orbital setting: value J (exchange interaction)
+        ''',
+        categories=[public.energy_value])
+
+    dft_plus_u_orbital_label = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        DFT+U-orbital setting: orbital label (normally (n,l)), notation: '3d', '4f', ...
+        ''')
+
+    dft_plus_u_orbital_U_effective = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        description='''
+        DFT+U-orbital setting: value U_{effective} (U-J), if implementation uses it
+        ''',
+        categories=[public.energy_value])
+
+    dft_plus_u_orbital_U = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        description='''
+        DFT+U-orbital setting: value U (on-site Coulomb interaction)
+        ''',
+        categories=[public.energy_value])
+
+
+class section_excited_states(MSection):
+    '''
+    Excited states properties.
+    '''
+
+    m_def = Section(validate=False)
+
+    excitation_energies = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_excited_states'],
+        description='''
+        Excitation energies.
+        ''',
+        categories=[public.energy_value])
+
+    number_of_excited_states = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Number of excited states.
+        ''')
+
+    oscillator_strengths = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_excited_states'],
+        description='''
+        Excited states oscillator strengths.
+        ''')
+
+    transition_dipole_moments = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_excited_states', 3],
+        description='''
+        Transition dipole moments.
+        ''')
+
+
+class section_interaction(MSection):
+    '''
+    Section containing the description of a bonded interaction between arbitrary atoms.
+    '''
+
+    m_def = Section(validate=False)
+
+    interaction_atoms = Quantity(
+        type=np.dtype(np.int32),
+        shape=['number_of_interactions', 'number_of_atoms_per_interaction'],
+        description='''
+        List of the indexes involved in this interaction. The fist atom has index 1, the
+        last atom index number_of_topology_atoms.
+        ''')
+
+    interaction_kind = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Short and unique name for this interaction type. Valid names are described in the
+        [interaction\\_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-
+        info/wikis/metainfo/interaction-kind).
+        ''')
+
+    interaction_parameters = Quantity(
+        type=typing.Any,
+        shape=[],
+        description='''
+        Explicit interaction parameters for this kind of interaction (depending on the
+        interaction_kind some might be given implicitly through other means).
+        ''')
+
+    number_of_atoms_per_interaction = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Number of atoms involved in this interaction.
+        ''')
+
+    number_of_interactions = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Number of interactions of this type.
+        ''')
+
+
+class section_method_basis_set(MSection):
+    '''
+    This section contains the definition of the basis sets that are defined independently
+    of the atomic configuration.
+    '''
+
+    m_def = Section(validate=False)
+
+    mapping_section_method_basis_set_atom_centered = Quantity(
+        type=np.dtype(np.int64),
+        shape=['number_of_basis_sets_atom_centered', 2],
+        description='''
+        Reference to an atom-centered basis set defined in section_basis_set_atom_centered
+        and to the atom kind as defined in section_method_atom_kind.
+        ''')
+
+    mapping_section_method_basis_set_cell_associated = Quantity(
+        type=public.section_basis_set_cell_dependent,
+        shape=[],
+        description='''
+        Reference to a cell-associated basis set.
+        ''')
+
+    method_basis_set_kind = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        String describing the use of the basis set, i.e, if it used for expanding a
+        wavefunction or an electron density. Allowed values are listed in the
+        [basis\\_set\\_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-
+        info/wikis/metainfo/basis-set-kind).
+        ''')
+
+    number_of_basis_sets_atom_centered = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        String describing the use of the basis set, i.e, if it used for expanding a
+        wavefunction or an electron density. Allowed values are listed in the
+        [basis\\_set\\_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-
+        info/wikis/metainfo/basis-set-kind).
+        ''')
+
+
+class section_molecule_constraint(MSection):
+    '''
+    Section describing a constraint between atoms within a molecule.
+    '''
+
+    m_def = Section(validate=False)
+
+    molecule_constraint_atoms = Quantity(
+        type=np.dtype(np.int32),
+        shape=['number_of_molecule_constraints', 'number_of_atoms_per_molecule_constraint'],
+        description='''
+        List of the indexes involved in this constraint. The fist atom has index 1, the
+        last index is number_of_atoms_in_molecule.
+        ''')
+
+    molecule_constraint_kind = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Short and unique name for this constraint type. Valid names are described in the
+        [constraint\\_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-
+        info/wikis/metainfo/constraint-kind).
+        ''')
+
+    molecule_constraint_parameters = Quantity(
+        type=typing.Any,
+        shape=[],
+        description='''
+        Explicit constraint parameters for this kind of constraint (depending on the
+        constraint type some might be given implicitly through other means).
+        ''')
+
+    number_of_atoms_per_molecule_constraint = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Number of atoms, in this molecule, involved in this constraint.
+        ''')
+
+    number_of_molecule_constraints = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Number of constraints of this type.
+        ''')
+
+
+class section_molecule_interaction(MSection):
+    '''
+    Section describing a bonded interaction between atoms within a molecule.
+    '''
+
+    m_def = Section(validate=False)
+
+    molecule_interaction_atoms = Quantity(
+        type=np.dtype(np.int32),
+        shape=['number_of_molecule_interactions', 'number_of_atoms_per_molecule_interaction'],
+        description='''
+        List of the indexes involved in this bonded interaction within a molecule. The
+        first atom has index 1, the last index is number_of_atoms_in_.
+        ''')
+
+    molecule_interaction_kind = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Short and unique name for this interaction type, used for bonded interactions for
+        atoms in a molecule. Valid names are described in the [interaction\\_kind wiki
+        page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-
+        info/wikis/metainfo/interaction-kind).
+        ''')
+
+    molecule_interaction_parameters = Quantity(
+        type=typing.Any,
+        shape=[],
+        description='''
+        Explicit interaction parameters for this kind of interaction (depending on the
+        interaction type some might be given implicitly through other means), used for
+        bonded interactions for atoms in a molecule.
+        ''')
+
+    number_of_atoms_per_molecule_interaction = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Number of atoms, in this molecule, involved in this interaction.
+        ''')
+
+    number_of_molecule_interactions = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Number of bonded interactions of this type.
+        ''')
+
+
+class section_molecule_type(MSection):
+    '''
+    Section describing a type of molecule in the system.
+    '''
+
+    m_def = Section(validate=False)
+
+    atom_in_molecule_charge = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_atoms_in_molecule'],
+        unit='coulomb',
+        description='''
+        Charge of each atom in the molecule.
+        ''',
+        categories=[settings_atom_in_molecule])
+
+    atom_in_molecule_name = Quantity(
+        type=str,
+        shape=['number_of_atoms_in_molecule'],
+        description='''
+        Name (label) of each atom in the molecule.
+        ''',
+        categories=[settings_atom_in_molecule])
+
+    atom_in_molecule_to_atom_type_ref = Quantity(
+        type=Reference(SectionProxy('section_atom_type')),
+        shape=['number_of_atoms_in_molecule'],
+        description='''
+        Reference to the atom type of each atom in the molecule.
+        ''',
+        categories=[settings_atom_in_molecule])
+
+    molecule_type_name = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Name of the molecule.
+        ''')
+
+    number_of_atoms_in_molecule = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Number of atoms in this molecule.
+        ''')
+
+    section_molecule_constraint = SubSection(
+        sub_section=SectionProxy('section_molecule_constraint'),
+        repeats=True)
+
+    section_molecule_interaction = SubSection(
+        sub_section=SectionProxy('section_molecule_interaction'),
+        repeats=True)
+
+
+class section_response_message(MSection):
+    '''
+    Messages outputted by the program formatting the data in the current response
+    '''
+
+    m_def = Section(validate=False)
+
+    response_message_count = Quantity(
+        type=np.dtype(np.int32),
+        shape=[],
+        description='''
+        How many times this message was repeated
+        ''')
+
+    response_message_level = Quantity(
+        type=np.dtype(np.int32),
+        shape=[],
+        description='''
+        level of the message: 0 fatal, 1 error, 2 warning, 3 debug
+        ''')
+
+    response_message = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Message outputted by the program formatting the data in the current format
+        ''')
+
+
+class section_soap_coefficients(MSection):
+    '''
+    Stores the soap coefficients for the pair of atoms given in
+    soap_coefficients_atom_pair.
+    '''
+
+    m_def = Section(validate=False)
+
+    number_of_soap_coefficients = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        number of soap coefficients
+        ''')
+
+    soap_coefficients_atom_pair = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Pair of atoms described in the current section
+        ''')
+
+    soap_coefficients = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_soap_coefficients'],
+        description='''
+        Compressed coefficient of the soap descriptor for the atom pair
+        soap_coefficients_atom_pair
+        ''')
+
+
+class section_soap(MSection):
+    '''
+    Stores a soap descriptor for this configuration.
+    '''
+
+    m_def = Section(validate=False)
+
+    soap_angular_basis_L = Quantity(
+        type=np.dtype(np.int32),
+        shape=[],
+        description='''
+        angular basis L
+        ''',
+        categories=[soap_parameter])
+
+    soap_angular_basis_type = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        angular basis type
+        ''',
+        categories=[soap_parameter])
+
+    soap_kernel_adaptor = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        kernel adaptor
+        ''',
+        categories=[soap_parameter])
+
+    soap_parameters_gid = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Unique checksum of all the soap parameters (all those with abstract type
+        soap_parameter) with prefix psoap
+        ''')
+
+    soap_radial_basis_integration_steps = Quantity(
+        type=np.dtype(np.int32),
+        shape=[],
+        description='''
+        radial basis integration steps
+        ''',
+        categories=[soap_parameter])
+
+    soap_radial_basis_mode = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        radial basis mode
+        ''',
+        categories=[soap_parameter])
+
+    soap_radial_basis_n = Quantity(
+        type=np.dtype(np.int32),
+        shape=[],
+        description='''
+        radial basis N
+        ''',
+        categories=[soap_parameter])
+
+    soap_radial_basis_sigma = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        description='''
+        radial basis sigma
+        ''',
+        categories=[soap_parameter])
+
+    soap_radial_basis_type = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        radial basis type
+        ''',
+        categories=[soap_parameter])
+
+    soap_radial_cutoff_center_weight = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        description='''
+        radial cutoff center weight
+        ''',
+        categories=[soap_parameter])
+
+    soap_radial_cutoff_rc_width = Quantity(
+        type=np.dtype(np.int32),
+        shape=[],
+        description='''
+        radial cutoff width
+        ''',
+        categories=[soap_parameter])
+
+    soap_radial_cutoff_rc = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        description='''
+        radial cutoff
+        ''',
+        categories=[soap_parameter])
+
+    soap_radial_cutoff_type = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        radial cutoff type
+        ''',
+        categories=[soap_parameter])
+
+    soap_spectrum_2l1_norm = Quantity(
+        type=bool,
+        shape=[],
+        description='''
+        2l1 norm spectrum
+        ''',
+        categories=[soap_parameter])
+
+    soap_spectrum_global = Quantity(
+        type=bool,
+        shape=[],
+        description='''
+        global spectrum
+        ''',
+        categories=[soap_parameter])
+
+    soap_spectrum_gradients = Quantity(
+        type=bool,
+        shape=[],
+        description='''
+        gradients in specturm
+        ''',
+        categories=[soap_parameter])
+
+    soap_type_list = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Type list
+        ''',
+        categories=[soap_parameter])
+
+    section_soap_coefficients = SubSection(
+        sub_section=SectionProxy('section_soap_coefficients'),
+        repeats=True)
+
+
+class section_topology(MSection):
+    '''
+    Section containing the definition of topology (connectivity among atoms in force
+    fileds), force field, and constraints of a system.
+    '''
+
+    m_def = Section(validate=False)
+
+    atom_to_molecule = Quantity(
+        type=np.dtype(np.int32),
+        shape=['number_of_topology_atoms', 2],
+        description='''
+        Table mapping atom to molecules: the first column is the index of the molecule and
+        the second column the index of the atom, signifying that the atom in the second
+        column belongs to the molecule in the first column in the same row.
+        ''')
+
+    molecule_to_molecule_type_map = Quantity(
+        type=Reference(SectionProxy('section_molecule_type')),
+        shape=['number_of_topology_molecules'],
+        description='''
+        Mapping from molecules to molecule types.
+        ''')
+
+    number_of_topology_atoms = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Number of atoms in the system described by this topology.
+        ''')
+
+    number_of_topology_molecules = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Number of molecules in the system, as described by this topology.
+        ''')
+
+    topology_force_field_name = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        A unique string idenfiying the force field defined in this section. Strategies to
+        define it are discussed in the
+        [topology\\_force\\_field\\_name](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-
+        info/wikis/metainfo/topology-force-field-name).
+        ''')
+
+    section_atom_type = SubSection(
+        sub_section=SectionProxy('section_atom_type'),
+        repeats=True)
+
+    section_constraint = SubSection(
+        sub_section=SectionProxy('section_constraint'),
+        repeats=True)
+
+    section_interaction = SubSection(
+        sub_section=SectionProxy('section_interaction'),
+        repeats=True)
+
+    section_molecule_type = SubSection(
+        sub_section=SectionProxy('section_molecule_type'),
+        repeats=True)
+
+
+class section_method(public.section_method):
+
+    m_def = Section(validate=False, extends_base_section=True)
+
+    dft_plus_u_functional = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Type of DFT+U functional (such as DFT/DFT+U double-counting compensation). Valid
+        names are described in the [dft\\_plus\\_u\\_functional wiki
+        page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/dft-
+        plus-u-functional).
+        ''')
+
+    dft_plus_u_projection_type = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        DFT+U: Type of orbitals used for projection in order to calculate occupation
+        numbers. Valid names are described in the [dft\\_plus\\_u\\_projection\\_type wiki
+        page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/dft-
+        plus-u-projection-type).
+        ''')
+
+    gw_bare_coulomb_cutofftype = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Cutoff type for the calculation of the bare Coulomb potential: none, 0d, 1d, 2d.
+        See Rozzi et al., PRB 73, 205119 (2006)
+        ''')
+
+    gw_bare_coulomb_gmax = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='1 / meter',
+        description='''
+        Maximum G for the pw basis for the Coulomb potential.
+        ''')
+
+    gw_basis_set = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Auxillary basis set used for non-local operators: mixed - mixed basis set, Kotani
+        and Schilfgaarde, Solid State Comm. 121, 461 (2002).
+        ''')
+
+    gw_core_treatment = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        It specifies whether the core states are treated in the GW calculation: all - All
+        electron calculation; val - Valence electron only calculation; vab - Core
+        electrons are excluded from the mixed product basis; xal - All electron treatment
+        of the exchange self-energy only
+        ''')
+
+    gw_frequency_grid_type = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Frequency integration grid type for the correlational self energy: 'eqdis' -
+        equidistant frequencies from 0 to freqmax; 'gaulag' - Gauss-Laguerre quadrature
+        from 0 to infinity; 'gauleg' - Gauss-Legendre quadrature from 0 to freqmax;
+        'gaule2' (default) - double Gauss-Legendre quadrature from 0 to freqmax and from
+        freqmax to infinity.
+        ''')
+
+    gw_max_frequency = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        description='''
+        Maximum frequency for the calculation of the self energy.
+        ''')
+
+    gw_mixed_basis_gmax = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='1 / meter',
+        description='''
+        Cut-off parameter for the truncation of the expansion of the plane waves in the
+        interstitial region.
+        ''')
+
+    gw_mixed_basis_lmax = Quantity(
+        type=np.dtype(np.int32),
+        shape=[],
+        description='''
+        Maximum l value used for the radial functions within the muffin-tin.
+        ''')
+
+    gw_mixed_basis_tolerance = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        description='''
+        Eigenvalue threshold below which the egenvectors are discarded in the construction
+        of the radial basis set.
+        ''')
+
+    gw_ngridq = Quantity(
+        type=np.dtype(np.int32),
+        shape=[3],
+        description='''
+        k/q-point grid size used in the GW calculation.
+        ''')
+
+    gw_frequency_number = Quantity(
+        type=np.dtype(np.int32),
+        shape=[],
+        description='''
+        Number referring to the frequency used in the calculation of the self energy.
+        ''')
+
+    gw_frequency_values = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Values of the frequency used in the calculation of the self energy.
+        ''')
+
+    gw_frequency_weights = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        description='''
+        Weights of the frequency used in the calculation of the self energy.
+        ''')
+
+    gw_number_of_frequencies = Quantity(
+        type=np.dtype(np.int32),
+        shape=[],
+        description='''
+        Number of frequency points used in the calculation of the self energy.
+        ''')
+
+    gw_polarizability_number_of_empty_states = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Number of empty states used to compute the polarizability P
+        ''')
+
+    gw_qp_equation_treatment = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Methods to solve the quasi-particle equation: 'linearization', 'self-consistent'
+        ''')
+
+    gw_screened_coulomb_volume_average = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Type of volume averaging for the dynamically screened Coulomb potential: isotropic
+        - Simple averaging along a specified direction using only diagonal components of
+        the dielectric tensor; anisotropic - Anisotropic screening by C. Freysoldt et al.,
+        CPC 176, 1-13 (2007)
+        ''')
+
+    gw_screened_Coulomb = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Model used to calculate the dinamically-screened Coulomb potential: 'rpa' - Full-
+        frequency random-phase approximation; 'ppm' - Godby-Needs plasmon-pole model Godby
+        and Needs, Phys. Rev. Lett. 62, 1169 (1989); 'ppm_hl' - Hybertsen and Louie, Phys.
+        Rev. B 34, 5390 (1986); 'ppm_lh' - von der Linden and P. Horsh, Phys. Rev. B 37,
+        8351 (1988); 'ppm_fe' - Farid and Engel, Phys. Rev. B 47,15931 (1993); 'cdm' -
+        Contour deformation method, Phys. Rev. B 67, 155208 (2003).)
+        ''')
+
+    gw_self_energy_c_analytical_continuation = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Models for the correlation self-energy analytical continuation: 'pade' -  Pade's
+        approximant (by H. J. Vidberg and J. W. Serence, J. Low Temp. Phys. 29, 179
+        (1977)); 'mpf' -  Multi-Pole Fitting (by H. N Rojas, R. W. Godby and R. J. Needs,
+        Phys. Rev. Lett. 74, 1827 (1995)); 'cd' - contour deformation; 'ra' - real axis
+        ''')
+
+    gw_self_energy_c_number_of_empty_states = Quantity(
+        type=np.dtype(np.int32),
+        shape=[],
+        description='''
+        Number of empty states to be used to calculate the correlation self energy.
+        ''')
+
+    gw_self_energy_c_number_of_poles = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Number of poles used in the analytical continuation.
+        ''')
+
+    gw_self_energy_singularity_treatment = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Treatment of the integrable singular terms in the calculation of the self energy.
+        Values: 'mpb' - Auxiliary function method by S. Massidda, M. Posternak, and A.
+        Baldereschi, PRB 48, 5058 (1993); 'crg' - Auxiliary function method by P. Carrier,
+        S. Rohra, and A. Goerling, PRB 75, 205126 (2007).
+        ''')
+
+    gw_starting_point = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Exchange-correlation functional of the ground-state calculation. See XC_functional
+        list at https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/XC-
+        functional
+        ''')
+
+    gw_type_test = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        GW methodology: exciting test variable
+        ''')
+
+    gw_type = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        GW methodology: G0W0; ev-scGW: (eigenvalues self-consistent GW) – Phys.Rev.B 34,
+        5390 (1986); qp-scGW: (quasi-particle self-consistent GW) – Phys. Rev. Lett. 96,
+        226402 (2006)  scGW0: (self-consistent G with fixed W0) – Phys.Rev.B 54, 8411
+        (1996); scG0W: (self-consistent W with fixed G0); scGW: (self-consistent GW) –
+        Phys. Rev. B 88, 075105 (2013)
+        ''')
+
+    method_to_topology_ref = Quantity(
+        type=Reference(SectionProxy('section_topology')),
+        shape=[],
+        description='''
+        Reference to the topology and force fields to be used.
+        ''')
+
+    section_dft_plus_u_orbital = SubSection(
+        sub_section=SectionProxy('section_dft_plus_u_orbital'),
+        repeats=True)
+
+    section_method_basis_set = SubSection(
+        sub_section=SectionProxy('section_method_basis_set'),
+        repeats=True)
+
+
+class section_single_configuration_calculation(public.section_single_configuration_calculation):
+
+    m_def = Section(validate=False, extends_base_section=True)
+
+    energy_C_mGGA = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Component of the correlation (C) energy at the GGA (or MetaGGA) level using the
+        self-consistent density of the target XC functional (full unscaled value, i.e.,
+        not scaled due to exact-exchange mixing).
+        ''',
+        categories=[public.energy_value, public.energy_type_C, public.energy_component])
+
+    energy_reference_fermi = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_spin_channels'],
+        unit='joule',
+        description='''
+        Fermi energy (separates occupied from unoccupied single-particle states in metals)
+        ''',
+        categories=[public.energy_type_reference, public.energy_value])
+
+    energy_reference_highest_occupied = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_spin_channels'],
+        unit='joule',
+        description='''
+        Highest occupied single-particle state energy (in insulators or HOMO energy in
+        finite systems)
+        ''',
+        categories=[public.energy_type_reference, public.energy_value])
+
+    energy_reference_lowest_unoccupied = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_spin_channels'],
+        unit='joule',
+        description='''
+        Lowest unoccupied single-particle state energy (in insulators or LUMO energy in
+        finite systems)
+        ''',
+        categories=[public.energy_type_reference, public.energy_value])
+
+    energy_X_mGGA_scaled = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Component of the exchange (X) energy at the GGA (or MetaGGA) level, using the self
+        consistent density of the target functional, scaled accordingly to the mixing
+        parameter.
+        ''',
+        categories=[public.energy_value, public.energy_component])
+
+    energy_X_mGGA = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Component of the exchange (X) energy at the GGA (or MetaGGA) level using the self
+        consistent density of the target functional (full unscaled value, i.e., not scaled
+        due to exact-exchange mixing).
+        ''',
+        categories=[public.energy_type_X, public.energy_value, public.energy_component])
+
+    gw_fermi_energy = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        GW Fermi energy
+        ''')
+
+    gw_fundamental_gap = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        GW fundamental band gap
+        ''')
+
+    gw_optical_gap = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        GW optical band gap
+        ''')
+
+    gw_self_energy_c = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_spin_channels', 'number_of_eigenvalues_kpoints', 'number_of_eigenvalues'],
+        unit='joule',
+        description='''
+        Diagonal matrix elements of the correlation self-energy
+        ''')
+
+    gw_self_energy_x = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_spin_channels', 'number_of_eigenvalues_kpoints', 'number_of_eigenvalues'],
+        unit='joule',
+        description='''
+        Diagonal matrix elements of the exchange self-energy
+        ''')
+
+    gw_xc_potential = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_spin_channels', 'number_of_eigenvalues_kpoints', 'number_of_eigenvalues'],
+        unit='joule',
+        description='''
+        Diagonal matrix elements of the exchange-correlation potential
+        ''')
+
+    section_excited_states = SubSection(
+        sub_section=SectionProxy('section_excited_states'),
+        repeats=True)
+
+
+class section_scf_iteration(public.section_scf_iteration):
+
+    m_def = Section(validate=False, extends_base_section=True)
+
+    energy_reference_fermi_iteration = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_spin_channels'],
+        unit='joule',
+        description='''
+        Fermi energy (separates occupied from unoccupied single-particle states in metals)
+        during the self-consistent field (SCF) iterations.
+        ''',
+        categories=[public.energy_type_reference, public.energy_value])
+
+    energy_reference_highest_occupied_iteration = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_spin_channels'],
+        unit='joule',
+        description='''
+        Highest occupied single-particle state energy (in insulators or HOMO energy in
+        finite systems) during the self-consistent field (SCF) iterations.
+        ''',
+        categories=[public.energy_type_reference, public.energy_value])
+
+    energy_reference_lowest_unoccupied_iteration = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_spin_channels'],
+        unit='joule',
+        description='''
+        Lowest unoccupied single-particle state energy (in insulators or LUMO energy in
+        finite systems) during the self-consistent field (SCF) iterations.
+        ''',
+        categories=[public.energy_type_reference, public.energy_value])
+
+
+class section_eigenvalues(public.section_eigenvalues):
+
+    m_def = Section(validate=False, extends_base_section=True)
+
+    gw_qp_linearization_prefactor = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_spin_channels', 'number_of_eigenvalues_kpoints', 'number_of_eigenvalues'],
+        description='''
+        Linearization prefactor
+        ''')
+
+
+class section_system(public.section_system):
+
+    m_def = Section(validate=False, extends_base_section=True)
+
+    number_of_electrons = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_spin_channels'],
+        description='''
+        Number of electrons in system
+        ''',
+        categories=[public.configuration_core])
+
+    topology_ref = Quantity(
+        type=Reference(SectionProxy('section_topology')),
+        shape=[],
+        description='''
+        Reference to the topology used for this system; if not given, the trivial topology
+        should be assumed.
+        ''')
+
+    is_representative = Quantity(
+        type=bool,
+        shape=[],
+        description='''
+        Most systems in a run are only minor variations of each other. Systems marked
+        representative where chosen to be representative for all systems in the run.
+        ''')
+
+    section_soap = SubSection(
+        sub_section=SectionProxy('section_soap'),
+        repeats=True)
+
+
+class section_run(public.section_run):
+
+    m_def = Section(validate=False, extends_base_section=True)
+
+    section_topology = SubSection(
+        sub_section=SectionProxy('section_topology'),
+        repeats=True)
+
+
+m_package.__init_metainfo__()
diff --git a/nomad/datamodel/metainfo/general.py b/nomad/datamodel/metainfo/general.py
new file mode 100644
index 0000000000000000000000000000000000000000..bbb8dda361553f4485dace53b8c67d1e60fce48d
--- /dev/null
+++ b/nomad/datamodel/metainfo/general.py
@@ -0,0 +1,141 @@
+import numpy as np            # pylint: disable=unused-import
+import typing                 # pylint: disable=unused-import
+from nomad.metainfo import (  # pylint: disable=unused-import
+    MSection, MCategory, Category, Package, Quantity, Section, SubSection, SectionProxy,
+    Reference
+)
+
+
+m_package = Package(name='general', description='None')
+
+
+class section_entry_info(MSection):
+    '''
+    General information about this entry that is independent from its domain, field, or
+    used parser
+    '''
+
+    m_def = Section(validate=False)
+
+    entry_upload_time = Quantity(
+        type=np.dtype(np.int64),
+        shape=[],
+        description='''
+        Upload datetime, given as total number of seconds is the elapsed since the unix
+        epoch (1 January 1970)
+        ''')
+
+    entry_uploader_name = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Name of the uploader, given as lastname, firstname.
+        ''')
+
+    entry_uploader_id = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        The id of the uploader.
+        ''')
+
+    upload_id = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Nomad upload id
+        ''')
+
+    calc_id = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Nomad calc id.
+        ''')
+
+    calc_hash = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Calculation hash based on raw file contents.
+        ''')
+
+    mainfile = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Path to the main file within the upload.
+        ''')
+
+    parser_name = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Name of the parser used to extract this information.
+        ''')
+
+    filepaths = Quantity(
+        type=str,
+        shape=['number_of_files'],
+        description='''
+        Filepaths of files that belong to this entry, i.e. files in the same directory.
+        Filepaths are relative to the upload.
+        ''')
+
+    number_of_files = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Number of files that belong to this entry.
+        ''')
+
+    section_archive_processing_info = SubSection(
+        sub_section=SectionProxy('section_archive_processing_info'),
+        repeats=True)
+
+
+class section_archive_processing_info(MSection):
+    '''
+    Information about the used archive processing steps and their execution.
+    '''
+
+    m_def = Section(validate=False)
+
+    archive_processor_name = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Name of the applied archive processing program.
+        ''')
+
+    archive_processor_error = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        The main error during execution of the archive processing program that failed the
+        program.
+        ''')
+
+    number_of_archive_processor_warnings = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Number of warnings during execution of the archive processing program.
+        ''')
+
+    archive_processor_warnings = Quantity(
+        type=str,
+        shape=['number_of_archive_processor_warnings'],
+        description='''
+        Warnings during execution of the archive processing program.
+        ''')
+
+    archive_processor_status = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Status returned by archive processing program.
+        ''')
+
+
+m_package.__init_metainfo__()
diff --git a/nomad/datamodel/metainfo/public.py b/nomad/datamodel/metainfo/public.py
new file mode 100644
index 0000000000000000000000000000000000000000..f58404cf1c9eceb0fc437594df2741e861454fc6
--- /dev/null
+++ b/nomad/datamodel/metainfo/public.py
@@ -0,0 +1,4747 @@
+import numpy as np            # pylint: disable=unused-import
+import typing                 # pylint: disable=unused-import
+from nomad.metainfo import (  # pylint: disable=unused-import
+    MSection, MCategory, Category, Package, Quantity, Section, SubSection, SectionProxy,
+    Reference
+)
+
+
+m_package = Package(name='public', description='None')
+
+
+class accessory_info(MCategory):
+    '''
+    Information that *in theory* should not affect the results of the calculations (e.g.,
+    timing).
+    '''
+
+
+class atom_forces_type(MCategory):
+    '''
+    The types of forces acting on the atoms (i.e., minus derivatives of the specific type
+    of energy with respect to the atom position).
+    '''
+
+
+class basis_set_description(MCategory):
+    '''
+    One of the parts building the basis set of the system (e.g., some atom-centered basis
+    set, plane-waves or both).
+    '''
+
+
+class configuration_core(MCategory):
+    '''
+    Properties defining the current configuration.
+    '''
+
+
+class conserved_quantity(MCategory):
+    '''
+    A quantity that is preserved during the time propagation (for example,
+    kinetic+potential energy during NVE).
+    '''
+
+
+class energy_component_per_atom(MCategory):
+    '''
+    A value of an energy component per atom, concurring in defining the total energy per
+    atom.
+    '''
+
+
+class energy_component(MCategory):
+    '''
+    A value of an energy component, expected to be an extensive property.
+    '''
+
+
+class energy_total_potential_per_atom(MCategory):
+    '''
+    A value of the total potential energy per atom. Note that a direct comparison may not
+    be possible because of a difference in the methods for computing total energies and
+    numerical implementations of various codes might leads to different energy zeros (see
+    section_energy_code_independent for a code-independent definition of the energy).
+    '''
+
+
+class energy_total_potential(MCategory):
+    '''
+    A value of the total potential energy. Note that a direct comparison may not be
+    possible because of a difference in the methods for computing total energies and
+    numerical implementations of various codes might leads to different energy zeros (see
+    section_energy_code_independent for a code-independent definition of the energy).
+    '''
+
+
+class energy_type_C(MCategory):
+    '''
+    This metadata stores the correlation (C) energy.
+    '''
+
+
+class energy_type_reference(MCategory):
+    '''
+    This metadata stores an energy used as reference point.
+    '''
+
+
+class energy_type_van_der_Waals(MCategory):
+    '''
+    This metadata stores the converged van der Waals energy.
+    '''
+
+
+class energy_type_XC(MCategory):
+    '''
+    This metadata stores the exchange-correlation (XC) energy.
+    '''
+
+
+class energy_type_X(MCategory):
+    '''
+    This metadata stores the exchange (X) energy.
+    '''
+
+
+class energy_value(MCategory):
+    '''
+    This metadata stores an energy value.
+    '''
+
+
+class error_estimate_contribution(MCategory):
+    '''
+    An estimate of a partial quantity contributing to the error for a given quantity.
+    '''
+
+
+class error_estimate(MCategory):
+    '''
+    An estimate of the error on the converged (final) value.
+    '''
+
+
+class message_debug(MCategory):
+    '''
+    A debugging message of the computational program.
+    '''
+
+
+class message_error(MCategory):
+    '''
+    An error message of the computational program.
+    '''
+
+
+class message_info(MCategory):
+    '''
+    An information message of the computational program.
+    '''
+
+
+class message_warning(MCategory):
+    '''
+    A warning message of the computational program.
+    '''
+
+
+class parallelization_info(MCategory):
+    '''
+    Contains information on the parallelization of the program, i.e. which parallel
+    programming language was used and its version, how many cores had been working on the
+    calculation and the flags and parameters needed to run the parallelization of the
+    code.
+    '''
+
+
+class parsing_message_debug(MCategory):
+    '''
+    This field is used for debugging messages of the parsing program.
+    '''
+
+
+class parsing_message_error(MCategory):
+    '''
+    This field is used for error messages of the parsing program.
+    '''
+
+
+class parsing_message_info(MCategory):
+    '''
+    This field is used for info messages of the parsing program.
+    '''
+
+
+class parsing_message_warning(MCategory):
+    '''
+    This field is used for warning messages of the parsing program.
+    '''
+
+
+class program_info(MCategory):
+    '''
+    Contains information on the program that generated the data, i.e. the program_name,
+    program_version, program_compilation_host and program_compilation_datetime as direct
+    children of this field.
+    '''
+
+
+class scf_info(MCategory):
+    '''
+    Contains information on the self-consistent field (SCF) procedure, i.e. the number of
+    SCF iterations (number_of_scf_iterations) or a section_scf_iteration section with
+    detailed information on the SCF procedure of specified quantities.
+    '''
+
+
+class settings_barostat(MCategory):
+    '''
+    Contains parameters controlling the barostat in a molecular dynamics calculation.
+    '''
+
+
+class settings_coupled_cluster(MCategory):
+    '''
+    Contains parameters for the coupled-cluster method (CC) in the post Hartree-Fock step.
+    '''
+
+
+class settings_geometry_optimization(MCategory):
+    '''
+    Contains parameters controlling the geometry optimization.
+    '''
+
+
+class settings_GW(MCategory):
+    '''
+    Contains parameters for the GW-method in the post Hartree-Fock step, that expands the
+    self-energy in terms of the single particle Green's function $G$ and the screened
+    Coulomb interaction $W$.
+    '''
+
+
+class settings_integrator(MCategory):
+    '''
+    Contains parameters that control the molecular dynamics (MD) integrator.
+    '''
+
+
+class settings_k_points(MCategory):
+    '''
+    Contains parameters that control the $k$-point mesh.
+    '''
+
+
+class settings_MCSCF(MCategory):
+    '''
+    Contains parameters for the multi-configurational self-consistent-field (MCSCF)
+    method.
+    '''
+
+
+class settings_metadynamics(MCategory):
+    '''
+    Contains parameters that control the metadynamics sampling.
+    '''
+
+
+class settings_molecular_dynamics(MCategory):
+    '''
+    Contains parameters that control the molecular dynamics sampling.
+    '''
+
+
+class settings_moller_plesset_perturbation_theory(MCategory):
+    '''
+    Contains parameters for Møller–Plesset perturbation theory.
+    '''
+
+
+class settings_Monte_Carlo(MCategory):
+    '''
+    Contains parameters that control the Monte-Carlo sampling.
+    '''
+
+
+class settings_multi_reference(MCategory):
+    '''
+    Contains parameters for the multi-reference single and double configuration
+    interaction method.
+    '''
+
+
+class settings_numerical_parameter(MCategory):
+    '''
+    A parameter that can influence the convergence, but not the physics (unlike
+    settings_physical_parameter)
+    '''
+
+
+class settings_physical_parameter(MCategory):
+    '''
+    A parameter that defines the physical model used. Use settings_numerical_parameter for
+    parameters that that influence only the convergence/accuracy.
+    '''
+
+
+class settings_post_hartree_fock(MCategory):
+    '''
+    Contains parameters for the post Hartree-Fock method.
+    '''
+
+
+class settings_potential_energy_surface(MCategory):
+    '''
+    Contains parameters that control the potential energy surface.
+    '''
+
+
+class settings_relativity(MCategory):
+    '''
+    Contains parameters and information connected with the relativistic treatment used in
+    the calculation.
+    '''
+
+
+class settings_run(MCategory):
+    '''
+    Contains parameters that control the whole run (but not the *single configuration
+    calculation*, see section_single_configuration_calculation).
+    '''
+
+
+class settings_sampling(MCategory):
+    '''
+    Contains parameters controlling the sampling.
+    '''
+
+
+class settings_scf(MCategory):
+    '''
+    Contains parameters connected with the convergence of the self-consistent field (SCF)
+    iterations.
+    '''
+
+
+class settings_self_interaction_correction(MCategory):
+    '''
+    Contains parameters and information connected with the self-interaction correction
+    (SIC) method being used in self_interaction_correction_method.
+    '''
+
+
+class settings_smearing(MCategory):
+    '''
+    Contain parameters that control the smearing of the orbital occupation at finite
+    electronic temperatures.
+    '''
+
+
+class settings_stress_tensor(MCategory):
+    '''
+    Settings to calculate the stress tensor (stress_tensor) consistent with the total
+    energy of the system given in energy_total.
+    '''
+
+
+class settings_thermostat(MCategory):
+    '''
+    Contains parameters that control the thermostat in the molecular dynamics (MD)
+    calculations.
+    '''
+
+
+class settings_van_der_Waals(MCategory):
+    '''
+    Contain parameters and information connected with the Van der Waals treatment used in
+    the calculation to compute the Van der Waals energy (energy_van_der_Waals).
+    '''
+
+
+class settings_XC_functional(MCategory):
+    '''
+    Contain parameters connected with the definition of the exchange-correlation (XC)
+    functional (see section_XC_functionals and XC_functional).
+    '''
+
+
+class settings_XC(MCategory):
+    '''
+    Contains parameters connected with the definition of the exchange-correlation (XC)
+    *method*. Here, the term *method* is a more general concept than just *functionals*
+    and include, e.g., post Hartree-Fock methods, too.
+    '''
+
+
+class stress_tensor_type(MCategory):
+    '''
+    Contains the final value of the default stress tensor (stress_tensor) and/or the value
+    of the stress tensor (stress_tensor_value) of the kind defined in stress_tensor_kind.
+    '''
+
+
+class time_info(MCategory):
+    '''
+    Stores information on the date and timings of the calculation. They are useful for,
+    e.g., debugging or visualization purposes.
+    '''
+
+
+class archive_context(MSection):
+    '''
+    Contains information relating to an archive.
+    '''
+
+    m_def = Section(validate=False)
+
+    archive_gid = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        unique identifier of an archive.
+        ''')
+
+
+class calculation_context(MSection):
+    '''
+    Contains information relating to a calculation.
+    '''
+
+    m_def = Section(validate=False)
+
+    calculation_gid = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        unique identifier of a calculation.
+        ''')
+
+
+class section_atom_projected_dos(MSection):
+    '''
+    Section collecting the information on an atom projected density of states (DOS)
+    evaluation.
+    '''
+
+    m_def = Section(validate=False)
+
+    atom_projected_dos_energies = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_atom_projected_dos_values'],
+        unit='joule',
+        description='''
+        Array containing the set of discrete energy values for the atom-projected density
+        (electronic-energy) of states (DOS).
+        ''')
+
+    atom_projected_dos_lm = Quantity(
+        type=np.dtype(np.int32),
+        shape=['number_of_lm_atom_projected_dos', 2],
+        description='''
+        Tuples of $l$ and $m$ values for which atom_projected_dos_values_lm are given. For
+        the quantum number $l$ the conventional meaning of azimuthal quantum number is
+        always adopted. For the integer number $m$, besides the conventional use as
+        magnetic quantum number ($l+1$ integer values from $-l$ to $l$), a set of
+        different conventions is accepted (see the [m_kind wiki
+        page](https://gitlab.rzg.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/m-kind).
+        The adopted convention is specified by atom_projected_dos_m_kind.
+        ''')
+
+    atom_projected_dos_m_kind = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        String describing what the integer numbers of $m$ in atom_projected_dos_lm mean.
+        The allowed values are listed in the [m_kind wiki
+        page](https://gitlab.rzg.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/m-kind).
+        ''')
+
+    atom_projected_dos_values_lm = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_lm_atom_projected_dos', 'number_of_spin_channels', 'number_of_atoms', 'number_of_atom_projected_dos_values'],
+        description='''
+        Values correspond to the number of states for a given energy (the set of discrete
+        energy values is given in atom_projected_dos_energies) divided into contributions
+        from each $l,m$ channel for the atom-projected density (electronic-energy) of
+        states. Here, there are as many atom-projected DOS as the number_of_atoms, the
+        list of labels of the atoms and their meanings are in atom_labels.
+        ''')
+
+    atom_projected_dos_values_total = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_spin_channels', 'number_of_atoms', 'number_of_atom_projected_dos_values'],
+        description='''
+        Values correspond to the number of states for a given energy (the set of discrete
+        energy values is given in atom_projected_dos_energies) divided into contributions
+        summed up over all $l$ channels for the atom-projected density (electronic-energy)
+        of states (DOS). Here, there are as many atom-projected DOS as the
+        number_of_atoms, the list of labels of the atoms and their meanings are in
+        atom_labels.
+        ''')
+
+    number_of_atom_projected_dos_values = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Gives the number of energy values for the atom-projected density of states (DOS)
+        based on atom_projected_dos_values_lm and atom_projected_dos_values_total.
+        ''')
+
+    number_of_lm_atom_projected_dos = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Gives the number of $l$, $m$ combinations for the atom projected density of states
+        (DOS) defined in section_atom_projected_dos.
+        ''')
+
+
+class section_atomic_multipoles(MSection):
+    '''
+    Section describing multipoles (charges/monopoles, dipoles, quadrupoles, ...) for each
+    atom.
+    '''
+
+    m_def = Section(validate=False)
+
+    atomic_multipole_kind = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        String describing the method used to obtain the electrostatic multipoles
+        (including the electric charge, dipole, etc.) for each atom. Such multipoles
+        require a charge-density partitioning scheme, specified by the value of this
+        metadata. Allowed values are listed in the [atomic_multipole_kind wiki
+        page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/atomic-
+        multipole-kind).
+        ''')
+
+    atomic_multipole_lm = Quantity(
+        type=np.dtype(np.int32),
+        shape=['number_of_lm_atomic_multipoles', 2],
+        description='''
+        Tuples of $l$ and $m$ values for which the atomic multipoles (including the
+        electric charge, dipole, etc.) are given. The method used to obtain the multipoles
+        is specified by atomic_multipole_kind. The meaning of the integer number $l$ is
+        monopole/charge for $l=0$, dipole for $l=1$, quadrupole for $l=2$, etc. The
+        meaning of the integer numbers $m$ is specified by atomic_multipole_m_kind.
+        ''')
+
+    atomic_multipole_m_kind = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        String describing the definition for each integer number $m$ in
+        atomic_multipole_lm. Allowed values are listed in the [m_kind wiki
+        page](https://gitlab.rzg.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/m-kind).
+        ''')
+
+    atomic_multipole_values = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_lm_atomic_multipoles', 'number_of_atoms'],
+        description='''
+        Value of the multipoles (including the monopole/charge for $l$ = 0, the dipole for
+        $l$ = 1, etc.) for each atom, calculated as described in atomic_multipole_kind.
+        ''')
+
+    number_of_lm_atomic_multipoles = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Gives the number of $l$, $m$ combinations for atomic multipoles
+        atomic_multipole_lm.
+        ''')
+
+
+class section_basis_functions_atom_centered(MSection):
+    '''
+    This section contains the description of the basis functions (at least one function)
+    of the (atom-centered) basis set defined in section_basis_set_atom_centered.
+    '''
+
+    m_def = Section(validate=False)
+
+
+class section_basis_set_atom_centered(MSection):
+    '''
+    This section describes the atom-centered basis set. The main contained information is
+    a short, non unique but human-interpretable, name for identifying the basis set
+    (basis_set_atom_centered_short_name), a longer, unique name
+    (basis_set_atom_centered_unique_name), the atomic number of the atomic species the
+    basis set is meant for (basis_set_atom_number), and a list of actual basis functions
+    in the section_basis_functions_atom_centered section.
+    '''
+
+    m_def = Section(validate=False)
+
+    basis_set_atom_centered_ls = Quantity(
+        type=np.dtype(np.int32),
+        shape=['number_of_kinds_in_basis_set_atom_centered'],
+        description='''
+        Azimuthal quantum number ($l$) values (of the angular part given by the spherical
+        harmonic $Y_{lm}$) of the atom-centered basis function defined in the current
+        section_basis_set_atom_centered.
+        ''')
+
+    basis_set_atom_centered_radial_functions = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_kinds_in_basis_set_atom_centered', 401, 5],
+        description='''
+        Values of the radial function of the different basis function kinds. The values
+        are numerically tabulated on a default 0.01-nm equally spaced grid from 0 to 4 nm.
+        The 5 tabulated values are $r$, $f(r)$, $f'(r)$, $f(r) \\cdot r$,
+        $\\frac{d}{dr}(f(r) \\cdot r)$.
+        ''')
+
+    basis_set_atom_centered_short_name = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Code-specific, but explicative, base name for the basis set (not unique). Details
+        are explained in the [basis_set_atom_centered_short_name wiki
+        page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/basis-
+        set-atom-centered-short-name), this name should not contain the *atom kind* (to
+        simplify the use of a single name for multiple elements).
+        ''')
+
+    basis_set_atom_centered_unique_name = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Code-specific, but explicative, base name for the basis set (not unique). This
+        string starts with basis_set_atom_centered_short_name. If the basis set defined in
+        this section_basis_set_atom_centered is not identical to the default definition
+        (stored in a database) of the basis set with the same name stored in a database,
+        then the string is extended by 10 identifiable characters as explained in the
+        [basis_set_atom_centered_name wiki page](https://gitlab.mpcdf.mpg.de/nomad-
+        lab/nomad-meta-info/wikis/metainfo/basis-set-atom-centered-unique-name). The
+        reason for this procedure is that often atom-centered basis sets are obtained by
+        fine tuning basis sets provided by the code developers or other sources. Each
+        basis sets, which has normally a standard name, often reported in publications,
+        has also several parameters that can be tuned. This metadata tries to keep track
+        of the original basis set and its modifications. This string here defined should
+        not contain the *atom kind* for which this basis set is intended for, in order to
+        simplify the use of a single name for multiple *atom kinds* (see atom_labels for
+        the actual meaning of *atom kind*).
+        ''')
+
+    basis_set_atom_number = Quantity(
+        type=np.dtype(np.int32),
+        shape=[],
+        description='''
+        Atomic number (i.e., number of protons) of the atom for which this basis set is
+        constructed (0 means unspecified or a pseudo atom).
+        ''')
+
+    number_of_basis_functions_in_basis_set_atom_centered = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Gives the number of different basis functions in a section_basis_set_atom_centered
+        section. This equals the number of actual coefficients that are specified when
+        using this basis set.
+        ''')
+
+    number_of_kinds_in_basis_set_atom_centered = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Gives the number of different *kinds* of radial basis functions in the
+        section_basis_set_atom_centered section. Specifically, basis functions with the
+        same $n$ and $l$ quantum numbers are grouped in sets. Each set counts as one
+        *kind*.
+        ''')
+
+    section_basis_functions_atom_centered = SubSection(
+        sub_section=SectionProxy('section_basis_functions_atom_centered'),
+        repeats=True)
+
+    section_gaussian_basis_group = SubSection(
+        sub_section=SectionProxy('section_gaussian_basis_group'),
+        repeats=True)
+
+
+class section_basis_set_cell_dependent(MSection):
+    '''
+    Section describing a cell-dependent (atom-independent) basis set, e.g. plane waves.
+    The contained information is the type of basis set (in basis_set_cell_dependent_kind),
+    its parameters (e.g., for plane waves in basis_set_planewave_cutoff), and a name that
+    identifies the actually used basis set (a string combining the type and the
+    parameter(s), stored in basis_set_cell_dependent_name).
+    '''
+
+    m_def = Section(validate=False)
+
+    basis_set_cell_dependent_kind = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        A string defining the type of the cell-dependent basis set (i.e., non atom
+        centered such as plane-waves). Allowed values are listed in the
+        [basis_set_cell_dependent_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-
+        lab/nomad-meta-info/wikis/metainfo/basis-set-cell-dependent-kind).
+        ''')
+
+    basis_set_cell_dependent_name = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        A label identifying the cell-dependent basis set (i.e., non atom centered such as
+        plane-waves). Allowed values are listed in the [basis_set_cell_dependent_name wiki
+        page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/basis-
+        set-cell-dependent-name).
+        ''')
+
+    basis_set_planewave_cutoff = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Spherical cutoff  in reciprocal space for a plane-wave basis set. It is the energy
+        of the highest plan-ewave ($\\frac{\\hbar^2|k+G|^2}{2m_e}$) included in the basis
+        set. Note that normally this basis set is used for the wavefunctions, and the
+        density would have 4 times the cutoff, but this actually depends on the use of the
+        basis set by the method.
+        ''')
+
+
+class section_basis_set(MSection):
+    '''
+    This section contains references to *all* basis sets used in this
+    section_single_configuration_calculation. More than one basis set instance per *single
+    configuration calculation* (see section_single_configuration_calculation) may be
+    needed. This is true for example, for codes that implement adaptive basis sets along
+    the self-consistent field (SCF) convergence (e.g., exciting). In such cases, there is
+    a section_basis_set instance per SCF iteration, if necessary. Another example is
+    having a basis set for wavefunctions, a different one for the density, an auxiliary
+    basis set for resolution of identity (RI), etc.
+
+    Supported are the two broad classes of basis sets: *atom-centered* (e.g., Gaussian-
+    type, numerical atomic orbitals) and *cell-dependent* (like plane waves or real-space
+    grids, so named because they are typically used for periodic-system calculations and
+    dependent to the simulated cell as a whole).
+
+    Basis sets used in this section_single_configuration_calculation, belonging to either
+    class, are defined in the dedicated section: [section_basis_set_cell_dependent
+    ](section_basis_set_cell_dependent) or section_basis_set_atom_centered. The
+    correspondence between the basis sets listed in this section and the definition given
+    in the dedicated sessions is given by the two concrete metadata:
+    mapping_section_basis_set_cell_dependent and mapping_section_basis_set_atom_centered.
+    The latter metadata is a list that connects each atom in the system with its basis
+    set, where the same basis set can be assigned to more than one atom.
+    '''
+
+    m_def = Section(validate=False)
+
+    basis_set_kind = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        String describing the use of the basis set, i.e, if it used for expanding a wave-
+        function or an electron density. Allowed values are listed in the [basis_set_kind
+        wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-
+        info/wikis/metainfo/basis-set-kind).
+        ''')
+
+    basis_set_name = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        String identifying the basis set in an unique way. The rules for building this
+        string are specified in the [basis_set_name wiki
+        page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/basis-
+        set-name).
+        ''')
+
+    mapping_section_basis_set_atom_centered = Quantity(
+        type=Reference(SectionProxy('section_basis_set_atom_centered')),
+        shape=['number_of_atoms'],
+        description='''
+        An array of the dimension of number_of_atoms where each atom (identified by the
+        index in the array) is assigned to an atom-centered basis set, for this
+        section_single_configuration_calculation. The actual definition of the atom-
+        centered basis set is in the section_basis_set_atom_centered that is referred to
+        by this metadata.
+        ''')
+
+    mapping_section_basis_set_cell_dependent = Quantity(
+        type=Reference(SectionProxy('section_basis_set_cell_dependent')),
+        shape=[],
+        description='''
+        Assignment of the cell-dependent (i.e., non atom centered, e.g., plane-waves)
+        parts of the basis set, which is defined (type, parameters) in
+        section_basis_set_cell_dependent that is referred to by this metadata.
+        ''')
+
+    number_of_basis_functions = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Stores the total number of basis functions in a section_basis_set section.
+        ''')
+
+
+class section_restricted_uri(MSection):
+    '''
+    Restricted URIs on this calculation (Coverage: any info or files that are related with
+    this calculation can be subject to restriction)
+    '''
+
+    m_def = Section(validate=False)
+
+    number_of_restricted_uri = Quantity(
+        type=np.dtype(np.int32),
+        shape=[],
+        description='''
+        The number of restricted uris in restricted_uri list.
+        ''')
+
+    restricted_uri = Quantity(
+        type=str,
+        shape=['number_of_restricted_uri'],
+        description='''
+        The list of nomad uri(s) identifying the restricted info/file corresponding to
+        this calculation
+        ''')
+
+    restricted_uri_reason = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        The reason of restriction for the uri or file. The reason can be 'propriety
+        license', 'open-source redistribution restricted license', 'other license', or
+        'author restricted'.
+        ''')
+
+    restricted_uri_issue_authority = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        The issue authority is the restriction owner for the uri or file. This can be
+        license owner such as 'VASP' or 'AMBER', 'NOMAD', or the author of the uri. For
+        example the repository user name of the author.
+        ''')
+
+    restricted_uri_end_date = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        The deadline date of the restriction for the uri or file. The end date can be in
+        date format string for those restrictions set by authors or NOMAD otherwise it is
+        set to 'unlimited' for the restriction related to license.
+        ''')
+
+    restricted_uri_restriction = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        The type of restriction for the uri or file. The type can be 'any access' or
+        'license permitted'.
+        ''')
+
+    restricted_uri_license = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        The info of the license that is the reason of restriction.
+        ''')
+
+    number_of_restricted_uri_files = Quantity(
+        type=np.dtype(np.int32),
+        shape=[],
+        description='''
+        The number of restricted files in restricted_uri_files list.
+        ''')
+
+
+class section_calculation_to_calculation_refs(MSection):
+    '''
+    Section that describes the relationship between different
+    section_single_configuration_calculation sections.
+
+    For instance, one calculation is a perturbation performed using a self-consistent
+    field (SCF) calculation as starting point, or a simulated system is partitioned in
+    regions with different but connected Hamiltonians (e.g., QM/MM, or a region treated
+    via Kohn-Sham DFT embedded into a region treated via orbital-free DFT).
+
+    The kind of relationship between the calculation defined in this section and the
+    referenced one is described by calculation_to_calculation_kind. The referenced
+    section_single_configuration_calculation is identified via
+    calculation_to_calculation_ref (typically used for a
+    section_single_configuration_calculation in the same section_run) or
+    calculation_to_calculation_external_url.
+    '''
+
+    m_def = Section(validate=False)
+
+    calculation_to_calculation_external_url = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        URL used to reference an externally stored calculation. The kind of relationship
+        between the present and the referenced section_single_configuration_calculation is
+        specified by calculation_to_calculation_kind.
+        ''')
+
+    calculation_to_calculation_kind = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        String defining the relationship between the referenced
+        section_single_configuration_calculation and the present
+        section_single_configuration_calculation. Valid values are described in the
+        [calculation_to_calculation_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-
+        lab/nomad-meta-info/wikis/metainfo/calculation-to-calculation-kind). Often
+        calculations are connected, for instance, one calculation is a perturbation
+        performed using a self-consistent field (SCF) calculation as starting point, or a
+        simulated system is partitioned in regions with different but connected
+        Hamiltonians (e.g., QM/MM, or a region treated via Kohn-Sham DFT embedded into a
+        region treated via orbital-free DFT). Hence, the need of keeping track of these
+        connected calculations. The referenced calculation is identified via
+        calculation_to_calculation_ref (typically used for a calculation in the same
+        section_run) or calculation_to_calculation_external_url.
+        ''')
+
+    calculation_to_calculation_ref = Quantity(
+        type=Reference(SectionProxy('section_single_configuration_calculation')),
+        shape=[],
+        description='''
+        Reference to another calculation. If both this and
+        calculation_to_calculation_external_url are given, then
+        calculation_to_calculation_ref is a local copy of the URL given in
+        calculation_to_calculation_external_url. The kind of relationship between the
+        present and the referenced section_single_configuration_calculation is specified
+        by calculation_to_calculation_kind.
+        ''')
+
+
+class section_calculation_to_folder_refs(MSection):
+    '''
+    Section that describes the relationship between
+    section_single_configuration_calculationa and the folder containing the original
+    calulations
+    '''
+
+    m_def = Section(validate=False)
+
+    calculation_to_folder_external_url = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        URL used to reference a folder containing external calculations. The kind of
+        relationship between the present and the referenced
+        section_single_configuration_calculation is specified by
+        calculation_to_folder_kind.
+        ''')
+
+    calculation_to_folder_kind = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        String defining the relationship between the referenced
+        section_single_configuration_calculation and a folder containing calculations.
+        ''')
+
+
+class section_dos(MSection):
+    '''
+    Section collecting information of a (electronic-energy or vibrational-energy) density
+    of states (DOS) evaluation.
+    '''
+
+    m_def = Section(validate=False)
+
+    dos_energies_normalized = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_dos_values'],
+        unit='joule',
+        description='''
+        Array containing the set of discrete energy values with respect to the top of the
+        valence band for the density (electronic-energy) of states (DOS). This is the
+        total DOS, see atom_projected_dos_energies and species_projected_dos_energies for
+        partial density of states.
+        ''')
+
+    dos_energies = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_dos_values'],
+        unit='joule',
+        description='''
+        Array containing the set of discrete energy values for the density (electronic-
+        energy or vibrational energy) of states (DOS). This is the total DOS, see
+        atom_projected_dos_energies and species_projected_dos_energies for partial density
+        of states.
+        ''')
+
+    dos_fermi_energy = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        description='''
+        Stores the Fermi energy of the density of states.
+        ''')
+
+    dos_integrated_values = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_spin_channels', 'number_of_dos_values'],
+        description='''
+        Integrated density of states (starting at $-\\infty$), pseudo potential
+        calculations should start with the number of core electrons if they cover only the
+        active electrons
+        ''')
+
+    dos_kind = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        String to specify the kind of density of states (either electronic or
+        vibrational).
+        ''')
+
+    dos_lm = Quantity(
+        type=np.dtype(np.int32),
+        shape=['number_of_dos_lms', 2],
+        description='''
+        Tuples of $l$ and $m$ values for which dos_values_lm are given. For the quantum
+        number $l$ the conventional meaning of azimuthal quantum number is always adopted.
+        For the integer number $m$, besides the conventional use as magnetic quantum
+        number ($l+1$ integer values from $-l$ to $l$), a set of different conventions is
+        accepted (see the [m_kind wiki page](https://gitlab.rzg.mpg.de/nomad-lab/nomad-
+        meta-info/wikis/metainfo/m-kind). The actual adopted convention is specified by
+        dos_m_kind.
+        ''')
+
+    dos_m_kind = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        String describing what the integer numbers of $m$ in dos_lm mean. The allowed
+        values are listed in the [m_kind wiki page](https://gitlab.rzg.mpg.de/nomad-
+        lab/nomad-meta-info/wikis/metainfo/m-kind).
+        ''')
+
+    dos_values_lm = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_dos_lms', 'number_of_spin_channels', 'number_of_atoms', 'number_of_dos_values'],
+        unit='joule',
+        description='''
+        Array containing the density (electronic-energy) of states values projected on the
+        various spherical harmonics (integrated on all atoms), see
+        atom_projected_dos_values_lm for atom values.
+        ''')
+
+    dos_values_normalized = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_spin_channels', 'number_of_dos_values'],
+        description='''
+        Density of states (DOS) values divided by the unit cell volume and by the number
+        of atoms.
+        ''')
+
+    dos_values = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_spin_channels', 'number_of_dos_values'],
+        description='''
+        Values (number of states for a given energy, the set of discrete energy values is
+        given in dos_energies) of density (electronic-energy or vibrational-energy) of
+        states. This refers to the simulation cell, i.e. integrating over all energies
+        will give the number of electrons in the simulation cell.
+        ''')
+
+    number_of_dos_lms = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Gives the number of $l$, $m$ combinations for the given projected density of
+        states (DOS) in dos_values and dos_values_lm.
+        ''')
+
+    number_of_dos_values = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Gives the number of energy values for the density of states (DOS), see
+        dos_energies.
+        ''')
+
+
+class section_eigenvalues(MSection):
+    '''
+    Section containing (electronic-energy) eigenvalues for one spin channel. If, for
+    example, the eigenvalues of the Kohn-Sham operator are to be stored, a string
+    identifying this kind of eigenvalues is put in eigenvalues_kind, the coordinates of
+    the $k$-points at which the eigenvalues are evaluated is stored in
+    eigenvalues_kpoints, and the energy values of the eigenstates and their occupation is
+    stored in eigenvalues_values and eigenvalues_occupation, respectively.
+    '''
+
+    m_def = Section(validate=False)
+
+    eigenvalues_kind = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        A short string describing the kind of eigenvalues, as defined in the
+        [eigenvalues_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-
+        info/wikis/metainfo/eigenvalues-kind).
+        ''')
+
+    eigenvalues_kpoints_multiplicity = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_eigenvalues_kpoints'],
+        description='''
+        Multiplicity of the $k$ point (i.e., how many distinct points per cell this
+        expands to after applying all symmetries). This defaults to 1. If expansion is
+        preformed then each point will have weight
+        eigenvalues_kpoints_weights/eigenvalues_kpoints_multiplicity.
+        ''')
+
+    eigenvalues_kpoints_weights = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_eigenvalues_kpoints'],
+        description='''
+        Weights of the $k$ points (in the basis of the reciprocal lattice vectors) used
+        for the evaluation of the eigenvalues tabulated in eigenvalues_values, should
+        account for symmetry too.
+        ''')
+
+    eigenvalues_kpoints = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_eigenvalues_kpoints', 3],
+        description='''
+        Coordinates of the $k$ points (in the basis of the reciprocal lattice vectors)
+        used for the evaluation of the eigenvalues tabulated in eigenvalues_values.
+        ''')
+
+    eigenvalues_occupation = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_spin_channels', 'number_of_eigenvalues_kpoints', 'number_of_eigenvalues'],
+        description='''
+        Occupation of the eigenstates. The corresponding eigenvalues (energy) are given in
+        eigenvalues_values. The coordinates in the reciprocal space are defined in
+        eigenvalues_kpoints.
+        ''')
+
+    eigenvalues_values = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_spin_channels', 'number_of_eigenvalues_kpoints', 'number_of_eigenvalues'],
+        unit='joule',
+        description='''
+        Values of the (electronic-energy) eigenvalues. The coordinates of the
+        corresponding eigenstates in the reciprocal space are defined in
+        eigenvalues_kpoints and their occupations are given in eigenvalues_occupation.
+        ''')
+
+    number_of_band_segment_eigenvalues = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Gives the number of eigenvalues in a band segment, see band_energies.
+        ''')
+
+    number_of_eigenvalues_kpoints = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Gives the number of $k$ points, see eigenvalues_kpoints. $k$ points are calculated
+        within a run and are irreducible if a symmetry is used.
+        ''')
+
+    number_of_eigenvalues = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Gives the number of eigenvalues, see eigenvalues_values.
+        ''')
+
+    number_of_normalized_band_segment_eigenvalues = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Gives the number of normalized eigenvalues in a band segment, see
+
+        band_energies_normalized.
+        ''')
+
+
+class section_energy_code_independent(MSection):
+    '''
+    Section describing a code-independent total energy obtained by subtracting some
+    reference energy calculated with the same code. It contains the type in
+    energy_code_independent_kind and the computed code-independent total energy in
+    energy_code_independent_value. The computed energy allows for comparisons among
+    different codes and numerical settings.
+    '''
+
+    m_def = Section(validate=False)
+
+    energy_code_independent_kind = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Type of the code-independent total energy (obtained by subtracting a reference
+        energy calculated with the same code), created to be comparable among different
+        codes and numerical settings. Details can be found on the [energy_code_independent
+        wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-
+        info/wikis/metainfo/energy-code-independent).
+        ''')
+
+    energy_code_independent_value = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Value of the code-independent total energy (obtained by subtracting a reference
+        energy calculated with the same code). This value is created to be comparable
+        among different codes and numerical settings. Details can be found on the
+        [energy_code_independent wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-
+        meta-info/wikis/metainfo/energy-code-independent).
+        ''',
+        categories=[energy_component, energy_value, energy_total_potential])
+
+
+class section_energy_van_der_Waals(MSection):
+    '''
+    Section containing the Van der Waals energy value (energy_van_der_Waals_value) of type
+    van_der_Waals_kind. This is used when more than one Van der Waals methods are applied
+    in the same *single configuration calculation*, see
+    section_single_configuration_calculation. The main Van der Waals method (the one
+    concurring to energy_current, and used, e.g., for evaluating the forces for a
+    relaxation or dynamics) is given in energy_van_der_Waals and is defined in
+    settings_van_der_Waals.
+    '''
+
+    m_def = Section(validate=False)
+
+    energy_van_der_Waals_kind = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Method used to compute van der Waals energy stored in energy_van_der_Waals_value.
+        This metadata is used when more than one van der Waals method is applied in the
+        same *single configuration calculation* (see
+        section_single_configuration_calculation). The method used for van der Waals  (the
+        one consistent with energy_current and, e.g., for evaluating the forces for a
+        relaxation or dynamics) is defined in settings_van_der_Waals.
+        ''')
+
+    energy_van_der_Waals_value = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Value of van der Waals energy, calculated with the method defined in
+        energy_van_der_Waals_kind. This metadata is used when more than one van der Waals
+        method is applied in the same *single configuration calculation* (see
+        section_single_configuration_calculation). The value of the van der Waals energy
+        consistent with energy_current and used, e.g., for evaluating the forces for a
+        relaxation or dynamics, is given in energy_van_der_Waals and defined in
+        settings_van_der_Waals.
+        ''',
+        categories=[energy_value, energy_type_van_der_Waals, energy_component])
+
+    energy_van_der_Waals = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Value for the converged van der Waals energy calculated using the method described
+        in van_der_Waals_method, and used in energy_current. This is the van der Waals
+        method consistent with, e.g., forces used for relaxation or dynamics. Alternative
+        methods are listed in section_energy_van_der_Waals.
+        ''',
+        categories=[energy_value, energy_type_van_der_Waals, energy_component])
+
+
+class section_frame_sequence_user_quantity(MSection):
+    '''
+    Section collecting some user-defined quantities evaluated along a sequence of frame.
+    '''
+
+    m_def = Section(validate=False)
+
+    frame_sequence_user_quantity_frames = Quantity(
+        type=np.dtype(np.int32),
+        shape=['number_of_user_quantity_evaluations_in_sequence'],
+        description='''
+        Array containing the strictly increasing indices referring to the frames of
+        frame_sequence_user_quantity. If not given it defaults to the trivial mapping
+        0,1,...
+        ''')
+
+    frame_sequence_user_quantity_name = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Descriptive name of a user-defined quantity, sampled along this sequence of frames
+        (i.e., a trajectory, a frame is one section_single_configuration_calculation).
+        Dedicated metadata are created for the conserved energy-like quantity
+        (frame_sequence_conserved_quantity), the kinetic and potential energies
+        (frame_sequence_kinetic_energy and frame_sequence_potential_energy), the
+        instantaneous temperature (frame_sequence_temperature) and pressure
+        (frame_sequence_pressure). This metadata should be used for other quantities that
+        are monitored along a sequence of frames.
+        ''')
+
+    frame_sequence_user_quantity_stats = Quantity(
+        type=np.dtype(np.float64),
+        shape=[2, 'number_of_frame_sequence_user_quantity_components'],
+        description='''
+        Average of frame_sequence_user_quantity and its standard deviation in this
+        sequence of frames (i.e., a trajectory, a frame is one
+        section_single_configuration_calculation).
+        ''')
+
+    frame_sequence_user_quantity = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_user_quantity_evaluations_in_sequence', 'number_of_frame_sequence_user_quantity_components'],
+        description='''
+        Array containing the values of the user-defined quantity defined in
+        frame_sequence_user_quantity_name, evaluated along this sequence of frames (i.e.,
+        trajectory, a frame is one section_single_configuration_calculation). If not all
+        frames have a value the indices of the frames that have a value are stored in
+        frame_sequence_kinetic_energy_frames. If not all frames have a value the indices
+        of the frames that have a value are stored in
+        frame_sequence_kinetic_energy_frames.
+        ''')
+
+    number_of_frame_sequence_user_quantity_components = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Gives the number of user-defined quantity defined by
+        frame_sequence_user_quantity_name and monitored in a sequence of frames. A
+        sequence is a trajectory, which can have number_of_frames_in_sequence each
+        representing one section_single_configuration_calculation section.
+
+        Dedicated metadata monitored along a sequence of frames are created for the
+        conserved energy-like quantity (frame_sequence_conserved_quantity), the kinetic
+        and potential energies ([frame_sequence_kinetic_energy and
+        frame_sequence_potential_energy](frame_sequence_kinetic_energy and
+        frame_sequence_potential_energy)), the instantaneous temperature
+        (frame_sequence_temperature) and the pressure (frame_sequence_pressure).
+        ''')
+
+    number_of_user_quantity_evaluations_in_sequence = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Gives the number of user defined quantity evaluations along a sequence of
+        frame_sequence_user_quantity frames. A sequence is a trajectory, which can have
+        number_of_frames_in_sequence each representing one
+        section_single_configuration_calculation section.
+        ''')
+
+
+class section_frame_sequence(MSection):
+    '''
+    Section containing a sequence of frames, i.e. a trajectory which can have
+    number_of_frames_in_sequence each representing one
+    section_single_configuration_calculation section evaluated with a sampling method
+    (e.g, molecular dynamics, Monte Carlo, geometry optimization). The sampling method
+    might be a subset of the whole trajectory.
+
+    Information on the method used for the sampling can be found in the
+    section_sampling_method section and information of each frame of the sequence are
+    found in the section_single_configuration_calculation section.
+    '''
+
+    m_def = Section(validate=False)
+
+    frame_sequence_conserved_quantity_frames = Quantity(
+        type=np.dtype(np.int32),
+        shape=['number_of_conserved_quantity_evaluations_in_sequence'],
+        description='''
+        Array containing the strictly increasing indices of the frames the
+        frame_sequence_conserved_quantity values refers to. If not given it defaults to
+        the trivial mapping 0,1,...
+        ''')
+
+    frame_sequence_conserved_quantity_stats = Quantity(
+        type=np.dtype(np.float64),
+        shape=[2],
+        unit='joule',
+        description='''
+        Average value of energy-like frame_sequence_conserved_quantity, and its standard
+        deviation, over this sequence of frames (i.e., a trajectory, a frame is one
+        section_single_configuration_calculation).
+        ''')
+
+    frame_sequence_conserved_quantity = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_conserved_quantity_evaluations_in_sequence'],
+        unit='joule',
+        description='''
+        Array containing the values of a quantity that should be conserved,  along a
+        sequence of frames (i.e., a trajectory). A frame is one
+        section_single_configuration_calculation), for example the total energy in the NVE
+        ensemble. If not all frames have a value the indices of the frames that have a
+        value are stored in frame_sequence_conserved_quantity_frames.
+        ''')
+
+    frame_sequence_continuation_kind = Quantity(
+        type=Reference(SectionProxy('section_frame_sequence')),
+        shape=[],
+        description='''
+        Type of continuation that has been performed from the previous sequence of frames
+        (i.e., a trajectory, a frame is one section_single_configuration_calculation),
+        upon restart.
+        ''')
+
+    frame_sequence_external_url = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        If the energy, forces, and other quantities for the frames (a frame is one
+        section_single_configuration_calculation) in  section_frame_sequence are obtained
+        by calling a different code than the code that drives the sequence (e.g., a
+        wrapper that drives a molecular dynamics, Monte Carlo, geometry optimization and
+        calls an electronic-structure code for energy and forces for each configuration),
+        this metadata holds the reference to where the
+        section_single_configuration_calculation for each frame are located. The format
+        for this reference is described in the [frame_sequence_external_url wiki
+        page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/frame-
+        sequence-external-url).
+        ''')
+
+    frame_sequence_kinetic_energy_frames = Quantity(
+        type=np.dtype(np.int32),
+        shape=['number_of_kinetic_energies_in_sequence'],
+        description='''
+        Array containing the strictly increasing indices referring to the frames of
+        frame_sequence_kinetic_energy. If not given it defaults to the trivial mapping
+        0,1,...
+        ''')
+
+    frame_sequence_kinetic_energy_stats = Quantity(
+        type=np.dtype(np.float64),
+        shape=[2],
+        unit='joule',
+        description='''
+        Average kinetic energy and its standard deviation over this sequence of frames
+        (i.e., a trajectory, a frame is one section_single_configuration_calculation).
+        ''')
+
+    frame_sequence_kinetic_energy = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_kinetic_energies_in_sequence'],
+        unit='joule',
+        description='''
+        Array containing the values of the kinetic energy along this sequence of frames
+        (i.e., a trajectory, a frame is one section_single_configuration_calculation). If
+        not all frames have a value the indices of the frames that have a value are stored
+        in frame_sequence_kinetic_energy_frames.
+        ''')
+
+    frame_sequence_local_frames_ref = Quantity(
+        type=Reference(SectionProxy('section_single_configuration_calculation')),
+        shape=['number_of_frames_in_sequence'],
+        description='''
+        Reference from each frame (a frame is one
+        section_single_configuration_calculation) in this section_frame_sequence to the
+        corresponding section_single_configuration_calculation. Each
+        section_frame_sequence binds a collection of
+        section_single_configuration_calculation, because they all belong to, e.g., a
+        molecular dynamics trajectory, or geometry optimization. The full information for
+        each frame is stored in section_single_configuration_calculation and this metadata
+        establishes the link for each frame.
+        ''')
+
+    frame_sequence_potential_energy_frames = Quantity(
+        type=np.dtype(np.int32),
+        shape=['number_of_potential_energies_in_sequence'],
+        description='''
+        Array containing the strictly increasing indices referring to the frames of
+        frame_sequence_potential_energy. If not given it defaults to the trivial mapping
+        0,1,...
+        ''')
+
+    frame_sequence_potential_energy_stats = Quantity(
+        type=np.dtype(np.float64),
+        shape=[2],
+        unit='joule',
+        description='''
+        Average potential energy and its standard deviation over this sequence of frames
+        (i.e., a trajectory, a frame is one section_single_configuration_calculation).
+        ''')
+
+    frame_sequence_potential_energy = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_potential_energies_in_sequence'],
+        unit='joule',
+        description='''
+        Array containing the value of the potential energy along this sequence of frames
+        (i.e., a trajectory, a frame is one section_single_configuration_calculation).
+        This is equal to energy_total of the corresponding
+        section_single_configuration_calculation and repeated here in a summary array for
+        easier access. If not all frames have a value the indices of the frames that have
+        a value are stored in frame_sequence_potential_energy_frames.
+        ''')
+
+    frame_sequence_pressure_frames = Quantity(
+        type=np.dtype(np.int32),
+        shape=['number_of_pressure_evaluations_in_sequence'],
+        description='''
+        Array containing the strictly increasing indices referring to the frames of
+        frame_sequence_pressure. If not given it defaults to the trivial mapping 0,1,...
+        ''')
+
+    frame_sequence_pressure_stats = Quantity(
+        type=np.dtype(np.float64),
+        shape=[2],
+        unit='pascal',
+        description='''
+        Average pressure (one third of the trace of the stress tensor) and standard
+        deviation over this sequence of frames (i.e., a trajectory, a frame is one
+        section_single_configuration_calculation).
+        ''')
+
+    frame_sequence_pressure = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_pressure_evaluations_in_sequence'],
+        unit='pascal',
+        description='''
+        Array containing the values of the pressure (one third of the trace of the stress
+        tensor) along this sequence of frames (a frame is one
+        section_single_configuration_calculation). If not all frames have a value the
+        indices of the frames that have a value are stored in
+        frame_sequence_pressure_frames.
+        ''')
+
+    frame_sequence_temperature_frames = Quantity(
+        type=np.dtype(np.int32),
+        shape=['number_of_temperatures_in_sequence'],
+        description='''
+        Array containing the strictly increasing indices referring to the frames of
+        frame_sequence_temperature. If not given it defaults to the trivial mapping
+        0,1,...
+        ''')
+
+    frame_sequence_temperature_stats = Quantity(
+        type=np.dtype(np.float64),
+        shape=[2],
+        unit='kelvin',
+        description='''
+        Average temperature and its standard deviation over this sequence of frames (i.e.,
+        a trajectory, a frame is one section_single_configuration_calculation).
+        ''')
+
+    frame_sequence_temperature = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_temperatures_in_sequence'],
+        unit='kelvin',
+        description='''
+        Array containing the values of the instantaneous temperature (a quantity,
+        proportional to frame_sequence_kinetic_energy, whose ensemble average equals the
+        thermodynamic temperature) along this sequence of frames (i.e., a trajectory, a
+        frame is one section_single_configuration_calculation). If not all frames have a
+        value the indices of the frames that have a value are stored in
+        frame_sequence_temperature_frames.
+        ''')
+
+    frame_sequence_time = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_frames_in_sequence'],
+        unit='second',
+        description='''
+        Time along this sequence of frames (i.e., a trajectory, a frame is one
+        section_single_configuration_calculation). Time start is arbitrary, but when a
+        sequence is a continuation of another time should be continued too.
+        ''')
+
+    frame_sequence_to_sampling_ref = Quantity(
+        type=Reference(SectionProxy('section_sampling_method')),
+        shape=[],
+        description='''
+        Reference from the present section_frame_sequence to the section_sampling_method,
+        that defines the parameters used in this sequence of frames (i.e., a trajectory, a
+        frame is one section_single_configuration_calculation).
+        ''')
+
+    geometry_optimization_converged = Quantity(
+        type=bool,
+        shape=[],
+        description='''
+        Arrays specify whether a geometry optimization is converged.
+        ''')
+
+    number_of_conserved_quantity_evaluations_in_sequence = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Gives the number of conserved quantity evaluations in this sequence. A sequence is
+        a trajectory, which can have number_of_frames_in_sequence each representing one
+        section_single_configuration_calculation section.
+        ''')
+
+    number_of_frames_in_sequence = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Gives the number of frames in a sequence. A sequence is a trajectory, which can
+        have number_of_frames_in_sequence each representing one
+        section_single_configuration_calculation section.
+        ''')
+
+    number_of_kinetic_energies_in_sequence = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Gives the number of kinetic energy evaluations in this sequence of frames, see
+        frame_sequence_kinetic_energy.
+        ''')
+
+    number_of_potential_energies_in_sequence = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Gives the number of potential energies evaluation in this sequence. A sequence is
+        a trajectory, which can have number_of_frames_in_sequence each representing one
+        section_single_configuration_calculation section.
+        ''')
+
+    number_of_pressure_evaluations_in_sequence = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Gives the number of pressure evaluations in this sequence. A sequence is a
+        trajectory, which can have number_of_frames_in_sequence each representing one
+        section_single_configuration_calculation section.
+        ''')
+
+    number_of_temperatures_in_sequence = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Gives the number of temperature frames (frame_sequence_temperature) used in the
+        section_frame_sequence. A sequence is a trajectory, which can have
+        number_of_frames_in_sequence each representing one
+        section_single_configuration_calculation section.
+        ''')
+
+    previous_sequence_ref = Quantity(
+        type=Reference(SectionProxy('section_frame_sequence')),
+        shape=[],
+        description='''
+        Contains a reference to the previous sequence. A sequence is a trajectory, which
+        can have number_of_frames_in_sequence each representing one
+        section_single_configuration_calculation section. If not given, a start from an
+        initial configuration is assumed.
+        ''')
+
+    section_frame_sequence_user_quantity = SubSection(
+        sub_section=SectionProxy('section_frame_sequence_user_quantity'),
+        repeats=True)
+
+    section_thermodynamical_properties = SubSection(
+        sub_section=SectionProxy('section_thermodynamical_properties'),
+        repeats=True)
+
+
+class section_gaussian_basis_group(MSection):
+    '''
+    Section that describes a group of Gaussian contractions. Groups allow one to calculate
+    the primitive Gaussian integrals once for several different linear combinations of
+    them. This defines basis functions with radial part $f_i(r) = r^{l_i} \\\\sum_{j} c_{i
+    j} A(l_i, \\\\alpha_j) exp(-\\\\alpha_j r^2)$ where $A(l_i, \\\\alpha_j)$ is a the
+    normalization coefficient for primitive Gaussian basis functions. Here, $\\\\alpha_j$ is
+    defined in gaussian_basis_group_exponents, $l_i$ is given in gaussian_basis_group_ls,
+    and $c_{i j}$ is given in gaussian_basis_group_contractions, whereas the radial part
+    is given by the spherical harmonics $Y_{l m}$.
+
+    This section is defined only if the original basis function uses Gaussian basis
+    functions, and the sequence of radial functions $f_i$ across all
+    section_gaussian_basis_group in section_basis_set_atom_centered should match the one
+    of basis_set_atom_centered_radial_functions.
+    '''
+
+    m_def = Section(validate=False)
+
+    gaussian_basis_group_contractions = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_gaussian_basis_group_contractions', 'number_of_gaussian_basis_group_exponents'],
+        description='''
+        contraction coefficients $c_{i j}$ defining the contracted basis functions with
+        respect to *normalized* primitive Gaussian functions. They define the Gaussian
+        basis functions as described in section_gaussian_basis_group.
+        ''')
+
+    gaussian_basis_group_exponents = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_gaussian_basis_group_exponents'],
+        unit='1 / meter ** 2',
+        description='''
+        Exponents $\\alpha_j$ of the Gaussian functions defining this basis set
+        $exp(-\\alpha_j r^2)$. One should be careful about the units of the coefficients.
+        ''')
+
+    gaussian_basis_group_ls = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_gaussian_basis_group_contractions'],
+        description='''
+        Azimuthal quantum number ($l$) values (of the angular part given by the spherical
+        harmonic $Y_{l m}$ of the various contracted basis functions).
+        ''')
+
+    number_of_gaussian_basis_group_contractions = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Gives the number of different contractions, i.e. resulting basis functions in a
+        section_gaussian_basis_group section.
+        ''')
+
+    number_of_gaussian_basis_group_exponents = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Gives the number of different Gaussian exponents in a section_gaussian_basis_group
+        section.
+        ''')
+
+
+class section_k_band_normalized(MSection):
+    '''
+    This section stores information on a normalized $k$-band (electronic band structure)
+    evaluation along one-dimensional pathways in the $k$ (reciprocal) space given in
+    section_k_band_segment. Eigenvalues calculated at the actual $k$-mesh used for
+    energy_total evaluations, can be found in the section_eigenvalues section.
+    '''
+
+    m_def = Section(validate=False)
+
+    k_band_path_normalized_is_standard = Quantity(
+        type=bool,
+        shape=[],
+        description='''
+        If the normalized path is along the default path defined in W. Setyawan and S.
+        Curtarolo, [Comput. Mater. Sci. **49**, 299-312
+        (2010)](http://dx.doi.org/10.1016/j.commatsci.2010.05.010).
+        ''')
+
+    section_k_band_segment_normalized = SubSection(
+        sub_section=SectionProxy('section_k_band_segment_normalized'),
+        repeats=True)
+
+
+class section_k_band_segment_normalized(MSection):
+    '''
+    Section collecting the information on a normalized $k$-band segment. This section
+    stores band structures along a one-dimensional pathway in the $k$ (reciprocal) space.
+
+    Eigenvalues calculated at the actual $k$-mesh used for energy_total evaluations are
+    defined in section_eigenvalues and the band structures are represented as third-order
+    tensors: one dimension for the spin channels, one for the sequence of $k$ points for
+    the segment (given in number_of_k_points_per_segment), and one for the sequence of
+    eigenvalues at a given $k$ point. The values of the $k$ points in each segment are
+    stored in band_k_points. The energies and occupation for each eigenstate, at each $k$
+    point, segment, and spin channel are stored in band_energies and band_occupations,
+    respectively. The labels for the segment are specified in band_segm_labels.
+    '''
+
+    m_def = Section(validate=False)
+
+    band_energies_normalized = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_spin_channels', 'number_of_normalized_k_points_per_segment', 'number_of_normalized_band_segment_eigenvalues'],
+        unit='joule',
+        description='''
+        $k$-dependent energies of the electronic band segment (electronic band structure)
+        with respect to the top of the valence band. This is a third-order tensor, with
+        one dimension used for the spin channels, one for the $k$ points for each segment,
+        and one for the eigenvalue sequence.
+        ''')
+
+    band_k_points_normalized = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_normalized_k_points_per_segment', 3],
+        description='''
+        Fractional coordinates of the $k$ points (in the basis of the reciprocal-lattice
+        vectors) for which the normalized electronic energies are given.
+        ''')
+
+    band_occupations_normalized = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_spin_channels', 'number_of_normalized_k_points_per_segment', 'number_of_normalized_band_segment_eigenvalues'],
+        description='''
+        Occupation of the $k$-points along the normalized electronic band. The size of the
+        dimensions of this third-order tensor are the same as for the tensor in
+        band_energies.
+        ''')
+
+    band_segm_labels_normalized = Quantity(
+        type=str,
+        shape=[2],
+        description='''
+        Start and end labels of the points in the segment (one-dimensional pathways)
+        sampled in the $k$-space, using the conventional symbols, e.g., Gamma, K, L. The
+        coordinates (fractional, in the reciprocal space) of the start and end points for
+        each segment are given in band_segm_start_end_normalized
+        ''')
+
+    band_segm_start_end_normalized = Quantity(
+        type=np.dtype(np.float64),
+        shape=[2, 3],
+        description='''
+        Fractional coordinates of the start and end point (in the basis of the reciprocal
+        lattice vectors) of the segment sampled in the $k$ space. The conventional symbols
+        (e.g., Gamma, K, L) of the same points are given in band_segm_labels
+        ''')
+
+    number_of_normalized_k_points_per_segment = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Gives the number of $k$ points in the segment of the normalized band structure
+        (see section_k_band_segment_normalized).
+        ''')
+
+
+class section_k_band_segment(MSection):
+    '''
+    Section collecting the information on a $k$-band or $q$-band segment. This section
+    stores band structures along a one-dimensional pathway in the $k$ or $q$ (reciprocal)
+    space.
+
+    Eigenvalues calculated at the actual $k$-mesh used for energy_total evaluations are
+    defined in section_eigenvalues and the band structures are represented as third-order
+    tensors: one dimension for the spin channels, one for the sequence of $k$ or $q$
+    points for the segment (given in number_of_k_points_per_segment), and one for the
+    sequence of eigenvalues at a given $k$ or $q$ point. The values of the $k$ or $q$
+    points in each segment are stored in band_k_points. The energies and occupation for
+    each eigenstate, at each $k$ or $q$ point, segment, and spin channel are stored in
+    band_energies and band_occupations, respectively. The labels for the segment are
+    specified in band_segm_labels.
+    '''
+
+    m_def = Section(validate=False)
+
+    band_energies = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_spin_channels', 'number_of_k_points_per_segment', 'number_of_band_segment_eigenvalues'],
+        unit='joule',
+        description='''
+        $k$-dependent or $q$-dependent  energies of the electronic or vibrational band
+        segment (electronic/vibrational band structure). This is a third-order tensor,
+        with one dimension used for the spin channels (1 in case of a vibrational band
+        structure), one for the $k$ or $q$ points for each segment, and one for the
+        eigenvalue sequence.
+        ''')
+
+    band_k_points = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_k_points_per_segment', 3],
+        description='''
+        Fractional coordinates of the $k$ or $q$ points (in the basis of the reciprocal-
+        lattice vectors) for which the electronic energy are given.
+        ''')
+
+    band_occupations = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_spin_channels', 'number_of_k_points_per_segment', 'number_of_band_segment_eigenvalues'],
+        description='''
+        Occupation of the $k$-points along the electronic band. The size of the dimensions
+        of this third-order tensor are the same as for the tensor in band_energies.
+        ''')
+
+    band_segm_labels = Quantity(
+        type=str,
+        shape=[2],
+        description='''
+        Start and end labels of the points in the segment (one-dimensional pathways)
+        sampled in the $k$-space or $q$-space, using the conventional symbols, e.g.,
+        Gamma, K, L. The coordinates (fractional, in the reciprocal space) of the start
+        and end points for each segment are given in band_segm_start_end
+        ''')
+
+    band_segm_start_end = Quantity(
+        type=np.dtype(np.float64),
+        shape=[2, 3],
+        description='''
+        Fractional coordinates of the start and end point (in the basis of the reciprocal
+        lattice vectors) of the segment sampled in the $k$ space. The conventional symbols
+        (e.g., Gamma, K, L) of the same points are given in band_segm_labels
+        ''')
+
+    number_of_k_points_per_segment = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Gives the number of $k$ points in the segment of the band structure, see
+        section_k_band_segment.
+        ''')
+
+
+class section_k_band(MSection):
+    '''
+    This section stores information on a $k$-band (electronic or vibrational band
+    structure) evaluation along one-dimensional pathways in the $k$ or $q$ (reciprocal)
+    space given in section_k_band_segment. Eigenvalues calculated at the actual $k$-mesh
+    used for energy_total evaluations, can be found in the section_eigenvalues section.
+    '''
+
+    m_def = Section(validate=False)
+
+    band_structure_kind = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        String to specify the kind of band structure (either electronic or vibrational).
+        ''')
+
+    section_k_band_segment = SubSection(
+        sub_section=SectionProxy('section_k_band_segment'),
+        repeats=True)
+
+
+class section_method_atom_kind(MSection):
+    '''
+    Every section_method_atom_kind section contains method-related information about a
+    kind of atom, and is identified by one or more strings stored in
+    method_atom_kind_label.
+
+    This categorization into atom kinds is more flexible than just atomic species, because
+    to different atoms of the same species different atom-centered basis sets or pseudo-
+    potentials may be assigned. For instance, if two different oxygen atoms are assigned
+    to different basis sets or pseudo-potentials, they have to distinguished into two
+    different *kinds* of O atoms, by creating two distinct section_method_atom_kind
+    sections.
+    '''
+
+    m_def = Section(validate=False)
+
+    method_atom_kind_atom_number = Quantity(
+        type=np.dtype(np.int32),
+        shape=[],
+        description='''
+        Atomic number (number of protons) of this atom kind, use 0 if not an atom.
+        ''')
+
+    method_atom_kind_explicit_electrons = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        description='''
+        Number of explicit electrons (often called valence).
+        ''')
+
+    method_atom_kind_label = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        String used to identify the atoms of this kind. This should correspond to the
+        atom_labels of the configuration. It is possible for one atom kind to have
+        multiple labels (in order to allow two atoms of the same kind to have two
+        differently defined sets of atom-centered basis functions or two different pseudo-
+        potentials). Atom kind is typically the symbol of the atomic species but it can be
+        also a ghost or pseudo-atom.
+        ''')
+
+    method_atom_kind_mass = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='atomic_mass_unit',
+        description='''
+        Mass of the kind of this kind of atoms.
+        ''')
+
+    method_atom_kind_pseudopotential_name = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Name identifying the pseudopotential used.
+        ''')
+
+
+class section_method_to_method_refs(MSection):
+    '''
+    Section that describes the relationship between different section_method sections.
+
+    For instance, one calculation is a perturbation performed using a self-consistent
+    field (SCF) calculation as starting point, or a simulated system is partitioned in
+    regions with different but connected Hamiltonians (e.g., QM/MM, or a region treated
+    via Kohn-Sham DFT embedded into a region treated via orbital-free DFT).
+
+    The kind of relationship between the method defined in this section and the referenced
+    one is described by method_to_method_kind. The referenced section section_method is
+    identified via method_to_method_ref (typically used for a section_method section in
+    the same section_run) or method_to_method_external_url.
+    '''
+
+    m_def = Section(validate=False)
+
+    method_to_method_external_url = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        URL used to reference an externally stored section_method. The kind of
+        relationship between the present and the referenced section_method is specified by
+        method_to_method_kind.
+        ''')
+
+    method_to_method_kind = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        String defining the kind of relationship that the referenced section_method has
+        with the present section_method. Valid values are described in the
+        [method_to_method_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-
+        meta-info/wikis/metainfo/method-to-method-kind). Often calculations are connected,
+        for instance, one calculation is a perturbation performed using a self-consistent
+        field (SCF) calculation as starting point, or a simulated system is partitioned in
+        regions with different but connected Hamiltonians (e.g., QM/MM, or a region
+        treated via Kohn-Sham DFT embedded into a region treated via orbital-free DFT).
+        Hence, the need of keeping track of these connected calculations. The referenced
+        section_method is identified via method_to_method_ref (typically used for a
+        section_method in the same section_run) or method_to_method_external_url.
+        ''')
+
+    method_to_method_ref = Quantity(
+        type=Reference(SectionProxy('section_method')),
+        shape=[],
+        description='''
+        Reference to a local section_method. If both method_to_method_ref and
+        method_to_method_external_url are given, then method_to_method_ref is a local copy
+        of the value contained in method_to_method_external_url. The kind of relationship
+        between the method defined in the present section_method and the referenced one is
+        described by method_to_method_kind.
+        ''')
+
+
+class section_method(MSection):
+    '''
+    Section containing the various parameters that define the theory and the
+    approximations (convergence, thresholds,...) to perform a *single configuration
+    calculation*, see section_single_configuration_calculation.
+
+    *NOTE*: This section does not contain settings for molecular dynamics, geometry
+    optimization etc. See section frame_sequence for these other settings instead.
+    '''
+
+    m_def = Section(validate=False)
+
+    basis_set = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Unique string identifying the basis set used for the final wavefunctions
+        calculated with XC_method. It might identify a class of basis sets, often matches
+        one of the strings given in any of basis_set_name.
+        ''',
+        categories=[settings_potential_energy_surface, settings_numerical_parameter])
+
+    calculation_method_current = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        String that represents the method used to calculate the energy_current. If the
+        method is perturbative, this string does not describe the starting point method,
+        the latter being referenced to by section_method_to_method_refs. For self-
+        consistent field (SCF) ab initio calculations, for example, this is composed by
+        concatenating XC_method_current and basis_set. See [calculation_method_current
+        wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-
+        info/wikis/metainfo/calculation-method-current) for the details.
+        ''')
+
+    calculation_method_kind = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Kind of method in calculation_method_current.
+
+        Accepted values are:
+
+        - absolute
+
+        - perturbative.
+        ''')
+
+    calculation_method = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        String that uniquely represents the method used to calculate energy_total, If the
+        present calculation_method_current is a perturbative method Y that uses method X
+        as starting point, this string is automatically created as X@Y, where X is taken
+        from calculation_method_current and Y from method_to_method_ref. In order to
+        activate this, method_to_method_kind must have the value starting_point (see the
+        [method_to_method_kind wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-
+        meta-info/wikis/metainfo/method-to-method-kind)).
+        ''')
+
+    electronic_structure_method = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Non-unique string identifying the used electronic structure method. It is not
+        unique in the sense that two calculations with the same
+        electronic_structure_method string may have not been performed with exactly the
+        same method. The allowed strings are given in the [electronic structure method
+        wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-
+        info/wikis/metainfo/electronic-structure-method).
+        ''',
+        categories=[settings_potential_energy_surface, settings_XC])
+
+    k_mesh_points = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_k_mesh_points', 3],
+        description='''
+        List of all the k points in the $k$-point mesh. These are the k point used to
+        evaluate energy_total, and are in fractional coordinates (in the basis of the
+        reciprocal-lattice vectors).
+        ''',
+        categories=[settings_k_points, settings_potential_energy_surface])
+
+    k_mesh_weights = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_k_mesh_points'],
+        description='''
+        Weights of all the k points in the $k$-point mesh. These are the weights for
+        k_mesh_points (i.e. the k point used to evaluate energy_total).
+        ''',
+        categories=[settings_k_points, settings_potential_energy_surface])
+
+    number_of_k_mesh_points = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        number of k points in the mesh (i.e. the k points used to evaluate energy_total).
+        ''',
+        categories=[settings_k_points, settings_potential_energy_surface])
+
+    number_of_spin_channels = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Gives the number of spin channels, see section_method.
+        ''')
+
+    relativity_method = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Describes the relativistic treatment used for the calculation of the final energy
+        and related quantities. If skipped or empty, no relativistic treatment is applied.
+        ''',
+        categories=[settings_potential_energy_surface, settings_XC, settings_relativity])
+
+    scf_max_iteration = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        description='''
+        Specifies the maximum number of allowed self-consistent field (SCF) iterations in
+        a calculation run, see section_run.
+        ''',
+        categories=[settings_scf])
+
+    scf_threshold_energy_change = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Specifies the threshold for the energy_total_scf_iteration change between two
+        subsequent self-consistent field (SCF) iterations. The SCF is considered converged
+        when the total-energy change between two SCF cycles is below the threshold
+        (possibly in combination with other criteria).
+        ''',
+        categories=[settings_scf])
+
+    self_interaction_correction_method = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Contains the name for the self-interaction correction (SIC) treatment used to
+        calculate the final energy and related quantities. If skipped or empty, no special
+        correction is applied.
+
+        The following SIC methods are available:
+
+        | SIC method                | Description                       |
+
+        | ------------------------- | --------------------------------  |
+
+        | `""`                      | No correction                     |
+
+        | `"SIC_AD"`                | The average density correction    |
+
+        | `"SIC_SOSEX"`             | Second order screened exchange    |
+
+        | `"SIC_EXPLICIT_ORBITALS"` | (scaled) Perdew-Zunger correction explicitly on a
+        set of orbitals |
+
+        | `"SIC_MAURI_SPZ"`         | (scaled) Perdew-Zunger expression on the spin
+        density / doublet unpaired orbital |
+
+        | `"SIC_MAURI_US"`          | A (scaled) correction proposed by Mauri and co-
+        workers on the spin density / doublet unpaired orbital |
+        ''',
+        categories=[settings_potential_energy_surface, settings_XC, settings_self_interaction_correction])
+
+    smearing_kind = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Specifies the kind of smearing on the electron occupation used to calculate the
+        free energy (see energy_free)
+
+        Valid values are:
+
+        | Smearing kind             | Description                       |
+
+        | ------------------------- | --------------------------------- |
+
+        | `"empty"`                 | No smearing is applied            |
+
+        | `"gaussian"`              | Gaussian smearing                 |
+
+        | `"fermi"`                 | Fermi smearing                    |
+
+        | `"marzari-vanderbilt"`    | Marzari-Vanderbilt smearing       |
+
+        | `"methfessel-paxton"`     | Methfessel-Paxton smearing        |
+
+        | `"tetrahedra"`            | Interpolation of state energies and occupations
+        (ignores smearing_width) |
+        ''',
+        categories=[settings_smearing])
+
+    smearing_width = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        description='''
+        Specifies the width of the smearing in energy for the electron occupation used to
+        calculate the free energy (see energy_free).
+
+        *NOTE:* Not all methods specified in smearing_kind uses this value.
+        ''',
+        categories=[settings_smearing])
+
+    spin_target_multiplicity = Quantity(
+        type=np.dtype(np.int32),
+        shape=[],
+        description='''
+        Stores the target (user-imposed) value of the spin multiplicity $M=2S+1$, where
+        $S$ is the total spin. It is an integer number. This value is not necessarily the
+        value obtained at the end of the calculation. See spin_S2 for the converged value
+        of the spin moment.
+        ''')
+
+    stress_tensor_method = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Specifies the method used to calculate stress_tensor for, e.g., molecular dynamics
+        and geometry optimization.
+
+        The allowed values are:
+
+        * numeric
+
+        * analytic
+        ''',
+        categories=[settings_stress_tensor])
+
+    total_charge = Quantity(
+        type=np.dtype(np.int32),
+        shape=[],
+        unit='coulomb',
+        description='''
+        Provides the total amount of charge of the system in a run.
+        ''')
+
+    van_der_Waals_method = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Describes the Van der Waals method. If skipped or an empty string is used, it
+        means no Van der Waals correction is applied.
+
+        Allowed values are:
+
+        | Van der Waals method  | Description                               |
+
+        | --------------------- | ----------------------------------------- |
+
+        | `""`                  | No Van der Waals correction               |
+
+        | `"TS"`                | A. Tkatchenko and M. Scheffler, [Phys. Rev. Lett.
+        **102**, 073005 (2009)](http://dx.doi.org/10.1103/PhysRevLett.102.073005) |
+
+        | `"OBS"`               | F. Ortmann, F. Bechstedt, and W. G. Schmidt, [Phys. Rev.
+        B **73**, 205101 (2006)](http://dx.doi.org/10.1103/PhysRevB.73.205101) |
+
+        | `"G06"`               | S. Grimme, [J. Comput. Chem. **27**, 1787
+        (2006)](http://dx.doi.org/10.1002/jcc.20495) |
+
+        | `"JCHS"`              | P. Jurečka, J. Černý, P. Hobza, and D. R. Salahub,
+        [Journal of Computational Chemistry **28**, 555
+        (2007)](http://dx.doi.org/10.1002/jcc.20570) |
+
+        | `"MDB"`               | Many-body dispersion. A. Tkatchenko, R. A. Di Stasio Jr,
+        R. Car, and M. Scheffler, [Physical Review Letters **108**, 236402
+        (2012)](http://dx.doi.org/10.1103/PhysRevLett.108.236402) and A. Ambrosetti, A. M.
+        Reilly, R. A. Di Stasio Jr, and A. Tkatchenko, [The Journal of Chemical Physics
+        **140**, 18A508 (2014)](http://dx.doi.org/10.1063/1.4865104) |
+
+        | `"XC"`                | The method to calculate the Van der Waals energy uses a
+        non-local functional which is described in section_XC_functionals. |
+        ''',
+        categories=[settings_van_der_Waals, settings_potential_energy_surface, settings_XC])
+
+    XC_functional = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        This value describes a DFT exchange-correlation (XC) functional used for
+        evaluating the energy value stored in energy_XC_functional and related quantities
+        (e.g., forces).
+
+        It is a unique short name obtained by combining the data stored in
+        section_XC_functionals, more specifically by combining different
+        XC_functional_name as described in the [XC_functional wiki
+        page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/XC-
+        functional).
+        ''',
+        categories=[settings_physical_parameter, settings_XC_functional, settings_potential_energy_surface, settings_XC])
+
+    XC_method = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Describes the exchange correlation (XC) method used for evaluating the XC energy
+        (energy_XC). Differently from XC_functional, perturbative treatments are also
+        accounted for, where the string contains the reference to both the perturbative
+        (e.g., MP2) and the starting point (e.g, Hartree-Fock) XC method defined in the
+        section section_method.
+
+        The value consists of XC_method_current concatenated with the `@` character and
+        the XC method (XC_method) defined in section_method that is referred to by
+        method_to_method_ref where method_to_method_kind = "starting_point_method".
+        ''',
+        categories=[settings_potential_energy_surface, settings_XC])
+
+    XC_method_current = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Identifies the exchange correlation (XC) method used for energy_XC and related
+        quantities in a standardized short form as a string.
+
+        It is built by joining the values in the following order using the underscore `_`
+        character: electronic_structure_method, XC_functional,
+        self_interaction_correction_method, van_der_Waals_method and relativity_method.
+
+        If any of the methods listed in the string contain non-standard settings, then the
+        first 10 characters of the Base64 URL encoding of SHA 512 checksum of a normalized
+        JSON with all non-redundant non-derived settings_XC are appended to the the string
+        preceded by an underscore.
+
+        With empty strings, the underscore `_` character is skipped.
+
+        If the method defined in the section_method section is perturbative, the
+        XC_method_current contains only the perturbative method, not the starting point
+        (e.g. the DFT XC functional used as a starting point for a RPA perturbative
+        calculation). In this case, the string that contains both the perturbative and
+        starting point method is stored in XC_method.
+        ''',
+        categories=[settings_potential_energy_surface, settings_XC])
+
+    section_method_atom_kind = SubSection(
+        sub_section=SectionProxy('section_method_atom_kind'),
+        repeats=True)
+
+    section_method_to_method_refs = SubSection(
+        sub_section=SectionProxy('section_method_to_method_refs'),
+        repeats=True)
+
+    section_XC_functionals = SubSection(
+        sub_section=SectionProxy('section_XC_functionals'),
+        repeats=True)
+
+
+class section_original_system(MSection):
+    '''
+    Section containing symmetry information that is specific to the original system.
+    '''
+
+    m_def = Section(validate=False)
+
+    equivalent_atoms_original = Quantity(
+        type=np.dtype(np.int32),
+        shape=['number_of_atoms'],
+        description='''
+        Gives a mapping table of atoms to symmetrically independent atoms in the original
+        cell. This is used to find symmetrically equivalent atoms.
+        ''')
+
+    wyckoff_letters_original = Quantity(
+        type=str,
+        shape=['number_of_atoms'],
+        description='''
+        Wyckoff letters for atoms in the original cell.
+        ''')
+
+
+class section_primitive_system(MSection):
+    '''
+    Section containing symmetry information that is specific to the primitive system. The
+    primitive system is derived from the standardized system with a transformation that is
+    specific to the centring. The transformation matrices can be found e.g. from here:
+    https://atztogo.github.io/spglib/definition.html#transformation-to-the-primitive-cell
+    '''
+
+    m_def = Section(validate=False)
+
+    atom_positions_primitive = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_atoms_primitive', 3],
+        description='''
+        Atom positions in the primitive cell in reduced units.
+        ''')
+
+    atomic_numbers_primitive = Quantity(
+        type=np.dtype(np.int32),
+        shape=['number_of_atoms_primitive'],
+        description='''
+        Atomic numbers in the primitive cell.
+        ''')
+
+    equivalent_atoms_primitive = Quantity(
+        type=np.dtype(np.int32),
+        shape=['number_of_atoms_primitive'],
+        description='''
+        Gives a mapping table of atoms to symmetrically independent atoms in the primitive
+        cell. This is used to find symmetrically equivalent atoms.
+        ''')
+
+    lattice_vectors_primitive = Quantity(
+        type=np.dtype(np.float64),
+        shape=[3, 3],
+        unit='meter',
+        description='''
+        Primitive lattice vectors. The vectors are the rows of this matrix.
+        ''')
+
+    number_of_atoms_primitive = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Number of atoms in primitive system.
+        ''')
+
+    wyckoff_letters_primitive = Quantity(
+        type=str,
+        shape=['number_of_atoms_primitive'],
+        description='''
+        Wyckoff letters for atoms in the primitive cell.
+        ''')
+
+
+class section_processor_info(MSection):
+    '''
+    Section with information about a processor that generated or added information to the
+    current calculation.
+    '''
+
+    m_def = Section(validate=False)
+
+    processor_id = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Id (name+version) of the processor that generated or added information to the
+        current calculation.
+        ''')
+
+    processor_number_of_evaluated_contexts = Quantity(
+        type=np.dtype(np.int64),
+        shape=[],
+        description='''
+        number of contexts evaluated with this processor in the current current
+        calculation.
+        ''')
+
+    processor_number_of_failed_contexts = Quantity(
+        type=np.dtype(np.int64),
+        shape=[],
+        description='''
+        number of contexts in the current current calculation that had failure for this
+        processor.
+        ''')
+
+    processor_number_of_skipped_contexts = Quantity(
+        type=np.dtype(np.int64),
+        shape=[],
+        description='''
+        number of contexts skipped by this processor in the current current calculation.
+        ''')
+
+    processor_number_of_successful_contexts = Quantity(
+        type=np.dtype(np.int64),
+        shape=[],
+        description='''
+        number of contexts in the current calculation that where successfully handled by
+        this processor.
+        ''')
+
+    processor_version_details = Quantity(
+        type=typing.Any,
+        shape=[],
+        description='''
+        detailed version information on the processor that generated or added information
+        to the current calculation.
+        ''')
+
+
+class section_processor_log_event(MSection):
+    '''
+    A log event
+    '''
+
+    m_def = Section(validate=False)
+
+    processor_log_event_level = Quantity(
+        type=np.dtype(np.int32),
+        shape=[],
+        description='''
+        Level of the logging, a lower number has more priority. The levels are the same as
+        log4j: FATAL -> 100, ERROR -> 200, WARN -> 300, INFO -> 400, DEBUG -> 500, TRACE
+        -> 600
+        ''')
+
+    processor_log_event_message = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        The log message
+        ''')
+
+
+class section_processor_log(MSection):
+    '''
+    log of a processor
+    '''
+
+    m_def = Section(validate=False)
+
+    processor_log_processor_id = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        The processor id of the processor creating this log
+        ''')
+
+    processor_log_start = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Start of the log (in ansi notation YYYY-MM-TT...)
+        ''')
+
+    section_processor_log_event = SubSection(
+        sub_section=SectionProxy('section_processor_log_event'),
+        repeats=True)
+
+
+class section_prototype(MSection):
+    '''
+    Information on the prototype corresponding to the current section.
+    '''
+
+    m_def = Section(validate=False)
+
+    prototype_aflow_id = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        AFLOW id of the prototype (see
+        http://aflowlib.org/CrystalDatabase/prototype_index.html) identified on the basis
+        of the space_group and normalized_wyckoff.
+        ''')
+
+    prototype_aflow_url = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Url to the AFLOW definition of the prototype (see
+        http://aflowlib.org/CrystalDatabase/prototype_index.html) identified on the basis
+        of the space_group and normalized_wyckoff.
+        ''')
+
+    prototype_assignment_method = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Method used to identify the prototype.
+        ''')
+
+    prototype_label = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Label of the prototype identified on the basis of the space_group and
+        normalized_wyckoff. The label is in the same format as in the read_prototypes
+        function: <space_group_number>-<prototype_name>-<Pearson's symbol>).
+        ''')
+
+
+class section_run(MSection):
+    '''
+    Every section_run represents a single call of a program. What exactly is contained in
+    a run depends on the run type (see for example section_method and
+    section_single_configuration_calculation) and the program (see [program_info
+    ](program_info)).
+    '''
+
+    m_def = Section(validate=False)
+
+    calculation_file_uri = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Contains the nomad uri of a raw the data file connected to the current run. There
+        should be an value for the main_file_uri and all ancillary files.
+        ''')
+
+    message_debug_run = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        A debugging message of the computational program, associated with a run.
+        ''',
+        categories=[message_debug])
+
+    message_error_run = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        An error message of the computational program, associated with a run.
+        ''',
+        categories=[message_info, message_debug, message_warning, message_error])
+
+    message_info_run = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        An information message of the computational program, associated with a run.
+        ''',
+        categories=[message_info, message_debug])
+
+    message_warning_run = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        A warning message of the computational program, associated with a run.
+        ''',
+        categories=[message_info, message_debug, message_warning])
+
+    parsing_message_debug_run = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        This field is used for debugging messages of the parsing program associated with a
+        single configuration calculation, see section_single_configuration_calculation.
+        ''',
+        categories=[parsing_message_debug])
+
+    parsing_message_error_run = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        This field is used for error messages of the parsing program associated with a
+        run, see section_run.
+        ''',
+        categories=[parsing_message_info, parsing_message_error, parsing_message_warning, parsing_message_debug])
+
+    parsing_message_info_run = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        This field is used for info messages of the parsing program associated with a run,
+        see section_run.
+        ''',
+        categories=[parsing_message_info, parsing_message_debug])
+
+    parsing_message_warning_run = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        This field is used for warning messages of the parsing program associated with a
+        run, see section_run.
+        ''',
+        categories=[parsing_message_info, parsing_message_warning, parsing_message_debug])
+
+    program_basis_set_type = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        The type of basis set used by the program to represent wave functions.
+
+        Valid values are:
+
+        * Numeric AOs
+
+        * Gaussians
+
+        * (L)APW+lo
+
+        * FLAPW (full-potential linearized augmented planewave)
+
+        * Plane waves
+
+        * Real-space grid
+
+        * Local-orbital minimum-basis
+        ''')
+
+    program_compilation_datetime = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='second',
+        description='''
+        Contains the program compilation date and time from *Unix epoch* (00:00:00 UTC on
+        1 January 1970) in seconds. For date and times without a timezone, the default
+        timezone GMT is used.
+        ''',
+        categories=[accessory_info, program_info])
+
+    program_compilation_host = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Specifies the host on which the program was compiled.
+        ''',
+        categories=[accessory_info, program_info])
+
+    program_name = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Specifies the name of the program that generated the data.
+        ''',
+        categories=[accessory_info, program_info])
+
+    program_version = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Specifies the version of the program that was used. This should be the version
+        number of an official release, the version tag or a commit id as well as the
+        location of the repository.
+        ''',
+        categories=[accessory_info, program_info])
+
+    run_clean_end = Quantity(
+        type=bool,
+        shape=[],
+        description='''
+        Indicates whether this run terminated properly (true), or if it was killed or
+        exited with an error code unequal to zero (false).
+        ''')
+
+    run_hosts = Quantity(
+        type=typing.Any,
+        shape=[],
+        description='''
+        An associative list of host(s) that performed this simulation. This is an
+        associative list that contains program-dependent information (*key*) on how the
+        host was used (*value*). Useful for debugging purposes.
+        ''',
+        categories=[accessory_info, parallelization_info])
+
+    raw_id = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        An optional calculation id, if one is found in the code input/output files.
+        ''')
+
+    time_run_cpu1_end = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='second',
+        description='''
+        Stores the end time of the run on CPU 1.
+        ''',
+        categories=[accessory_info, time_info])
+
+    time_run_cpu1_start = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='second',
+        description='''
+        Stores the start time of the run on CPU 1.
+        ''',
+        categories=[accessory_info, time_info])
+
+    time_run_date_end = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='second',
+        description='''
+        Stores the end date of the run as time since the *Unix epoch* (00:00:00 UTC on 1
+        January 1970) in seconds. For date and times without a timezone, the default
+        timezone GMT is used.
+        ''',
+        categories=[accessory_info, time_info])
+
+    time_run_date_start = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='second',
+        description='''
+        Stores the start date of the run as time since the *Unix epoch* (00:00:00 UTC on 1
+        January 1970) in seconds. For date and times without a timezone, the default
+        timezone GMT is used.
+        ''',
+        categories=[accessory_info, time_info])
+
+    time_run_wall_end = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='second',
+        description='''
+        Stores the internal wall-clock time at the end of the run.
+        ''',
+        categories=[accessory_info, time_info])
+
+    time_run_wall_start = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='second',
+        description='''
+        Stores the internal wall-clock time from the start of the run.
+        ''',
+        categories=[accessory_info, time_info])
+
+    section_basis_set_atom_centered = SubSection(
+        sub_section=SectionProxy('section_basis_set_atom_centered'),
+        repeats=True)
+
+    section_basis_set_cell_dependent = SubSection(
+        sub_section=SectionProxy('section_basis_set_cell_dependent'),
+        repeats=True)
+
+    section_frame_sequence = SubSection(
+        sub_section=SectionProxy('section_frame_sequence'),
+        repeats=True)
+
+    section_method = SubSection(
+        sub_section=SectionProxy('section_method'),
+        repeats=True)
+
+    section_sampling_method = SubSection(
+        sub_section=SectionProxy('section_sampling_method'),
+        repeats=True)
+
+    section_single_configuration_calculation = SubSection(
+        sub_section=SectionProxy('section_single_configuration_calculation'),
+        repeats=True)
+
+    section_system = SubSection(
+        sub_section=SectionProxy('section_system'),
+        repeats=True)
+
+
+class section_sampling_method(MSection):
+    '''
+    Section containing the settings describing a (potential-energy surface) sampling
+    method.
+
+    Results and monitored quantities of such sampling are collected in a sequence of
+    frames, section_frame_sequence.
+    '''
+
+    m_def = Section(validate=False)
+
+    ensemble_type = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Kind of sampled ensemble stored in section_frame_sequence; valid values are
+        defined in [ensemble_type wiki page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-
+        meta-info/wikis/metainfo/ensemble-type).
+        ''')
+
+    geometry_optimization_energy_change = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Value of threshold for the energy_total change between two geometry optimization
+        steps, as convergence criterion of the geometry_optimization_method. A geometry
+        optimization is considered converged when the energy_total change between two
+        geometry optimization steps is below the threshold (possibly in combination with
+        other criteria)
+        ''',
+        categories=[settings_sampling, settings_geometry_optimization])
+
+    geometry_optimization_geometry_change = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='meter',
+        description='''
+        Value of threshold for the displacement of the nuclei between two geometry
+        optimization steps as convergence criterion of the geometry_optimization_method. A
+        geometry optimization is considered converged when the maximum among the
+        displacements of the nuclei between two geometry optimization steps is below the
+        threshold (possibly in combination with other criteria)
+        ''',
+        categories=[settings_sampling, settings_geometry_optimization])
+
+    geometry_optimization_method = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Algorithm for the geometry optimization. Allowed values are listed in the
+        [geometry_optimization_method wiki page](https://gitlab.mpcdf.mpg.de/nomad-
+        lab/nomad-meta-info/wikis/metainfo/geometry-optimization-method).
+        ''',
+        categories=[settings_sampling, settings_geometry_optimization])
+
+    geometry_optimization_threshold_force = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='newton',
+        description='''
+        Value of threshold for the force modulus as convergence criterion of the
+        geometry_optimization_method. A geometry optimization is considered converged when
+        the maximum of the moduli of the force on each of the atoms is below this
+        threshold (possibly in combination with other criteria)
+        ''',
+        categories=[settings_sampling, settings_geometry_optimization])
+
+    sampling_method_expansion_order = Quantity(
+        type=np.dtype(np.int32),
+        shape=[],
+        description='''
+        Order up to which the potential energy surface was expanded in a Taylor series
+        (see sampling_method).
+        ''')
+
+    sampling_method = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Type of method used to do the sampling.
+
+        Allowed values are:
+
+        | Sampling method                | Description                      |
+
+        | ------------------------------ | -------------------------------- |
+
+        | `"geometry_optimization"`      | Geometry optimization            |
+
+        | `"molecular_dynamics"`         | Molecular dynamics               |
+
+        | `"montecarlo"`                 | (Metropolis) Monte Carlo         |
+
+        | `"steered_molecular_dynamics"` | Steered molecular dynamics (with time dependent
+        external forces) |
+
+        | `"meta_dynamics"`              | Biased molecular dynamics with history-
+        dependent Hamiltonian |
+
+        | `"wang_landau_montecarlo"`     | Monte Carlo according to the Wang-Landau
+        formulation. |
+
+        | `"blue_moon"`                  | Blue Moon sampling               |
+
+        | `"langevin_dynamics"`          | Langevin dynamics                |
+
+        | `"taylor_expansion"`           | Taylor expansion of the potential energy
+        surface |
+        ''')
+
+
+class section_scf_iteration(MSection):
+    '''
+    Every section_scf_iteration represents a self-consistent field (SCF) iteration, see
+    scf_info, and gives detailed information on the SCF procedure of the specified
+    quantities.
+    '''
+
+    m_def = Section(validate=False)
+
+    electronic_kinetic_energy_scf_iteration = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Electronic kinetic energy as defined in XC_method during the self-consistent field
+        (SCF) iterations.
+        ''',
+        categories=[energy_value, energy_component])
+
+    energy_change_scf_iteration = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Stores the change of total energy with respect to the previous self-consistent
+        field (SCF) iteration.
+        ''',
+        categories=[energy_value, error_estimate_contribution])
+
+    energy_correction_entropy_scf_iteration = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Entropy correction to the potential energy to compensate for the change in
+        occupation so that forces at finite T do not need to keep the change of occupation
+        in account. The array lists the values of the entropy correction for each self-
+        consistent field (SCF) iteration. Defined consistently with XC_method.
+        ''',
+        categories=[energy_value, energy_component])
+
+    energy_correction_hartree_scf_iteration = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Correction to the density-density electrostatic energy in the sum of eigenvalues
+        (that uses the mixed density on one side), and the fully consistent density-
+        density electrostatic energy during the self-consistent field (SCF) iterations.
+        Defined consistently with XC_method.
+        ''',
+        categories=[energy_value, energy_component])
+
+    energy_electrostatic_scf_iteration = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Total electrostatic energy (nuclei + electrons) during each self-consistent field
+        (SCF) iteration.
+        ''',
+        categories=[energy_value, energy_component])
+
+    energy_free_per_atom_scf_iteration = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Free energy per atom (whose minimum gives the smeared occupation density
+        calculated with smearing_kind) calculated with XC_method during the self-
+        consistent field (SCF) iterations.
+        ''',
+        categories=[energy_value, energy_component_per_atom])
+
+    energy_free_scf_iteration = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Free energy (whose minimum gives the smeared occupation density calculated with
+        smearing_kind) calculated with the method described in XC_method during the self-
+        consistent field (SCF) iterations.
+        ''',
+        categories=[energy_component, energy_value, energy_total_potential])
+
+    energy_hartree_error_scf_iteration = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Error in the Hartree (electrostatic) potential energy during each self-consistent
+        field (SCF) iteration. Defined consistently with XC_method.
+        ''',
+        categories=[energy_value, error_estimate_contribution])
+
+    energy_sum_eigenvalues_per_atom_scf_iteration = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Value of the energy per atom, where the energy is defined as the sum of the
+        eigenvalues of the Hamiltonian matrix given by XC_method, during each self-
+        consistent field (SCF) iteration.
+        ''',
+        categories=[energy_value, energy_component_per_atom])
+
+    energy_sum_eigenvalues_scf_iteration = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Sum of the eigenvalues of the Hamiltonian matrix defined by XC_method, during each
+        self-consistent field (SCF) iteration.
+        ''',
+        categories=[energy_value, energy_component])
+
+    energy_total_scf_iteration = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Value of the total electronic energy calculated with the method described in
+        XC_method during each self-consistent field (SCF) iteration.
+        ''',
+        categories=[energy_component, energy_value, energy_total_potential])
+
+    energy_total_T0_per_atom_scf_iteration = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Value of the total energy, calculated with the method described in XC_method per
+        atom extrapolated to $T=0$, based on a free-electron gas argument, during each
+        self-consistent field (SCF) iteration.
+        ''',
+        categories=[energy_total_potential_per_atom, energy_value, energy_component])
+
+    energy_total_T0_scf_iteration = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Value of the total energy (or equivalently free energy), calculated with the
+        method described in XC_method and extrapolated to $T=0$, based on a free-electron
+        gas argument, during each self-consistent field (SCF) iteration.
+        ''',
+        categories=[energy_component, energy_value, energy_total_potential])
+
+    energy_XC_potential_scf_iteration = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Value for exchange-correlation (XC) potential energy: the integral of the first
+        order derivative of the functional stored in XC_functional (integral of
+        v_xc*electron_density), i.e., the component of XC that is in the sum of the
+        eigenvalues. Values are given for each self-consistent field (SCF) iteration
+        (i.e., not the converged value, the latter being stored in energy_XC_potential).
+        ''',
+        categories=[energy_value, energy_component])
+
+    energy_XC_scf_iteration = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Value for exchange-correlation (XC) energy obtained during each self-consistent
+        field (SCF) iteration, using the method described in XC_method.
+        ''',
+        categories=[energy_value, energy_component])
+
+    spin_S2_scf_iteration = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        description='''
+        Stores the value of the total spin moment operator $S^2$ during the self-
+        consistent field (SCF) iterations of the XC_method. It can be used to calculate
+        the spin contamination in spin-unrestricted calculations.
+        ''')
+
+    time_scf_iteration_cpu1_end = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='second',
+        description='''
+        Stores the end time of a self-consistent field (SCF) iteration on CPU 1.
+        ''',
+        categories=[accessory_info, time_info])
+
+    time_scf_iteration_cpu1_start = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='second',
+        description='''
+        Stores the start time of a self-consistent field (SCF) iteration on CPU 1.
+        ''',
+        categories=[accessory_info, time_info])
+
+    time_scf_iteration_date_end = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='second',
+        description='''
+        Stores the end date of a self-consistent field (SCF) iteration as time since the
+        *Unix epoch* (00:00:00 UTC on 1 January 1970) in seconds. For date and times
+        without a timezone, the default timezone GMT is used.
+        ''',
+        categories=[accessory_info, time_info])
+
+    time_scf_iteration_date_start = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='second',
+        description='''
+        Stores the start date of a self-consistent field (SCF) iteration as time since the
+        *Unix epoch* (00:00:00 UTC on 1 January 1970) in seconds. For date and times
+        without a timezone, the default timezone GMT is used.
+        ''',
+        categories=[accessory_info, time_info])
+
+    time_scf_iteration_wall_end = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='second',
+        description='''
+        Stores the internal wall-clock time at the end of a self-consistent field (SCF)
+        iteration.
+        ''',
+        categories=[accessory_info, time_info])
+
+    time_scf_iteration_wall_start = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='second',
+        description='''
+        Stores the internal wall-clock time from the start of a self-consistent field
+        (SCF) iteration.
+        ''',
+        categories=[accessory_info, time_info])
+
+
+class section_single_configuration_calculation(MSection):
+    '''
+    Every section_single_configuration_calculation section contains the values computed
+    during a *single configuration calculation*, i.e. a calculation performed on a given
+    configuration of the system (as defined in section_system) and a given computational
+    method (e.g., exchange-correlation method, basis sets, as defined in section_method).
+
+    The link between the current section_single_configuration_calculation and the related
+    section_system and section_method sections is established by the values stored in
+    single_configuration_calculation_to_system_ref and
+    single_configuration_to_calculation_method_ref, respectively.
+
+    The reason why information on the system configuration and computational method is
+    stored separately is that several *single configuration calculations* can be performed
+    on the same system configuration, viz. several system configurations can be evaluated
+    with the same computational method. This storage strategy avoids redundancies.
+    '''
+
+    m_def = Section(validate=False)
+
+    atom_forces_free_raw = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_atoms', 3],
+        unit='newton',
+        description='''
+        Forces acting on the atoms, calculated as minus gradient of energy_free,
+        **without** constraints. The derivatives with respect to displacements of nuclei
+        are evaluated in Cartesian coordinates. The (electronic) energy_free contains the
+        change in (fractional) occupation of the electronic eigenstates, which are
+        accounted for in the derivatives, yielding a truly energy-conserved quantity.
+        These forces may contain unitary transformations (center-of-mass translations and
+        rigid rotations for non-periodic systems) that are normally filtered separately
+        (see atom_forces_free for the filtered counterpart). Forces due to constraints
+        such as fixed atoms, distances, angles, dihedrals, etc. are also considered
+        separately (see atom_forces_free for the filtered counterpart).
+        ''',
+        categories=[atom_forces_type])
+
+    atom_forces_free = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_atoms', 3],
+        unit='newton',
+        description='''
+        Forces acting on the atoms, calculated as minus gradient of energy_free,
+        **including** constraints, if present. The derivatives with respect to
+        displacements of the nuclei are evaluated in Cartesian coordinates. The
+        (electronic) energy_free contains the information on the change in (fractional)
+        occupation of the electronic eigenstates, which are accounted for in the
+        derivatives, yielding a truly energy-conserved quantity. In addition, these forces
+        are obtained by filtering out the unitary transformations (center-of-mass
+        translations and rigid rotations for non-periodic systems, see
+        atom_forces_free_raw for the unfiltered counterpart). Forces due to constraints
+        such as fixed atoms, distances, angles, dihedrals, etc. are included (see
+        atom_forces_free_raw for the unfiltered counterpart).
+        ''',
+        categories=[atom_forces_type])
+
+    atom_forces_raw = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_atoms', 3],
+        unit='newton',
+        description='''
+        Forces acting on the atoms, calculated as minus gradient of energy_total,
+        **without** constraints. The derivatives with respect to displacements of the
+        nuclei are evaluated in Cartesian coordinates. These forces may contain unitary
+        transformations (center-of-mass translations and rigid rotations for non-periodic
+        systems) that are normally filtered separately (see atom_forces for the filtered
+        counterpart). Forces due to constraints such as fixed atoms, distances, angles,
+        dihedrals, etc. are also considered separately (see atom_forces for the filtered
+        counterpart).
+        ''',
+        categories=[atom_forces_type])
+
+    atom_forces_T0_raw = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_atoms', 3],
+        unit='newton',
+        description='''
+        Forces acting on the atoms, calculated as minus gradient of energy_total_T0,
+        **without** constraints. The derivatives with respect to displacements of the
+        nuclei are evaluated in Cartesian coordinates. These forces may contain unitary
+        transformations (center-of-mass translations and rigid rotations for non-periodic
+        systems) that are normally filtered separately (see atom_forces_T0 for the
+        filtered counterpart). Forces due to constraints such as fixed atoms, distances,
+        angles, dihedrals, etc. are also considered separately (see atom_forces_T0 for the
+        filtered counterpart).
+        ''',
+        categories=[atom_forces_type])
+
+    atom_forces_T0 = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_atoms', 3],
+        unit='newton',
+        description='''
+        Forces acting on the atoms, calculated as minus gradient of energy_total_T0,
+        **including** constraints, if present. The derivatives with respect to
+        displacements of the nuclei are evaluated in Cartesian coordinates. In addition,
+        these forces are obtained by filtering out the unitary transformations (center-of-
+        mass translations and rigid rotations for non-periodic systems, see
+        atom_forces_free_T0_raw for the unfiltered counterpart). Forces due to constraints
+        such as fixed atoms, distances, angles, dihedrals, etc. are also included (see
+        atom_forces_free_T0_raw for the unfiltered counterpart).
+        ''',
+        categories=[atom_forces_type])
+
+    atom_forces = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_atoms', 3],
+        unit='newton',
+        description='''
+        Forces acting on the atoms, calculated as minus gradient of energy_total,
+        **including** constraints, if present. The derivatives with respect to
+        displacements of nuclei are evaluated in Cartesian coordinates. In addition, these
+        forces are obtained by filtering out the unitary transformations (center-of-mass
+        translations and rigid rotations for non-periodic systems, see
+        atom_forces_free_raw for the unfiltered counterpart). Forces due to constraints
+        such as fixed atoms, distances, angles, dihedrals, etc. are included (see
+        atom_forces_raw for the unfiltered counterpart).
+        ''',
+        categories=[atom_forces_type])
+
+    electronic_kinetic_energy = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Self-consistent electronic kinetic energy as defined in XC_method.
+        ''',
+        categories=[energy_value, energy_component])
+
+    energy_C = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Correlation (C) energy calculated with the method described in XC_functional.
+        ''',
+        categories=[energy_value, energy_type_C, energy_component])
+
+    energy_correction_entropy = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Entropy correction to the potential energy to compensate for the change in
+        occupation so that forces at finite T do not need to keep the change of occupation
+        in account. Defined consistently with XC_method.
+        ''',
+        categories=[energy_value, energy_component])
+
+    energy_correction_hartree = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Correction to the density-density electrostatic energy in the sum of eigenvalues
+        (that uses the mixed density on one side), and the fully consistent density-
+        density electrostatic energy. Defined consistently with XC_method.
+        ''',
+        categories=[energy_value, energy_component])
+
+    energy_current = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Value of the energy calculated with calculation_method_current. energy_current is
+        equal to energy_total for non-perturbative methods. For perturbative methods,
+        energy_current is equal to the correction: energy_total minus energy_total of the
+        calculation_to_calculation_ref with calculation_to_calculation_kind =
+        starting_point (see the [method_to_method_kind wiki
+        page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/method-
+        to-method-kind)). See also [energy_current wiki
+        page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/energy-
+        current).
+        ''',
+        categories=[energy_component, energy_value, energy_total_potential])
+
+    energy_electrostatic = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Total electrostatic energy (nuclei + electrons), defined consistently with
+        calculation_method.
+        ''',
+        categories=[energy_value, energy_component])
+
+    energy_free_per_atom = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Free energy per atom (whose minimum gives the smeared occupation density
+        calculated with smearing_kind) calculated with XC_method.
+        ''',
+        categories=[energy_value, energy_component_per_atom])
+
+    energy_free = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Free energy (nuclei + electrons) (whose minimum gives the smeared occupation
+        density calculated with smearing_kind) calculated with the method described in
+        XC_method.
+        ''',
+        categories=[energy_component, energy_value, energy_total_potential])
+
+    energy_hartree_error = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Error in the Hartree (electrostatic) potential energy. Defined consistently with
+        XC_method.
+        ''',
+        categories=[energy_value, error_estimate_contribution])
+
+    energy_hartree_fock_X_scaled = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Scaled exact-exchange energy that depends on the mixing parameter of the
+        functional. For example in hybrid functionals, the exchange energy is given as a
+        linear combination of exact-energy and exchange energy of an approximate DFT
+        functional; the exact exchange energy multiplied by the mixing coefficient of the
+        hybrid functional would be stored in this metadata. Defined consistently with
+        XC_method.
+        ''',
+        categories=[energy_value, energy_component])
+
+    energy_hartree_fock_X = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Converged exact-exchange (Hartree-Fock) energy. Defined consistently with
+        XC_method.
+        ''',
+        categories=[energy_type_X, energy_value, energy_component])
+
+    energy_method_current = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Value of the energy calculated with the method calculation_method_current.
+        Depending on calculation_method_kind it might be a total energy or only a
+        correction.
+        ''',
+        categories=[energy_value, energy_component])
+
+    energy_sum_eigenvalues_per_atom = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Value of the energy per atom, where the energy is defined as the sum of the
+        eigenvalues of the Hamiltonian matrix given by XC_method.
+        ''',
+        categories=[energy_value, energy_component_per_atom])
+
+    energy_sum_eigenvalues = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Sum of the eigenvalues of the Hamiltonian matrix defined by XC_method.
+        ''',
+        categories=[energy_value, energy_component])
+
+    energy_T0_per_atom = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Value of the total energy per atom, calculated with the method described in
+        XC_method and extrapolated to $T=0$, based on a free-electron gas argument.
+        ''',
+        categories=[energy_total_potential_per_atom, energy_value, energy_component])
+
+    energy_total_T0_per_atom = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Value of the total energy, calculated with the method described in XC_method per
+        atom extrapolated to $T=0$, based on a free-electron gas argument.
+        ''',
+        categories=[energy_total_potential_per_atom, energy_value, energy_component])
+
+    energy_total_T0 = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Value of the total energy (or equivalently free energy), calculated with the
+        method described in XC_method and extrapolated to $T=0$, based on a free-electron
+        gas argument.
+        ''',
+        categories=[energy_component, energy_value, energy_total_potential])
+
+    energy_total = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Value of the total energy, calculated with the method described in XC_method and
+        extrapolated to $T=0$, based on a free-electron gas argument.
+        ''',
+        categories=[energy_component, energy_value, energy_total_potential])
+
+    energy_XC_functional = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Value of the exchange-correlation (XC) energy calculated with the functional
+        stored in XC_functional.
+        ''',
+        categories=[energy_type_XC, energy_value, energy_component])
+
+    energy_XC_potential = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Value of the exchange-correlation (XC) potential energy: the integral of the first
+        order derivative of the functional stored in XC_functional (integral of
+        v_xc*electron_density), i.e., the component of XC that is in the sum of the
+        eigenvalues. Value associated with the configuration, should be the most converged
+        value.
+        ''',
+        categories=[energy_value, energy_component])
+
+    energy_XC = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Value of the exchange-correlation (XC) energy calculated with the method described
+        in XC_method.
+        ''',
+        categories=[energy_type_XC, energy_value, energy_component])
+
+    energy_X = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='joule',
+        description='''
+        Value fo the exchange (X) energy calculated with the method described in
+        XC_method.
+        ''',
+        categories=[energy_type_X, energy_value, energy_component])
+
+    energy_zero_point = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        description='''
+        Value for the converged zero-point vibrations energy calculated using the method
+        described in zero_point_method , and used in energy_current .
+        ''')
+
+    hessian_matrix = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_atoms', 'number_of_atoms', 3, 3],
+        description='''
+        The matrix with the second derivative with respect to atom displacements.
+        ''')
+
+    message_debug_evaluation = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        A debugging message of the computational program, associated with a *single
+        configuration calculation* (see section_single_configuration_calculation).
+        ''',
+        categories=[message_debug])
+
+    message_error_evaluation = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        An error message of the computational program, associated with a *single
+        configuration calculation* (see section_single_configuration_calculation).
+        ''',
+        categories=[message_info, message_debug, message_warning, message_error])
+
+    message_info_evaluation = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        An information message of the computational program, associated with a *single
+        configuration calculation* (see section_single_configuration_calculation).
+        ''',
+        categories=[message_info, message_debug])
+
+    message_warning_evaluation = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        A warning message of the computational program.
+        ''',
+        categories=[message_info, message_debug, message_warning])
+
+    number_of_scf_iterations = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Gives the number of performed self-consistent field (SCF) iterations at a specfied
+        level of theory.
+        ''',
+        categories=[scf_info])
+
+    parsing_message_debug_evaluation = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        This field is used for debugging messages of the parsing program associated with a
+        run, see section_run.
+        ''',
+        categories=[parsing_message_debug])
+
+    parsing_message_error_single_configuration = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        This field is used for error messages of the parsing program associated with a
+        single configuration calculation, see section_single_configuration_calculation.
+        ''',
+        categories=[parsing_message_info, parsing_message_error, parsing_message_warning, parsing_message_debug])
+
+    parsing_message_info_single_configuration = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        This field is used for info messages of the parsing program associated with a
+        single configuration calculation, see section_single_configuration_calculation.
+        ''',
+        categories=[parsing_message_info, parsing_message_debug])
+
+    parsing_message_warning_evaluation = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        This field is used for warning messages of the parsing program associated with a
+        run, see section_run.
+        ''',
+        categories=[parsing_message_info, parsing_message_warning, parsing_message_debug])
+
+    single_configuration_calculation_converged = Quantity(
+        type=bool,
+        shape=[],
+        description='''
+        Determines whether a *single configuration calculation* in
+        section_single_configuration_calculation is converged.
+        ''')
+
+    single_configuration_calculation_to_system_ref = Quantity(
+        type=Reference(SectionProxy('section_system')),
+        shape=[],
+        description='''
+        Reference to the system (atomic configuration, cell, ...) that is calculated in
+        section_single_configuration_calculation.
+        ''')
+
+    single_configuration_to_calculation_method_ref = Quantity(
+        type=Reference(SectionProxy('section_method')),
+        shape=[],
+        description='''
+        Reference to the method used for the calculation in
+        section_single_configuration_calculation.
+        ''')
+
+    spin_S2 = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        description='''
+        Stores the value of the total spin moment operator $S^2$ for the converged
+        wavefunctions calculated with the XC_method. It can be used to calculate the spin
+        contamination in spin-unrestricted calculations.
+        ''')
+
+    stress_tensor = Quantity(
+        type=np.dtype(np.float64),
+        shape=[3, 3],
+        unit='pascal',
+        description='''
+        Stores the final value of the default stress tensor consistent with energy_total
+        and calculated with the method specified in stress_tensor_method.
+
+        This value is used (if needed) for, e.g., molecular dynamics and geometry
+        optimization. Alternative definitions of the stress tensor can be assigned with
+        stress_tensor_kind
+        ''',
+        categories=[stress_tensor_type])
+
+    time_calculation = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='second',
+        description='''
+        Stores the wall-clock time needed for a calculation using
+        calculation_method_current. Basically, it tracks the real time that has been
+        elapsed from start to end.
+        ''',
+        categories=[accessory_info, time_info])
+
+    time_single_configuration_calculation_cpu1_end = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='second',
+        description='''
+        Stores the end time of the *single configuration calculation* (see
+        section_single_configuration_calculation) on CPU 1.
+        ''',
+        categories=[accessory_info, time_info])
+
+    time_single_configuration_calculation_cpu1_start = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='second',
+        description='''
+        Stores the start time of the *single configuration calculation* (see
+        section_single_configuration_calculation) on CPU 1.
+        ''',
+        categories=[accessory_info, time_info])
+
+    time_single_configuration_calculation_date_end = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='second',
+        description='''
+        Stores the end date of the *single configuration calculation* (see
+        section_single_configuration_calculation) as time since the *Unix epoch* (00:00:00
+        UTC on 1 January 1970) in seconds. For date and times without a timezone, the
+        default timezone GMT is used.
+        ''',
+        categories=[accessory_info, time_info])
+
+    time_single_configuration_calculation_date_start = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='second',
+        description='''
+        Stores the start date of the *single configuration calculation* (see
+        section_single_configuration_calculation) as time since the *Unix epoch* (00:00:00
+        UTC on 1 January 1970) in seconds. For date and times without a timezone, the
+        default timezone GMT is used.
+        ''',
+        categories=[accessory_info, time_info])
+
+    time_single_configuration_calculation_wall_end = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='second',
+        description='''
+        Stores the internal wall-clock time at the end of the *single configuration
+        calculation* (see section_single_configuration_calculation).
+        ''',
+        categories=[accessory_info, time_info])
+
+    time_single_configuration_calculation_wall_start = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        unit='second',
+        description='''
+        Stores the internal wall-clock time from the start of the *single configuration
+        calculation* (see section_single_configuration_calculation).
+        ''',
+        categories=[accessory_info, time_info])
+
+    zero_point_method = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Describes the zero-point vibrations method. If skipped or an empty string is used,
+        it means no zero-point vibrations correction is applied.
+        ''')
+
+    section_atom_projected_dos = SubSection(
+        sub_section=SectionProxy('section_atom_projected_dos'),
+        repeats=True)
+
+    section_atomic_multipoles = SubSection(
+        sub_section=SectionProxy('section_atomic_multipoles'),
+        repeats=True)
+
+    section_basis_set = SubSection(
+        sub_section=SectionProxy('section_basis_set'),
+        repeats=True)
+
+    section_calculation_to_calculation_refs = SubSection(
+        sub_section=SectionProxy('section_calculation_to_calculation_refs'),
+        repeats=True)
+
+    section_calculation_to_folder_refs = SubSection(
+        sub_section=SectionProxy('section_calculation_to_folder_refs'),
+        repeats=True)
+
+    section_dos = SubSection(
+        sub_section=SectionProxy('section_dos'),
+        repeats=True)
+
+    section_eigenvalues = SubSection(
+        sub_section=SectionProxy('section_eigenvalues'),
+        repeats=True)
+
+    section_energy_code_independent = SubSection(
+        sub_section=SectionProxy('section_energy_code_independent'),
+        repeats=True)
+
+    section_energy_van_der_Waals = SubSection(
+        sub_section=SectionProxy('section_energy_van_der_Waals'),
+        repeats=True)
+
+    section_k_band_normalized = SubSection(
+        sub_section=SectionProxy('section_k_band_normalized'),
+        repeats=True)
+
+    section_k_band = SubSection(
+        sub_section=SectionProxy('section_k_band'),
+        repeats=True)
+
+    section_scf_iteration = SubSection(
+        sub_section=SectionProxy('section_scf_iteration'),
+        repeats=True)
+
+    section_species_projected_dos = SubSection(
+        sub_section=SectionProxy('section_species_projected_dos'),
+        repeats=True)
+
+    section_stress_tensor = SubSection(
+        sub_section=SectionProxy('section_stress_tensor'),
+        repeats=True)
+
+    section_volumetric_data = SubSection(
+        sub_section=SectionProxy('section_volumetric_data'),
+        repeats=True)
+
+
+class section_species_projected_dos(MSection):
+    '''
+    Section collecting the information on a species-projected density of states (DOS)
+    evaluation.
+    '''
+
+    m_def = Section(validate=False)
+
+    number_of_lm_species_projected_dos = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Gives the number of $l$, $m$ combinations for the species-projected density of
+        states (DOS) defined in section_species_projected_dos.
+        ''')
+
+    number_of_species_projected_dos_values = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Gives the number of energy values for the species-projected density of states
+        (DOS) defined in section_species_projected_dos.
+        ''')
+
+    number_of_species = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Gives the number of species for the species-projected density of states (DOS)
+        defined in section_species_projected_dos.
+        ''')
+
+    species_projected_dos_energies_normalized = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_species_projected_dos_values'],
+        unit='joule',
+        description='''
+        Contains the set of discrete energy values with respect to the top of the valence
+        band for the species-projected density of states (DOS). It is derived from the
+        species_projected_dos_energies species field.
+        ''')
+
+    species_projected_dos_energies = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_species_projected_dos_values'],
+        unit='joule',
+        description='''
+        Contains the set of discrete energy values for the species-projected density of
+        states (DOS).
+        ''')
+
+    species_projected_dos_lm = Quantity(
+        type=np.dtype(np.int32),
+        shape=['number_of_lm_species_projected_dos', 2],
+        description='''
+        Consists of tuples of $l$ and $m$ values for all given values in the
+        species_projected_dos_values_lm species field.
+
+        The quantum number $l$ represents the azimuthal quantum number, whereas for the
+        quantum number $m$, besides the conventional use as magnetic quantum number ($l+1$
+        integer values from $-l$ to $l$), a set of different conventions is accepted. The
+        adopted convention is specified by atom_projected_dos_m_kind.
+        ''')
+
+    species_projected_dos_m_kind = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Specifies the kind of the integer numbers $m$ used in species_projected_dos_lm.
+
+        Allowed values are listed in the [m_kind wiki
+        page](https://gitlab.rzg.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/m-kind)
+        and can be (quantum) numbers of
+
+        * spherical
+
+        * polynomial
+
+        * real_orbital
+
+        * integrated
+
+        functions or values.
+        ''')
+
+    species_projected_dos_species_label = Quantity(
+        type=str,
+        shape=['number_of_species'],
+        description='''
+        Contains labels of the atomic species for the species-projected density of states
+        (DOS).
+
+        Differently from atom_labels, which allow more than one label for the same atomic
+        species (by adding a number or a string to the label), this list is expected to
+        refer to actual atomic species, i.e. belonging to the periodic table of elements.
+        Thus, the species-projected DOS are expected to be as many as the different atomic
+        species in the system.
+        ''')
+
+    species_projected_dos_values_lm = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_lm_species_projected_dos', 'number_of_spin_channels', 'number_of_species', 'number_of_species_projected_dos_values'],
+        description='''
+        Holds species-projected density of states (DOS) values, divided into contributions
+        from each $l,m$ channel.
+
+        Here, there are as many species-projected DOS as the number of species,
+        number_of_species. The list of labels of the species is given in
+        species_projected_dos_species_label.
+        ''')
+
+    species_projected_dos_values_total = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_spin_channels', 'number_of_species', 'number_of_species_projected_dos_values'],
+        description='''
+        Holds species-projected density of states (DOS) values, summed up over all
+        azimuthal quantum numbers $l$.
+
+        Here, there are as many species-projected DOS as the number of species,
+        number_of_species. The list of labels of the species is given in
+        species_projected_dos_species_label.
+        ''')
+
+
+class section_springer_material(MSection):
+    '''
+    Every section_springer_material contains results of classification of materials with
+    the same formula according to Springer Materials - it contains
+    section_springer_classsification, section_springer_compound, section_springer_id,
+    section_springer_references
+    '''
+
+    m_def = Section(validate=False)
+
+    springer_id = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Id of the classified material according to Springer Materials
+        ''')
+
+    springer_alphabetical_formula = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        The alphabetical formula of the material according to Springer Materials Database
+        ''')
+
+    springer_url = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Url to the source page in Springer Materials describing the current entry
+        ''')
+
+    springer_compound_class = Quantity(
+        type=str,
+        shape=['N'],
+        description='''
+        Name of a class of the current compound, as defined in by Springer Materials. This
+        is a property of the chemical formula of the compound
+        ''')
+
+    springer_classification = Quantity(
+        type=str,
+        shape=['N'],
+        description='''
+        Contains the classification name of the current material according to Springer
+        Materials
+        ''')
+
+    section_springer_id = SubSection(
+        sub_section=SectionProxy('section_springer_id'),
+        repeats=True)
+
+
+class section_springer_id(MSection):
+    '''
+    Identifiers used by Springer Materials
+    '''
+
+    m_def = Section(validate=False)
+
+
+class section_std_system(MSection):
+    '''
+    Section containing symmetry information that is specific to the standardized system.
+    The standardized system is defined as given by spglib and the details can be found
+    from https://arxiv.org/abs/1506.01455
+    '''
+
+    m_def = Section(validate=False)
+
+    atom_positions_std = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_atoms_std', 3],
+        description='''
+        Standardized atom positions in reduced units.
+        ''')
+
+    atomic_numbers_std = Quantity(
+        type=np.dtype(np.int32),
+        shape=['number_of_atoms_std'],
+        description='''
+        Atomic numbers of the atoms in the standardized cell.
+        ''')
+
+    equivalent_atoms_std = Quantity(
+        type=np.dtype(np.int32),
+        shape=['number_of_atoms_std'],
+        description='''
+        Gives a mapping table of atoms to symmetrically independent atoms in the
+        standardized cell. This is used to find symmetrically equivalent atoms.
+        ''')
+
+    lattice_vectors_std = Quantity(
+        type=np.dtype(np.float64),
+        shape=[3, 3],
+        unit='meter',
+        description='''
+        Standardized lattice vectors of the conventional cell. The vectors are the rows of
+        this matrix.
+        ''')
+
+    number_of_atoms_std = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Number of atoms in standardized system.
+        ''')
+
+    wyckoff_letters_std = Quantity(
+        type=str,
+        shape=['number_of_atoms_std'],
+        description='''
+        Wyckoff letters for atoms in the standardized cell.
+        ''')
+
+
+class section_stress_tensor(MSection):
+    '''
+    Section collecting alternative values to stress_tensor that have been calculated.
+
+    This section allows the storage of multiple definitions and evaluated values of the
+    stress tensor, while only one definition is used for, e.g., molecular dynamics or
+    geometry optimization (if needed).
+    '''
+
+    m_def = Section(validate=False)
+
+    stress_tensor_kind = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Specifies the method used to compute the stress tensor stored in
+        stress_tensor_value. This is an *alternative* to the stress tensor defined in
+        stress_tensor_method, which is stored in stress_tensor.
+
+        This field allows for multiple definitions and evaluated values of the stress
+        tensor, while only one definition is used for, e.g., molecular dynamics and
+        geometry optimization.
+        ''')
+
+    stress_tensor_value = Quantity(
+        type=np.dtype(np.float64),
+        shape=[3, 3],
+        unit='pascal',
+        description='''
+        Contains the value of the stress tensor of the kind defined in stress_tensor_kind.
+        This is an *alternative* to the stress tensor defined in stress_tensor_method.
+
+        This field allows for multiple definitions and evaluated values of the stress
+        tensor, while only one definition is used for, e.g., molecular dynamics and
+        geometry optimization.
+        ''',
+        categories=[stress_tensor_type])
+
+
+class section_symmetry(MSection):
+    '''
+    Section containing information about the symmetry properties of the system.
+    '''
+
+    m_def = Section(validate=False)
+
+    bravais_lattice = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Identifier for the Bravais lattice in Pearson notation. The first lowercase letter
+        identifies the crystal family and can be one of the following: a (triclinic), b
+        (monoclinic), o (orthorhombic), t (tetragonal), h (hexagonal) or c (cubic). The
+        second uppercase letter identifies the centring and can be one of the following: P
+        (primitive), S (face centred), I (body centred), R (rhombohedral centring) or F
+        (all faces centred).
+        ''')
+
+    choice = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        String that specifies the centering, origin and basis vector settings of the 3D
+        space group that defines the symmetry group of the simulated physical system (see
+        section_system). Values are as defined by spglib.
+        ''')
+
+    crystal_system = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Name of the crystal system. Can be one of the following: triclinic, monoclinic,
+        orthorhombic, tetragonal, trigonal, hexagonal or cubic.
+        ''')
+
+    hall_number = Quantity(
+        type=np.dtype(np.int32),
+        shape=[],
+        description='''
+        The Hall number for this system.
+        ''')
+
+    hall_symbol = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        The Hall symbol for this system.
+        ''')
+
+    international_short_symbol = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Specifies the International Union of Crystallography (IUC) short symbol of the 3D
+        space group of this system
+        ''')
+
+    origin_shift = Quantity(
+        type=np.dtype(np.float64),
+        shape=[3],
+        description='''
+        Vector $\\mathbf{p}$ from the origin of the standardized system to the origin of
+        the original system. Together with the matrix $\\mathbf{P}$, found in
+        space_group_3D_transformation_matrix, the transformation between the standardized
+        coordinates $\\mathbf{x}_s$ and original coordinates $\\mathbf{x}$ is then given by
+        $\\mathbf{x}_s = \\mathbf{P} \\mathbf{x} + \\mathbf{p}$.
+        ''')
+
+    point_group = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Symbol of the crystallographic point group in the Hermann-Mauguin notation.
+        ''')
+
+    space_group_number = Quantity(
+        type=np.dtype(np.int32),
+        shape=[],
+        description='''
+        Specifies the International Union of Crystallography (IUC) number of the 3D space
+        group of this system.
+        ''')
+
+    symmetry_method = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Identifies the source of the symmetry information contained within this section.
+        If equal to 'spg_normalized' the information comes from a normalization step.
+        ''')
+
+    transformation_matrix = Quantity(
+        type=np.dtype(np.float64),
+        shape=[3, 3],
+        description='''
+        Matrix $\\mathbf{P}$ that is used to transform the standardized coordinates to the
+        original coordinates. Together with the vector $\\mathbf{p}$, found in
+        space_group_3D_origin_shift, the transformation between the standardized
+        coordinates $\\mathbf{x}_s$ and original coordinates $\\mathbf{x}$ is then given by
+        $\\mathbf{x}_s = \\mathbf{P} \\mathbf{x} + \\mathbf{p}$.
+        ''')
+
+    section_original_system = SubSection(
+        sub_section=SectionProxy('section_original_system'),
+        repeats=True)
+
+    section_primitive_system = SubSection(
+        sub_section=SectionProxy('section_primitive_system'),
+        repeats=True)
+
+    section_std_system = SubSection(
+        sub_section=SectionProxy('section_std_system'),
+        repeats=True)
+
+
+class section_system_to_system_refs(MSection):
+    '''
+    Section that describes the relationship between different section_system sections.
+
+    For instance, if a phonon calculation using a finite difference approach is performed
+    the force evaluation is typically done in a larger supercell but the properties such
+    as the phonon band structure are still calculated for the primitive cell.
+
+    The kind of relationship between the system defined in this section and the referenced
+    one is described by system_to_system_kind. The referenced section_system is identified
+    via system_to_system_ref.
+    '''
+
+    m_def = Section(validate=False)
+
+    system_to_system_kind = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        String defining the relationship between the referenced section_system and the
+        present section_system. Often systems are connected for example if a phonon
+        calculation using finite differences is performed the force ealuation is done in a
+        larger supercell but properties such as the phonon band structure are still
+        calculated for the primitive cell. Hence, the need of keeping track of these
+        connected systems. The referenced system is identified via system_to_system_ref.
+        ''')
+
+    system_to_system_ref = Quantity(
+        type=Reference(SectionProxy('section_system')),
+        shape=[],
+        description='''
+        Reference to another system. The kind of relationship between the present and the
+        referenced section_system is specified by system_to_system_kind.
+        ''')
+
+
+class section_system(MSection):
+    '''
+    Every section_system contains all needed properties required to describe the simulated
+    physical system, e.g. the given atomic configuration, the definition of periodic cell
+    (if present), the external potentials and other parameters.
+    '''
+
+    m_def = Section(validate=False)
+
+    atom_atom_number = Quantity(
+        type=np.dtype(np.int32),
+        shape=['number_of_sites'],
+        description='''
+        Atomic number Z of the atom.
+        ''')
+
+    atom_concentrations = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_atoms'],
+        description='''
+        concentration of the atom species in a variable composition, by default it should
+        be considered an array of ones. Summing these should give the number_of_sites
+        ''')
+
+    atom_labels = Quantity(
+        type=str,
+        shape=['number_of_atoms'],
+        description='''
+        Labels of the atoms. These strings identify the atom kind and conventionally start
+        with the symbol of the atomic species, possibly followed by the atomic number. The
+        same atomic species can be labeled with more than one atom_labels in order to
+        distinguish, e.g., atoms of the same species assigned to different atom-centered
+        basis sets or pseudo-potentials, or simply atoms in different locations in the
+        structure (e.g., bulk and surface). These labels can also be used for *particles*
+        that do not correspond to physical atoms (e.g., ghost atoms in some codes using
+        atom-centered basis sets). This metadata defines a configuration and is therefore
+        required.
+        ''',
+        categories=[configuration_core])
+
+    atom_positions = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_atoms', 3],
+        unit='meter',
+        description='''
+        Positions of all the atoms, in Cartesian coordinates. This metadata defines a
+        configuration and is therefore required. For alloys where concentrations of
+        species are given for each site in the unit cell, it stores the position of the
+        sites.
+        ''',
+        categories=[configuration_core])
+
+    atom_species = Quantity(
+        type=np.dtype(np.int32),
+        shape=['number_of_atoms'],
+        description='''
+        Species of the atom (normally the atomic number Z, 0 or negative for unidentifed
+        species or particles that are not atoms.
+        ''')
+
+    atom_velocities = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_atoms', 3],
+        unit='meter / second',
+        description='''
+        Velocities of the nuclei, defined as the change in Cartesian coordinates of the
+        nuclei with respect to time.
+        ''')
+
+    configuration_periodic_dimensions = Quantity(
+        type=bool,
+        shape=[3],
+        description='''
+        Array labeling which of the lattice vectors use periodic boundary conditions. Note
+        for the parser developers: This value is not expected to be given for each
+        section_single_configuration_calculation. It is assumed to be valid from the
+        section_single_configuration_calculation where it is defined for all subsequent
+        section_single_configuration_calculation in section_run, until redefined.
+        ''',
+        categories=[configuration_core])
+
+    configuration_raw_gid = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        checksum of the configuration_core, i.e. the geometry of the system. The values
+        are not normalized in any way so equivalent configurations might have different
+        values
+        ''')
+
+    embedded_system = Quantity(
+        type=bool,
+        shape=[],
+        description='''
+        Is the system embedded into a host geometry?.
+        ''',
+        categories=[configuration_core])
+
+    lattice_vectors = Quantity(
+        type=np.dtype(np.float64),
+        shape=[3, 3],
+        unit='meter',
+        description='''
+        Holds the lattice vectors (in Cartesian coordinates) of the simulation cell. The
+        last (fastest) index runs over the $x,y,z$ Cartesian coordinates, and the first
+        index runs over the 3 lattice vectors.
+        ''',
+        categories=[configuration_core])
+
+    local_rotations = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_atoms', 3, 3],
+        description='''
+        A rotation matrix defining the orientation of each atom. If the rotation matrix
+        only needs to be specified for some atoms, the remaining atoms should set it to
+        the zero matrix (not the identity!)
+        ''')
+
+    number_of_atoms = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Stores the total number of atoms used in the calculation. For alloys where
+        concentrations of species are given for each site in the unit cell, it stores the
+        number of sites.
+        ''')
+
+    number_of_sites = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        number of sites in a variable composition representation. By default (no variable
+        composition) it is the same as number_of_atoms.
+        ''')
+
+    SC_matrix = Quantity(
+        type=np.dtype(np.int32),
+        shape=[3, 3],
+        description='''
+        Specifies the matrix that transforms the unit-cell into the super-cell in which
+        the actual calculation is performed.
+        ''')
+
+    simulation_cell = Quantity(
+        type=np.dtype(np.float64),
+        shape=[3, 3],
+        unit='meter',
+        description='''
+        DEPRECATED, use lattice_vectors instead. Holds the lattice vectors (in Cartesian
+        coordinates) of the simulation cell. The last (fastest) index runs over the
+        $x,y,z$ Cartesian coordinates, and the first index runs over the 3 lattice
+        vectors.
+        ''',
+        categories=[configuration_core])
+
+    symmorphic = Quantity(
+        type=bool,
+        shape=[],
+        description='''
+        Is the space group symmorphic? Set to True if all translations are zero.
+        ''')
+
+    system_composition = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Composition, i.e. cumulative chemical formula with atoms ordered by decreasing
+        atomic number Z.
+        ''')
+
+    system_configuration_consistent = Quantity(
+        type=bool,
+        shape=[],
+        description='''
+        Flag set is the configuration is consistent
+        ''')
+
+    system_name = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Specifies the name of the system. This information is provided by the user in some
+        codes and is stored here for debugging or visualization purposes.
+        ''')
+
+    system_reweighted_composition = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Composition, i.e. cumulative chemical with atoms ordered by decreasing atomic
+        number Z reweighted so that the sum is close to 100, and values are rounded up,
+        and are stable (i.e. it is a fixed point).
+        ''')
+
+    system_type = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Type of the system
+        ''')
+
+    time_reversal_symmetry = Quantity(
+        type=bool,
+        shape=[],
+        description='''
+        Is time-reversal symmetry present?
+        ''')
+
+    chemical_composition = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        The chemical composition as full formula of the system, based on atom species.
+        ''')
+
+    chemical_composition_reduced = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        The chemical composition as reduced formula of the system, based on atom species.
+        ''')
+
+    chemical_composition_bulk_reduced = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        The chemical composition as reduced bulk formula of the system, based on atom
+        species.
+        ''')
+
+    section_prototype = SubSection(
+        sub_section=SectionProxy('section_prototype'),
+        repeats=True)
+
+    section_springer_material = SubSection(
+        sub_section=SectionProxy('section_springer_material'),
+        repeats=True)
+
+    section_symmetry = SubSection(
+        sub_section=SectionProxy('section_symmetry'),
+        repeats=True)
+
+    section_system_to_system_refs = SubSection(
+        sub_section=SectionProxy('section_system_to_system_refs'),
+        repeats=True)
+
+
+class section_thermodynamical_properties(MSection):
+    '''
+    Section that defines thermodynamical properties about the system in a
+    section_frame_sequence.
+    '''
+
+    m_def = Section(validate=False)
+
+    helmholz_free_energy = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_thermodynamical_property_values'],
+        unit='joule',
+        description='''
+        Stores the Helmholtz free energy per unit cell at constant volume of a
+        thermodynamic calculation.
+        ''')
+
+    number_of_thermodynamical_property_values = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        Gives the number of thermal properties values available in
+        section_thermodynamical_properties.
+        ''')
+
+    thermodynamical_properties_calculation_method = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Method used to calculate the thermodynamic quantities.
+
+        Valid values:
+
+        * harmonic
+        ''')
+
+    thermodynamical_property_heat_capacity_C_v = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_thermodynamical_property_values'],
+        unit='joule / kelvin',
+        description='''
+        Stores the heat capacity per cell unit at constant volume.
+        ''')
+
+    thermodynamical_property_temperature = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_thermodynamical_property_values'],
+        unit='kelvin',
+        description='''
+        Specifies the temperatures at which properties such as the Helmholtz free energy
+        are calculated.
+        ''')
+
+    vibrational_free_energy_at_constant_volume = Quantity(
+        type=np.dtype(np.float64),
+        shape=['number_of_thermodynamical_property_values'],
+        unit='joule',
+        description='''
+        Holds the vibrational free energy per atom at constant volume.
+        ''')
+
+
+class section_volumetric_data(MSection):
+    '''
+    Section defining a set of volumetric data on a uniform real-space
+
+    grid.
+
+    To store an array (e.g. a density or a potential), define:
+
+    * three grid point displacement vectors ("displacements")
+
+    * number of grid points along each axis ("nx", "ny" and "nz")
+
+    * the origin of the coordinate system, i.e. coordinates of the first grid
+
+    point ("origin")
+
+    * how many spatial functions are represented, e.g., two for a
+
+    normal spin-polarized density ("multiplicity")
+
+    * the values for each grid point ("values")
+
+    * the unit that applies to each value ("units")
+
+    * the kind of array represented by the volumetric data ("kind").
+
+    Allowed kinds are (please add new kinds as necessary): "density",
+
+    "potential_hartree" and "potential_effective".  Densities and
+
+    potentials that are spin-polarized should have multiplicity two.
+
+    Rules for more complex spins are to be decided when necessary.
+    '''
+
+    m_def = Section(validate=False)
+
+    volumetric_data_displacements = Quantity(
+        type=np.dtype(np.float64),
+        shape=[3, 3],
+        unit='meter',
+        description='''
+        displacement vectors between grid points along each axis; same indexing rules as
+        lattice_vectors.  In many cases, displacements and number of points are related to
+        lattice_vectors through: [displacement] * [number of points + N] =
+        [lattice_vector],where N is 1 for periodic directions and 0 for non-periodic ones
+        ''')
+
+    volumetric_data_kind = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        The kind of function, e.g. density, potential_hartree, potential_effective.  The
+        unit of measurement for "volumetric_data_values" depends on the kind: Densities
+        are 1/m^3 and potentials are J/m^3.  See [full specification on the
+        wiki](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-
+        info/wikis/metainfo/volumetric-data).
+        ''')
+
+    volumetric_data_multiplicity = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        number of functions stored
+        ''')
+
+    volumetric_data_nx = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        number of points along x axis
+        ''')
+
+    volumetric_data_ny = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        number of points along y axis
+        ''')
+
+    volumetric_data_nz = Quantity(
+        type=int,
+        shape=[],
+        description='''
+        number of points along z axis
+        ''')
+
+    volumetric_data_origin = Quantity(
+        type=np.dtype(np.float64),
+        shape=[3],
+        description='''
+        location of the first grid point; same coordinate system as atom_positions when
+        applicable.
+        ''')
+
+    volumetric_data_values = Quantity(
+        type=np.dtype(np.float64),
+        shape=['volumetric_data_multiplicity', 'volumetric_data_nx', 'volumetric_data_ny', 'volumetric_data_nz'],
+        description='''
+        Array of shape (multiplicity, nx, ny, nz) containing the values.  The units of
+        these values depend on which kind of data the values represent; see
+        "volumetric_data_kind".
+        ''')
+
+
+class section_XC_functionals(MSection):
+    '''
+    Section containing one of the exchange-correlation (XC) functionals for the present
+    section_method that are combined to form the XC_functional.
+    '''
+
+    m_def = Section(validate=False)
+
+    XC_functional_name = Quantity(
+        type=str,
+        shape=[],
+        description='''
+        Provides the name of one of the exchange and/or correlation (XC) functionals
+        combined in XC_functional.
+
+        The valid unique names that can be used are listed in the [XC_functional wiki
+        page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/XC-
+        functional).
+
+        *NOTE*: This value should refer to a correlation, an exchange or an exchange-
+        correlation functional only.
+        ''',
+        categories=[settings_physical_parameter])
+
+    XC_functional_parameters = Quantity(
+        type=typing.Any,
+        shape=[],
+        description='''
+        Contains an associative list of non-default values of the parameters for the
+        functional declared in XC_functional_name of the section_XC_functionals section.
+
+        For example, if a calculations using a hybrid XC functional (e.g., HSE06)
+        specifies a user-given value of the mixing parameter between exact and GGA
+        exchange, then this non-default value is stored in this metadata.
+
+        The labels and units of these values are defined in the paragraph dedicated to the
+        specified functional declared in XC_functional_name of the [XC_functional wiki
+        page](https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-meta-info/wikis/metainfo/XC-
+        functional).
+
+        If this metadata is not given, the default parameter values for the
+        XC_functional_name are assumed.
+        ''',
+        categories=[settings_physical_parameter])
+
+    XC_functional_weight = Quantity(
+        type=np.dtype(np.float64),
+        shape=[],
+        description='''
+        Provides the value of the weight for the exchange, correlation, or exchange-
+        correlation functional declared in XC_functional_name (see
+        section_XC_functionals).
+
+        This weight is used in the linear combination of the different XC functional names
+        (XC_functional_name) in different section_XC_functionals sections to form the
+        XC_functional used for evaluating energy_XC_functional and related quantities.
+
+        If not specified then the default is set to 1.
+        ''',
+        categories=[settings_physical_parameter])
+
+
+m_package.__init_metainfo__()
diff --git a/nomad/metainfo/elastic_extension.py b/nomad/metainfo/elastic_extension.py
index c68b29e8f7ea9e187e263661913842536a86ef57..99f33675ca06d56f893f6429c80e673b2353de68 100644
--- a/nomad/metainfo/elastic_extension.py
+++ b/nomad/metainfo/elastic_extension.py
@@ -167,7 +167,7 @@ class ElasticDocument(SectionAnnotation):
                         annotation.mapping = Date(**kwargs)
                     elif isinstance(quantity.type, Reference):
                         inner_document = ElasticDocument.create_document(
-                            quantity.type.target_section_def, inner_doc=True,
+                            cast(Section, quantity.type.target_section_def), inner_doc=True,
                             prefix=annotation.field)
                         annotation.mapping = Object(inner_document)
                     elif isinstance(quantity.type, MEnum):
diff --git a/nomad/metainfo/legacy.py b/nomad/metainfo/legacy.py
index f394ba80c3c0312a6b6ab1716b877791088be9a9..5bfaa9591eadf0e068793c3cd256f52aad9fc589 100644
--- a/nomad/metainfo/legacy.py
+++ b/nomad/metainfo/legacy.py
@@ -1,5 +1,5 @@
 
-from typing import cast, Dict, List, Union, Any, Set, Iterable
+from typing import cast, Dict, List, Union, Any, Set, Iterable, Tuple
 import numpy as np
 from pint.errors import UndefinedUnitError
 import os.path
@@ -12,7 +12,7 @@ import nomad_meta_info
 from nomad import utils
 from nomad.metainfo import (
     Definition, SubSection, Package, Quantity, Category, Section, Reference, units,
-    Environment, MEnum)
+    Environment, MEnum, MProxy)
 
 
 logger = utils.get_logger(__name__)
@@ -23,11 +23,37 @@ _ignored_packages = [
     'repository.nomadmetainfo.json']
 
 
+def python_package_mapping(metainfo_package_name: str) -> Tuple[str, str]:
+    '''
+    Compute the python package for the given metainfo package name. It returns
+    a tuple containing a file path and a package name. The filepath denotes the file
+    for this package within the nomad git project.
+    '''
+
+    split_mi_package_name = metainfo_package_name.split('_')
+    prefix = split_mi_package_name[0]
+
+    if prefix in ['common', 'general', 'public']:
+        directory = 'nomad/datamodel/metainfo'
+        python_package_name = 'nomad.datamodel.metainfo.%s' % metainfo_package_name
+
+    else:
+        directory = 'dependencies/parsers/%s/%sparser/metainfo' % (prefix, prefix)
+        python_package_name = '%sparser.metainfo.%s' % (prefix, metainfo_package_name)
+
+    path = '%s/%s.py' % (directory, metainfo_package_name)
+
+    return python_package_name, path
+
+
 class LegacyMetainfoEnvironment(Environment):
     '''
     A metainfo environment with functions to create a legacy metainfo version of
     the environment.
     '''
+
+    legacy_package_name = Quantity(type=str)
+
     def legacy_info(self, definition: Definition, *args, **kwargs) -> InfoKindEl:
         ''' Creates a legacy metainfo objects for the given definition. '''
         super_names: List[str] = list()
@@ -62,6 +88,11 @@ class LegacyMetainfoEnvironment(Environment):
                 dtype_str = 'C'
             elif isinstance(definition.type, Reference):
                 dtype_str = 'r'
+                if isinstance(definition.type.target_section_def, MProxy):
+                    proxy = definition.type.target_section_def
+                    proxy.m_proxy_section = definition
+                    proxy.m_proxy_quantity = Quantity.type
+                    definition.type.target_section_def = proxy.m_proxy_resolve()
                 result['referencedSections'] = [definition.type.target_section_def.name]
             elif isinstance(definition.type, MEnum):
                 dtype_str = 'C'
@@ -136,6 +167,7 @@ class EnvironmentConversion:
 
     def create_env(self) -> LegacyMetainfoEnvironment:
         env = LegacyMetainfoEnvironment()
+        env.legacy_package_name = self.legacy_env.name.replace('.nomadmetainfo.json', '').replace('.', '_')
         for package_conv in self.package_conversions.values():
             package = package_conv.package
             errors, warnings = package.m_all_validate()
@@ -149,7 +181,6 @@ class EnvironmentConversion:
                     (warnings[0], len(warnings) - 1, package))
             env.m_add_sub_section(Environment.packages, package)
             package.init_metainfo()
-
         return env
 
     def __fix_legacy_super_names(self):
@@ -206,7 +237,9 @@ class PackageConversion:
         self.env_conversion = env_conversion
         self.legacy_defs: List[InfoKindEl] = []
 
-        self.package = Package(name=name)
+        python_package, python_path = python_package_mapping(name)
+
+        self.package = Package(name=name, a_python=(python_package, python_path))
         self.quantities: Dict[str, Quantity] = {}
 
         self.logger = logger.bind(package=name)
@@ -356,20 +389,18 @@ def convert(metainfo_path: str) -> LegacyMetainfoEnvironment:
     return EnvironmentConversion(metainfo_path).create_env()
 
 
-def generate_metainfo_code(metainfo_env: Environment, directory: str = None):
+def generate_metainfo_code(metainfo_env: LegacyMetainfoEnvironment):
     '''
     Generates python code with metainfo definitions for all packages in the given
     environement
 
     Arguments:
         env: The metainfo environment.
-        directory: An optional directory path. The directory must exist. Default
-            is the working directory.
+        python_package_path: An optional directory path. The directory must exist. Default
+            is the working directory. The path will be used to form the module prefix
+            for generated Python modules.
     '''
 
-    if directory is None:
-        directory = '.'
-
     def format_description(description, indent=0, width=90):
         paragraphs = [paragraph.strip() for paragraph in description.split('\n')]
 
@@ -383,13 +414,19 @@ def generate_metainfo_code(metainfo_env: Environment, directory: str = None):
             format_paragraph(p, i == 0)
             for i, p in enumerate(paragraphs) if p != ''])
 
-    def format_type(mi_type):
+    def format_type(pkg, mi_type):
         if type(mi_type) == np.dtype:
             return 'np.dtype(np.%s)' % mi_type
         if mi_type in [int, float, str, bool]:
             return mi_type.__name__
         if isinstance(mi_type, Reference):
-            return "SectionProxy('%s')" % mi_type.target_section_def.name
+            if pkg == mi_type.target_section_def.m_parent:
+                return "Reference(SectionProxy('%s'))" % mi_type.target_section_def.name
+
+            else:
+                python_pkg, _ = mi_type.target_section_def.m_parent.a_python
+                return '%s.%s' % (python_pkg.split('.')[-1], mi_type.target_section_def.name)
+
         else:
             return str(mi_type)
 
@@ -401,10 +438,16 @@ def generate_metainfo_code(metainfo_env: Environment, directory: str = None):
             if pkg == definition.m_parent:
                 return definition.name
             else:
-                return definition.qualified_name()
+                python_pkg, _ = definition.m_parent.a_python
+                return '%s.%s' % (python_pkg.split('.')[-1], definition.name)
 
         return ', '.join([format_definition_ref(definition) for definition in definitions])
 
+    def fromat_package_import(pkg):
+        python_package, _ = pkg.a_python
+        packages = python_package.split('.')
+        return 'from %s import %s' % ('.'.join(packages[:-1]), packages[-1])
+
     env = JinjaEnvironment(
         loader=PackageLoader('nomad.metainfo', 'templates'),
         autoescape=select_autoescape(['python']))
@@ -412,31 +455,26 @@ def generate_metainfo_code(metainfo_env: Environment, directory: str = None):
         format_description=format_description,
         format_type=format_type,
         format_unit=format_unit,
-        format_definition_refs=format_definition_refs)
+        format_definition_refs=format_definition_refs,
+        fromat_package_import=fromat_package_import)
 
     for package in metainfo_env.packages:
-        file_name = package.name
-        with open(os.path.join(directory, '%s.py' % file_name), 'wt') as f:
+        _, path = package.a_python
+        if not os.path.exists(os.path.dirname(path)):
+            os.makedirs(os.path.dirname(path))
+
+        with open(path, 'wt') as f:
             code = env.get_template('package.j2').render(pkg=package)
             code = '\n'.join([
                 line.rstrip() if line.strip() != '' else ''
                 for line in code.split('\n')])
             f.write(code)
 
+    _, path = python_package_mapping(metainfo_env.legacy_package_name)
+    with open(os.path.join(os.path.dirname(path), '__init__.py'), 'wt') as f:
 
-# if __name__ == '__main__':
-#     output = 'output'
-
-#     env = convert('vasp.nomadmetainfo.json')
-#     assert env.resolve_definition('x_vasp_incar_EFIELD_PEAD', Quantity) is not None
-#     assert 'x_vasp_incar_EFIELD_PEAD' in env.legacy_info_env()
-#     generate_metainfo_code(env, output)
-
-#     from output import public
-#     import json
-
-#     run = public.section_run()
-#     system = run.m_create(public.section_system)
-#     system.atom_labels = ['H', 'H', 'O']
-
-#     print(json.dumps(run.m_to_dict(with_meta=True), indent=2))
+        code = env.get_template('environment.j2').render(env=metainfo_env)
+        code = '\n'.join([
+            line.rstrip() if line.strip() != '' else ''
+            for line in code.split('\n')])
+        f.write(code)
diff --git a/nomad/metainfo/metainfo.py b/nomad/metainfo/metainfo.py
index 02834a706894ded692df26157ef00e9f4d529321..4647ade4e3f4e7df798f6d703236b07378305bae 100644
--- a/nomad/metainfo/metainfo.py
+++ b/nomad/metainfo/metainfo.py
@@ -95,15 +95,17 @@ class MProxy():
         url: The reference represented as an URL string.
     '''
 
-    def __init__(self, m_proxy_url: str, m_proxy_section: 'MSection', m_proxy_quantity: 'Quantity'):
+    def __init__(
+            self, m_proxy_url: str, m_proxy_section: 'MSection' = None,
+            m_proxy_quantity: 'Quantity' = None):
         self.m_proxy_url = m_proxy_url
         self.m_proxy_section = m_proxy_section
         self.m_proxy_resolved = None
-        self.m_reference_type = m_proxy_quantity.type
+        self.m_proxy_quantity = m_proxy_quantity
 
     def m_proxy_resolve(self):
-        if self.m_proxy_section and not self.m_proxy_resolved:
-            self.m_proxy_resolved = self.m_reference_type.resolve(self)
+        if self.m_proxy_section and self.m_proxy_quantity and not self.m_proxy_resolved:
+            self.m_proxy_resolved = self.m_proxy_quantity.type.resolve(self)
 
         if self.m_proxy_resolved is not None and isinstance(self, MProxy):
             setattr(self, '__class__', self.m_proxy_resolved.__class__)
@@ -112,12 +114,28 @@ class MProxy():
         return self.m_proxy_resolved
 
     def __getattr__(self, key):
-        if self.m_proxy_resolve():
+        if self.m_proxy_resolve() is not None:
             return getattr(self.m_proxy_resolved, key)
 
         raise ReferenceError('could not resolve %s' % self.m_proxy_url)
 
 
+class SectionProxy(MProxy):
+    def m_proxy_resolve(self):
+        if self.m_proxy_section and not self.m_proxy_resolved:
+            root = self.m_proxy_section
+            while root is not None and not isinstance(root, Package):
+                root = root.m_parent
+
+            if isinstance(root, Package):
+                self.m_proxy_resolved = root.all_definitions.get(self.m_proxy_url)
+
+            if self.m_proxy_resolved is None:
+                raise ReferenceError('could not resolve %s' % self.m_proxy_url)
+
+        return self.m_proxy_resolved
+
+
 class DataType:
     '''
     Allows to define custom data types that can be used in the meta-info.
@@ -298,9 +316,7 @@ class _QuantityType(DataType):
 class Reference(DataType):
     ''' Datatype used for reference quantities. '''
 
-    def __init__(self, section_def: 'Section'):
-        if not isinstance(section_def, Section):
-            raise MetainfoError('%s is not a section definition.' % section_def)
+    def __init__(self, section_def: Union['Section', 'SectionProxy']):
         self.target_section_def = section_def
 
     def resolve(self, proxy) -> 'MSection':
@@ -311,6 +327,12 @@ class Reference(DataType):
         return proxy.m_proxy_section.m_resolve(proxy.m_proxy_url)
 
     def set_normalize(self, section: 'MSection', quantity_def: 'Quantity', value: Any) -> Any:
+        if isinstance(self.target_section_def, MProxy):
+            proxy = self.target_section_def
+            proxy.m_proxy_section = section
+            proxy.m_proxy_quantity = quantity_def
+            self.target_section_def = proxy.m_proxy_resolve()
+
         if self.target_section_def.m_follows(Definition.m_def):
             # special case used in metainfo definitions, where we reference metainfo definitions
             # using their Python class. E.g. referencing a section definition using its
@@ -325,13 +347,14 @@ class Reference(DataType):
 
         if isinstance(value, MProxy):
             value.m_proxy_section = section
+            value.m_proxy_quantity = quantity_def
             return value
 
         if not isinstance(value, MSection):
             raise TypeError(
                 'The value %s is not a section and can not be used as a reference.' % value)
 
-        if not value.m_follows(self.target_section_def):
+        if not value.m_follows(self.target_section_def):  # type: ignore
             raise TypeError(
                 '%s is not a %s and therefore an invalid value of %s.' %
                 (value, self.target_section_def, quantity_def))
@@ -2398,13 +2421,3 @@ class Environment(MSection):
             raise KeyError('Could not uniquely identify %s' % name)
         else:
             raise KeyError('Could not resolve %s' % name)
-
-
-class SectionProxy(MProxy):
-    def m_proxy_resolve(self):
-        if self.m_proxy_section and not self.m_proxy_resolved:
-            root = self.m_proxy_section.m_root()
-            if isinstance(root, Package):
-                self.m_proxy_resolved = root.all_definitions.get(self.m_proxy_url)
-
-        super().m_proxy_resolve()
diff --git a/nomad/metainfo/templates/environment.j2 b/nomad/metainfo/templates/environment.j2
new file mode 100644
index 0000000000000000000000000000000000000000..36c874093c11e58379d6695d84822ca3d6e28177
--- /dev/null
+++ b/nomad/metainfo/templates/environment.j2
@@ -0,0 +1,14 @@
+import sys
+from nomad.metainfo import Environment
+from nomad.metainfo.legacy import LegacyMetainfoEnvironment
+
+{%- for package in env.packages %}
+import {{ package.a_python[0] }}
+{%- endfor %}
+
+m_env = LegacyMetainfoEnvironment()
+
+{%- for package in env.packages %}
+m_env.m_add_sub_section(Environment.packages, sys.modules['{{ package.a_python[0] }}'].m_package)  # type: ignore
+{%- endfor %}
+
diff --git a/nomad/metainfo/templates/package.j2 b/nomad/metainfo/templates/package.j2
index dff2fe2cb4f7191db08c91d8da026e2e149a35eb..731cb210f66bd56cead7f30ac65c465b10215910 100644
--- a/nomad/metainfo/templates/package.j2
+++ b/nomad/metainfo/templates/package.j2
@@ -1,10 +1,11 @@
 import numpy as np            # pylint: disable=unused-import
 import typing                 # pylint: disable=unused-import
 from nomad.metainfo import (  # pylint: disable=unused-import
-    MSection, MCategory, Category, Package, Quantity, Section, SubSection, SectionProxy
+    MSection, MCategory, Category, Package, Quantity, Section, SubSection, SectionProxy,
+    Reference
 )
 {% for dependency in pkg.dependencies %}
-from . import {{dependency.name}}
+{{ fromat_package_import(dependency) }}
 {%- endfor %}
 
 m_package = Package(name='{{ pkg.name }}', description='{{ pkg.description }}')
@@ -33,7 +34,7 @@ class {{ section.name }}({%- if section.extends_base_section -%}{{ format_defini
     m_def = Section(validate=False{%- if section.extends_base_section -%}, extends_base_section=True{%- endif -%})
     {% for quantity in section.quantities %}
     {{ quantity.name }} = Quantity(
-        type={{ format_type(quantity.type) }},
+        type={{ format_type(pkg, quantity.type) }},
         shape={{ quantity.shape }}
         {%- if quantity.unit is not none -%},
         unit={{ format_unit(quantity.unit) }}
diff --git a/nomad/parsing/metainfo.py b/nomad/parsing/metainfo.py
index 55c3f3e823b60625a9cc77f2cbe108b15e9dbdef..588434595573fbae87d5710d2755a01962a8502d 100644
--- a/nomad/parsing/metainfo.py
+++ b/nomad/parsing/metainfo.py
@@ -318,4 +318,4 @@ class MetainfoBackend(LegacyParserBackend):
         pass
 
     def pwarn(self, msg):
-        pass
+        self.logger.warning(msg)
diff --git a/nomad/utils.py b/nomad/utils.py
index c2a71853c3cbedad352c04f9dcd39a5ef198264e..2fc434d7457874c970601c8ca8b7ebb9dade382a 100644
--- a/nomad/utils.py
+++ b/nomad/utils.py
@@ -407,6 +407,10 @@ def timer(logger, event, method='info', **kwargs):
     finally:
         stop = time.time()
 
+    if logger is None:
+        print(event, stop - start)
+        return
+
     logger_method = getattr(logger, 'info', None)
     if logger_method is not None:
         logger_method(event, exec_time=stop - start, **kwargs)
diff --git a/tests/metainfo/test_legacy.py b/tests/metainfo/test_legacy.py
index 71d54e9f6fe7a5b7e6a91fd65077dbe9dce78338..b0e7de7c1b64bb012f57a99dbee578a3bfb6ee97 100644
--- a/tests/metainfo/test_legacy.py
+++ b/tests/metainfo/test_legacy.py
@@ -21,7 +21,7 @@ from nomad.metainfo.metainfo import (
     MSection, MCategory, Section, Quantity, SubSection, Definition, Package, DeriveError,
     MetainfoError, Environment, MResource, Datetime, units, Annotation, SectionAnnotation,
     DefinitionAnnotation, Reference, MProxy, derived)
-from nomad.metainfo.legacy import LegacyMetainfoEnvironment, convert
+from nomad.metainfo.legacy import LegacyMetainfoEnvironment, convert, python_package_mapping
 from nomad.parsing.metainfo import MetainfoBackend
 
 
@@ -60,6 +60,7 @@ def legacy_example():
 @pytest.fixture(scope='session')
 def legacy_env(legacy_example):
     env = InfoKindEnv()
+    env.name = 'test.nomadmetainfo.json'
     for definition in legacy_example.get('metaInfos'):
         env.addInfoKindEl(InfoKindEl(
             description='test_description', package='test_package', **definition))
@@ -71,6 +72,24 @@ def env(legacy_env):
     return convert(legacy_env)
 
 
+@pytest.mark.parametrize('package,path,name', [
+    (
+        'vasp',
+        'dependencies/parsers/vasp/vaspparser/metainfo/vasp.py',
+        'vaspparser.metainfo.vasp'),
+    (
+        'common',
+        'nomad/datamodel/metainfo/common.py',
+        'nomad.datamodel.metainfo.common'),
+    (
+        'vasp_incars',
+        'dependencies/parsers/vasp/vaspparser/metainfo/vasp_incars.py',
+        'vaspparser.metainfo.vasp_incars')
+])
+def test_package_mapping(package, path, name):
+    assert python_package_mapping(package) == (name, path)
+
+
 def test_environment(env: LegacyMetainfoEnvironment, no_warn):
     assert env.packages[0].name == 'test_package'
     assert 'section_system' in env.packages[0].all_definitions
diff --git a/tests/test_datamodel.py b/tests/test_datamodel.py
index 41275bc37ed9fd6f4f20a158f659ddc1a814fbf1..2c7b581945e5683498c8e0895e41995943957886 100644
--- a/tests/test_datamodel.py
+++ b/tests/test_datamodel.py
@@ -111,6 +111,25 @@ def generate_calc(pid: int = 0, calc_id: str = None, upload_id: str = None) -> d
     return entry
 
 
+def test_common_metainfo():
+    from nomad.datamodel.metainfo import public
+
+    run = public.section_run()
+    system = run.m_create(public.section_system)
+    system.atom_labels = ['H', 'H', 'O']
+
+    assert run.section_system[0].atom_labels == ['H', 'H', 'O']
+
+
+def test_vasp_metainfo():
+    from nomad.datamodel.metainfo import public
+
+    run = public.section_run()
+
+    assert 'vasp_src_date' not in run.m_def.all_quantities
+    from vaspparser.metainfo import m_env  # pylint: disable=unused-import
+
+
 if __name__ == '__main__':
     import sys
     import json