diff --git a/lammpsparser/lammps_parser.py b/lammpsparser/lammps_parser.py
index 9e782e7fa6142d4b9e64bc169a0884badbd2dbb7..59e7a758ba6bfb34fca0bb15682908f400ff17e7 100644
--- a/lammpsparser/lammps_parser.py
+++ b/lammpsparser/lammps_parser.py
@@ -7,10 +7,9 @@ import pint
 from .metainfo import m_env
 from nomad.parsing.parser import FairdiParser
 
-from nomad.parsing.file_parser import Quantity, UnstructuredTextFileParser
-from nomad.datamodel.metainfo.public import section_run, section_sampling_method,\
-    section_system, section_single_configuration_calculation, section_energy_contribution,\
-    Workflow, MolecularDynamics
+from nomad.parsing.file_parser import Quantity, TextParser
+from nomad.datamodel.metainfo.common_dft import Run, SamplingMethod, System,\
+    SingleConfigurationCalculation, EnergyContribution, Workflow, MolecularDynamics
 from nomad.datamodel.metainfo.common import section_topology, section_interaction
 from .metainfo.lammps import x_lammps_section_input_output_files, x_lammps_section_control_parameters
 
@@ -85,7 +84,7 @@ def get_unit(units_type, property_type=None, dimension=3):
         return units
 
 
-class DataParser(UnstructuredTextFileParser):
+class DataParser(TextParser):
     def __init__(self):
         self._headers = [
             'atoms', 'bonds', 'angles', 'dihedrals', 'impropers', 'atom types', 'bond types',
@@ -109,8 +108,8 @@ class DataParser(UnstructuredTextFileParser):
     def init_quantities(self):
         self._quantities = []
         for header in self._headers:
-            self._quantities.append(
-                Quantity(header, r'\s*([\+\-eE\d\. ]+)\s*%s\s*\n' % header, comment='#'))
+            self._quantities.append(Quantity(
+                header, r'\s*([\+\-eE\d\. ]+)\s*%s\s*\n' % header, comment='#', repeats=True))
 
         def get_section_value(val):
             val = val.split('\n')
@@ -137,7 +136,7 @@ class DataParser(UnstructuredTextFileParser):
             self._quantities.append(
                 Quantity(
                     section, r'\s*%s\s*(#*\s*[\s\S]*?\n)\n*([\deE\-\+\.\s]+)\n' % section,
-                    str_operation=get_section_value))
+                    str_operation=get_section_value, repeats=True))
 
     def get_interactions(self):
         styles_coeffs = []
@@ -153,7 +152,7 @@ class DataParser(UnstructuredTextFileParser):
         return styles_coeffs
 
 
-class TrajParser(UnstructuredTextFileParser):
+class TrajParser(TextParser):
     def __init__(self):
         self._masses = None
         self._reference_masses = dict(
@@ -183,15 +182,17 @@ class TrajParser(UnstructuredTextFileParser):
 
         self._quantities = [
             Quantity(
-                'time_step', r'\s*ITEM:\s*TIMESTEP\s*\n\s*(\d+)\s*\n', comment='#'),
+                'time_step', r'\s*ITEM:\s*TIMESTEP\s*\n\s*(\d+)\s*\n', comment='#',
+                repeats=True),
             Quantity(
-                'n_atoms', r'\s*ITEM:\s*NUMBER OF ATOMS\s*\n\s*(\d+)\s*\n', comment='#'),
+                'n_atoms', r'\s*ITEM:\s*NUMBER OF ATOMS\s*\n\s*(\d+)\s*\n', comment='#',
+                repeats=True),
             Quantity(
                 'pbc_cell', r'\s*ITEM: BOX BOUNDS\s*([\s\w]+)([\+\-\d\.eE\s]+)\n',
-                str_operation=get_pbc_cell, comment='#'),
+                str_operation=get_pbc_cell, comment='#', repeats=True),
             Quantity(
                 'atoms_info', r's*ITEM:\s*ATOMS\s*([ \w]+\n)*?([\+\-eE\d\.\n ]+)\n*I*',
-                str_operation=get_atoms_info, comment='#')
+                str_operation=get_atoms_info, comment='#', repeats=True)
         ]
 
     def with_trajectory(self):
@@ -291,7 +292,7 @@ class TrajParser(UnstructuredTextFileParser):
         return pint.Quantity(forces, self._units.get('force', None))
 
 
-class LogParser(UnstructuredTextFileParser):
+class LogParser(TextParser):
     def __init__(self):
         self._commands = [
             'angle_coeff', 'angle_style', 'atom_modify', 'atom_style', 'balance',
@@ -329,25 +330,18 @@ class LogParser(UnstructuredTextFileParser):
         self._quantities = [
             Quantity(
                 name, r'\n\s*%s\s+([\w\. \/\#\-]+)(\&\n[\w\. \/\#\-]*)*' % name,
-                str_operation=str_op, comment='#') for name in self._commands]
+                str_operation=str_op, comment='#', repeats=True) for name in self._commands]
 
-        self._quantities.append(
-            Quantity('program_version', r'\s*LAMMPS\s*\(([\w ]+)\)\n', dtype=str)
+        self._quantities.append(Quantity(
+            'program_version', r'\s*LAMMPS\s*\(([\w ]+)\)\n', dtype=str, repeats=False,
+            flatten=False)
         )
 
-        self._quantities.append(
-            Quantity('finished', r'\s*Dangerous builds\s*=\s*(\d+)')
+        self._quantities.append(Quantity(
+            'finished', r'\s*Dangerous builds\s*=\s*(\d+)', repeats=False)
         )
 
-    @property
-    def units(self):
-        if self._file_handler is None or self._units is None:
-            units_type = self.get('units', ['lj'])[0]
-            self._units = get_unit(units_type)
-        return self._units
-
-    def get_thermodynamic_data(self):
-        def str_operation(val):
+        def str_to_thermo(val):
             res = {}
             if val.count('Step') > 1:
                 val = val.replace('-', '').replace('=', '').replace('(sec)', '').split()
@@ -369,14 +363,23 @@ class LogParser(UnstructuredTextFileParser):
 
             return res
 
-        pattern = r'\s*\-*(\s*Step\s*[\-\s\w\.\=\(\)]*[ \-\.\d\n]+)Loop'
+        self._quantities.append(Quantity(
+            'thermo_data', r'\s*\-*(\s*Step\s*[\-\s\w\.\=\(\)]*[ \-\.\d\n]+)Loop',
+            str_operation=str_to_thermo, repeats=False, convert=False)
+        )
 
-        parser = UnstructuredTextFileParser(
-            self.mainfile, [Quantity('thermo_data', pattern, str_operation=str_operation)])
+    @property
+    def units(self):
+        if self._file_handler is None or self._units is None:
+            units_type = self.get('units', ['lj'])[0]
+            self._units = get_unit(units_type)
+        return self._units
 
-        thermo_data = parser['thermo_data']
+    def get_thermodynamic_data(self):
+        self._thermo_data = self.get('thermo_data')
 
-        self._thermo_data = list(thermo_data)[0] if thermo_data is not None else thermo_data
+        if self._thermo_data is None:
+            return
 
         for key, val in self._thermo_data.items():
             low_key = key.lower()
@@ -422,10 +425,6 @@ class LogParser(UnstructuredTextFileParser):
         pbc = self.get('boundary', ['p', 'p', 'p'])
         return [v == 'p' for v in pbc]
 
-    def get_program_version(self):
-        version = self.get('program_version', [''])[0]
-        return ' '.join(version)
-
     def get_sampling_method(self):
         fix_style = self.get('fix', [[''] * 3])[0][2]
 
@@ -505,12 +504,6 @@ class LogParser(UnstructuredTextFileParser):
 
         return styles_coeffs
 
-    def finished_normally(self):
-        return self.get('finished') is not None
-
-    def with_thermodynamics(self):
-        return self._thermo_data is not None
-
 
 class LammpsParser(FairdiParser):
     def __init__(self):
@@ -553,14 +546,14 @@ class LammpsParser(FairdiParser):
 
         for n in range(n_evaluations):
             if create_scc:
-                sec_scc = sec_run.m_create(section_single_configuration_calculation)
+                sec_scc = sec_run.m_create(SingleConfigurationCalculation)
             else:
                 sec_scc = sec_sccs[n]
 
             for key, val in thermo_data.items():
                 key = key.lower()
                 if key in energy_keys_mapping:
-                    sec_energy = sec_scc.m_create(section_energy_contribution)
+                    sec_energy = sec_scc.m_create(EnergyContribution)
                     sec_energy.energy_contibution_kind = energy_keys_mapping[key]
                     sec_energy.energy_contribution_value = val[n]
 
@@ -586,7 +579,7 @@ class LammpsParser(FairdiParser):
 
     def parse_sampling_method(self):
         sec_run = self.archive.section_run[-1]
-        sec_sampling_method = sec_run.m_create(section_sampling_method)
+        sec_sampling_method = sec_run.m_create(SamplingMethod)
 
         run_style = self.log_parser.get('run_style', ['verlet'])[0]
         run = self.log_parser.get('run', [0])[0]
@@ -641,7 +634,7 @@ class LammpsParser(FairdiParser):
         self.traj_parser._units = self.log_parser.units
 
         for i in range(len(pbc_cell)):
-            sec_system = sec_run.m_create(section_system)
+            sec_system = sec_run.m_create(System)
             sec_system.number_of_atoms = n_atoms[i]
             sec_system.configuration_periodic_dimensions = pbc_cell[i][0]
             sec_system.simulation_cell = pbc_cell[i][1] * distance_unit
@@ -658,7 +651,7 @@ class LammpsParser(FairdiParser):
             forces = self.traj_parser.get_forces(i)
             if forces is not None:
                 if create_scc:
-                    sec_scc = sec_run.m_create(section_single_configuration_calculation)
+                    sec_scc = sec_run.m_create(SingleConfigurationCalculation)
                 else:
                     sec_scc = sec_sccs[i]
 
@@ -723,11 +716,11 @@ class LammpsParser(FairdiParser):
 
         self._init_parsers()
 
-        sec_run = self.archive.m_create(section_run)
+        sec_run = self.archive.m_create(Run)
 
         # parse basic
         sec_run.program_name = 'LAMMPS'
-        sec_run.program_version = self.log_parser.get_program_version()
+        sec_run.program_version = self.log_parser.get('program_version', '')
 
         # parse method-related
         self.parse_sampling_method()
@@ -760,6 +753,6 @@ class LammpsParser(FairdiParser):
             if sec_workflow.workflow_type == 'molecular_dynamics':
                 sec_md = sec_workflow.m_create(MolecularDynamics)
 
-                sec_md.finished_normally = self.log_parser.finished_normally()
+                sec_md.finished_normally = self.log_parser.get('finished') is not None
                 sec_md.with_trajectory = self.traj_parser.with_trajectory()
-                sec_md.with_thermodynamics = self.log_parser.with_thermodynamics()
+                sec_md.with_thermodynamics = self.log_parser.get('thermo_data') is not None