From 3c9c2b5de84527801d7f026fa6fdacbf9288fb8b Mon Sep 17 00:00:00 2001 From: sanbrock Date: Mon, 16 Dec 2024 20:06:25 +0100 Subject: [PATCH 1/4] using readonly instead of user_editability; enabling injesting multiple methods to the base classes and not only the normalization; Entry to inherit also from Task, so Workflow click drives there directly --- src/pynxtools/nomad/parser.py | 2 +- src/pynxtools/nomad/schema.py | 26 +++++++++++++++++++++----- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/pynxtools/nomad/parser.py b/src/pynxtools/nomad/parser.py index ef266663a..2fea9afde 100644 --- a/src/pynxtools/nomad/parser.py +++ b/src/pynxtools/nomad/parser.py @@ -513,7 +513,7 @@ def parse( if archive.metadata.entry_type is None: archive.metadata.entry_type = app_def archive.metadata.domain = "nexus" - archive.metadata.user_editable = False + archive.metadata.readonly = True # Normalise element info if archive.results is None: diff --git a/src/pynxtools/nomad/schema.py b/src/pynxtools/nomad/schema.py index 61174f38d..81846327c 100644 --- a/src/pynxtools/nomad/schema.py +++ b/src/pynxtools/nomad/schema.py @@ -47,6 +47,7 @@ InstrumentReference, Measurement, ) + from nomad.datamodel.metainfo.workflow import Task from nomad.metainfo import ( Attribute, Bytes, @@ -105,8 +106,8 @@ "NXsample": [CompositeSystem], "NXsample_component": [Component], "NXidentifier": [EntityReference], - "NXentry": [ActivityStep], - "NXprocess": [ActivityStep], + "NXentry": [ActivityStep, Task], + "NXprocess": [ActivityStep, Task], "NXdata": [ActivityResult], # "object": BaseSection, } @@ -970,6 +971,11 @@ def normalize_entry(self, archive, logger): super(current_cls, self).normalize(archive, logger) +def to_task_itself(self): + """takes advantage if an object itself is also a Task""" + return self + + def normalize_process(self, archive, logger): """Normalizer for Process section.""" current_cls = __section_definitions[__rename_nx_for_nomad("NXprocess")].section_cls @@ -1039,8 +1045,14 @@ def get_entry_reference(archive, f_name): __rename_nx_for_nomad("NXsample"): normalize_sample, __rename_nx_for_nomad("NXsample_component"): normalize_sample_component, __rename_nx_for_nomad("NXidentifier"): normalize_identifier, - __rename_nx_for_nomad("NXentry"): normalize_entry, - __rename_nx_for_nomad("NXprocess"): normalize_process, + __rename_nx_for_nomad("NXentry"): { + "normalize": normalize_entry, + "to_task": to_task_itself, + }, + __rename_nx_for_nomad("NXprocess"): { + "normalize": normalize_process, + "to_task": to_task_itself, + }, __rename_nx_for_nomad("NXdata"): normalize_data, } @@ -1053,4 +1065,8 @@ def get_entry_reference(archive, f_name): # Append the normalize method from a function if normalize_func: - section.section_cls.normalize = normalize_func + if isinstance(normalize_func, dict): + for key, value in normalize_func.items(): + setattr(section.section_cls, key, value) + else: + section.section_cls.normalize = normalize_func From 9f0b992d9056cb3dc8bc6de007875616d1894828 Mon Sep 17 00:00:00 2001 From: sanbrock Date: Wed, 18 Dec 2024 13:37:54 +0100 Subject: [PATCH 2/4] moving changes to NeXusMeasurement which is not anymore using normalisation from Measurement and Activity --- src/pynxtools/nomad/schema.py | 56 +++++++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 9 deletions(-) diff --git a/src/pynxtools/nomad/schema.py b/src/pynxtools/nomad/schema.py index 81846327c..81bc40f8b 100644 --- a/src/pynxtools/nomad/schema.py +++ b/src/pynxtools/nomad/schema.py @@ -106,8 +106,8 @@ "NXsample": [CompositeSystem], "NXsample_component": [Component], "NXidentifier": [EntityReference], - "NXentry": [ActivityStep, Task], - "NXprocess": [ActivityStep, Task], + "NXentry": [ActivityStep], # , Task], + "NXprocess": [ActivityStep], # , Task], "NXdata": [ActivityResult], # "object": BaseSection, } @@ -140,7 +140,44 @@ def normalize(self, archive, logger): self.method = self.m_def.name + " Experiment" except (AttributeError, TypeError): pass - super(NexusMeasurement, self).normalize(archive, logger) + super(Activity, self).normalize(archive, logger) + + if archive.results.eln.methods is None: + archive.results.eln.methods = [] + if self.method: + archive.results.eln.methods.append(self.method) + else: + archive.results.eln.methods.append(self.m_def.name) + if archive.workflow2 is None: + archive.workflow2 = Workflow(name=self.name) + # steps to tasks + act_array = archive.workflow2.tasks + existing_items = {(task.name, task.section) for task in act_array} + new_items = [ + item.to_task() + for item in self.steps + if (item.name, item) not in existing_items + ] + act_array.extend(new_items) + # samples to inputs + act_array = archive.workflow2.inputs + existing_items = {(link.name, link.section) for link in act_array} + new_items = [ + Link(name=item.name, section=item.reference) + for item in self.samples + if (item.name, item.reference) not in existing_items + ] + act_array.extend(new_items) + + # results to outputs + act_array = archive.workflow2.outputs + existing_items = {(link.name, link.section) for link in act_array} + new_items = [ + Link(name=item.name, section=item) + for item in self.results + if (item.name, item) not in existing_items + ] + act_array.extend(new_items) VALIDATE = False @@ -971,9 +1008,10 @@ def normalize_entry(self, archive, logger): super(current_cls, self).normalize(archive, logger) -def to_task_itself(self): - """takes advantage if an object itself is also a Task""" - return self +# def to_task_itself(self): +# """takes advantage if an object itself is also a Task""" +# self.section=self +# return self def normalize_process(self, archive, logger): @@ -1004,7 +1042,7 @@ def create_Entity(lab_id, archive, f_name): data=entitySec, m_context=archive.m_context, metadata=EntryMetadata( - entry_type="identifier", domain="nexus" + entry_type="identifier", domain="nexus", readonly=True ), # upload_id=archive.m_context.upload_id, ) with archive.m_context.raw_file(f_name, "w") as f_obj: @@ -1047,11 +1085,11 @@ def get_entry_reference(archive, f_name): __rename_nx_for_nomad("NXidentifier"): normalize_identifier, __rename_nx_for_nomad("NXentry"): { "normalize": normalize_entry, - "to_task": to_task_itself, + # "to_task": to_task_itself, }, __rename_nx_for_nomad("NXprocess"): { "normalize": normalize_process, - "to_task": to_task_itself, + # "to_task": to_task_itself, }, __rename_nx_for_nomad("NXdata"): normalize_data, } From a70fa1ef3b3b98aa32473a33ef78e0dfcb95cb35 Mon Sep 17 00:00:00 2001 From: sanbrock Date: Thu, 19 Dec 2024 11:18:16 +0100 Subject: [PATCH 3/4] fix for the new normalisation function --- src/pynxtools/nomad/schema.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pynxtools/nomad/schema.py b/src/pynxtools/nomad/schema.py index 81bc40f8b..6c9761937 100644 --- a/src/pynxtools/nomad/schema.py +++ b/src/pynxtools/nomad/schema.py @@ -47,7 +47,7 @@ InstrumentReference, Measurement, ) - from nomad.datamodel.metainfo.workflow import Task + from nomad.datamodel.metainfo.workflow import Link, Task, Workflow from nomad.metainfo import ( Attribute, Bytes, @@ -140,7 +140,7 @@ def normalize(self, archive, logger): self.method = self.m_def.name + " Experiment" except (AttributeError, TypeError): pass - super(Activity, self).normalize(archive, logger) + super(basesections.Activity, self).normalize(archive, logger) if archive.results.eln.methods is None: archive.results.eln.methods = [] From d2cc0e9c23325017f6a5e9aa86c7f7b2cb4ca732 Mon Sep 17 00:00:00 2001 From: sanbrock Date: Thu, 19 Dec 2024 11:41:49 +0100 Subject: [PATCH 4/4] nicer name layout --- src/pynxtools/nomad/schema.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pynxtools/nomad/schema.py b/src/pynxtools/nomad/schema.py index 6c9761937..96e2a78a3 100644 --- a/src/pynxtools/nomad/schema.py +++ b/src/pynxtools/nomad/schema.py @@ -990,7 +990,7 @@ def normalize_sample(self, archive, logger): """Normalizer for sample section.""" current_cls = __section_definitions[__rename_nx_for_nomad("NXsample")].section_cls self.name = self.__dict__["nx_name"] + ( - "(" + self.name__field + ")" if self.name__field else "" + " (" + self.name__field + ")" if self.name__field else "" ) # one could also copy local ids to identifier for search purposes super(current_cls, self).normalize(archive, logger) @@ -1002,7 +1002,7 @@ def normalize_entry(self, archive, logger): if self.start_time__field: self.start_time = self.start_time__field self.name = self.__dict__["nx_name"] + ( - "(" + self.title__field + ")" if self.title__field is not None else "" + " (" + self.title__field + ")" if self.title__field is not None else "" ) # one could also copy local ids to identifier for search purposes super(current_cls, self).normalize(archive, logger)