diff --git a/docs/schema/coremeta4cat.yaml b/docs/schema/coremeta4cat.yaml index 3f6072e5c..423f40983 100644 --- a/docs/schema/coremeta4cat.yaml +++ b/docs/schema/coremeta4cat.yaml @@ -715,9 +715,10 @@ slots: mappings: - VOC4CAT:0000187 slot_uri: VOC4CAT:0000187 - owner: ThermalSynthesisMixin + owner: Characterization domain_of: - ThermalSynthesisMixin + - Characterization range: string multivalued: true flow_rate: @@ -3716,6 +3717,27 @@ slots: domain_of: - FluidizedBedReactor range: string + product_identification_method: + name: product_identification_method + definition_uri: https://w3id.org/nfdi4cat/coremeta4cat/product_identification_method + description: 'The analytical method used to identify and/or quantify reaction + products. + + Should reference a CharacterizationTechnique instance (e.g. GCMS, HPLC_MS). + + The abstract stub ProductIdentificationMethod is retained for backward compatibility.' + from_schema: https://w3id.org/nfdi4cat/coremeta4cat/reaction/ + mappings: + - coremeta4cat:product_identification_method + slot_uri: coremeta4cat:product_identification_method + owner: Reaction + domain_of: + - Reaction + range: ProductIdentificationMethod + required: true + multivalued: true + inlined: true + inlined_as_list: true software_package: name: software_package definition_uri: https://w3id.org/nfdi4cat/coremeta4cat/software_package @@ -6975,23 +6997,6 @@ slots: binds_value_of: id description: Restricts the allowable defined terms to the QUDT Unit vocabulary. recommended: true - product_identification_method: - name: product_identification_method - description: 'The analytical method used to identify and/or quantify reaction - products. - - Should reference a CharacterizationTechnique instance (e.g. a GCMS or - - HPLC_MS object from coremeta4cat_characterization_ap). The abstract stub - - ProductIdentificationMethod is retained for backward compatibility.' - from_schema: https://w3id.org/nfdi4cat/coremeta4cat - slot_uri: coremeta4cat:product_identification_method - range: ProductIdentificationMethod - required: true - multivalued: true - inlined: true - inlined_as_list: true CatalysisDataset_rdf_type: name: CatalysisDataset_rdf_type definition_uri: https://w3id.org/nfdi-de/dcat-ap-plus/rdf_type @@ -7442,6 +7447,7 @@ slots: inlined_as_list: true Reaction_product_identification_method: name: Reaction_product_identification_method + definition_uri: https://w3id.org/nfdi4cat/coremeta4cat/product_identification_method description: 'The analytical method used to identify and/or quantify reaction products. @@ -7450,7 +7456,9 @@ slots: HPLC_MS object from coremeta4cat_characterization_ap). The abstract stub ProductIdentificationMethod is retained for backward compatibility.' - from_schema: https://w3id.org/nfdi4cat/coremeta4cat + from_schema: https://w3id.org/nfdi4cat/coremeta4cat/reaction/ + mappings: + - coremeta4cat:product_identification_method is_a: product_identification_method domain: Reaction slot_uri: coremeta4cat:product_identification_method @@ -7511,7 +7519,6 @@ slots: usage_slot_name: realized_plan range: SimulationMethod required: true - multivalued: true inlined: true inlined_as_list: true Simulation_carried_out_by: @@ -12192,12 +12199,12 @@ classes: - ClassifierMixin_type - evaluated_activity - occurred_in + - Characterization_equipment - sample_state - sample_description - sample_preparation - sample_pretreatment - detector_type - - Characterization_equipment - Characterization_evaluated_entity - Characterization_realized_plan - Characterization_rdf_type @@ -12935,10 +12942,10 @@ classes: - experiment_pressure - feed_composition_range - experiment_duration + - Reaction_product_identification_method - Reaction_rdf_type - Reaction_carried_out_by - Reaction_had_input_entity - - Reaction_product_identification_method slot_usage: rdf_type: name: rdf_type @@ -12972,12 +12979,9 @@ classes: HPLC_MS object from coremeta4cat_characterization_ap). The abstract stub ProductIdentificationMethod is retained for backward compatibility.' - from_schema: https://w3id.org/nfdi4cat/coremeta4cat - slot_uri: coremeta4cat:product_identification_method range: ProductIdentificationMethod required: true multivalued: true - inlined: true inlined_as_list: true class_uri: SIO:010345 ProductIdentificationMethod: @@ -13001,7 +13005,6 @@ classes: mappings: - OBI:0000272 is_a: Plan - abstract: true slots: - title - description @@ -13300,8 +13303,6 @@ classes: description: The SimulationMethod (protocol) realized in this Simulation. range: SimulationMethod required: true - multivalued: true - inlined_as_list: true carried_out_by: name: carried_out_by description: The simulation software used, provided as a Software agent instance. @@ -17078,5 +17079,5 @@ metamodel_version: 1.7.0 source_file: coremeta4cat.yaml source_file_date: '2026-03-09T16:14:14' source_file_size: 6730 -generation_date: '2026-03-09T17:32:19' +generation_date: '2026-03-10T08:36:44' diff --git a/src/coremeta4cat/datamodel/coremeta4cat.py b/src/coremeta4cat/datamodel/coremeta4cat.py index 6d12f2006..727f2acf7 100644 --- a/src/coremeta4cat/datamodel/coremeta4cat.py +++ b/src/coremeta4cat/datamodel/coremeta4cat.py @@ -1,5 +1,5 @@ # Auto generated from coremeta4cat.yaml by pythongen.py version: 0.0.1 -# Generation date: 2026-03-09T17:19:45 +# Generation date: 2026-03-10T09:36:20 # Schema: coremeta4cat-metadata # # id: https://w3id.org/nfdi4cat/coremeta4cat @@ -1572,7 +1572,7 @@ class Simulation(DataGeneratingActivity): id: Union[str, SimulationId] = None software_package: Union[str, list[str]] = None calculated_property: Union[Union[dict, "CalculatedProperty"], list[Union[dict, "CalculatedProperty"]]] = None - realized_plan: Union[Union[dict, "SimulationMethod"], list[Union[dict, "SimulationMethod"]]] = None + realized_plan: Union[dict, "SimulationMethod"] = None rdf_type: Optional[Union[dict, "DefinedTerm"]] = None carried_out_by: Optional[Union[dict[Union[str, AgenticEntityId], Union[dict, AgenticEntity]], list[Union[dict, AgenticEntity]]]] = empty_dict() evaluated_entity: Optional[Union[dict[Union[str, EvaluatedEntityId], Union[dict, "EvaluatedEntity"]], list[Union[dict, "EvaluatedEntity"]]]] = empty_dict() @@ -1597,9 +1597,8 @@ def __post_init__(self, *_: str, **kwargs: Any): if self._is_empty(self.realized_plan): self.MissingRequiredField("realized_plan") - if not isinstance(self.realized_plan, list): - self.realized_plan = [self.realized_plan] if self.realized_plan is not None else [] - self.realized_plan = [v if isinstance(v, SimulationMethod) else SimulationMethod(**as_dict(v)) for v in self.realized_plan] + if not isinstance(self.realized_plan, SimulationMethod): + self.realized_plan = SimulationMethod(**as_dict(self.realized_plan)) if self.rdf_type is not None and not isinstance(self.rdf_type, DefinedTerm): self.rdf_type = DefinedTerm(**as_dict(self.rdf_type)) @@ -2579,8 +2578,8 @@ class Reaction(EvaluatedActivity): id: Union[str, ReactionId] = None catalyst_quantity: Union[float, list[float]] = None reactant: Union[str, list[str]] = None - carried_out_by: Union[dict[Union[str, ReactorDesignTypeId], Union[dict, ReactorDesignType]], list[Union[dict, ReactorDesignType]]] = empty_dict() product_identification_method: Union[Union[dict, "ProductIdentificationMethod"], list[Union[dict, "ProductIdentificationMethod"]]] = None + carried_out_by: Union[dict[Union[str, ReactorDesignTypeId], Union[dict, ReactorDesignType]], list[Union[dict, ReactorDesignType]]] = empty_dict() catalyst_type: Optional[Union[str, list[str]]] = empty_list() reactor_temperature_range: Optional[Union[str, list[str]]] = empty_list() atmosphere: Optional[Union[str, list[str]]] = empty_list() @@ -2608,16 +2607,16 @@ def __post_init__(self, *_: str, **kwargs: Any): self.reactant = [self.reactant] if self.reactant is not None else [] self.reactant = [v if isinstance(v, str) else str(v) for v in self.reactant] - if self._is_empty(self.carried_out_by): - self.MissingRequiredField("carried_out_by") - self._normalize_inlined_as_list(slot_name="carried_out_by", slot_type=ReactorDesignType, key_name="id", keyed=True) - if self._is_empty(self.product_identification_method): self.MissingRequiredField("product_identification_method") if not isinstance(self.product_identification_method, list): self.product_identification_method = [self.product_identification_method] if self.product_identification_method is not None else [] self.product_identification_method = [v if isinstance(v, ProductIdentificationMethod) else ProductIdentificationMethod(**as_dict(v)) for v in self.product_identification_method] + if self._is_empty(self.carried_out_by): + self.MissingRequiredField("carried_out_by") + self._normalize_inlined_as_list(slot_name="carried_out_by", slot_type=ReactorDesignType, key_name="id", keyed=True) + if not isinstance(self.catalyst_type, list): self.catalyst_type = [self.catalyst_type] if self.catalyst_type is not None else [] self.catalyst_type = [v if isinstance(v, str) else str(v) for v in self.catalyst_type] @@ -9221,6 +9220,9 @@ class slots: slots.bubble_size_distribution = Slot(uri=COREMETA4CAT.bubble_size_distribution, name="bubble_size_distribution", curie=COREMETA4CAT.curie('bubble_size_distribution'), model_uri=COREMETA4CAT.bubble_size_distribution, domain=None, range=Optional[str]) +slots.product_identification_method = Slot(uri=COREMETA4CAT.product_identification_method, name="product_identification_method", curie=COREMETA4CAT.curie('product_identification_method'), + model_uri=COREMETA4CAT.product_identification_method, domain=None, range=Union[Union[dict, ProductIdentificationMethod], list[Union[dict, ProductIdentificationMethod]]]) + slots.software_package = Slot(uri=COREMETA4CAT.software_package, name="software_package", curie=COREMETA4CAT.curie('software_package'), model_uri=COREMETA4CAT.software_package, domain=None, range=Union[str, list[str]]) @@ -9854,9 +9856,6 @@ class slots: slots.quantitativeAttribute__unit = Slot(uri=QUDT.unit, name="quantitativeAttribute__unit", curie=QUDT.curie('unit'), model_uri=COREMETA4CAT.quantitativeAttribute__unit, domain=None, range=Optional[Union[str, DefinedTermId]]) -slots.product_identification_method = Slot(uri=COREMETA4CAT.product_identification_method, name="product_identification_method", curie=COREMETA4CAT.curie('product_identification_method'), - model_uri=COREMETA4CAT.product_identification_method, domain=None, range=Union[Union[dict, ProductIdentificationMethod], list[Union[dict, ProductIdentificationMethod]]]) - slots.CatalysisDataset_rdf_type = Slot(uri=RDF.type, name="CatalysisDataset_rdf_type", curie=RDF.curie('type'), model_uri=COREMETA4CAT.CatalysisDataset_rdf_type, domain=CatalysisDataset, range=Optional[Union[dict, "DefinedTerm"]]) @@ -9921,7 +9920,7 @@ class slots: model_uri=COREMETA4CAT.Simulation_rdf_type, domain=Simulation, range=Optional[Union[dict, "DefinedTerm"]]) slots.Simulation_realized_plan = Slot(uri=PROV.used, name="Simulation_realized_plan", curie=PROV.curie('used'), - model_uri=COREMETA4CAT.Simulation_realized_plan, domain=Simulation, range=Union[Union[dict, "SimulationMethod"], list[Union[dict, "SimulationMethod"]]]) + model_uri=COREMETA4CAT.Simulation_realized_plan, domain=Simulation, range=Union[dict, "SimulationMethod"]) slots.Simulation_carried_out_by = Slot(uri=PROV.wasAssociatedWith, name="Simulation_carried_out_by", curie=PROV.curie('wasAssociatedWith'), model_uri=COREMETA4CAT.Simulation_carried_out_by, domain=Simulation, range=Optional[Union[dict[Union[str, AgenticEntityId], Union[dict, AgenticEntity]], list[Union[dict, AgenticEntity]]]]) diff --git a/src/coremeta4cat/datamodel/coremeta4cat_pydantic.py b/src/coremeta4cat/datamodel/coremeta4cat_pydantic.py index 7e2f9d091..acc5b0213 100644 --- a/src/coremeta4cat/datamodel/coremeta4cat_pydantic.py +++ b/src/coremeta4cat/datamodel/coremeta4cat_pydantic.py @@ -518,7 +518,8 @@ class ThermalSynthesisMixin(ConfiguredBaseModel): synthesis_duration: Optional[list[float]] = Field(default=[], description="""Total duration of the synthesis step.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin'], 'slot_uri': 'VOC4CAT:0000050', 'unit': {'ucum_code': 'h'}} }) - equipment: Optional[list[str]] = Field(default=[], description="""Equipment or instrument used in a process.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin'], 'slot_uri': 'VOC4CAT:0000187'} }) + equipment: Optional[list[str]] = Field(default=[], description="""Equipment or instrument used in a process.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin', 'Characterization'], + 'slot_uri': 'VOC4CAT:0000187'} }) vessel_type: Optional[list[str]] = Field(default=[], description="""Type of reaction or synthesis vessel used.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin'], 'slot_uri': 'coremeta4cat:vessel_type'} }) atmosphere: Optional[list[str]] = Field(default=[], description="""Gaseous environment or atmospheric conditions during a process.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin', 'MolecularSynthesis', @@ -2045,6 +2046,8 @@ class Characterization(DataGeneratingActivity): 'range': 'CharacterizationTechnique', 'required': True}}}) + equipment: list[str] = Field(default=..., description="""Instrument or equipment used for characterization.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin', 'Characterization'], + 'slot_uri': 'VOC4CAT:0000187'} }) sample_state: Optional[list[SampleStateEnum]] = Field(default=[], description="""Physical state of the sample during characterization.""", json_schema_extra = { "linkml_meta": {'domain_of': ['Characterization'], 'slot_uri': 'coremeta4cat:sample_state'} }) sample_description: Optional[list[str]] = Field(default=[], description="""Free-text description of the sample used in this characterization.""", json_schema_extra = { "linkml_meta": {'domain_of': ['Characterization'], 'slot_uri': 'coremeta4cat:sample_description'} }) @@ -5514,6 +5517,11 @@ class Reaction(EvaluatedActivity): experiment_duration: Optional[list[float]] = Field(default=[], description="""Total duration of the experiment or measurement run.""", json_schema_extra = { "linkml_meta": {'domain_of': ['PowderXRD', 'Reaction'], 'slot_uri': 'AFR:0002455', 'unit': {'ucum_code': 'h'}} }) + product_identification_method: list[ProductIdentificationMethod] = Field(default=..., description="""The analytical method used to identify and/or quantify reaction products. +Should reference a CharacterizationTechnique instance (e.g. a GCMS or +HPLC_MS object from coremeta4cat_characterization_ap). The abstract stub +ProductIdentificationMethod is retained for backward compatibility.""", json_schema_extra = { "linkml_meta": {'domain_of': ['Reaction'], + 'slot_uri': 'coremeta4cat:product_identification_method'} }) id: str = Field(default=..., description="""A slot to provide an URI for an entity within this schema.""", json_schema_extra = { "linkml_meta": {'domain_of': ['Activity', 'AgenticEntity', 'Dataset', @@ -6566,7 +6574,8 @@ class Solvothermal(PreparationMethod, ThermalSynthesisMixin): synthesis_duration: Optional[list[float]] = Field(default=[], description="""Total duration of the synthesis step.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin'], 'slot_uri': 'VOC4CAT:0000050', 'unit': {'ucum_code': 'h'}} }) - equipment: Optional[list[str]] = Field(default=[], description="""Equipment or instrument used in a process.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin'], 'slot_uri': 'VOC4CAT:0000187'} }) + equipment: Optional[list[str]] = Field(default=[], description="""Equipment or instrument used in a process.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin', 'Characterization'], + 'slot_uri': 'VOC4CAT:0000187'} }) vessel_type: Optional[list[str]] = Field(default=[], description="""Type of reaction or synthesis vessel used.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin'], 'slot_uri': 'coremeta4cat:vessel_type'} }) atmosphere: Optional[list[str]] = Field(default=[], description="""Gaseous environment or atmospheric conditions during a process.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin', 'MolecularSynthesis', @@ -6688,7 +6697,8 @@ class PlasmaAssisted(PreparationMethod, ThermalSynthesisMixin): synthesis_duration: Optional[list[float]] = Field(default=[], description="""Total duration of the synthesis step.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin'], 'slot_uri': 'VOC4CAT:0000050', 'unit': {'ucum_code': 'h'}} }) - equipment: Optional[list[str]] = Field(default=[], description="""Equipment or instrument used in a process.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin'], 'slot_uri': 'VOC4CAT:0000187'} }) + equipment: Optional[list[str]] = Field(default=[], description="""Equipment or instrument used in a process.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin', 'Characterization'], + 'slot_uri': 'VOC4CAT:0000187'} }) vessel_type: Optional[list[str]] = Field(default=[], description="""Type of reaction or synthesis vessel used.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin'], 'slot_uri': 'coremeta4cat:vessel_type'} }) atmosphere: Optional[list[str]] = Field(default=[], description="""Gaseous environment or atmospheric conditions during a process.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin', 'MolecularSynthesis', @@ -6809,7 +6819,8 @@ class CombustionSynthesis(PreparationMethod, ThermalSynthesisMixin): synthesis_duration: Optional[list[float]] = Field(default=[], description="""Total duration of the synthesis step.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin'], 'slot_uri': 'VOC4CAT:0000050', 'unit': {'ucum_code': 'h'}} }) - equipment: Optional[list[str]] = Field(default=[], description="""Equipment or instrument used in a process.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin'], 'slot_uri': 'VOC4CAT:0000187'} }) + equipment: Optional[list[str]] = Field(default=[], description="""Equipment or instrument used in a process.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin', 'Characterization'], + 'slot_uri': 'VOC4CAT:0000187'} }) vessel_type: Optional[list[str]] = Field(default=[], description="""Type of reaction or synthesis vessel used.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin'], 'slot_uri': 'coremeta4cat:vessel_type'} }) atmosphere: Optional[list[str]] = Field(default=[], description="""Gaseous environment or atmospheric conditions during a process.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin', 'MolecularSynthesis', @@ -7193,7 +7204,8 @@ class MicrowaveAssisted(PreparationMethod, ThermalSynthesisMixin): synthesis_duration: Optional[list[float]] = Field(default=[], description="""Total duration of the synthesis step.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin'], 'slot_uri': 'VOC4CAT:0000050', 'unit': {'ucum_code': 'h'}} }) - equipment: Optional[list[str]] = Field(default=[], description="""Equipment or instrument used in a process.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin'], 'slot_uri': 'VOC4CAT:0000187'} }) + equipment: Optional[list[str]] = Field(default=[], description="""Equipment or instrument used in a process.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin', 'Characterization'], + 'slot_uri': 'VOC4CAT:0000187'} }) vessel_type: Optional[list[str]] = Field(default=[], description="""Type of reaction or synthesis vessel used.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin'], 'slot_uri': 'coremeta4cat:vessel_type'} }) atmosphere: Optional[list[str]] = Field(default=[], description="""Gaseous environment or atmospheric conditions during a process.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin', 'MolecularSynthesis', @@ -7580,7 +7592,8 @@ class MechanochemicalSynthesis(PreparationMethod, ThermalSynthesisMixin): synthesis_duration: Optional[list[float]] = Field(default=[], description="""Total duration of the synthesis step.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin'], 'slot_uri': 'VOC4CAT:0000050', 'unit': {'ucum_code': 'h'}} }) - equipment: Optional[list[str]] = Field(default=[], description="""Equipment or instrument used in a process.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin'], 'slot_uri': 'VOC4CAT:0000187'} }) + equipment: Optional[list[str]] = Field(default=[], description="""Equipment or instrument used in a process.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin', 'Characterization'], + 'slot_uri': 'VOC4CAT:0000187'} }) vessel_type: Optional[list[str]] = Field(default=[], description="""Type of reaction or synthesis vessel used.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin'], 'slot_uri': 'coremeta4cat:vessel_type'} }) atmosphere: Optional[list[str]] = Field(default=[], description="""Gaseous environment or atmospheric conditions during a process.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin', 'MolecularSynthesis', @@ -7695,7 +7708,8 @@ class Sublimation(PreparationMethod, ThermalSynthesisMixin): synthesis_duration: Optional[list[float]] = Field(default=[], description="""Total duration of the synthesis step.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin'], 'slot_uri': 'VOC4CAT:0000050', 'unit': {'ucum_code': 'h'}} }) - equipment: Optional[list[str]] = Field(default=[], description="""Equipment or instrument used in a process.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin'], 'slot_uri': 'VOC4CAT:0000187'} }) + equipment: Optional[list[str]] = Field(default=[], description="""Equipment or instrument used in a process.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin', 'Characterization'], + 'slot_uri': 'VOC4CAT:0000187'} }) vessel_type: Optional[list[str]] = Field(default=[], description="""Type of reaction or synthesis vessel used.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin'], 'slot_uri': 'coremeta4cat:vessel_type'} }) atmosphere: Optional[list[str]] = Field(default=[], description="""Gaseous environment or atmospheric conditions during a process.""", json_schema_extra = { "linkml_meta": {'domain_of': ['ThermalSynthesisMixin', 'MolecularSynthesis', @@ -11485,8 +11499,7 @@ class ProductIdentificationMethod(Plan): CoreMeta4Cat monolith. It is a subclass of Plan (prov:Plan / OBI:0000272) so that it can participate in the realized_plan slot if needed. """ - linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({'abstract': True, - 'class_uri': 'OBI:0000272', + linkml_meta: ClassVar[LinkMLMeta] = LinkMLMeta({'class_uri': 'OBI:0000272', 'from_schema': 'https://w3id.org/nfdi4cat/coremeta4cat/reaction/'}) title: Optional[str] = Field(default=None, description="""This slot is described in more detail within the class in which it is used.""", json_schema_extra = { "linkml_meta": {'domain_of': ['Activity', @@ -18918,8 +18931,6 @@ class Simulation(DataGeneratingActivity): 'realized_plan': {'description': 'The SimulationMethod ' '(protocol) realized in this ' 'Simulation.', - 'inlined_as_list': True, - 'multivalued': True, 'name': 'realized_plan', 'range': 'SimulationMethod', 'required': True}}}) @@ -18938,7 +18949,7 @@ class Simulation(DataGeneratingActivity): 'is_a': 'had_input_activity', 'recommended': True, 'slot_uri': 'prov:wasInformedBy'} }) - realized_plan: list[SimulationMethod] = Field(default=..., description="""The SimulationMethod (protocol) realized in this Simulation.""", json_schema_extra = { "linkml_meta": {'domain_of': ['DataGeneratingActivity'], + realized_plan: SimulationMethod = Field(default=..., description="""The SimulationMethod (protocol) realized in this Simulation.""", json_schema_extra = { "linkml_meta": {'domain_of': ['DataGeneratingActivity'], 'in_subset': ['domain_agnostic_core'], 'slot_uri': 'prov:used'} }) occurred_in: Optional[Surrounding] = Field(default=None, description="""The slot to specify the Surrounding in which an Activity took place.""", json_schema_extra = { "linkml_meta": {'domain_of': ['DataGeneratingActivity'], diff --git a/src/coremeta4cat/schema/coremeta4cat_characterization_ap.yaml b/src/coremeta4cat/schema/coremeta4cat_characterization_ap.yaml index 3c88f2586..e6a6f61f7 100644 --- a/src/coremeta4cat/schema/coremeta4cat_characterization_ap.yaml +++ b/src/coremeta4cat/schema/coremeta4cat_characterization_ap.yaml @@ -165,6 +165,7 @@ classes: following DCAT-AP-PLUS Pattern 3 — exactly as NMRSpectroscopy uses rdf_type: CHMO:0000613. slots: + - equipment - sample_state - sample_description - sample_preparation diff --git a/src/coremeta4cat/schema/coremeta4cat_reaction_ap.yaml b/src/coremeta4cat/schema/coremeta4cat_reaction_ap.yaml index c5f7e3fba..27b008c02 100644 --- a/src/coremeta4cat/schema/coremeta4cat_reaction_ap.yaml +++ b/src/coremeta4cat/schema/coremeta4cat_reaction_ap.yaml @@ -92,6 +92,7 @@ classes: - experiment_pressure - feed_composition_range - experiment_duration + - product_identification_method slot_usage: rdf_type: description: |- @@ -129,7 +130,6 @@ classes: ProductIdentificationMethod: is_a: Plan class_uri: OBI:0000272 - abstract: true description: |- Abstract Plan representing the method used to identify and quantify reaction products. In practice, users should reference a concrete CharacterizationTechnique @@ -297,3 +297,14 @@ slots: description: Description or characterization of bubble size distribution in the fluidized bed. range: string slot_uri: coremeta4cat:bubble_size_distribution + + product_identification_method: + description: |- + The analytical method used to identify and/or quantify reaction products. + Should reference a CharacterizationTechnique instance (e.g. GCMS, HPLC_MS). + The abstract stub ProductIdentificationMethod is retained for backward compatibility. + range: ProductIdentificationMethod + slot_uri: coremeta4cat:product_identification_method + required: true + multivalued: true + inlined_as_list: true diff --git a/src/coremeta4cat/schema/coremeta4cat_simulation_ap.yaml b/src/coremeta4cat/schema/coremeta4cat_simulation_ap.yaml index fda0b7655..47df02417 100644 --- a/src/coremeta4cat/schema/coremeta4cat_simulation_ap.yaml +++ b/src/coremeta4cat/schema/coremeta4cat_simulation_ap.yaml @@ -116,8 +116,6 @@ classes: The SimulationMethod (protocol) realized in this Simulation. range: SimulationMethod required: true - multivalued: true - inlined_as_list: true carried_out_by: description: |- The simulation software used, provided as a Software agent instance. diff --git a/tests/data/valid/CatalysisDataset-001.yaml b/tests/data/valid/CatalysisDataset-001.yaml new file mode 100644 index 000000000..e3eab3c34 --- /dev/null +++ b/tests/data/valid/CatalysisDataset-001.yaml @@ -0,0 +1,37 @@ +--- +# CatalysisDataset-001 -- Methanol synthesis over Cu/ZnO/Al2O3 +# Target class: CatalysisDataset +# +# This dataset covers Synthesis + Characterization + Reaction subprofiles. +# +# Naming note: user-preferred CatalysisDataset_Reac_Syn-001.yaml is incompatible +# with test_data.py (stem.split("-")[0] gives invalid class name). +# Using CatalysisDataset-001.yaml for test compatibility. +# See SCHEMA_REVIEW.md: "File naming convention". +# +# JSON schema notes: +# - title and description on CatalysisDataset must be arrays (DCAT multivalued). +# - DataGeneratingActivity.title in JSON schema is also an array (or null). +# - was_generated_by items must include at least title:[] to avoid a linkml_runtime +# loader bug where single-field JsonObj args cause DataGeneratingActivityId +# to receive a JsonObj instead of a string. + +id: "coremeta4cat:DS_001_MeOH_synthesis_CuZnO" +title: + - "Methanol synthesis over Cu/ZnO/Al2O3: synthesis and catalytic performance dataset" +description: + - "Dataset covering preparation of Cu/ZnO/Al2O3 methanol synthesis catalyst by incipient wetness impregnation and catalytic performance in CO2 hydrogenation at 50 bar, 200-300 deg C." +was_generated_by: + - id: "coremeta4cat:SYNTH_001_Pt_Al2O3" + title: + - "incipient wetness impregnation of Cu/ZnO/Al2O3" + - id: "coremeta4cat:CHAR_001_BET_CuZnO_Al2O3" + title: + - "BET surface area measurement of Cu/ZnO/Al2O3" + - id: "coremeta4cat:CHAR_002_XRD_CuZnO_Al2O3" + title: + - "Powder XRD measurement of Cu/ZnO/Al2O3" +is_about_entity: + - id: "coremeta4cat:CAT_001_CuZnO_Al2O3" + title: "Cu/ZnO/Al2O3 methanol synthesis catalyst" + description: "63 wt% CuO, 24 wt% ZnO, 13 wt% Al2O3 (calcined precursor)" diff --git a/tests/data/valid/CatalysisDataset-002.yaml b/tests/data/valid/CatalysisDataset-002.yaml new file mode 100644 index 000000000..1913ba9d6 --- /dev/null +++ b/tests/data/valid/CatalysisDataset-002.yaml @@ -0,0 +1,41 @@ +--- +# CatalysisDataset-002 -- NiO/CeO2 dry methane reforming catalyst study +# Target class: CatalysisDataset +# +# Comprehensive dataset linking synthesis, characterization, reaction, and simulation +# activities for the NiO/CeO2 DRM catalyst system (files -002 series). +# +# JSON schema notes (same as CatalysisDataset-001): +# - title and description must be arrays (DCAT multivalued). +# - was_generated_by items must include at least title:[] to avoid linkml_runtime +# JsonObj loader bug (single-field objects passed as positional arg). +# - is_about_entity items inlined with title and description. + +id: "coremeta4cat:DS_002_DRM_NiO_CeO2" +title: + - "NiO/CeO2 dry methane reforming catalyst: co-precipitation synthesis, multi-technique characterization, catalytic performance, and computational interface study" +description: + - "Dataset covering the full lifecycle of a 15 wt% NiO/CeO2 dry reforming catalyst: (1) co-precipitation synthesis with precipitation parameters and calcination protocol; (2) XPS surface composition and oxidation state analysis; (3) H2-TPR reducibility profiling; (4) catalytic performance in CH4+CO2 dry reforming at 600-800 deg C over 20 h; (5) ReaxFF molecular dynamics of the Ni/CeO2(111) interface at 800 deg C to rationalise metal-support interaction." +was_generated_by: + - id: "coremeta4cat:SYNTH_002_NiO_CeO2" + title: + - "co-precipitation synthesis of 15 wt% NiO/CeO2" + - id: "coremeta4cat:CHAR_003_XPS_NiO_CeO2" + title: + - "XPS surface analysis of NiO/CeO2 (Ni 2p, Ce 3d, O 1s)" + - id: "coremeta4cat:CHAR_004_TPR_NiO_CeO2" + title: + - "H2-TPR reducibility measurement of NiO/CeO2" + - id: "coremeta4cat:REAC_002_DRM_NiCeO2" + title: + - "dry methane reforming catalytic activity test (600-800 deg C, 20 h)" + - id: "coremeta4cat:SIM_002_MD_Ni_CeO2_111" + title: + - "ReaxFF MD simulation of Ni13 cluster on CeO2(111) at 800 deg C" +is_about_entity: + - id: "coremeta4cat:CAT_002_NiO_CeO2" + title: "NiO/CeO2 dry reforming catalyst" + description: "15 wt% NiO on CeO2 support, co-precipitated at pH 8.5, calcined 500 deg C / 4 h, active phase Ni0 formed by in situ reduction" + - id: "coremeta4cat:SLAB_002_CeO2_111_Ni13" + title: "Ni13/CeO2(111) computational model" + description: "13-atom cuboctahedral Ni cluster on 6-layer CeO2(111) p(4x4) periodic slab; ReaxFF MD model representing Ni/CeO2 metal-support interface" diff --git a/tests/data/valid/Characterization-001.yaml b/tests/data/valid/Characterization-001.yaml new file mode 100644 index 000000000..59d1ac446 --- /dev/null +++ b/tests/data/valid/Characterization-001.yaml @@ -0,0 +1,19 @@ +--- +# Characterization-001 -- BET surface area measurement of Cu/ZnO/Al2O3 catalyst +# Target class: Characterization +# +# NOTE: realized_plan range is CharacterizationTechnique (abstract). +# The generated Python loader instantiates the abstract CharacterizationTechnique; +# concrete BET subclass fields are silently ignored. +# Technique identity is expressed via title/description on realized_plan. + +id: "coremeta4cat:CHAR_001_BET_CuZnO_Al2O3" +equipment: + - "Micromeritics ASAP 2020 surface area and porosimetry analyzer" +evaluated_entity: + - id: "coremeta4cat:CAT_001_CuZnO_Al2O3" + title: "Cu/ZnO/Al2O3 methanol synthesis catalyst" + description: "63 wt% CuO, 24 wt% ZnO, 13 wt% Al2O3 (calcined precursor)" +realized_plan: + title: "BET surface area measurement" + description: "N2 physisorption at 77 K, degassing at 300 deg C for 3 h under vacuum prior to measurement" diff --git a/tests/data/valid/Characterization-002.yaml b/tests/data/valid/Characterization-002.yaml new file mode 100644 index 000000000..59874512c --- /dev/null +++ b/tests/data/valid/Characterization-002.yaml @@ -0,0 +1,19 @@ +--- +# Characterization-002 -- Powder XRD measurement of Cu/ZnO/Al2O3 catalyst +# Target class: Characterization +# +# NOTE: realized_plan range is CharacterizationTechnique (abstract). +# The generated Python loader instantiates the abstract CharacterizationTechnique; +# concrete PowderXRD subclass fields are silently ignored. +# Technique identity is expressed via title/description on realized_plan. + +id: "coremeta4cat:CHAR_002_XRD_CuZnO_Al2O3" +equipment: + - "Bruker D8 Advance diffractometer with Cu K-alpha radiation (1.5406 Ang)" +evaluated_entity: + - id: "coremeta4cat:CAT_001_CuZnO_Al2O3" + title: "Cu/ZnO/Al2O3 methanol synthesis catalyst" + description: "63 wt% CuO, 24 wt% ZnO, 13 wt% Al2O3 (calcined precursor)" +realized_plan: + title: "powder X-ray diffraction" + description: "Cu K-alpha, 2theta range 5 to 80 deg, step size 0.02 deg, scan rate 1 deg/min, Rietveld refinement for phase quantification" diff --git a/tests/data/valid/Characterization-003.yaml b/tests/data/valid/Characterization-003.yaml new file mode 100644 index 000000000..51a68748f --- /dev/null +++ b/tests/data/valid/Characterization-003.yaml @@ -0,0 +1,36 @@ +--- +# Characterization-003 -- XPS surface analysis of NiO/CeO2 catalyst +# Target class: Characterization +# +# Technique: XPS (XRaySourceMixin + EnergyRangeMixin + technique-specific slots). +# realized_plan range is CharacterizationTechnique (abstract) -- Python loader +# instantiates abstract class; XPS-specific parameters encoded in description. +# +# Demonstrates: +# - Full Characterization-level slots: sample_state, sample_description, +# sample_preparation, sample_pretreatment, detector_type +# - Multiple equipment items (instrument + X-ray source specification) +# - Rich realized_plan description encoding survey + HR scan parameters, +# pass energy, spot size, charge compensation, binding energy calibration + +id: "coremeta4cat:CHAR_003_XPS_NiO_CeO2" +equipment: + - "Thermo Scientific K-Alpha+ XPS spectrometer" + - "Al K-alpha monochromatic X-ray source (1486.6 eV, 72 W)" +sample_state: + - "powder" +sample_description: + - "NiO/CeO2 co-precipitated catalyst (SYNTH_002), calcined at 500 deg C, as-prepared (non-reduced), ca. 10 mg pressed into indium foil" +sample_preparation: + - "lightly pressed into indium foil to obtain flat surface; mounted on sample stub with copper tape; no Ar+ sputtering performed" +sample_pretreatment: + - "outgassed in XPS load-lock chamber at < 1e-7 mbar for 12 h before transfer to analysis chamber (< 5e-9 mbar)" +detector_type: + - "128-channel 2D delay-line detector (DLD)" +evaluated_entity: + - id: "coremeta4cat:CAT_002_NiO_CeO2" + title: "NiO/CeO2 dry reforming catalyst (calcined)" + description: "15 wt% NiO on CeO2 support, calcined at 500 deg C" +realized_plan: + title: "X-ray photoelectron spectroscopy (XPS)" + description: "monochromatic Al K-alpha (1486.6 eV); base pressure 5e-9 mbar; survey scan: 0-1350 eV, 1.0 eV step, 50 ms dwell, 3 scans, pass energy 200 eV; high-resolution regions: Ni 2p3/2 (845-895 eV), Ce 3d (875-935 eV), O 1s (525-540 eV), C 1s (280-295 eV); step size 0.1 eV, 20 scans each, pass energy 50 eV; spot size 400 um; lens mode: large area XL; charge compensation: dual-beam flood gun (1 eV electrons + 10 eV Ar+); binding energy scale calibrated to C 1s adventitious carbon at 284.8 eV; Shirley background subtraction; peak fitting: Voigt profiles (CasaXPS v2.3.25); atomic concentrations from Scofield sensitivity factors corrected for transmission function" diff --git a/tests/data/valid/Characterization-004.yaml b/tests/data/valid/Characterization-004.yaml new file mode 100644 index 000000000..2f2e81411 --- /dev/null +++ b/tests/data/valid/Characterization-004.yaml @@ -0,0 +1,30 @@ +--- +# Characterization-004 -- H2 temperature-programmed reduction (H2-TPR) of NiO/CeO2 +# Target class: Characterization +# +# Technique: TPR (TemperatureProgramMixin: minimum_temperature, maximum_temperature, +# heating_rate, heating_procedure slots in realized_plan description). +# realized_plan range is CharacterizationTechnique (abstract) -- TPR params in description. +# +# Demonstrates: +# - TPR characterization with full temperature programme description +# - sample_description, sample_pretreatment (oxidative pre-treatment before reduction) +# - detector_type (TCD) +# - Two evaluated_entity items (fresh catalyst + spent catalyst comparison) + +id: "coremeta4cat:CHAR_004_TPR_NiO_CeO2" +equipment: + - "Micromeritics AutoChem II 2920 chemisorption analyzer" +sample_description: + - "NiO/CeO2 calcined at 500 deg C; 50 mg packed in quartz U-tube reactor (4 mm ID); quartz wool plugs above and below bed" +sample_pretreatment: + - "oxidative pretreatment: 10 vol% O2/Ar (50 mL/min) at 300 deg C for 30 min; cool to 50 deg C under Ar purge" +detector_type: + - "thermal conductivity detector (TCD), Ar carrier gas reference channel" +evaluated_entity: + - id: "coremeta4cat:CAT_002_NiO_CeO2" + title: "NiO/CeO2 dry reforming catalyst (calcined)" + description: "15 wt% NiO on CeO2, calcined at 500 deg C / 4 h" +realized_plan: + title: "H2 temperature-programmed reduction (H2-TPR)" + description: "reducing gas: 5 vol% H2/Ar, total flow 50 mL/min (calibrated Brooks MFC); temperature programme: 50 deg C to 900 deg C at 10 deg C/min; isothermal hold: 30 min at 900 deg C; H2O trap: molecular sieve 3A between reactor outlet and TCD to prevent TCD signal interference; baseline: Ar flow for 30 min at 50 deg C before switching to H2/Ar; H2 consumption quantified by integration of TCD signal, calibrated against CuO reference standard (99.9%, 10 mg, single reduction peak at 310 deg C); NiO reduction: expected peaks at 280-350 deg C (NiO weakly interacting with CeO2) and 400-600 deg C (NiO strongly interacting); CeO2 surface reduction: 600-900 deg C" diff --git a/tests/data/valid/Reaction-001.yaml b/tests/data/valid/Reaction-001.yaml new file mode 100644 index 000000000..167bbedd9 --- /dev/null +++ b/tests/data/valid/Reaction-001.yaml @@ -0,0 +1,42 @@ +--- +# Reaction-001 -- CO2 hydrogenation to methanol over Cu/ZnO/Al2O3 in fixed-bed reactor +# Target class: Reaction +# +# SCHEMA ERROR (product_identification_method): The slot range is abstract +# ProductIdentificationMethod (a Plan stub with no concrete subclasses). +# The schema description says to reference a CharacterizationTechnique, but +# CharacterizationTechnique is NOT a subclass of ProductIdentificationMethod. +# As a workaround, title/description are provided on the abstract stub; +# the generated Python loader instantiates ProductIdentificationMethod directly. +# See SCHEMA_REVIEW.md for the proposed fix. +# +# NOTE (carried_out_by): keyed inline list; each item needs an id. +# The loader instantiates the abstract ReactorDesignType (not FixedBedReactor). + +id: "coremeta4cat:REAC_001_CO2_hydrogenation" +catalyst_quantity: + - 0.5 +reactant: + - "CO2 (99.998% purity, 20 vol% in H2)" + - "H2 (99.999% purity)" +catalyst_type: + - "heterogeneous, supported metal oxide" +reactor_temperature_range: + - "200-300 deg C" +experiment_pressure: + - 50.0 +atmosphere: + - "H2/CO2 = 3:1 (molar), GHSV = 10000 mL/(g*h)" +feed_composition_range: + - "H2/CO2 = 3:1, CO2 concentration 20 vol%" +carried_out_by: + - id: "coremeta4cat:REACT_001_FixedBed" + title: "stainless steel fixed-bed plug-flow reactor" + description: "10 mm inner diameter, 30 cm length, 0.5 g catalyst diluted with SiC" +had_input_entity: + - id: "coremeta4cat:FEED_001_CO2_H2" + title: "CO2/H2 feed gas mixture" + description: "H2/CO2 molar ratio 3:1, total flow 100 mL/min" +product_identification_method: + - title: "online gas chromatography" + description: "GC (Agilent 7890B) with TCD and FID detectors; columns: Molecular Sieve 5A and Poraplot Q; products: MeOH, CO, CH4, H2O quantified" diff --git a/tests/data/valid/Reaction-002.yaml b/tests/data/valid/Reaction-002.yaml new file mode 100644 index 000000000..6e8ed5061 --- /dev/null +++ b/tests/data/valid/Reaction-002.yaml @@ -0,0 +1,52 @@ +--- +# Reaction-002 -- Dry methane reforming (DRM) over Ni/CeO2 in fixed-bed reactor +# Target class: Reaction +# +# NOTE (carried_out_by): range is ReactorDesignType (abstract: true) -> dangling $ref. +# Loader instantiates abstract ReactorDesignType. Each item needs an id. +# NOTE (product_identification_method): same abstract stub limitation as Reaction-001. +# +# Demonstrates: +# - Two reactants (CH4 + CO2) with separate had_input_entity feed descriptions +# - experiment_duration (20 h stability test) +# - feed_composition_range (two entries: stoichiometric + CO2-rich conditions) +# - Detailed product_identification_method (online GC with two columns) +# - FixedBedReactor with detailed description (quartz tube, dilution, thermocouple) + +id: "coremeta4cat:REAC_002_DRM_NiCeO2" +catalyst_quantity: + - 0.2 +catalyst_type: + - "heterogeneous, supported metal (Ni0 after in situ reduction of NiO/CeO2)" +reactant: + - "CH4 (99.995% purity, Linde)" + - "CO2 (99.998% purity, Linde)" + - "N2 balance (99.999% purity, internal standard for GC quantification)" +reactor_temperature_range: + - "600-800 deg C" +experiment_pressure: + - 1.0 +atmosphere: + - "CH4/CO2/N2 = 45:45:10 vol%, total flow 100 mL/min (STP), GHSV = 30000 mL/(g*h)" +feed_composition_range: + - "stoichiometric DRM: CH4/CO2 = 1:1 (molar)" + - "CO2-rich condition: CH4/CO2 = 1:1.5 to suppress carbon deposition" +experiment_duration: + - 20.0 +carried_out_by: + - id: "coremeta4cat:REACT_003_FixedBed_DRM" + title: "quartz fixed-bed plug-flow reactor (DRM)" + description: "quartz tube reactor, 8 mm inner diameter, 30 cm length; catalyst bed: 200 mg NiO/CeO2 (250-500 um sieve fraction) diluted 1:2 (mass) with inert SiC chips (500 um); thermocouple inserted into catalyst bed centre; backpressure regulator at outlet (1 bar); reactor surrounded by ceramic-fibre furnace with PID temperature controller; mass flow controllers (Brooks SLA5850) for CH4, CO2, N2" +had_input_entity: + - id: "coremeta4cat:FEED_004_CH4_DRM" + title: "methane feed (99.995%, Linde)" + description: "CH4 flow: 45 mL/min (STP); calibrated Brooks SLA5850 MFC" + - id: "coremeta4cat:FEED_005_CO2_DRM" + title: "CO2 feed (99.998%, Linde)" + description: "CO2 flow: 45 mL/min (STP); calibrated Brooks SLA5850 MFC" + - id: "coremeta4cat:FEED_006_N2_standard" + title: "N2 internal standard (99.999%, Linde)" + description: "N2 flow: 10 mL/min (STP); used as internal standard for GC molar balance" +product_identification_method: + - title: "online dual-column gas chromatography (TCD)" + description: "Shimadzu GC-2014 with TCD detector (Ar carrier gas); column 1: HayeSep D (2 m x 1/8 in) for CO2, CH4 separation; column 2: Molecular Sieve 5A (2 m x 1/8 in) for CO, H2, N2, CH4 separation; 10-port Valco valve for column switching; oven temperature: 50 deg C isothermal; TCD temperature: 250 deg C; injection: automated gas sampling valve, 1 mL loop; analysis cycle: 10 min; calibration: certified gas standard (Air Liquide CRYSTAL mixture: H2 5%, CO 5%, CH4 5%, CO2 10%, N2 balance); CH4 conversion, CO2 conversion, H2/CO ratio, and carbon balance calculated from N2-normalised molar flows" diff --git a/tests/data/valid/Simulation-001.yaml b/tests/data/valid/Simulation-001.yaml new file mode 100644 index 000000000..f246e9d07 --- /dev/null +++ b/tests/data/valid/Simulation-001.yaml @@ -0,0 +1,33 @@ +--- +# Simulation-001 -- DFT calculation of CO adsorption on Cu(111) surface +# Target class: Simulation +# +# NOTE: realized_plan range is SimulationMethod (abstract). +# The generated Python loader always instantiates abstract SimulationMethod; +# concrete DFT subclass fields (exchange_correlation_functional, energy_cutoff, …) +# are silently ignored at load time. +# +# NOTE: calculated_property range is CalculatedProperty (abstract). +# Each item MUST include "value" (required by QualitativeAttribute base class). +# Concrete subclass fields are silently ignored at load time. +# +# Both realized_plan and calculated_property are lists (multivalued). + +id: "coremeta4cat:SIM_001_DFT_Cu111_CO_ads" +software_package: + - "VASP 6.3.0" + - "VESTA 3.5.8 (structure visualization)" +evaluated_entity: + - id: "coremeta4cat:SLAB_001_Cu111" + title: "Cu(111) surface slab model" + description: "4-layer Cu(111) p(3x3) slab, bottom 2 layers fixed, 15 Ang vacuum" +realized_plan: + title: "periodic plane-wave DFT" + description: "PBE functional, PAW pseudopotentials, 400 eV cutoff, 4x4x1 Monkhorst-Pack k-mesh, D3 dispersion correction, spin-unpolarized" +calculated_property: + - value: "-0.67 eV" + description: "CO adsorption energy on hollow fcc site of Cu(111) relative to gas-phase CO" + - value: "1.157 Ang" + description: "C-O bond length of adsorbed CO" + - value: "2.312 Ang" + description: "Cu-C bond length at hollow adsorption site" diff --git a/tests/data/valid/Simulation-002.yaml b/tests/data/valid/Simulation-002.yaml new file mode 100644 index 000000000..91af1ed4a --- /dev/null +++ b/tests/data/valid/Simulation-002.yaml @@ -0,0 +1,39 @@ +--- +# Simulation-002 -- ReaxFF molecular dynamics of Ni cluster on CeO2(111) surface +# Target class: Simulation +# +# NOTE: realized_plan range is SimulationMethod (abstract). +# Python loader always instantiates abstract SimulationMethod; MolecularDynamics +# subclass fields (force_field, simulation_timestep, ensemble_type, etc.) +# are silently ignored at load time. All MD parameters encoded in description. +# +# NOTE: calculated_property range is CalculatedProperty (abstract). +# Each item MUST include "value" (required by QualitativeAttribute base class). +# Concrete subclass fields are silently ignored at load time. +# +# Demonstrates: +# - MolecularDynamics SimulationMethod (contrast with DFT in Simulation-001) +# - Four calculated_property entries with diverse value types +# - Two software_package entries (LAMMPS + analysis tool) +# - Detailed evaluated_entity (periodic slab with adsorbed cluster) + +id: "coremeta4cat:SIM_002_MD_Ni_CeO2_111" +software_package: + - "LAMMPS (29 Sep 2021 stable release, OpenMP build)" + - "OVITO 3.7.11 (structure analysis, RDF, CNA, cluster tracking)" +evaluated_entity: + - id: "coremeta4cat:SLAB_002_CeO2_111_Ni13" + title: "CeO2(111) surface slab with supported 13-atom Ni cluster" + description: "6-layer CeO2(111) p(4x4) slab (256 CeO2 formula units, 768 atoms total); bottom 3 layers fixed during MD; 13-atom cuboctahedral Ni cluster adsorbed on three-fold hollow O site; 20 Ang vacuum layer; 3D periodic boundary conditions" +realized_plan: + title: "ReaxFF molecular dynamics (NVT, 800 deg C)" + description: "force field: ReaxFF C/H/Ni/O parametrisation (van Duin et al. 2012, DOI: 10.1021/jp210484t); ensemble: NVT with Nose-Hoover thermostat (tau = 100 fs) at 800 deg C (1073 K); integration timestep: 0.5 fs; total simulation time: 1 ns (2,000,000 steps); equilibration phase: 200 ps (400,000 steps) discarded; production phase: 800 ps (1,600,000 steps) used for analysis; sampling interval: every 1000 steps (0.5 ps); bond order cutoff: C-O 0.3, Ni-O 0.3 (fix reax/c/bonds); radial distribution functions computed with OVITO using 0.05 Ang bin width; common-neighbour analysis (CNA) to track Ni cluster crystallographic ordering" +calculated_property: + - value: "1.52 J/m2" + description: "CeO2(111) cleavage surface energy (clean slab without Ni cluster, computed from relaxed DFT-D3 reference at 0 K, used as force field validation benchmark)" + - value: "-1.83 eV/atom" + description: "time-averaged Ni-CeO2 adhesion energy per Ni atom (13-atom cluster) relative to bulk Ni cohesive energy and clean CeO2(111) slab; computed from 800 ps production trajectory" + - value: "3.8 Ang" + description: "first-shell Ni-O coordination distance at Ni cluster / CeO2 interface (peak of Ni-O radial distribution function, production trajectory average)" + - value: "0.42" + description: "fraction of Ni atoms in direct contact with CeO2 surface (Ni-O bond order > 0.3) averaged over production trajectory; measures cluster wetting / spreading" diff --git a/tests/data/valid/Synthesis-002.yaml b/tests/data/valid/Synthesis-002.yaml new file mode 100644 index 000000000..e049f0752 --- /dev/null +++ b/tests/data/valid/Synthesis-002.yaml @@ -0,0 +1,49 @@ +--- +# Synthesis-002 -- Co-precipitation of 15 wt% NiO/CeO2 dry reforming catalyst +# Target class: Synthesis +# +# Preparation method: CoPrecipitation (PrecipitationMixin + DryingMixin + CalcinationMixin). +# realized_plan range is PreparationMethod (abstract) -- concrete subclass slots silently +# ignored by Python loader. All method-specific parameters encoded in description. +# See SCHEMA_REVIEW.md for the abstract-range limitation. +# +# Demonstrates: +# - Three Precursor instances (Ni salt, Ce salt, precipitant) +# - had_output_entity with CatalystSample +# - Full synthesis-level slots (support, solvent, sample_pretreatment, storage_conditions) +# - Rich realized_plan description encoding precipitation / drying / calcination params + +id: "coremeta4cat:SYNTH_002_NiO_CeO2" +nominal_composition: + - "15 wt% NiO/CeO2" +catalyst_measured_properties: + - "BET surface area: 42 m2/g" + - "NiO crystallite size: 8.4 nm (Scherrer, XRD)" + - "Ni loading: 14.7 wt% (ICP-AES)" + - "reducibility onset: 280 deg C, completion at 600 deg C (H2-TPR)" +storage_conditions: + - "sealed glass vial in desiccator, ambient temperature, protected from moisture" +solvent: + - "deionized water (18.2 MOhm cm, MilliQ)" +sample_pretreatment: + - "in situ reduction: 5 vol% H2/N2 at 700 deg C for 1 h (10 deg C/min ramp) before DRM tests" +had_input_entity: + - id: "coremeta4cat:PREC_004_Ni_NO3_6H2O" + title: "nickel(II) nitrate hexahydrate (Sigma-Aldrich, purity 99%)" + precursor_quantity: + - 8.72 + - id: "coremeta4cat:PREC_005_Ce_NO3_6H2O" + title: "cerium(III) nitrate hexahydrate (Sigma-Aldrich, purity 99.5%)" + precursor_quantity: + - 13.03 + - id: "coremeta4cat:PREC_006_Na2CO3" + title: "sodium carbonate precipitating agent (anhydrous, Sigma-Aldrich, purity 99.5%)" + precursor_quantity: + - 5.30 +had_output_entity: + - id: "coremeta4cat:CAT_002_NiO_CeO2" + title: "NiO/CeO2 dry reforming catalyst (calcined precursor)" + description: "15 wt% NiO on CeO2 support, co-precipitated at pH 8.5, calcined 500 deg C / 4 h, sieved to 250-500 um" +realized_plan: + title: "co-precipitation" + description: "aqueous solutions of Ni(NO3)2 (0.5 M) and Ce(NO3)3 (0.5 M) mixed in stoichiometric ratio; precipitant: 1 M Na2CO3 solution added dropwise at 2 mL/min; target pH 8.5 maintained by feedback addition; mixing: 600 rpm mechanical stirring at 60 deg C for 2 h; aging: 12 h at 60 deg C without stirring; filtration: vacuum filtration through Whatman grade 4 filter paper; washing: 5 successive deionized water washes until conductivity < 5 uS/cm (Na+ removal); drying: 120 deg C for 12 h in static air oven; calcination: 5 deg C/min ramp to 500 deg C, isothermal hold for 4 h in static air, natural cooling"