diff --git a/.trunk/configs/.cspell.json b/.trunk/configs/.cspell.json index e236b70be..a0dfac46a 100644 --- a/.trunk/configs/.cspell.json +++ b/.trunk/configs/.cspell.json @@ -121,6 +121,7 @@ "doctest", "Doctest", "Doctests", - "linenums" + "linenums", + "XLYOFNOQVPJJNP" ] } diff --git a/docs/examples/simulation.md b/docs/examples/simulation.md index b49cb65bc..41b15243a 100644 --- a/docs/examples/simulation.md +++ b/docs/examples/simulation.md @@ -361,23 +361,13 @@ bulk.output_data = [final_data] ## Create a virtual Material -First, we'll create a virtual material and add some -[`Identifiers`](../../nodes/primary_nodes/material/#cript.nodes.primary_nodes.material.Material.identifier) -to the material to make it easier to identify and search. +First, we'll create a virtual material with identifiers to make it easier to search for. ```python -# create identifier dictionaries and put it in `identifiers` variable -identifiers = [{"names": ["poly(styrene)", "poly(vinylbenzene)"]}] -identifiers += [{"bigsmiles": "[H]{[>][<]C(C[>])c1ccccc1[<]}C(C)CC"}] -identifiers += [{"chem_repeat": ["C8H8"]}] - # create a material node object with identifiers -polystyrene = cript.Material(name="virtual polystyrene", identifier=identifiers) +polystyrene = cript.Material(name="virtual polystyrene", bigsmiles="[H]{[>][<]C(C[>])c1ccccc1[<]}C(C)CC", names = ["poly(styrene)", "poly(vinylbenzene)"], chem_repeat= ["C8H8"]) ``` -!!! note "Identifier keys" - The allowed [`Identifiers`](../../nodes/primary_nodes/material/#cript.nodes.primary_nodes.material.Material.identifier) keys are listed in the [material identifier keys](https://app.criptapp.org/vocab/material_identifier_key) in the CRIPT controlled vocabulary. - ## Add [`Property`](../../nodes/subobjects/property) sub-objects Let's also add some [`Property`](../../nodes/subobjects/property) nodes to the [`Material`](../../nodes/primary_nodes/material), which represent its physical or virtual (in the case of a simulated material) properties. diff --git a/docs/examples/synthesis.md b/docs/examples/synthesis.md index cd9c60638..3fdeb5d8b 100644 --- a/docs/examples/synthesis.md +++ b/docs/examples/synthesis.md @@ -116,15 +116,9 @@ They are for example the chemical you buy commercially and use as input into you For this we create this inventory by adding the [Material](../../nodes/primary_nodes/material) we need one by one. ```python -# create a list of identifiers as dictionaries to -# identify your material to the community and your team -my_solution_material_identifiers = [ - {"chemical_id": "598-30-1"} -] - solution = cript.Material( name="SecBuLi solution 1.4M cHex", - identifier=my_solution_material_identifiers + chemical_id = "598-30-1", ) ``` @@ -132,10 +126,10 @@ These materials are simple, notice how we use the SMILES notation here as an ide Similarly, we can create more initial materials. ```python -toluene = cript.Material(name="toluene", identifier=[{"smiles": "Cc1ccccc1"}, {"pubchem_cid": 1140}]) -styrene = cript.Material(name="styrene", identifier=[{"smiles": "c1ccccc1C=C"}, {"inchi": "InChI=1S/C8H8/c1-2-8-6-4-3-5-7-8/h2-7H,1H2"}]) -butanol = cript.Material(name="1-butanol", identifier=[{"smiles": "OCCCC"}, {"inchi_key": "InChIKey=LRHPLDYGYMQRHN-UHFFFAOYSA-N"}]) -methanol = cript.Material(name="methanol", identifier=[{"smiles": "CO"}, {"names": ["Butan-1-ol", "Butyric alcohol", "Methylolpropane", "n-Butan-1-ol", "methanol"]}]) +toluene = cript.Material(name="toluene", smiles="Cc1ccccc1", pubchem_cid = 1140) +styrene = cript.Material(name="styrene", smiles = "c1ccccc1C=C", inchi = "InChI=1S/C8H8/c1-2-8-6-4-3-5-7-8/h2-7H,1H2") +butanol = cript.Material(name="1-butanol", smiles = "OCCCC", inchi_key = "InChIKey=LRHPLDYGYMQRHN-UHFFFAOYSA-N") +methanol = cript.Material(name="methanol", smiles = "CO", names = ["Butan-1-ol", "Butyric alcohol", "Methylolpropane", "n-Butan-1-ol", "methanol"]) ``` Now that we defined those materials, we can combine them into an inventory @@ -250,20 +244,15 @@ that will serve as our product. We give the material a `name` attribute and add [Project]((../../nodes/primary_nodes/project). ```python -polystyrene = cript.Material(name="polystyrene", identifier=[]) +polystyrene = cript.Material(name="polystyrene", bigsmiles="[H]{[>][<]C(C[>])c1ccccc1[<]}C(C)CC") project.material += [polystyrene] ``` Let's add some `Identifiers` to the material to make it easier to identify and search. ```python -# create a name identifier -polystyrene.identifier += [{"names": ["poly(styrene)", "poly(vinylbenzene)"]}] - -# create a BigSMILES identifier -polystyrene.identifier += [{"bigsmiles": "[H]{[>][<]C(C[>])c1ccccc1[<]}C(C)CC"}] # create a chemical repeat unit identifier -polystyrene.identifier += [{"chem_repeat": ["C8H8"]}] +polystyrene.chem_repeat = ["C8H8"] ``` Next, we'll add some [Property](../../nodes/subobjects/property) nodes to the diff --git a/mkdocs.yml b/mkdocs.yml index 31a19f992..e33d66a2a 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -38,7 +38,6 @@ nav: - Computational Forcefield: nodes/subobjects/computational_forcefield.md - Condition: nodes/subobjects/condition.md - Equipment: nodes/subobjects/equipment.md - # - Identifier: nodes/subobjects/identifier.md - Ingredient: nodes/subobjects/ingredient.md - Parameter: nodes/subobjects/parameter.md - Property: nodes/subobjects/property.md diff --git a/src/cript/api/api.py b/src/cript/api/api.py index 14f864bb9..025863a83 100644 --- a/src/cript/api/api.py +++ b/src/cript/api/api.py @@ -824,7 +824,7 @@ def delete(self, node) -> None: >>> import cript >>> my_material_node = cript.Material( ... name="my component material 1", - ... identifier=[{"amino_acid": "component 1 alternative name"}], + ... names = ["component 1 alternative name"], ... ) >>> api.delete(node=my_material_node) # doctest: +SKIP diff --git a/src/cript/api/valid_search_modes.py b/src/cript/api/valid_search_modes.py index 206f4b540..c5a06078c 100644 --- a/src/cript/api/valid_search_modes.py +++ b/src/cript/api/valid_search_modes.py @@ -16,7 +16,7 @@ class SearchModes(Enum): UUID : str Search by node UUID. BIGSMILES: str - search materials by bigsmiles identifier. + search materials by bigsmiles. Examples ------- diff --git a/src/cript/nodes/core.py b/src/cript/nodes/core.py index b385692ed..3f43fedd4 100644 --- a/src/cript/nodes/core.py +++ b/src/cript/nodes/core.py @@ -293,10 +293,10 @@ def get_expanded_json(self, **kwargs) -> str: >>> my_project = cript.Project(name=f"my_Project") >>> my_collection = cript.Collection(name="my collection") >>> my_material_1 = cript.Material( - ... name="my material 1", identifier=[{"bigsmiles": "my material 1 bigsmiles"}] + ... name="my material 1", bigsmiles = "my material 1 bigsmiles" ... ) >>> my_material_2 = cript.Material( - ... name="my material 2", identifier=[{"bigsmiles": "my material 2 bigsmiles"}] + ... name="my material 2", bigsmiles = "my material 2 bigsmiles" ... ) >>> my_inventory = cript.Inventory( ... name="my inventory", material=[my_material_1, my_material_2] @@ -511,10 +511,10 @@ def find_children(self, search_attr: dict, search_depth: int = -1, handled_nodes >>> my_project = cript.Project(name=f"my_Project") >>> my_collection = cript.Collection(name="my collection") >>> my_material_1 = cript.Material( - ... name="my material 1", identifier=[{"bigsmiles": "my material 1 bigsmiles"}] + ... name="my material 1", bigsmiles = "my material 1 bigsmiles" ... ) >>> my_material_2 = cript.Material( - ... name="my material 2", identifier=[{"bigsmiles": "my material 2 bigsmiles"}] + ... name="my material 2", bigsmiles = "my material 2 bigsmiles" ... ) >>> my_inventory = cript.Inventory( ... name="my inventory", material=[my_material_1, my_material_2] diff --git a/src/cript/nodes/exceptions.py b/src/cript/nodes/exceptions.py index bfb427901..0d1942388 100644 --- a/src/cript/nodes/exceptions.py +++ b/src/cript/nodes/exceptions.py @@ -54,6 +54,19 @@ def __str__(self) -> str: return error_message +class CRIPTMaterialIdentifierError(CRIPTException): + """Every material node needs to have at least one identifier set.""" + + def __init__(self, material_node): + self.material_node = material_node + + def __str__(self) -> str: + error_message = "Every Material node needs at least one identifier from " + error_message += " [ 'amino_acid', 'bigsmiles', 'chem_formula', 'chem_repeat', 'chemical_id', 'inchi', 'lot_number', 'names', 'pubchem_cid', 'smiles','vendor'] set." + error_message += f" This node {self.material_node} has none set." + return error_message + + class CRIPTJsonDeserializationError(CRIPTException): """ ## Definition diff --git a/src/cript/nodes/primary_nodes/collection.py b/src/cript/nodes/primary_nodes/collection.py index 3beaf5c57..daa7e6278 100644 --- a/src/cript/nodes/primary_nodes/collection.py +++ b/src/cript/nodes/primary_nodes/collection.py @@ -175,11 +175,11 @@ def inventory(self) -> List[Any]: >>> my_collection = cript.Collection(name="my collection name") >>> material_1 = cript.Material( ... name="material 1", - ... identifier=[{"bigsmiles": "material 1 bigsmiles"}], + ... bigsmiles = "material 1 bigsmiles", ... ) >>> material_2 = cript.Material( ... name="material 2", - ... identifier=[{"bigsmiles": "material 2 bigsmiles"}], + ... bigsmiles = "material 2 bigsmiles", ... ) >>> my_inventory = cript.Inventory( ... name="my inventory name", material=[material_1, material_2] diff --git a/src/cript/nodes/primary_nodes/computation_process.py b/src/cript/nodes/primary_nodes/computation_process.py index 12502b738..c08f853c6 100644 --- a/src/cript/nodes/primary_nodes/computation_process.py +++ b/src/cript/nodes/primary_nodes/computation_process.py @@ -154,7 +154,7 @@ def __init__( >>> input_data = cript.Data(name="my data name", type="afm_amp", file=[data_files]) >>> my_material = cript.Material( ... name="my material", - ... identifier=[{"names": ["my material alternative name"]}] + ... names = ["my material alternative name"] ... ) >>> my_quantity = cript.Quantity(key="mass", value=1.23, unit="kg") >>> ingredient = cript.Ingredient( @@ -368,7 +368,7 @@ def ingredient(self) -> List[Any]: Examples -------- >>> import cript - >>> my_material = cript.Material(name="my material", identifier=[{"bigsmiles": "123456"}]) + >>> my_material = cript.Material(name="my material", bigsmiles = "my bigsmiles") >>> my_quantity = cript.Quantity( ... key="mass", value=11.2, unit="kg", uncertainty=0.2, uncertainty_type="stdev" ... ) diff --git a/src/cript/nodes/primary_nodes/data.py b/src/cript/nodes/primary_nodes/data.py index 586e292cb..e631dd27b 100644 --- a/src/cript/nodes/primary_nodes/data.py +++ b/src/cript/nodes/primary_nodes/data.py @@ -401,7 +401,7 @@ def computation_process(self) -> Union[Any, None]: ... ) >>> my_material = cript.Material( ... name="my material name", - ... identifier=[{"bigsmiles": "123456"}] + ... bigsmiles = "123456" ... ) >>> my_quantity = cript.Quantity( ... key="mass", value=11.2, unit="kg", uncertainty=0.2, uncertainty_type="stdev" @@ -459,7 +459,7 @@ def material(self) -> List[Any]: ... data_dictionary="my file's data dictionary" ... ) >>> my_data = cript.Data(name="my data name", type="afm_amp", file=[my_file]) - >>> my_material = cript.Material(name="my material name", identifier=[{"bigsmiles": "123456"}]) + >>> my_material = cript.Material(name="my material name", bigsmiles = "123456") >>> my_data.material = [my_material] Returns diff --git a/src/cript/nodes/primary_nodes/experiment.py b/src/cript/nodes/primary_nodes/experiment.py index 3d8433ebf..4646f733a 100644 --- a/src/cript/nodes/primary_nodes/experiment.py +++ b/src/cript/nodes/primary_nodes/experiment.py @@ -244,7 +244,7 @@ def computation_process(self) -> List[Any]: ... ) >>> my_data = cript.Data(name="my data name", type="afm_amp", file=[my_file]) >>> my_material = cript.Material( - ... name="my material name", identifier=[{"bigsmiles": "123456"}] + ... name="my material name", bigsmiles = "123456" ... ) >>> my_quantity = cript.Quantity( ... key="mass", value=11.2, unit="kg", uncertainty=0.2, uncertainty_type="stdev" diff --git a/src/cript/nodes/primary_nodes/inventory.py b/src/cript/nodes/primary_nodes/inventory.py index d654e8902..a0509755d 100644 --- a/src/cript/nodes/primary_nodes/inventory.py +++ b/src/cript/nodes/primary_nodes/inventory.py @@ -73,11 +73,11 @@ def __init__(self, name: str, material: List[Material], notes: str = "", **kwarg >>> import cript >>> material_1 = cript.Material( ... name="material 1", - ... identifier=[{"bigsmiles": "material 1 bigsmiles"}], + ... bigsmiles = "material 1 bigsmiles", ... ) >>> material_2 = cript.Material( ... name="material 2", - ... identifier=[{"bigsmiles": "material 2 bigsmiles"}], + ... bigsmiles = "material 2 bigsmiles", ... ) >>> my_inventory = cript.Inventory( ... name="my inventory name", material=[material_1, material_2] @@ -113,12 +113,12 @@ def material(self) -> List[Material]: >>> import cript >>> my_material = cript.Material( ... name="my material", - ... identifier=[{"bigsmiles": "my bigsmiles"}], + ... bigsmiles = "my bigsmiles", ... ) >>> my_inventory = cript.Inventory(name="my inventory", material=[my_material]) >>> new_material = cript.Material( ... name="new material", - ... identifier=[{"bigsmiles": "my bigsmiles"}], + ... bigsmiles = "my bigsmiles", ... ) >>> my_inventory.material = [new_material] diff --git a/src/cript/nodes/primary_nodes/material.py b/src/cript/nodes/primary_nodes/material.py index 110ee47e5..807711d0f 100644 --- a/src/cript/nodes/primary_nodes/material.py +++ b/src/cript/nodes/primary_nodes/material.py @@ -1,8 +1,9 @@ from dataclasses import dataclass, field, replace -from typing import Any, Dict, List, Optional +from typing import Any, List, Optional, Union from beartype import beartype +from cript.nodes.exceptions import CRIPTMaterialIdentifierError from cript.nodes.primary_nodes.primary_base_node import PrimaryBaseNode from cript.nodes.primary_nodes.process import Process @@ -11,12 +12,11 @@ class Material(PrimaryBaseNode): """ ## Definition A [Material node](https://pubs.acs.org/doi/suppl/10.1021/acscentsci.3c00011/suppl_file/oc3c00011_si_001.pdf#page=10) - is a collection of the identifiers and properties of a chemical, mixture, or substance. + is a collection of the properties of a chemical, mixture, or substance. ## Attributes | attribute | type | example | description | required | vocab | |---------------------------|----------------------------------------------------------------------|---------------------------------------------------|-----------------------------------------------------|-------------|-------| - | identifier | list[Identifier] | | material identifiers | True | | | component | list[[Material](./)] | | list of component that make up the mixture | | | | property | list[[Property](../../subobjects/property)] | | material properties | | | | process | [Process](../process) | | process node that made this material | | | @@ -24,13 +24,25 @@ class Material(PrimaryBaseNode): | computational_forcefield | [Computation Forcefield](../../subobjects/computational_forcefield) | | computation forcefield | Conditional | | | keyword | list[str] | [thermoplastic, homopolymer, linear, polyolefins] | words that classify the material | | True | | notes | str | "my awesome notes" | miscellaneous information, or custom data structure | | True | + | amino_acid | str | "LeuProHis" | if the material is an amino acid sequence, list it. | Conditional | | + | bigsmiles | str | "CC{[$][$]CC[$][]}" | BigSMILES string for polymer | Conditional | | + | chem_formula | str | "C22H33NO10" | Chemical formula of the material or monomer | Conditional | | + | chem_repeat | str | "C=Cc1ccccc1" | Chemical formula of the repeat unit | Conditional | | + | chemical_id | str | "126094" | Unique chemical ID | Conditional | | + | inchi | str | "InChI=1S/H2O/h1H2" | InChI string of the chemical | Conditional | | + | inchi_key | str | "XLYOFNOQVPJJNP-UHFFFAOYSA-N" | InChI key of the chemical | Conditional | | + | lot_number | str | "123" | Lot number of the chemical | Conditional | | + | names | list[str] | ["water", "Hydrogen oxide"] | Alternative names that are being used | Conditional | | + | pubchem_cid | int | 962 | PubChemID of the chemical | Conditional | | + | smiles | str | "O" | Smiles string of the chemical | Conditional | | + | vendor | str | "fisher scientific" | Vendor the chemical was purchased from | Conditional | | + ## Navigating to Material Materials can be easily found on the [CRIPT](https://app.criptapp.org) home screen in the under the navigation within the [Materials link](https://app.criptapp.org/material/) ## Available Sub-Objects for Material - * [Identifier](../../subobjects/identifier) * [Property](../../subobjects/property) * [Computational_forcefield](../../subobjects/computational_forcefield) @@ -61,8 +73,6 @@ class JsonAttributes(PrimaryBaseNode.JsonAttributes): all Material attributes """ - # identifier sub-object for the material - identifier: List[Dict[str, str]] = field(default_factory=dict) # type: ignore # TODO add proper typing in future, using Any for now to avoid circular import error component: List["Material"] = field(default_factory=list) process: Optional[Process] = None @@ -70,6 +80,18 @@ class JsonAttributes(PrimaryBaseNode.JsonAttributes): parent_material: Optional["Material"] = None computational_forcefield: Optional[Any] = None keyword: List[str] = field(default_factory=list) + amino_acid: Optional[str] = None + bigsmiles: Optional[str] = None + chem_formula: Optional[str] = None + chem_repeat: List[str] = field(default_factory=list) + chemical_id: Optional[str] = None + inchi: Optional[str] = None + inchi_key: Optional[str] = None + lot_number: Optional[str] = None + names: List[str] = field(default_factory=list) + pubchem_cid: Optional[int] = None + smiles: Optional[str] = None + vendor: Optional[str] = None _json_attrs: JsonAttributes = JsonAttributes() @@ -77,13 +99,24 @@ class JsonAttributes(PrimaryBaseNode.JsonAttributes): def __init__( self, name: str, - identifier: List[Dict[str, str]], component: Optional[List["Material"]] = None, process: Optional[Process] = None, property: Optional[List[Any]] = None, parent_material: Optional["Material"] = None, computational_forcefield: Optional[Any] = None, keyword: Optional[List[str]] = None, + amino_acid: Optional[str] = None, + bigsmiles: Optional[str] = None, + chem_formula: Optional[str] = None, + chem_repeat: Optional[List[str]] = None, + chemical_id: Optional[str] = None, + inchi: Optional[str] = None, + inchi_key: Optional[str] = None, + lot_number: Optional[str] = None, + names: Optional[List[str]] = None, + pubchem_cid: Optional[int] = None, + smiles: Optional[str] = None, + vendor: Optional[str] = None, notes: str = "", **kwargs ): @@ -95,19 +128,30 @@ def __init__( >>> import cript >>> my_material = cript.Material( ... name="my component material 1", - ... identifier=[{"amino_acid": "component 1 alternative name"}], + ... amino_acid = "component 1 alternative name", ... ) Parameters ---------- name: str - identifier: List[Dict[str, str]] component: List["Material"], default=None property: Optional[Process], default=None process: List[Process], default=None parent_material: "Material", default=None computational_forcefield: ComputationalForcefield, default=None keyword: List[str], default=None + amino_acid: Optional[str] = None, + bigsmiles: Optional[str] = None, + chem_formula: Optional[str] = None, + chem_repeat: Optional[List[str]] = None, + chemical_id: Optional[str] = None, + inchi: Optional[str] = None, + inchi_key: Optional[str] = None, + lot_number: Optional[str] = None, + names: Optional[List[str]] = None, + pubchem_cid: Optional[int] = None, + smiles: Optional[str] = None, + vendor: Optional[str] = None, Returns ------- @@ -126,62 +170,185 @@ def __init__( if keyword is None: keyword = [] + if chem_repeat is None: + chem_repeat = [] + + if names is None: + names = [] + new_json_attrs = replace( self._json_attrs, name=name, - identifier=identifier, component=component, process=process, property=property, parent_material=parent_material, computational_forcefield=computational_forcefield, keyword=keyword, + amino_acid=amino_acid, + bigsmiles=bigsmiles, + chem_formula=chem_formula, + chem_repeat=chem_repeat, + chemical_id=chemical_id, + inchi=inchi, + inchi_key=inchi_key, + lot_number=lot_number, + names=names, + pubchem_cid=pubchem_cid, + smiles=smiles, + vendor=vendor, ) self._update_json_attrs_if_valid(new_json_attrs) + def validate(self, api=None, is_patch: bool = False, force_validation: bool = False) -> None: + super().validate(api=api, is_patch=is_patch, force_validation=force_validation) + + if ( + self.amino_acid is None + and self.bigsmiles is None + and self.chem_formula is None + and len(self.chem_repeat) == 0 + and self.chemical_id is None + and self.inchi_key is None + and self.inchi is None + and self.lot_number is None + and len(self.names) == 0 + and self.pubchem_cid is None + and self.smiles is None + and self.vendor is None + ): + raise CRIPTMaterialIdentifierError(self) + @property @beartype - def identifier(self) -> List[Dict[str, str]]: - """ - get the identifiers for this material + def amino_acid(self) -> Union[str, None]: + return self._json_attrs.amino_acid - Examples - -------- - >>> import cript - >>> my_material = cript.Material( - ... name="my component material 1", - ... identifier=[{"smiles": "component 1 smiles"}], - ... ) - >>> my_material.identifier = [{"smiles": "my material alternative name"}] + @amino_acid.setter + @beartype + def amino_acid(self, new_amino_acid: str) -> None: + new_attrs = replace(self._json_attrs, amino_acid=new_amino_acid) + self._update_json_attrs_if_valid(new_attrs) - [material identifier key](https://app.criptapp.org/vocab/material_identifier_key) - must come from CRIPT controlled vocabulary + @property + @beartype + def bigsmiles(self) -> Union[str, None]: + return self._json_attrs.bigsmiles - Returns - ------- - List[Dict[str, str]] - list of dictionary that has identifiers for this material - """ - return self._json_attrs.identifier.copy() + @bigsmiles.setter + @beartype + def bigsmiles(self, new_bigsmiles: str) -> None: + new_attrs = replace(self._json_attrs, bigsmiles=new_bigsmiles) + self._update_json_attrs_if_valid(new_attrs) - @identifier.setter + @property @beartype - def identifier(self, new_identifier_list: List[Dict[str, str]]) -> None: - """ - set the list of identifiers for this material + def chem_formula(self) -> Union[str, None]: + return self._json_attrs.chem_formula - the identifier keys must come from the - material identifiers keyword within the CRIPT controlled vocabulary + @chem_formula.setter + @beartype + def chem_formula(self, new_chem_formula: str) -> None: + new_attrs = replace(self._json_attrs, chem_formula=new_chem_formula) + self._update_json_attrs_if_valid(new_attrs) - Parameters - ---------- - new_identifier_list: List[Dict[str, str]] + @property + @beartype + def chemical_id(self) -> Union[str, None]: + return self._json_attrs.chemical_id - Returns - ------- - None - """ - new_attrs = replace(self._json_attrs, identifier=new_identifier_list) + @chemical_id.setter + @beartype + def chemical_id(self, new_chemical_id: str) -> None: + new_attrs = replace(self._json_attrs, chemical_id=new_chemical_id) + self._update_json_attrs_if_valid(new_attrs) + + @property + @beartype + def inchi(self) -> Union[str, None]: + return self._json_attrs.inchi + + @inchi.setter + @beartype + def inchi(self, new_inchi: str) -> None: + new_attrs = replace(self._json_attrs, inchi=new_inchi) + self._update_json_attrs_if_valid(new_attrs) + + @property + @beartype + def inchi_key(self) -> Union[str, None]: + return self._json_attrs.inchi_key + + @inchi_key.setter + @beartype + def inchi_key(self, new_inchi_key: str) -> None: + new_attrs = replace(self._json_attrs, inchi_key=new_inchi_key) + self._update_json_attrs_if_valid(new_attrs) + + @property + @beartype + def lot_number(self) -> Union[str, None]: + return self._json_attrs.lot_number + + @lot_number.setter + @beartype + def lot_number(self, new_lot_number: str) -> None: + new_attrs = replace(self._json_attrs, lot_number=new_lot_number) + self._update_json_attrs_if_valid(new_attrs) + + @property + @beartype + def smiles(self) -> Union[str, None]: + return self._json_attrs.smiles + + @smiles.setter + @beartype + def smiles(self, new_smiles: str) -> None: + new_attrs = replace(self._json_attrs, smiles=new_smiles) + self._update_json_attrs_if_valid(new_attrs) + + @property + @beartype + def vendor(self) -> Union[str, None]: + return self._json_attrs.vendor + + @vendor.setter + @beartype + def vendor(self, new_vendor: str) -> None: + new_attrs = replace(self._json_attrs, vendor=new_vendor) + self._update_json_attrs_if_valid(new_attrs) + + @property + @beartype + def chem_repeat(self) -> List[str]: + return self._json_attrs.chem_repeat.copy() + + @chem_repeat.setter + @beartype + def chem_repeat(self, new_chem_repeat: List[str]) -> None: + new_attrs = replace(self._json_attrs, chem_repeat=new_chem_repeat) + self._update_json_attrs_if_valid(new_attrs) + + @property + @beartype + def names(self) -> List[str]: + return self._json_attrs.names.copy() + + @names.setter + @beartype + def names(self, new_names: List[str]) -> None: + new_attrs = replace(self._json_attrs, names=new_names) + self._update_json_attrs_if_valid(new_attrs) + + @property + @beartype + def pubchem_cid(self) -> Union[int, None]: + return self._json_attrs.pubchem_cid + + @pubchem_cid.setter + @beartype + def pubchem_cid(self, new_pubchem_cid: int) -> None: + new_attrs = replace(self._json_attrs, pubchem_cid=new_pubchem_cid) self._update_json_attrs_if_valid(new_attrs) @property @@ -196,17 +363,17 @@ def component(self) -> List["Material"]: >>> my_components = [ ... cript.Material( ... name="my component material 1", - ... identifier=[{"smiles": "my material smiles"}], + ... smiles="my material smiles", ... ), ... cript.Material( ... name="my component material 2", - ... identifier=[{"vendor": "my material vendor"}], + ... vendor= "my material vendor", ... ), ... ] >>> my_mixed_material = cript.Material( ... name="my material", ... component=my_components, - ... identifier=[{"bigsmiles": "123456"}] + ... bigsmiles = "123456", ... ) Returns @@ -274,7 +441,7 @@ def computational_forcefield(self) -> Any: -------- >>> import cript >>> my_material = cript.Material( - ... name="my component material 1", identifier=[{"smiles": "my smiles"}] + ... name="my component material 1", smiles= "my smiles" ... ) >>> my_computational_forcefield = cript.ComputationalForcefield( ... key="opls_aa", @@ -319,7 +486,7 @@ def keyword(self) -> List[str]: -------- >>> import cript >>> my_material = cript.Material( - ... name="my material", identifier=[{"inchi": "my material inchi"}] + ... name="my material", inchi = "my material inchi" ... ) >>> my_material.keyword = ["acetylene", "acrylate", "alternating"] @@ -369,7 +536,7 @@ def property(self) -> List[Any]: >>> import cript >>> my_material = cript.Material( ... name="my component material 1", - ... identifier=[{"smiles": "component 1 smiles"}], + ... smiles = "component 1 smiles", ... ) >>> my_property = cript.Property(key="modulus_shear", type="min", value=1.23, unit="gram") >>> my_material.property = [my_property] @@ -397,37 +564,3 @@ def property(self, new_property_list: List[Any]) -> None: """ new_attrs = replace(self._json_attrs, property=new_property_list) self._update_json_attrs_if_valid(new_attrs) - - @classmethod - @beartype - def _from_json(cls, json_dict: Dict): - """ - Create a new instance of a node from a JSON representation. - - Parameters - ---------- - json_dict : Dict - A JSON dictionary representing a node - - Returns - ------- - node - A new instance of a node. - - Notes - ----- - required fields in JSON: - * `name`: The name of the node - - optional fields in JSON: - * `identifier`: A list of material identifiers. - * If the `identifier` property is not present in the JSON dictionary, - it will be set to an empty list. - """ - from cript.nodes.util.material_deserialization import ( - _deserialize_flattened_material_identifiers, - ) - - json_dict = _deserialize_flattened_material_identifiers(json_dict) - - return super()._from_json(json_dict) diff --git a/src/cript/nodes/primary_nodes/process.py b/src/cript/nodes/primary_nodes/process.py index a8d9de573..f730a14e2 100644 --- a/src/cript/nodes/primary_nodes/process.py +++ b/src/cript/nodes/primary_nodes/process.py @@ -223,8 +223,7 @@ def ingredient(self) -> List[Any]: --------- >>> import cript >>> my_process = cript.Process(name="my process name", type="affinity_pure") - >>> my_identifier = [{"bigsmiles": "123456"}] - >>> my_material = cript.Material(name="my material", identifier=my_identifier) + >>> my_material = cript.Material(name="my material", bigsmiles = "material bigsmiles") >>> my_quantity = cript.Quantity( ... key="mass", value=11.2, unit="kg", uncertainty=0.2, uncertainty_type="stdev" ... ) @@ -345,7 +344,7 @@ def product(self) -> List[Any]: >>> my_process = cript.Process(name="my process name", type="affinity_pure") >>> my_product_material = cript.Material( ... name="my product material", - ... identifier=[{"amino_acid": "my material product amino_acid"}], + ... amino_acid = "my material product amino_acid", ... ) >>> my_process.product = [my_product_material] @@ -386,7 +385,7 @@ def waste(self) -> List[Any]: >>> my_process = cript.Process(name="my process name", type="affinity_pure") >>> my_waste_material = cript.Material( ... name="my waste material", - ... identifier=[{"bigsmiles": "123456"}], + ... bigsmiles = "123456", ... ) >>> my_process.waste = [my_waste_material] diff --git a/src/cript/nodes/primary_nodes/project.py b/src/cript/nodes/primary_nodes/project.py index bab62cbfa..48e182463 100644 --- a/src/cript/nodes/primary_nodes/project.py +++ b/src/cript/nodes/primary_nodes/project.py @@ -206,8 +206,7 @@ def material(self) -> List[Material]: -------- >>> import cript >>> my_project = cript.Project(name="my Project name") - >>> identifier = [{"bigsmiles": "my big smiles"}] - >>> my_material = cript.Material(name="my material", identifier=identifier) + >>> my_material = cript.Material(name="my material", bigsmiles="my bigsmiles") >>> my_project.material = [my_material] Returns diff --git a/src/cript/nodes/subobjects/ingredient.py b/src/cript/nodes/subobjects/ingredient.py index fc698173a..9c66a304c 100644 --- a/src/cript/nodes/subobjects/ingredient.py +++ b/src/cript/nodes/subobjects/ingredient.py @@ -79,8 +79,7 @@ def __init__(self, material: Material, quantity: List[Quantity], keyword: Option Examples -------- >>> import cript - >>> my_identifier = [{"bigsmiles": "123456"}] - >>> my_material = cript.Material(name="my material", identifier=my_identifier) + >>> my_material = cript.Material(name="my material", bigsmiles="my bigsmiles") >>> my_quantity = cript.Quantity( ... key="mass", value=11.2, unit="kg", uncertainty=0.2, uncertainty_type="stdev" ... ) @@ -150,7 +149,7 @@ def set_material(self, new_material: Material, new_quantity: List[Quantity]) -> Examples -------- >>> import cript - >>> my_material = cript.Material(name="my material", identifier=[{"bigsmiles": "123456"}]) + >>> my_material = cript.Material(name="my material", bigsmiles = "123456") >>> my_quantity = cript.Quantity( ... key="mass", value=11.2, unit="kg", uncertainty=0.2, uncertainty_type="stdev" ... ) @@ -158,7 +157,7 @@ def set_material(self, new_material: Material, new_quantity: List[Quantity]) -> ... material=my_material, quantity=[my_quantity], keyword=["catalyst"] ... ) >>> my_new_material = cript.Material( - ... name="my material", identifier=[{"bigsmiles": "78910"}] + ... name="my material", bigsmiles = "78910" ... ) >>> my_new_quantity = cript.Quantity( ... key="mass", value=11.2, unit="kg", uncertainty=0.2, uncertainty_type="stdev" @@ -189,7 +188,7 @@ def keyword(self) -> List[str]: Examples -------- >>> import cript - >>> my_material = cript.Material(name="my material", identifier=[{"bigsmiles": "123456"}]) + >>> my_material = cript.Material(name="my material", bigsmiles = "123456") >>> my_quantity = cript.Quantity( ... key="mass", value=11.2, unit="kg", uncertainty=0.2, uncertainty_type="stdev" ... ) diff --git a/src/cript/nodes/subobjects/property.py b/src/cript/nodes/subobjects/property.py index fb97e8f30..196772865 100644 --- a/src/cript/nodes/subobjects/property.py +++ b/src/cript/nodes/subobjects/property.py @@ -380,7 +380,7 @@ def component(self) -> List[Material]: --------- >>> import cript >>> my_property = cript.Property(key="air_flow", type="min", value=1.00, unit="gram") - >>> my_material = cript.Material(name="my material", identifier=[{"bigsmiles": "123456"}]) + >>> my_material = cript.Material(name="my material", bigsmiles = "123456") >>> my_property.component = [my_material] Returns diff --git a/src/cript/nodes/util/json.py b/src/cript/nodes/util/json.py index 1106f5e0d..e61ff2307 100644 --- a/src/cript/nodes/util/json.py +++ b/src/cript/nodes/util/json.py @@ -196,10 +196,6 @@ def strip_to_edge_uuid(element): processed_attribute = process_attribute(attribute_to_condense) serialize_dict[attribute] = processed_attribute - # Check if the node is "Material" and convert the identifiers list to JSON fields - if serialize_dict["node"] == ["Material"]: - serialize_dict = _material_identifiers_list_to_json_fields(serialize_dict) - return serialize_dict, uid_of_condensed @@ -356,52 +352,6 @@ def load_nodes_from_json(nodes_json: Union[str, Dict]): return json.loads(nodes_json, object_hook=node_json_hook) -def _material_identifiers_list_to_json_fields(serialize_dict: Dict) -> Dict: - """ - input: - ```json - { - "node":["Material"], - "name":"my material", - "identifier":[ {"cas":"my material cas"} ], - "uid":"_:a78203cb-82ea-4376-910e-dee74088cd37" - } - ``` - - output: - ```json - { - "node":["Material"], - "name":"my material", - "cas":"my material cas", - "uid":"_:08018f4a-e8e3-4ac0-bdad-fa704fdc0145" - } - ``` - - Parameters - ---------- - serialize_dict: Dict - the serialized dictionary of the node - - Returns - ------- - serialized_dict = Dict - new dictionary that has converted the list of dictionary identifiers into the dictionary as fields - - """ - - # TODO this if statement might not be needed in future - if "identifier" in serialize_dict: - for identifier in serialize_dict["identifier"]: - for key, value in identifier.items(): - serialize_dict[key] = value - - # remove identifiers list of objects after it has been flattened - del serialize_dict["identifier"] - - return serialize_dict - - def _rename_field(serialize_dict: Dict, old_name: str, new_name: str) -> Dict: """ renames `property_` to `property` the JSON diff --git a/src/cript/nodes/util/material_deserialization.py b/src/cript/nodes/util/material_deserialization.py deleted file mode 100644 index 255721c73..000000000 --- a/src/cript/nodes/util/material_deserialization.py +++ /dev/null @@ -1,74 +0,0 @@ -from typing import Dict, List - -import cript - - -def _deserialize_flattened_material_identifiers(json_dict: Dict) -> Dict: - """ - takes a material node in JSON format that has its identifiers as attributes and convert it to have the - identifiers within the identifiers field of a material node - - 1. gets the material identifiers controlled vocabulary from the API - 1. converts the API response from list[dicts] to just a list[str] - 1. loops through all the material identifiers and checks if they exist within the JSON dict - 1. if a material identifier is spotted in json dict, then that material identifier is moved from JSON attribute - into an identifiers field - - - ## Input - ```python - { - "node": ["Material"], - "name": "my cool material", - "uuid": "_:my cool material", - "smiles": "CCC", - "bigsmiles": "my big smiles" - } - ``` - - ## Output - ```python - { - "node":["Material"], - "name":"my cool material", - "uuid":"_:my cool material", - "identifier":[ - {"smiles":"CCC"}, - {"bigsmiles":"my big smiles"} - ] - } - ``` - - Parameters - ---------- - json_dict: Dict - A JSON dictionary representing a node - - Returns - ------- - json_dict: Dict - A new JSON dictionary with the material identifiers moved from attributes to the identifiers field - """ - from cript.api.api import _get_global_cached_api - - api = _get_global_cached_api() - - # get material identifiers keys from API and create a simple list - # eg ["smiles", "bigsmiles", etc.] - all_identifiers_list: List[str] = [identifier.get("name") for identifier in api.schema.get_vocab_by_category(cript.VocabCategories.MATERIAL_IDENTIFIER_KEY)] - - # pop "name" from identifiers list because the node has to have a name - all_identifiers_list.remove("name") - - identifier_argument: List[Dict] = [] - - # move material identifiers from JSON attribute to identifiers attributes - for identifier in all_identifiers_list: - if identifier in json_dict: - identifier_argument.append({identifier: json_dict[identifier]}) - # delete identifiers from the API JSON response as they are added to the material node - del json_dict[identifier] - - json_dict["identifier"] = identifier_argument - - return json_dict diff --git a/tests/fixtures/primary_nodes.py b/tests/fixtures/primary_nodes.py index 837994add..65fbf0222 100644 --- a/tests/fixtures/primary_nodes.py +++ b/tests/fixtures/primary_nodes.py @@ -177,7 +177,7 @@ def complex_process_node(complex_ingredient_node, simple_equipment_node, complex my_process_description = "my simple material description" process_waste = [ - cript.Material(name="my process waste material 1", identifier=[{"bigsmiles": "process waste bigsmiles"}]), + cript.Material(name="my process waste material 1", bigsmiles="CC{[$][$]COC[$][]}"), ] my_process_keywords = [ @@ -218,9 +218,8 @@ def simple_material_node() -> cript.Material: """ simple material node to use between tests """ - identifier = [{"bigsmiles": "123456"}] # Use a unique name - my_material = cript.Material(name="my test material " + str(uuid.uuid4()), identifier=identifier) + my_material = cript.Material(name="my test material " + str(uuid.uuid4()), bigsmiles="{[][$]COC[$][]}") return my_material @@ -231,7 +230,7 @@ def simple_material_dict() -> dict: the dictionary that `simple_material_node` produces putting it in one location to make updating it easy """ - simple_material_dict: dict = {"node": ["Material"], "name": "my material", "bigsmiles": "123456"} + simple_material_dict: dict = {"node": ["Material"], "name": "my material", "bigsmiles": "{[][$]COC[$][]}"} return simple_material_dict @@ -249,7 +248,7 @@ def complex_material_dict(simple_property_node, simple_process_node, complex_com material_dict["process"] = json.loads(simple_process_node.get_json(condense_to_uuid={}).json) material_dict["parent_material"] = json.loads(simple_material_node.get_json(condense_to_uuid={}).json) material_dict["computational_forcefield"] = json.loads(complex_computational_forcefield_node.get_json(condense_to_uuid={}).json) - material_dict["bigsmiles"] = "my complex_material_node" + material_dict["bigsmiles"] = "{[][$]CC[$][]}" material_dict["keyword"] = my_material_keyword return strip_uid_from_dict(material_dict) @@ -260,12 +259,11 @@ def complex_material_node(simple_property_node, simple_process_node, complex_com """ complex Material node with all possible attributes filled """ - my_identifier = [{"bigsmiles": "my complex_material_node"}] my_material_keyword = ["acetylene"] my_complex_material = cript.Material( name="my complex material", - identifier=my_identifier, + bigsmiles="{[][$]CC[$][]}", property=[simple_property_node], process=copy.deepcopy(simple_process_node), parent_material=simple_material_node, @@ -283,7 +281,7 @@ def simple_inventory_node(simple_material_node) -> None: """ # set up inventory node - material_2 = cript.Material(name="material 2 " + str(uuid.uuid4()), identifier=[{"bigsmiles": "my big smiles"}]) + material_2 = cript.Material(name="material 2 " + str(uuid.uuid4()), bigsmiles="{[][$]COC[$][]}") my_inventory = cript.Inventory(name="my inventory name", material=[simple_material_node, material_2]) diff --git a/tests/nodes/primary_nodes/test_inventory.py b/tests/nodes/primary_nodes/test_inventory.py index 708cb2cbf..ecb5add37 100644 --- a/tests/nodes/primary_nodes/test_inventory.py +++ b/tests/nodes/primary_nodes/test_inventory.py @@ -20,7 +20,7 @@ def test_get_and_set_inventory(simple_inventory_node) -> None: 4. assert that the materials list set and the one gotten are the same """ # create new materials - material_1 = cript.Material(name="new material 1", identifier=[{"names": ["new material 1 alternative name"]}]) + material_1 = cript.Material(name="new material 1", names=["new material 1 alternative name"]) my_notes = "my inventory notes" # set inventory @@ -49,7 +49,7 @@ def test_inventory_serialization(simple_inventory_node, simple_material_dict) -> 2. strips the UID from all the nodes within that dict 3. compares the expected_dict written to what JSON deserializes """ - expected_dict = {"node": ["Inventory"], "name": "my inventory name", "material": [simple_material_dict, {"node": ["Material"], "name": "material 2", "bigsmiles": "my big smiles"}]} + expected_dict = {"node": ["Inventory"], "name": "my inventory name", "material": [simple_material_dict, {"node": ["Material"], "name": "material 2", "bigsmiles": "{[][$]COC[$][]}"}]} # TODO this needs better testing # force not condensing to edge uuid during json serialization diff --git a/tests/nodes/primary_nodes/test_material.py b/tests/nodes/primary_nodes/test_material.py index 627eb3c04..9a858db66 100644 --- a/tests/nodes/primary_nodes/test_material.py +++ b/tests/nodes/primary_nodes/test_material.py @@ -15,34 +15,69 @@ def test_create_complex_material(cript_api, simple_material_node, simple_computa """ material_name = "my material name" - identifier = [{"bigsmiles": "1234"}, {"bigsmiles": "4567"}] keyword = ["acetylene"] material_notes = "my material notes" + amino_acid = "adenosine" + bigsmiles = "NC{[$][$]CC[$][]}" + chem_formula = "NC5" + chem_repeat = ["CC"] + chemical_id = "my chemical_id" + inchi = "my inchi" + lot_number = "lot 1" + names = ["polyethylene"] + pubchem_cid = 155 + smiles = "*CC*" + vendor = "my vendor" + inchi_key = "XLYOFNOQVPJJNP-UHFFFAOYSA-N" + component = [simple_material_node] forcefield = simple_computational_forcefield_node my_property = [cript.Property(key="modulus_shear", type="min", value=1.23, unit="gram")] - my_material = cript.Material(name=material_name, identifier=identifier, keyword=keyword, component=component, process=simple_process_node, property=my_property, computational_forcefield=forcefield, notes=material_notes) + my_material = cript.Material( + name=material_name, + keyword=keyword, + component=component, + process=simple_process_node, + property=my_property, + computational_forcefield=forcefield, + notes=material_notes, + amino_acid=amino_acid, + bigsmiles=bigsmiles, + chem_formula=chem_formula, + chemical_id=chemical_id, + chem_repeat=chem_repeat, + inchi=inchi, + inchi_key=inchi_key, + lot_number=lot_number, + names=names, + pubchem_cid=pubchem_cid, + smiles=smiles, + vendor=vendor, + ) assert isinstance(my_material, cript.Material) assert my_material.name == material_name - assert my_material.identifier == identifier assert my_material.keyword == keyword assert my_material.component == component assert my_material.process == simple_process_node assert my_material.property == my_property assert my_material.computational_forcefield == forcefield assert my_material.notes == material_notes - - -def test_invalid_material_keywords() -> None: - """ - tries to create a material with invalid keywords and expects to get an Exception - """ - # with pytest.raises(InvalidVocabulary): - pass + assert my_material.amino_acid == amino_acid + assert my_material.bigsmiles == bigsmiles + assert my_material.chem_formula == chem_formula + assert my_material.chem_repeat == chem_repeat + assert my_material.chemical_id == chemical_id + assert my_material.inchi == inchi + assert my_material.inchi_key == inchi_key + assert my_material.lot_number == lot_number + assert my_material.names == names + assert my_material.pubchem_cid == pubchem_cid + assert my_material.smiles == smiles + assert my_material.vendor == vendor def test_all_getters_and_setters(simple_material_node, simple_property_node, simple_process_node, simple_computational_forcefield_node) -> None: @@ -57,13 +92,9 @@ def test_all_getters_and_setters(simple_material_node, simple_property_node, sim new_name = "new material name" new_notes = "new material notes" - new_identifier = [{"bigsmiles": "6789"}] - new_parent_material = cript.Material( name="my parent material", - identifier=[ - {"bigsmiles": "9876"}, - ], + smiles="CC", ) new_material_keywords = ["acetylene"] @@ -71,31 +102,61 @@ def test_all_getters_and_setters(simple_material_node, simple_property_node, sim new_components = [ cript.Material( name="my component material 1", - identifier=[ - {"bigsmiles": "654321"}, - ], + smiles="CC", ), ] + amino_acid = "adenosine" + bigsmiles = "NC{[$][$]CC[$][]}" + chem_formula = "NC5" + chem_repeat = ["CC"] + chemical_id = "my chemical_id" + inchi = "my inchi" + lot_number = "lot 1" + names = ["polyethylene"] + pubchem_cid = 155 + smiles = "*CC*" + vendor = "my vendor" + # set all attributes for Material node simple_material_node.name = new_name - simple_material_node.identifier = new_identifier simple_material_node.property = [simple_property_node] simple_material_node.parent_material = new_parent_material simple_material_node.computational_forcefield = simple_computational_forcefield_node simple_material_node.keyword = new_material_keywords simple_material_node.component = new_components simple_material_node.notes = new_notes + simple_material_node.amino_acid = amino_acid + simple_material_node.bigsmiles = bigsmiles + simple_material_node.chem_formula = chem_formula + simple_material_node.chem_repeat = chem_repeat + simple_material_node.chemical_id = chemical_id + simple_material_node.inchi = inchi + simple_material_node.lot_number = lot_number + simple_material_node.names = names + simple_material_node.pubchem_cid = pubchem_cid + simple_material_node.smiles = smiles + simple_material_node.vendor = vendor # get all attributes and assert that they are equal to the setter assert simple_material_node.name == new_name - assert simple_material_node.identifier == new_identifier assert simple_material_node.property == [simple_property_node] assert simple_material_node.parent_material == new_parent_material assert simple_material_node.computational_forcefield == simple_computational_forcefield_node assert simple_material_node.keyword == new_material_keywords assert simple_material_node.component == new_components assert simple_material_node.notes == new_notes + assert simple_material_node.amino_acid == amino_acid + assert simple_material_node.bigsmiles == bigsmiles + assert simple_material_node.chem_formula == chem_formula + assert simple_material_node.chem_repeat == chem_repeat + assert simple_material_node.chemical_id == chemical_id + assert simple_material_node.inchi == inchi + assert simple_material_node.lot_number == lot_number + assert simple_material_node.names == names + assert simple_material_node.pubchem_cid == pubchem_cid + assert simple_material_node.smiles == smiles + assert simple_material_node.vendor == vendor # remove optional attributes simple_material_node.property = [] @@ -150,7 +211,7 @@ def test_integration_material(cript_api, simple_project_node, simple_material_no # ========= test update ========= # update material attribute to trigger update - simple_project_node.material[0].identifier = [{"bigsmiles": "my bigsmiles UPDATED"}] + simple_project_node.material[0].bigsmiles = "CC{[$][$]CC[$][]} UPDATED" save_integration_node_helper(cript_api=cript_api, project_node=simple_project_node) diff --git a/tests/nodes/primary_nodes/test_process.py b/tests/nodes/primary_nodes/test_process.py index ebd58774f..ee21e1aa4 100644 --- a/tests/nodes/primary_nodes/test_process.py +++ b/tests/nodes/primary_nodes/test_process.py @@ -42,7 +42,7 @@ def test_complex_process_node(complex_ingredient_node, complex_citation_node, si my_process_description = "my simple material description" process_waste = [ - cript.Material(name="my process waste material 1", identifier=[{"bigsmiles": "process waste bigsmiles"}]), + cript.Material(name="my process waste material 1", bigsmiles="process waste bigsmiles"), ] my_process_keywords = [ diff --git a/tests/nodes/test_utils.py b/tests/nodes/test_utils.py index ad5255c22..81e403701 100644 --- a/tests/nodes/test_utils.py +++ b/tests/nodes/test_utils.py @@ -47,7 +47,7 @@ def test_load_node_from_json_dict_argument() -> None: # assert material is correctly deserialized from JSON dict to Material Python object assert type(my_material_node_from_dict) == cript.Material assert my_material_node_from_dict.name == material_name - assert my_material_node_from_dict.identifier[0]["bigsmiles"] == "my bigsmiles" + assert my_material_node_from_dict.bigsmiles == "my bigsmiles" # convert UUID object to UUID str and compare assert str(my_material_node_from_dict.uuid) == material_uuid diff --git a/tests/test_node_util.py b/tests/test_node_util.py index d4e4e4551..3b03e93b1 100644 --- a/tests/test_node_util.py +++ b/tests/test_node_util.py @@ -29,8 +29,7 @@ def test_removing_nodes(simple_algorithm_node, complex_parameter_node, simple_al def test_uid_deserialization(simple_algorithm_node, complex_parameter_node, simple_algorithm_dict): - identifier = [{"bigsmiles": "123456"}] - material = cript.Material(name="my material", identifier=identifier) + material = cript.Material(name="my material", bigsmiles="{[][$]CC[$][]}") computation = cript.Computation(name="my computation name", type="analysis") property1 = cript.Property("modulus_shear", "value", 5.0, "GPa", computation=[computation]) diff --git a/tests/utils/integration_test_helper.py b/tests/utils/integration_test_helper.py index 6c319fdbe..591d70258 100644 --- a/tests/utils/integration_test_helper.py +++ b/tests/utils/integration_test_helper.py @@ -58,7 +58,7 @@ def save_integration_node_helper(cript_api: cript.API, project_node: cript.Proje my_paginator = cript_api.search(node_type=cript.Project, search_mode=cript.SearchModes.EXACT_NAME, value_to_search=project_node.name) # get the project from paginator - my_project_from_api_node = my_paginator.next() + my_project_from_api_node = next(my_paginator) print("\n\n================= API Response Node ============================") print(json.dumps(my_project_from_api_node.json, sort_keys=False, indent=2))