matterviz 0.3.2 → 0.3.3
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/dist/EmptyState.svelte +10 -2
- package/dist/FilePicker.svelte +123 -82
- package/dist/Icon.svelte +18 -12
- package/dist/MillerIndexInput.svelte +27 -21
- package/dist/api/optimade.js +6 -6
- package/dist/app.css +216 -207
- package/dist/brillouin/BrillouinZone.svelte +292 -149
- package/dist/brillouin/BrillouinZone.svelte.d.ts +1 -1
- package/dist/brillouin/BrillouinZoneControls.svelte +32 -5
- package/dist/brillouin/BrillouinZoneExportPane.svelte +69 -42
- package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +1 -1
- package/dist/brillouin/BrillouinZoneInfoPane.svelte +99 -68
- package/dist/brillouin/BrillouinZoneScene.svelte +275 -163
- package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -1
- package/dist/brillouin/BrillouinZoneTooltip.svelte +17 -7
- package/dist/brillouin/compute.js +11 -6
- package/dist/chempot-diagram/ChemPotDiagram.svelte +162 -27
- package/dist/chempot-diagram/ChemPotDiagram2D.svelte +451 -281
- package/dist/chempot-diagram/ChemPotDiagram3D.svelte +2148 -1642
- package/dist/chempot-diagram/ChemPotScene3D.svelte +8 -5
- package/dist/chempot-diagram/async-compute.svelte.d.ts +3 -0
- package/dist/chempot-diagram/async-compute.svelte.js +77 -0
- package/dist/chempot-diagram/chempot-worker.d.ts +1 -0
- package/dist/chempot-diagram/chempot-worker.js +11 -0
- package/dist/chempot-diagram/color.js +1 -2
- package/dist/chempot-diagram/compute.d.ts +10 -0
- package/dist/chempot-diagram/compute.js +250 -88
- package/dist/chempot-diagram/index.d.ts +2 -1
- package/dist/chempot-diagram/index.js +2 -1
- package/dist/chempot-diagram/temperature.js +8 -9
- package/dist/chempot-diagram/types.d.ts +3 -0
- package/dist/chempot-diagram/types.js +1 -0
- package/dist/colors/index.d.ts +1 -1
- package/dist/colors/index.js +5 -3
- package/dist/composition/BarChart.svelte +128 -55
- package/dist/composition/BubbleChart.svelte +102 -49
- package/dist/composition/Composition.svelte +100 -79
- package/dist/composition/Formula.svelte +108 -62
- package/dist/composition/FormulaFilter.svelte +665 -537
- package/dist/composition/PieChart.svelte +183 -108
- package/dist/composition/format.d.ts +5 -0
- package/dist/composition/format.js +20 -3
- package/dist/composition/parse.js +14 -9
- package/dist/convex-hull/ConvexHull.svelte +93 -40
- package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull2D.svelte +549 -360
- package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull3D.svelte +1296 -827
- package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull4D.svelte +1004 -688
- package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHullControls.svelte +115 -28
- package/dist/convex-hull/ConvexHullControls.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHullInfoPane.svelte +29 -3
- package/dist/convex-hull/ConvexHullStats.svelte +425 -328
- package/dist/convex-hull/ConvexHullTooltip.svelte +40 -16
- package/dist/convex-hull/GasPressureControls.svelte +104 -61
- package/dist/convex-hull/StructurePopup.svelte +25 -4
- package/dist/convex-hull/TemperatureSlider.svelte +45 -25
- package/dist/convex-hull/barycentric-coords.js +13 -7
- package/dist/convex-hull/demo-temperature.js +8 -4
- package/dist/convex-hull/gas-thermodynamics.js +17 -12
- package/dist/convex-hull/helpers.d.ts +9 -0
- package/dist/convex-hull/helpers.js +77 -34
- package/dist/convex-hull/thermodynamics.js +61 -56
- package/dist/convex-hull/types.d.ts +9 -14
- package/dist/convex-hull/types.js +0 -17
- package/dist/coordination/CoordinationBarPlot.svelte +227 -154
- package/dist/element/BohrAtom.svelte +55 -12
- package/dist/element/ElementHeading.svelte +7 -2
- package/dist/element/ElementPhoto.svelte +15 -9
- package/dist/element/ElementStats.svelte +10 -4
- package/dist/element/ElementTile.svelte +137 -73
- package/dist/element/Nucleus.svelte +39 -11
- package/dist/feedback/ClickFeedback.svelte +16 -5
- package/dist/feedback/DragOverlay.svelte +10 -2
- package/dist/feedback/Spinner.svelte +4 -2
- package/dist/feedback/StatusMessage.svelte +8 -2
- package/dist/fermi-surface/FermiSlice.svelte +118 -88
- package/dist/fermi-surface/FermiSurface.svelte +328 -187
- package/dist/fermi-surface/FermiSurface.svelte.d.ts +1 -1
- package/dist/fermi-surface/FermiSurfaceControls.svelte +113 -46
- package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
- package/dist/fermi-surface/FermiSurfaceScene.svelte +535 -342
- package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +1 -1
- package/dist/fermi-surface/FermiSurfaceTooltip.svelte +14 -5
- package/dist/fermi-surface/compute.js +16 -20
- package/dist/fermi-surface/parse.js +24 -14
- package/dist/fermi-surface/symmetry.js +2 -7
- package/dist/fermi-surface/types.d.ts +3 -5
- package/dist/heatmap-matrix/HeatmapMatrix.svelte +1019 -765
- package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +1 -1
- package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +76 -22
- package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +2 -3
- package/dist/icons.js +47 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/io/decompress.js +1 -1
- package/dist/io/export.d.ts +3 -0
- package/dist/io/export.js +129 -143
- package/dist/io/is-binary.js +2 -3
- package/dist/io/url-drop.js +1 -2
- package/dist/isosurface/Isosurface.svelte +202 -148
- package/dist/isosurface/IsosurfaceControls.svelte +46 -28
- package/dist/isosurface/parse.js +34 -29
- package/dist/isosurface/slice.js +5 -10
- package/dist/isosurface/types.d.ts +2 -1
- package/dist/isosurface/types.js +61 -12
- package/dist/labels.js +11 -8
- package/dist/layout/FullscreenToggle.svelte +11 -2
- package/dist/layout/InfoCard.svelte +38 -6
- package/dist/layout/InfoTag.svelte +63 -32
- package/dist/layout/PropertyFilter.svelte +82 -37
- package/dist/layout/SettingsSection.svelte +85 -55
- package/dist/layout/SubpageGrid.svelte +10 -2
- package/dist/layout/json-tree/JsonNode.svelte +183 -138
- package/dist/layout/json-tree/JsonTree.svelte +499 -413
- package/dist/layout/json-tree/JsonValue.svelte +127 -99
- package/dist/layout/json-tree/utils.js +4 -2
- package/dist/marching-cubes.js +25 -2
- package/dist/math.d.ts +13 -17
- package/dist/math.js +133 -67
- package/dist/overlays/ContextMenu.svelte +65 -40
- package/dist/overlays/DraggablePane.svelte +211 -139
- package/dist/periodic-table/PeriodicTable.svelte +278 -145
- package/dist/periodic-table/PeriodicTableControls.svelte +178 -128
- package/dist/periodic-table/PropertySelect.svelte +25 -7
- package/dist/periodic-table/TableInset.svelte +8 -3
- package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +446 -309
- package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +1 -1
- package/dist/phase-diagram/PhaseDiagramControls.svelte +102 -43
- package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +1 -1
- package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +63 -40
- package/dist/phase-diagram/PhaseDiagramExportPane.svelte +71 -28
- package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +1 -1
- package/dist/phase-diagram/PhaseDiagramTooltip.svelte +158 -101
- package/dist/phase-diagram/TdbInfoPanel.svelte +28 -4
- package/dist/phase-diagram/build-diagram.js +9 -9
- package/dist/phase-diagram/colors.js +1 -3
- package/dist/phase-diagram/parse.js +10 -9
- package/dist/phase-diagram/svg-to-diagram.js +53 -49
- package/dist/phase-diagram/utils.d.ts +1 -0
- package/dist/phase-diagram/utils.js +80 -25
- package/dist/plot/AxisLabel.svelte +28 -3
- package/dist/plot/BarPlot.svelte +1182 -734
- package/dist/plot/BarPlot.svelte.d.ts +2 -2
- package/dist/plot/BarPlotControls.svelte +31 -5
- package/dist/plot/BarPlotControls.svelte.d.ts +1 -1
- package/dist/plot/ColorBar.svelte +479 -329
- package/dist/plot/ColorScaleSelect.svelte +27 -6
- package/dist/plot/ElementScatter.svelte +36 -15
- package/dist/plot/FillArea.svelte +152 -95
- package/dist/plot/Histogram.svelte +934 -571
- package/dist/plot/Histogram.svelte.d.ts +1 -1
- package/dist/plot/HistogramControls.svelte +53 -9
- package/dist/plot/HistogramControls.svelte.d.ts +1 -1
- package/dist/plot/InteractiveAxisLabel.svelte +34 -11
- package/dist/plot/InteractiveAxisLabel.svelte.d.ts +1 -1
- package/dist/plot/Line.svelte +63 -28
- package/dist/plot/PlotControls.svelte +157 -114
- package/dist/plot/PlotControls.svelte.d.ts +1 -1
- package/dist/plot/PlotLegend.svelte +174 -91
- package/dist/plot/PlotTooltip.svelte +45 -6
- package/dist/plot/PortalSelect.svelte +175 -147
- package/dist/plot/ReferenceLine.svelte +76 -22
- package/dist/plot/ReferenceLine3D.svelte +132 -107
- package/dist/plot/ReferencePlane.svelte +146 -121
- package/dist/plot/ScatterPlot.svelte +1681 -1091
- package/dist/plot/ScatterPlot.svelte.d.ts +2 -2
- package/dist/plot/ScatterPlot3D.svelte +256 -131
- package/dist/plot/ScatterPlot3D.svelte.d.ts +2 -2
- package/dist/plot/ScatterPlot3DControls.svelte +113 -63
- package/dist/plot/ScatterPlot3DControls.svelte.d.ts +2 -1
- package/dist/plot/ScatterPlot3DScene.svelte +608 -403
- package/dist/plot/ScatterPlot3DScene.svelte.d.ts +2 -2
- package/dist/plot/ScatterPlotControls.svelte +65 -25
- package/dist/plot/ScatterPlotControls.svelte.d.ts +1 -1
- package/dist/plot/ScatterPoint.svelte +98 -26
- package/dist/plot/ScatterPoint.svelte.d.ts +1 -0
- package/dist/plot/SpacegroupBarPlot.svelte +142 -85
- package/dist/plot/Surface3D.svelte +159 -108
- package/dist/plot/ZeroLines.svelte +55 -3
- package/dist/plot/ZoomRect.svelte +4 -2
- package/dist/plot/axis-utils.js +1 -3
- package/dist/plot/data-cleaning.js +12 -28
- package/dist/plot/data-transform.js +2 -1
- package/dist/plot/fill-utils.js +2 -0
- package/dist/plot/layout.d.ts +4 -1
- package/dist/plot/layout.js +33 -14
- package/dist/plot/reference-line.d.ts +2 -2
- package/dist/plot/reference-line.js +7 -5
- package/dist/plot/scales.js +24 -36
- package/dist/plot/types.d.ts +11 -23
- package/dist/plot/types.js +6 -11
- package/dist/plot/utils/label-placement.d.ts +32 -15
- package/dist/plot/utils/label-placement.js +227 -66
- package/dist/plot/utils/series-visibility.js +2 -3
- package/dist/rdf/RdfPlot.svelte +143 -91
- package/dist/rdf/calc-rdf.js +4 -5
- package/dist/sanitize.d.ts +4 -0
- package/dist/sanitize.js +107 -0
- package/dist/settings.d.ts +18 -6
- package/dist/settings.js +46 -16
- package/dist/spectral/Bands.svelte +632 -453
- package/dist/spectral/BandsAndDos.svelte +90 -49
- package/dist/spectral/BrillouinBandsDos.svelte +151 -93
- package/dist/spectral/Dos.svelte +389 -258
- package/dist/spectral/helpers.js +55 -43
- package/dist/state.svelte.d.ts +1 -1
- package/dist/state.svelte.js +3 -2
- package/dist/structure/Arrow.svelte +59 -20
- package/dist/structure/AtomLegend.svelte +215 -134
- package/dist/structure/Bond.svelte +73 -47
- package/dist/structure/CanvasTooltip.svelte +10 -2
- package/dist/structure/CellSelect.svelte +72 -45
- package/dist/structure/Cylinder.svelte +33 -17
- package/dist/structure/Lattice.svelte +88 -33
- package/dist/structure/Structure.svelte +1063 -797
- package/dist/structure/Structure.svelte.d.ts +1 -1
- package/dist/structure/StructureControls.svelte +349 -118
- package/dist/structure/StructureExportPane.svelte +124 -89
- package/dist/structure/StructureExportPane.svelte.d.ts +1 -1
- package/dist/structure/StructureInfoPane.svelte +304 -237
- package/dist/structure/StructureScene.svelte +879 -443
- package/dist/structure/StructureScene.svelte.d.ts +15 -7
- package/dist/structure/atom-properties.js +8 -8
- package/dist/structure/bonding.js +6 -7
- package/dist/structure/export.js +14 -29
- package/dist/structure/ferrox-wasm.js +1 -1
- package/dist/structure/index.d.ts +13 -3
- package/dist/structure/index.js +83 -23
- package/dist/structure/measure.d.ts +2 -2
- package/dist/structure/measure.js +4 -44
- package/dist/structure/parse.js +113 -141
- package/dist/structure/partial-occupancy.js +7 -10
- package/dist/structure/pbc.d.ts +1 -0
- package/dist/structure/pbc.js +16 -6
- package/dist/structure/supercell.d.ts +2 -2
- package/dist/structure/supercell.js +12 -22
- package/dist/structure/validation.js +1 -2
- package/dist/symmetry/SymmetryStats.svelte +84 -41
- package/dist/symmetry/WyckoffTable.svelte +26 -6
- package/dist/symmetry/cell-transform.js +5 -3
- package/dist/symmetry/index.js +8 -7
- package/dist/symmetry/spacegroups.js +148 -148
- package/dist/table/HeatmapTable.svelte +790 -554
- package/dist/table/HeatmapTable.svelte.d.ts +1 -1
- package/dist/table/ToggleMenu.svelte +125 -92
- package/dist/table/index.js +2 -4
- package/dist/theme/ThemeControl.svelte +21 -12
- package/dist/time.js +4 -1
- package/dist/tooltip/TooltipContent.svelte +33 -8
- package/dist/trajectory/Trajectory.svelte +758 -558
- package/dist/trajectory/TrajectoryError.svelte +14 -3
- package/dist/trajectory/TrajectoryExportPane.svelte +137 -83
- package/dist/trajectory/TrajectoryInfoPane.svelte +272 -143
- package/dist/trajectory/extract.js +10 -26
- package/dist/trajectory/format-detect.js +5 -5
- package/dist/trajectory/frame-reader.d.ts +1 -1
- package/dist/trajectory/frame-reader.js +5 -12
- package/dist/trajectory/helpers.d.ts +0 -1
- package/dist/trajectory/helpers.js +2 -17
- package/dist/trajectory/index.js +14 -12
- package/dist/trajectory/parse/ase.js +5 -4
- package/dist/trajectory/parse/hdf5.js +26 -18
- package/dist/trajectory/parse/index.js +13 -18
- package/dist/trajectory/parse/lammps.js +17 -7
- package/dist/trajectory/parse/vasp.js +5 -2
- package/dist/trajectory/parse/xyz.js +8 -7
- package/dist/trajectory/plotting.js +13 -8
- package/dist/utils.d.ts +1 -0
- package/dist/utils.js +13 -0
- package/dist/xrd/XrdPlot.svelte +337 -247
- package/dist/xrd/broadening.js +14 -9
- package/dist/xrd/calc-xrd.js +12 -18
- package/dist/xrd/parse.d.ts +1 -1
- package/dist/xrd/parse.js +17 -17
- package/package.json +99 -103
- package/readme.md +1 -1
- /package/dist/theme/{themes.js → themes.mjs} +0 -0
package/dist/spectral/helpers.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Helper utilities for band structure and DOS data processing
|
|
2
2
|
import { SUBSCRIPT_MAP } from '../labels';
|
|
3
|
-
import { centered_frac, euclidean_dist
|
|
3
|
+
import { centered_frac, euclidean_dist } from '../math';
|
|
4
4
|
// Check if range is a valid [min, max] tuple (strict 2-element array of finite numbers)
|
|
5
5
|
export const is_valid_range = (range) => Array.isArray(range) &&
|
|
6
6
|
range.length === 2 &&
|
|
@@ -70,7 +70,10 @@ export function pretty_sym_point(symbol) {
|
|
|
70
70
|
.replace(/\\?SIGMA/gi, `Σ`)
|
|
71
71
|
.replace(/\\?LAMBDA/gi, `Λ`)
|
|
72
72
|
.replace(/(\p{L})(\d+)/gu, (_, letter, num) => letter +
|
|
73
|
-
num
|
|
73
|
+
num
|
|
74
|
+
.split(``)
|
|
75
|
+
.map((digit) => SUBSCRIPT_MAP[digit] ?? digit)
|
|
76
|
+
.join(``));
|
|
74
77
|
}
|
|
75
78
|
// Create segment key from start and end labels
|
|
76
79
|
export const get_segment_key = (start_label, end_label) => `${start_label ?? `null`}_${end_label ?? `null`}`;
|
|
@@ -148,10 +151,10 @@ export function get_band_xaxis_ticks(band_struct, branches = []) {
|
|
|
148
151
|
// Convert frequencies from THz to specified units.
|
|
149
152
|
export function convert_frequencies(frequencies, unit = `THz`) {
|
|
150
153
|
const conversion_factors = {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
154
|
+
THz: 1,
|
|
155
|
+
eV: THz_TO_EV,
|
|
156
|
+
meV: THz_TO_MEV,
|
|
157
|
+
Ha: THz_TO_HA,
|
|
155
158
|
'cm-1': THz_TO_CM,
|
|
156
159
|
};
|
|
157
160
|
const factor = conversion_factors[unit];
|
|
@@ -276,7 +279,9 @@ export function clear_smearing_cache() {
|
|
|
276
279
|
}
|
|
277
280
|
// Type guards for pymatgen qpoint formats
|
|
278
281
|
const is_vec3 = (val) => Array.isArray(val) && val.length >= 3 && val.slice(0, 3).every(Number.isFinite);
|
|
279
|
-
const is_kpoint = (val) => !!val &&
|
|
282
|
+
const is_kpoint = (val) => !!val &&
|
|
283
|
+
typeof val === `object` &&
|
|
284
|
+
`frac_coords` in val &&
|
|
280
285
|
is_vec3(val.frac_coords);
|
|
281
286
|
const is_pymatgen_format = (obj) => {
|
|
282
287
|
// Check for explicit pymatgen markers
|
|
@@ -369,19 +374,24 @@ function convert_pymatgen_band_structure(pmg) {
|
|
|
369
374
|
const labels_dict = pmg.labels_dict;
|
|
370
375
|
const lattice_rec = pmg.lattice_rec;
|
|
371
376
|
// Determine unit: cm-1 if frequencies_cm present, else check explicit unit or default to THz
|
|
372
|
-
const unit = pmg.unit?.toLowerCase() ??
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
!raw_qpts.length ||
|
|
377
|
+
const unit = pmg.unit?.toLowerCase() ?? (has_frequencies_cm ? `cm-1` : `thz`);
|
|
378
|
+
if (!Array.isArray(raw_qpts) ||
|
|
379
|
+
!Array.isArray(raw_bands) ||
|
|
380
|
+
!raw_qpts.length ||
|
|
381
|
+
!raw_bands.length)
|
|
376
382
|
return null;
|
|
377
|
-
const qpoints = raw_qpts
|
|
383
|
+
const qpoints = raw_qpts
|
|
384
|
+
.map((q) => parse_qpoint(q, labels_dict))
|
|
385
|
+
.filter((q) => q !== null);
|
|
378
386
|
if (!qpoints.length)
|
|
379
387
|
return null;
|
|
380
388
|
// Step distances and discontinuity detection (5x median threshold)
|
|
381
|
-
const steps = qpoints
|
|
389
|
+
const steps = qpoints
|
|
390
|
+
.slice(1)
|
|
391
|
+
.map((q, idx) => euclidean_dist(qpoints[idx].frac_coords, q.frac_coords));
|
|
382
392
|
const sorted = steps.slice().sort((a, b) => a - b);
|
|
383
393
|
const threshold = (sorted[Math.floor(sorted.length / 2)] ?? 0) * 5;
|
|
384
|
-
const disc_set = new Set(steps.map((s, idx) => s > threshold ? idx + 1 : -1).filter((i) => i >= 0));
|
|
394
|
+
const disc_set = new Set(steps.map((s, idx) => (s > threshold ? idx + 1 : -1)).filter((i) => i >= 0));
|
|
385
395
|
// Cumulative distance (skip discontinuities)
|
|
386
396
|
const distance = steps.reduce((acc, step, idx) => [...acc, disc_set.has(idx + 1) ? acc[idx] : acc[idx] + step], [0]);
|
|
387
397
|
// Use pymatgen's branches if available - they correctly handle discontinuities
|
|
@@ -398,7 +408,7 @@ function convert_pymatgen_band_structure(pmg) {
|
|
|
398
408
|
}
|
|
399
409
|
// Fallback: infer branches from discontinuities when none provided or all invalid
|
|
400
410
|
if (branches.length === 0) {
|
|
401
|
-
console.
|
|
411
|
+
console.warn(`Band structure missing 'branches' field - inferring from path discontinuities`);
|
|
402
412
|
// Discontinuity indices mark points where the path jumps (disc before that index)
|
|
403
413
|
// Create continuous segments between discontinuities
|
|
404
414
|
const disc_indices = [...disc_set].sort((a, b) => a - b);
|
|
@@ -444,7 +454,13 @@ function convert_pymatgen_band_structure(pmg) {
|
|
|
444
454
|
spin_down_bands: converted_spin_down_bands,
|
|
445
455
|
nb_bands: raw_bands.length,
|
|
446
456
|
labels_dict: labels_dict ?? {},
|
|
447
|
-
recip_lattice: {
|
|
457
|
+
recip_lattice: {
|
|
458
|
+
matrix: lattice_rec?.matrix ?? [
|
|
459
|
+
[1, 0, 0],
|
|
460
|
+
[0, 1, 0],
|
|
461
|
+
[0, 0, 1],
|
|
462
|
+
],
|
|
463
|
+
},
|
|
448
464
|
};
|
|
449
465
|
}
|
|
450
466
|
export function normalize_band_structure(bs) {
|
|
@@ -483,8 +499,7 @@ export function normalize_dos(dos, options = {}) {
|
|
|
483
499
|
return null;
|
|
484
500
|
const dos_obj = dos;
|
|
485
501
|
// Check for pymatgen format (has @class or @module)
|
|
486
|
-
const is_pymatgen = typeof dos_obj[`@class`] === `string` ||
|
|
487
|
-
typeof dos_obj[`@module`] === `string`;
|
|
502
|
+
const is_pymatgen = typeof dos_obj[`@class`] === `string` || typeof dos_obj[`@module`] === `string`;
|
|
488
503
|
const { frequencies, energies, spin_polarized } = dos_obj;
|
|
489
504
|
// Handle densities as either array or dict with spin keys (pymatgen format)
|
|
490
505
|
// Pymatgen stores densities as {1: [...], -1: [...]} or {"Spin.up": [...], ...}
|
|
@@ -493,8 +508,7 @@ export function normalize_dos(dos, options = {}) {
|
|
|
493
508
|
return null;
|
|
494
509
|
const densities = spin_channels.up;
|
|
495
510
|
// Use extracted spin-down or fallback to explicit field (for already-normalized DosData)
|
|
496
|
-
const spin_down_densities = spin_channels.down ??
|
|
497
|
-
dos_obj.spin_down_densities ?? null;
|
|
511
|
+
const spin_down_densities = spin_channels.down ?? dos_obj.spin_down_densities ?? null;
|
|
498
512
|
if (!Array.isArray(densities))
|
|
499
513
|
return null;
|
|
500
514
|
// Phonon DOS: has frequencies
|
|
@@ -509,7 +523,7 @@ export function normalize_dos(dos, options = {}) {
|
|
|
509
523
|
if (auto_convert_units && max_freq > 100) {
|
|
510
524
|
// Likely in cm⁻¹, convert to THz
|
|
511
525
|
final_frequencies = frequencies.map((f) => f * CM_TO_THZ);
|
|
512
|
-
console.
|
|
526
|
+
console.warn(`Phonon DOS frequencies appear to be in cm⁻¹ (max: ${max_freq.toFixed(1)}). ` +
|
|
513
527
|
`Converting to THz (max: ${(max_freq * CM_TO_THZ).toFixed(1)} THz).`);
|
|
514
528
|
}
|
|
515
529
|
return { type: `phonon`, frequencies: final_frequencies, densities };
|
|
@@ -525,9 +539,7 @@ export function normalize_dos(dos, options = {}) {
|
|
|
525
539
|
type: `electronic`,
|
|
526
540
|
energies,
|
|
527
541
|
densities,
|
|
528
|
-
spin_down_densities: is_spin_polarized
|
|
529
|
-
? spin_down_densities ?? undefined
|
|
530
|
-
: undefined,
|
|
542
|
+
spin_down_densities: is_spin_polarized ? (spin_down_densities ?? undefined) : undefined,
|
|
531
543
|
spin_polarized: is_spin_polarized,
|
|
532
544
|
};
|
|
533
545
|
}
|
|
@@ -558,11 +570,10 @@ export function extract_k_path_points(band_struct, recip_lattice_matrix, options
|
|
|
558
570
|
y = centered_frac(y);
|
|
559
571
|
z = centered_frac(z);
|
|
560
572
|
}
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
];
|
|
573
|
+
const kx = x * m00 + y * m10 + z * m20;
|
|
574
|
+
const ky = x * m01 + y * m11 + z * m21;
|
|
575
|
+
const kz = x * m02 + y * m12 + z * m22;
|
|
576
|
+
return [kx, ky, kz];
|
|
566
577
|
});
|
|
567
578
|
}
|
|
568
579
|
// Find the q-point index closest to a given distance along the band structure path
|
|
@@ -638,7 +649,10 @@ export function find_qpoint_at_rescaled_x(band_struct, rescaled_x, x_positions)
|
|
|
638
649
|
if (!segment_range)
|
|
639
650
|
continue;
|
|
640
651
|
const [x_start, x_end] = segment_range;
|
|
641
|
-
for (const [x_pos, idx] of [
|
|
652
|
+
for (const [x_pos, idx] of [
|
|
653
|
+
[x_start, start_idx],
|
|
654
|
+
[x_end, end_idx],
|
|
655
|
+
]) {
|
|
642
656
|
const dist = Math.abs(rescaled_x - x_pos);
|
|
643
657
|
if (dist < min_dist) {
|
|
644
658
|
min_dist = dist;
|
|
@@ -675,15 +689,12 @@ export function extract_pdos(dos, pdos_type, filter_keys) {
|
|
|
675
689
|
const densities = spin_channels.up;
|
|
676
690
|
if (!Array.isArray(densities) || energies.length !== densities.length)
|
|
677
691
|
continue;
|
|
678
|
-
const is_spin_polarized = spin_channels.down !== null &&
|
|
679
|
-
spin_channels.down.length === densities.length;
|
|
692
|
+
const is_spin_polarized = spin_channels.down !== null && spin_channels.down.length === densities.length;
|
|
680
693
|
result[key] = {
|
|
681
694
|
type: `electronic`,
|
|
682
695
|
energies,
|
|
683
696
|
densities,
|
|
684
|
-
spin_down_densities: is_spin_polarized
|
|
685
|
-
? spin_channels.down ?? undefined
|
|
686
|
-
: undefined,
|
|
697
|
+
spin_down_densities: is_spin_polarized ? (spin_channels.down ?? undefined) : undefined,
|
|
687
698
|
spin_polarized: is_spin_polarized,
|
|
688
699
|
efermi: nested_dos.efermi,
|
|
689
700
|
};
|
|
@@ -743,9 +754,7 @@ export function generate_ribbon_path(x_values, y_values, width_values, x_scale_f
|
|
|
743
754
|
const x_px = x_scale_fn(x_values[idx]);
|
|
744
755
|
const y_data = y_values[idx];
|
|
745
756
|
const raw_width = width_values[idx] ?? 0;
|
|
746
|
-
const width_normalized = Number.isFinite(raw_width) && raw_width > 0
|
|
747
|
-
? raw_width / max_width_val
|
|
748
|
-
: 0;
|
|
757
|
+
const width_normalized = Number.isFinite(raw_width) && raw_width > 0 ? raw_width / max_width_val : 0;
|
|
749
758
|
const half_width_px = width_normalized * max_width_px * scale;
|
|
750
759
|
// In SVG, y increases downward, so upper edge has smaller y value
|
|
751
760
|
const y_upper_px = y_scale_fn(y_data) - half_width_px;
|
|
@@ -757,7 +766,7 @@ export function generate_ribbon_path(x_values, y_values, width_values, x_scale_f
|
|
|
757
766
|
const path_parts = [
|
|
758
767
|
`M${upper_points[0]}`,
|
|
759
768
|
...upper_points.slice(1).map((pt) => `L${pt}`),
|
|
760
|
-
...lower_points.
|
|
769
|
+
...lower_points.toReversed().map((pt) => `L${pt}`),
|
|
761
770
|
`Z`,
|
|
762
771
|
];
|
|
763
772
|
return path_parts.join(` `);
|
|
@@ -811,7 +820,8 @@ function is_electronic_band_struct(bs) {
|
|
|
811
820
|
return true;
|
|
812
821
|
}
|
|
813
822
|
// Pymatgen @class: BandStructure* but not Phonon*
|
|
814
|
-
const
|
|
823
|
+
const raw_class = obj[`@class`];
|
|
824
|
+
const py_class_name = typeof raw_class === `string` ? raw_class : ``;
|
|
815
825
|
if (py_class_name.startsWith(`BandStructure`) && !py_class_name.includes(`Phonon`)) {
|
|
816
826
|
return true;
|
|
817
827
|
}
|
|
@@ -825,7 +835,8 @@ export function compute_frequency_range(band_structs, doses, padding_factor = 0.
|
|
|
825
835
|
// (normalized structures always have qpoints, so we can't detect from them)
|
|
826
836
|
let has_electronic_bs = false;
|
|
827
837
|
// Support both qpoints (phonon) and kpoints (electronic) to detect single vs dict
|
|
828
|
-
const is_single_bs = band_structs &&
|
|
838
|
+
const is_single_bs = band_structs &&
|
|
839
|
+
typeof band_structs === `object` &&
|
|
829
840
|
(`qpoints` in band_structs || `kpoints` in band_structs);
|
|
830
841
|
if (band_structs && typeof band_structs === `object`) {
|
|
831
842
|
// Single structure check
|
|
@@ -887,7 +898,8 @@ export function compute_frequency_range(band_structs, doses, padding_factor = 0.
|
|
|
887
898
|
}
|
|
888
899
|
if (!Number.isFinite(min_val) || !Number.isFinite(max_val))
|
|
889
900
|
return undefined;
|
|
890
|
-
const clamp_min = is_phonon &&
|
|
901
|
+
const clamp_min = is_phonon &&
|
|
902
|
+
min_val < 0 && // clamp phonon noise to 0
|
|
891
903
|
negative_fraction(all_freqs) < IMAGINARY_MODE_NOISE_THRESHOLD;
|
|
892
904
|
if (clamp_min)
|
|
893
905
|
min_val = 0;
|
|
@@ -897,7 +909,7 @@ export function compute_frequency_range(band_structs, doses, padding_factor = 0.
|
|
|
897
909
|
}
|
|
898
910
|
// Parse axis label: "Frequency (THz)" → { name: "Frequency", unit: "THz" }
|
|
899
911
|
function parse_axis_label(label) {
|
|
900
|
-
const match =
|
|
912
|
+
const match = /^(.+?)\s*\(([^)]+)\)$/.exec(label);
|
|
901
913
|
return match ? { name: match[1], unit: match[2] } : { name: label };
|
|
902
914
|
}
|
|
903
915
|
// Format DOS tooltip content from axis labels and values
|
package/dist/state.svelte.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ChemicalElement, ElementCategory } from './element/types';
|
|
2
2
|
import { DEFAULT_CATEGORY_COLORS, default_element_colors } from './colors';
|
|
3
3
|
import type { Tooltip } from './plot';
|
|
4
|
-
import type
|
|
4
|
+
import { type ThemeMode, type ThemeType } from './theme';
|
|
5
5
|
export declare const selected: {
|
|
6
6
|
category: ElementCategory | null;
|
|
7
7
|
element: ChemicalElement | null;
|
package/dist/state.svelte.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AUTO_THEME, COLOR_THEMES, THEME_TYPE } from './theme/index';
|
|
2
2
|
import { DEFAULT_CATEGORY_COLORS, default_element_colors } from './colors';
|
|
3
|
+
import { is_valid_theme_mode } from './theme';
|
|
3
4
|
export const selected = $state({
|
|
4
5
|
category: null,
|
|
5
6
|
element: null,
|
|
@@ -22,8 +23,8 @@ let initial_system_mode = COLOR_THEMES.light;
|
|
|
22
23
|
// Safe theme initialization for test environments
|
|
23
24
|
try {
|
|
24
25
|
if (typeof window !== `undefined` && globalThis.localStorage) {
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
const saved_theme = localStorage.getItem(`matterviz-theme`) ?? ``;
|
|
27
|
+
initial_theme_mode = is_valid_theme_mode(saved_theme) ? saved_theme : AUTO_THEME;
|
|
27
28
|
}
|
|
28
29
|
else {
|
|
29
30
|
initial_theme_mode = AUTO_THEME;
|
|
@@ -1,23 +1,62 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Vec3 } from '../math'
|
|
3
|
+
import * as math from '../math'
|
|
4
|
+
import { DEFAULTS } from '../settings'
|
|
5
|
+
import { T } from '@threlte/core'
|
|
6
|
+
import type { ComponentProps } from 'svelte'
|
|
7
|
+
import { Euler, Quaternion, Vector3 } from 'three'
|
|
8
|
+
|
|
9
|
+
let {
|
|
10
|
+
position,
|
|
11
|
+
vector,
|
|
12
|
+
scale = DEFAULTS.structure.vector_scale,
|
|
13
|
+
color = DEFAULTS.structure.vector_color,
|
|
14
|
+
shaft_radius = DEFAULTS.structure.vector_shaft_radius,
|
|
15
|
+
arrow_head_radius = DEFAULTS.structure.vector_arrow_head_radius,
|
|
16
|
+
arrow_head_length = DEFAULTS.structure.vector_arrow_head_length,
|
|
17
|
+
...rest
|
|
18
|
+
}: ComponentProps<typeof T.Mesh> & {
|
|
19
|
+
position: Vec3
|
|
20
|
+
vector: Vec3
|
|
21
|
+
scale?: number
|
|
22
|
+
color?: string
|
|
23
|
+
shaft_radius?: number // negative = relative to length
|
|
24
|
+
arrow_head_radius?: number
|
|
25
|
+
arrow_head_length?: number
|
|
26
|
+
} = $props()
|
|
27
|
+
|
|
28
|
+
const mag = $derived(Math.hypot(...vector))
|
|
29
|
+
const dir = $derived(
|
|
30
|
+
mag > math.EPS ? math.scale(vector, 1 / mag) : ([0, 1, 0] as Vec3),
|
|
31
|
+
)
|
|
32
|
+
const vec_len = $derived(mag * scale)
|
|
33
|
+
|
|
34
|
+
const head_len = $derived(
|
|
35
|
+
arrow_head_length < 0 ? vec_len * -arrow_head_length : arrow_head_length,
|
|
36
|
+
)
|
|
37
|
+
const shaft_len = $derived(Math.max(0, vec_len - head_len * 0.5))
|
|
38
|
+
const shaft_r = $derived(
|
|
39
|
+
shaft_radius < 0 ? shaft_len * -shaft_radius : shaft_radius,
|
|
40
|
+
)
|
|
41
|
+
const head_r = $derived(
|
|
42
|
+
arrow_head_radius < 0 ? shaft_len * -arrow_head_radius : arrow_head_radius,
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
const shaft_pos = $derived(
|
|
46
|
+
math.add(position, math.scale(dir, shaft_len * 0.5)) as Vec3,
|
|
47
|
+
)
|
|
48
|
+
const head_pos = $derived(
|
|
49
|
+
math.add(position, math.scale(dir, shaft_len + head_len * 0.5)) as Vec3,
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
const rotation = $derived.by((): Vec3 => {
|
|
53
|
+
if (mag < math.EPS) return [0, 0, 0]
|
|
54
|
+
const quat = new Quaternion().setFromUnitVectors(
|
|
55
|
+
new Vector3(0, 1, 0),
|
|
56
|
+
new Vector3(...dir),
|
|
57
|
+
)
|
|
58
|
+
return new Euler().setFromQuaternion(quat).toArray().slice(0, 3) as Vec3
|
|
59
|
+
})
|
|
21
60
|
</script>
|
|
22
61
|
|
|
23
62
|
{#if shaft_len > 0.01}
|