Commits (2)
# Copyright 2016-2018 Markus Scheidgen
# Copyright 2016-2019 Markus Scheidgen, Markus Kühbach
# 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
......@@ -15,6 +15,7 @@ import sys
import os.path
import json
import ase
import re
import numpy as np
from datetime import datetime
......@@ -24,8 +25,7 @@ from nomadcore.baseclasses import ParserInterface, AbstractBaseParser
from nomad.parsing import LocalBackend
class SkeletonParserInterface(ParserInterface):
class APTFIMParserInterface(ParserInterface):
def get_metainfo_filename(self):
"""
The parser specific metainfo. To include other metadata definitions, use
......@@ -33,13 +33,13 @@ class SkeletonParserInterface(ParserInterface):
to nomadmetainfo.json files that are part of the general nomad-meta-info
submodule (i.e. ``dependencies/nomad-meta-info``).
"""
return os.path.join(os.path.dirname(__file__), 'skeleton.nomadmetainfo.json')
return os.path.join(os.path.dirname(__file__), 'aptfim.nomadmetainfo.json')
def get_parser_info(self):
""" Basic info about parser used in archive data and logs. """
return {
'name': 'you parser name',
'version': '1.0.0'
'name': 'aptfimparser',
'version': '0.1.0'
}
def setup_version(self):
......@@ -48,55 +48,71 @@ class SkeletonParserInterface(ParserInterface):
def setup_main_parser(self, _):
""" Setup the actual parser (behind this interface) """
self.main_parser = SkeletonParser(self.parser_context)
self.main_parser = APTFIMParser(self.parser_context)
class APTFIMParser(AbstractBaseParser):
class SkeletonParser(AbstractBaseParser):
def parse(self, filepath):
backend = self.parser_context.super_backend
with open(filepath, 'rt') as f:
data = json.load(f)
# You need to open sections before you can add values or sub sections to it.
# The returned 'gid' can be used to reference a specific section if multiple
# sections of the same type are opened.
root_gid = backend.openSection('section_experiment')
# Values are added to the open section of the given metadata definitions. In
# the following case 'experiment_location' is a quantity of 'section_experiment'.
# When multiple sections of the same type (e.g. 'section_experiment') are open,
# you can use the 'gid' as an additional argument.
backend.addValue('experiment_location', data.get('location'))
# The backend will check the type of the given value agains the metadata definition.
backend.addValue('experiment_time', int(datetime.strptime(data.get('date'), '%d.%M.%Y').timestamp()))
# Subsections work like before. The parent section must still be open.
method_gid = backend.openSection('section_method')
backend.addValue('experiment_method_name', data.get('method', 'Bare eyes'))
# Values do not necessarely have to be read from the parsed file.
backend.addValue('probing_method', 'laser pulsing')
backend.closeSection('section_method', method_gid)
# Read general tool environment details
backend.addValue('experiment_location', data.get('experiment_location'))
backend.addValue('experiment_facility_institution', data.get('experiment_facility_institution'))
backend.addValue('experiment_summary', '%s of %s.' % (data.get('experiment_method').capitalize(), data.get('specimen_description')))
try:
backend.addValue('experiment_time', int(datetime.strptime(data.get('experiment_date_global_start'), '%d.%m.%Y %M:%H:%S').timestamp()))
except ValueError:
pass
try:
backend.addValue('experiment_end_time', int(datetime.strptime(data.get('experiment_date_global_end'), '%d.%m.%Y %M:%H:%S').timestamp()))
except ValueError:
pass
# Read data parameters
data_gid = backend.openSection('section_data')
backend.addValue('data_repository_name', 'zenodo.org')
backend.addValue('data_repository_url', 'https://zenodo.org/path/to/mydata')
backend.addValue('data_preview_url', 'https://www.physicsforums.com/insights/wp-content/uploads/2015/09/fem.jpg')
backend.addValue('data_repository_name', data.get('data_repository_name'))
backend.addValue('data_repository_url', data.get('data_repository_url'))
preview_url = data.get('data_preview_url')
# TODO: This a little hack to correct the preview url and should be removed
# after urls are corrected
preview_url = '%s/files/%s' % tuple(preview_url.rsplit('/', 1))
backend.addValue('data_preview_url', preview_url)
backend.closeSection('section_data', data_gid)
# Subsections work like before. The parent section must still be open.
# Read parameters related to method
method_gid = backend.openSection('section_method')
backend.addValue('experiment_method_name', data.get('experiment_method'))
backend.addValue('experiment_method_abbreviation', 'APT/FIM')
backend.addValue('probing_method', 'electric pulsing')
# backend.addValue('experiment_tool_info', data.get('instrument_info')) ###test here the case that input.json keyword is different to output.json
# measured_pulse_voltage for instance should be a conditional read
# backend.addValue('measured_number_ions_evaporated', data.get('measured_number_ions_evaporated'))
# backend.addValue('measured_detector_hit_pos', data.get('measured_detector_hit_pos'))
# backend.addValue('measured_detector_hit_mult', data.get('measured_detector_hit_mult'))
# backend.addValue('measured_detector_dead_pulses', data.get('measured_detector_dead_pulses'))
# backend.addValue('measured_time_of_flight', data.get('measured_time_of_flight'))
# backend.addValue('measured_standing_voltage', data.get('measured_standing_voltage'))
# backend.addValue('measured_pulse_voltage', data.get('measured_pulse_voltage'))
# backend.addValue('experiment_operation_method', data.get('experiment_operation_method'))
# backend.addValue('experiment_imaging_method', data.get('experiment_imaging_method'))
backend.closeSection('section_method', method_gid)
# Read parameters related to sample
sample_gid = backend.openSection('section_sample')
backend.addValue('sample_chemical_name', data.get('sample_chemical'))
backend.addValue('sample_chemical_formula', data.get('sample_formula'))
backend.addValue('sample_temperature', data.get('sample_temp'))
backend.addValue('sample_microstructure', 'thin films')
backend.addValue('sample_constituents', 'multi phase')
atoms = set(ase.Atoms(data.get('sample_formula')).get_chemical_symbols())
# To add arrays (vectors, matrices, etc.) use addArrayValues and provide a
# numpy array. The shape of the numpy array must match the shape defined in
# the respective metadata definition.
backend.addArrayValues('sample_atom_labels', np.array(list(atoms)))
# Close sections in the reverse order.
backend.addValue('sample_description', data.get('specimen_description'))
backend.addValue('sample_microstructure', data.get('specimen_microstructure'))
backend.addValue('sample_constituents', data.get('specimen_constitution'))
atom_labels = data.get('specimen_chemistry')
formula = ase.Atoms(atom_labels).get_chemical_formula()
backend.addArrayValues('sample_atom_labels', np.array(atom_labels))
backend.addValue('sample_chemical_formula', formula)
backend.closeSection('section_sample', sample_gid)
# Close sections in the reverse order
backend.closeSection('section_experiment', root_gid)
......@@ -14,11 +14,11 @@
import sys
from nomad.parsing import LocalBackend
from skeletonparser import SkeletonParserInterface
from aptfimparser import APTFIMParserInterface
if __name__ == "__main__":
# instantiate the parser via its interface with a LocalBackend
parser = SkeletonParserInterface(backend=LocalBackend)
parser = APTFIMParserInterface(backend=LocalBackend)
# call the actual parsing with the given mainfile
parser.parse(sys.argv[1])
# print the results stored in the LocalBackend
......
{
"type": "nomad_meta_info_1_0",
"description": "Metadata for an atom probe tomography or field ion microscopy experiment.",
"dependencies":[
{
"metainfoPath":"general.nomadmetainfo.json"
},
{
"metainfoPath":"general.experimental.nomadmetainfo.json"
}
],
"metaInfos": [
{
"description": "Shape of the None/Null object",
"name": "none_shape",
"dtypeStr": "i",
"kindStr": "type_dimension",
"shape": [],
"superNames": ["section_experiment"]
},
{
"description": "Name of the equipment, instrument with which the experiment was performed e.g. LEAP5000XS",
"name": "experiment_tool_info",
"dtypeStr": "C",
"shape": [],
"superNames": ["section_experiment"],
"units": ""
},
{
"description": "Operation mode of the instrument (APT, FIM or combination)",
"name": "experiment_operation_method",
"dtypeStr": "C",
"shape": [],
"superNames": ["section_experiment"],
"units": ""
},
{
"description": "Pulsing method to enforce a controlled ion evaporation sequence",
"name": "experiment_imaging_method",
"dtypeStr": "C",
"shape": [],
"superNames": ["section_experiment"],
"units": ""
},
{
"description": "Sample description e.g. pure W wire samples trial 2",
"name": "specimen_description",
"dtypeStr": "C",
"shape": [],
"superNames": ["section_experiment"],
"units": ""
},
{
"description": "Number of elements (disjoint element names) expected",
"name": "number_of_elements",
"dtypeStr": "i",
"kindStr": "type_dimension",
"shape": [],
"superNames": ["section_experiment"],
"units": ""
},
{
"description": "List of periodic table names expected contained in dataset",
"name": "specimen_chemistry",
"dtypeStr": "C",
"shape": ["number_of_elements"],
"superNames": ["section_experiment"],
"units": ""
},
{
"description": "Qualitative type of specimen and microstructure analyzed (e.g. thin films, nano objects, single crystal, polycrystal)",
"name": "specimen_microstructure",
"dtypeStr": "C",
"shape": [],
"superNames": ["section_experiment"],
"units": ""
},
{
"description": "Qualitative information how many phases in the specimen",
"name": "specimen_constitution",
"dtypeStr": "C",
"shape": [],
"superNames": ["section_experiment"],
"units": ""
},
{
"description": "Number of ions successfully evaporated",
"name": "measured_number_ions_evaporated",
"dtypeStr": "i",
"shape": [],
"superNames": ["section_experiment"],
"units": "1"
},
{
"description": "Detector hit positions x and y",
"name": "measured_detector_hit_pos",
"dtypeStr": "C",
"shape": [],
"superNames": ["section_experiment"],
"units": "mm, mm"
},
{
"description": "Detector hit multiplicity",
"name": "measured_detector_hit_mult",
"dtypeStr": "C",
"shape": [],
"superNames": ["section_experiment"],
"units": "1"
},
{
"description": "Detector number of dead pulses",
"name": "measured_detector_dead_pulses",
"dtypeStr": "C",
"shape": [],
"superNames": ["section_experiment"],
"units": "1"
},
{
"description": "Raw ion time of flight",
"name": "measured_time_of_flight",
"dtypeStr": "C",
"shape": [],
"superNames": ["section_experiment"],
"units": "ns"
},
{
"description": "Standing voltage",
"name": "measured_standing_voltage",
"dtypeStr": "C",
"shape": [],
"superNames": ["section_experiment"],
"units": "V"
},
{
"description": "Pulse voltage",
"name": "measured_pulse_voltage",
"dtypeStr": "C",
"shape": [],
"superNames": ["section_experiment"],
"units": "V"
}
]
}
{
"type": "nomad_meta_info_1_0",
"description": "Metadata for an atom probe tomography or field ion microscopy experiment.",
"dependencies":[
{
"metainfoPath":"general.nomadmetainfo.json"
},
{
"metainfoPath":"general.experimental.nomadmetainfo.json"
}
],
"metaInfos": [
{
"description": "String identifier aka name of the repository where the raw data to the experiment is available",
"name": "experiment_typpe",
"dtypeStr": "C",
"shape": [],
"superNames": ["section_context"]
},
{
"description": "String identifier aka name of the repository where the raw data to the experiment is available",
"name": "data_repository_name",
"dtypeStr": "C",
"shape": [],
"superNames": ["section_experiment"],
"units": ""
},
{
"description": "URL of this repository",
"name": "where",
"dtypeStr": "C",
"shape": [],
"superNames": ["section_experiment"],
"units": ""
},
{
"description": "Thumbnail image informing about the experiment",
"name": "data_preview_url",
"dtypeStr": "C",
"shape": [],
"superNames": ["section_experiment"],
"units": ""
},
{
"description": "Shape of the None/Null object",
"name": "none_shape",
"dtypeStr": "i",
"kindStr": "type_dimension",
"shape": [],
"superNames": ["section_experiment"]
},
{
"description": "Full name of the experimental method in use",
"name": "experiment_method",
"dtypeStr": "C",
"shape": [],
"superNames": ["section_experiment"],
"units": ""
},
{
"description": "Name of the city and country the experiment took place, format 'Country, City'",
"name": "experiment_location",
"dtypeStr": "C",
"shape": [],
"superNames": ["section_experiment"],
"units": ""
},
{
"description": "Name of the institution hosting the experimental facility",
"name": "experiment_facility_institution",
"dtypeStr": "C",
"shape": [],
"superNames": ["section_experiment"],
"units": ""
},
{
"description": "Name of the equipment, instrument with which the experiment was performed e.g. LEAP5000XS",
"name": "experiment_tool_info",
"dtypeStr": "C",
"shape": [],
"superNames": ["section_experiment"],
"units": ""
},
{
"description": "UTC start time of the experiment, format 'DD.MM.YYYY - HH.MM.SS'",
"name": "experiment_date_global_start",
"dtypeStr": "C",
"shape": [],
"superNames": ["section_experiment"],
"units": "C"
},
{
"description": "UTC end time of the experiment, format 'DD.MM.YYYY - HH.MM.SS'",
"name": "experiment_date_global_end",
"dtypeStr": "C",
"shape": [],
"superNames": ["section_experiment"],
"units": "C"
},
{
"description": "Local start time of the experiment, format 'DD.MM.YYYY - HH.MM.SS'",
"name": "experiment_date_local_start",
"dtypeStr": "C",
"shape": [],
"superNames": ["section_experiment"],
"units": "C"
},
{
"description": "Operation mode of the instrument (APT, FIM or combination)",
"name": "experiment_operation_method",
"dtypeStr": "C",
"shape": [],
"superNames": ["section_experiment"],
"units": ""
},
{
"description": "Pulsing method to enforce a controlled ion evaporation sequence",
"name": "experiment_imaging_method",
"dtypeStr": "C",
"shape": [],
"superNames": ["section_experiment"],
"units": ""
},
{
"description": "Sample description e.g. pure W wire samples trial 2",
"name": "specimen_description",
"dtypeStr": "C",
"shape": [],
"superNames": ["section_experiment"],
"units": ""
},
{
"description": "Number of elements (disjoint element names) expected",
"name": "number_of_elements",
"dtypeStr": "i",
"kindStr": "type_dimension",
"shape": [],
"superNames": ["section_experiment"],
"units": ""
},
{
"description": "List of periodic table names expected contained in dataset",
"name": "specimen_chemistry",
"dtypeStr": "C",
"shape": ["number_of_elements"],
"superNames": ["section_experiment"],
"units": ""
},
{
"description": "Qualitative type of specimen and microstructure analyzed (e.g. thin films, nano objects, single crystal, polycrystal)",
"name": "specimen_microstructure",
"dtypeStr": "C",
"shape": [],
"superNames": ["section_experiment"],
"units": ""
},
{
"description": "Qualitative information how many phases in the specimen",
"name": "specimen_constitution",
"dtypeStr": "C",
"shape": [],
"superNames": ["section_experiment"],
"units": ""
},
{
"description": "Number of ions successfully evaporated",
"name": "measured_number_ions_evaporated",
"dtypeStr": "i",
"shape": [],
"superNames": ["section_experiment"],
"units": "1"
},
{
"description": "Detector hit positions x and y",
"name": "measured_detector_hit_pos",
"dtypeStr": "C",
"shape": [],
"superNames": ["section_experiment"],
"units": "mm, mm"
},
{
"description": "Detector hit multiplicity",
"name": "measured_detector_hit_mult",
"dtypeStr": "C",
"shape": [],
"superNames": ["section_experiment"],
"units": "1"
},
{
"description": "Detector number of dead pulses",
"name": "measured_detector_dead_pulses",
"dtypeStr": "C",
"shape": [],
"superNames": ["section_experiment"],
"units": "1"
},
{
"description": "Raw ion time of flight",
"name": "measured_time_of_flight",
"dtypeStr": "C",
"shape": [],
"superNames": ["section_experiment"],
"units": "ns"
},
{
"description": "Standing voltage",
"name": "measured_standing_voltage",
"dtypeStr": "C",
"shape": [],
"superNames": ["section_experiment"],
"units": "V"
},
{
"description": "Pulse voltage",
"name": "measured_pulse_voltage",
"dtypeStr": "C",
"shape": [],
"superNames": ["section_experiment"],
"units": "V"
}
]
}
......@@ -16,14 +16,14 @@ from setuptools import setup, find_packages
def main():
setup(
name='skeletonparser', # replace with new name for parser's python package
name='aptfimparser', # replace with new name for parser's python package
version='0.1',
description='A skeleton NOMAD parser implementation.', # change accordingly
author='', # add your names
description='A NOMAD parser implementation for aptfim data.', # change accordingly
author='Markus Kühbach', # add your names
license='APACHE 2.0',
packages=find_packages(),
package_data={
'skeletonparser': ['*.json']
'aptfimparser': ['*.json']
},
install_requires=[
'nomadcore'
......
{
"type": "nomad_meta_info_1_0",
"description": "Parser specific metadata definitions.",
"dependencies":[
{
"metainfoPath":"general.nomadmetainfo.json"
},
{
"metainfoPath":"general.experimental.nomadmetainfo.json"
}
],
"metaInfos": [
{
"description": "Contains information relating to an archive.",
"name": "experiment_location",
"dtypeStr": "C",
"superNames": ["section_experiment"]
}
]
}
{
"data_repository_name": "zenodo.org",
"data_repository_url": "http://zenodo.org/record/1249280",
"data_preview_url": "http://zenodo.org/record/1249280/preview.png",
"experiment_method": "atom probe tomography or field ion microscopy",
"experiment_location": "Düsseldorf, Germany",
"experiment_facility_institution": "Max-Planck-Institut für Eisenforschung GmbH",
"instrument_info": "LEAP5000",
"experiment_date_global_start": "01.01.2000 11:11:11",
"experiment_date_global_end": "01.01.2000 22:22:22",
"experiment_data_local_start": "01.01.2000 11:11:11",
"experiment_operation_method": "apt",
"experiment_imaging_method": "laser",
"specimen_description": "Pure W wire samples bulk polycrystal",
"specimen_chemistry": ["Fe", "Mn"],
"specimen_microstructure": "single crystal",
"specimen_constitution": "single phase",
"measured_nions_evaporated": 129000,
"measured_detector_hit_pos": "yes",
"measured_detector_hit_mult": "no",
"measured_detector_dead_pulses": "no",
"measured_time_of_flight": "yes",
"measured_standing_voltage": "yes",
"measured_pulse_voltage": "no"
}