@mat3ra/made 2024.3.22-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/.babelrc +10 -0
- package/.eslintrc.json +11 -0
- package/.mocharc.json +5 -0
- package/.prettierignore +1 -0
- package/.prettierrc +6 -0
- package/LICENSE.md +15 -0
- package/README.md +167 -0
- package/dist/abstract/array_with_ids.d.ts +43 -0
- package/dist/abstract/array_with_ids.js +88 -0
- package/dist/abstract/scalar_with_id.d.ts +25 -0
- package/dist/abstract/scalar_with_id.js +44 -0
- package/dist/basis/basis.d.ts +269 -0
- package/dist/basis/basis.js +499 -0
- package/dist/basis/constrained_basis.d.ts +56 -0
- package/dist/basis/constrained_basis.js +90 -0
- package/dist/basis/types.d.ts +1 -0
- package/dist/basis/types.js +2 -0
- package/dist/cell/cell.d.ts +45 -0
- package/dist/cell/cell.js +88 -0
- package/dist/cell/conventional_cell.d.ts +22 -0
- package/dist/cell/conventional_cell.js +83 -0
- package/dist/cell/primitive_cell.d.ts +9 -0
- package/dist/cell/primitive_cell.js +166 -0
- package/dist/constants.d.ts +2 -0
- package/dist/constants.js +25 -0
- package/dist/constraints/constraints.d.ts +45 -0
- package/dist/constraints/constraints.js +49 -0
- package/dist/lattice/lattice.d.ts +104 -0
- package/dist/lattice/lattice.js +208 -0
- package/dist/lattice/lattice_bravais.d.ts +59 -0
- package/dist/lattice/lattice_bravais.js +120 -0
- package/dist/lattice/lattice_vectors.d.ts +46 -0
- package/dist/lattice/lattice_vectors.js +98 -0
- package/dist/lattice/reciprocal/lattice_reciprocal.d.ts +75 -0
- package/dist/lattice/reciprocal/lattice_reciprocal.js +148 -0
- package/dist/lattice/reciprocal/paths.d.ts +24 -0
- package/dist/lattice/reciprocal/paths.js +136 -0
- package/dist/lattice/reciprocal/symmetry_points.d.ts +8 -0
- package/dist/lattice/reciprocal/symmetry_points.js +866 -0
- package/dist/lattice/types.d.ts +49 -0
- package/dist/lattice/types.js +127 -0
- package/dist/lattice/unit_cell.d.ts +30 -0
- package/dist/lattice/unit_cell.js +31 -0
- package/dist/made.d.ts +40 -0
- package/dist/made.js +39 -0
- package/dist/material.d.ts +1562 -0
- package/dist/material.js +317 -0
- package/dist/math.d.ts +395 -0
- package/dist/math.js +7 -0
- package/dist/parsers/cif.d.ts +10 -0
- package/dist/parsers/cif.js +21 -0
- package/dist/parsers/errors.d.ts +5 -0
- package/dist/parsers/errors.js +11 -0
- package/dist/parsers/espresso.d.ts +10 -0
- package/dist/parsers/espresso.js +24 -0
- package/dist/parsers/native_format_parsers.d.ts +26 -0
- package/dist/parsers/native_format_parsers.js +52 -0
- package/dist/parsers/parsers.d.ts +13 -0
- package/dist/parsers/parsers.js +17 -0
- package/dist/parsers/poscar.d.ts +31 -0
- package/dist/parsers/poscar.js +180 -0
- package/dist/parsers/xyz.d.ts +62 -0
- package/dist/parsers/xyz.js +167 -0
- package/dist/parsers/xyz_combinatorial_basis.d.ts +64 -0
- package/dist/parsers/xyz_combinatorial_basis.js +241 -0
- package/dist/tools/basis.d.ts +22 -0
- package/dist/tools/basis.js +100 -0
- package/dist/tools/cell.d.ts +9 -0
- package/dist/tools/cell.js +39 -0
- package/dist/tools/index.d.ts +11 -0
- package/dist/tools/index.js +15 -0
- package/dist/tools/material.d.ts +25 -0
- package/dist/tools/material.js +54 -0
- package/dist/tools/supercell.d.ts +22 -0
- package/dist/tools/supercell.js +62 -0
- package/dist/tools/surface.d.ts +10 -0
- package/dist/tools/surface.js +147 -0
- package/dist/types.d.ts +3 -0
- package/dist/types.js +2 -0
- package/package.json +89 -0
- package/pyproject.toml +77 -0
- package/src/js/abstract/array_with_ids.ts +100 -0
- package/src/js/abstract/scalar_with_id.ts +53 -0
- package/src/js/basis/basis.ts +607 -0
- package/src/js/basis/constrained_basis.ts +107 -0
- package/src/js/basis/types.ts +1 -0
- package/src/js/cell/cell.ts +109 -0
- package/src/js/cell/conventional_cell.ts +89 -0
- package/src/js/cell/primitive_cell.ts +189 -0
- package/src/js/constants.js +4 -0
- package/src/js/constraints/constraints.ts +63 -0
- package/src/js/lattice/lattice.ts +229 -0
- package/src/js/lattice/lattice_bravais.ts +170 -0
- package/src/js/lattice/lattice_vectors.ts +126 -0
- package/src/js/lattice/reciprocal/lattice_reciprocal.js +155 -0
- package/src/js/lattice/reciprocal/paths.js +134 -0
- package/src/js/lattice/reciprocal/symmetry_points.ts +886 -0
- package/src/js/lattice/types.ts +142 -0
- package/src/js/lattice/unit_cell.ts +66 -0
- package/src/js/made.js +36 -0
- package/src/js/material.ts +398 -0
- package/src/js/math.js +6 -0
- package/src/js/parsers/cif.js +22 -0
- package/src/js/parsers/errors.js +7 -0
- package/src/js/parsers/espresso.ts +30 -0
- package/src/js/parsers/native_format_parsers.js +51 -0
- package/src/js/parsers/parsers.js +13 -0
- package/src/js/parsers/poscar.ts +201 -0
- package/src/js/parsers/xyz.ts +216 -0
- package/src/js/parsers/xyz_combinatorial_basis.js +243 -0
- package/src/js/tools/basis.js +116 -0
- package/src/js/tools/cell.js +36 -0
- package/src/js/tools/index.js +11 -0
- package/src/js/tools/material.js +60 -0
- package/src/js/tools/supercell.ts +80 -0
- package/src/js/tools/surface.js +176 -0
- package/src/js/types.ts +4 -0
- package/src/py/__init__.py +0 -0
- package/src/py/mat3ra/__init__.py +0 -0
- package/src/py/mat3ra/made/__init__.py +5 -0
- package/tests/.gitattributes +1 -0
- package/tests/fixtures/AsGe-basis.json +3 -0
- package/tests/fixtures/C2H4-translated.json +3 -0
- package/tests/fixtures/C2H4.json +3 -0
- package/tests/fixtures/FeLiSi-basis.json +3 -0
- package/tests/fixtures/FeO.json +3 -0
- package/tests/fixtures/Ge2-basis.json +3 -0
- package/tests/fixtures/Graphene.json +3 -0
- package/tests/fixtures/Graphene.poscar +3 -0
- package/tests/fixtures/H2+H-final.json +3 -0
- package/tests/fixtures/H2+H-image.json +3 -0
- package/tests/fixtures/H2+H-initial.json +3 -0
- package/tests/fixtures/H2O.poscar +3 -0
- package/tests/fixtures/LiFeSi-basis.json +3 -0
- package/tests/fixtures/Na.json +3 -0
- package/tests/fixtures/Na4Cl4-cartesian.json +3 -0
- package/tests/fixtures/Na4Cl4.json +3 -0
- package/tests/fixtures/Na4Cl4.poscar +3 -0
- package/tests/fixtures/Ni-hex.json +3 -0
- package/tests/fixtures/Ni-hex.poscar +3 -0
- package/tests/fixtures/OSi-basis.json +3 -0
- package/tests/fixtures/Si-hex.json +3 -0
- package/tests/fixtures/Si-hex.poscar +3 -0
- package/tests/fixtures/Si-pwscf.in +3 -0
- package/tests/fixtures/Si-slab.json +3 -0
- package/tests/fixtures/Si-supercell.json +3 -0
- package/tests/fixtures/Si.json +3 -0
- package/tests/fixtures/Si2-basis-repeated.json +3 -0
- package/tests/fixtures/Si2-basis.json +3 -0
- package/tests/fixtures/Zr1H23Zr1H1.json +3 -0
- package/tests/fixtures/Zr1H23Zr1H1.poscar +3 -0
- package/tests/fixtures/atomic-constraints.json +3 -0
- package/tests/js/basis/basis.js +221 -0
- package/tests/js/cell/cell.js +21 -0
- package/tests/js/cell/primitive_cell.js +17 -0
- package/tests/js/constraints/constraints.js +27 -0
- package/tests/js/enums.js +40 -0
- package/tests/js/lattice/lattice.js +31 -0
- package/tests/js/lattice/lattice_bravais.js +17 -0
- package/tests/js/lattice/lattice_reciprocal.js +99 -0
- package/tests/js/lattice/lattice_vectors.js +10 -0
- package/tests/js/material.test.js +11 -0
- package/tests/js/parsers/espresso.js +12 -0
- package/tests/js/parsers/native_formats.js +30 -0
- package/tests/js/parsers/poscar.js +21 -0
- package/tests/js/parsers/xyz.js +25 -0
- package/tests/js/parsers/xyz_combinatorial_basis.js +153 -0
- package/tests/js/setup.js +6 -0
- package/tests/js/tools/basis.js +18 -0
- package/tests/js/tools/supercell.js +23 -0
- package/tests/js/tools/surface.js +12 -0
- package/tests/js/utils.js +17 -0
- package/tests/py/__init__.py +0 -0
- package/tests/py/unit/__init__.py +0 -0
- package/tests/py/unit/test_sample.py +10 -0
- package/tsconfig.json +3 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { MaterialJSON } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Obtain a textual representation of a material in POSCAR format.
|
|
4
|
+
* @param materialOrConfig - material class instance or config object.
|
|
5
|
+
* @param omitConstraints - whether to discard constraints passed with material.
|
|
6
|
+
*/
|
|
7
|
+
declare function toPoscar(materialOrConfig: MaterialJSON, omitConstraints?: boolean): string;
|
|
8
|
+
/**
|
|
9
|
+
* @summary calculates the number of atoms in a poscar file based on the summation of the numbers in line 7 of the file.
|
|
10
|
+
* Poscar file formatting: https://www.vasp.at/wiki/index.php/POSCAR
|
|
11
|
+
*/
|
|
12
|
+
export declare function atomsCount(poscarFileContent: string): number;
|
|
13
|
+
/**
|
|
14
|
+
* Parses POSCAR file into a Material config object.
|
|
15
|
+
* @param fileContent - POSCAR file content.
|
|
16
|
+
* @return Material config.
|
|
17
|
+
*/
|
|
18
|
+
declare function fromPoscar(fileContent: string): object;
|
|
19
|
+
/**
|
|
20
|
+
* @summary Checks if a string has a POSCAR format (first 8 lines are read)
|
|
21
|
+
* @param text - string to check
|
|
22
|
+
*/
|
|
23
|
+
declare function isPoscar(text: string): boolean;
|
|
24
|
+
declare const _default: {
|
|
25
|
+
isPoscar: typeof isPoscar;
|
|
26
|
+
toPoscar: typeof toPoscar;
|
|
27
|
+
fromPoscar: typeof fromPoscar;
|
|
28
|
+
atomicConstraintsCharFromBool: (bool: boolean) => string;
|
|
29
|
+
atomsCount: typeof atomsCount;
|
|
30
|
+
};
|
|
31
|
+
export default _default;
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.atomsCount = void 0;
|
|
7
|
+
const underscore_string_1 = __importDefault(require("underscore.string"));
|
|
8
|
+
const constrained_basis_1 = require("../basis/constrained_basis");
|
|
9
|
+
const constants_1 = require("../constants");
|
|
10
|
+
const lattice_1 = require("../lattice/lattice");
|
|
11
|
+
const math_1 = __importDefault(require("../math"));
|
|
12
|
+
const _print = (x, printFormat = "%14.9f") => underscore_string_1.default.sprintf(printFormat, math_1.default.precise(x));
|
|
13
|
+
const _latticeVectorsToString = (vectors) => vectors.map((v) => v.map((c) => _print(c)).join("\t")).join("\n");
|
|
14
|
+
const atomicConstraintsCharFromBool = (bool) => (bool ? "T" : "F");
|
|
15
|
+
/**
|
|
16
|
+
* Obtain a textual representation of a material in POSCAR format.
|
|
17
|
+
* @param materialOrConfig - material class instance or config object.
|
|
18
|
+
* @param omitConstraints - whether to discard constraints passed with material.
|
|
19
|
+
*/
|
|
20
|
+
function toPoscar(materialOrConfig, omitConstraints = false) {
|
|
21
|
+
const lattice = new lattice_1.Lattice(materialOrConfig.lattice);
|
|
22
|
+
const vectorsAsString = _latticeVectorsToString(lattice.vectorArrays);
|
|
23
|
+
// @ts-ignore
|
|
24
|
+
const basis = new constrained_basis_1.ConstrainedBasis({
|
|
25
|
+
...materialOrConfig.basis,
|
|
26
|
+
cell: lattice.vectorArrays,
|
|
27
|
+
});
|
|
28
|
+
const BasisLines = [];
|
|
29
|
+
let addSelectiveDynamics = false;
|
|
30
|
+
basis._elements.array.forEach((item, idx) => {
|
|
31
|
+
const coord = basis.getCoordinateByIndex(idx).map((x) => _print(x));
|
|
32
|
+
const constraintsAsString = omitConstraints
|
|
33
|
+
? ""
|
|
34
|
+
: basis.AtomicConstraints.getAsStringByIndex(idx, atomicConstraintsCharFromBool);
|
|
35
|
+
if (constraintsAsString && !omitConstraints)
|
|
36
|
+
addSelectiveDynamics = true;
|
|
37
|
+
BasisLines.push([coord.join(" "), constraintsAsString, item].join(" "));
|
|
38
|
+
});
|
|
39
|
+
const basisContent = BasisLines.join("\n");
|
|
40
|
+
const elementsLine = basis.elementCounts.map((e) => e.value).join(" ");
|
|
41
|
+
const countsLine = basis.elementCounts.map((e) => parseInt(`${e.count}`, 10)).join(" ");
|
|
42
|
+
const coordsType = materialOrConfig.basis.units === constants_1.ATOMIC_COORD_UNITS.cartesian ? "cartesian" : "direct";
|
|
43
|
+
return [
|
|
44
|
+
materialOrConfig.name,
|
|
45
|
+
"1.0",
|
|
46
|
+
vectorsAsString,
|
|
47
|
+
elementsLine,
|
|
48
|
+
countsLine,
|
|
49
|
+
// add selective dynamics only if there are some constraints!
|
|
50
|
+
...(addSelectiveDynamics ? ["Selective dynamics"] : []),
|
|
51
|
+
coordsType,
|
|
52
|
+
basisContent,
|
|
53
|
+
].join("\n");
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* @summary calculates the number of atoms in a poscar file based on the summation of the numbers in line 7 of the file.
|
|
57
|
+
* Poscar file formatting: https://www.vasp.at/wiki/index.php/POSCAR
|
|
58
|
+
*/
|
|
59
|
+
function atomsCount(poscarFileContent) {
|
|
60
|
+
const atomsLine = poscarFileContent.split("\n")[6].split(/\s+/);
|
|
61
|
+
return atomsLine.map((x) => parseInt(x, 10)).reduce((a, b) => a + b);
|
|
62
|
+
}
|
|
63
|
+
exports.atomsCount = atomsCount;
|
|
64
|
+
/**
|
|
65
|
+
* Parses POSCAR file into a Material config object.
|
|
66
|
+
* @param fileContent - POSCAR file content.
|
|
67
|
+
* @return Material config.
|
|
68
|
+
*/
|
|
69
|
+
function fromPoscar(fileContent) {
|
|
70
|
+
const lines = fileContent.split("\n");
|
|
71
|
+
const comment = lines[0];
|
|
72
|
+
const latticeConstant = parseFloat(lines[1].trim());
|
|
73
|
+
// Atom symbols and counts
|
|
74
|
+
const atomSymbols = lines[5].trim().split(/\s+/);
|
|
75
|
+
const atomCounts = lines[6].trim().split(/\s+/).map(Number);
|
|
76
|
+
// Check if selective dynamics and coordinates type is used
|
|
77
|
+
let selectiveDynamics = false;
|
|
78
|
+
let coordinateType = "";
|
|
79
|
+
let startLine = 7;
|
|
80
|
+
if (lines[startLine].trim()[0].toLowerCase() === "s") {
|
|
81
|
+
selectiveDynamics = true;
|
|
82
|
+
coordinateType = lines[8].trim()[0].toLowerCase();
|
|
83
|
+
startLine = 9;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
coordinateType = lines[7].trim()[0].toLowerCase();
|
|
87
|
+
startLine = 8;
|
|
88
|
+
}
|
|
89
|
+
const elements = atomSymbols
|
|
90
|
+
.map((symbol, i) => Array(atomCounts[i]).fill(symbol))
|
|
91
|
+
.reduce((a, b) => a.concat(b), []);
|
|
92
|
+
// Atom coordinates and constraints
|
|
93
|
+
const coordinates = [];
|
|
94
|
+
const constraints = [];
|
|
95
|
+
let atomIndex = 0;
|
|
96
|
+
for (let i = 0; i < atomSymbols.length; i++) {
|
|
97
|
+
for (let j = 0; j < atomCounts[i]; j++) {
|
|
98
|
+
const lineComponents = lines[startLine + atomIndex].trim().split(/\s+/);
|
|
99
|
+
const coordinate = [
|
|
100
|
+
parseFloat(lineComponents[0]),
|
|
101
|
+
parseFloat(lineComponents[1]),
|
|
102
|
+
parseFloat(lineComponents[2]),
|
|
103
|
+
];
|
|
104
|
+
coordinates.push(coordinate);
|
|
105
|
+
// Add constraints if selective dynamics is used
|
|
106
|
+
if (selectiveDynamics) {
|
|
107
|
+
const constraint = [
|
|
108
|
+
lineComponents[3] === "T",
|
|
109
|
+
lineComponents[4] === "T",
|
|
110
|
+
lineComponents[5] === "T",
|
|
111
|
+
];
|
|
112
|
+
constraints.push({ id: j, value: constraint });
|
|
113
|
+
}
|
|
114
|
+
atomIndex += 1;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
const lattice = lattice_1.Lattice.fromVectors({
|
|
118
|
+
a: lines[2].trim().split(/\s+/).map(Number),
|
|
119
|
+
b: lines[3].trim().split(/\s+/).map(Number),
|
|
120
|
+
c: lines[4].trim().split(/\s+/).map(Number),
|
|
121
|
+
alat: latticeConstant,
|
|
122
|
+
units: "angstrom",
|
|
123
|
+
});
|
|
124
|
+
const basis = new constrained_basis_1.ConstrainedBasis({
|
|
125
|
+
elements,
|
|
126
|
+
coordinates,
|
|
127
|
+
units: coordinateType === "c" ? constants_1.ATOMIC_COORD_UNITS.cartesian : constants_1.ATOMIC_COORD_UNITS.crystal,
|
|
128
|
+
cell: lattice.vectorArrays,
|
|
129
|
+
constraints,
|
|
130
|
+
});
|
|
131
|
+
const materialConfig = {
|
|
132
|
+
lattice: lattice.toJSON(),
|
|
133
|
+
basis: basis.toJSON(),
|
|
134
|
+
name: comment,
|
|
135
|
+
isNonPeriodic: false,
|
|
136
|
+
};
|
|
137
|
+
return materialConfig;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* @summary Checks if a string has a POSCAR format (first 8 lines are read)
|
|
141
|
+
* @param text - string to check
|
|
142
|
+
*/
|
|
143
|
+
function isPoscar(text) {
|
|
144
|
+
const lines = text.split("\n");
|
|
145
|
+
// Checking number of lines, minimum requirement for POSCAR
|
|
146
|
+
if (lines.length < 7) {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
// Check the lattice constant (a single floating point number)
|
|
150
|
+
if (!/^[+-]?[\d.]+$/.test(lines[1].trim())) {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
// Check the lattice vectors (three lines, each with three floating point numbers)
|
|
154
|
+
for (let i = 2; i <= 4; i++) {
|
|
155
|
+
if (!/^[-+]?\d*\.\d+\s+[-+]?\d*\.\d+\s+[-+]?\d*\.\d+$/.test(lines[i].trim())) {
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
// Check the atomic species line (alphabetic characters, space-separated)
|
|
160
|
+
if (!/^[a-zA-Z\s]+$/.test(lines[5].trim())) {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
// Check the number of atoms per species line (digits, space-separated)
|
|
164
|
+
if (!/^[\d\s]+$/.test(lines[6].trim())) {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
// Check the coordinate type line (only first character is neccessary, "s" or "S" for "Selective dynamics",
|
|
168
|
+
// "d" or "D" for "Direct", or "c" or "C" for "Cartesian")
|
|
169
|
+
if (!/^[sdc]/.test(lines[7].trim().toLowerCase())) {
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
exports.default = {
|
|
175
|
+
isPoscar,
|
|
176
|
+
toPoscar,
|
|
177
|
+
fromPoscar,
|
|
178
|
+
atomicConstraintsCharFromBool,
|
|
179
|
+
atomsCount,
|
|
180
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { MaterialSchema } from "@mat3ra/esse/lib/js/types";
|
|
2
|
+
import { ConstrainedBasis } from "../basis/constrained_basis";
|
|
3
|
+
import { Constraint } from "../constraints/constraints";
|
|
4
|
+
import { Vector } from "../lattice/types";
|
|
5
|
+
import { CombinatorialBasis } from "./xyz_combinatorial_basis";
|
|
6
|
+
/**
|
|
7
|
+
* Validates that passed string is well-formed XYZ file.
|
|
8
|
+
*/
|
|
9
|
+
export declare function validate(xyzTxt: string): void;
|
|
10
|
+
export interface ParsedObject {
|
|
11
|
+
element: string;
|
|
12
|
+
coordinates: Vector;
|
|
13
|
+
constraints: [boolean, boolean, boolean];
|
|
14
|
+
label?: number;
|
|
15
|
+
}
|
|
16
|
+
export interface BasisConfig {
|
|
17
|
+
elements: {
|
|
18
|
+
id: number;
|
|
19
|
+
value: string;
|
|
20
|
+
}[];
|
|
21
|
+
labels?: {
|
|
22
|
+
id: number;
|
|
23
|
+
value: number;
|
|
24
|
+
}[];
|
|
25
|
+
coordinates: {
|
|
26
|
+
id: number;
|
|
27
|
+
value: Vector;
|
|
28
|
+
}[];
|
|
29
|
+
units: string;
|
|
30
|
+
cell: Vector[];
|
|
31
|
+
constraints: Constraint[];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Parse XYZ text for basis.
|
|
35
|
+
* @param txt Text
|
|
36
|
+
* @param units Coordinate units
|
|
37
|
+
* @param cell Basis Cell
|
|
38
|
+
*/
|
|
39
|
+
declare function toBasisConfig(txt: string, units?: string, cell?: [import("@mat3ra/esse/lib/js/types").ArrayOf3NumberElementsSchema, import("@mat3ra/esse/lib/js/types").ArrayOf3NumberElementsSchema, import("@mat3ra/esse/lib/js/types").ArrayOf3NumberElementsSchema]): BasisConfig;
|
|
40
|
+
/**
|
|
41
|
+
* Create XYZ from Basis class instance.
|
|
42
|
+
* @param basisClsInstance Basis class instance.
|
|
43
|
+
* @param printFormat Output format for coordinates.
|
|
44
|
+
* @param skipRounding Whether to round the numbers (ie. to avoid negative zeros).
|
|
45
|
+
* @return Basis string in XYZ format
|
|
46
|
+
*/
|
|
47
|
+
declare function fromBasis(basisClsInstance: ConstrainedBasis, printFormat?: string, skipRounding?: boolean): string;
|
|
48
|
+
/**
|
|
49
|
+
* Create XYZ from Material class instance (or its JSON config).
|
|
50
|
+
* @param materialOrConfig Material.
|
|
51
|
+
* @param fractional Coordinate units as fractional.
|
|
52
|
+
* @return Class Instance
|
|
53
|
+
*/
|
|
54
|
+
declare function fromMaterial(materialOrConfig: MaterialSchema, fractional?: boolean): string;
|
|
55
|
+
declare const _default: {
|
|
56
|
+
validate: typeof validate;
|
|
57
|
+
fromMaterial: typeof fromMaterial;
|
|
58
|
+
toBasisConfig: typeof toBasisConfig;
|
|
59
|
+
fromBasis: typeof fromBasis;
|
|
60
|
+
CombinatorialBasis: typeof CombinatorialBasis;
|
|
61
|
+
};
|
|
62
|
+
export default _default;
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.validate = void 0;
|
|
7
|
+
const underscore_1 = __importDefault(require("underscore"));
|
|
8
|
+
const underscore_string_1 = __importDefault(require("underscore.string"));
|
|
9
|
+
const basis_1 = require("../basis/basis");
|
|
10
|
+
const constrained_basis_1 = require("../basis/constrained_basis");
|
|
11
|
+
const lattice_1 = require("../lattice/lattice");
|
|
12
|
+
const math_1 = __importDefault(require("../math"));
|
|
13
|
+
const errors_1 = require("./errors");
|
|
14
|
+
const xyz_combinatorial_basis_1 = require("./xyz_combinatorial_basis");
|
|
15
|
+
// Regular expression for an XYZ line with atomic constraints, eg. Si 0.000000 0.500000 0.446678 1 1 1`
|
|
16
|
+
// eslint-disable-next-line max-len
|
|
17
|
+
const XYZ_LINE_REGEX = /[A-Z][a-z]?(\d)?\s+((-?\d+\.?\d*|\.\d+)\s+(-?\d+\.?\d*|\.\d+)\s+(-?\d+\.?\d*|\.\d+)(\s+)?(\s+[0-1]\s+[0-1]\s+[0-1](\s+)?)?)$/;
|
|
18
|
+
/**
|
|
19
|
+
* Validates XYZ file's line. Line should be in following format "Si 0.5 0.5 0.5".
|
|
20
|
+
* Raises an error if line is in wrong format.
|
|
21
|
+
*/
|
|
22
|
+
function validateLine(xyzLine, index) {
|
|
23
|
+
const words = xyzLine.split(" ").filter((x) => x.trim() !== "");
|
|
24
|
+
if (!xyzLine.match(XYZ_LINE_REGEX)) {
|
|
25
|
+
throw new errors_1.InvalidLineError(index, xyzLine);
|
|
26
|
+
}
|
|
27
|
+
const coordinates = [parseFloat(words[1]), parseFloat(words[2]), parseFloat(words[3])];
|
|
28
|
+
coordinates.forEach((num, i) => {
|
|
29
|
+
if (underscore_1.default.isNaN(num)) {
|
|
30
|
+
throw new Error(`Coordinates should be a number. Possible error in ${i} coordinate`);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Validates that passed string is well-formed XYZ file.
|
|
36
|
+
*/
|
|
37
|
+
function validate(xyzTxt) {
|
|
38
|
+
// The @types/underscore.string package does not provide interfaces for function chaining at the moment. Disable TS here
|
|
39
|
+
// @ts-ignore
|
|
40
|
+
(0, underscore_string_1.default)(xyzTxt)
|
|
41
|
+
.trim()
|
|
42
|
+
.lines()
|
|
43
|
+
.filter((x) => x.trim() !== "")
|
|
44
|
+
.forEach(validateLine);
|
|
45
|
+
}
|
|
46
|
+
exports.validate = validate;
|
|
47
|
+
/**
|
|
48
|
+
* Parses XYZ line and returns an object.
|
|
49
|
+
* @param line - line of text
|
|
50
|
+
*/
|
|
51
|
+
function _parseXYZLineAsWords(line) {
|
|
52
|
+
const words = underscore_string_1.default.words(line);
|
|
53
|
+
const elementWithOptionalLabel = words[0];
|
|
54
|
+
const element = elementWithOptionalLabel.replace(/\d$/, ""); // Fe1 => Fe
|
|
55
|
+
const constraint = (n) => parseInt(`${n}`, 10) !== 0;
|
|
56
|
+
const basisLineConfig = {
|
|
57
|
+
element,
|
|
58
|
+
coordinates: [+words[1], +words[2], +words[3]],
|
|
59
|
+
// Below maps zero values to false (atom is fixed) and non-zero values to true (atom is moving)
|
|
60
|
+
constraints: [constraint(+words[4]), constraint(+words[5]), constraint(+words[6])],
|
|
61
|
+
};
|
|
62
|
+
if (elementWithOptionalLabel !== element) {
|
|
63
|
+
return {
|
|
64
|
+
...basisLineConfig,
|
|
65
|
+
label: parseInt(elementWithOptionalLabel[elementWithOptionalLabel.length - 1], 10),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
return basisLineConfig;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Parse XYZ text for basis.
|
|
72
|
+
* @param txt Text
|
|
73
|
+
* @param units Coordinate units
|
|
74
|
+
* @param cell Basis Cell
|
|
75
|
+
*/
|
|
76
|
+
function toBasisConfig(txt, units = "angstrom", cell = basis_1.Basis.defaultCell) {
|
|
77
|
+
// @ts-ignore
|
|
78
|
+
const lines = (0, underscore_string_1.default)(txt).trim().lines();
|
|
79
|
+
const listOfObjects = underscore_1.default.map(lines, _parseXYZLineAsWords);
|
|
80
|
+
const basisConfig = {
|
|
81
|
+
elements: listOfObjects.map((elm, idx) => {
|
|
82
|
+
return {
|
|
83
|
+
id: idx,
|
|
84
|
+
value: elm.element,
|
|
85
|
+
};
|
|
86
|
+
}),
|
|
87
|
+
coordinates: listOfObjects.map((elm, idx) => {
|
|
88
|
+
return {
|
|
89
|
+
id: idx,
|
|
90
|
+
value: elm.coordinates,
|
|
91
|
+
};
|
|
92
|
+
}),
|
|
93
|
+
units,
|
|
94
|
+
cell,
|
|
95
|
+
constraints: listOfObjects.map((elm, idx) => {
|
|
96
|
+
return {
|
|
97
|
+
id: idx,
|
|
98
|
+
value: elm.constraints,
|
|
99
|
+
};
|
|
100
|
+
}),
|
|
101
|
+
};
|
|
102
|
+
const labels = [];
|
|
103
|
+
listOfObjects.forEach((elm, idx) => {
|
|
104
|
+
if (elm.label) {
|
|
105
|
+
labels.push({
|
|
106
|
+
id: idx,
|
|
107
|
+
value: elm.label,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
if (!underscore_1.default.isEmpty(labels)) {
|
|
112
|
+
return {
|
|
113
|
+
...basisConfig,
|
|
114
|
+
labels,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
return basisConfig;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Create XYZ from Basis class instance.
|
|
121
|
+
* @param basisClsInstance Basis class instance.
|
|
122
|
+
* @param printFormat Output format for coordinates.
|
|
123
|
+
* @param skipRounding Whether to round the numbers (ie. to avoid negative zeros).
|
|
124
|
+
* @return Basis string in XYZ format
|
|
125
|
+
*/
|
|
126
|
+
function fromBasis(basisClsInstance, printFormat = "%9.5f", skipRounding = false) {
|
|
127
|
+
const XYZArray = [];
|
|
128
|
+
basisClsInstance._elements.array.forEach((item, idx) => {
|
|
129
|
+
// assume that _elements and _coordinates are indexed equivalently
|
|
130
|
+
const atomicLabel = basisClsInstance.atomicLabelsArray[idx];
|
|
131
|
+
const elementWithLabel = item + atomicLabel;
|
|
132
|
+
const element = underscore_string_1.default.sprintf("%-3s", elementWithLabel);
|
|
133
|
+
const coordinates = basisClsInstance.getCoordinateByIndex(idx).map((x) => {
|
|
134
|
+
return underscore_string_1.default.sprintf(printFormat, skipRounding ? x : math_1.default.precise(math_1.default.roundToZero(x)));
|
|
135
|
+
});
|
|
136
|
+
const constraints = basisClsInstance.constraints
|
|
137
|
+
? basisClsInstance.AtomicConstraints.getAsStringByIndex(idx)
|
|
138
|
+
: "";
|
|
139
|
+
XYZArray.push([element, coordinates.join(" "), constraints].join(" "));
|
|
140
|
+
});
|
|
141
|
+
return `${XYZArray.join("\n")}\n`;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Create XYZ from Material class instance (or its JSON config).
|
|
145
|
+
* @param materialOrConfig Material.
|
|
146
|
+
* @param fractional Coordinate units as fractional.
|
|
147
|
+
* @return Class Instance
|
|
148
|
+
*/
|
|
149
|
+
function fromMaterial(materialOrConfig, fractional = false) {
|
|
150
|
+
const lattice = new lattice_1.Lattice(materialOrConfig.lattice);
|
|
151
|
+
// @ts-ignore
|
|
152
|
+
const basis = new constrained_basis_1.ConstrainedBasis({
|
|
153
|
+
...materialOrConfig.basis,
|
|
154
|
+
cell: lattice.vectorArrays,
|
|
155
|
+
});
|
|
156
|
+
if (fractional) {
|
|
157
|
+
basis.toCrystal();
|
|
158
|
+
}
|
|
159
|
+
return fromBasis(basis, "%11.6f");
|
|
160
|
+
}
|
|
161
|
+
exports.default = {
|
|
162
|
+
validate,
|
|
163
|
+
fromMaterial,
|
|
164
|
+
toBasisConfig,
|
|
165
|
+
fromBasis,
|
|
166
|
+
CombinatorialBasis: xyz_combinatorial_basis_1.CombinatorialBasis,
|
|
167
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export class WrongBasisFormat extends Error {
|
|
2
|
+
constructor(xyz: any, message: any, type: any);
|
|
3
|
+
xyz: any;
|
|
4
|
+
}
|
|
5
|
+
export class CombinatorialBasis {
|
|
6
|
+
static toBasisConfig(array: any, units?: string, cell?: [import("@mat3ra/esse/lib/js/types").ArrayOf3NumberElementsSchema, import("@mat3ra/esse/lib/js/types").ArrayOf3NumberElementsSchema, import("@mat3ra/esse/lib/js/types").ArrayOf3NumberElementsSchema]): {
|
|
7
|
+
elements: any[];
|
|
8
|
+
coordinates: any[];
|
|
9
|
+
units: string;
|
|
10
|
+
cell: [import("@mat3ra/esse/lib/js/types").ArrayOf3NumberElementsSchema, import("@mat3ra/esse/lib/js/types").ArrayOf3NumberElementsSchema, import("@mat3ra/esse/lib/js/types").ArrayOf3NumberElementsSchema];
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Creates Combinatorial basis
|
|
14
|
+
* @param eXYZ
|
|
15
|
+
*/
|
|
16
|
+
constructor(eXYZ: any);
|
|
17
|
+
_xyz: any;
|
|
18
|
+
_lines: {
|
|
19
|
+
displayName: string;
|
|
20
|
+
isCombination: boolean;
|
|
21
|
+
isPermutation: boolean;
|
|
22
|
+
elements: any[];
|
|
23
|
+
coordinates: any[];
|
|
24
|
+
}[];
|
|
25
|
+
_hasPermutationLine: boolean;
|
|
26
|
+
_hasCombinationLine: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Parses combinatorial basis line and returns result as Object. Throws exception if line is not valid:
|
|
29
|
+
* - does not meet RegExp
|
|
30
|
+
* - mixes permutation and combination
|
|
31
|
+
* @param str {String} Combinatorial basis' line
|
|
32
|
+
* @param index {Number} order of the
|
|
33
|
+
* @return {{displayName: string, isCombination: boolean, isPermutation: boolean, elements: Array, coordinates: *[]}}
|
|
34
|
+
* @private
|
|
35
|
+
*/
|
|
36
|
+
private _parseBasisLine;
|
|
37
|
+
/**
|
|
38
|
+
* Returns array of ALL unique elements used in basis.
|
|
39
|
+
* @return {String[]}
|
|
40
|
+
*/
|
|
41
|
+
get uniqueElements(): string[];
|
|
42
|
+
/**
|
|
43
|
+
* Returns array of regular bases extracted from current combinatorial basis.
|
|
44
|
+
* @return {Basis[]|Object[]}
|
|
45
|
+
*/
|
|
46
|
+
get allBasisConfigs(): Object[] | Basis[];
|
|
47
|
+
/**
|
|
48
|
+
* Returns array of regular bases extracted from current combinatorial basis with combinations.
|
|
49
|
+
* @private
|
|
50
|
+
*/
|
|
51
|
+
private _combination;
|
|
52
|
+
/**
|
|
53
|
+
* Returns array of regular bases extracted from current combinatorial basis with permutations.
|
|
54
|
+
* @return {Basis[]}
|
|
55
|
+
* @private
|
|
56
|
+
*/
|
|
57
|
+
private _permutation;
|
|
58
|
+
/**
|
|
59
|
+
* Returns true if current combinatorial basis contains more than one regular basis.
|
|
60
|
+
* @return {Boolean}
|
|
61
|
+
*/
|
|
62
|
+
isCombinatorial(): boolean;
|
|
63
|
+
}
|
|
64
|
+
import { Basis } from "../basis/basis";
|