diff --git a/config.yml b/config.yml index 7358d270..e10322fe 100644 --- a/config.yml +++ b/config.yml @@ -66,3 +66,5 @@ notebooks: packages_common: - mat3ra-standata - exabyte-api-client + - mat3ra-ade + - mat3ra-wode diff --git a/other/materials_designer/uploads/0-Ni.json b/other/materials_designer/uploads/0-Ni.json index 2adc9475..cd92b2d0 100644 --- a/other/materials_designer/uploads/0-Ni.json +++ b/other/materials_designer/uploads/0-Ni.json @@ -54,7 +54,7 @@ }, "external": { "id": "mp-23", - "source": "Materials Project", + "source": "MaterialsProject", "doi": "10.17188/1199153", "url": "https://next-gen.materialsproject.org/materials/mp-23", "origin": true diff --git a/other/materials_designer/uploads/MoS2(001)-MoS2(001), Interface.json b/other/materials_designer/uploads/MoS2(001)-MoS2(001), Interface.json new file mode 100644 index 00000000..41cd91a3 --- /dev/null +++ b/other/materials_designer/uploads/MoS2(001)-MoS2(001), Interface.json @@ -0,0 +1 @@ +{"description": null, "descriptionObject": null, "metadata": {"build": [{"configuration": {"stack_components": [{"xy_supercell_matrix": [[-3, -1], [-2, -3]], "strain_matrix": [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]], "stack_components": [{"termination_top": {"chemical_elements": "S", "space_group_symmetry_label": "P6/mmm_1"}, "number_of_repetitions": 1, "miller_indices": [0, 0, 1], "crystal": {"description": null, "descriptionObject": null, "metadata": {"build": [], "boundaryConditions": {"type": "pbc", "offset": 0}}, "name": "Mo1 S2", "isDefault": false, "formula": null, "unitCellFormula": null, "basis": {"elements": [{"id": 0, "value": "Mo"}, {"id": 1, "value": "S"}, {"id": 2, "value": "S"}], "coordinates": [{"id": 0, "value": [0.666666667, 0.333333333, 0.5]}, {"id": 1, "value": [0.333333333, 0.666666667, 0.432137]}, {"id": 2, "value": [0.333333333, 0.666666667, 0.567863]}], "units": "crystal", "labels": [], "constraints": []}, "lattice": {"a": 3.196223, "b": 3.196223, "c": 23.12983, "alpha": 90.0, "beta": 90.0, "gamma": 120.0, "units": {"length": "angstrom", "angle": "degree"}, "type": "TRI"}, "derivedProperties": null, "external": null, "src": null, "scaledHash": null, "icsdId": null, "isNonPeriodic": false, "consistencyChecks": null, "field_id": null, "slug": null, "systemName": null, "schemaVersion": "2022.8.16"}, "use_conventional_cell": true, "termination_bottom": {"chemical_elements": "S", "space_group_symmetry_label": "P6/mmm_1"}}, {"direction": "z", "size": 20.0, "crystal": {"description": null, "descriptionObject": null, "metadata": {"build": [{"configuration": {"termination_top": {"chemical_elements": "S", "space_group_symmetry_label": "P6/mmm_1"}, "number_of_repetitions": 1, "miller_indices": [0, 0, 1], "crystal": {"description": null, "descriptionObject": null, "metadata": {"build": [], "boundaryConditions": {"type": "pbc", "offset": 0}}, "name": "Mo1 S2", "isDefault": false, "formula": null, "unitCellFormula": null, "basis": {"elements": [{"id": 0, "value": "Mo"}, {"id": 1, "value": "S"}, {"id": 2, "value": "S"}], "coordinates": [{"id": 0, "value": [0.666666667, 0.333333333, 0.5]}, {"id": 1, "value": [0.333333333, 0.666666667, 0.432137]}, {"id": 2, "value": [0.333333333, 0.666666667, 0.567863]}], "units": "crystal", "labels": [], "constraints": []}, "lattice": {"a": 3.196223, "b": 3.196223, "c": 23.12983, "alpha": 90.0, "beta": 90.0, "gamma": 120.0, "units": {"length": "angstrom", "angle": "degree"}, "type": "TRI"}, "derivedProperties": null, "external": null, "src": null, "scaledHash": null, "icsdId": null, "isNonPeriodic": false, "consistencyChecks": null, "field_id": null, "slug": null, "systemName": null, "schemaVersion": "2022.8.16"}, "use_conventional_cell": true, "termination_bottom": {"chemical_elements": "S", "space_group_symmetry_label": "P6/mmm_1"}}, "build_parameters": {}}], "boundaryConditions": {"type": "pbc", "offset": 0}}, "name": "MoS2(001), termination S_P6/mmm_1", "isDefault": false, "formula": "MoS2", "unitCellFormula": null, "basis": {"elements": [{"id": 0, "value": "Mo"}, {"id": 1, "value": "S"}, {"id": 2, "value": "S"}], "coordinates": [{"id": 0, "value": [0.666666667, 0.333333333, 0.067864]}, {"id": 1, "value": [0.333333333, 0.666666667, 1e-06]}, {"id": 2, "value": [0.333333333, 0.666666667, 0.135727]}], "units": "crystal", "labels": [], "constraints": []}, "lattice": {"a": 3.196223, "b": 3.196223, "c": 23.12983, "alpha": 90.0, "beta": 90.0, "gamma": 120.0, "units": {"length": "angstrom", "angle": "degree"}, "type": "TRI"}, "derivedProperties": null, "external": null, "src": null, "scaledHash": null, "icsdId": null, "isNonPeriodic": false, "consistencyChecks": null, "field_id": null, "slug": null, "systemName": null, "schemaVersion": "2022.8.16"}, "type": "VacuumConfiguration"}], "direction": "z", "gaps": [], "type": "SlabConfiguration", "termination_top": null, "termination_bottom": null}, {"xy_supercell_matrix": [[-3, -2], [-1, -3]], "strain_matrix": [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]], "stack_components": [{"termination_top": {"chemical_elements": "S", "space_group_symmetry_label": "P6/mmm_1"}, "number_of_repetitions": 1, "miller_indices": [0, 0, 1], "crystal": {"description": null, "descriptionObject": null, "metadata": {"build": [], "boundaryConditions": {"type": "pbc", "offset": 0}}, "name": "Mo1 S2", "isDefault": false, "formula": null, "unitCellFormula": null, "basis": {"elements": [{"id": 0, "value": "Mo"}, {"id": 1, "value": "S"}, {"id": 2, "value": "S"}], "coordinates": [{"id": 0, "value": [0.666666667, 0.333333333, 0.5]}, {"id": 1, "value": [0.333333333, 0.666666667, 0.432137]}, {"id": 2, "value": [0.333333333, 0.666666667, 0.567863]}], "units": "crystal", "labels": [], "constraints": []}, "lattice": {"a": 3.196223, "b": 3.196223, "c": 23.12983, "alpha": 90.0, "beta": 90.0, "gamma": 120.0, "units": {"length": "angstrom", "angle": "degree"}, "type": "TRI"}, "derivedProperties": null, "external": null, "src": null, "scaledHash": null, "icsdId": null, "isNonPeriodic": false, "consistencyChecks": null, "field_id": null, "slug": null, "systemName": null, "schemaVersion": "2022.8.16"}, "use_conventional_cell": true, "termination_bottom": {"chemical_elements": "S", "space_group_symmetry_label": "P6/mmm_1"}}, {"direction": "z", "size": 20.0, "crystal": {"description": null, "descriptionObject": null, "metadata": {"build": [{"configuration": {"termination_top": {"chemical_elements": "S", "space_group_symmetry_label": "P6/mmm_1"}, "number_of_repetitions": 1, "miller_indices": [0, 0, 1], "crystal": {"description": null, "descriptionObject": null, "metadata": {"build": [], "boundaryConditions": {"type": "pbc", "offset": 0}}, "name": "Mo1 S2", "isDefault": false, "formula": null, "unitCellFormula": null, "basis": {"elements": [{"id": 0, "value": "Mo"}, {"id": 1, "value": "S"}, {"id": 2, "value": "S"}], "coordinates": [{"id": 0, "value": [0.666666667, 0.333333333, 0.5]}, {"id": 1, "value": [0.333333333, 0.666666667, 0.432137]}, {"id": 2, "value": [0.333333333, 0.666666667, 0.567863]}], "units": "crystal", "labels": [], "constraints": []}, "lattice": {"a": 3.196223, "b": 3.196223, "c": 23.12983, "alpha": 90.0, "beta": 90.0, "gamma": 120.0, "units": {"length": "angstrom", "angle": "degree"}, "type": "TRI"}, "derivedProperties": null, "external": null, "src": null, "scaledHash": null, "icsdId": null, "isNonPeriodic": false, "consistencyChecks": null, "field_id": null, "slug": null, "systemName": null, "schemaVersion": "2022.8.16"}, "use_conventional_cell": true, "termination_bottom": {"chemical_elements": "S", "space_group_symmetry_label": "P6/mmm_1"}}, "build_parameters": {}}], "boundaryConditions": {"type": "pbc", "offset": 0}}, "name": "MoS2(001), termination S_P6/mmm_1", "isDefault": false, "formula": "MoS2", "unitCellFormula": null, "basis": {"elements": [{"id": 0, "value": "Mo"}, {"id": 1, "value": "S"}, {"id": 2, "value": "S"}], "coordinates": [{"id": 0, "value": [0.666666667, 0.333333333, 0.067864]}, {"id": 1, "value": [0.333333333, 0.666666667, 1e-06]}, {"id": 2, "value": [0.333333333, 0.666666667, 0.135727]}], "units": "crystal", "labels": [], "constraints": []}, "lattice": {"a": 3.196223, "b": 3.196223, "c": 23.12983, "alpha": 90.0, "beta": 90.0, "gamma": 120.0, "units": {"length": "angstrom", "angle": "degree"}, "type": "TRI"}, "derivedProperties": null, "external": null, "src": null, "scaledHash": null, "icsdId": null, "isNonPeriodic": false, "consistencyChecks": null, "field_id": null, "slug": null, "systemName": null, "schemaVersion": "2022.8.16"}, "type": "VacuumConfiguration"}], "direction": "z", "gaps": [], "type": "SlabConfiguration", "termination_top": null, "termination_bottom": null}, {"direction": "z", "size": 20.0, "crystal": {"description": null, "descriptionObject": null, "metadata": {"build": [{"configuration": {"xy_supercell_matrix": [[-3, -1], [-2, -3]], "strain_matrix": [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]], "stack_components": [{"termination_top": {"chemical_elements": "S", "space_group_symmetry_label": "P6/mmm_1"}, "number_of_repetitions": 1, "miller_indices": [0, 0, 1], "crystal": {"description": null, "descriptionObject": null, "metadata": {"build": [], "boundaryConditions": {"type": "pbc", "offset": 0}}, "name": "Mo1 S2", "isDefault": false, "formula": null, "unitCellFormula": null, "basis": {"elements": [{"id": 0, "value": "Mo"}, {"id": 1, "value": "S"}, {"id": 2, "value": "S"}], "coordinates": [{"id": 0, "value": [0.666666667, 0.333333333, 0.5]}, {"id": 1, "value": [0.333333333, 0.666666667, 0.432137]}, {"id": 2, "value": [0.333333333, 0.666666667, 0.567863]}], "units": "crystal", "labels": [], "constraints": []}, "lattice": {"a": 3.196223, "b": 3.196223, "c": 23.12983, "alpha": 90.0, "beta": 90.0, "gamma": 120.0, "units": {"length": "angstrom", "angle": "degree"}, "type": "TRI"}, "derivedProperties": null, "external": null, "src": null, "scaledHash": null, "icsdId": null, "isNonPeriodic": false, "consistencyChecks": null, "field_id": null, "slug": null, "systemName": null, "schemaVersion": "2022.8.16"}, "use_conventional_cell": true, "termination_bottom": {"chemical_elements": "S", "space_group_symmetry_label": "P6/mmm_1"}}, {"direction": "z", "size": 20.0, "crystal": {"description": null, "descriptionObject": null, "metadata": {"build": [{"configuration": {"termination_top": {"chemical_elements": "S", "space_group_symmetry_label": "P6/mmm_1"}, "number_of_repetitions": 1, "miller_indices": [0, 0, 1], "crystal": {"description": null, "descriptionObject": null, "metadata": {"build": [], "boundaryConditions": {"type": "pbc", "offset": 0}}, "name": "Mo1 S2", "isDefault": false, "formula": null, "unitCellFormula": null, "basis": {"elements": [{"id": 0, "value": "Mo"}, {"id": 1, "value": "S"}, {"id": 2, "value": "S"}], "coordinates": [{"id": 0, "value": [0.666666667, 0.333333333, 0.5]}, {"id": 1, "value": [0.333333333, 0.666666667, 0.432137]}, {"id": 2, "value": [0.333333333, 0.666666667, 0.567863]}], "units": "crystal", "labels": [], "constraints": []}, "lattice": {"a": 3.196223, "b": 3.196223, "c": 23.12983, "alpha": 90.0, "beta": 90.0, "gamma": 120.0, "units": {"length": "angstrom", "angle": "degree"}, "type": "TRI"}, "derivedProperties": null, "external": null, "src": null, "scaledHash": null, "icsdId": null, "isNonPeriodic": false, "consistencyChecks": null, "field_id": null, "slug": null, "systemName": null, "schemaVersion": "2022.8.16"}, "use_conventional_cell": true, "termination_bottom": {"chemical_elements": "S", "space_group_symmetry_label": "P6/mmm_1"}}, "build_parameters": {}}], "boundaryConditions": {"type": "pbc", "offset": 0}}, "name": "MoS2(001), termination S_P6/mmm_1", "isDefault": false, "formula": "MoS2", "unitCellFormula": null, "basis": {"elements": [{"id": 0, "value": "Mo"}, {"id": 1, "value": "S"}, {"id": 2, "value": "S"}], "coordinates": [{"id": 0, "value": [0.666666667, 0.333333333, 0.067864]}, {"id": 1, "value": [0.333333333, 0.666666667, 1e-06]}, {"id": 2, "value": [0.333333333, 0.666666667, 0.135727]}], "units": "crystal", "labels": [], "constraints": []}, "lattice": {"a": 3.196223, "b": 3.196223, "c": 23.12983, "alpha": 90.0, "beta": 90.0, "gamma": 120.0, "units": {"length": "angstrom", "angle": "degree"}, "type": "TRI"}, "derivedProperties": null, "external": null, "src": null, "scaledHash": null, "icsdId": null, "isNonPeriodic": false, "consistencyChecks": null, "field_id": null, "slug": null, "systemName": null, "schemaVersion": "2022.8.16"}, "type": "VacuumConfiguration"}], "direction": "z", "gaps": [], "type": "SlabConfiguration", "termination_top": null, "termination_bottom": null}, "build_parameters": {"use_orthogonal_c": true, "xy_supercell_matrix": [[1, 0], [0, 1]]}}], "boundaryConditions": {"type": "pbc", "offset": 0}}, "name": "MoS2(001), termination S_P6/mmm_1, Slab", "isDefault": false, "formula": "MoS2", "unitCellFormula": null, "basis": {"elements": [{"id": 0, "value": "Mo"}, {"id": 1, "value": "S"}, {"id": 2, "value": "S"}, {"id": 3, "value": "Mo"}, {"id": 4, "value": "S"}, {"id": 5, "value": "S"}, {"id": 6, "value": "Mo"}, {"id": 7, "value": "S"}, {"id": 8, "value": "S"}, {"id": 9, "value": "Mo"}, {"id": 10, "value": "S"}, {"id": 11, "value": "S"}, {"id": 12, "value": "Mo"}, {"id": 13, "value": "S"}, {"id": 14, "value": "S"}, {"id": 15, "value": "Mo"}, {"id": 16, "value": "S"}, {"id": 17, "value": "S"}, {"id": 18, "value": "Mo"}, {"id": 19, "value": "S"}, {"id": 20, "value": "S"}], "coordinates": [{"id": 0, "value": [0.666666666, 0.666666667, 0.036394365]}, {"id": 1, "value": [0.904761905, 0.476190476, 5.36e-07]}, {"id": 2, "value": [0.904761905, 0.476190476, 0.072788194]}, {"id": 3, "value": [0.238095238, 0.80952381, 0.036394365]}, {"id": 4, "value": [0.476190476, 0.619047619, 5.36e-07]}, {"id": 5, "value": [0.476190476, 0.619047619, 0.072788194]}, {"id": 6, "value": [0.523809524, 0.380952381, 0.036394365]}, {"id": 7, "value": [0.761904762, 0.19047619, 5.36e-07]}, {"id": 8, "value": [0.761904762, 0.19047619, 0.072788194]}, {"id": 9, "value": [0.095238095, 0.523809524, 0.036394365]}, {"id": 10, "value": [0.333333334, 0.333333333, 5.36e-07]}, {"id": 11, "value": [0.333333334, 0.333333333, 0.072788194]}, {"id": 12, "value": [0.380952381, 0.095238095, 0.036394365]}, {"id": 13, "value": [0.619047619, 0.904761905, 5.36e-07]}, {"id": 14, "value": [0.619047619, 0.904761905, 0.072788194]}, {"id": 15, "value": [0.952380952, 0.238095238, 0.036394365]}, {"id": 16, "value": [0.190476191, 0.047619047, 5.36e-07]}, {"id": 17, "value": [0.190476191, 0.047619047, 0.072788194]}, {"id": 18, "value": [0.809523809, 0.952380953, 0.036394365]}, {"id": 19, "value": [0.047619048, 0.761904762, 5.36e-07]}, {"id": 20, "value": [0.047619048, 0.761904762, 0.072788194]}], "units": "crystal", "labels": [{"id": 0, "value": 0}, {"id": 1, "value": 0}, {"id": 2, "value": 0}, {"id": 3, "value": 0}, {"id": 4, "value": 0}, {"id": 5, "value": 0}, {"id": 6, "value": 0}, {"id": 7, "value": 0}, {"id": 8, "value": 0}, {"id": 9, "value": 0}, {"id": 10, "value": 0}, {"id": 11, "value": 0}, {"id": 12, "value": 0}, {"id": 13, "value": 0}, {"id": 14, "value": 0}, {"id": 15, "value": 0}, {"id": 16, "value": 0}, {"id": 17, "value": 0}, {"id": 18, "value": 0}, {"id": 19, "value": 0}, {"id": 20, "value": 0}], "constraints": []}, "lattice": {"a": 8.456411193, "b": 8.456411193, "c": 43.12983, "alpha": 90.0, "beta": 90.0, "gamma": 59.999999999999986, "units": {"length": "angstrom", "angle": "degree"}, "type": "TRI"}, "derivedProperties": null, "external": null, "src": null, "scaledHash": null, "icsdId": null, "isNonPeriodic": false, "consistencyChecks": null, "field_id": null, "slug": null, "systemName": null, "schemaVersion": "2022.8.16"}, "type": "VacuumConfiguration"}], "direction": "z", "xy_shift": [0.0, 0.0], "gaps": [{"id": 0, "value": 6.5}, {"id": 1, "value": 6.5}], "type": "InterfaceConfiguration"}, "build_parameters": {"make_primitive": true}}], "boundaryConditions": {"type": "pbc", "offset": 0}}, "name": "MoS2(001)-MoS2(001), Interface", "isDefault": false, "formula": null, "unitCellFormula": null, "basis": {"elements": [{"id": 0, "value": "Mo"}, {"id": 1, "value": "S"}, {"id": 2, "value": "S"}, {"id": 3, "value": "Mo"}, {"id": 4, "value": "S"}, {"id": 5, "value": "S"}, {"id": 6, "value": "Mo"}, {"id": 7, "value": "S"}, {"id": 8, "value": "S"}, {"id": 9, "value": "Mo"}, {"id": 10, "value": "S"}, {"id": 11, "value": "S"}, {"id": 12, "value": "Mo"}, {"id": 13, "value": "S"}, {"id": 14, "value": "S"}, {"id": 15, "value": "Mo"}, {"id": 16, "value": "S"}, {"id": 17, "value": "S"}, {"id": 18, "value": "Mo"}, {"id": 19, "value": "S"}, {"id": 20, "value": "S"}, {"id": 21, "value": "Mo"}, {"id": 22, "value": "S"}, {"id": 23, "value": "S"}, {"id": 24, "value": "Mo"}, {"id": 25, "value": "S"}, {"id": 26, "value": "S"}, {"id": 27, "value": "Mo"}, {"id": 28, "value": "S"}, {"id": 29, "value": "S"}, {"id": 30, "value": "Mo"}, {"id": 31, "value": "S"}, {"id": 32, "value": "S"}, {"id": 33, "value": "Mo"}, {"id": 34, "value": "S"}, {"id": 35, "value": "S"}, {"id": 36, "value": "Mo"}, {"id": 37, "value": "S"}, {"id": 38, "value": "S"}, {"id": 39, "value": "Mo"}, {"id": 40, "value": "S"}, {"id": 41, "value": "S"}], "coordinates": [{"id": 0, "value": [0.666666666, 0.666666667, 0.039962712]}, {"id": 1, "value": [0.904761905, 0.476190476, 5.88e-07]}, {"id": 2, "value": [0.904761905, 0.476190476, 0.079924836]}, {"id": 3, "value": [0.238095238, 0.80952381, 0.039962712]}, {"id": 4, "value": [0.476190476, 0.619047619, 5.88e-07]}, {"id": 5, "value": [0.476190476, 0.619047619, 0.079924836]}, {"id": 6, "value": [0.523809524, 0.380952381, 0.039962712]}, {"id": 7, "value": [0.761904762, 0.19047619, 5.88e-07]}, {"id": 8, "value": [0.761904762, 0.19047619, 0.079924836]}, {"id": 9, "value": [0.095238095, 0.523809524, 0.039962712]}, {"id": 10, "value": [0.333333334, 0.333333333, 5.88e-07]}, {"id": 11, "value": [0.333333334, 0.333333333, 0.079924836]}, {"id": 12, "value": [0.380952381, 0.095238095, 0.039962712]}, {"id": 13, "value": [0.619047619, 0.904761905, 5.88e-07]}, {"id": 14, "value": [0.619047619, 0.904761905, 0.079924836]}, {"id": 15, "value": [0.952380952, 0.238095238, 0.039962712]}, {"id": 16, "value": [0.190476191, 0.047619047, 5.88e-07]}, {"id": 17, "value": [0.190476191, 0.047619047, 0.079924836]}, {"id": 18, "value": [0.809523809, 0.952380953, 0.039962712]}, {"id": 19, "value": [0.047619048, 0.761904762, 5.88e-07]}, {"id": 20, "value": [0.047619048, 0.761904762, 0.079924836]}, {"id": 21, "value": [0.476190476, 0.904761905, 0.285371704]}, {"id": 22, "value": [0.666666667, 0.666666666, 0.24540958]}, {"id": 23, "value": [0.666666667, 0.666666666, 0.325333827]}, {"id": 24, "value": [0.619047619, 0.476190476, 0.285371704]}, {"id": 25, "value": [0.80952381, 0.238095238, 0.24540958]}, {"id": 26, "value": [0.80952381, 0.238095238, 0.325333827]}, {"id": 27, "value": [0.19047619, 0.761904762, 0.285371704]}, {"id": 28, "value": [0.380952381, 0.523809524, 0.24540958]}, {"id": 29, "value": [0.380952381, 0.523809524, 0.325333827]}, {"id": 30, "value": [0.333333333, 0.333333334, 0.285371704]}, {"id": 31, "value": [0.523809524, 0.095238095, 0.24540958]}, {"id": 32, "value": [0.523809524, 0.095238095, 0.325333827]}, {"id": 33, "value": [0.904761905, 0.619047619, 0.285371704]}, {"id": 34, "value": [0.095238095, 0.380952381, 0.24540958]}, {"id": 35, "value": [0.095238095, 0.380952381, 0.325333827]}, {"id": 36, "value": [0.047619047, 0.190476191, 0.285371704]}, {"id": 37, "value": [0.238095238, 0.952380952, 0.24540958]}, {"id": 38, "value": [0.238095238, 0.952380952, 0.325333827]}, {"id": 39, "value": [0.761904762, 0.047619048, 0.285371704]}, {"id": 40, "value": [0.952380953, 0.809523809, 0.24540958]}, {"id": 41, "value": [0.952380953, 0.809523809, 0.325333827]}], "units": "crystal", "labels": [{"id": 0, "value": 0}, {"id": 1, "value": 0}, {"id": 2, "value": 0}, {"id": 3, "value": 0}, {"id": 4, "value": 0}, {"id": 5, "value": 0}, {"id": 6, "value": 0}, {"id": 7, "value": 0}, {"id": 8, "value": 0}, {"id": 9, "value": 0}, {"id": 10, "value": 0}, {"id": 11, "value": 0}, {"id": 12, "value": 0}, {"id": 13, "value": 0}, {"id": 14, "value": 0}, {"id": 15, "value": 0}, {"id": 16, "value": 0}, {"id": 17, "value": 0}, {"id": 18, "value": 0}, {"id": 19, "value": 0}, {"id": 20, "value": 0}, {"id": 21, "value": 1}, {"id": 22, "value": 1}, {"id": 23, "value": 1}, {"id": 24, "value": 1}, {"id": 25, "value": 1}, {"id": 26, "value": 1}, {"id": 27, "value": 1}, {"id": 28, "value": 1}, {"id": 29, "value": 1}, {"id": 30, "value": 1}, {"id": 31, "value": 1}, {"id": 32, "value": 1}, {"id": 33, "value": 1}, {"id": 34, "value": 1}, {"id": 35, "value": 1}, {"id": 36, "value": 1}, {"id": 37, "value": 1}, {"id": 38, "value": 1}, {"id": 39, "value": 1}, {"id": 40, "value": 1}, {"id": 41, "value": 1}], "constraints": []}, "lattice": {"a": 8.456411193, "b": 8.456411193, "c": 39.278684866, "alpha": 90.0, "beta": 90.0, "gamma": 60.0, "units": {"length": "angstrom", "angle": "degree"}, "type": "TRI"}, "derivedProperties": null, "external": null, "src": null, "scaledHash": null, "icsdId": null, "isNonPeriodic": false, "consistencyChecks": null, "field_id": null, "slug": null, "systemName": null, "schemaVersion": "2022.8.16"} \ No newline at end of file diff --git a/other/materials_designer/workflows/run_bandgap_workflow_max.ipynb b/other/materials_designer/workflows/run_bandgap_workflow_max.ipynb new file mode 100644 index 00000000..a307b174 --- /dev/null +++ b/other/materials_designer/workflows/run_bandgap_workflow_max.ipynb @@ -0,0 +1,413 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "0", + "metadata": {}, + "source": [ + "# Bandgap Workflow Example\n", + " This notebook demonstrates how to build and run a bandgap workflow for a material.\n", + " Example of building and running a bandgap workflow for twisted MoS2 interface from specific_examples.\n", + "\n", + "## Process Overview\n", + "### 1. Set up the environment and parameters.\n", + "### 2. Log in to get the API token\n", + "### 3. Load the target material.\n", + "### 4. Import workflow builder and related analyzers.\n", + "### 5. Analyze material to get parameters for the workflow configuration.\n", + "### 6. Create the workflow configuration.\n", + "### 7. Create a job with material and workflow configuration.\n", + "### 8. Submit the job to the server.\n", + "### 9. Monitor the job status and retrieve results.\n", + "### 10. Display the results." + ] + }, + { + "cell_type": "markdown", + "id": "1", + "metadata": {}, + "source": [ + "## 1. Set up the environment and parameters" + ] + }, + { + "cell_type": "markdown", + "id": "2", + "metadata": {}, + "source": [ + "## 2. Log in to get the API token" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3", + "metadata": {}, + "outputs": [], + "source": [ + "from mat3ra.api import ApiClient\n", + "\n", + "# Log in to get the API token\n", + "auth_config = await ApiClient().login()" + ] + }, + { + "cell_type": "markdown", + "id": "4", + "metadata": {}, + "source": [ + "## 3. Load the target material" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5", + "metadata": {}, + "outputs": [], + "source": [ + "from utils.visualize import visualize_materials as visualize\n", + "from utils.jupyterlite import load_material_from_folder\n", + "\n", + "material = load_material_from_folder(\"/uploads\", \"MoS2_twisted_interface_60_degrees.json\")\n", + "visualize(material)" + ] + }, + { + "cell_type": "markdown", + "id": "6", + "metadata": {}, + "source": [ + "## 5. Create workflow and set its parameters\n", + "### 5.1. Get list of applications and select one" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7", + "metadata": {}, + "outputs": [], + "source": [ + "from mat3ra.standata.applications import ApplicationStandata\n", + "\n", + "# Get Applications list (with versions, build)\n", + "apps_list = ApplicationStandata.list_all()\n", + "# returns apps_list[0] = [{\"name\" : \"espresso\", \"version\": \"7.2\", \"build\": \"GNU\"}]\n", + "\n", + "app = ApplicationStandata.get_by_name_first_match(\"espresso\")\n", + "# returns name, version, build config" + ] + }, + { + "cell_type": "markdown", + "id": "8", + "metadata": {}, + "source": [ + "### 5.2. Create workflow from standard workflows and preview it" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9", + "metadata": {}, + "outputs": [], + "source": [ + "from mat3ra.standata.workflows import WorkflowStandata\n", + "from mat3ra.wode.workflows import Workflow\n", + "from utils.visualize import visualize_workflow\n", + "\n", + "# Search WF by name and application\n", + "workflow_config = WorkflowStandata.filter_by_application(app).get_by_name_first_match(\"band_gap\")\n", + "workflow = Workflow.create(workflow_config)\n", + "\n", + "# View workflow to understand its structure\n", + "visualize_workflow(workflow)" + ] + }, + { + "cell_type": "markdown", + "id": "10", + "metadata": {}, + "source": [ + "### 5.3. Add relaxation subworkflow" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "11", + "metadata": {}, + "outputs": [], + "source": [ + "workflow.add_relaxation()\n", + "visualize_workflow(workflow)\n", + "# Relaxation subworkflow is added as the first subworkflow" + ] + }, + { + "cell_type": "markdown", + "id": "12", + "metadata": {}, + "source": [ + "### 5.4. Change subworkflow details (Model subtype)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "13", + "metadata": {}, + "outputs": [], + "source": [ + "from mat3ra.standata.model_tree import ModelTreeStandata\n", + "\n", + "swf_0 = workflow.subworkflows[0] # relaxation subworkflow\n", + "swf_1 = workflow.subworkflows[1] # band structure subworkflow\n", + "\n", + "# Change model subtype for relaxation subworkflow\n", + "# For preview:\n", + "subtypes = ModelTreeStandata.get_subtypes_by_model_type(\"dft\") # [\"gga\", \"lda\"] as enum\n", + "functionals = ModelTreeStandata.get_functionals_by_subtype(\"dft\", subtypes.LDA) # [\"pz\", ...] as enum\n", + "\n", + "model = ModelTreeStandata.get_model_by_parameters(\n", + " model_type=\"dft\",\n", + " subtype=subtypes.LDA,\n", + " functional=functionals.PZ,\n", + ")\n", + "swf_0.model = model\n", + "swf_1.model = model" + ] + }, + { + "cell_type": "markdown", + "id": "14", + "metadata": {}, + "source": [ + "### 5.5. Modify k-grid in subworkflow units" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "15", + "metadata": {}, + "outputs": [], + "source": [ + "from mat3ra.wode.context.providers import PointsGridDataProvider\n", + "\n", + "# Values from publication\n", + "kgrid_scf = [6, 6, 1]\n", + "kgrid_nscf = [12, 12, 1]\n", + "kgrid_relax = kgrid_scf\n", + "\n", + "# TODO: helper to workflow.set_context_to_unit_by_name_regex(context_provider, unit_name_regex)\n", + "kgrid_context_provider = PointsGridDataProvider(material=material)\n", + "\n", + "new_context_relax = kgrid_context_provider.get_data(dimensions=kgrid_relax)\n", + "new_context_scf = kgrid_context_provider.get_data(dimensions=kgrid_scf)\n", + "new_context_nscf = kgrid_context_provider.get_data(dimensions=kgrid_nscf)\n", + "\n", + "# Get workflow's specific unit that needs to be modified\n", + "# Option A-1: search is done by unit name regex across the entire workflow\n", + "unit_to_modify_relax = workflow.get_unit_by_name(name_regex=\"relax\")\n", + "unit_to_modify_relax.add_context(new_context_relax)\n", + "\n", + "# Option A-2: search is done by unit name within a specific subworkflow\n", + "unit_to_modify_scf = workflow.subworkflows[1].get_unit_by_name(name=\"pw_scf\")\n", + "unit_to_modify_scf.add_context(new_context_scf)\n", + "\n", + "# Set the modified unit back to the workflow\n", + "# Option B-1: direct set by unit object, replacing the existing one\n", + "workflow.set_unit(unit_to_modify_relax)\n", + "\n", + "# Option B-2: set by unit flowchart id and new unit object\n", + "workflow.set_unit(unit_flowchart_id=unit_to_modify_scf.flowchart_id, new_unit=unit_to_modify_scf)\n", + "\n", + "# Option B-3: set context to unit directly\n", + "workflow.get_unit_by_name(name=\"pw_nscf\").set_context(new_context_nscf)\n", + "# workflow.set_context_to_unit(unit_name=\"pw_nscf\", new_context=new_context_nscf)" + ] + }, + { + "cell_type": "markdown", + "id": "16", + "metadata": {}, + "source": [ + "## 6. Create the compute configuration\n", + "### 6.1. View available clusters and providers" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "17", + "metadata": {}, + "outputs": [], + "source": [ + "# List available compute providers and clusters\n", + "from mat3ra.ide.compute import ComputeProvider, ComputeCluster\n", + "\n", + "providers = ComputeProvider.list_all()\n", + "clusters = ComputeCluster.list_all()" + ] + }, + { + "cell_type": "markdown", + "id": "18", + "metadata": {}, + "source": [ + "### 6.2. Create compute configuration" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "19", + "metadata": {}, + "outputs": [], + "source": [ + "from mat3ra.ide.compute import ComputeConfiguration, QueueTypesEnum\n", + "\n", + "compute_config = ComputeConfiguration(\n", + " queue=QueueTypesEnum.OR8,\n", + " nodes=1,\n", + " ppn=8,\n", + " cluster=clusters[0], # select first available cluster\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "20", + "metadata": {}, + "source": [ + "## 7. Create the job with material and workflow configuration" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "21", + "metadata": {}, + "outputs": [], + "source": [ + "from mat3ra.jode.job import create_job\n", + "\n", + "job = create_job(\n", + " workflow=workflow,\n", + " material=material,\n", + " compute=compute_config,\n", + " auth_config=auth_config\n", + ")\n" + ] + }, + { + "cell_type": "markdown", + "id": "22", + "metadata": {}, + "source": [ + "## 8. Submit the job and monitor the status" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "23", + "metadata": {}, + "outputs": [], + "source": [ + "from mat3ra.prode import PropertyEnum\n", + "\n", + "job.run()\n", + "job.wait_for_complete()\n", + "# job.check_status()\n", + "# job.get_current_output()" + ] + }, + { + "cell_type": "markdown", + "id": "24", + "metadata": {}, + "source": [ + "## 9. Retrieve results" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "25", + "metadata": {}, + "outputs": [], + "source": [ + "# AFTER Finished\n", + "# A class from Prode to handle results\n", + "results = job.get_results(PropertyEnum.BAND_GAP, PropertyEnum.BAND_STRUCTURE)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "26", + "metadata": {}, + "outputs": [], + "source": [ + "# Prode has property analyzer to get all eigen_values and return occupied and unoccupied states\n", + "# Gets data from express that has parser" + ] + }, + { + "cell_type": "markdown", + "id": "27", + "metadata": {}, + "source": [ + "## 10. Display results" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "28", + "metadata": {}, + "outputs": [], + "source": [ + "# Visual library that can visualize any property defined in Prode\n", + "# Use similar to Wave\n", + "from mat3ra.prove import visualize_property\n", + "\n", + "visualize_property(results.band_structure)\n", + "print(results.band_gap)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "29", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/other/materials_designer/workflows/run_bandgap_workflow_min.ipynb b/other/materials_designer/workflows/run_bandgap_workflow_min.ipynb new file mode 100644 index 00000000..73b5507c --- /dev/null +++ b/other/materials_designer/workflows/run_bandgap_workflow_min.ipynb @@ -0,0 +1,619 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "0", + "metadata": {}, + "source": [ + "# Bandgap Workflow Example\n", + " This notebook demonstrates how to build and run a bandgap workflow for a material.\n", + " Example of building and running a bandgap workflow for twisted MoS2 interface from specific_examples.\n", + "\n", + "## Process Overview\n", + "### 1. Set up the environment and parameters.\n", + "### 2. Log in to get the API token\n", + "### 3. Load the target material.\n", + "### 4. Import workflow builder and related analyzers.\n", + "### 5. Analyze material to get parameters for the workflow configuration.\n", + "### 6. Create the workflow configuration.\n", + "### 7. Create a job with material and workflow configuration.\n", + "### 8. Submit the job to the server.\n", + "### 9. Monitor the job status and retrieve results.\n", + "### 10. Display the results." + ] + }, + { + "cell_type": "markdown", + "id": "1", + "metadata": {}, + "source": [ + "## 1. Set up the environment and parameters" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "\n", + "if sys.platform == \"emscripten\":\n", + " import micropip\n", + "\n", + " await micropip.install(\"https://exabyte-io.github.io/api-examples/mat3ra_api_examples-0.1.dev1+gc24498978-py3-none-any.whl\", deps=False)\n", + " await micropip.install(\"mat3ra-utils\")\n", + " from mat3ra.utils.jupyterlite.packages import install_packages\n", + "\n", + " await install_packages(\"api_examples\")" + ] + }, + { + "cell_type": "markdown", + "id": "3", + "metadata": {}, + "source": [ + "## 2. Log in to get the API token" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4", + "metadata": {}, + "outputs": [], + "source": [ + "ACCOUNT_ID = \"ACCOUNT_ID\"\n", + "AUTH_TOKEN = \"AUTH_TOKEN\"\n", + "ORGANIZATION_ID = \"ORGANIZATION_ID\"\n", + "\n", + "import os\n", + "import sys\n", + "import json\n", + "\n", + "# TODO: add OIDC\n", + "if sys.platform == \"emscripten\":\n", + " # Only works if launched within the Platform, otherwise requires redirect to Login\n", + " apiConfig = data_from_host.get(\"apiConfig\")\n", + " os.environ.update(data_from_host.get(\"environ\", {}))\n", + " os.environ.update(\n", + " dict(\n", + " ACCOUNT_ID=apiConfig.get(\"accountId\"),\n", + " AUTH_TOKEN=apiConfig.get(\"authToken\"),\n", + " ORGANIZATION_ID=apiConfig.get(\"organizationId\", \"\"),\n", + " CLUSTERS=json.dumps(apiConfig.get(\"clusters\", [])),\n", + " )\n", + " )" + ] + }, + { + "cell_type": "markdown", + "id": "5", + "metadata": {}, + "source": [ + "## 3. Create material\n", + "### 3.1. Load material from local file" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6", + "metadata": {}, + "outputs": [], + "source": [ + "from utils.visualize import visualize_materials as visualize\n", + "from utils.jupyterlite import load_material_from_folder\n", + "\n", + "material = load_material_from_folder(\"../uploads\", \"MoS2(001)-MoS2(001), Interface\")\n", + "visualize(material)" + ] + }, + { + "cell_type": "markdown", + "id": "7", + "metadata": {}, + "source": [ + "### 3.2. Save material to the platform" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8", + "metadata": {}, + "outputs": [], + "source": [ + "from utils.settings import ACCOUNT_ID\n", + "from utils.generic import dict_to_namespace, display_JSON\n", + "from utils.api import create_material\n", + "\n", + "OWNER_ID = os.getenv(\"ORGANIZATION_ID\") or ACCOUNT_ID\n", + "\n", + "saved_material_data = create_material(material, OWNER_ID)" + ] + }, + { + "cell_type": "markdown", + "id": "9", + "metadata": {}, + "source": [ + "### 3.3. Get material id" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "10", + "metadata": {}, + "outputs": [], + "source": [ + "print(\"Material ID:\", saved_material_data[\"_id\"])" + ] + }, + { + "cell_type": "markdown", + "id": "11", + "metadata": {}, + "source": [ + "## 5. Create workflow and set its parameters\n", + "### 5.1. Get list of applications and select one" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "12", + "metadata": {}, + "outputs": [], + "source": [ + "from mat3ra.standata.applications import ApplicationStandata\n", + "from mat3ra.ade.application import Application\n", + "\n", + "# Get Applications list (with versions, build)\n", + "apps_list = ApplicationStandata.list_all()\n", + "# returns apps_list[0] = [{\"name\" : \"espresso\", \"version\": \"7.2\", \"build\": \"GNU\"}]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "13", + "metadata": {}, + "outputs": [], + "source": [ + "app_config = ApplicationStandata.get_by_name_first_match(\"espresso\")\n", + "# returns name, version, build config\n", + "app = Application(**app_config)\n", + "app.name" + ] + }, + { + "cell_type": "markdown", + "id": "14", + "metadata": {}, + "source": [ + "### 5.2. Create workflow from standard workflows and preview it" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "15", + "metadata": {}, + "outputs": [], + "source": [ + "from mat3ra.standata.workflows import WorkflowStandata\n", + "from mat3ra.wode.workflows import Workflow\n", + "from utils.visualize import visualize_workflow\n", + "\n", + "# TODO: adjust Standata to search for human readable `name`, or regex, or filename\n", + "# Search WF by name and application\n", + "workflow_config = WorkflowStandata.filter_by_application(app.name).get_by_name_first_match(\"band_gap.json\")\n", + "workflow = Workflow.create(workflow_config)\n", + "\n", + "# View workflow to understand its structure\n", + "visualize_workflow(workflow)" + ] + }, + { + "cell_type": "markdown", + "id": "16", + "metadata": {}, + "source": [ + "### 5.3. Add relaxation subworkflow" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "17", + "metadata": {}, + "outputs": [], + "source": [ + "from utils.visualize import visualize_workflow\n", + "\n", + "workflow.add_relaxation()\n", + "# Relaxation subworkflow is added as the first subworkflow\n", + "visualize_workflow(workflow)" + ] + }, + { + "cell_type": "markdown", + "id": "18", + "metadata": {}, + "source": [ + "### 5.4. Change subworkflow details (Model subtype)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "19", + "metadata": {}, + "outputs": [], + "source": [ + "from mat3ra.standata.model_tree import ModelTreeStandata\n", + "\n", + "swf_0 = workflow.subworkflows[0] # relaxation subworkflow\n", + "swf_1 = workflow.subworkflows[1] # band structure subworkflow\n", + "\n", + "# Change model subtype for relaxation subworkflow\n", + "# For preview:\n", + "subtypes = ModelTreeStandata.get_subtypes_by_model_type(\"dft\") # [\"gga\", \"lda\"] as enum\n", + "functionals = ModelTreeStandata.get_functionals_by_subtype(\"dft\", subtypes.LDA) # [\"pz\", ...] as enum\n", + "\n", + "model = ModelTreeStandata.get_model_by_parameters(\n", + " type=\"dft\",\n", + " subtype=subtypes.LDA,\n", + " functional=functionals.PZ,\n", + ")\n", + "swf_0.model = model\n", + "swf_1.model = model\n", + "model" + ] + }, + { + "cell_type": "markdown", + "id": "20", + "metadata": {}, + "source": [ + "### 5.5. Modify k-grid in subworkflow units\n", + "#### 5.5.1. Define k-grid values and create context providers" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "21", + "metadata": {}, + "outputs": [], + "source": [ + "from mat3ra.wode.context.providers import PointsGridDataProvider\n", + "\n", + "# Values from publication\n", + "kgrid_relax = kgrid_scf = [6, 6, 1]\n", + "kgrid_nscf = [12, 12, 1]\n", + "\n", + "# In future: helper to workflow.set_context_to_unit_by_name_regex(context_provider, unit_name_regex)\n", + "kgrid_context_provider_relax = PointsGridDataProvider(dimensions=kgrid_scf)\n", + "kgrid_context_provider_scf = PointsGridDataProvider(dimensions=kgrid_scf)\n", + "kgrid_context_provider_nscf = PointsGridDataProvider(dimensions=kgrid_nscf)" + ] + }, + { + "cell_type": "markdown", + "id": "22", + "metadata": {}, + "source": [ + "#### 5.5.2. Get new context data and set it to workflow units" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "23", + "metadata": {}, + "outputs": [], + "source": [ + "new_context_relax = kgrid_context_provider_relax.get_data()\n", + "new_context_scf = kgrid_context_provider_scf.get_data()\n", + "new_context_nscf = kgrid_context_provider_nscf.get_data()" + ] + }, + { + "cell_type": "markdown", + "id": "24", + "metadata": {}, + "source": [ + "#### 5.5.3. Modify workflow units with new context" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "25", + "metadata": {}, + "outputs": [], + "source": [ + "# Get workflow's specific unit that needs to be modified\n", + "# Option 1: search is done by unit name regex across the entire workflow\n", + "unit_to_modify_relax = workflow.get_unit_by_name(name_regex=\"relax\")\n", + "unit_to_modify_relax.add_context(new_context_relax)\n", + "\n", + "# Option 2: search is done by unit name within a specific subworkflow\n", + "unit_to_modify_scf = workflow.subworkflows[1].get_unit_by_name(name=\"pw_scf\")\n", + "unit_to_modify_scf.add_context(new_context_scf)\n", + "unit_to_modify_nscf = workflow.subworkflows[1].get_unit_by_name(name=\"pw_nscf\")\n", + "unit_to_modify_nscf.add_context(new_context_nscf)\n", + "\n", + "# Set the modified unit back to the workflow\n", + "# Option 1: direct set by unit object, replacing the existing one\n", + "workflow.set_unit(unit_to_modify_relax)\n", + "\n", + "# Option 2: set by unit flowchart id and new unit object\n", + "workflow.set_unit(unit_flowchart_id=unit_to_modify_scf.flowchart_id, new_unit=unit_to_modify_scf)\n", + "workflow.set_unit(unit_flowchart_id=unit_to_modify_nscf.flowchart_id, new_unit=unit_to_modify_nscf)\n", + "visualize_workflow(workflow)\n", + "workflow.to_dict()" + ] + }, + { + "cell_type": "markdown", + "id": "26", + "metadata": {}, + "source": [ + "### 5.6. Save workflow to collection" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "27", + "metadata": {}, + "outputs": [], + "source": [ + "from utils.settings import ACCOUNT_ID\n", + "from utils.api import create_workflow\n", + "\n", + "saved_workflow_data = create_workflow(workflow, ACCOUNT_ID)" + ] + }, + { + "cell_type": "markdown", + "id": "28", + "metadata": {}, + "source": [ + "## 6. Create the compute configuration\n", + "### 6.1. View available clusters and providers" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "29", + "metadata": {}, + "outputs": [], + "source": [ + "cluster_config = next(iter(json.loads(os.getenv(\"CLUSTERS\"))), {})\n", + "queue_configs = cluster_config.get(\"queues\", [])\n", + "\n", + "CLUSTER_NAME = cluster_config.get(\"displayName\", \"cluster-001\")" + ] + }, + { + "cell_type": "markdown", + "id": "30", + "metadata": {}, + "source": [ + "### 6.2. Create compute configuration" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "31", + "metadata": {}, + "outputs": [], + "source": [ + "from exabyte_api_client.endpoints.jobs import JobEndpoints\n", + "from utils.settings import ENDPOINT_ARGS\n", + "\n", + "exabyte_jobs_endpoint = JobEndpoints(*ENDPOINT_ARGS)\n", + "\n", + "compute = exabyte_jobs_endpoint.get_compute(\n", + " cluster=CLUSTER_NAME\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "32", + "metadata": {}, + "source": [ + "## 7. Create the job with material and workflow configuration" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "33", + "metadata": {}, + "outputs": [], + "source": [ + "from datetime import datetime\n", + "\n", + "from utils.settings import ACCOUNT_ID\n", + "from utils.api import get_default_project\n", + "\n", + "OWNER_ID = os.getenv(\"ORGANIZATION_ID\") or ACCOUNT_ID\n", + "\n", + "project_id = get_default_project(OWNER_ID)\n", + "\n", + "timestamp = datetime.now().strftime(\"%Y-%m-%d %H:%M\")\n", + "\n", + "JOB_NAME = f\"Band Gap {timestamp}\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "34", + "metadata": {}, + "outputs": [], + "source": [ + "from utils.generic import display_JSON\n", + "\n", + "job_endpoints = JobEndpoints(*ENDPOINT_ARGS)\n", + "\n", + "job_response = job_endpoints.create_by_ids(\n", + " materials=[saved_material_data],\n", + " workflow_id=saved_workflow_data[\"_id\"],\n", + " project_id=project_id,\n", + " prefix=JOB_NAME,\n", + " owner_id=OWNER_ID,\n", + " compute=compute\n", + ")\n", + "\n", + "# Convert jobs list to SimpleNamespace objects for dot notation access\n", + "job = dict_to_namespace(job_response)\n", + "\n", + "display_JSON(job_response)" + ] + }, + { + "cell_type": "markdown", + "id": "35", + "metadata": {}, + "source": [ + "## 8. Submit the job and monitor the status" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "36", + "metadata": {}, + "outputs": [], + "source": [ + "job_endpoints.submit(job._id)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "37", + "metadata": {}, + "outputs": [], + "source": [ + "from utils.generic import wait_for_jobs_to_finish\n", + "\n", + "wait_for_jobs_to_finish(job_endpoints, [job._id], poll_interval=60)" + ] + }, + { + "cell_type": "markdown", + "id": "38", + "metadata": {}, + "source": [ + "## 9. Retrieve results" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "39", + "metadata": {}, + "outputs": [], + "source": [ + "import re\n", + "from utils.generic import get_property_by_subworkflow_and_unit_indicies\n", + "from exabyte_api_client.endpoints.properties import PropertiesEndpoints\n", + "\n", + "property_endpoints = PropertiesEndpoints(*ENDPOINT_ARGS)\n", + "\n", + "results = []\n", + "final_structure = get_property_by_subworkflow_and_unit_indicies(property_endpoints, \"final_structure\", job, 0, 0)[\n", + " \"data\"\n", + "]\n", + "pressure = get_property_by_subworkflow_and_unit_indicies(property_endpoints, \"pressure\", job, 0, 0)[\"data\"][\"value\"]\n", + "\n", + "# Use dot notation to access workflow property\n", + "unit_flowchart_id = Workflow(job.workflow).get_unit_by_name(name=\"pw_scf\").flowchart_id\n", + "band_gap_direct = property_endpoints.get_direct_band_gap(job._id, unit_flowchart_id)\n", + "band_gap_indirect = property_endpoints.get_indirect_band_gap(job._id, unit_flowchart_id)\n", + "\n", + "results.append(\n", + " {\n", + " \"material_id\": material._id,\n", + " \"angle_deg\": re.search(r\"(\\d+(?:\\.\\d+)?) degrees\", material.name).group(1),\n", + " \"band_gap_direct\": band_gap_direct,\n", + " \"band_gap_indirect\": band_gap_indirect,\n", + " }\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "40", + "metadata": {}, + "source": [ + "## 10. Display results" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "41", + "metadata": {}, + "outputs": [], + "source": [ + "from matplotlib import pyplot as plt\n", + "import pandas as pd\n", + "\n", + "df = pd.DataFrame(results).dropna(subset=[\"band_gap_direct\", \"band_gap_indirect\"]).sort_values(\"angle_deg\")\n", + "display(df)\n", + "\n", + "plt.figure(figsize=(5, 3.6), dpi=130)\n", + "plt.scatter(df[\"angle_deg\"], df[\"band_gap_direct\"], marker=\">\", label=\"K-valley bandgap (direct)\")\n", + "plt.scatter(df[\"angle_deg\"], df[\"band_gap_indirect\"], marker=\"<\", label=\"Indirect bandgap\")\n", + "plt.xlabel(r\"$\\theta$ (°)\")\n", + "plt.ylabel(\"Energy (eV)\")\n", + "plt.xlim(-2, 62)\n", + "plt.legend(frameon=False, loc=\"best\")\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "42", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/pyproject.toml b/pyproject.toml index f5feb0f7..1fbda5cb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,6 +14,7 @@ dependencies = [ "pymatgen==2024.4.13", "mat3ra-made>=2025.8.13.post0", "mat3ra-utils>=2024.6.11.post0", + "mat3ra-wode @ git+https://github.com/Exabyte-io/wode.git@ffc88d15184b2bedae558c47c2a7ba2e49624c52" ] [project.optional-dependencies] diff --git a/utils/api.py b/utils/api.py new file mode 100644 index 00000000..652003c3 --- /dev/null +++ b/utils/api.py @@ -0,0 +1,71 @@ +from typing import Any, Dict, Optional, Union + +from exabyte_api_client.endpoints.materials import MaterialEndpoints +from exabyte_api_client.endpoints.projects import ProjectEndpoints +from exabyte_api_client.endpoints.workflows import WorkflowEndpoints +from mat3ra.wode.workflows import Workflow + +from .settings import ACCOUNT_ID, ENDPOINT_ARGS + + +def create_material(material: Any, owner_id: Optional[str] = None) -> Dict[str, Any]: + """ + Creates a material on the platform. + + Args: + material: Material object with a to_dict() method + owner_id: Optional owner ID. Defaults to ACCOUNT_ID from settings + + Returns: + dict: Created material response from the API + """ + endpoint = MaterialEndpoints(*ENDPOINT_ARGS) + owner = owner_id or ACCOUNT_ID + + if isinstance(material, dict): + raw_config = material + else: + raw_config = material.to_dict() + fields = ["name", "lattice", "basis"] + config = {key: raw_config[key] for key in fields} + + return endpoint.create(config, owner) + + +def create_workflow(workflow: Union[Workflow, Dict], owner_id: Optional[str] = None) -> Dict[str, Any]: + """ + Creates a workflow on the platform. + + Args: + workflow: Workflow object with a to_dict() method + owner_id: Optional owner ID. Defaults to ACCOUNT_ID from settings + + Returns: + dict: Created workflow response from the API + """ + endpoint = WorkflowEndpoints(*ENDPOINT_ARGS) + owner = owner_id or ACCOUNT_ID + if isinstance(workflow, dict): + config = workflow + else: + config = workflow.to_dict() + + return endpoint.create(config, owner) + + +def get_default_project(owner_id: Optional[str] = None) -> str: + """ + Gets the default project ID for an owner. + + Args: + owner_id: Optional owner ID. Defaults to ACCOUNT_ID from settings + + Returns: + str: Default project ID + """ + endpoint = ProjectEndpoints(*ENDPOINT_ARGS) + owner = owner_id or ACCOUNT_ID + + projects = endpoint.list({"isDefault": True, "owner._id": owner}) + + return projects[0]["_id"] diff --git a/utils/generic.py b/utils/generic.py index 8c903265..818e9ae0 100644 --- a/utils/generic.py +++ b/utils/generic.py @@ -5,18 +5,20 @@ import time import urllib.request import uuid +from types import SimpleNamespace from typing import List, Union +from IPython.display import HTML, display from exabyte_api_client.endpoints.bank_workflows import BankWorkflowEndpoints from exabyte_api_client.endpoints.jobs import JobEndpoints from exabyte_api_client.endpoints.properties import PropertiesEndpoints -from IPython.display import HTML, display from pandas import DataFrame from pandas.io.formats.style import Styler from tabulate import tabulate from . import settings + # GENERIC UTILITIES @@ -223,3 +225,13 @@ def display_JSON( ) else: print(json.dumps(obj, indent=4)) + + +# Helper function to convert dictionaries to SimpleNamespace objects for dot notation access +def dict_to_namespace(obj): + if isinstance(obj, dict): + return SimpleNamespace(**{k: dict_to_namespace(v) for k, v in obj.items()}) + elif isinstance(obj, list): + return [dict_to_namespace(item) for item in obj] + else: + return obj diff --git a/utils/visualize.py b/utils/visualize.py index c76e81f7..d2d111f4 100644 --- a/utils/visualize.py +++ b/utils/visualize.py @@ -12,6 +12,8 @@ from mat3ra.utils.array import convert_to_array_if_not from pydantic import BaseModel +from .generic import display_JSON + class ViewersEnum(str, Enum): wave = "wave" @@ -255,3 +257,18 @@ def visualize_materials( items.append((image_data, image_title)) display(create_responsive_image_grid(items)) + + +def visualize_workflow(workflow, level: int = 2) -> None: + """ + Visualize a workflow by displaying its JSON configuration. + + Args: + workflow: Workflow object with a to_dict() method + level: Expansion level for the JSON viewer (default: 2) + + Returns: + None + """ + workflow_config = workflow.to_dict() + display_JSON(workflow_config, level=level)