@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.
- package/package.json +32 -17
- package/src/js/default_methods.ts +36 -0
- package/src/js/default_models.ts +11 -0
- package/src/js/generated/MethodSchemaMixin.ts +26 -0
- package/src/js/generated/ModelSchemaMixin.ts +23 -0
- package/src/{index.js → js/index.ts} +5 -11
- package/src/js/method.ts +67 -0
- package/src/js/methodConversionHandler.ts +142 -0
- package/src/{methods/factory.js → js/methods/factory.ts} +3 -1
- package/src/js/methods/pseudopotential.ts +86 -0
- package/src/js/model.ts +168 -0
- package/src/js/modelConversionHandler.ts +102 -0
- package/src/js/models/dft.ts +110 -0
- package/src/{models/factory.js → js/models/factory.ts} +9 -4
- package/src/{tree.js → js/tree.ts} +26 -33
- package/src/js/types/index.ts +37 -0
- package/tsconfig.json +3 -0
- package/.babelrc +0 -17
- package/dist/data/method_list.js +0 -1132
- package/dist/data/model_list.js +0 -786
- package/dist/data/model_method_map.js +0 -82
- package/dist/default_methods.js +0 -39
- package/dist/default_models.js +0 -14
- package/dist/index.js +0 -62
- package/dist/method.js +0 -84
- package/dist/methods/factory.js +0 -24
- package/dist/methods/pseudopotential.js +0 -100
- package/dist/model.js +0 -123
- package/dist/models/dft.js +0 -102
- package/dist/models/factory.js +0 -36
- package/dist/tree.js +0 -165
- package/src/data/method_list.js +0 -2
- package/src/data/model_list.js +0 -2
- package/src/data/model_method_map.js +0 -2
- package/src/default_methods.js +0 -38
- package/src/default_models.js +0 -9
- package/src/method.js +0 -77
- package/src/methods/pseudopotential.js +0 -99
- package/src/model.js +0 -127
- package/src/models/dft.js +0 -115
package/src/js/model.ts
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { InMemoryEntity } from "@mat3ra/code/dist/js/entity";
|
|
2
|
+
import type { Constructor } from "@mat3ra/code/dist/js/utils/types";
|
|
3
|
+
import type {
|
|
4
|
+
ApplicationSchemaBase,
|
|
5
|
+
BaseMethod,
|
|
6
|
+
BaseModel,
|
|
7
|
+
SlugifiedEntry,
|
|
8
|
+
SlugifiedEntryOrSlug,
|
|
9
|
+
} from "@mat3ra/esse/dist/js/types";
|
|
10
|
+
import lodash from "lodash";
|
|
11
|
+
|
|
12
|
+
import { DFTModelConfig } from "./default_models";
|
|
13
|
+
import { type ModelSchemaMixin, modelSchemaMixin } from "./generated/ModelSchemaMixin";
|
|
14
|
+
import { Method } from "./method";
|
|
15
|
+
import { MethodFactory } from "./methods/factory";
|
|
16
|
+
import { getTreeByApplicationNameAndVersion, MODEL_TREE, treeSlugToNamedObject } from "./tree";
|
|
17
|
+
import type { ModelConfig, MethodTreeBranch, ModelTree } from "./types";
|
|
18
|
+
|
|
19
|
+
const EMPTY_BRANCH: MethodTreeBranch = { methods: {} };
|
|
20
|
+
|
|
21
|
+
type Base = typeof InMemoryEntity & Constructor<ModelSchemaMixin>;
|
|
22
|
+
|
|
23
|
+
export class Model extends (InMemoryEntity as Base) implements BaseModel {
|
|
24
|
+
protected _application?: ApplicationSchemaBase;
|
|
25
|
+
|
|
26
|
+
protected _MethodFactory: typeof MethodFactory;
|
|
27
|
+
|
|
28
|
+
protected _method?: Method;
|
|
29
|
+
|
|
30
|
+
constructor(config: ModelConfig) {
|
|
31
|
+
const { application, ...entityConfig } = config as any;
|
|
32
|
+
super(entityConfig);
|
|
33
|
+
this._application = application as ApplicationSchemaBase | undefined;
|
|
34
|
+
this._MethodFactory = MethodFactory;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// get type(): string {
|
|
38
|
+
// return this.prop<string>("type", this.defaultType);
|
|
39
|
+
// }
|
|
40
|
+
|
|
41
|
+
// get subtype(): StringOrNamedSlug {
|
|
42
|
+
// return this.prop<StringOrNamedSlug>("subtype", this.defaultSubtype);
|
|
43
|
+
// }
|
|
44
|
+
|
|
45
|
+
setSubtype(subtype: SlugifiedEntryOrSlug): void {
|
|
46
|
+
this.setProp("subtype", subtype);
|
|
47
|
+
this.setMethod(this._MethodFactory.create(this.defaultMethodConfig));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
get allowedTypes(): SlugifiedEntry[] {
|
|
51
|
+
return Object.keys(this.tree).map((modelSlug) => treeSlugToNamedObject(modelSlug));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
get allowedSubtypes(): SlugifiedEntry[] {
|
|
55
|
+
return Object.keys(this.treeBranchForType).map((slug) => treeSlugToNamedObject(slug));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
get defaultType(): string {
|
|
59
|
+
return this.allowedTypes[0]?.slug || "";
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
get defaultSubtype(): string {
|
|
63
|
+
return this.allowedSubtypes[0]?.slug || "";
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
get tree(): ModelTree {
|
|
67
|
+
if (this._application) {
|
|
68
|
+
const treeByApplication = this.treeByApplicationNameAndVersion;
|
|
69
|
+
if (treeByApplication) return treeByApplication;
|
|
70
|
+
}
|
|
71
|
+
return MODEL_TREE;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
get treeBranchForType(): Record<string, MethodTreeBranch> {
|
|
75
|
+
return this.tree[this.type] || {};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
get treeBranchForSubType(): MethodTreeBranch {
|
|
79
|
+
return this.treeBranchForType[this.subtypeSlug] || EMPTY_BRANCH;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
get treeByApplicationNameAndVersion(): ModelTree | undefined {
|
|
83
|
+
if (!this._application) return undefined;
|
|
84
|
+
const { name, version } = this._application;
|
|
85
|
+
return getTreeByApplicationNameAndVersion({ name, version });
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
get groupSlug(): string {
|
|
89
|
+
const subtype = this.subtypeSlug;
|
|
90
|
+
if (!this._application) return `${this.type}:${subtype}`;
|
|
91
|
+
return `${this._application.shortName}:${this.type}:${subtype}`;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
get Method(): Method {
|
|
95
|
+
if (!this._method) {
|
|
96
|
+
const methodOrConfig = this.method;
|
|
97
|
+
const config = methodOrConfig || this.defaultMethodConfig;
|
|
98
|
+
this._method = this._MethodFactory.create(config);
|
|
99
|
+
}
|
|
100
|
+
return this._method;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
setMethod(method: Method): void {
|
|
104
|
+
this._method = method;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
get methodsFromTree(): Record<string, string[]> {
|
|
108
|
+
return this.treeBranchForSubType.methods || {};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
get methodTypes(): SlugifiedEntry[] {
|
|
112
|
+
return Object.keys(this.methodsFromTree).map((type) => treeSlugToNamedObject(type));
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
get methodSubtypes(): SlugifiedEntry[] {
|
|
116
|
+
const { type } = this.method;
|
|
117
|
+
const subtypes = this.methodsFromTree[type] || [];
|
|
118
|
+
return subtypes.map((slug) => treeSlugToNamedObject(slug));
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
get defaultMethodConfig(): BaseMethod {
|
|
122
|
+
const methodTypes = Object.keys(this.methodsFromTree);
|
|
123
|
+
const type = methodTypes[0];
|
|
124
|
+
if (!type) return Method.defaultConfig;
|
|
125
|
+
const subtype = this.methodsFromTree[type]?.[0];
|
|
126
|
+
if (!subtype) return Method.defaultConfig;
|
|
127
|
+
return { type, subtype };
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
static get defaultConfig(): ModelConfig {
|
|
131
|
+
return {
|
|
132
|
+
...DFTModelConfig,
|
|
133
|
+
method: Method.defaultConfig,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
static get allTypes(): SlugifiedEntry[] {
|
|
138
|
+
return Object.keys(MODEL_TREE).map((modelSlug) => treeSlugToNamedObject(modelSlug));
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
toJSON(): Record<string, unknown> {
|
|
142
|
+
const json = super.toJSON();
|
|
143
|
+
return {
|
|
144
|
+
...json,
|
|
145
|
+
type: this.type,
|
|
146
|
+
subtype: this.subtype,
|
|
147
|
+
method: (this.method as any).toJSONWithCleanData(),
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
protected _stringToSlugifiedObject(slug: SlugifiedEntryOrSlug): SlugifiedEntry {
|
|
152
|
+
if (lodash.isString(slug)) {
|
|
153
|
+
return { slug } as SlugifiedEntry;
|
|
154
|
+
}
|
|
155
|
+
return slug;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
get isUnknown(): boolean {
|
|
159
|
+
return this.type === "unknown";
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
protected get subtypeSlug(): string {
|
|
163
|
+
const subtype = this.subtype as SlugifiedEntryOrSlug;
|
|
164
|
+
return typeof subtype === "string" ? subtype : subtype.slug;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
modelSchemaMixin(Model.prototype);
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { CategorizedModel, SlugifiedEntryOrSlug } from "@mat3ra/esse/dist/js/types";
|
|
2
|
+
|
|
3
|
+
import * as tree from "./tree";
|
|
4
|
+
import type { ModelConfig, SimplifiedCategorizedModel } from "./types";
|
|
5
|
+
|
|
6
|
+
export function safelyGetSlug(slugObj: SlugifiedEntryOrSlug): string {
|
|
7
|
+
return typeof slugObj === "string" ? slugObj : slugObj.slug;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export class ModelConversionHandler {
|
|
11
|
+
static convertToSimple(categorizedModel: CategorizedModel | undefined): ModelConfig {
|
|
12
|
+
if (!categorizedModel) return this.convertUnknownToSimple();
|
|
13
|
+
switch (categorizedModel.categories.tier3) {
|
|
14
|
+
case "dft":
|
|
15
|
+
return this.convertDftToSimple(categorizedModel);
|
|
16
|
+
case "ml":
|
|
17
|
+
return this.convertMlToSimple();
|
|
18
|
+
default:
|
|
19
|
+
return this.convertUnknownToSimple();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
static convertDftToSimple(categorizedModel: CategorizedModel): ModelConfig {
|
|
24
|
+
if (!categorizedModel.categories?.subtype) return this.convertUnknownToSimple();
|
|
25
|
+
const subtypeCategory = categorizedModel.categories.subtype as SlugifiedEntryOrSlug;
|
|
26
|
+
const subtype = safelyGetSlug(subtypeCategory);
|
|
27
|
+
const functionalParam = (categorizedModel.parameters as any)?.functional;
|
|
28
|
+
const functionalSlug = functionalParam
|
|
29
|
+
? safelyGetSlug(functionalParam as SlugifiedEntryOrSlug)
|
|
30
|
+
: "";
|
|
31
|
+
return {
|
|
32
|
+
type: "dft",
|
|
33
|
+
subtype,
|
|
34
|
+
functional: tree.treeSlugToNamedObject(functionalSlug),
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
static convertMlToSimple(): ModelConfig {
|
|
39
|
+
return {
|
|
40
|
+
type: "ml",
|
|
41
|
+
subtype: "re",
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
static convertUnknownToSimple(): ModelConfig {
|
|
46
|
+
return {
|
|
47
|
+
type: "unknown",
|
|
48
|
+
subtype: "unknown",
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
static convertToCategorized(
|
|
53
|
+
simpleModel: ModelConfig | undefined,
|
|
54
|
+
allModels: CategorizedModel[] = [],
|
|
55
|
+
): SimplifiedCategorizedModel | undefined {
|
|
56
|
+
switch (simpleModel?.type) {
|
|
57
|
+
case "dft":
|
|
58
|
+
return this.convertDftToCategorized(simpleModel, allModels);
|
|
59
|
+
case "ml":
|
|
60
|
+
return this.convertMlToCategorized(simpleModel);
|
|
61
|
+
case "unknown":
|
|
62
|
+
return undefined;
|
|
63
|
+
default:
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
static convertDftToCategorized(
|
|
69
|
+
simpleModel: ModelConfig,
|
|
70
|
+
allModels: CategorizedModel[] = [],
|
|
71
|
+
): SimplifiedCategorizedModel | undefined {
|
|
72
|
+
const { subtype, functional: functionalStringOrObject } = simpleModel;
|
|
73
|
+
const defaultFunctionals: Record<string, string> = {
|
|
74
|
+
lda: "pz",
|
|
75
|
+
gga: "pbe",
|
|
76
|
+
hybrid: "b3lyp",
|
|
77
|
+
};
|
|
78
|
+
let functional: string | undefined;
|
|
79
|
+
if (!functionalStringOrObject) {
|
|
80
|
+
functional = defaultFunctionals[subtype as string];
|
|
81
|
+
} else {
|
|
82
|
+
functional = safelyGetSlug(functionalStringOrObject as SlugifiedEntryOrSlug);
|
|
83
|
+
}
|
|
84
|
+
const path = `/pb/qm/dft/ksdft/${subtype}?functional=${functional}`;
|
|
85
|
+
return allModels.find((categorized) => categorized.path === path);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
static convertMlToCategorized(simpleModel: ModelConfig): SimplifiedCategorizedModel {
|
|
89
|
+
const subtype = safelyGetSlug(simpleModel.subtype as SlugifiedEntryOrSlug);
|
|
90
|
+
return {
|
|
91
|
+
name: "Regression",
|
|
92
|
+
path: "/st/det/ml/re/none",
|
|
93
|
+
categories: {
|
|
94
|
+
tier1: "st",
|
|
95
|
+
tier2: "det",
|
|
96
|
+
tier3: "ml",
|
|
97
|
+
type: subtype,
|
|
98
|
+
},
|
|
99
|
+
parameters: {},
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { safeMakeArray } from "@mat3ra/code/dist/js/utils";
|
|
2
|
+
import { SlugifiedEntry, SlugifiedEntryOrSlug } from "@mat3ra/esse/dist/js/types";
|
|
3
|
+
import _ from "underscore";
|
|
4
|
+
|
|
5
|
+
import { MethodFactory } from "../methods/factory";
|
|
6
|
+
import { Model } from "../model";
|
|
7
|
+
import { treeSlugToNamedObject } from "../tree";
|
|
8
|
+
import type { ModelConfig } from "../types";
|
|
9
|
+
|
|
10
|
+
export class DFTModel extends Model {
|
|
11
|
+
constructor(config: ModelConfig & { MethodFactory?: typeof MethodFactory }) {
|
|
12
|
+
super(config);
|
|
13
|
+
this._MethodFactory = config.MethodFactory || MethodFactory;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
get groupSlug(): string {
|
|
17
|
+
const functionalSlug = this.functional.slug;
|
|
18
|
+
const refinersSlug = this.refiners.map((o) => o.slug).join("+");
|
|
19
|
+
const modifiersSlug = this.modifiers.map((o) => o.slug).join("+");
|
|
20
|
+
const slugs = [
|
|
21
|
+
this._application?.shortName,
|
|
22
|
+
this.type,
|
|
23
|
+
this.subtype,
|
|
24
|
+
functionalSlug,
|
|
25
|
+
refinersSlug,
|
|
26
|
+
modifiersSlug,
|
|
27
|
+
].filter(Boolean);
|
|
28
|
+
return slugs.join(":");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
get defaultFunctional(): SlugifiedEntry {
|
|
32
|
+
const [slug] = this.treeBranchForSubType.functionals || [];
|
|
33
|
+
return treeSlugToNamedObject(slug);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
get defaultRefiners(): SlugifiedEntry[] {
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
get defaultModifiers(): SlugifiedEntry[] {
|
|
41
|
+
return [];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
get functional(): SlugifiedEntry {
|
|
45
|
+
return this.prop<SlugifiedEntry>("functional", this.defaultFunctional);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
get refiners(): SlugifiedEntry[] {
|
|
49
|
+
return this.prop<SlugifiedEntry[]>("refiners", this.defaultRefiners);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
get modifiers(): SlugifiedEntry[] {
|
|
53
|
+
return this.prop<SlugifiedEntry[]>("modifiers", this.defaultModifiers);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
setSubtype(subtype: SlugifiedEntryOrSlug): void {
|
|
57
|
+
this.setProp("subtype", subtype);
|
|
58
|
+
this.setFunctional(this.defaultFunctional);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
setFunctional(functional: SlugifiedEntryOrSlug): void {
|
|
62
|
+
this.setProp("functional", this._stringToSlugifiedObject(functional));
|
|
63
|
+
this.setMethod(this._MethodFactory.create(this.defaultMethodConfig));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private _setArrayProp(
|
|
67
|
+
name: "refiners" | "modifiers",
|
|
68
|
+
data: SlugifiedEntryOrSlug | SlugifiedEntryOrSlug[],
|
|
69
|
+
): void {
|
|
70
|
+
const normalized = safeMakeArray(data).map((item) => this._stringToSlugifiedObject(item));
|
|
71
|
+
this.setProp(name, normalized);
|
|
72
|
+
(this as unknown as Record<string, SlugifiedEntry[]>)[`_${name}`] = normalized;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
setRefiners(refiners: SlugifiedEntryOrSlug | SlugifiedEntryOrSlug[]): void {
|
|
76
|
+
this._setArrayProp("refiners", refiners);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
setModifiers(modifiers: SlugifiedEntryOrSlug | SlugifiedEntryOrSlug[]): void {
|
|
80
|
+
this._setArrayProp("modifiers", modifiers);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
toJSON(): Record<string, unknown> {
|
|
84
|
+
const pickSlugFromObject = (item: SlugifiedEntry) => _.pick(item, "slug");
|
|
85
|
+
return {
|
|
86
|
+
...super.toJSON(),
|
|
87
|
+
functional: pickSlugFromObject(this.functional),
|
|
88
|
+
refiners: this.refiners,
|
|
89
|
+
modifiers: this.modifiers,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
get allFunctionals(): SlugifiedEntry[] {
|
|
94
|
+
return (this.treeBranchForSubType.functionals || []).map((slug) =>
|
|
95
|
+
treeSlugToNamedObject(slug),
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
get allRefiners(): SlugifiedEntry[] {
|
|
100
|
+
return (this.treeBranchForSubType.refiners || []).map((slug) =>
|
|
101
|
+
treeSlugToNamedObject(slug),
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
get allModifiers(): SlugifiedEntry[] {
|
|
106
|
+
return (this.treeBranchForSubType.modifiers || []).map((slug) =>
|
|
107
|
+
treeSlugToNamedObject(slug),
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Model } from "../model";
|
|
2
2
|
import { getDefaultModelTypeForApplication } from "../tree";
|
|
3
|
+
import type { ModelConfig } from "../types";
|
|
3
4
|
import { DFTModel } from "./dft";
|
|
4
5
|
|
|
5
6
|
export class ModelFactory {
|
|
@@ -7,7 +8,7 @@ export class ModelFactory {
|
|
|
7
8
|
|
|
8
9
|
static Model = Model;
|
|
9
10
|
|
|
10
|
-
static create(config) {
|
|
11
|
+
static create(config: ModelConfig): Model {
|
|
11
12
|
switch (config.type) {
|
|
12
13
|
case "dft":
|
|
13
14
|
return new this.DFTModel(config);
|
|
@@ -16,13 +17,17 @@ export class ModelFactory {
|
|
|
16
17
|
}
|
|
17
18
|
}
|
|
18
19
|
|
|
19
|
-
static createFromApplication(config) {
|
|
20
|
+
static createFromApplication(config: ModelConfig): Model {
|
|
20
21
|
const { application } = config;
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
if (!application) {
|
|
23
|
+
throw new Error("ModelFactory.createFromApplication: application is required");
|
|
24
|
+
}
|
|
25
|
+
const type = getDefaultModelTypeForApplication(application);
|
|
26
|
+
if (!type) {
|
|
23
27
|
throw new Error(
|
|
24
28
|
`ModelFactory.createFromApplication: cannot determine model type: ${type}`,
|
|
25
29
|
);
|
|
30
|
+
}
|
|
26
31
|
return this.create({ ...config, type });
|
|
27
32
|
}
|
|
28
33
|
}
|
|
@@ -1,24 +1,26 @@
|
|
|
1
1
|
import { deepClone } from "@mat3ra/code/dist/js/utils";
|
|
2
|
-
import {
|
|
2
|
+
import { ApplicationSchemaBase, SlugifiedEntry } from "@mat3ra/esse/dist/js/types";
|
|
3
3
|
import lodash from "lodash";
|
|
4
4
|
import _ from "underscore";
|
|
5
5
|
|
|
6
|
+
import type { ModelTree } from "./types";
|
|
7
|
+
|
|
6
8
|
// TODO: migrate to use manifest instead
|
|
7
9
|
|
|
8
10
|
export const METHODS = {
|
|
9
11
|
pseudopotential: "pseudopotential",
|
|
10
12
|
localorbital: "localorbital",
|
|
11
13
|
unknown: "unknown",
|
|
12
|
-
};
|
|
14
|
+
} as const;
|
|
13
15
|
|
|
14
|
-
const methods = {
|
|
16
|
+
const methods: Record<string, string[]> = {
|
|
15
17
|
[METHODS.pseudopotential]: ["paw", "nc", "nc-fr", "us"],
|
|
16
18
|
// TODO: Add additional basis set options, once user choice of specific (i.e 3-21G vs cc-pVDZ) is implemented.
|
|
17
19
|
[METHODS.localorbital]: ["pople"],
|
|
18
20
|
[METHODS.unknown]: ["unknown"],
|
|
19
21
|
};
|
|
20
22
|
|
|
21
|
-
export const getPseudopotentialTypesFromTree = () => methods[METHODS.pseudopotential];
|
|
23
|
+
export const getPseudopotentialTypesFromTree = (): string[] => methods[METHODS.pseudopotential];
|
|
22
24
|
|
|
23
25
|
// DFT-specific
|
|
24
26
|
|
|
@@ -48,16 +50,16 @@ const DFTModelTree = {
|
|
|
48
50
|
},
|
|
49
51
|
};
|
|
50
52
|
|
|
51
|
-
export const getDFTFunctionalsFromTree = () => Object.keys(DFTModelTree);
|
|
53
|
+
export const getDFTFunctionalsFromTree = (): string[] => Object.keys(DFTModelTree);
|
|
52
54
|
|
|
53
|
-
export const getDFTFunctionalsByApproximation = (approximation) => {
|
|
54
|
-
const branch = DFTModelTree[approximation];
|
|
55
|
+
export const getDFTFunctionalsByApproximation = (approximation: string): string[] | undefined => {
|
|
56
|
+
const branch = DFTModelTree[approximation as keyof typeof DFTModelTree];
|
|
55
57
|
return branch && branch.functionals;
|
|
56
58
|
};
|
|
57
59
|
|
|
58
60
|
// GENERAL
|
|
59
61
|
|
|
60
|
-
export const MODEL_TREE = {
|
|
62
|
+
export const MODEL_TREE: ModelTree = {
|
|
61
63
|
dft: DFTModelTree,
|
|
62
64
|
ml: {
|
|
63
65
|
re: {
|
|
@@ -76,7 +78,7 @@ export const MODEL_TREE = {
|
|
|
76
78
|
},
|
|
77
79
|
};
|
|
78
80
|
|
|
79
|
-
export const MODEL_NAMES = {
|
|
81
|
+
export const MODEL_NAMES: Record<string, string> = {
|
|
80
82
|
dft: "density functional theory",
|
|
81
83
|
lda: "local density approximation",
|
|
82
84
|
gga: "generalized gradient approximation",
|
|
@@ -85,7 +87,7 @@ export const MODEL_NAMES = {
|
|
|
85
87
|
re: "regression",
|
|
86
88
|
};
|
|
87
89
|
|
|
88
|
-
export const treeSlugToNamedObject = (modelSlug) => {
|
|
90
|
+
export const treeSlugToNamedObject = (modelSlug: string): SlugifiedEntry => {
|
|
89
91
|
return {
|
|
90
92
|
slug: modelSlug,
|
|
91
93
|
name: lodash.get(MODEL_NAMES, modelSlug, modelSlug),
|
|
@@ -97,11 +99,13 @@ export const treeSlugToNamedObject = (modelSlug) => {
|
|
|
97
99
|
// demonstrate how tree can be modified
|
|
98
100
|
// VASP_MODELS_TREE.gga.functionals = _.omit(VASP_MODELS_TREE.gga.functionals);
|
|
99
101
|
|
|
100
|
-
|
|
101
|
-
const ESPRESSO_MODELS_TREE = deepClone(_.pick(MODEL_TREE, "dft"));
|
|
102
|
-
const NWCHEM_MODELS_TREE = deepClone(_.pick(MODEL_TREE, "dft"));
|
|
102
|
+
type DftOnlyTree = { dft: typeof DFTModelTree };
|
|
103
103
|
|
|
104
|
-
|
|
104
|
+
const VASP_MODELS_TREE = deepClone(_.pick(MODEL_TREE, "dft")) as DftOnlyTree;
|
|
105
|
+
const ESPRESSO_MODELS_TREE = deepClone(_.pick(MODEL_TREE, "dft")) as DftOnlyTree;
|
|
106
|
+
const NWCHEM_MODELS_TREE = deepClone(_.pick(MODEL_TREE, "dft")) as DftOnlyTree;
|
|
107
|
+
|
|
108
|
+
(["gga", "lda"] as const).forEach((approximation) => {
|
|
105
109
|
// pick "paw" for vasp
|
|
106
110
|
VASP_MODELS_TREE.dft[approximation].methods.pseudopotential = VASP_MODELS_TREE.dft[
|
|
107
111
|
approximation
|
|
@@ -112,10 +116,13 @@ const NWCHEM_MODELS_TREE = deepClone(_.pick(MODEL_TREE, "dft"));
|
|
|
112
116
|
ESPRESSO_MODELS_TREE.dft[approximation].methods.pseudopotential.reverse();
|
|
113
117
|
});
|
|
114
118
|
|
|
115
|
-
const UNKNOWN_MODELS_TREE = _.pick(MODEL_TREE, "unknown");
|
|
119
|
+
const UNKNOWN_MODELS_TREE = _.pick(MODEL_TREE, "unknown") as ModelTree;
|
|
116
120
|
// const ML_MODELS_TREE = _.pick(MODEL_TREE, "ml");
|
|
117
121
|
|
|
118
|
-
const MODELS_TREE_CONFIGS_BY_APPLICATION_NAME_VERSION
|
|
122
|
+
const MODELS_TREE_CONFIGS_BY_APPLICATION_NAME_VERSION: Array<{
|
|
123
|
+
name: string;
|
|
124
|
+
tree: ModelTree;
|
|
125
|
+
}> = [
|
|
119
126
|
{
|
|
120
127
|
name: "vasp",
|
|
121
128
|
tree: VASP_MODELS_TREE,
|
|
@@ -148,28 +155,14 @@ const MODELS_TREE_CONFIGS_BY_APPLICATION_NAME_VERSION = [
|
|
|
148
155
|
|
|
149
156
|
export const getTreeByApplicationNameAndVersion = ({
|
|
150
157
|
name,
|
|
151
|
-
|
|
152
|
-
version,
|
|
153
|
-
}) => {
|
|
158
|
+
}: Pick<ApplicationSchemaBase, "name" | "version">): ModelTree => {
|
|
154
159
|
// TODO: add logic to filter by version when necessary
|
|
155
160
|
const cfgs = MODELS_TREE_CONFIGS_BY_APPLICATION_NAME_VERSION.filter(
|
|
156
161
|
(cfg) => cfg.name === name,
|
|
157
|
-
).map((
|
|
162
|
+
).map((cfg) => cfg.tree);
|
|
158
163
|
return Object.assign({}, ...cfgs);
|
|
159
164
|
};
|
|
160
165
|
|
|
161
|
-
export const getDefaultModelTypeForApplication = (application) => {
|
|
166
|
+
export const getDefaultModelTypeForApplication = (application: ApplicationSchemaBase): string => {
|
|
162
167
|
return Object.keys(getTreeByApplicationNameAndVersion(application))[0];
|
|
163
168
|
};
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Filter list of method configs based on model
|
|
167
|
-
* @param {Object[]} methodList - Array of method configs
|
|
168
|
-
* @param {Object} model - Model config for which methods should be filtered
|
|
169
|
-
* @return {Object[]}
|
|
170
|
-
*/
|
|
171
|
-
export function filterMethodsByModel({ methodList, model }) {
|
|
172
|
-
if (!model) return [];
|
|
173
|
-
const modelMethodFilter = new ModelMethodFilter();
|
|
174
|
-
return modelMethodFilter.getCompatibleMethods(model, methodList);
|
|
175
|
-
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ApplicationSchemaBase,
|
|
3
|
+
BaseModel,
|
|
4
|
+
CategorizedMethod,
|
|
5
|
+
CategorizedModel,
|
|
6
|
+
CategorizedUnitMethod,
|
|
7
|
+
} from "@mat3ra/esse/dist/js/types";
|
|
8
|
+
|
|
9
|
+
export type ModelConfig = Pick<BaseModel, "type" | "subtype"> &
|
|
10
|
+
Partial<Omit<BaseModel, "type" | "subtype">> & {
|
|
11
|
+
application?: ApplicationSchemaBase;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export type SimplifiedCategorizedModel = Pick<
|
|
15
|
+
CategorizedModel,
|
|
16
|
+
"name" | "path" | "categories" | "parameters"
|
|
17
|
+
>;
|
|
18
|
+
|
|
19
|
+
export type SimplifiedCategorizedMethod = Pick<CategorizedMethod, "name" | "path"> & {
|
|
20
|
+
units: CategorizedUnitMethod[];
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export interface PseudopotentialLike {
|
|
24
|
+
element?: string;
|
|
25
|
+
toJSON(): Record<string, unknown>;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type PseudopotentialCtor = new (config: Record<string, unknown>) => PseudopotentialLike;
|
|
29
|
+
|
|
30
|
+
export interface MethodTreeBranch {
|
|
31
|
+
methods: Record<string, string[]>;
|
|
32
|
+
functionals?: string[];
|
|
33
|
+
refiners?: string[];
|
|
34
|
+
modifiers?: string[];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export type ModelTree = Record<string, Record<string, MethodTreeBranch>>;
|
package/tsconfig.json
ADDED