1010###################
1111# Create a data class domain
1212###################
13- simple_molecules_domain = api .domain .create ({
14- "kind" : "DataClass" ,
15- "domainDesign" : {
16- "name" : "SimpleMolecules" ,
17- "fields" : [
18- {"name" : "formula" , "label" : "Chemical Formula" , "rangeURI" : "string" },
19- {"name" : "molarMass" , "label" : "Molar Mass (g/mol)" , "rangeURI" : "double" },
20- ]
13+ simple_molecules_domain = api .domain .create (
14+ {
15+ "kind" : "DataClass" ,
16+ "domainDesign" : {
17+ "name" : "SimpleMolecules" ,
18+ "fields" : [
19+ {"name" : "formula" , "label" : "Chemical Formula" , "rangeURI" : "string" },
20+ {"name" : "molarMass" , "label" : "Molar Mass (g/mol)" , "rangeURI" : "double" },
21+ ],
22+ },
2123 }
22- } )
24+ )
2325
24- api .query .insert_rows ("exp.data" , "SimpleMolecules" , [
25- {"name" : "Water" , "formula" : "H20" , "molarMass" : 18.01528 },
26- {"name" : "Salt" , "formula" : "NaCl" , "molarMass" : 58.443 }
27- ])
26+ api .query .insert_rows (
27+ "exp.data" ,
28+ "SimpleMolecules" ,
29+ [
30+ {"name" : "Water" , "formula" : "H20" , "molarMass" : 18.01528 },
31+ {"name" : "Salt" , "formula" : "NaCl" , "molarMass" : 58.443 },
32+ ],
33+ )
2834
2935###################
3036# Create a second data class domain
3137###################
32- substances_domain = api .domain .create ({
33- "kind" : "DataClass" ,
34- "domainDesign" : {
35- "name" : "Substances" ,
36- "fields" : [
37- {"name" : "type" , "rangeURI" : "string" },
38- {"name" : "fromNature" , "rangeURI" : "boolean" },
39- ]
38+ substances_domain = api .domain .create (
39+ {
40+ "kind" : "DataClass" ,
41+ "domainDesign" : {
42+ "name" : "Substances" ,
43+ "fields" : [
44+ {"name" : "type" , "rangeURI" : "string" },
45+ {"name" : "fromNature" , "rangeURI" : "boolean" },
46+ ],
47+ },
4048 }
41- })
42-
43- api .query .insert_rows ("exp.data" , "Substances" , [
44- {"name" : "Ocean Water" , "type" : "liquid" , "fromNature" : True , "DataInputs/SimpleMolecules" : "Water, Salt" },
45- {"name" : "Bath Water" , "type" : "liquid" , "fromNature" : False , "DataInputs/SimpleMolecules" : "Water" }
46- ])
49+ )
50+
51+ api .query .insert_rows (
52+ "exp.data" ,
53+ "Substances" ,
54+ [
55+ {
56+ "name" : "Ocean Water" ,
57+ "type" : "liquid" ,
58+ "fromNature" : True ,
59+ "DataInputs/SimpleMolecules" : "Water, Salt" ,
60+ },
61+ {
62+ "name" : "Bath Water" ,
63+ "type" : "liquid" ,
64+ "fromNature" : False ,
65+ "DataInputs/SimpleMolecules" : "Water" ,
66+ },
67+ ],
68+ )
4769
4870###################
4971# Create a sample type domain
5072###################
51- field_samples_domain = api .domain .create ({
52- "kind" : "SampleSet" ,
53- "domainDesign" : {
54- "name" : "FieldSamples" ,
55- "fields" : [
56- {"name" : "name" , "rangeURI" : "string" },
57- {"name" : "receivedDate" , "rangeURI" : "dateTime" },
58- {"name" : "volume_mL" , "rangeURI" : "int" },
59- ]
73+ field_samples_domain = api .domain .create (
74+ {
75+ "kind" : "SampleSet" ,
76+ "domainDesign" : {
77+ "name" : "FieldSamples" ,
78+ "fields" : [
79+ {"name" : "name" , "rangeURI" : "string" },
80+ {"name" : "receivedDate" , "rangeURI" : "dateTime" },
81+ {"name" : "volume_mL" , "rangeURI" : "int" },
82+ ],
83+ },
6084 }
61- })
62-
63- api .query .insert_rows ("samples" , "FieldSamples" , [
64- {"name" : "OC-1" , "receivedDate" : "05/12/2025" , "volume_mL" : 400 , "DataInputs/Substances" : "Ocean Water" },
65- {"name" : "OC-2" , "receivedDate" : "05/13/2025" , "volume_mL" : 600 , "DataInputs/Substances" : "Ocean Water" },
66- {"name" : "OC-3" , "receivedDate" : "05/14/2025" , "volume_mL" : 800 , "DataInputs/Substances" : "Ocean Water" },
67-
68- {"name" : "BW-1" , "receivedDate" : "05/12/2025" , "volume_mL" : 400 , "DataInputs/Substances" : "Bath Water" },
69- {"name" : "BW-2" , "receivedDate" : "05/13/2025" , "volume_mL" : 600 , "DataInputs/Substances" : "Bath Water" },
70- {"name" : "BW-3" , "receivedDate" : "05/14/2025" , "volume_mL" : 800 , "DataInputs/Substances" : "Bath Water" },
71-
72- {"name" : "Mixed-1" , "receivedDate" : "05/18/2025" , "volume_mL" : 50 , "DataInputs/Substances" : "\" Bath Water\" , \" Ocean Water\" " },
73- ])
85+ )
86+
87+ api .query .insert_rows (
88+ "samples" ,
89+ "FieldSamples" ,
90+ [
91+ {
92+ "name" : "OC-1" ,
93+ "receivedDate" : "05/12/2025" ,
94+ "volume_mL" : 400 ,
95+ "DataInputs/Substances" : "Ocean Water" ,
96+ },
97+ {
98+ "name" : "OC-2" ,
99+ "receivedDate" : "05/13/2025" ,
100+ "volume_mL" : 600 ,
101+ "DataInputs/Substances" : "Ocean Water" ,
102+ },
103+ {
104+ "name" : "OC-3" ,
105+ "receivedDate" : "05/14/2025" ,
106+ "volume_mL" : 800 ,
107+ "DataInputs/Substances" : "Ocean Water" ,
108+ },
109+ {
110+ "name" : "BW-1" ,
111+ "receivedDate" : "05/12/2025" ,
112+ "volume_mL" : 400 ,
113+ "DataInputs/Substances" : "Bath Water" ,
114+ },
115+ {
116+ "name" : "BW-2" ,
117+ "receivedDate" : "05/13/2025" ,
118+ "volume_mL" : 600 ,
119+ "DataInputs/Substances" : "Bath Water" ,
120+ },
121+ {
122+ "name" : "BW-3" ,
123+ "receivedDate" : "05/14/2025" ,
124+ "volume_mL" : 800 ,
125+ "DataInputs/Substances" : "Bath Water" ,
126+ },
127+ {
128+ "name" : "Mixed-1" ,
129+ "receivedDate" : "05/18/2025" ,
130+ "volume_mL" : 50 ,
131+ "DataInputs/Substances" : '"Bath Water", "Ocean Water"' ,
132+ },
133+ ],
134+ )
74135
75136###################
76137# Query the lineage
82143entity_name = "Ocean Water"
83144
84145# Fetch the LSID of the "seed" for the lineage request. In this case, we'll query for the "Ocean Water" entity in Substances.
85- result = api .query .select_rows (schema_name , query_name , columns = "Name, LSID" , filter_array = [QueryFilter ("name" , entity_name )])
146+ result = api .query .select_rows (
147+ schema_name , query_name , columns = "Name, LSID" , filter_array = [QueryFilter ("name" , entity_name )]
148+ )
86149seed_lsid = result ["rows" ][0 ]["LSID" ]
87150
88151# Lineage results includes the following:
94157# "children": An aray of objects representing edges in the graph to nodes to which this node refers.
95158lineage_result = api .experiment .lineage ([seed_lsid ], depth = 10 )
96159
160+
97161###################
98162# Traverse the lineage
99163###################
@@ -114,9 +178,11 @@ def process_edges(edges, offset):
114178 for edge in edges :
115179 related_lsid = edge ["lsid" ]
116180 related_node = lineage_result ["nodes" ][related_lsid ]
117- nodes_by_depth [new_depth ].add (related_node [' name' ])
181+ nodes_by_depth [new_depth ].add (related_node [" name" ])
118182
119- traverse_lineage (related_lsid , lineage_result , new_depth , visited .copy (), nodes_by_depth )
183+ traverse_lineage (
184+ related_lsid , lineage_result , new_depth , visited .copy (), nodes_by_depth
185+ )
120186
121187 process_edges (node .get ("parents" , []), - 1 )
122188 process_edges (node .get ("children" , []), 1 )
0 commit comments