@mat3ra/mode 2025.10.2-0 → 2025.11.5-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 (40) hide show
  1. package/package.json +32 -17
  2. package/src/js/default_methods.ts +36 -0
  3. package/src/js/default_models.ts +11 -0
  4. package/src/js/generated/MethodSchemaMixin.ts +26 -0
  5. package/src/js/generated/ModelSchemaMixin.ts +23 -0
  6. package/src/{index.js → js/index.ts} +5 -11
  7. package/src/js/method.ts +67 -0
  8. package/src/js/methodConversionHandler.ts +142 -0
  9. package/src/{methods/factory.js → js/methods/factory.ts} +3 -1
  10. package/src/js/methods/pseudopotential.ts +86 -0
  11. package/src/js/model.ts +168 -0
  12. package/src/js/modelConversionHandler.ts +102 -0
  13. package/src/js/models/dft.ts +110 -0
  14. package/src/{models/factory.js → js/models/factory.ts} +9 -4
  15. package/src/{tree.js → js/tree.ts} +26 -33
  16. package/src/js/types/index.ts +37 -0
  17. package/tsconfig.json +3 -0
  18. package/.babelrc +0 -17
  19. package/dist/data/method_list.js +0 -1132
  20. package/dist/data/model_list.js +0 -786
  21. package/dist/data/model_method_map.js +0 -82
  22. package/dist/default_methods.js +0 -39
  23. package/dist/default_models.js +0 -14
  24. package/dist/index.js +0 -62
  25. package/dist/method.js +0 -84
  26. package/dist/methods/factory.js +0 -24
  27. package/dist/methods/pseudopotential.js +0 -100
  28. package/dist/model.js +0 -123
  29. package/dist/models/dft.js +0 -102
  30. package/dist/models/factory.js +0 -36
  31. package/dist/tree.js +0 -165
  32. package/src/data/method_list.js +0 -2
  33. package/src/data/model_list.js +0 -2
  34. package/src/data/model_method_map.js +0 -2
  35. package/src/default_methods.js +0 -38
  36. package/src/default_models.js +0 -9
  37. package/src/method.js +0 -77
  38. package/src/methods/pseudopotential.js +0 -99
  39. package/src/model.js +0 -127
  40. package/src/models/dft.js +0 -115
package/package.json CHANGED
@@ -1,26 +1,30 @@
1
1
  {
2
2
  "name": "@mat3ra/mode",
3
- "version": "2025.10.2-0",
3
+ "version": "2025.11.5-0",
4
4
  "description": "MOdel and method DEfinitions",
5
5
  "scripts": {
6
- "test": "nyc --reporter=text mocha --recursive --bail --require @babel/register/lib --require tests/setup.js tests",
6
+ "test": "nyc --reporter=text mocha --extension ts --recursive --bail --require ts-node/register/transpile-only \"tests/**/*.test.ts\"",
7
+ "pretest": "npm run transpile",
7
8
  "lint": "eslint src tests && prettier --write src tests",
8
9
  "lint:fix": "eslint --fix --cache src tests && prettier --write src tests",
9
- "transpile": "babel --out-dir dist src",
10
- "postinstall": "npm run transpile",
10
+ "transpile": "npm run transpile:js && npm run transpile:ts",
11
+ "transpile:js": "babel --out-dir dist src",
12
+ "transpile:ts": "tsc --project tsconfig.json",
11
13
  "prettier": "prettier --check src tests",
12
14
  "prepare": "husky install || exit 0",
13
- "prepublishOnly": "rm -rf dist; npm run transpile"
15
+ "prepublishOnly": "rm -rf dist; npm run transpile",
16
+ "generate-mixins": "ts-node scripts/generate-mixins.ts"
14
17
  },
15
18
  "repository": {
16
19
  "type": "git",
17
20
  "url": "https://github.com/Exabyte-io/mode.git"
18
21
  },
19
22
  "main": "dist/index.js",
23
+ "types": "dist/js/index.d.ts",
20
24
  "files": [
21
25
  "/dist",
22
26
  "/src",
23
- ".babelrc"
27
+ "tsconfig.json"
24
28
  ],
25
29
  "author": "Exabyte Inc.",
26
30
  "bugs": {
@@ -37,29 +41,40 @@
37
41
  "@babel/preset-react": "7.16.7",
38
42
  "@babel/register": "^7.16.0",
39
43
  "@babel/runtime-corejs3": "7.16.8",
44
+ "@types/lodash": "^4.14.202",
45
+ "@types/underscore": "^1.11.14",
46
+ "@types/node": "^20.11.30",
40
47
  "ajv": "^8.12.0",
41
48
  "js-yaml": "^4.1.0",
42
49
  "lodash": "^4.17.21",
43
50
  "mixwith": "^0.1.1",
51
+ "ts-node": "^10.9.2",
52
+ "typescript": "^5.4.0",
44
53
  "underscore": "^1.13.3",
45
54
  "underscore.string": "^3.3.4"
46
55
  },
47
56
  "devDependencies": {
48
- "@exabyte-io/eslint-config": "^2022.11.17-0",
49
- "@mat3ra/esse": "2024.4.19-1",
57
+ "@exabyte-io/eslint-config": "2025.5.13-0",
58
+ "@mat3ra/esse": "2025.10.8-0",
50
59
  "@mat3ra/standata": "2025.10.2-0",
51
- "@mat3ra/code": "2024.3.25-3",
60
+ "@mat3ra/code": "2025.10.8-0",
61
+ "@mat3ra/tsconfig": "2024.6.3-0",
62
+ "@types/chai": "^4.3.11",
63
+ "@types/mocha": "^10.0.6",
52
64
  "chai": "^4.3.4",
53
- "eslint": "7.32.0",
54
- "eslint-config-airbnb": "19.0.2",
65
+ "eslint": "^7.32.0",
66
+ "eslint-config-airbnb": "^19.0.2",
55
67
  "eslint-config-prettier": "^8.5.0",
56
- "eslint-import-resolver-exports": "^1.0.0-beta.2",
57
- "eslint-plugin-import": "2.25.3",
58
- "eslint-plugin-jsdoc": "37.1.0",
59
- "eslint-plugin-jsx-a11y": "6.5.1",
68
+ "eslint-import-resolver-exports": "^1.0.0-beta.5",
69
+ "eslint-import-resolver-meteor": "^0.4.0",
70
+ "eslint-import-resolver-node": "^0.3.9",
71
+ "eslint-plugin-import": "^2.25.3",
72
+ "eslint-plugin-jsdoc": "^37.1.0",
73
+ "eslint-plugin-jsx-a11y": "^6.5.1",
74
+ "eslint-plugin-mui-path-imports": "0.0.15",
60
75
  "eslint-plugin-prettier": "^4.2.1",
61
- "eslint-plugin-react": "7.30.0",
62
- "eslint-plugin-simple-import-sort": "7.0.0",
76
+ "eslint-plugin-react": "^7.30.0",
77
+ "eslint-plugin-simple-import-sort": "^7.0.0",
63
78
  "husky": "^7.0.4",
64
79
  "lint-staged": "^12.1.2",
65
80
  "mocha": "^9.1.3",
@@ -0,0 +1,36 @@
1
+ import { BaseMethod, BaseModel, SlugifiedEntry } from "@mat3ra/esse/dist/js/types";
2
+ import lodash from "lodash";
3
+
4
+ import { MODEL_NAMES, MODEL_TREE } from "./tree";
5
+
6
+ export const PseudopotentialMethodConfig: BaseMethod = {
7
+ type: "pseudopotential",
8
+ subtype: "us",
9
+ };
10
+
11
+ export const LocalOrbitalMethodConfig: BaseMethod = {
12
+ type: "localorbital",
13
+ subtype: "pople",
14
+ };
15
+
16
+ export const UnknownMethodConfig: BaseMethod = {
17
+ type: "unknown",
18
+ subtype: "unknown",
19
+ };
20
+
21
+ const mapSlugToNamedObject = (slug: string): SlugifiedEntry => {
22
+ return {
23
+ slug,
24
+ name: lodash.get(MODEL_NAMES, slug, slug),
25
+ };
26
+ };
27
+
28
+ export function allowedTypes(model: Pick<BaseModel, "type" | "subtype">): SlugifiedEntry[] {
29
+ const branch = lodash.get(MODEL_TREE, `${model.type}.${model.subtype}.methods`, {});
30
+ return lodash.keys(branch).map(mapSlugToNamedObject);
31
+ }
32
+
33
+ export function allowedSubtypes(model: Pick<BaseModel, "type" | "subtype">, type: string): SlugifiedEntry[] {
34
+ const branch = lodash.get(MODEL_TREE, `${model.type}.${model.subtype}.methods.${type}`, []);
35
+ return (branch as string[]).map(mapSlugToNamedObject);
36
+ }
@@ -0,0 +1,11 @@
1
+ import type { ModelConfig } from "./types";
2
+
3
+ export const DFTModelConfig: ModelConfig = {
4
+ type: "dft",
5
+ subtype: "gga",
6
+ };
7
+
8
+ export const UnknownModelConfig: ModelConfig = {
9
+ type: "unknown",
10
+ subtype: "unknown",
11
+ };
@@ -0,0 +1,26 @@
1
+ import type { InMemoryEntity } from "@mat3ra/code/dist/js/entity";
2
+ import type { BaseMethod } from "@mat3ra/esse/dist/js/types";
3
+
4
+ export type MethodSchemaMixin = BaseMethod;
5
+
6
+ export type MethodInMemoryEntity = InMemoryEntity & MethodSchemaMixin;
7
+
8
+ export function methodSchemaMixin(item: InMemoryEntity) {
9
+ // @ts-expect-error
10
+ const properties: InMemoryEntity & MethodSchemaMixin = {
11
+ get type() {
12
+ return this.requiredProp<BaseMethod["type"]>("type");
13
+ },
14
+ get subtype() {
15
+ return this.requiredProp<BaseMethod["subtype"]>("subtype");
16
+ },
17
+ get precision() {
18
+ return this.prop<BaseMethod["precision"]>("precision");
19
+ },
20
+ get data() {
21
+ return this.prop<BaseMethod["data"]>("data");
22
+ },
23
+ };
24
+
25
+ Object.defineProperties(item, Object.getOwnPropertyDescriptors(properties));
26
+ }
@@ -0,0 +1,23 @@
1
+ import type { InMemoryEntity } from "@mat3ra/code/dist/js/entity";
2
+ import type { BaseModel } from "@mat3ra/esse/dist/js/types";
3
+
4
+ export type ModelSchemaMixin = BaseModel;
5
+
6
+ export type ModelInMemoryEntity = InMemoryEntity & ModelSchemaMixin;
7
+
8
+ export function modelSchemaMixin(item: InMemoryEntity) {
9
+ // @ts-expect-error
10
+ const properties: InMemoryEntity & ModelSchemaMixin = {
11
+ get type() {
12
+ return this.requiredProp<BaseModel["type"]>("type");
13
+ },
14
+ get subtype() {
15
+ return this.requiredProp<BaseModel["subtype"]>("subtype");
16
+ },
17
+ get method() {
18
+ return this.requiredProp<BaseModel["method"]>("method");
19
+ },
20
+ };
21
+
22
+ Object.defineProperties(item, Object.getOwnPropertyDescriptors(properties));
23
+ }
@@ -1,22 +1,15 @@
1
- import { MethodStandata, ModelStandata } from "@mat3ra/standata";
2
-
3
1
  import * as default_methods from "./default_methods";
4
2
  import * as default_models from "./default_models";
5
3
  import { Method } from "./method";
4
+ import { MethodConversionHandler } from "./methodConversionHandler";
6
5
  import { MethodFactory } from "./methods/factory";
7
6
  import { PseudopotentialMethod } from "./methods/pseudopotential";
8
7
  import { Model } from "./model";
8
+ import { ModelConversionHandler } from "./modelConversionHandler";
9
9
  import { DFTModel } from "./models/dft";
10
10
  import { ModelFactory } from "./models/factory";
11
- // TODO : can replace these with subpackages in exports in package.json
12
11
  import * as tree from "./tree";
13
12
 
14
- const methodStandata = new MethodStandata();
15
- const modelStandata = new ModelStandata();
16
-
17
- const categorizedMethodList = methodStandata.getAll();
18
- const categorizedModelList = modelStandata.getAll();
19
-
20
13
  export {
21
14
  Method,
22
15
  Model,
@@ -24,9 +17,10 @@ export {
24
17
  ModelFactory,
25
18
  PseudopotentialMethod,
26
19
  DFTModel,
20
+ MethodConversionHandler,
21
+ ModelConversionHandler,
27
22
  tree,
28
23
  default_models,
29
24
  default_methods,
30
- categorizedModelList,
31
- categorizedMethodList,
32
25
  };
26
+
@@ -0,0 +1,67 @@
1
+ import { InMemoryEntity } from "@mat3ra/code/dist/js/entity";
2
+ import { deepClone } from "@mat3ra/code/dist/js/utils";
3
+ import type { Constructor } from "@mat3ra/code/dist/js/utils/types";
4
+ import type { BaseMethod, SlugifiedEntry } from "@mat3ra/esse/dist/js/types";
5
+ import lodash from "lodash";
6
+
7
+ import { PseudopotentialMethodConfig } from "./default_methods";
8
+ import { type MethodSchemaMixin, methodSchemaMixin } from "./generated/MethodSchemaMixin";
9
+
10
+ type Base = typeof InMemoryEntity & Constructor<MethodSchemaMixin>;
11
+
12
+ interface MethodData extends Record<string, unknown> {
13
+ searchText?: string;
14
+ }
15
+
16
+ export class Method extends (InMemoryEntity as Base) implements BaseMethod {
17
+ constructor(config: BaseMethod) {
18
+ const data = config.data || {};
19
+ super({ ...config, data });
20
+ }
21
+
22
+ cloneWithoutData(): Method {
23
+ const clone = this.clone() as Method;
24
+ clone.setData({});
25
+ return clone;
26
+ }
27
+
28
+ setSubtype(subtype: SlugifiedEntry): void {
29
+ this.setProp("subtype", subtype);
30
+ }
31
+
32
+ static get defaultConfig(): BaseMethod {
33
+ return PseudopotentialMethodConfig;
34
+ }
35
+
36
+ get searchText(): string {
37
+ return this.prop<string>("data.searchText", "");
38
+ }
39
+
40
+ setSearchText(searchText: string): void {
41
+ this.setData({ ...this.data, searchText });
42
+ }
43
+
44
+ setData(data: MethodData = {}): void {
45
+ this.setProp("data", data);
46
+ }
47
+
48
+ get omitInHashCalculation(): boolean {
49
+ const data = this.data as MethodData;
50
+ return !data?.searchText && lodash.isEmpty(lodash.omit(data, "searchText"));
51
+ }
52
+
53
+ cleanData(fieldsToExclude: string[] = []): MethodData {
54
+ const filteredData = { ...(this.data as MethodData) };
55
+ fieldsToExclude.forEach((field) => {
56
+ delete filteredData[field];
57
+ });
58
+ return filteredData;
59
+ }
60
+
61
+ toJSONWithCleanData(fieldsToExclude: string[] = []): BaseMethod {
62
+ const json = { ...this._json, data: this.cleanData(fieldsToExclude) };
63
+ return deepClone(json);
64
+ }
65
+ }
66
+
67
+ methodSchemaMixin(Method.prototype);
@@ -0,0 +1,142 @@
1
+ import {
2
+ BaseMethod,
3
+ CategorizedMethod,
4
+ CategorizedUnitMethod,
5
+ SlugifiedEntry,
6
+ } from "@mat3ra/esse/dist/js/types";
7
+
8
+ import { LocalOrbitalMethodConfig, UnknownMethodConfig } from "./default_methods";
9
+ import type { SimplifiedCategorizedMethod } from "./types";
10
+
11
+ export function safelyGetSlug(slugObj: SlugifiedEntry | string): SlugifiedEntry["slug"] {
12
+ return typeof slugObj === "string" ? slugObj : slugObj.slug;
13
+ }
14
+
15
+ export class MethodConversionHandler {
16
+ static convertToSimple(categorizedMethod: CategorizedMethod | undefined): BaseMethod {
17
+ if (!categorizedMethod) return this.convertUnknownToSimple();
18
+ const pspUnits = categorizedMethod.units.filter((unit) => unit.categories?.type === "psp");
19
+ const aoUnit = categorizedMethod.units.find((unit) => unit.categories?.type === "ao");
20
+ const regressionUnit = categorizedMethod.units.find((unit) => {
21
+ return unit.name && unit.name.includes("regression");
22
+ });
23
+ if (pspUnits.length) return this.convertPspUnitsToSimple(pspUnits);
24
+ if (aoUnit) return this.convertAoUnitToSimple();
25
+ if (regressionUnit) return this.convertRegressionUnitToSimple(regressionUnit);
26
+ return this.convertUnknownToSimple();
27
+ }
28
+
29
+ static convertUnknownToSimple(): BaseMethod {
30
+ return UnknownMethodConfig;
31
+ }
32
+
33
+ static convertPspUnitsToSimple(units: CategorizedUnitMethod[]): BaseMethod {
34
+ const [firstUnit, ...otherUnits] = units;
35
+ if (!firstUnit || !firstUnit.categories?.subtype) return this.convertUnknownToSimple();
36
+ const subtype = otherUnits.length ? "any" : safelyGetSlug(firstUnit.categories.subtype);
37
+ return {
38
+ type: "pseudopotential",
39
+ subtype,
40
+ };
41
+ }
42
+
43
+ static convertAoUnitToSimple(): BaseMethod {
44
+ return LocalOrbitalMethodConfig;
45
+ }
46
+
47
+ static convertRegressionUnitToSimple(unit: CategorizedUnitMethod): BaseMethod {
48
+ const type = unit.categories?.type || "linear";
49
+ const subtype = unit.categories?.subtype || "least_squares";
50
+ return {
51
+ type: safelyGetSlug(type),
52
+ subtype: safelyGetSlug(subtype),
53
+ precision: unit.precision as number | undefined,
54
+ };
55
+ }
56
+
57
+ static convertToCategorized(
58
+ simpleMethod: BaseMethod | undefined,
59
+ allMethods: CategorizedMethod[] = [],
60
+ ): SimplifiedCategorizedMethod | undefined {
61
+ switch (simpleMethod?.type) {
62
+ case "pseudopotential":
63
+ return this.convertPspToCategorized(simpleMethod, allMethods);
64
+ case "localorbital":
65
+ return this.convertAoToCategorized(simpleMethod);
66
+ case "linear":
67
+ case "kernel_ridge":
68
+ return this.convertRegressionToCategorized(simpleMethod);
69
+ default:
70
+ return undefined;
71
+ }
72
+ }
73
+
74
+ static convertPspToCategorized(
75
+ simpleMethod: BaseMethod,
76
+ allMethods: CategorizedMethod[] = [],
77
+ ): SimplifiedCategorizedMethod | undefined {
78
+ const subtype = safelyGetSlug(simpleMethod.subtype);
79
+ // the "any" subtype is equivalent to the method representing all planewave-pseudopotential
80
+ // methods. All other subtypes are equivalent to using a specific PW-PSP method.
81
+ const allPath =
82
+ "/qm/wf/none/psp/us::/qm/wf/none/psp/nc::/qm/wf/none/psp/nc-fr::/qm/wf/none/psp/paw::/qm/wf/none/pw/none";
83
+ const path =
84
+ subtype === "any"
85
+ ? allPath
86
+ : `/qm/wf/none/smearing/gaussian::/linalg/diag/none/davidson/none::/qm/wf/none/psp/${subtype}::/qm/wf/none/pw/none`;
87
+ return allMethods.find((categorized) => categorized.path === path);
88
+ }
89
+
90
+ static convertAoToCategorized(simpleMethod: BaseMethod): SimplifiedCategorizedMethod {
91
+ const subtype = safelyGetSlug(simpleMethod.subtype);
92
+ return {
93
+ units: [
94
+ {
95
+ parameters: {
96
+ basisSlug: "6-31G",
97
+ },
98
+ categories: {
99
+ tier1: "qm",
100
+ tier2: "wf",
101
+ type: "ao",
102
+ subtype,
103
+ },
104
+ tags: ["atomic orbital"],
105
+ name: "Wave function: LCAO - Pople basis set (6-31G)",
106
+ path: "/qm/wf/none/ao/pople?basisSlug=6-31G",
107
+ },
108
+ ],
109
+ name: "Wave function: LCAO - Pople basis set (6-31G)",
110
+ path: "/qm/wf/none/ao/pople?basisSlug=6-31G",
111
+ };
112
+ }
113
+
114
+ static convertRegressionToCategorized(simpleMethod: BaseMethod): SimplifiedCategorizedMethod {
115
+ const type = safelyGetSlug(simpleMethod.type);
116
+ const subtype = safelyGetSlug(simpleMethod.subtype);
117
+ const precision = simpleMethod.precision as number | undefined;
118
+ const path = `/none/none/none/${type}/${subtype}`;
119
+ const nameMap: Record<string, string> = {
120
+ kernel_ridge: "Kernel ridge",
121
+ linear: "Linear",
122
+ least_squares: "least squares",
123
+ ridge: "ridge",
124
+ };
125
+ const name = `${nameMap[type] || type} ${nameMap[subtype] || subtype} regression`;
126
+ return {
127
+ units: [
128
+ {
129
+ categories: {
130
+ type,
131
+ subtype,
132
+ },
133
+ name,
134
+ path,
135
+ precision,
136
+ },
137
+ ],
138
+ name,
139
+ path,
140
+ };
141
+ }
142
+ }
@@ -1,3 +1,5 @@
1
+ import { BaseMethod } from "@mat3ra/esse/dist/js/types";
2
+
1
3
  import { Method } from "../method";
2
4
  import { PseudopotentialMethod } from "./pseudopotential";
3
5
 
@@ -6,7 +8,7 @@ export class MethodFactory {
6
8
 
7
9
  static PseudopotentialMethod = PseudopotentialMethod;
8
10
 
9
- static create(config) {
11
+ static create(config: BaseMethod): Method {
10
12
  switch (config.type) {
11
13
  case "pseudopotential":
12
14
  return new this.PseudopotentialMethod(config);
@@ -0,0 +1,86 @@
1
+ import { safeMakeArray } from "@mat3ra/code/dist/js/utils";
2
+ import { BaseMethod } from "@mat3ra/esse/dist/js/types";
3
+ import _ from "underscore";
4
+
5
+ import { Method } from "../method";
6
+ import type { PseudopotentialCtor, PseudopotentialLike } from "../types";
7
+
8
+ export class PseudopotentialMethod extends Method {
9
+ PseudopotentialCls: PseudopotentialCtor | null;
10
+
11
+ constructor(config: BaseMethod) {
12
+ super(config);
13
+ this.PseudopotentialCls = null;
14
+ }
15
+
16
+ get pseudo(): Record<string, unknown>[] {
17
+ return this.prop<Record<string, unknown>[]>("data.pseudo", []);
18
+ }
19
+
20
+ get allPseudo(): Record<string, unknown>[] {
21
+ return this.prop<Record<string, unknown>[]>("data.allPseudo", []);
22
+ }
23
+
24
+ get pseudopotentials(): PseudopotentialLike[] {
25
+ if (!this.PseudopotentialCls) return [];
26
+ return this.pseudo.map((config) => new this.PseudopotentialCls!(config));
27
+ }
28
+
29
+ get allPseudopotentials(): PseudopotentialLike[] {
30
+ if (!this.PseudopotentialCls) return [];
31
+ return this.allPseudo.map((config) => new this.PseudopotentialCls!(config));
32
+ }
33
+
34
+ static extractExchangeCorrelationFromSubworkflow(subworkflow: any): {
35
+ approximation: string;
36
+ functional: string;
37
+ } {
38
+ const { model } = subworkflow;
39
+ const approximation = model.subtype;
40
+ const functionalValue = model.functional;
41
+ const functional = functionalValue && (functionalValue.slug || functionalValue);
42
+ return {
43
+ approximation,
44
+ functional: functional || "",
45
+ };
46
+ }
47
+
48
+ hasPseudopotentialFor(element: string): boolean {
49
+ return Boolean(this.pseudopotentials.find((pseudo) => pseudo.element === element));
50
+ }
51
+
52
+ setPseudopotentialPerElement(pseudo: PseudopotentialLike | undefined): void {
53
+ if (!pseudo) {
54
+ this.setPseudopotentials([]);
55
+ return;
56
+ }
57
+ const filtered = this.pseudopotentials.filter((item) => item.element !== pseudo.element);
58
+ filtered.push(pseudo);
59
+ this.setPseudopotentials(filtered);
60
+ }
61
+
62
+ addToAllPseudos(pseudos: PseudopotentialLike | PseudopotentialLike[]): void {
63
+ const list = safeMakeArray(pseudos);
64
+ const all = this.allPseudopotentials;
65
+ all.push(...list);
66
+ this.setAllPseudopotentials(all);
67
+ }
68
+
69
+ setPseudopotentials(pseudopotentials: PseudopotentialLike[]): void {
70
+ this.setData({
71
+ ...this.data,
72
+ pseudo: _.sortBy(pseudopotentials, "element").map((item) => item.toJSON()),
73
+ });
74
+ }
75
+
76
+ setAllPseudopotentials(pseudopotentials: PseudopotentialLike[]): void {
77
+ this.setData({
78
+ ...this.data,
79
+ allPseudo: _.sortBy(pseudopotentials, "element").map((item) => item.toJSON()),
80
+ });
81
+ }
82
+
83
+ toJSONWithCleanData(exclude: string[] = []): BaseMethod {
84
+ return super.toJSONWithCleanData(exclude.concat(["allPseudo"]));
85
+ }
86
+ }