example.py 4.58 KB
Newer Older
1
2
3
""" An example metainfo package. """

import numpy as np
4
from datetime import datetime
5

6
from nomad.metainfo import MSection, MCategory, Section, Quantity, Package, SubSection, MEnum, Datetime, units
7
8
9
10
11
12
13
14
15

m_package = Package(links=['http://metainfo.nomad-coe.eu'])


class SystemHash(MCategory):
    """ All quantities that contribute to what makes a system unique. """


class Parsing(MSection):
16
17
18
19
20
21
22
23
    """ All data that describes the NOMAD parsing of this run.

    Quantities can also be documented like this:

    Args:
        parser_name: 'Name of the used parser'
        parser_version: 'Version of the used parser'
    """
24
25
26
27
28

    parser_name = Quantity(type=str)
    parser_version = Quantity(type=str)
    nomad_version = Quantity(type=str)
    warnings = Quantity(type=str, shape=['0..*'])
29
    parse_time = Quantity(type=Datetime)
30
31
32
33
34
35


class System(MSection):
    """ All data that describes a simulated system. """

    n_atoms = Quantity(
36
        type=int, derived=lambda system: len(system.atom_labels),
37
38
39
        description='Number of atoms in the simulated system.')

    atom_labels = Quantity(
40
        type=str, shape=['n_atoms'], categories=[SystemHash],
41
42
43
        description='The atoms in the simulated systems.')

    atom_positions = Quantity(
44
        type=np.dtype('f'), shape=['n_atoms', 3], unit=units.m, categories=[SystemHash],
45
46
47
        description='The atom positions in the simulated system.')

    lattice_vectors = Quantity(
48
        type=np.dtype('f'), shape=[3, 3], unit=units.m, categories=[SystemHash],
49
50
        description='The lattice vectors of the simulated unit cell.')

Markus Scheidgen's avatar
Markus Scheidgen committed
51
52
    unit_cell = Quantity(synonym_for='lattice_vectors')

53
    periodic_dimensions = Quantity(
54
        type=bool, shape=[3], default=[False, False, False], categories=[SystemHash],
55
56
57
        description='A vector of booleans indicating in which dimensions the unit cell is repeated.')


58
59
60
61
class SCC(MSection):

    energy_total = Quantity(type=float, default=0.0, unit=units.J)

62
    system = Quantity(type=System, description='The system that this calculation is based on.')
63
64


65
66
67
68
69
70
class Run(MSection):
    """ All data that belongs to a single code run. """

    code_name = Quantity(type=str, description='The name of the code that was run.')
    code_version = Quantity(type=str, description='The version of the code that was run.')

71
72
73
    parsing = SubSection(sub_section=Parsing)
    systems = SubSection(sub_section=System, repeats=True)
    sccs = SubSection(sub_section=SCC, repeats=True)
74

Markus Scheidgen's avatar
Markus Scheidgen committed
75
76
77
78
    def c_one_scc_per_system(self):
        assert self.m_sub_section_count(Run.systems) == self.m_sub_section_count(Run.sccs),\
            'Numbers of system does not match numbers of calculations.'

79

80
81
82
class VaspRun(Run):
    """ All VASP specific quantities for section Run. """
    m_def = Section(extends_base_section=True)
83

84
    x_vasp_raw_format = Quantity(
85
        type=MEnum(['xml', 'outcar']),
86
        description='The file format of the parsed VASP mainfile.')
87
88


89
90
91
92
93
94
95
if __name__ == '__main__':
    # Demonstration of how to reflect on the definitions

    # All definitions are metainfo data themselves, and they can be accessed like any other
    # metainfo data. E.g. all section definitions are sections themselves.

    # To get quantities of a given section
96
    print(Run.m_def.m_get_sub_sections(Section.quantities))
97
98

    # Or all Sections in the package
99
    print(m_package.m_get_sub_sections(Package.section_definitions))  # type: ignore, pylint: disable=undefined-variable
100
101
102

    # There are also some definition specific helper methods.
    # For example to get all attributes (Quantities and possible sub-sections) of a section.
103
    print(Run.m_def.all_properties)
104
105
106
107
108

    # Demonstration on how to use the definitions, e.g. to create a run with system:
    run = Run()
    run.code_name = 'VASP'
    run.code_version = '1.0.0'
109
110
111
112

    parsing = run.m_create(Parsing)
    parsing.parse_time = datetime.now()

113
114
115
    run.m_as(VaspRun).x_vasp_raw_format = 'outcar'
    # The same as
    run.x_vasp_raw_format = 'outcar'  # type: ignore
116
117
118
119

    system = run.m_create(System)
    system.atom_labels = ['H', 'H', 'O']

120
121
122
123
    calc = run.m_create(SCC)
    calc.energy_total = 1.23e-10
    calc.system = system

124
125
    # Or to read data from existing metainfo data:
    print(system.atom_labels)
126
    print(system.n_atoms)
127

Markus Scheidgen's avatar
Markus Scheidgen committed
128
129
130
    # To validate dimensions and custom constraints
    print('errors: %s' % run.m_all_validate())

131
    # To serialize the data:
132
133
    serializable = run.m_to_dict()
    # or
134
135
    print(run.m_to_json(indent=2))

136
137
138
139
    # To deserialize data
    run = Run.m_from_dict(serializable)
    print(run.sccs[0].system)

140
    # print(m_package.m_to_json(indent=2))  # type: ignore, pylint: disable=undefined-variable