diff --git a/nomad/datamodel/metainfo/__init__.py b/nomad/datamodel/metainfo/__init__.py
index fc2a91d583e66578c3029d85d054d6c597ea0eeb..71b4badd91dd18ae3f173678bfbc1078f7a48862 100644
--- a/nomad/datamodel/metainfo/__init__.py
+++ b/nomad/datamodel/metainfo/__init__.py
@@ -17,3 +17,6 @@
 #
 from .simulation import m_env
 from .material_library import m_package
+
+from .apm import m_package
+from .em_nion import m_package
diff --git a/nomad/datamodel/metainfo/apm/__init__.py b/nomad/datamodel/metainfo/apm/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e67becad427fde7e33671f41850ba22be00667dc
--- /dev/null
+++ b/nomad/datamodel/metainfo/apm/__init__.py
@@ -0,0 +1,529 @@
+#
+# Copyright The NOMAD Authors.
+#
+# This file is part of NOMAD. See https://nomad-lab.eu for further info.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+from matplotlib.afm import CharMetrics
+import numpy as np
+import os
+
+from nomad.units import ureg
+from nomad.metainfo import (
+    MSection, Package, Quantity, SubSection, MEnum, Datetime, Section)
+from nomad.datamodel.data import EntryData
+
+
+m_package = Package(name='atom_probe_microscopy')
+
+
+class Reflectron(MSection):
+    """Details about a reflectron device at the instrument."""
+
+    has_reflectron = Quantity(
+        type=bool,
+        description='''Does the instrument have a reflectron?''',
+        a_eln=dict(component='BoolEditQuantity'))
+
+    # watch out for auto-translated keywords which become py reserved keywords
+    # nexus_string prefixing, like with nx_<<quantity_name>> comes to rescue
+    name = Quantity(
+        type=str,
+        description='''Name of the reflectron.''',
+        a_eln=dict(component='StringEditQuantity'))
+    # keyword "name" must not be used except as keyword nomad
+
+    model = Quantity(
+        type=str,
+        description='''Reflectron model.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    serial_number = Quantity(
+        type=str,
+        description='''Reflectron serial number.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    manufacturer_name = Quantity(
+        type=str,
+        description='''Reflectron manufacturer.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+
+class Detector(MSection):
+    """Details about the detector."""
+
+    description = Quantity(
+        type=str,
+        description='''
+        An (ideally globally persistent) unique identifier, link, or text
+        which gives further details.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    detector_type = Quantity(
+        type=str,
+        description='''
+        Description of the detector type. Specify if the detector is not
+        the usual type of delay-line detectors.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+
+class Pulser(MSection):
+    """Details about the pulser (laser/high-voltage)."""
+
+    name = Quantity(
+        type=str,
+        description='''Given name.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    model = Quantity(
+        type=str,
+        description='''Given brand or model name by the manufacturer.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    serial_number = Quantity(
+        type=str,
+        description='''
+        Given hardware name/serial number or hash identifier issued by
+        the manufacturer.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    manufacturer_name = Quantity(
+        type=str,
+        description='''Given name of the manufacturer.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    pulse_mode = Quantity(
+        type=MEnum([
+            'laser',
+            'high_voltage',
+            'laser_and_high_voltage']),
+        shape=[],
+        description='''Which type of pulsing mode.''',
+        a_eln=dict(component='RadioEnumEditQuantity'))
+
+    pulse_fraction = Quantity(
+        type=np.dtype(np.float64),
+        description='''Average pulse fraction.''',
+        a_eln=dict(component='NumberEditQuantity'))
+
+    _pulse_fraction_units = Quantity(
+        type=str,
+        description='''SI unit used for pulse fraction.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+
+class Stage(MSection):
+    """Details about the stage."""
+
+    design = Quantity(
+        type=str,
+        description='''Principal design of the stage.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    name = Quantity(
+        type=str,
+        description='''Name of the stage''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    model = Quantity(
+        type=str,
+        description='''Type of the stage''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    serial_number = Quantity(
+        type=str,
+        description='''
+        Serial number of the stage.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    manufacturer_name = Quantity(
+        type=str,
+        description='''Given name of the stage manufacturer.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+
+class InstrumentControl(MSection):
+    """Details relevant for the control of the instrument."""
+
+    base_temperature = Quantity(
+        type=np.dtype(np.float64),
+        unit='kelvin',
+        description='''
+        Average temperature at the specimen base, i.e. base temperature,
+        during the measurement.''',
+        a_eln=dict(component='NumberEditQuantity'))
+
+    _base_temperature_units = Quantity(
+        type=str,
+        description='''
+        Unit used for the average temperature at the specimen base.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    pressure = Quantity(
+        type=np.dtype(np.float64),
+        unit='pascal',
+        description='''Average pressure in the analysis chamber.''',
+        a_eln=dict(component='NumberEditQuantity'))
+
+    _pressure_units = Quantity(
+        type=str,
+        description='''Average pressure in the analysis chamber.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    program = Quantity(
+        type=str,
+        description='''
+        Given name of the program that was used to control the experiment.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    _program_version = Quantity(
+        type=str,
+        description='''
+        Ideally program version plus build number, or commit hash or
+        description of ever persistent resources where the source code of the
+        program and build instructions can be found so that the program can
+        be configured ideally in such a manner that the result of this
+        computational process is recreatable
+        in the same deterministic manner.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+
+class Instrument(MSection):
+    """Details about the atom probe microscope, components, and software."""
+
+    name = Quantity(
+        type=str,
+        description='''
+        Given name of the microscope, e.g Oxcart, One atom at a time.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    location = Quantity(
+        type=str,
+        description='''
+        Geographic coordinates of the lab or the place where the instrument
+        is installed using GEOREF geocodes ideally.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    instrument_manufacturer = Quantity(
+        type=str,
+        description='''
+        Manufacturer of the entire instrument (e.g. AMETEK/Cameca) to enable
+        e.g. queries in materials database systems for instrument
+        manufacturers. Usually more technical details are needed though to
+        specify the instrument, these should be written into instrument_model
+        and instrument_capabilities.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    instrument_model = Quantity(
+        type=str,
+        description='''
+        Manufacturer brand/model to enable e.g. queries about
+        microscope models (e.g. LEAP3000XS).''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    instrument_identifier = Quantity(
+        type=str,
+        description='''
+        Hardware name/serial number or hash identifier given by the
+        manufacturer to identify the instrument.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    instrument_capability = Quantity(
+        type=str,
+        description='''Free-text list possibly multiple terms of
+        functionalities which the instrument provides.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    flight_path_length = Quantity(
+        type=np.dtype(np.float64),
+        unit='meter',
+        description='''
+        The space inside the atom probe that ions pass through when they
+        leave the specimen and travel to the detector.''',
+        a_eln=dict(component='NumberEditQuantity'))
+
+    _flight_path_length_units = Quantity(
+        type=str,
+        description='''
+        The space inside the atom probe that ions pass through when they
+        leave the specimen and travel to the detector.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    reflectron = SubSection(section_def=Reflectron)
+    detector = SubSection(section_def=Detector)
+    pulser = SubSection(section_def=Pulser)
+    control = SubSection(section_def=InstrumentControl)
+
+
+class Operator(MSection):
+    """Contact information of at least the user of the instrument.
+
+    Or the investigator who performed this experiment.
+    Adding multiple users if relevant is recommended.
+    """
+
+    m_def = Section(a_eln=dict())
+
+    name = Quantity(
+        type=str,
+        description='''
+        Given (first) name and surname of the user.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    affiliation = Quantity(
+        type=str,
+        description='''
+        Name of the affiliation of the user at the point in time
+        when the experiment was performed.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    address = Quantity(
+        type=str,
+        description='''Postal address of the affiliation.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    email = Quantity(
+        type=str,
+        description='''
+        Email address of the user at the point in time
+        when the experiment was performed.
+        Giving the most permanently used email is recommended.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    orcid = Quantity(
+        type=str,
+        description='''
+        Globally unique identifier of the user as offers
+        by services like ORCID or Researcher ID.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    telephone_number = Quantity(
+        type=str,
+        description='''
+        (Business) (tele)phone number of the user at the point
+        in time when the experiment was performed.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    role = Quantity(
+        type=str,
+        description='''
+        Which role does the user have in the place, and at the point in time
+        when, the experiment was performed (e.g. technician operating the
+        microscope, student, postdoc, principal investigator, guest ...)''',
+        a_eln=dict(component='StringEditQuantity'))
+
+
+class Sample(MSection):
+    """Properties of the specimen, its history."""
+
+    name = Quantity(
+        type=str,
+        description='''
+        Descriptive name or identifier with which to distinguish the specimen
+        from all others and especially the parts from where it was cut.
+        In cases where the specimen was e.g. site-specifically cut from
+        samples or in cases of an instrument session during which multiple
+        specimens are loaded, the name has to be descriptive enough to resolve
+        which specimen on e.g. the microtip array was taken. The user is
+        advised to store the details how specimens were cut/prepared from
+        samples in the sample history.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    sample_history = Quantity(
+        type=str,
+        description='''
+        Ideally, a reference to the location of or a (globally persistent)
+        unique identifier of e.g. another file which should document ideally
+        as many details as possible of the material, its microstructure, and
+        its thermo-chemo-mechanical processing/preparation history.
+        In the case that such a detailed history of the sample/specimen is not
+        available, use this field as a free-text description to specify a sub-
+        set of the entire sample history, i.e. what you would consider being
+        the key steps and relevant information about the specimen, its
+        material, microstructure, thermo-chemo-mechanical processing state,
+        and details of the preparation.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    preparation_date = Quantity(
+        type=Datetime,
+        description='''
+        ISO8601 date and time with local time zone offset to UTC included
+        when the specimen was prepared. Ideally report the end of the
+        preparation, i.e. the last known time the measured specimen surface
+        was actively prepared. Knowing when the specimen was exposed to e.g.
+        specific atmosphere is especially required for environmentally
+        sensitive material such as hydrogen-charged specimens or experiments
+        including tracers with a short half-time. The user is advised to
+        include these temporal details in the sample_history.''',
+        a_eln=dict(component='DateTimeEditQuantity'))
+
+    atom_types = Quantity(
+        type=str,
+        description='''
+        Use Hill's system for listing elements of the periodic table which
+        are inside or attached to the surface of the specimen and thus
+        considered relevant from a scientific point. The purpose of the field
+        is to offer materials database systems an opportunity to parse the
+        relevant elements without having to interpret these
+        from the sample history.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+
+class AtomProbeMicroscopy(EntryData):
+    """Application definition describing atom probe experiments.
+
+    The here specified ELN is a proof-of-concept whose scope is to provide
+    a mechanism to inject additional pieces of information to create a NeXus
+    file that matches a:
+    - particular version of the NXapm.nxdl.xml appdef
+    -  https://github.com/FAIRmat-Experimental/nexus_definitions/commit/
+    -  1d46b94dc36a42225ad247cc763277a47dcd30d4
+    - working with experiments as a pair of APT/RNG or APT/RRNG files,
+    - specifically with these file formats being interpretable as with the
+    - following so-called apm dataconverter (see commit below).
+    The ELN returns a json file that is to be used to inject the
+    here collected pieces of information in a
+    - specifically-versioned dataconverter apm
+    -  https://github.com/nomad-coe/nomad-parser-nexus/commit/
+    -  47bc4f9724b8e980bd41d0fca3a663c0b79a7fb1
+    """
+
+    start_time = Quantity(
+        type=Datetime,
+        description='''
+        ISO 8601 formatted time code with local time zone offset to UTC
+        information included when the experiment started.
+        If the application demands that time codes in this section of the
+        application definition should only be used for specifying when the
+        experiment was performed - and the exact duration is not relevant
+        - this start time field should be used. Often though it is useful to
+        specify a time interval with specifying both start_time and end_time
+        to allow for more detailed bookkeeping and interpretation of the
+        experiment. The user should be aware that even with having both time
+        instances specified it may not be advisable to infer how long the
+        experiment took or for how long data were acquired. More detailed
+        timing data over the course of the experiment have to be collected.''',
+        a_eln=dict(component='DateTimeEditQuantity'))
+
+    end_time = Quantity(
+        type=Datetime,
+        description='''
+        ISO 8601-formatted time code with local time zone offset to UTC
+        included when the experiment ended.''',
+        a_eln=dict(component='DateTimeEditQuantity'))
+
+    run_number = Quantity(
+        type=str,
+        description='''
+        Not the specimen name or the experiment identifier but the identifier
+        through which the experiment is referred to in the control software.
+        For LEAP instruments it is recommended to use the IVAS/AP Suite run
+        number. For other instruments, such as the one from Stuttgart or Oxcart
+        from Erlangen, or the instruments in Rouen, use the identifier that is
+        closest in meaning to the LEAP run number. As a destructive microscopy
+        method, a run can be performed only once. It is possible, however,
+        to interrupt a run and restart, still all using the same specimen.
+        In this case, each evaporation run needs to be distinguished with
+        different run numbers. This is how most atom probe groups handle
+        it across the globe.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    operation_mode = Quantity(
+        type=MEnum([
+            'leap',
+            'apt',
+            'fim',
+            'apt_and_fim']),
+        shape=[],
+        description='''
+        What type of atom probe microscope experiment is performed.
+        This field can be used e.g. by materials database systems to
+        qualitatively filter experiments.''',
+        a_eln=dict(component='RadioEnumEditQuantity'))
+
+    sample = SubSection(section_def=Sample)
+    operator = SubSection(section_def=Operator, repeats=True)
+    instrument = SubSection(section_def=Instrument)
+
+    reconstruction_file = Quantity(
+        type=str,
+        description='''
+        Vendor/community-specific file (APT, POS, ePOS are supported)
+        which contains reconstructed ion positions and other data.''',
+        a_eln=dict(component='FileEditQuantity'),
+        a_browser=dict(adaptor='RawFileAdaptor'))
+
+    ranging_file = Quantity(
+        type=str,
+        description='''
+        Vendor/community-specific file (RNG, RRNG are supported)
+        which contains ranging definitions.''',
+        a_eln=dict(component='FileEditQuantity'),
+        a_browser=dict(adaptor='RawFileAdaptor'))
+
+    # maybe a database dump file from IVAS/APSuite
+
+    def normalize(self, archive, logger):
+        """Normalize data."""
+        # store content of the above ELN entries into a dictionary
+        # data = self.m_to_dict()
+
+        # map paths in this dictionary on paths as expected by apm reader
+        # for instance by storing flattened data key value pairs in a json
+        # file
+
+        # remains to be implemented
+
+#       runner = CliRunner()
+#       converter_args = ['--input-file', self.reconstruction_file,
+#                         '--input-file', self.ranging_file,
+#                         '--input-file',
+#                         os.path.join(filepath, 'eln.apm.json'),
+#                         '--reader', 'apm',
+#                         '--nxdl', 'NXapm',
+#                         '--output', os.path.join(filepath, \
+#                         'apm.test.nxs')]
+#       runner.invoke(convert, converter_args)
+
+        pass
+
+# =============================================================================
+#         import yaml
+#         from nomad.datamodel.metainfo.ellipsometry.dict_flattener \
+#    import dict_flatten, dict_key_cut
+#         from nexusparser.tools.dataconverter.convert import convert
+#         from click.testing import CliRunner
+#
+#         data = self.m_to_dict()
+#         data.update(data.pop('data_file'))
+#         dict_flatten(data)
+#         dict_key_cut(data)
+#
+#         kl = list(data.keys())
+#         for k in kl:
+#             if '/_' in k:
+#                 data[k.replace('/_', r"/\@")] = data.pop(k)
+#         dict_key_cut(data, '/', 1, '@')
+#         data['definition'] = 'NXellipsometry'
+#         data[r"definition/\@version"] = '0.0.1'
+#         data[r"definition/\@url"] = 'https://'
+#
+#         with archive.m_context.raw_file('eln.apm.json', 'w') as outfile:
+#             yaml.dump(data, outfile, default_flow_style=False)
+#             filepath = os.path.dirname(outfile.name)
+# =============================================================================
+
+
+m_package.__init_metainfo__()
diff --git a/nomad/datamodel/metainfo/em_nion/__init__.py b/nomad/datamodel/metainfo/em_nion/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..9ba4fd24a00f1d5b087c56b59c2e0787e97e3d50
--- /dev/null
+++ b/nomad/datamodel/metainfo/em_nion/__init__.py
@@ -0,0 +1,599 @@
+#
+# Copyright The NOMAD Authors.
+#
+# This file is part of NOMAD. See https://nomad-lab.eu for further info.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+from matplotlib.afm import CharMetrics
+import numpy as np
+import os
+
+from nomad.units import ureg
+from nomad.metainfo import (
+    MSection, Package, Quantity, SubSection, MEnum, Datetime, Section)
+from nomad.datamodel.data import EntryData
+
+
+m_package = Package(name='electron_microscopy_nion')
+
+
+class ElectronGun(MSection):
+    """Details the electron gun."""
+
+    emitter_type = Quantity(
+        type=str,
+        description='''
+        Emitter type used to create the beam.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    description = Quantity(
+        type=str,
+        description='''
+        Ideally a reference to (another) file (ideally formatted using also an
+        an application definition) via a link, name, or a (globally persistent)
+        unique identifier to give further details about the electron gun.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    name = Quantity(
+        type=str,
+        description='''Given name.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    model = Quantity(
+        type=str,
+        description='''Given brand or model name by the manufacturer.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    serial_number = Quantity(
+        type=str,
+        description='''
+        Given hardware name/serial number or hash identifier issued by the
+        manufacturer.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+
+class Aperture(MSection):
+    """Details about an aperture."""
+
+    name = Quantity(
+        type=str,
+        description='''Given name.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    model = Quantity(
+        type=str,
+        description='''Given brand or model name by the manufacturer.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    serial_number = Quantity(
+        type=str,
+        description='''
+        Given hardware name/serial number or hash identifier issued by the
+        manufacturer.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    manufacturer_name = Quantity(
+        type=str,
+        description='''Given name of the manufacturer.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    value = Quantity(
+        type=np.dtype(np.float64),
+        description='''
+        Relevant value from the control software as this is not always just
+        the diameter of (not even in the case) of a circular aperture but a
+        rather a value from a list of predefined ones in the control software.
+        Which actual settings are behind these should be Details which choice
+        was made should be explained under description.''',
+        a_eln=dict(component='NumberEditQuantity'))
+
+    _value_units = Quantity(
+        type=str,
+        description='''
+        Relevant value from the control software as this is not always just
+        the diameter of (not even in the case) of a circular aperture but
+        a rather a value from a list of predefined ones in the control
+        software. Which actual settings are behind these should be detailed and
+        which choices were made should be explained under description.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    description = Quantity(
+        type=str,
+        description='''
+        An (ideally globally persistent) unique identifier, link, or text
+        which gives further details.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+
+class Lens(MSection):
+    """Details about a lens."""
+
+    name = Quantity(
+        type=str,
+        description='''Given name.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    model = Quantity(
+        type=str,
+        description='''Given brand or model name by the manufacturer.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    serial_number = Quantity(
+        type=str, description='''Given hardware name/serial number or
+        hash identifier issued by the manufacturer.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    manufacturer_name = Quantity(
+        type=str, description='''Given name of the manufacturer.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+
+class Detector(MSection):
+    """Details about the detector."""
+
+    name = Quantity(
+        type=str,
+        description='''Given name.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    model = Quantity(
+        type=str,
+        description='''Given brand or model name by the manufacturer.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    serial_number = Quantity(
+        type=str, description='''
+        Given hardware name/serial number or hash identifier issued
+        by the manufacturer.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    manufacturer_name = Quantity(
+        type=str,
+        description='''Given name of the manufacturer.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    sensor_material = Quantity(
+        type=str,
+        description=''' ''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    bit_depth_readout = Quantity(
+        type=np.dtype(np.int64),
+        description=''' ''',
+        a_eln=dict(component='NumberEditQuantity'))
+
+    _bit_depth_readout_units = Quantity(
+        type=str,
+        description=''' ''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    number_of_cycles = Quantity(
+        type=np.dtype(np.int64),
+        description=''' ''',
+        a_eln=dict(component='NumberEditQuantity'))
+
+    _number_of_cycles_units = Quantity(
+        type=str,
+        description=''' ''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    x_pixel_size = Quantity(
+        type=np.dtype(np.float64),
+        unit='meter',
+        description='''Physical distance represented by
+        the edge of the pixel along the x direction.''',
+        a_eln=dict(component='NumberEditQuantity'))
+
+    _x_pixel_size_units = Quantity(
+        type=str,
+        description=''' ''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    y_pixel_size = Quantity(
+        type=np.dtype(np.float64),
+        unit='meter',
+        description='''Physical distance represented by
+        the edge of the pixel along the y direction.''',
+        a_eln=dict(component='NumberEditQuantity'))
+
+    _y_pixel_size_units = Quantity(
+        type=str,
+        description=''' ''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    flatfield_applied = Quantity(
+        type=bool,
+        description=''' ''',
+        a_eln=dict(component='BoolEditQuantity'))
+
+    flatfield = Quantity(
+        type=np.dtype(np.float64),
+        description=''' ''',
+        a_eln=dict(component='NumberEditQuantity'))
+
+    _flatfield_units = Quantity(
+        type=str,
+        description=''' ''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    description = Quantity(
+        type=str,
+        description='''
+        Free text option to write further details about the detector.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+
+class InstrumentControl(MSection):
+    """Details relevant for the control of the instrument."""
+
+    camera_length = Quantity(
+        type=np.dtype(np.float64),
+        unit='meter',
+        description='''Exact definition as understood by HU colleagues
+        remains to be communicated.''',
+        a_eln=dict(component='NumberEditQuantity'))
+
+    _camera_length_units = Quantity(
+        type=str,
+        description='''Exact definition as understood by HU colleagues
+        remains to be communicated.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    magnification = Quantity(
+        type=np.dtype(np.float64),
+        description='''
+        Exact definition as understood by HU colleagues
+        remains to be communicated.''',
+        a_eln=dict(component='NumberEditQuantity'))
+
+    _magnification_units = Quantity(
+        type=str,
+        description='''
+        Exact definition as understood by HU colleagues
+        remains to be communicated.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+
+class Stage(MSection):
+    """Details about the stage."""
+
+    design = Quantity(
+        type=str,
+        description=''' ''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    name = Quantity(
+        type=str,
+        description=''' ''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    model = Quantity(
+        type=str,
+        description=''' ''', a_eln=dict(component='StringEditQuantity'))
+
+    serial_number = Quantity(
+        type=str,
+        description=''' ''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    manufacturer_name = Quantity(
+        type=str,
+        description=''' ''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    description = Quantity(
+        type=str,
+        description=''' ''',
+        a_eln=dict(component='StringEditQuantity'))
+
+
+class Instrument(MSection):
+    """Details about the electron microscope, its components, and software."""
+
+    name = Quantity(
+        type=str,
+        description='''
+        Given name of the microscope, e.g NionHermes.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    location = Quantity(
+        type=str,
+        description='''
+        Geographic coordinates of the lab or the place where the instrument
+        is installed using GEOREF geocodes ideally.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    instrument_manufacturer = Quantity(
+        type=str,
+        description='''
+        Manufacturer of the entire instrument (e.g. Nion, FEI, Zeiss,
+        Thermofisher) to enable e.g. queries in materials
+        database systems for instrument manufacturers.
+        Usually more technical details are needed though to specify the
+        instrument, these should be written into instrument_model and
+        instrument_capabilities.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    instrument_model = Quantity(
+        type=str,
+        description='''
+        Manufacturer brand/model to enable e.g. queries about
+        microscope models.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    instrument_identifier = Quantity(
+        type=str,
+        description='''
+        Hardware name/serial number or hash identifier given by the
+        manufacturer to identify the instrument.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    instrument_capability = Quantity(
+        type=str,
+        description='''Free-text list possibly multiple terms of
+        functionalities which the instrument provides.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    electron_gun = SubSection(section_def=ElectronGun)
+    aperture = SubSection(section_def=Aperture, repeats=True)
+    lens = SubSection(section_def=Lens, repeats=True)
+    stage = SubSection(section_def=Stage)
+    detector = SubSection(section_def=Detector)
+    control = SubSection(section_def=InstrumentControl)
+
+
+class Operator(MSection):
+    """Contact information of at least the user of the instrument.
+
+    Or the investigator who performed this experiment.
+    Adding multiple users if relevant is recommended.
+    """
+
+    m_def = Section(a_eln=dict())
+
+    name = Quantity(
+        type=str,
+        description='''
+        Given (first) name and surname of the user.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    affiliation = Quantity(
+        type=str,
+        description='''
+        Name of the affiliation of the user at the point in time
+        when the experiment was performed.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    address = Quantity(
+        type=str,
+        description='''Postal address of the affiliation.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    email = Quantity(
+        type=str,
+        description='''
+        Email address of the user at the point in time
+        when the experiment was performed.
+        Giving the most permanently used email is recommended.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    orcid = Quantity(
+        type=str,
+        description='''
+        Globally unique identifier of the user as offered
+        by services like ORCID or ResearcherID.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    telephone_number = Quantity(
+        type=str,
+        description='''
+        (Business) (tele)phone number of the user at the point
+        in time when the experiment was performed.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    role = Quantity(
+        type=str,
+        description='''
+        Which role does the user have in the place, and at the point in time
+        when, the experiment was performed (e.g. technician operating the
+        microscope, student, postdoc, principal investigator, guest ...)''',
+        a_eln=dict(component='StringEditQuantity'))
+
+
+class Sample(MSection):
+    """Properties of the specimen, its history."""
+
+    name = Quantity(
+        type=str,
+        description='''
+        Descriptive name or identifier with which to distinguish the specimen
+        from all others and especially the parts from where it was cut.
+        In cases where the specimen was e.g. site-specifically cut from
+        samples or in cases of an instrument session during which multiple
+        specimens are loaded, the name has to be descriptive enough to resolve
+        which specimen on e.g. the microtip array was taken. The user is
+        advised to store the details how specimens were cut/prepared from
+        samples in the sample history.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    sample_history = Quantity(
+        type=str,
+        description='''
+        Ideally, a reference to the location of or a (globally persistent)
+        unique identifier of e.g. another file which should document ideally
+        as many details as possible of the material, its microstructure, and
+        its thermo-chemo-mechanical processing/preparation history.
+        In the case that such a detailed history of the sample/specimen is not
+        available, use this field as a free-text description to specify a sub-
+        set of the entire sample history, i.e. what you would consider being
+        the key steps and relevant information about the specimen, its
+        material, microstructure, thermo-chemo-mechanical processing state,
+        and details of the preparation.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    preparation_date = Quantity(
+        type=Datetime,
+        description='''
+        ISO8601 date and time with local time zone offset to UTC included
+        when the specimen was prepared. Ideally report the end of the
+        preparation, i.e. the last known time the measured specimen surface
+        was actively prepared. Knowing when the specimen was exposed to e.g.
+        specific atmosphere is especially required for environmentally
+        sensitive material such as hydrogen-charged specimens or experiments
+        including tracers with a short half-time. The user is advised to
+        include these temporal details in the sample_history.''',
+        a_eln=dict(component='DateTimeEditQuantity'))
+
+    atom_types = Quantity(
+        type=str,
+        description='''
+        Use Hill's system for listing elements of the periodic table which
+        are inside or attached to the surface of the specimen and thus
+        considered relevant from a scientific point. The purpose of the field
+        is to offer materials database systems an opportunity to parse the
+        relevant elements without having to interpret these
+        from the sample history.''',
+        a_eln=dict(component='StringEditQuantity'))
+
+    thickness = Quantity(
+        type=np.dtype(np.float64),
+        unit='meter',
+        description='''Sample thickness''',
+        a_eln=dict(component='NumberEditQuantity'))
+
+    _thickness_units = Quantity(
+        type=str,
+        description='''Sample thickness''',
+        a_eln=dict(component='StringEditQuantity'))
+
+
+class ElectronMicroscopyNion(EntryData):
+    """Application definition describing electron microscope experiments.
+
+    Applies when working with a Nion microscope using NXem_nion.nxdl.xml.
+    The here specified ELN is a proof-of-concept whose scope is to provide
+    a mechanism to inject additional pieces of information to create a NeXus
+    file that matches a:
+    - particular version of the NXem_nion.nxdl.xml appdef
+    - https://github.com/FAIRmat-Experimental/nexus_definitions/commit/
+    - 1d46b94dc36a42225ad247cc763277a47dcd30d4
+    - working with experiments as a pair of Numpy NPY binary and Nion
+    - metadata JSON file. Specifically with these file formats being
+    - interpretable with the following, so-called em_nion dataconverter
+    - (see commit below).
+    The ELN returns a json file that is to be used to inject the
+    here collected pieces of information in a
+    - specifically-versioned dataconverter em_nion
+    - https://github.com/nomad-coe/nomad-parser-nexus/commit/
+     47bc4f9724b8e980bd41d0fca3a663c0b79a7fb1
+    """
+
+    start_time = Quantity(
+        type=Datetime,
+        description='''
+        ISO 8601 formatted time code with local time zone offset to UTC
+        information included when the experiment started. If the application
+        demands that time codes in this section of the application definition
+        should only be used for specifying when the experiment was performed -
+        and the exact duration is not relevant - this start time field
+        should be used. Often though it is useful to specify a time interval
+        with specifying both start_time and end_time to allow for more
+        detailed bookkeeping and interpretation of the experiment. The user
+        should be aware that even with having both time instances specified
+        it may not be advisable to infer how long the experiment took or
+        for how long data were acquired. More detailed timing data over
+        the course of the experiment have to be collected.''',
+        a_eln=dict(component='DateTimeEditQuantity'))
+
+    end_time = Quantity(
+        type=Datetime,
+        description='''
+        ISO 8601-formatted time code with local time zone offset to UTC
+        included when the experiment ended.''',
+        a_eln=dict(component='DateTimeEditQuantity'))
+
+    sample = SubSection(section_def=Sample)
+    operator = SubSection(section_def=Operator, repeats=True)
+    instrument = SubSection(section_def=Instrument)
+
+    nionswift_data_npy_file = Quantity(
+        type=str,
+        description='''
+        Numpy data file as exported from NionSwift''',
+        a_eln=dict(component='FileEditQuantity'),
+        a_browser=dict(adaptor='RawFileAdaptor'))
+
+    nionswift_metadata_json_file = Quantity(
+        type=str,
+        description='''
+        Json file with metadata as exported from NionSwift''',
+        a_eln=dict(component='FileEditQuantity'),
+        a_browser=dict(adaptor='RawFileAdaptor'))
+
+    # maybe a database dump file from e.g. NionSwift or microscope control
+    # software in general
+
+    def normalize(self, archive, logger):
+        """Normalize data."""
+        # store content of the above ELN entries into a dictionary
+        # data = self.m_to_dict()
+
+        # map paths in this dictionary on paths as expected by apm reader
+        # for instance by storing flattened data key value pairs in a json
+        # file
+
+        # remains to be implemented
+
+#       runner = CliRunner()
+#       converter_args = ['--input-file', self.nionswift_data_npy_file,
+#                         '--input-file', self.nionswift_metadata_json_file,
+#                         '--input-file',
+#                         os.path.join(filepath, 'eln.em_nion.json'),
+#                         '--reader', 'em_nion',
+#                         '--nxdl', 'NXem_nion',
+#                         '--output', os.path.join(filepath, \
+#                         'em_nion.test.nxs')]
+#       runner.invoke(convert, converter_args)
+
+        pass
+
+# =============================================================================
+#         import yaml
+#         from nomad.datamodel.metainfo.ellipsometry.dict_flattener \
+#    import dict_flatten, dict_key_cut
+#         from nexusparser.tools.dataconverter.convert import convert
+#         from click.testing import CliRunner
+#
+#         data = self.m_to_dict()
+#         data.update(data.pop('data_file'))
+#         dict_flatten(data)
+#         dict_key_cut(data)
+#
+#         kl = list(data.keys())
+#         for k in kl:
+#             if '/_' in k:
+#                 data[k.replace('/_', r"/\@")] = data.pop(k)
+#         dict_key_cut(data, '/', 1, '@')
+#         data['definition'] = 'NXellipsometry'
+#         data[r"definition/\@version"] = '0.0.1'
+#         data[r"definition/\@url"] = 'https://'
+#
+#         with archive.m_context.raw_file('eln.apm.json', 'w') as outfile:
+#             yaml.dump(data, outfile, default_flow_style=False)
+#             filepath = os.path.dirname(outfile.name)
+# =============================================================================
+
+
+m_package.__init_metainfo__()