diff --git a/pyproject.toml b/pyproject.toml index d7c7416..7ae4ed5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -113,8 +113,10 @@ where = ["src"] [project.entry-points.'nomad.plugin'] # schema -xrfschema = "nomad_uibk_plugin.schema_packages:xrfschema" -sputtering = "nomad_uibk_plugin.schema_packages:sputtering" +basesections = "nomad_uibk_plugin.schema_packages:basesections" sample = "nomad_uibk_plugin.schema_packages:sample" +sputtering = "nomad_uibk_plugin.schema_packages:sputtering" +xrfschema = "nomad_uibk_plugin.schema_packages:xrfschema" # parser +sputterparser = "nomad_uibk_plugin.parsers:sputterparser" xrfparser = "nomad_uibk_plugin.parsers:xrfparser" diff --git a/src/nomad_uibk_plugin/parsers/__init__.py b/src/nomad_uibk_plugin/parsers/__init__.py index 28a7a70..472f1a9 100644 --- a/src/nomad_uibk_plugin/parsers/__init__.py +++ b/src/nomad_uibk_plugin/parsers/__init__.py @@ -19,3 +19,23 @@ def load(self): mainfile_name_re=r'.*\.txt', mainfile_content_re=r'PositionType\s+Application\s+Sample\s+name\s+Date\s+\n[A-Z0-9-]+\s+Quant\s+analysis', ) + + +class SputterParserEntryPoint(ParserEntryPoint): + """ + Sputter Parser plugin entry point. + """ + + def load(self): + # lazy import to avoid circular dependencies + from nomad_uibk_plugin.parsers.sputterparser import SputterParser + + return SputterParser(**self.dict()) + + +sputterparser = SputterParserEntryPoint( + name='SputterParser', + description='Parser for UIBK Sputterdeposition .csv log files.', + mainfile_name_re=r'.*\.csv', + # mainfile_content_re=r'', +) diff --git a/src/nomad_uibk_plugin/parsers/sputterparser.py b/src/nomad_uibk_plugin/parsers/sputterparser.py new file mode 100644 index 0000000..d168f3a --- /dev/null +++ b/src/nomad_uibk_plugin/parsers/sputterparser.py @@ -0,0 +1,59 @@ +from typing import TYPE_CHECKING + +from nomad.datamodel.data import EntryData +from nomad.datamodel.metainfo.annotations import ELNAnnotation +from nomad.metainfo import Quantity +from nomad.parsing.parser import MatchingParser +from nomad_measurements.utils import ( + create_archive, + get_entry_id_from_file_name, + get_reference, +) + +from nomad_uibk_plugin.schema_packages.sputtering import UIBKSputterDeposition + +if TYPE_CHECKING: + from nomad.datamodel.datamodel import EntryArchive + from structlog.stdlib import BoundLogger + + +class RawFileSputterData(EntryData): + """ + Section for a sputter deposition data file. + """ + + measurement = Quantity( + type=UIBKSputterDeposition, + a_eln=ELNAnnotation( + component='ReferenceEditQuantity', + ), + ) + + +class SputterParser(MatchingParser): + """ + Parser for matching sputter deposition files and creating instances of + SputterDeposition. + """ + + def parse( + self, + mainfile: str, + archive: 'EntryArchive', + logger: 'BoundLogger', + child_archives: dict[str, 'EntryArchive'] = None, + ) -> None: + logger.info('SputterParser.parse') + data_file = mainfile.split('/')[-1] + entry = UIBKSputterDeposition.m_from_dict( + UIBKSputterDeposition.m_def.a_template + ) + entry.data_file = data_file + file_name = f'{"".join(data_file.split(".")[:-1])}.archive.json' + archive.data = RawFileSputterData( + measurement=get_reference( + archive.metadata.upload_id, + get_entry_id_from_file_name(file_name, archive), + ) + ) + create_archive(entry, archive, file_name) diff --git a/src/nomad_uibk_plugin/schema_packages/XRFschema.py b/src/nomad_uibk_plugin/schema_packages/XRFschema.py index 01798f4..a78aee0 100644 --- a/src/nomad_uibk_plugin/schema_packages/XRFschema.py +++ b/src/nomad_uibk_plugin/schema_packages/XRFschema.py @@ -68,7 +68,7 @@ 'nomad_uibk_plugin.schema_packages:xrfschema' ) -m_package = SchemaPackage(name='nomad_xrf') +m_package = SchemaPackage() class XRFElementalComposition(ElementalComposition): diff --git a/src/nomad_uibk_plugin/schema_packages/__init__.py b/src/nomad_uibk_plugin/schema_packages/__init__.py index ebdc5b6..8fa7824 100644 --- a/src/nomad_uibk_plugin/schema_packages/__init__.py +++ b/src/nomad_uibk_plugin/schema_packages/__init__.py @@ -12,6 +12,19 @@ class UIBKCategory(EntryDataCategory): m_def = Category(label='UIBK', categories=[EntryDataCategory]) +class BaseSectionEntryPoint(SchemaPackageEntryPoint): + def load(self): + from nomad_uibk_plugin.schema_packages.basesections import m_package + + return m_package + + +basesections = BaseSectionEntryPoint( + name='Basesections', + description='Base sections for the UIBK plugin.', +) + + class XRFSchemaPackageEntryPoint(SchemaPackageEntryPoint): parameter: int = Field(0, description='Custom configuration parameter') diff --git a/src/nomad_uibk_plugin/schema_packages/basesections.py b/src/nomad_uibk_plugin/schema_packages/basesections.py new file mode 100644 index 0000000..e280822 --- /dev/null +++ b/src/nomad_uibk_plugin/schema_packages/basesections.py @@ -0,0 +1,85 @@ +# +# 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 typing import TYPE_CHECKING + +from nomad.datamodel.metainfo.annotations import ELNAnnotation, ELNComponentEnum +from nomad.datamodel.metainfo.basesections import ( + Process, +) +from nomad.metainfo import Quantity, SchemaPackage, SubSection + +from nomad_uibk_plugin.schema_packages.sample import UIBKSampleReference + +# if TYPE_CHECKING: +# from nomad.datamodel.datamodel import EntryArchive +# from structlog.stdlib import BoundLogger + +m_package = SchemaPackage() + + +class UIBKProcess(Process): + """Base class for UIBK processes which adds sample linking.""" + + samples = SubSection( + section_def=UIBKSampleReference, + description='Reference to the sample.', + repeats=True, + ) + + lab_id = Quantity( + type=str, + description='The lab ID of the process.', + a_eln=ELNAnnotation(component=ELNComponentEnum.StringEditQuantity), + ) + + # def normalize(self, archive: EntryArchive, logger: BoundLogger) -> None: + + # from nomad.datamodel.context import ServerContext + + # # TODO: check if statement + # if self.samples is None or self.samples == []: + + # from nomad.search import MetadataPagination, search + + # query = {'results.eln.lab_ids': self.lab_id} + # search_result = search( + # owner='all', + # query=query, + # pagination=MetadataPagination(page_size=1), + # user_id=archive.metadata.user_id, # TODO: check if this is correct + # ) + + # if search_result.pagination.total > 0: + # entry_id = search_result.data[0]['entry_id'] + # upload_id = search_result.data[0]['upload_id'] + # self.system = f'../uploads/{upload_id}/archive/{entry_id}#data' + # if search_result.pagination.total > 1: + # logger.warn( + # f'Found {search_result.pagination.total} entries with lab_id: ' # noqa: E501 + # f'"{self.lab_id}". Will use the first one found.' + # ) + # else: + # logger.warn(f'Found no entries with lab_id: "{self.lab_id}".') + # elif self.lab_id is None and len(self.samples) > 0: + # self.lab_id = self.samples[0].lab_id + # if self.name is None: + # self.name = self.lab_id + + +m_package.__init_metainfo__() diff --git a/src/nomad_uibk_plugin/schema_packages/sample.py b/src/nomad_uibk_plugin/schema_packages/sample.py index a2db475..58d3072 100644 --- a/src/nomad_uibk_plugin/schema_packages/sample.py +++ b/src/nomad_uibk_plugin/schema_packages/sample.py @@ -6,7 +6,8 @@ ) from nomad.datamodel.metainfo.annotations import ELNAnnotation, ELNComponentEnum from nomad.datamodel.metainfo.basesections import ( - CompositeSystem, # CompositeSystemReference + CompositeSystem, + CompositeSystemReference, ) from nomad.datamodel.metainfo.plot import PlotlyFigure, PlotSection from nomad.metainfo import Quantity, SchemaPackage, Section, SubSection @@ -16,7 +17,7 @@ from structlog.stdlib import BoundLogger -m_package = SchemaPackage(name='nomad_uibk_sample') +m_package = SchemaPackage() class MicroCell(CompositeSystem): @@ -133,4 +134,19 @@ def normalize(self, archive, logger): self.plot(archive, logger) +class UIBKSampleReference(CompositeSystemReference): + """ + Reference section to an UIBK sample. + """ + + reference = Quantity( + type=UIBKSample, + description='Reference to an UIBK sample', + a_eln=ELNAnnotation( + component='ReferenceEditQuantity', + label='Link to Sample', + ), + ) + + m_package.__init_metainfo__() diff --git a/src/nomad_uibk_plugin/schema_packages/sputtering.py b/src/nomad_uibk_plugin/schema_packages/sputtering.py index 3b5dd4d..e394a4a 100644 --- a/src/nomad_uibk_plugin/schema_packages/sputtering.py +++ b/src/nomad_uibk_plugin/schema_packages/sputtering.py @@ -27,7 +27,7 @@ from nomad_uibk_plugin.schema_packages import UIBKCategory from nomad_uibk_plugin.schema_packages.sample import UIBKSample -m_package = SchemaPackage(name='nomad_uibk_sputtering') +m_package = SchemaPackage() class Target(PVDSource, EntryData):