@mat3ra/wode 2025.10.1-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (252) hide show
  1. package/.babelrc +17 -0
  2. package/LICENSE.md +15 -0
  3. package/README.md +164 -0
  4. package/assets/subworkflows/deepmd/deepmd.yml +31 -0
  5. package/assets/subworkflows/deepmd/espresso_cp_md.yml +16 -0
  6. package/assets/subworkflows/espresso/average_electrostatic_potential_find_minima.yml +27 -0
  7. package/assets/subworkflows/espresso/average_electrostatic_potential_via_band_structure.yml +67 -0
  8. package/assets/subworkflows/espresso/band_gap.yml +21 -0
  9. package/assets/subworkflows/espresso/band_gap_hse_dos.yml +30 -0
  10. package/assets/subworkflows/espresso/band_structure.yml +26 -0
  11. package/assets/subworkflows/espresso/band_structure_dos.yml +34 -0
  12. package/assets/subworkflows/espresso/band_structure_hse.yml +30 -0
  13. package/assets/subworkflows/espresso/band_structure_magn.yml +31 -0
  14. package/assets/subworkflows/espresso/band_structure_soc.yml +30 -0
  15. package/assets/subworkflows/espresso/dielectric_tensor.yml +35 -0
  16. package/assets/subworkflows/espresso/dos.yml +24 -0
  17. package/assets/subworkflows/espresso/electronic_density_mesh.yml +19 -0
  18. package/assets/subworkflows/espresso/esm.yml +14 -0
  19. package/assets/subworkflows/espresso/esm_relax.yml +14 -0
  20. package/assets/subworkflows/espresso/espresso_extract_kpoints.yml +16 -0
  21. package/assets/subworkflows/espresso/espresso_xml_get_qpt_irr.yml +12 -0
  22. package/assets/subworkflows/espresso/fixed_cell_relaxation.yml +16 -0
  23. package/assets/subworkflows/espresso/gw_band_structure_band_gap_full_frequency.yml +22 -0
  24. package/assets/subworkflows/espresso/gw_band_structure_band_gap_plasmon_pole.yml +22 -0
  25. package/assets/subworkflows/espresso/hubbard_u_hp.yml +21 -0
  26. package/assets/subworkflows/espresso/kpoint_convergence.yml +86 -0
  27. package/assets/subworkflows/espresso/neb.yml +16 -0
  28. package/assets/subworkflows/espresso/ph_init_qpoints.yml +14 -0
  29. package/assets/subworkflows/espresso/ph_single_irr_qpt.yml +14 -0
  30. package/assets/subworkflows/espresso/phonon_dispersions.yml +29 -0
  31. package/assets/subworkflows/espresso/phonon_dos.yml +29 -0
  32. package/assets/subworkflows/espresso/phonon_dos_dispersion.yml +34 -0
  33. package/assets/subworkflows/espresso/phonon_reduce.yml +29 -0
  34. package/assets/subworkflows/espresso/post_processor.yml +14 -0
  35. package/assets/subworkflows/espresso/pre_processor.yml +14 -0
  36. package/assets/subworkflows/espresso/pw_scf.yml +16 -0
  37. package/assets/subworkflows/espresso/recalculate_bands.yml +19 -0
  38. package/assets/subworkflows/espresso/surface_energy.yml +16 -0
  39. package/assets/subworkflows/espresso/total_energy.yml +16 -0
  40. package/assets/subworkflows/espresso/valence_band_offset_calc_from_previous_esp_vbm.yml +35 -0
  41. package/assets/subworkflows/espresso/variable_cell_relaxation.yml +18 -0
  42. package/assets/subworkflows/espresso/zero_point_energy.yml +19 -0
  43. package/assets/subworkflows/jupyterLab/jupyter_notebook.yml +17 -0
  44. package/assets/subworkflows/nwchem/total_energy.yml +16 -0
  45. package/assets/subworkflows/python/ml/classification_tail.yml +56 -0
  46. package/assets/subworkflows/python/ml/clustering_tail.yml +62 -0
  47. package/assets/subworkflows/python/ml/regression_tail.yml +56 -0
  48. package/assets/subworkflows/python/ml/train_head.yml +61 -0
  49. package/assets/subworkflows/python/python_script.yml +14 -0
  50. package/assets/subworkflows/shell/batch_espresso_pwscf.yml +14 -0
  51. package/assets/subworkflows/shell/hello_world.yml +14 -0
  52. package/assets/subworkflows/vasp/band_gap.yml +21 -0
  53. package/assets/subworkflows/vasp/band_structure.yml +21 -0
  54. package/assets/subworkflows/vasp/band_structure_dos.yml +23 -0
  55. package/assets/subworkflows/vasp/dos.yml +18 -0
  56. package/assets/subworkflows/vasp/fixed_cell_relaxation.yml +16 -0
  57. package/assets/subworkflows/vasp/initial_final_total_energies.yml +25 -0
  58. package/assets/subworkflows/vasp/kpoint_convergence.yml +89 -0
  59. package/assets/subworkflows/vasp/neb_subworkflow.yml +16 -0
  60. package/assets/subworkflows/vasp/prepare_images.yml +16 -0
  61. package/assets/subworkflows/vasp/recalculate_bands.yml +16 -0
  62. package/assets/subworkflows/vasp/surface_energy.yml +18 -0
  63. package/assets/subworkflows/vasp/total_energy.yml +16 -0
  64. package/assets/subworkflows/vasp/variable_cell_relaxation.yml +18 -0
  65. package/assets/subworkflows/vasp/zero_point_energy.yml +16 -0
  66. package/assets/workflows/deepmd/deepmd_md.yml +6 -0
  67. package/assets/workflows/espresso/band_gap.yml +4 -0
  68. package/assets/workflows/espresso/band_gap_dos_hse.yml +4 -0
  69. package/assets/workflows/espresso/band_structure.yml +4 -0
  70. package/assets/workflows/espresso/band_structure_dos.yml +4 -0
  71. package/assets/workflows/espresso/band_structure_hse.yml +14 -0
  72. package/assets/workflows/espresso/band_structure_magn.yml +7 -0
  73. package/assets/workflows/espresso/band_structure_soc.yml +7 -0
  74. package/assets/workflows/espresso/dielectric_tensor.yml +4 -0
  75. package/assets/workflows/espresso/dos.yml +4 -0
  76. package/assets/workflows/espresso/electronic_density_mesh.yml +4 -0
  77. package/assets/workflows/espresso/esm.yml +4 -0
  78. package/assets/workflows/espresso/esm_relax.yml +4 -0
  79. package/assets/workflows/espresso/fixed_cell_relaxation.yml +4 -0
  80. package/assets/workflows/espresso/gw_band_structure_band_gap_full_frequency.yml +4 -0
  81. package/assets/workflows/espresso/gw_band_structure_band_gap_plasmon_pole.yml +4 -0
  82. package/assets/workflows/espresso/hubbard_u_hp.yml +7 -0
  83. package/assets/workflows/espresso/kpoint_convergence.yml +4 -0
  84. package/assets/workflows/espresso/neb.yml +4 -0
  85. package/assets/workflows/espresso/phonon_dispersions.yml +4 -0
  86. package/assets/workflows/espresso/phonon_dos.yml +4 -0
  87. package/assets/workflows/espresso/phonon_dos_dispersion.yml +4 -0
  88. package/assets/workflows/espresso/phonon_map.yml +28 -0
  89. package/assets/workflows/espresso/recalculate_bands.yml +4 -0
  90. package/assets/workflows/espresso/surface_energy.yml +4 -0
  91. package/assets/workflows/espresso/total_energy.yml +4 -0
  92. package/assets/workflows/espresso/valence_band_offset.yml +171 -0
  93. package/assets/workflows/espresso/variable_cell_relaxation.yml +4 -0
  94. package/assets/workflows/espresso/zero_point_energy.yml +4 -0
  95. package/assets/workflows/jupyterLab/jupyter_notebook.yml +4 -0
  96. package/assets/workflows/nwchem/total_energy.yml +4 -0
  97. package/assets/workflows/python/ml/classification_workflow.yml +9 -0
  98. package/assets/workflows/python/ml/clustering_workflow.yml +9 -0
  99. package/assets/workflows/python/ml/regression_workflow.yml +9 -0
  100. package/assets/workflows/python/python_script.yml +4 -0
  101. package/assets/workflows/shell/batch_espresso_pwscf.yml +4 -0
  102. package/assets/workflows/shell/hello_world.yml +4 -0
  103. package/assets/workflows/vasp/band_gap.yml +4 -0
  104. package/assets/workflows/vasp/band_structure.yml +4 -0
  105. package/assets/workflows/vasp/band_structure_dos.yml +4 -0
  106. package/assets/workflows/vasp/dos.yml +4 -0
  107. package/assets/workflows/vasp/fixed_cell_relaxation.yml +4 -0
  108. package/assets/workflows/vasp/kpoint_convergence.yml +4 -0
  109. package/assets/workflows/vasp/neb.yml +8 -0
  110. package/assets/workflows/vasp/recalculate_bands.yml +4 -0
  111. package/assets/workflows/vasp/surface_energy.yml +4 -0
  112. package/assets/workflows/vasp/total_energy.yml +4 -0
  113. package/assets/workflows/vasp/variable_cell_relaxation.yml +4 -0
  114. package/assets/workflows/vasp/zero_point_energy.yml +4 -0
  115. package/build_workflows.js +65 -0
  116. package/dist/context/context.js +49 -0
  117. package/dist/context/mixins/ApplicationContextMixin.js +19 -0
  118. package/dist/context/mixins/JobContextMixin.js +39 -0
  119. package/dist/context/mixins/MaterialContextMixin.js +40 -0
  120. package/dist/context/mixins/MaterialsContextMixin.js +19 -0
  121. package/dist/context/mixins/MaterialsSetContextMixin.js +25 -0
  122. package/dist/context/mixins/MethodDataContextMixin.js +48 -0
  123. package/dist/context/mixins/WorkflowContextMixin.js +28 -0
  124. package/dist/context/providers/BoundaryConditionsFormDataProvider.js +86 -0
  125. package/dist/context/providers/CollinearMagnetizationContextProvider.js +113 -0
  126. package/dist/context/providers/HubbardContextProviderLegacy.js +81 -0
  127. package/dist/context/providers/HubbardJContextProvider.js +74 -0
  128. package/dist/context/providers/HubbardUContextProvider.js +77 -0
  129. package/dist/context/providers/HubbardVContextProvider.js +104 -0
  130. package/dist/context/providers/IonDynamicsContextProvider.js +62 -0
  131. package/dist/context/providers/MLSettingsContextProvider.js +52 -0
  132. package/dist/context/providers/MLTrainTestSplitContextProvider.js +48 -0
  133. package/dist/context/providers/NEBFormDataProvider.js +38 -0
  134. package/dist/context/providers/NonCollinearMagnetizationContextProvider.js +253 -0
  135. package/dist/context/providers/PlanewaveCutoffsContextProvider.js +67 -0
  136. package/dist/context/providers/PointsGridFormDataProvider.js +272 -0
  137. package/dist/context/providers/PointsPathFormDataProvider.js +155 -0
  138. package/dist/context/providers/by_application/ExecutableContextProvider.js +17 -0
  139. package/dist/context/providers/by_application/espresso/QENEBContextProvider.js +60 -0
  140. package/dist/context/providers/by_application/espresso/QEPWXContextProvider.js +149 -0
  141. package/dist/context/providers/by_application/nwchem/NWChemTotalEnergyContextProvider.js +84 -0
  142. package/dist/context/providers/by_application/vasp/VASPContextProvider.js +64 -0
  143. package/dist/context/providers/by_application/vasp/VASPNEBContextProvider.js +56 -0
  144. package/dist/context/providers/settings.js +37 -0
  145. package/dist/context/providers.js +199 -0
  146. package/dist/enums.js +65 -0
  147. package/dist/index.js +64 -0
  148. package/dist/patch.js +19 -0
  149. package/dist/subworkflows/convergence/factory.js +35 -0
  150. package/dist/subworkflows/convergence/non_uniform_kgrid.js +31 -0
  151. package/dist/subworkflows/convergence/parameter.js +70 -0
  152. package/dist/subworkflows/convergence/uniform_kgrid.js +26 -0
  153. package/dist/subworkflows/convergence.js +189 -0
  154. package/dist/subworkflows/create.js +285 -0
  155. package/dist/subworkflows/dynamic/espresso/getQpointIrrep.js +34 -0
  156. package/dist/subworkflows/dynamic/index.js +19 -0
  157. package/dist/subworkflows/dynamic/surfaceEnergy.js +67 -0
  158. package/dist/subworkflows/index.js +19 -0
  159. package/dist/subworkflows/subworkflow.js +279 -0
  160. package/dist/units/assertion.js +37 -0
  161. package/dist/units/assignment.js +42 -0
  162. package/dist/units/base.js +91 -0
  163. package/dist/units/builders/AssertionUnitConfigBuilder.js +34 -0
  164. package/dist/units/builders/AssignmentUnitConfigBuilder.js +41 -0
  165. package/dist/units/builders/ExecutionUnitConfigBuilder.js +67 -0
  166. package/dist/units/builders/IOUnitConfigBuilder.js +54 -0
  167. package/dist/units/builders/UnitConfigBuilder.js +79 -0
  168. package/dist/units/builders/index.js +18 -0
  169. package/dist/units/condition.js +52 -0
  170. package/dist/units/execution.js +222 -0
  171. package/dist/units/factory.js +53 -0
  172. package/dist/units/index.js +82 -0
  173. package/dist/units/io.js +148 -0
  174. package/dist/units/map.js +38 -0
  175. package/dist/units/processing.js +41 -0
  176. package/dist/units/reduce.js +24 -0
  177. package/dist/units/subworkflow.js +23 -0
  178. package/dist/utils.js +92 -0
  179. package/dist/workflows/create.js +312 -0
  180. package/dist/workflows/default.js +41 -0
  181. package/dist/workflows/index.js +108 -0
  182. package/dist/workflows/relaxation.js +37 -0
  183. package/dist/workflows/workflow.js +303 -0
  184. package/package.json +94 -0
  185. package/src/context/context.js +47 -0
  186. package/src/context/mixins/ApplicationContextMixin.js +19 -0
  187. package/src/context/mixins/JobContextMixin.js +36 -0
  188. package/src/context/mixins/MaterialContextMixin.js +41 -0
  189. package/src/context/mixins/MaterialsContextMixin.js +18 -0
  190. package/src/context/mixins/MaterialsSetContextMixin.js +24 -0
  191. package/src/context/mixins/MethodDataContextMixin.js +48 -0
  192. package/src/context/mixins/WorkflowContextMixin.js +25 -0
  193. package/src/context/providers/BoundaryConditionsFormDataProvider.js +80 -0
  194. package/src/context/providers/CollinearMagnetizationContextProvider.js +117 -0
  195. package/src/context/providers/HubbardContextProviderLegacy.js +75 -0
  196. package/src/context/providers/HubbardJContextProvider.js +73 -0
  197. package/src/context/providers/HubbardUContextProvider.js +100 -0
  198. package/src/context/providers/HubbardVContextProvider.js +111 -0
  199. package/src/context/providers/IonDynamicsContextProvider.js +56 -0
  200. package/src/context/providers/MLSettingsContextProvider.js +48 -0
  201. package/src/context/providers/MLTrainTestSplitContextProvider.js +45 -0
  202. package/src/context/providers/NEBFormDataProvider.js +32 -0
  203. package/src/context/providers/NonCollinearMagnetizationContextProvider.js +269 -0
  204. package/src/context/providers/PlanewaveCutoffsContextProvider.js +68 -0
  205. package/src/context/providers/PointsGridFormDataProvider.js +285 -0
  206. package/src/context/providers/PointsPathFormDataProvider.js +165 -0
  207. package/src/context/providers/by_application/ExecutableContextProvider.js +10 -0
  208. package/src/context/providers/by_application/espresso/QENEBContextProvider.js +56 -0
  209. package/src/context/providers/by_application/espresso/QEPWXContextProvider.js +166 -0
  210. package/src/context/providers/by_application/nwchem/NWChemTotalEnergyContextProvider.js +86 -0
  211. package/src/context/providers/by_application/vasp/VASPContextProvider.js +56 -0
  212. package/src/context/providers/by_application/vasp/VASPNEBContextProvider.js +46 -0
  213. package/src/context/providers/settings.js +38 -0
  214. package/src/context/providers.js +140 -0
  215. package/src/enums.js +65 -0
  216. package/src/index.js +17 -0
  217. package/src/patch.js +12 -0
  218. package/src/subworkflows/convergence/factory.js +14 -0
  219. package/src/subworkflows/convergence/non_uniform_kgrid.js +28 -0
  220. package/src/subworkflows/convergence/parameter.js +58 -0
  221. package/src/subworkflows/convergence/uniform_kgrid.js +22 -0
  222. package/src/subworkflows/convergence.js +196 -0
  223. package/src/subworkflows/create.js +201 -0
  224. package/src/subworkflows/dynamic/espresso/getQpointIrrep.js +35 -0
  225. package/src/subworkflows/dynamic/index.js +8 -0
  226. package/src/subworkflows/dynamic/surfaceEnergy.js +124 -0
  227. package/src/subworkflows/index.js +2 -0
  228. package/src/subworkflows/subworkflow.js +329 -0
  229. package/src/units/assertion.js +29 -0
  230. package/src/units/assignment.js +34 -0
  231. package/src/units/base.js +97 -0
  232. package/src/units/builders/AssertionUnitConfigBuilder.js +28 -0
  233. package/src/units/builders/AssignmentUnitConfigBuilder.js +36 -0
  234. package/src/units/builders/ExecutionUnitConfigBuilder.js +59 -0
  235. package/src/units/builders/IOUnitConfigBuilder.js +53 -0
  236. package/src/units/builders/UnitConfigBuilder.js +86 -0
  237. package/src/units/builders/index.js +15 -0
  238. package/src/units/condition.js +47 -0
  239. package/src/units/execution.js +263 -0
  240. package/src/units/factory.js +53 -0
  241. package/src/units/index.js +25 -0
  242. package/src/units/io.js +163 -0
  243. package/src/units/map.js +33 -0
  244. package/src/units/processing.js +39 -0
  245. package/src/units/reduce.js +17 -0
  246. package/src/units/subworkflow.js +15 -0
  247. package/src/utils.js +73 -0
  248. package/src/workflows/create.js +222 -0
  249. package/src/workflows/default.js +39 -0
  250. package/src/workflows/index.js +99 -0
  251. package/src/workflows/relaxation.js +41 -0
  252. package/src/workflows/workflow.js +351 -0
@@ -0,0 +1,351 @@
1
+ /* eslint-disable max-classes-per-file */
2
+ import { ComputedEntityMixin, getDefaultComputeConfig } from "@exabyte-io/ide.js";
3
+ import { tree } from "@exabyte-io/mode.js";
4
+ import { NamedDefaultableRepetitionContextAndRenderInMemoryEntity } from "@mat3ra/code/dist/js/entity";
5
+ import workflowSchema from "@mat3ra/esse/dist/js/schema/workflow.json";
6
+ import { Utils } from "@mat3ra/utils";
7
+ import lodash from "lodash";
8
+ import { mix } from "mixwith";
9
+ import _ from "underscore";
10
+ import s from "underscore.string";
11
+
12
+ import { UNIT_TYPES } from "../enums";
13
+ import { Subworkflow } from "../subworkflows/subworkflow";
14
+ import { MapUnit } from "../units";
15
+ import { UnitFactory } from "../units/factory";
16
+ import { setNextLinks, setUnitsHead } from "../utils";
17
+ import defaultWorkflowConfig from "./default";
18
+ import { RelaxationLogicMixin } from "./relaxation";
19
+
20
+ const { MODEL_NAMES } = tree;
21
+
22
+ class BaseWorkflow extends mix(NamedDefaultableRepetitionContextAndRenderInMemoryEntity).with(
23
+ ComputedEntityMixin,
24
+ RelaxationLogicMixin,
25
+ ) {}
26
+
27
+ export class Workflow extends BaseWorkflow {
28
+ static getDefaultComputeConfig = getDefaultComputeConfig;
29
+
30
+ static jsonSchema = workflowSchema;
31
+
32
+ static usePredefinedIds = false;
33
+
34
+ constructor(config) {
35
+ if (!config._id) config._id = Workflow.generateWorkflowId(config.name);
36
+
37
+ super(config);
38
+ this._Subworkflow = Subworkflow;
39
+ this._UnitFactory = UnitFactory;
40
+ this._Workflow = Workflow;
41
+ this._MapUnit = MapUnit;
42
+ if (!config.skipInitialize) this.initialize();
43
+ }
44
+
45
+ initialize() {
46
+ const me = this;
47
+ this._subworkflows = this.prop("subworkflows").map((x) => new me._Subworkflow(x));
48
+ this._units = this.prop("units").map((unit) => me._UnitFactory.create(unit));
49
+ this._json.workflows = this._json.workflows || [];
50
+ this._workflows = this.prop("workflows").map((x) => new me._Workflow(x));
51
+ }
52
+
53
+ static get defaultConfig() {
54
+ return defaultWorkflowConfig;
55
+ }
56
+
57
+ static generateWorkflowId(...args) {
58
+ args[0] = `workflow-${args[0]}`;
59
+ if (this.usePredefinedIds) return Utils.uuid.getUUIDFromNamespace(...args);
60
+ return Utils.uuid.getUUID();
61
+ }
62
+
63
+ static fromSubworkflow(subworkflow, ClsConstructor = Workflow) {
64
+ const config = {
65
+ name: subworkflow.name,
66
+ subworkflows: [subworkflow.toJSON()],
67
+ units: setNextLinks(setUnitsHead([subworkflow.getAsUnit().toJSON()])),
68
+ properties: subworkflow.properties,
69
+ };
70
+ return new ClsConstructor(config);
71
+ }
72
+
73
+ static fromSubworkflows(name, ClsConstructor = Workflow, ...subworkflows) {
74
+ return new ClsConstructor(
75
+ name,
76
+ subworkflows,
77
+ subworkflows.map((sw) => sw.getAsUnit()),
78
+ );
79
+ }
80
+
81
+ /**
82
+ * @summary Adds subworkflow to current workflow.
83
+ * @param subworkflow {Subworkflow}
84
+ * @param head {Boolean}
85
+ */
86
+ addSubworkflow(subworkflow, head = false, index = -1) {
87
+ const subworkflowUnit = subworkflow.getAsUnit();
88
+ if (head) {
89
+ this.subworkflows.unshift(subworkflow);
90
+ this.addUnit(subworkflowUnit, head, index);
91
+ } else {
92
+ this.subworkflows.push(subworkflow);
93
+ this.addUnit(subworkflowUnit, head, index);
94
+ }
95
+ }
96
+
97
+ removeSubworkflow(id) {
98
+ const subworkflowUnit = this.units.find((u) => u.id === id);
99
+ if (subworkflowUnit) this.removeUnit(subworkflowUnit.flowchartId);
100
+ }
101
+
102
+ subworkflowId(index) {
103
+ const sw = this.prop(`subworkflows[${index}]`);
104
+ return sw ? sw._id : null;
105
+ }
106
+
107
+ replaceSubworkflowAtIndex(index, newSubworkflow) {
108
+ this._subworkflows[index] = newSubworkflow;
109
+ this.setUnits(setNextLinks(setUnitsHead(this._units)));
110
+ }
111
+
112
+ get units() {
113
+ return this._units;
114
+ }
115
+
116
+ setUnits(arr) {
117
+ this._units = arr;
118
+ }
119
+
120
+ // returns a list of `app` Classes
121
+ get usedApplications() {
122
+ const swApplications = this.subworkflows.map((sw) => sw.application);
123
+ const wfApplications = lodash.flatten(this.workflows.map((w) => w.usedApplications));
124
+ return lodash.uniqBy(swApplications.concat(wfApplications), (a) => a.name);
125
+ }
126
+
127
+ // return application names
128
+ get usedApplicationNames() {
129
+ return this.usedApplications.map((a) => a.name);
130
+ }
131
+
132
+ get usedApplicationVersions() {
133
+ return this.usedApplications.map((a) => a.version);
134
+ }
135
+
136
+ get usedApplicationNamesWithVersions() {
137
+ return this.usedApplications.map((a) => `${a.name} ${a.version}`);
138
+ }
139
+
140
+ get usedModels() {
141
+ return lodash.uniq(this.subworkflows.map((sw) => sw.model.type));
142
+ }
143
+
144
+ get humanReadableUsedModels() {
145
+ return this.usedModels.filter((m) => m !== "unknown").map((m) => MODEL_NAMES[m]);
146
+ }
147
+
148
+ toJSON(exclude = []) {
149
+ return lodash.omit(
150
+ {
151
+ ...super.toJSON(),
152
+ units: this._units.map((x) => x.toJSON()),
153
+ subworkflows: this._subworkflows.map((x) => x.toJSON()),
154
+ workflows: this.workflows.map((x) => x.toJSON()),
155
+ ...(this.compute ? { compute: this.compute } : {}), // {"compute": null } won't pass esse validation
156
+ },
157
+ exclude,
158
+ );
159
+ }
160
+
161
+ get isDefault() {
162
+ return this.prop("isDefault", false);
163
+ }
164
+
165
+ get isMultiMaterial() {
166
+ const fromSubworkflows = this.subworkflows.some((sw) => sw.isMultiMaterial);
167
+ return this.prop("isMultiMaterial") || fromSubworkflows;
168
+ }
169
+
170
+ set isMultiMaterial(value) {
171
+ this.setProp("isMultiMaterial", value);
172
+ }
173
+
174
+ set isUsingDataset(value) {
175
+ this.setProp("isUsingDataset", value);
176
+ }
177
+
178
+ get isUsingDataset() {
179
+ return !!this.prop("isUsingDataset", false);
180
+ }
181
+
182
+ get properties() {
183
+ return lodash.uniq(lodash.flatten(this._subworkflows.map((x) => x.properties)));
184
+ }
185
+
186
+ get humanReadableProperties() {
187
+ return this.properties.map((name) => s.humanize(name));
188
+ }
189
+
190
+ get systemName() {
191
+ return s.slugify(`${this.usedApplicationNames.join(":")}-${this.name.toLowerCase()}`);
192
+ }
193
+
194
+ get defaultDescription() {
195
+ return `${this.usedModels
196
+ .join(", ")
197
+ .toUpperCase()} workflow using ${this.usedApplicationNames.join(", ")}.`;
198
+ }
199
+
200
+ get exabyteId() {
201
+ return this.prop("exabyteId");
202
+ }
203
+
204
+ get hash() {
205
+ return this.prop("hash", "");
206
+ }
207
+
208
+ get isOutdated() {
209
+ return this.prop("isOutdated", false);
210
+ }
211
+
212
+ get history() {
213
+ return this.prop("history", []);
214
+ }
215
+
216
+ setMethodData(methodData) {
217
+ this.subworkflows.forEach((sw) => {
218
+ const method = methodData.getMethodBySubworkflow(sw);
219
+ if (method) sw.model.setMethod(method);
220
+ });
221
+
222
+ this.workflows.forEach((wf) => {
223
+ wf.subworkflows.forEach((sw) => {
224
+ const method = methodData.getMethodBySubworkflow(sw);
225
+ if (method) sw.model.setMethod(method);
226
+ });
227
+ });
228
+ }
229
+
230
+ /**
231
+ * @param unit {Unit}
232
+ * @param head {Boolean}
233
+ * @param index {Number}
234
+ */
235
+ addUnit(unit, head = false, index = -1) {
236
+ const { units } = this;
237
+ if (units.length === 0) {
238
+ unit.head = true;
239
+ this.setUnits([unit]);
240
+ } else {
241
+ if (head) {
242
+ units.unshift(unit);
243
+ } else if (index >= 0) {
244
+ units.splice(index, 0, unit);
245
+ } else {
246
+ units.push(unit);
247
+ }
248
+ this.setUnits(setNextLinks(setUnitsHead(units)));
249
+ }
250
+ }
251
+
252
+ removeUnit(flowchartId) {
253
+ if (this.units.length < 2) return;
254
+
255
+ const unit = this.units.find((x) => x.flowchartId === flowchartId);
256
+ const previousUnit = this.units.find((x) => x.next === unit.flowchartId);
257
+ if (previousUnit) {
258
+ delete previousUnit.next;
259
+ }
260
+
261
+ this._subworkflows = this._subworkflows.filter((x) => x.id !== unit.id);
262
+ this._units = setNextLinks(
263
+ setUnitsHead(this._units.filter((x) => x.flowchartId !== flowchartId)),
264
+ );
265
+ }
266
+
267
+ /**
268
+ * @return Subworkflow[]
269
+ */
270
+ get subworkflows() {
271
+ return this._subworkflows;
272
+ }
273
+
274
+ get workflows() {
275
+ return this._workflows;
276
+ }
277
+
278
+ /*
279
+ * @param type {String|Object} Unit type, map or subworkflow
280
+ * @param head {Boolean}
281
+ * @param index {Number} Index at which the unit will be added. -1 by default (ignored).
282
+ */
283
+ addUnitType(type, head = false, index = -1) {
284
+ switch (type) {
285
+ case UNIT_TYPES.map:
286
+ // eslint-disable-next-line no-case-declarations
287
+ const workflowConfig = defaultWorkflowConfig;
288
+ // eslint-disable-next-line no-case-declarations
289
+ const mapUnit = new this._MapUnit();
290
+ workflowConfig._id = this._Workflow.generateWorkflowId(workflowConfig.name);
291
+ this.prop("workflows").push(workflowConfig);
292
+ this._workflows = this.prop("workflows").map((x) => new this._Workflow(x));
293
+ mapUnit.setWorkflowId(workflowConfig._id);
294
+ this.addUnit(mapUnit, head, index);
295
+ break;
296
+ case UNIT_TYPES.subworkflow:
297
+ this.addSubworkflow(this._Subworkflow.createDefault(), head, index);
298
+ break;
299
+ default:
300
+ console.log(`unit_type=${type} unrecognized, skipping.`);
301
+ }
302
+ }
303
+
304
+ addMapUnit(mapUnit, mapWorkflow) {
305
+ const mapWorkflowConfig = mapWorkflow.toJSON();
306
+ if (!mapWorkflowConfig._id)
307
+ mapWorkflowConfig._id = this._Workflow.generateWorkflowId(mapWorkflowConfig.name);
308
+ mapUnit.setWorkflowId(mapWorkflowConfig._id);
309
+ this.addUnit(mapUnit);
310
+ this._json.workflows.push(mapWorkflowConfig);
311
+ const me = this;
312
+ this._workflows = this.prop("workflows").map((x) => new me._Workflow(x));
313
+ }
314
+
315
+ findSubworkflowById(id) {
316
+ if (!id) return;
317
+
318
+ const workflows = this.workflows || [];
319
+ const subworkflows = this.subworkflows || [];
320
+
321
+ const subworkflow = subworkflows.find((sw) => sw.id === id);
322
+ if (subworkflow) return subworkflow;
323
+
324
+ const workflow = workflows.find((w) => w.findSubworkflowById(id));
325
+ if (workflow) return workflow.findSubworkflowById(id);
326
+
327
+ console.warn("attempted to find a non-existing subworkflow");
328
+ }
329
+
330
+ get allSubworkflows() {
331
+ const subworkflowsList = [];
332
+ this.subworkflows.forEach((sw) => subworkflowsList.push(sw));
333
+ this.workflows.forEach((workflow) => {
334
+ return Array.prototype.push.apply(subworkflowsList, workflow.allSubworkflows);
335
+ });
336
+ return subworkflowsList;
337
+ }
338
+
339
+ /**
340
+ * @summary Calculates hash of the workflow. Meaningful fields are units and subworkflows.
341
+ * units and subworkflows must be sorted topologically before hashing (already sorted).
342
+ */
343
+ calculateHash() {
344
+ const meaningfulFields = {
345
+ units: _.map(this.units, (u) => u.calculateHash()).join(),
346
+ subworkflows: _.map(this.subworkflows, (sw) => sw.calculateHash()).join(),
347
+ workflows: _.map(this.workflows, (w) => w.calculateHash()).join(),
348
+ };
349
+ return Utils.hash.calculateHashFromObject(meaningfulFields);
350
+ }
351
+ }