matterviz 0.4.2 → 0.4.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/FilePicker.svelte +40 -50
- package/dist/api/optimade.js +10 -7
- package/dist/app.css +15 -0
- package/dist/brillouin/BrillouinZone.svelte +18 -9
- package/dist/brillouin/BrillouinZoneScene.svelte +20 -29
- package/dist/brillouin/compute.js +10 -16
- package/dist/brillouin/geometry.js +2 -2
- package/dist/chempot-diagram/ChemPotDiagram.svelte +18 -15
- package/dist/chempot-diagram/ChemPotDiagram2D.svelte +17 -113
- package/dist/chempot-diagram/ChemPotDiagram3D.svelte +104 -264
- package/dist/chempot-diagram/async-compute.svelte.js +12 -13
- package/dist/chempot-diagram/color.d.ts +21 -1
- package/dist/chempot-diagram/color.js +70 -1
- package/dist/chempot-diagram/compute.d.ts +7 -0
- package/dist/chempot-diagram/compute.js +85 -26
- package/dist/chempot-diagram/export.js +1 -6
- package/dist/chempot-diagram/temperature.js +9 -10
- package/dist/composition/BarChart.svelte +7 -9
- package/dist/composition/Composition.svelte +3 -8
- package/dist/composition/Formula.svelte +2 -2
- package/dist/composition/FormulaFilter.svelte +27 -93
- package/dist/composition/format.js +6 -8
- package/dist/composition/parse.js +50 -105
- package/dist/constants.d.ts +0 -1
- package/dist/constants.js +6 -17
- package/dist/convex-hull/ConvexHull2D.svelte +0 -2
- package/dist/convex-hull/ConvexHull3D.svelte +19 -47
- package/dist/convex-hull/ConvexHull4D.svelte +65 -95
- package/dist/convex-hull/StructurePopup.svelte +1 -1
- package/dist/convex-hull/gas-thermodynamics.js +21 -53
- package/dist/convex-hull/helpers.js +1 -7
- package/dist/convex-hull/thermodynamics.js +19 -27
- package/dist/coordination/CoordinationBarPlot.svelte +12 -21
- package/dist/element/BohrAtom.svelte +0 -1
- package/dist/element/ElementTile.svelte +26 -44
- package/dist/element/data.d.ts +2 -0
- package/dist/element/data.js +5 -1
- package/dist/element/index.d.ts +1 -1
- package/dist/element/index.js +1 -1
- package/dist/fermi-surface/FermiSurface.svelte +22 -23
- package/dist/fermi-surface/FermiSurface.svelte.d.ts +2 -6
- package/dist/fermi-surface/FermiSurfaceScene.svelte +32 -77
- package/dist/fermi-surface/compute.js +22 -55
- package/dist/fermi-surface/parse.js +38 -70
- package/dist/file-viewer/JsonBrowser.svelte +1043 -0
- package/dist/file-viewer/JsonBrowser.svelte.d.ts +9 -0
- package/dist/file-viewer/PlotPanel.svelte +350 -0
- package/dist/file-viewer/PlotPanel.svelte.d.ts +9 -0
- package/dist/file-viewer/TrajectoryWithDos.svelte +30 -0
- package/dist/file-viewer/TrajectoryWithDos.svelte.d.ts +10 -0
- package/dist/file-viewer/detect.d.ts +11 -0
- package/dist/file-viewer/detect.js +381 -0
- package/dist/file-viewer/eligibility.d.ts +4 -0
- package/dist/file-viewer/eligibility.js +53 -0
- package/dist/file-viewer/host-protocol.d.ts +50 -0
- package/dist/file-viewer/host-transfer.d.ts +25 -0
- package/dist/file-viewer/host-transfer.js +42 -0
- package/dist/file-viewer/index.d.ts +5 -0
- package/dist/file-viewer/index.js +5 -0
- package/dist/file-viewer/main.d.ts +44 -0
- package/dist/file-viewer/main.js +535 -0
- package/dist/file-viewer/parse.d.ts +9 -0
- package/dist/file-viewer/parse.js +170 -0
- package/dist/file-viewer/plot-utils.d.ts +24 -0
- package/dist/file-viewer/plot-utils.js +191 -0
- package/dist/file-viewer/types.d.ts +4 -0
- package/dist/file-viewer/types.js +5 -0
- package/dist/heatmap-matrix/HeatmapMatrix.svelte +57 -84
- package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/io/ExportPane.svelte +1 -1
- package/dist/io/decompress.d.ts +2 -0
- package/dist/io/decompress.js +3 -2
- package/dist/io/export.d.ts +7 -4
- package/dist/io/export.js +70 -18
- package/dist/io/file-drop.js +60 -35
- package/dist/io/url-drop.d.ts +2 -0
- package/dist/io/url-drop.js +28 -16
- package/dist/isosurface/Isosurface.svelte +687 -196
- package/dist/isosurface/Isosurface.svelte.d.ts +7 -1
- package/dist/isosurface/IsosurfaceControls.svelte +564 -85
- package/dist/isosurface/IsosurfaceControls.svelte.d.ts +1 -1
- package/dist/isosurface/VolumeSlice.svelte +224 -0
- package/dist/isosurface/VolumeSlice.svelte.d.ts +28 -0
- package/dist/isosurface/coloring.d.ts +20 -0
- package/dist/isosurface/coloring.js +118 -0
- package/dist/isosurface/geometry-worker-types.d.ts +38 -0
- package/dist/isosurface/geometry.worker.d.ts +1 -0
- package/dist/isosurface/geometry.worker.js +59 -0
- package/dist/isosurface/grid.d.ts +10 -0
- package/dist/isosurface/grid.js +31 -0
- package/dist/isosurface/index.d.ts +4 -0
- package/dist/isosurface/index.js +4 -0
- package/dist/isosurface/profile.d.ts +12 -0
- package/dist/isosurface/profile.js +19 -0
- package/dist/isosurface/sampling.d.ts +34 -0
- package/dist/isosurface/sampling.js +408 -0
- package/dist/isosurface/slice-rendering.d.ts +13 -0
- package/dist/isosurface/slice-rendering.js +79 -0
- package/dist/isosurface/slice.d.ts +22 -2
- package/dist/isosurface/slice.js +200 -116
- package/dist/isosurface/types.d.ts +24 -1
- package/dist/isosurface/types.js +120 -8
- package/dist/json-path.d.ts +4 -0
- package/dist/json-path.js +89 -0
- package/dist/labels.js +1 -1
- package/dist/layout/InfoCard.svelte +1 -3
- package/dist/layout/SettingsSection.svelte +52 -61
- package/dist/layout/SettingsSection.svelte.d.ts +6 -7
- package/dist/layout/ViewerChrome.svelte +7 -1
- package/dist/layout/json-tree/JsonNode.svelte +14 -48
- package/dist/layout/json-tree/JsonTree.svelte +48 -95
- package/dist/layout/json-tree/JsonValue.svelte +3 -18
- package/dist/layout/json-tree/utils.d.ts +0 -3
- package/dist/layout/json-tree/utils.js +50 -179
- package/dist/marching-cubes.d.ts +8 -1
- package/dist/marching-cubes.js +115 -48
- package/dist/math.d.ts +3 -2
- package/dist/math.js +29 -38
- package/dist/overlays/ContextMenu.svelte +15 -32
- package/dist/overlays/DraggablePane.svelte +39 -58
- package/dist/overlays/DraggablePane.svelte.d.ts +1 -1
- package/dist/overlays/GlassChip.svelte +3 -1
- package/dist/periodic-table/PeriodicTableControls.svelte +26 -52
- package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +18 -34
- package/dist/phase-diagram/build-diagram.js +1 -6
- package/dist/phase-diagram/svg-to-diagram.js +9 -14
- package/dist/plot/bar/BarPlot.svelte +38 -42
- package/dist/plot/bar/SpacegroupBarPlot.svelte +18 -42
- package/dist/plot/box/BoxPlot.svelte +27 -23
- package/dist/plot/core/auto-place.d.ts +1 -1
- package/dist/plot/core/auto-place.js +1 -1
- package/dist/plot/core/data-transform.d.ts +1 -2
- package/dist/plot/core/data-transform.js +0 -10
- package/dist/plot/core/layout.d.ts +12 -5
- package/dist/plot/core/layout.js +37 -27
- package/dist/plot/core/pan-zoom.svelte.d.ts +2 -4
- package/dist/plot/core/pan-zoom.svelte.js +34 -17
- package/dist/plot/core/placed-tween.svelte.d.ts +3 -0
- package/dist/plot/core/placed-tween.svelte.js +68 -21
- package/dist/plot/core/svg.js +0 -1
- package/dist/plot/core/utils/hierarchy-chart.d.ts +1 -0
- package/dist/plot/core/utils/hierarchy-chart.js +12 -0
- package/dist/plot/core/utils/hierarchy-labels.js +3 -2
- package/dist/plot/histogram/Histogram.svelte +21 -26
- package/dist/plot/sankey/sankey.js +13 -9
- package/dist/plot/scatter/BinnedScatterPlot.svelte +59 -43
- package/dist/plot/scatter/ScatterPlot.svelte +67 -52
- package/dist/plot/scatter/adaptive-density.d.ts +1 -1
- package/dist/plot/scatter/adaptive-density.js +36 -20
- package/dist/plot/sunburst/Sunburst.svelte +20 -20
- package/dist/plot/treemap/Treemap.svelte +175 -60
- package/dist/plot/treemap/Treemap.svelte.d.ts +6 -0
- package/dist/plot/treemap/index.d.ts +1 -0
- package/dist/plot/treemap/labels.d.ts +38 -0
- package/dist/plot/treemap/labels.js +80 -0
- package/dist/plot/treemap/treemap.d.ts +4 -2
- package/dist/plot/treemap/treemap.js +5 -2
- package/dist/rdf/RdfPlot.svelte +17 -35
- package/dist/rdf/calc-rdf.js +59 -44
- package/dist/rdf/index.d.ts +0 -1
- package/dist/sanitize.js +84 -26
- package/dist/scene/SceneCamera.svelte +1 -1
- package/dist/scene/SceneCamera.svelte.d.ts +1 -1
- package/dist/scene/index.d.ts +1 -2
- package/dist/scene/index.js +1 -1
- package/dist/scene/{props.js → props.svelte.js} +15 -1
- package/dist/settings.js +159 -482
- package/dist/spectral/Bands.svelte +151 -158
- package/dist/spectral/BrillouinBandsDos.svelte +4 -19
- package/dist/spectral/Dos.svelte +26 -24
- package/dist/spectral/helpers.js +40 -105
- package/dist/structure/AtomLegend.svelte +8 -13
- package/dist/structure/AtomLegend.svelte.d.ts +2 -3
- package/dist/structure/CellSelect.svelte +35 -10
- package/dist/structure/Structure.svelte +177 -99
- package/dist/structure/Structure.svelte.d.ts +1 -1
- package/dist/structure/StructureCarousel.svelte +10 -3
- package/dist/structure/StructureControls.svelte +8 -26
- package/dist/structure/StructureControls.svelte.d.ts +1 -1
- package/dist/structure/StructureInfoPane.svelte +65 -76
- package/dist/structure/StructureScene.svelte +75 -109
- package/dist/structure/StructureScene.svelte.d.ts +3 -1
- package/dist/structure/StructureViewport.svelte +120 -55
- package/dist/structure/StructureViewport.svelte.d.ts +3 -1
- package/dist/structure/atom-properties.d.ts +1 -1
- package/dist/structure/atom-properties.js +4 -3
- package/dist/structure/bond-order-perception.js +3 -8
- package/dist/structure/bonding.d.ts +0 -1
- package/dist/structure/bonding.js +16 -23
- package/dist/structure/export.js +50 -74
- package/dist/structure/format-detect.js +5 -7
- package/dist/structure/index.js +6 -12
- package/dist/structure/parse.js +38 -100
- package/dist/structure/partial-occupancy.js +7 -4
- package/dist/structure/pbc.js +8 -10
- package/dist/structure/polyhedra.js +5 -4
- package/dist/structure/prop-groups.d.ts +85 -0
- package/dist/structure/prop-groups.js +18 -0
- package/dist/symmetry/SymmetryStats.svelte +0 -4
- package/dist/symmetry/WyckoffTable.svelte +5 -4
- package/dist/symmetry/cell-transform.js +5 -14
- package/dist/symmetry/index.js +6 -9
- package/dist/table/HeatmapTable.svelte +61 -103
- package/dist/table/ToggleMenu.svelte +166 -44
- package/dist/table/ToggleMenu.svelte.d.ts +1 -1
- package/dist/theme/embedded.d.ts +18 -0
- package/dist/theme/embedded.js +206 -0
- package/dist/theme/index.d.ts +4 -0
- package/dist/theme/index.js +1 -2
- package/dist/theme/themes.mjs +31 -60
- package/dist/tooltip/TooltipContent.svelte +1 -1
- package/dist/tooltip/TooltipContent.svelte.d.ts +1 -1
- package/dist/tooltip/index.d.ts +8 -1
- package/dist/trajectory/Trajectory.svelte +140 -120
- package/dist/trajectory/TrajectoryError.svelte +1 -66
- package/dist/trajectory/TrajectoryExportPane.svelte +0 -1
- package/dist/trajectory/TrajectoryInfoPane.svelte +55 -80
- package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +2 -1
- package/dist/trajectory/extract.js +19 -29
- package/dist/trajectory/format-detect.d.ts +2 -0
- package/dist/trajectory/format-detect.js +7 -5
- package/dist/trajectory/frame-reader.js +3 -4
- package/dist/trajectory/helpers.js +16 -49
- package/dist/trajectory/index.js +2 -8
- package/dist/trajectory/parse/ase.js +1 -1
- package/dist/trajectory/parse/index.d.ts +4 -3
- package/dist/trajectory/parse/index.js +12 -17
- package/dist/trajectory/parse/vaspout-h5.d.ts +0 -1
- package/dist/trajectory/parse/vaspout-h5.js +1 -4
- package/dist/trajectory/parse/xyz.js +48 -2
- package/dist/trajectory/plotting.js +14 -37
- package/dist/xrd/XrdPlot.svelte +43 -68
- package/dist/xrd/calc-xrd.js +22 -58
- package/dist/xrd/parse.js +13 -22
- package/package.json +40 -8
- package/readme.md +6 -5
- package/dist/scene/types.d.ts +0 -26
- package/dist/tooltip/types.d.ts +0 -8
- package/dist/trajectory/constants.d.ts +0 -6
- package/dist/trajectory/constants.js +0 -11
- /package/dist/{scene/types.js → file-viewer/host-protocol.js} +0 -0
- /package/dist/{tooltip/types.js → isosurface/geometry-worker-types.js} +0 -0
|
@@ -250,7 +250,7 @@
|
|
|
250
250
|
|
|
251
251
|
let num_structures = $derived(Object.keys(band_structs_dict).length)
|
|
252
252
|
let all_segment_keys = $derived(Object.keys(all_segments))
|
|
253
|
-
let common_segment_keys = $derived
|
|
253
|
+
let common_segment_keys = $derived(
|
|
254
254
|
all_segment_keys.filter(
|
|
255
255
|
(segment_key) => all_segments[segment_key].length === num_structures,
|
|
256
256
|
),
|
|
@@ -337,124 +337,145 @@
|
|
|
337
337
|
x_positions = positions
|
|
338
338
|
})
|
|
339
339
|
|
|
340
|
+
// Plottable branch segments with rescaled x coordinates, shared by the band-line
|
|
341
|
+
// series and fat-band ribbon computations below
|
|
342
|
+
interface PlotSegment {
|
|
343
|
+
bs_idx: number
|
|
344
|
+
label: string
|
|
345
|
+
bs: BaseBandStructure
|
|
346
|
+
start_idx: number
|
|
347
|
+
end_idx: number // exclusive
|
|
348
|
+
segment_key: string
|
|
349
|
+
scaled_distances: number[]
|
|
350
|
+
}
|
|
351
|
+
let plot_segments = $derived.by((): PlotSegment[] => {
|
|
352
|
+
const segments: PlotSegment[] = []
|
|
353
|
+
for (const [bs_idx, [label, bs]] of Object.entries(band_structs_dict).entries()) {
|
|
354
|
+
for (const branch of bs.branches) {
|
|
355
|
+
// Skip discontinuous segments (consecutive labeled points)
|
|
356
|
+
if (branch.end_index - branch.start_index === 1) continue
|
|
357
|
+
|
|
358
|
+
const start_idx = branch.start_index
|
|
359
|
+
const end_idx = branch.end_index + 1
|
|
360
|
+
const segment_key = helpers.get_segment_key(
|
|
361
|
+
bs.qpoints[start_idx]?.label ?? undefined,
|
|
362
|
+
bs.qpoints[end_idx - 1]?.label ?? undefined,
|
|
363
|
+
)
|
|
364
|
+
if (!segments_to_plot.has(segment_key)) continue
|
|
365
|
+
|
|
366
|
+
const [x_start, x_end] = x_positions?.[segment_key] || [0, 1]
|
|
367
|
+
const scaled_distances = helpers.scale_segment_distances(
|
|
368
|
+
bs.distance.slice(start_idx, end_idx),
|
|
369
|
+
x_start,
|
|
370
|
+
x_end,
|
|
371
|
+
)
|
|
372
|
+
segments.push({ bs_idx, label, bs, start_idx, end_idx, segment_key, scaled_distances })
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
return segments
|
|
376
|
+
})
|
|
377
|
+
|
|
340
378
|
// Convert band structures to scatter plot series + track max slope in one pass
|
|
341
379
|
let { series_data, max_abs_slope } = $derived.by(
|
|
342
380
|
(): {
|
|
343
381
|
series_data: DataSeries[]
|
|
344
382
|
max_abs_slope: number
|
|
345
383
|
} => {
|
|
346
|
-
if (Object.keys(band_structs_dict).length === 0 || segments_to_plot.size === 0) {
|
|
347
|
-
return { series_data: [], max_abs_slope: 1 }
|
|
348
|
-
}
|
|
349
|
-
|
|
350
384
|
const all_series: DataSeries[] = []
|
|
351
385
|
let max_slope = 0
|
|
352
|
-
|
|
353
|
-
|
|
386
|
+
// Cache per band structure: segments share their bs, so avoid re-scanning
|
|
387
|
+
// all q-points once per plotted segment
|
|
388
|
+
const gamma_cache = new Map<BaseBandStructure, number[]>()
|
|
389
|
+
|
|
390
|
+
for (const {
|
|
391
|
+
bs_idx,
|
|
392
|
+
label,
|
|
393
|
+
bs,
|
|
394
|
+
start_idx,
|
|
395
|
+
end_idx,
|
|
396
|
+
scaled_distances,
|
|
397
|
+
} of plot_segments) {
|
|
354
398
|
const color = PLOT_COLORS[bs_idx % PLOT_COLORS.length]
|
|
355
399
|
const structure_label = label || `Structure ${bs_idx + 1}`
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
const end_idx = branch.end_index + 1
|
|
362
|
-
const start_label = bs.qpoints[start_idx]?.label ?? undefined
|
|
363
|
-
const end_label = bs.qpoints[end_idx - 1]?.label ?? undefined
|
|
364
|
-
const segment_key = helpers.get_segment_key(start_label, end_label)
|
|
365
|
-
|
|
366
|
-
if (!segments_to_plot.has(segment_key)) continue
|
|
367
|
-
|
|
368
|
-
// Skip discontinuous segments (consecutive labeled points)
|
|
369
|
-
const is_discontinuity = branch.end_index - branch.start_index === 1
|
|
370
|
-
if (is_discontinuity) continue
|
|
371
|
-
|
|
372
|
-
const [x_start, x_end] = x_positions?.[segment_key] || [0, 1]
|
|
373
|
-
|
|
374
|
-
// Scale distances for this segment
|
|
375
|
-
const segment_distances = bs.distance.slice(start_idx, end_idx)
|
|
376
|
-
const scaled_distances = helpers.scale_segment_distances(
|
|
377
|
-
segment_distances,
|
|
378
|
-
x_start,
|
|
379
|
-
x_end,
|
|
380
|
-
)
|
|
400
|
+
let gamma_indices = gamma_cache.get(bs)
|
|
401
|
+
if (!gamma_indices) {
|
|
402
|
+
gamma_indices = detected_band_type === `phonon` ? helpers.find_gamma_indices(bs) : []
|
|
403
|
+
gamma_cache.set(bs, gamma_indices)
|
|
404
|
+
}
|
|
381
405
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
)
|
|
387
|
-
const is_acoustic = helpers.classify_acoustic(bs, band_idx, gamma_indices)
|
|
406
|
+
// Create series for each band (and spin channel for electronic structures)
|
|
407
|
+
for (let band_idx = 0; band_idx < bs.nb_bands; band_idx++) {
|
|
408
|
+
const frequencies = convert_band_values(bs.bands[band_idx].slice(start_idx, end_idx))
|
|
409
|
+
const is_acoustic = helpers.classify_acoustic(bs, band_idx, gamma_indices)
|
|
388
410
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
411
|
+
const line_style_up = get_line_style(
|
|
412
|
+
color,
|
|
413
|
+
is_acoustic === true,
|
|
414
|
+
frequencies,
|
|
415
|
+
band_idx,
|
|
416
|
+
)
|
|
395
417
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
}
|
|
418
|
+
const spin_down_band = bs.spin_down_bands?.[band_idx]
|
|
419
|
+
const has_spin_down_channel =
|
|
420
|
+
detected_band_type === `electronic` &&
|
|
421
|
+
Array.isArray(spin_down_band) &&
|
|
422
|
+
spin_down_band.length >= end_idx
|
|
423
|
+
|
|
424
|
+
const track_max_slope = (meta: helpers.BandPointMeta[]) => {
|
|
425
|
+
for (const pt of meta) {
|
|
426
|
+
if (typeof pt.slope === `number` && Number.isFinite(pt.slope)) {
|
|
427
|
+
max_slope = Math.max(max_slope, Math.abs(pt.slope))
|
|
407
428
|
}
|
|
408
429
|
}
|
|
430
|
+
}
|
|
409
431
|
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
432
|
+
if (effective_spin_mode !== `down_only`) {
|
|
433
|
+
const meta = helpers.build_point_metadata({
|
|
434
|
+
x_vals: scaled_distances,
|
|
435
|
+
y_vals: frequencies,
|
|
436
|
+
band_idx,
|
|
437
|
+
spin: `up`,
|
|
438
|
+
is_acoustic,
|
|
439
|
+
bs,
|
|
440
|
+
start_idx,
|
|
441
|
+
})
|
|
442
|
+
track_max_slope(meta)
|
|
443
|
+
all_series.push({
|
|
444
|
+
x: scaled_distances,
|
|
445
|
+
y: frequencies,
|
|
446
|
+
markers: `line`,
|
|
447
|
+
label: has_spin_down_channel ? `${structure_label} (↑)` : structure_label,
|
|
448
|
+
line_style: line_style_up,
|
|
449
|
+
metadata: meta,
|
|
450
|
+
})
|
|
451
|
+
}
|
|
430
452
|
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
}
|
|
453
|
+
if (has_spin_down_channel && effective_spin_mode !== `up_only`) {
|
|
454
|
+
const spin_down_frequencies = convert_band_values(
|
|
455
|
+
spin_down_band.slice(start_idx, end_idx),
|
|
456
|
+
)
|
|
457
|
+
const meta = helpers.build_point_metadata({
|
|
458
|
+
x_vals: scaled_distances,
|
|
459
|
+
y_vals: spin_down_frequencies,
|
|
460
|
+
band_idx,
|
|
461
|
+
spin: `down`,
|
|
462
|
+
is_acoustic,
|
|
463
|
+
bs,
|
|
464
|
+
start_idx,
|
|
465
|
+
})
|
|
466
|
+
track_max_slope(meta)
|
|
467
|
+
all_series.push({
|
|
468
|
+
x: scaled_distances,
|
|
469
|
+
y: spin_down_frequencies,
|
|
470
|
+
markers: `line`,
|
|
471
|
+
label: `${structure_label} (↓)`,
|
|
472
|
+
line_style: {
|
|
473
|
+
...line_style_up,
|
|
474
|
+
line_dash: `4,2`,
|
|
475
|
+
stroke_width: Math.max(1, line_style_up.stroke_width - 0.1),
|
|
476
|
+
},
|
|
477
|
+
metadata: meta,
|
|
478
|
+
})
|
|
458
479
|
}
|
|
459
480
|
}
|
|
460
481
|
}
|
|
@@ -465,67 +486,39 @@
|
|
|
465
486
|
|
|
466
487
|
// Compute ribbon data for bands with width information
|
|
467
488
|
let ribbon_data = $derived.by((): RibbonData[] => {
|
|
468
|
-
if (Object.keys(band_structs_dict).length === 0 || segments_to_plot.size === 0) {
|
|
469
|
-
return []
|
|
470
|
-
}
|
|
471
|
-
|
|
472
489
|
const all_ribbons: RibbonData[] = []
|
|
473
490
|
|
|
474
|
-
for (const
|
|
491
|
+
for (const segment of plot_segments) {
|
|
492
|
+
const { bs_idx, label, bs, start_idx, end_idx, segment_key, scaled_distances } = segment
|
|
475
493
|
// Skip if this band structure has no width data
|
|
476
|
-
if (!bs.band_widths
|
|
494
|
+
if (!bs.band_widths?.length) continue
|
|
477
495
|
|
|
478
|
-
const color = PLOT_COLORS[bs_idx % PLOT_COLORS.length]
|
|
479
|
-
const structure_label = label || `Structure ${bs_idx + 1}`
|
|
480
496
|
const config = helpers.get_ribbon_config(ribbon_config, label)
|
|
497
|
+
const structure_label = label || `Structure ${bs_idx + 1}`
|
|
481
498
|
|
|
482
|
-
for
|
|
483
|
-
|
|
484
|
-
const
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
const
|
|
488
|
-
|
|
489
|
-
if (
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
// Create ribbon data for each band that has width data
|
|
506
|
-
for (let band_idx = 0; band_idx < bs.nb_bands; band_idx++) {
|
|
507
|
-
const band_widths = bs.band_widths[band_idx]
|
|
508
|
-
if (!band_widths) continue
|
|
509
|
-
|
|
510
|
-
const width_values = band_widths.slice(start_idx, end_idx)
|
|
511
|
-
// Skip if all widths are zero or missing
|
|
512
|
-
if (width_values.every((wv) => !wv || wv <= 0)) continue
|
|
513
|
-
|
|
514
|
-
const y_values = convert_band_values(bs.bands[band_idx].slice(start_idx, end_idx))
|
|
515
|
-
|
|
516
|
-
all_ribbons.push({
|
|
517
|
-
x_values: scaled_distances,
|
|
518
|
-
y_values,
|
|
519
|
-
width_values,
|
|
520
|
-
color: config.color ?? color,
|
|
521
|
-
opacity: config.opacity ?? 0.3,
|
|
522
|
-
max_width: config.max_width ?? 6,
|
|
523
|
-
scale: config.scale ?? 1,
|
|
524
|
-
band_idx,
|
|
525
|
-
structure_label,
|
|
526
|
-
segment_key,
|
|
527
|
-
})
|
|
528
|
-
}
|
|
499
|
+
// Create ribbon data for each band that has width data
|
|
500
|
+
for (let band_idx = 0; band_idx < bs.nb_bands; band_idx++) {
|
|
501
|
+
const band_widths = bs.band_widths[band_idx]
|
|
502
|
+
if (!band_widths) continue
|
|
503
|
+
|
|
504
|
+
const width_values = band_widths.slice(start_idx, end_idx)
|
|
505
|
+
// Skip if all widths are zero or missing
|
|
506
|
+
if (width_values.every((wv) => !wv || wv <= 0)) continue
|
|
507
|
+
|
|
508
|
+
const y_values = convert_band_values(bs.bands[band_idx].slice(start_idx, end_idx))
|
|
509
|
+
|
|
510
|
+
all_ribbons.push({
|
|
511
|
+
x_values: scaled_distances,
|
|
512
|
+
y_values,
|
|
513
|
+
width_values,
|
|
514
|
+
color: config.color ?? PLOT_COLORS[bs_idx % PLOT_COLORS.length],
|
|
515
|
+
opacity: config.opacity ?? 0.3,
|
|
516
|
+
max_width: config.max_width ?? 6,
|
|
517
|
+
scale: config.scale ?? 1,
|
|
518
|
+
band_idx,
|
|
519
|
+
structure_label,
|
|
520
|
+
segment_key,
|
|
521
|
+
})
|
|
529
522
|
}
|
|
530
523
|
}
|
|
531
524
|
|
|
@@ -642,7 +635,7 @@
|
|
|
642
635
|
]
|
|
643
636
|
})
|
|
644
637
|
|
|
645
|
-
let custom_highlight_regions = $derived
|
|
638
|
+
let custom_highlight_regions = $derived(
|
|
646
639
|
(highlight_regions ?? [])
|
|
647
640
|
.filter((region) => Number.isFinite(region.y_min) && Number.isFinite(region.y_max))
|
|
648
641
|
.map((region) => ({
|
|
@@ -47,18 +47,9 @@
|
|
|
47
47
|
let shared_frequency_range = $derived(helpers.compute_frequency_range(band_structs, doses))
|
|
48
48
|
|
|
49
49
|
// Extract Fermi level from electronic band structure or DOS data
|
|
50
|
-
let fermi_level = $derived
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
`efermi` in (band_structs as object) ? band_structs : Object.values(band_structs)[0]
|
|
54
|
-
const bs_efermi = (bs_source as Record<string, unknown>)?.efermi
|
|
55
|
-
if (typeof bs_efermi === `number`) return bs_efermi
|
|
56
|
-
|
|
57
|
-
// Check DOS for efermi
|
|
58
|
-
const dos_source = `efermi` in (doses as object) ? doses : Object.values(doses)[0]
|
|
59
|
-
const dos_efermi = (dos_source as Record<string, unknown>)?.efermi
|
|
60
|
-
return typeof dos_efermi === `number` ? dos_efermi : undefined
|
|
61
|
-
})
|
|
50
|
+
let fermi_level = $derived(
|
|
51
|
+
helpers.extract_efermi(band_structs) ?? helpers.extract_efermi(doses),
|
|
52
|
+
)
|
|
62
53
|
|
|
63
54
|
// Convert fractional k-point coordinates to Cartesian reciprocal space
|
|
64
55
|
// using the structure's reciprocal lattice (consistent with BZ computation)
|
|
@@ -91,13 +82,7 @@
|
|
|
91
82
|
let clientWidth = $state(desktop_width)
|
|
92
83
|
let is_desktop = $derived(clientWidth >= desktop_width)
|
|
93
84
|
let is_mobile = $derived(clientWidth < tablet_width)
|
|
94
|
-
let screen_class = $derived(
|
|
95
|
-
clientWidth >= desktop_width
|
|
96
|
-
? `desktop`
|
|
97
|
-
: clientWidth >= tablet_width
|
|
98
|
-
? `tablet`
|
|
99
|
-
: `phone`,
|
|
100
|
-
)
|
|
85
|
+
let screen_class = $derived(is_desktop ? `desktop` : is_mobile ? `phone` : `tablet`)
|
|
101
86
|
|
|
102
87
|
const bands_default_axis = (range = shared_frequency_range): AxisConfig =>
|
|
103
88
|
helpers.axis_with_range(bands_props.y_axis, range)
|
package/dist/spectral/Dos.svelte
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import type { Vec2 } from '../math'
|
|
6
6
|
import ScatterPlot from '../plot/scatter/ScatterPlot.svelte'
|
|
7
7
|
import type { AxisConfig, DataSeries } from '../plot/core/types'
|
|
8
|
+
import { extent } from 'd3-array'
|
|
8
9
|
import type { ComponentProps } from 'svelte'
|
|
9
10
|
import { tooltip as attach_tooltip } from 'svelte-multiselect/attachments'
|
|
10
11
|
import {
|
|
@@ -299,34 +300,35 @@
|
|
|
299
300
|
let clamp_to_zero = $derived(
|
|
300
301
|
is_phonon &&
|
|
301
302
|
all_freqs.length > 0 &&
|
|
302
|
-
|
|
303
|
+
(extent(all_freqs)[0] ?? 0) < 0 &&
|
|
303
304
|
negative_fraction(all_freqs) < IMAGINARY_MODE_NOISE_THRESHOLD,
|
|
304
305
|
)
|
|
305
306
|
|
|
306
307
|
// Check if we have mirrored spin-down data (negative densities)
|
|
307
308
|
let has_mirrored_spin = $derived(effective_spin_mode === `mirror` && has_spin_polarized)
|
|
308
309
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
if (
|
|
316
|
-
if (
|
|
317
|
-
return [
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
310
|
+
// Density axis starts at 0 (unless mirror mode needs negative values); frequency axis
|
|
311
|
+
// clamps to 0 only when negative phonon frequencies are numerical noise.
|
|
312
|
+
// Prefer d3 extent over Math.min/max(...arr) — large DOS grids can blow the call stack.
|
|
313
|
+
const compute_range = (values: number[], is_density_axis: boolean): Vec2 | undefined => {
|
|
314
|
+
if (values.length === 0) return undefined
|
|
315
|
+
const [min_val, max_val] = extent(values) as [number, number]
|
|
316
|
+
if (is_density_axis && has_mirrored_spin) return [min_val, max_val]
|
|
317
|
+
if (is_density_axis || clamp_to_zero) return [0, max_val]
|
|
318
|
+
return [min_val, max_val]
|
|
319
|
+
}
|
|
320
|
+
let x_range = $derived(
|
|
321
|
+
compute_range(
|
|
322
|
+
series_data.flatMap((srs) => srs.x),
|
|
323
|
+
is_horizontal,
|
|
324
|
+
),
|
|
325
|
+
)
|
|
326
|
+
let y_range = $derived(
|
|
327
|
+
compute_range(
|
|
328
|
+
series_data.flatMap((srs) => srs.y),
|
|
329
|
+
!is_horizontal,
|
|
330
|
+
),
|
|
331
|
+
)
|
|
330
332
|
|
|
331
333
|
// Get axis labels based on orientation
|
|
332
334
|
let x_label = $derived(
|
|
@@ -374,9 +376,9 @@
|
|
|
374
376
|
let effective_sigma_range = $derived.by((): Vec2 => {
|
|
375
377
|
if (sigma_range) return sigma_range
|
|
376
378
|
if (all_freqs.length === 0) return [0, 1]
|
|
377
|
-
const
|
|
379
|
+
const [min_freq, max_freq] = extent(all_freqs) as [number, number]
|
|
378
380
|
// Reasonable sigma range: 0 to ~5% of total range
|
|
379
|
-
const max_sigma = Math.max(0.1,
|
|
381
|
+
const max_sigma = Math.max(0.1, (max_freq - min_freq) * 0.05)
|
|
380
382
|
return [0, max_sigma]
|
|
381
383
|
})
|
|
382
384
|
|