matterviz 0.3.7 → 0.4.1
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/Icon.svelte +7 -4
- package/dist/MillerIndexInput.svelte +1 -1
- package/dist/api/optimade.js +32 -26
- package/dist/app.css +0 -3
- package/dist/brillouin/BrillouinZone.svelte +76 -148
- package/dist/brillouin/BrillouinZone.svelte.d.ts +6 -14
- package/dist/brillouin/BrillouinZoneExportPane.svelte +43 -96
- package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +1 -1
- package/dist/brillouin/BrillouinZoneInfoPane.svelte +9 -32
- package/dist/brillouin/BrillouinZoneInfoPane.svelte.d.ts +2 -3
- package/dist/brillouin/BrillouinZoneScene.svelte +97 -205
- package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +4 -23
- package/dist/brillouin/BrillouinZoneTooltip.svelte +16 -25
- package/dist/brillouin/ReciprocalVectors.svelte +39 -0
- package/dist/brillouin/ReciprocalVectors.svelte.d.ts +9 -0
- package/dist/brillouin/compute.d.ts +2 -0
- package/dist/brillouin/compute.js +89 -90
- package/dist/brillouin/geometry.d.ts +8 -0
- package/dist/brillouin/geometry.js +57 -0
- package/dist/brillouin/index.d.ts +2 -0
- package/dist/brillouin/index.js +2 -0
- package/dist/brillouin/types.d.ts +2 -2
- package/dist/chempot-diagram/ChemPotDiagram.svelte +14 -13
- package/dist/chempot-diagram/ChemPotDiagram.svelte.d.ts +1 -1
- package/dist/chempot-diagram/ChemPotDiagram2D.svelte +109 -203
- package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +4 -1
- package/dist/chempot-diagram/ChemPotDiagram3D.svelte +180 -470
- package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +7 -1
- package/dist/chempot-diagram/async-compute.svelte.js +3 -1
- package/dist/chempot-diagram/chempot-worker.js +2 -1
- package/dist/chempot-diagram/color.d.ts +3 -6
- package/dist/chempot-diagram/color.js +5 -5
- package/dist/chempot-diagram/compute.d.ts +4 -4
- package/dist/chempot-diagram/compute.js +20 -20
- package/dist/chempot-diagram/controls-state.svelte.d.ts +10 -0
- package/dist/chempot-diagram/controls-state.svelte.js +42 -0
- package/dist/chempot-diagram/export.d.ts +47 -0
- package/dist/chempot-diagram/export.js +133 -0
- package/dist/chempot-diagram/index.d.ts +1 -0
- package/dist/chempot-diagram/index.js +1 -0
- package/dist/chempot-diagram/pointer.d.ts +0 -10
- package/dist/chempot-diagram/pointer.js +4 -4
- package/dist/chempot-diagram/types.d.ts +3 -3
- package/dist/colors/index.js +8 -7
- package/dist/composition/FormulaFilter.svelte +18 -11
- package/dist/composition/PieChart.svelte +11 -10
- package/dist/composition/chem-sys.d.ts +8 -0
- package/dist/composition/chem-sys.js +86 -0
- package/dist/composition/format.js +7 -4
- package/dist/composition/index.d.ts +1 -0
- package/dist/composition/index.js +1 -0
- package/dist/composition/parse.d.ts +0 -1
- package/dist/composition/parse.js +41 -31
- package/dist/controls.d.ts +1 -0
- package/dist/controls.js +0 -1
- package/dist/convex-hull/ConvexHull.svelte +8 -10
- package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -4
- package/dist/convex-hull/ConvexHull2D.svelte +106 -185
- package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull3D.svelte +179 -683
- package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull4D.svelte +183 -687
- package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHullChrome.svelte +268 -0
- package/dist/convex-hull/ConvexHullChrome.svelte.d.ts +30 -0
- package/dist/convex-hull/ConvexHullControls.svelte +88 -7
- package/dist/convex-hull/ConvexHullControls.svelte.d.ts +7 -6
- package/dist/convex-hull/ConvexHullInfoPane.svelte +18 -5
- package/dist/convex-hull/ConvexHullInfoPane.svelte.d.ts +6 -5
- package/dist/convex-hull/ConvexHullStats.svelte +36 -175
- package/dist/convex-hull/ConvexHullStats.svelte.d.ts +3 -1
- package/dist/convex-hull/ConvexHullTooltip.svelte +11 -2
- package/dist/convex-hull/ConvexHullTooltip.svelte.d.ts +2 -1
- package/dist/convex-hull/GasPressureControls.svelte +4 -4
- package/dist/convex-hull/TemperatureSlider.svelte +2 -2
- package/dist/convex-hull/barycentric-coords.d.ts +2 -4
- package/dist/convex-hull/barycentric-coords.js +6 -33
- package/dist/convex-hull/canvas-interactions.svelte.d.ts +79 -0
- package/dist/convex-hull/canvas-interactions.svelte.js +278 -0
- package/dist/convex-hull/demo-temperature.d.ts +1 -1
- package/dist/convex-hull/demo-temperature.js +20 -22
- package/dist/convex-hull/gas-thermodynamics.d.ts +2 -2
- package/dist/convex-hull/gas-thermodynamics.js +22 -30
- package/dist/convex-hull/helpers.d.ts +42 -7
- package/dist/convex-hull/helpers.js +171 -78
- package/dist/convex-hull/hull-state.svelte.d.ts +44 -0
- package/dist/convex-hull/hull-state.svelte.js +124 -0
- package/dist/convex-hull/index.d.ts +10 -8
- package/dist/convex-hull/index.js +7 -2
- package/dist/convex-hull/thermodynamics.js +136 -960
- package/dist/convex-hull/types.d.ts +13 -5
- package/dist/convex-hull/types.js +12 -0
- package/dist/coordination/CoordinationBarPlot.svelte +27 -34
- package/dist/coordination/CoordinationBarPlot.svelte.d.ts +1 -1
- package/dist/element/BohrAtom.svelte +2 -1
- package/dist/element/index.d.ts +4 -0
- package/dist/element/index.js +18 -0
- package/dist/feedback/DragOverlay.svelte +3 -1
- package/dist/feedback/DragOverlay.svelte.d.ts +1 -0
- package/dist/feedback/StatusMessage.svelte +13 -3
- package/dist/fermi-surface/FermiSlice.svelte +13 -5
- package/dist/fermi-surface/FermiSurface.svelte +78 -151
- package/dist/fermi-surface/FermiSurface.svelte.d.ts +5 -14
- package/dist/fermi-surface/FermiSurfaceControls.svelte +1 -1
- package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
- package/dist/fermi-surface/FermiSurfaceScene.svelte +72 -221
- package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +3 -23
- package/dist/fermi-surface/FermiSurfaceTooltip.svelte +8 -34
- package/dist/fermi-surface/compute.js +67 -66
- package/dist/fermi-surface/export.js +6 -16
- package/dist/fermi-surface/index.d.ts +0 -1
- package/dist/fermi-surface/index.js +0 -1
- package/dist/fermi-surface/parse.d.ts +1 -1
- package/dist/fermi-surface/parse.js +71 -79
- package/dist/fermi-surface/types.d.ts +3 -2
- package/dist/heatmap-matrix/HeatmapMatrix.svelte +69 -52
- package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +4 -3
- package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +3 -2
- package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +5 -5
- package/dist/heatmap-matrix/index.d.ts +3 -2
- package/dist/heatmap-matrix/index.js +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/io/ExportPane.svelte +166 -0
- package/dist/io/ExportPane.svelte.d.ts +17 -0
- package/dist/io/decompress.js +5 -4
- package/dist/io/export.d.ts +9 -5
- package/dist/io/export.js +77 -51
- package/dist/io/fetch.d.ts +2 -1
- package/dist/io/fetch.js +5 -1
- package/dist/io/file-drop.d.ts +8 -1
- package/dist/io/file-drop.js +48 -36
- package/dist/io/index.d.ts +2 -0
- package/dist/io/index.js +10 -0
- package/dist/io/types.d.ts +13 -0
- package/dist/io/url-drop.js +64 -33
- package/dist/isosurface/parse.js +52 -51
- package/dist/isosurface/slice.js +5 -4
- package/dist/isosurface/types.js +1 -1
- package/dist/keyboard.d.ts +3 -0
- package/dist/keyboard.js +23 -0
- package/dist/labels.d.ts +1 -1
- package/dist/labels.js +9 -8
- package/dist/layout/FullscreenButton.svelte +33 -0
- package/dist/layout/FullscreenButton.svelte.d.ts +10 -0
- package/dist/layout/FullscreenToggle.svelte +8 -14
- package/dist/layout/PropertyFilter.svelte +3 -2
- package/dist/layout/SettingsSection.svelte +1 -1
- package/dist/layout/ViewerChrome.svelte +116 -0
- package/dist/layout/ViewerChrome.svelte.d.ts +17 -0
- package/dist/layout/fullscreen.d.ts +4 -0
- package/dist/layout/fullscreen.svelte.d.ts +8 -0
- package/dist/layout/fullscreen.svelte.js +37 -0
- package/dist/layout/index.d.ts +3 -0
- package/dist/layout/index.js +3 -0
- package/dist/layout/json-tree/JsonNode.svelte +1 -1
- package/dist/layout/json-tree/JsonTree.svelte +2 -2
- package/dist/layout/json-tree/utils.js +5 -4
- package/dist/marching-cubes.js +8 -13
- package/dist/math.d.ts +12 -4
- package/dist/math.js +42 -30
- package/dist/overlays/DraggablePane.svelte +4 -4
- package/dist/overlays/index.d.ts +4 -0
- package/dist/periodic-table/PeriodicTable.svelte +27 -15
- package/dist/periodic-table/PropertySelect.svelte +1 -0
- package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +9 -3
- package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +1 -1
- package/dist/phase-diagram/PhaseDiagramControls.svelte +3 -2
- package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +4 -3
- package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +4 -2
- package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +2 -3
- package/dist/phase-diagram/PhaseDiagramExportPane.svelte +47 -132
- package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +3 -4
- package/dist/phase-diagram/PhaseDiagramTooltip.svelte +1 -1
- package/dist/phase-diagram/build-diagram.js +2 -2
- package/dist/phase-diagram/colors.js +1 -1
- package/dist/phase-diagram/parse.d.ts +2 -1
- package/dist/phase-diagram/parse.js +6 -5
- package/dist/phase-diagram/types.d.ts +1 -1
- package/dist/phase-diagram/utils.d.ts +3 -3
- package/dist/phase-diagram/utils.js +8 -12
- package/dist/plot/{BarPlot.svelte → bar/BarPlot.svelte} +246 -841
- package/dist/plot/{BarPlot.svelte.d.ts → bar/BarPlot.svelte.d.ts} +8 -16
- package/dist/plot/{BarPlotControls.svelte → bar/BarPlotControls.svelte} +6 -5
- package/dist/plot/{BarPlotControls.svelte.d.ts → bar/BarPlotControls.svelte.d.ts} +3 -3
- package/dist/plot/{SpacegroupBarPlot.svelte → bar/SpacegroupBarPlot.svelte} +8 -7
- package/dist/plot/{SpacegroupBarPlot.svelte.d.ts → bar/SpacegroupBarPlot.svelte.d.ts} +1 -1
- package/dist/plot/bar/data.d.ts +40 -0
- package/dist/plot/bar/data.js +154 -0
- package/dist/plot/bar/geometry.d.ts +39 -0
- package/dist/plot/bar/geometry.js +60 -0
- package/dist/plot/bar/index.d.ts +3 -0
- package/dist/plot/bar/index.js +3 -0
- package/dist/plot/box/BoxPlot.svelte +1292 -0
- package/dist/plot/box/BoxPlot.svelte.d.ts +95 -0
- package/dist/plot/box/BoxPlotControls.svelte +109 -0
- package/dist/plot/box/BoxPlotControls.svelte.d.ts +19 -0
- package/dist/plot/box/Violin.svelte +14 -0
- package/dist/plot/box/Violin.svelte.d.ts +70 -0
- package/dist/plot/box/box-plot.d.ts +56 -0
- package/dist/plot/box/box-plot.js +129 -0
- package/dist/plot/box/index.d.ts +5 -0
- package/dist/plot/box/index.js +5 -0
- package/dist/plot/box/kde.d.ts +17 -0
- package/dist/plot/box/kde.js +160 -0
- package/dist/plot/box/quantile.d.ts +3 -0
- package/dist/plot/box/quantile.js +53 -0
- package/dist/plot/{auto-place.d.ts → core/auto-place.d.ts} +1 -1
- package/dist/plot/{auto-place.js → core/auto-place.js} +6 -3
- package/dist/plot/core/axis-utils.d.ts +46 -0
- package/dist/plot/core/axis-utils.js +110 -0
- package/dist/plot/{AxisLabel.svelte → core/components/AxisLabel.svelte} +2 -2
- package/dist/plot/{AxisLabel.svelte.d.ts → core/components/AxisLabel.svelte.d.ts} +1 -1
- package/dist/plot/{ColorBar.svelte → core/components/ColorBar.svelte} +41 -38
- package/dist/plot/{ColorBar.svelte.d.ts → core/components/ColorBar.svelte.d.ts} +7 -6
- package/dist/plot/{ColorScaleSelect.svelte → core/components/ColorScaleSelect.svelte} +4 -3
- package/dist/plot/{ColorScaleSelect.svelte.d.ts → core/components/ColorScaleSelect.svelte.d.ts} +2 -2
- package/dist/plot/core/components/ControlPane.svelte +46 -0
- package/dist/plot/core/components/ControlPane.svelte.d.ts +13 -0
- package/dist/plot/{FillArea.svelte → core/components/FillArea.svelte} +17 -6
- package/dist/plot/{FillArea.svelte.d.ts → core/components/FillArea.svelte.d.ts} +1 -1
- package/dist/plot/{InteractiveAxisLabel.svelte → core/components/InteractiveAxisLabel.svelte} +3 -3
- package/dist/plot/{InteractiveAxisLabel.svelte.d.ts → core/components/InteractiveAxisLabel.svelte.d.ts} +2 -2
- package/dist/plot/{Line.svelte → core/components/Line.svelte} +33 -15
- package/dist/plot/{Line.svelte.d.ts → core/components/Line.svelte.d.ts} +3 -2
- package/dist/plot/{PlotAxis.svelte → core/components/PlotAxis.svelte} +9 -6
- package/dist/plot/{PlotAxis.svelte.d.ts → core/components/PlotAxis.svelte.d.ts} +5 -3
- package/dist/plot/{PlotControls.svelte → core/components/PlotControls.svelte} +17 -29
- package/dist/plot/core/components/PlotControls.svelte.d.ts +4 -0
- package/dist/plot/{PlotLegend.svelte → core/components/PlotLegend.svelte} +21 -10
- package/dist/plot/{PlotLegend.svelte.d.ts → core/components/PlotLegend.svelte.d.ts} +3 -2
- package/dist/plot/{PlotTooltip.svelte → core/components/PlotTooltip.svelte} +17 -1
- package/dist/plot/{PlotTooltip.svelte.d.ts → core/components/PlotTooltip.svelte.d.ts} +8 -0
- package/dist/plot/{PortalSelect.svelte → core/components/PortalSelect.svelte} +11 -7
- package/dist/plot/{ReferenceLine.svelte → core/components/ReferenceLine.svelte} +3 -3
- package/dist/plot/{ReferenceLine.svelte.d.ts → core/components/ReferenceLine.svelte.d.ts} +1 -1
- package/dist/plot/{ReferenceLine3D.svelte → core/components/ReferenceLine3D.svelte} +5 -5
- package/dist/plot/{ReferenceLine3D.svelte.d.ts → core/components/ReferenceLine3D.svelte.d.ts} +5 -5
- package/dist/plot/{ReferencePlane.svelte → core/components/ReferencePlane.svelte} +8 -8
- package/dist/plot/{ReferencePlane.svelte.d.ts → core/components/ReferencePlane.svelte.d.ts} +5 -5
- package/dist/plot/{ZeroLines.svelte → core/components/ZeroLines.svelte} +3 -3
- package/dist/plot/{ZeroLines.svelte.d.ts → core/components/ZeroLines.svelte.d.ts} +3 -3
- package/dist/plot/{ZoomRect.svelte → core/components/ZoomRect.svelte} +1 -1
- package/dist/plot/{ZoomRect.svelte.d.ts → core/components/ZoomRect.svelte.d.ts} +1 -1
- package/dist/plot/core/components/index.d.ts +17 -0
- package/dist/plot/core/components/index.js +17 -0
- package/dist/plot/{data-cleaning.d.ts → core/data-cleaning.d.ts} +71 -1
- package/dist/plot/{data-cleaning.js → core/data-cleaning.js} +21 -23
- package/dist/plot/{data-transform.d.ts → core/data-transform.d.ts} +2 -2
- package/dist/plot/{data-transform.js → core/data-transform.js} +3 -3
- package/dist/plot/core/fill-utils.d.ts +34 -0
- package/dist/plot/core/fill-utils.js +391 -0
- package/dist/plot/core/index.d.ts +10 -0
- package/dist/plot/core/index.js +11 -0
- package/dist/plot/core/interactions.d.ts +39 -0
- package/dist/plot/core/interactions.js +209 -0
- package/dist/plot/{layout.d.ts → core/layout.d.ts} +1 -0
- package/dist/plot/{layout.js → core/layout.js} +16 -8
- package/dist/plot/core/pan-zoom.svelte.d.ts +35 -0
- package/dist/plot/core/pan-zoom.svelte.js +221 -0
- package/dist/plot/core/placed-tween.svelte.d.ts +21 -0
- package/dist/plot/core/placed-tween.svelte.js +68 -0
- package/dist/plot/{reference-line.d.ts → core/reference-line.d.ts} +11 -11
- package/dist/plot/{reference-line.js → core/reference-line.js} +29 -42
- package/dist/plot/core/scales.d.ts +40 -0
- package/dist/plot/{scales.js → core/scales.js} +94 -93
- package/dist/plot/core/svg.d.ts +3 -0
- package/dist/plot/core/svg.js +41 -0
- package/dist/plot/{types.d.ts → core/types.d.ts} +36 -85
- package/dist/plot/{types.js → core/types.js} +1 -1
- package/dist/plot/{utils → core/utils}/label-placement.d.ts +3 -3
- package/dist/plot/{utils → core/utils}/label-placement.js +3 -3
- package/dist/plot/core/utils/series-visibility.d.ts +26 -0
- package/dist/plot/{utils → core/utils}/series-visibility.js +29 -2
- package/dist/plot/core/utils.d.ts +12 -0
- package/dist/plot/core/utils.js +27 -0
- package/dist/plot/{Histogram.svelte → histogram/Histogram.svelte} +174 -551
- package/dist/plot/{Histogram.svelte.d.ts → histogram/Histogram.svelte.d.ts} +2 -2
- package/dist/plot/{HistogramControls.svelte → histogram/HistogramControls.svelte} +6 -6
- package/dist/plot/{HistogramControls.svelte.d.ts → histogram/HistogramControls.svelte.d.ts} +4 -4
- package/dist/plot/histogram/index.d.ts +2 -0
- package/dist/plot/histogram/index.js +2 -0
- package/dist/plot/index.d.ts +8 -41
- package/dist/plot/index.js +10 -39
- package/dist/plot/sankey/Sankey.svelte +697 -0
- package/dist/plot/sankey/Sankey.svelte.d.ts +74 -0
- package/dist/plot/sankey/SankeyControls.svelte +98 -0
- package/dist/plot/sankey/SankeyControls.svelte.d.ts +19 -0
- package/dist/plot/sankey/index.d.ts +4 -0
- package/dist/plot/sankey/index.js +3 -0
- package/dist/plot/sankey/sankey-types.d.ts +42 -0
- package/dist/plot/sankey/sankey-types.js +4 -0
- package/dist/plot/sankey/sankey.d.ts +52 -0
- package/dist/plot/sankey/sankey.js +189 -0
- package/dist/plot/{BinnedScatterPlot.svelte → scatter/BinnedScatterPlot.svelte} +64 -64
- package/dist/plot/{BinnedScatterPlot.svelte.d.ts → scatter/BinnedScatterPlot.svelte.d.ts} +6 -6
- package/dist/plot/{ElementScatter.svelte → scatter/ElementScatter.svelte} +6 -6
- package/dist/plot/{ElementScatter.svelte.d.ts → scatter/ElementScatter.svelte.d.ts} +2 -2
- package/dist/plot/{ScatterPlot.svelte → scatter/ScatterPlot.svelte} +297 -1008
- package/dist/plot/{ScatterPlot.svelte.d.ts → scatter/ScatterPlot.svelte.d.ts} +10 -18
- package/dist/plot/{ScatterPlotControls.svelte → scatter/ScatterPlotControls.svelte} +6 -5
- package/dist/plot/{ScatterPlotControls.svelte.d.ts → scatter/ScatterPlotControls.svelte.d.ts} +2 -2
- package/dist/plot/{ScatterPoint.svelte → scatter/ScatterPoint.svelte} +7 -7
- package/dist/plot/{ScatterPoint.svelte.d.ts → scatter/ScatterPoint.svelte.d.ts} +3 -3
- package/dist/plot/{adaptive-density.d.ts → scatter/adaptive-density.d.ts} +14 -4
- package/dist/plot/{adaptive-density.js → scatter/adaptive-density.js} +46 -20
- package/dist/plot/{binned-scatter-types.d.ts → scatter/binned-scatter-types.d.ts} +5 -12
- package/dist/plot/scatter/index.d.ts +7 -0
- package/dist/plot/scatter/index.js +5 -0
- package/dist/plot/scatter/scatter-data.d.ts +19 -0
- package/dist/plot/scatter/scatter-data.js +212 -0
- package/dist/plot/{ScatterPlot3D.svelte → scatter-3d/ScatterPlot3D.svelte} +25 -34
- package/dist/plot/{ScatterPlot3D.svelte.d.ts → scatter-3d/ScatterPlot3D.svelte.d.ts} +9 -17
- package/dist/plot/{ScatterPlot3DControls.svelte → scatter-3d/ScatterPlot3DControls.svelte} +14 -14
- package/dist/plot/{ScatterPlot3DControls.svelte.d.ts → scatter-3d/ScatterPlot3DControls.svelte.d.ts} +6 -6
- package/dist/plot/{ScatterPlot3DScene.svelte → scatter-3d/ScatterPlot3DScene.svelte} +129 -128
- package/dist/plot/{ScatterPlot3DScene.svelte.d.ts → scatter-3d/ScatterPlot3DScene.svelte.d.ts} +6 -15
- package/dist/plot/{Surface3D.svelte → scatter-3d/Surface3D.svelte} +7 -6
- package/dist/plot/{Surface3D.svelte.d.ts → scatter-3d/Surface3D.svelte.d.ts} +5 -4
- package/dist/plot/scatter-3d/index.d.ts +4 -0
- package/dist/plot/scatter-3d/index.js +4 -0
- package/dist/plot/sunburst/Sunburst.svelte +1041 -0
- package/dist/plot/sunburst/Sunburst.svelte.d.ts +97 -0
- package/dist/plot/sunburst/SunburstControls.svelte +200 -0
- package/dist/plot/sunburst/SunburstControls.svelte.d.ts +26 -0
- package/dist/plot/sunburst/index.d.ts +4 -0
- package/dist/plot/sunburst/index.js +4 -0
- package/dist/plot/sunburst/render.d.ts +34 -0
- package/dist/plot/sunburst/render.js +122 -0
- package/dist/plot/sunburst/sunburst.d.ts +62 -0
- package/dist/plot/sunburst/sunburst.js +269 -0
- package/dist/rdf/RdfPlot.svelte +2 -1
- package/dist/rdf/RdfPlot.svelte.d.ts +1 -1
- package/dist/rdf/calc-rdf.js +11 -24
- package/dist/sanitize.js +14 -3
- package/dist/scene/SceneCamera.svelte +62 -0
- package/dist/scene/SceneCamera.svelte.d.ts +19 -0
- package/dist/scene/bind-renderer.svelte.d.ts +2 -0
- package/dist/scene/bind-renderer.svelte.js +14 -0
- package/dist/scene/index.d.ts +4 -0
- package/dist/scene/index.js +5 -0
- package/dist/scene/props.js +52 -0
- package/dist/scene/types.d.ts +26 -0
- package/dist/scene/types.js +1 -0
- package/dist/settings.d.ts +79 -3
- package/dist/settings.js +321 -1
- package/dist/spectral/Bands.svelte +47 -36
- package/dist/spectral/Bands.svelte.d.ts +6 -6
- package/dist/spectral/BandsAndDos.svelte +23 -25
- package/dist/spectral/BrillouinBandsDos.svelte +42 -30
- package/dist/spectral/Dos.svelte +15 -23
- package/dist/spectral/Dos.svelte.d.ts +4 -3
- package/dist/spectral/helpers.d.ts +8 -6
- package/dist/spectral/helpers.js +137 -65
- package/dist/state.svelte.d.ts +0 -7
- package/dist/state.svelte.js +0 -6
- package/dist/structure/Arrow.svelte +2 -4
- package/dist/structure/AtomLegend.svelte +8 -9
- package/dist/structure/AtomLegend.svelte.d.ts +1 -1
- package/dist/structure/CanvasTooltip.svelte +1 -0
- package/dist/structure/CellSelect.svelte +12 -5
- package/dist/structure/CellSelect.svelte.d.ts +2 -1
- package/dist/structure/Cylinder.svelte +12 -8
- package/dist/structure/Cylinder.svelte.d.ts +4 -1
- package/dist/structure/Lattice.svelte +2 -2
- package/dist/structure/Structure.svelte +365 -423
- package/dist/structure/Structure.svelte.d.ts +5 -15
- package/dist/structure/StructureControls.svelte +217 -2
- package/dist/structure/StructureControls.svelte.d.ts +5 -3
- package/dist/structure/StructureExportPane.svelte +54 -156
- package/dist/structure/StructureExportPane.svelte.d.ts +4 -5
- package/dist/structure/StructureInfoPane.svelte +10 -9
- package/dist/structure/StructureInfoPane.svelte.d.ts +5 -5
- package/dist/structure/StructureScene.svelte +376 -208
- package/dist/structure/StructureScene.svelte.d.ts +22 -20
- package/dist/structure/{label-placement.d.ts → atom-label-placement.d.ts} +3 -3
- package/dist/structure/{label-placement.js → atom-label-placement.js} +15 -5
- package/dist/structure/atom-properties.d.ts +1 -1
- package/dist/structure/atom-properties.js +17 -22
- package/dist/structure/bond-order-perception.js +3 -5
- package/dist/structure/bonding.d.ts +4 -0
- package/dist/structure/bonding.js +134 -63
- package/dist/structure/export.d.ts +24 -4
- package/dist/structure/export.js +89 -143
- package/dist/structure/index.d.ts +4 -4
- package/dist/structure/index.js +3 -3
- package/dist/structure/measure.d.ts +3 -2
- package/dist/structure/measure.js +6 -5
- package/dist/structure/parse.d.ts +3 -2
- package/dist/structure/parse.js +419 -438
- package/dist/structure/partial-occupancy.d.ts +0 -1
- package/dist/structure/partial-occupancy.js +1 -1
- package/dist/structure/pbc.d.ts +1 -1
- package/dist/structure/pbc.js +190 -13
- package/dist/structure/polyhedra.d.ts +41 -0
- package/dist/structure/polyhedra.js +602 -0
- package/dist/structure/site.d.ts +4 -0
- package/dist/structure/site.js +1 -0
- package/dist/structure/supercell.js +3 -2
- package/dist/structure/validation.js +5 -6
- package/dist/symmetry/SymmetryElementControls.svelte +69 -0
- package/dist/symmetry/SymmetryElementControls.svelte.d.ts +9 -0
- package/dist/symmetry/SymmetryElements.svelte +354 -0
- package/dist/symmetry/SymmetryElements.svelte.d.ts +24 -0
- package/dist/symmetry/SymmetryStats.svelte +113 -8
- package/dist/symmetry/WyckoffTable.svelte +68 -7
- package/dist/symmetry/WyckoffTable.svelte.d.ts +3 -0
- package/dist/symmetry/cell-transform.js +7 -14
- package/dist/symmetry/index.d.ts +14 -4
- package/dist/symmetry/index.js +291 -72
- package/dist/symmetry/spacegroups.d.ts +12 -1
- package/dist/symmetry/spacegroups.js +63 -14
- package/dist/symmetry/symmetry-elements.d.ts +33 -0
- package/dist/symmetry/symmetry-elements.js +521 -0
- package/dist/symmetry/wyckoff-db.d.ts +9 -0
- package/dist/symmetry/wyckoff-db.js +87 -0
- package/dist/table/HeatmapTable.svelte +66 -25
- package/dist/table/HeatmapTable.svelte.d.ts +1 -1
- package/dist/table/index.d.ts +1 -3
- package/dist/table/index.js +1 -1
- package/dist/theme/index.js +8 -8
- package/dist/tooltip/KCoords.svelte +45 -0
- package/dist/tooltip/KCoords.svelte.d.ts +8 -0
- package/dist/tooltip/index.d.ts +1 -0
- package/dist/tooltip/index.js +1 -0
- package/dist/trajectory/Trajectory.svelte +123 -100
- package/dist/trajectory/Trajectory.svelte.d.ts +11 -22
- package/dist/trajectory/TrajectoryExportPane.svelte +17 -25
- package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +4 -5
- package/dist/trajectory/TrajectoryInfoPane.svelte +5 -3
- package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +3 -2
- package/dist/trajectory/constants.js +6 -2
- package/dist/trajectory/extract.js +17 -37
- package/dist/trajectory/format-detect.d.ts +1 -1
- package/dist/trajectory/format-detect.js +27 -19
- package/dist/trajectory/frame-reader.d.ts +0 -1
- package/dist/trajectory/frame-reader.js +63 -162
- package/dist/trajectory/helpers.d.ts +10 -2
- package/dist/trajectory/helpers.js +56 -36
- package/dist/trajectory/index.js +1 -1
- package/dist/trajectory/parse/ase.d.ts +9 -1
- package/dist/trajectory/parse/ase.js +47 -32
- package/dist/trajectory/parse/diagnostics.d.ts +3 -0
- package/dist/trajectory/parse/diagnostics.js +14 -0
- package/dist/trajectory/parse/hdf5.js +1 -1
- package/dist/trajectory/parse/index.d.ts +1 -1
- package/dist/trajectory/parse/index.js +65 -105
- package/dist/trajectory/parse/lammps.d.ts +0 -2
- package/dist/trajectory/parse/lammps.js +8 -6
- package/dist/trajectory/parse/pymatgen.d.ts +2 -0
- package/dist/trajectory/parse/pymatgen.js +74 -0
- package/dist/trajectory/parse/vasp.js +38 -18
- package/dist/trajectory/parse/xyz.d.ts +13 -1
- package/dist/trajectory/parse/xyz.js +102 -94
- package/dist/trajectory/plotting.d.ts +1 -2
- package/dist/trajectory/plotting.js +16 -113
- package/dist/utils.d.ts +2 -0
- package/dist/utils.js +7 -5
- package/dist/xrd/XrdPlot.svelte +16 -30
- package/dist/xrd/broadening.d.ts +2 -1
- package/dist/xrd/calc-xrd.js +18 -20
- package/dist/xrd/index.d.ts +2 -2
- package/dist/xrd/parse.js +2 -2
- package/package.json +43 -26
- package/dist/element/data.json +0 -11864
- package/dist/fermi-surface/marching-cubes.d.ts +0 -2
- package/dist/fermi-surface/marching-cubes.js +0 -2
- package/dist/plot/PlotControls.svelte.d.ts +0 -4
- package/dist/plot/axis-utils.d.ts +0 -19
- package/dist/plot/axis-utils.js +0 -78
- package/dist/plot/defaults.d.ts +0 -19
- package/dist/plot/defaults.js +0 -9
- package/dist/plot/fill-utils.d.ts +0 -46
- package/dist/plot/fill-utils.js +0 -322
- package/dist/plot/hover-lock.svelte.d.ts +0 -14
- package/dist/plot/hover-lock.svelte.js +0 -46
- package/dist/plot/interactions.d.ts +0 -12
- package/dist/plot/interactions.js +0 -101
- package/dist/plot/scales.d.ts +0 -48
- package/dist/plot/svg.d.ts +0 -1
- package/dist/plot/svg.js +0 -11
- package/dist/plot/utils/series-visibility.d.ts +0 -15
- package/dist/plot/utils.d.ts +0 -1
- package/dist/plot/utils.js +0 -14
- /package/dist/plot/{PortalSelect.svelte.d.ts → core/components/PortalSelect.svelte.d.ts} +0 -0
- /package/dist/plot/{binned-scatter-types.js → scatter/binned-scatter-types.js} +0 -0
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
// Shared utilities for trajectory parsing
|
|
2
2
|
import { ATOMIC_NUMBER_TO_SYMBOL } from '../composition/parse';
|
|
3
|
-
import {
|
|
3
|
+
import { is_elem_symbol } from '../element';
|
|
4
4
|
import * as math from '../math';
|
|
5
|
-
|
|
5
|
+
import { make_site } from '../structure/site';
|
|
6
6
|
const is_valid_row = (row) => {
|
|
7
7
|
if (!(Array.isArray(row) || (ArrayBuffer.isView(row) && `length` in row)))
|
|
8
8
|
return false;
|
|
9
9
|
return math.is_finite_vec3_like(row);
|
|
10
10
|
};
|
|
11
11
|
const is_valid_vec3 = (coords) => Array.isArray(coords) && math.is_finite_vec3_like(coords);
|
|
12
|
-
export const is_valid_element_symbol = (symbol) => element_symbol_set.has(symbol);
|
|
13
|
-
export const coerce_element_symbol = (symbol) => is_valid_element_symbol(symbol) ? symbol : undefined;
|
|
14
12
|
// Validate that data is a proper 3x3 matrix
|
|
15
13
|
// Accepts both regular arrays and typed arrays (Float32Array, Float64Array, etc.)
|
|
16
14
|
export function validate_3x3_matrix(data) {
|
|
@@ -24,7 +22,7 @@ export function validate_3x3_matrix(data) {
|
|
|
24
22
|
}
|
|
25
23
|
export const convert_atomic_numbers = (numbers) => numbers.map((num) => {
|
|
26
24
|
const symbol = ATOMIC_NUMBER_TO_SYMBOL[num];
|
|
27
|
-
if (!symbol || !
|
|
25
|
+
if (!symbol || !is_elem_symbol(symbol)) {
|
|
28
26
|
throw new Error(`Unknown atomic number in trajectory data: ${num}`);
|
|
29
27
|
}
|
|
30
28
|
return symbol;
|
|
@@ -42,13 +40,7 @@ export const create_structure = (positions, elements, lattice_matrix, pbc, force
|
|
|
42
40
|
const abc = cart_to_frac ? cart_to_frac(xyz) : [0, 0, 0];
|
|
43
41
|
const force = force_data?.[idx];
|
|
44
42
|
const properties = is_valid_vec3(force) ? { force } : {};
|
|
45
|
-
return {
|
|
46
|
-
species: [{ element: elements[idx], occu: 1, oxidation_state: 0 }],
|
|
47
|
-
abc,
|
|
48
|
-
xyz,
|
|
49
|
-
label: `${elements[idx]}${idx + 1}`,
|
|
50
|
-
properties,
|
|
51
|
-
};
|
|
43
|
+
return make_site(elements[idx], abc, xyz, `${elements[idx]}${idx + 1}`, properties);
|
|
52
44
|
});
|
|
53
45
|
return lattice_matrix
|
|
54
46
|
? {
|
|
@@ -126,39 +118,67 @@ export const read_ndarray_from_view = (view, ref) => {
|
|
|
126
118
|
throw new Error(`Unsupported shape`);
|
|
127
119
|
})();
|
|
128
120
|
};
|
|
129
|
-
//
|
|
130
|
-
export
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
121
|
+
// Copy listed fields from source to target when they hold numbers
|
|
122
|
+
export const copy_numeric_fields = (target, source, fields) => {
|
|
123
|
+
for (const field of fields) {
|
|
124
|
+
if (field in source && typeof source[field] === `number`)
|
|
125
|
+
target[field] = source[field];
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
// Max and RMS of per-atom force magnitudes, or null when no forces present. Loop-based
|
|
129
|
+
// rather than Math.max(...spread) to avoid call-stack overflow on very large frames.
|
|
130
|
+
export function calc_force_stats(forces) {
|
|
131
|
+
if (forces.length === 0)
|
|
132
|
+
return null;
|
|
133
|
+
let force_max = -Infinity;
|
|
134
|
+
let sum_sq = 0;
|
|
135
|
+
for (const force of forces) {
|
|
136
|
+
const magnitude = Math.hypot(...force);
|
|
137
|
+
if (magnitude > force_max)
|
|
138
|
+
force_max = magnitude;
|
|
139
|
+
sum_sq += magnitude ** 2;
|
|
140
|
+
}
|
|
141
|
+
return { force_max, force_norm: Math.sqrt(sum_sq / forces.length) };
|
|
142
|
+
}
|
|
143
|
+
// Walk concatenated (ext)XYZ frames in `lines`, yielding each frame's atom-count line
|
|
144
|
+
// index, parsed atom count, and comment line. A candidate frame is accepted only when its
|
|
145
|
+
// first few atom lines look like "<element> <x> <y> <z>"; otherwise we advance one line and
|
|
146
|
+
// rescan. That validation doubles as content sniffing so numeric-leading non-XYZ formats
|
|
147
|
+
// (e.g. VASP XDATCAR) aren't misread as frames, and keeps count_xyz_frames consistent with
|
|
148
|
+
// the actual parse/index walk (both go through this single source of truth).
|
|
149
|
+
export function* iter_xyz_frames(lines) {
|
|
135
150
|
let line_idx = 0;
|
|
136
151
|
while (line_idx < lines.length) {
|
|
137
|
-
|
|
138
|
-
line_idx++;
|
|
139
|
-
continue;
|
|
140
|
-
}
|
|
141
|
-
const num_atoms = parseInt(lines[line_idx].trim(), 10);
|
|
152
|
+
const num_atoms = parseInt(lines[line_idx]?.trim(), 10);
|
|
142
153
|
if (isNaN(num_atoms) || num_atoms <= 0 || line_idx + num_atoms + 2 > lines.length) {
|
|
143
|
-
line_idx++;
|
|
154
|
+
line_idx++; // skip blank/invalid lines until the next frame's atom-count line
|
|
144
155
|
continue;
|
|
145
156
|
}
|
|
146
|
-
// Quick validation of first few atom lines
|
|
147
157
|
let valid_coords = 0;
|
|
148
|
-
|
|
158
|
+
const sample = Math.min(num_atoms, 3);
|
|
159
|
+
for (let idx = 0; idx < sample; idx++) {
|
|
149
160
|
const parts = lines[line_idx + 2 + idx]?.trim().split(/\s+/);
|
|
150
|
-
if (parts?.length >= 4 &&
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
if (valid_coords >= Math.min(num_atoms, 3)) {
|
|
156
|
-
frame_count++;
|
|
157
|
-
line_idx += 2 + num_atoms;
|
|
161
|
+
if (parts?.length >= 4 &&
|
|
162
|
+
isNaN(parseInt(parts[0], 10)) &&
|
|
163
|
+
parts[0].length <= 3 &&
|
|
164
|
+
parts.slice(1, 4).every((coord) => !isNaN(parseFloat(coord))))
|
|
165
|
+
valid_coords++;
|
|
158
166
|
}
|
|
159
|
-
|
|
160
|
-
line_idx++;
|
|
167
|
+
if (valid_coords < sample) {
|
|
168
|
+
line_idx++; // count line looks valid but atom lines don't — likely non-XYZ content
|
|
169
|
+
continue;
|
|
161
170
|
}
|
|
171
|
+
yield { start: line_idx, num_atoms, comment: lines[line_idx + 1] || `` };
|
|
172
|
+
line_idx += num_atoms + 2;
|
|
162
173
|
}
|
|
174
|
+
}
|
|
175
|
+
// Count XYZ frames via iter_xyz_frames so total_frames matches what gets indexed/loaded
|
|
176
|
+
export function count_xyz_frames(data) {
|
|
177
|
+
if (!data || typeof data !== `string`)
|
|
178
|
+
return 0;
|
|
179
|
+
const frames = iter_xyz_frames(data.trim().split(/\r?\n/));
|
|
180
|
+
let frame_count = 0;
|
|
181
|
+
while (!frames.next().done)
|
|
182
|
+
frame_count += 1;
|
|
163
183
|
return frame_count;
|
|
164
184
|
}
|
package/dist/trajectory/index.js
CHANGED
|
@@ -77,7 +77,7 @@ export function validate_trajectory(trajectory) {
|
|
|
77
77
|
}
|
|
78
78
|
export function get_trajectory_stats(trajectory) {
|
|
79
79
|
const { frames, total_frames, indexed_frames, plot_metadata } = trajectory;
|
|
80
|
-
const frame_count = total_frames
|
|
80
|
+
const frame_count = total_frames ?? frames.length;
|
|
81
81
|
const stats = {
|
|
82
82
|
frame_count,
|
|
83
83
|
is_indexed: trajectory.is_indexed ?? false,
|
|
@@ -1,2 +1,10 @@
|
|
|
1
|
-
import type { TrajectoryType } from '../index';
|
|
1
|
+
import type { TrajectoryFrame, TrajectoryType } from '../index';
|
|
2
|
+
export declare const read_ase_header: (view: DataView) => {
|
|
3
|
+
n_items: number;
|
|
4
|
+
offsets_pos: number;
|
|
5
|
+
};
|
|
6
|
+
export declare function decode_ase_frame(view: DataView, buffer: ArrayBuffer, frame_offset: number, step: number, fallback_numbers?: number[], max_json_length?: number): {
|
|
7
|
+
frame: TrajectoryFrame;
|
|
8
|
+
numbers: number[];
|
|
9
|
+
};
|
|
2
10
|
export declare function parse_ase_trajectory(buffer: ArrayBuffer, filename?: string): TrajectoryType;
|
|
@@ -1,18 +1,55 @@
|
|
|
1
1
|
// ASE trajectory (.traj) parsing - binary format
|
|
2
|
+
import * as math from '../../math';
|
|
2
3
|
import { MAX_SAFE_STRING_LENGTH } from '../constants';
|
|
3
4
|
import { convert_atomic_numbers, create_trajectory_frame, read_ndarray_from_view, validate_3x3_matrix, } from '../helpers';
|
|
5
|
+
// ULM header: frame count lives at byte 32, frame-offsets table position at byte 40
|
|
6
|
+
export const read_ase_header = (view) => ({
|
|
7
|
+
n_items: Number(view.getBigInt64(32, true)),
|
|
8
|
+
offsets_pos: Number(view.getBigInt64(40, true)),
|
|
9
|
+
});
|
|
10
|
+
// Decode a single ASE/ULM frame (JSON header + optional ndarray payloads) into a
|
|
11
|
+
// TrajectoryFrame. Returns the atomic numbers actually used so callers can cache them
|
|
12
|
+
// as fallback for later frames that omit `numbers` (ASE stores them only once).
|
|
13
|
+
export function decode_ase_frame(view, buffer, frame_offset, step, fallback_numbers, max_json_length) {
|
|
14
|
+
const json_length = Number(view.getBigInt64(frame_offset, true));
|
|
15
|
+
if (max_json_length !== undefined && json_length > max_json_length) {
|
|
16
|
+
throw new Error(`frame JSON too large: ${json_length} bytes`);
|
|
17
|
+
}
|
|
18
|
+
const frame_data = JSON.parse(new TextDecoder().decode(new Uint8Array(buffer, frame_offset + 8, json_length)));
|
|
19
|
+
const positions_ref = frame_data[`positions.`] ?? frame_data.positions;
|
|
20
|
+
const positions = positions_ref?.ndarray
|
|
21
|
+
? read_ndarray_from_view(view, positions_ref)
|
|
22
|
+
: positions_ref;
|
|
23
|
+
const numbers_ref = frame_data[`numbers.`] ?? frame_data.numbers ?? fallback_numbers;
|
|
24
|
+
const numbers = numbers_ref?.ndarray
|
|
25
|
+
? read_ndarray_from_view(view, numbers_ref).flat()
|
|
26
|
+
: numbers_ref;
|
|
27
|
+
if (!numbers || !positions) {
|
|
28
|
+
throw new Error(`missing ${!numbers ? `numbers` : `positions`}`);
|
|
29
|
+
}
|
|
30
|
+
const cell = frame_data.cell ? validate_3x3_matrix(frame_data.cell) : undefined;
|
|
31
|
+
const metadata = {
|
|
32
|
+
step,
|
|
33
|
+
...frame_data.calculator,
|
|
34
|
+
...frame_data.info,
|
|
35
|
+
};
|
|
36
|
+
if (cell) {
|
|
37
|
+
try {
|
|
38
|
+
metadata.volume = Math.abs(math.det_3x3(cell));
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
console.warn(`Failed to calculate volume for frame ${step}:`, error);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const frame = create_trajectory_frame(positions, convert_atomic_numbers(numbers), cell, frame_data.pbc ?? [true, true, true], step, metadata);
|
|
45
|
+
return { frame, numbers };
|
|
46
|
+
}
|
|
4
47
|
export function parse_ase_trajectory(buffer, filename) {
|
|
5
48
|
const view = new DataView(buffer);
|
|
6
|
-
let offset = 0;
|
|
7
49
|
const signature = new TextDecoder().decode(new Uint8Array(buffer, 0, 8));
|
|
8
50
|
if (signature !== `- of Ulm`)
|
|
9
51
|
throw new Error(`Invalid ASE trajectory`);
|
|
10
|
-
|
|
11
|
-
// Skip ASE/Ulm version field; current parsing logic is version-independent.
|
|
12
|
-
offset += 8;
|
|
13
|
-
const n_items = Number(view.getBigInt64(offset, true));
|
|
14
|
-
offset += 8;
|
|
15
|
-
const offsets_pos = Number(view.getBigInt64(offset, true));
|
|
52
|
+
const { n_items, offsets_pos } = read_ase_header(view);
|
|
16
53
|
if (n_items <= 0)
|
|
17
54
|
throw new Error(`Invalid frame count`);
|
|
18
55
|
if (offsets_pos < 0 || offsets_pos + n_items * 8 > buffer.byteLength) {
|
|
@@ -23,31 +60,9 @@ export function parse_ase_trajectory(buffer, filename) {
|
|
|
23
60
|
let global_numbers;
|
|
24
61
|
for (let idx = 0; idx < n_items; idx++) {
|
|
25
62
|
try {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if (json_length > MAX_SAFE_STRING_LENGTH) {
|
|
30
|
-
console.warn(`Skipping frame ${idx + 1}/${n_items}: too large`);
|
|
31
|
-
continue;
|
|
32
|
-
}
|
|
33
|
-
const frame_data = JSON.parse(new TextDecoder().decode(new Uint8Array(buffer, offset, json_length)));
|
|
34
|
-
const positions_ref = frame_data[`positions.`] ?? frame_data.positions;
|
|
35
|
-
const positions = positions_ref?.ndarray
|
|
36
|
-
? read_ndarray_from_view(view, positions_ref)
|
|
37
|
-
: positions_ref;
|
|
38
|
-
const numbers_ref = frame_data[`numbers.`] ?? frame_data.numbers ?? global_numbers;
|
|
39
|
-
const numbers = numbers_ref?.ndarray
|
|
40
|
-
? read_ndarray_from_view(view, numbers_ref).flat()
|
|
41
|
-
: numbers_ref;
|
|
42
|
-
if (numbers)
|
|
43
|
-
global_numbers = numbers;
|
|
44
|
-
if (!numbers || !positions) {
|
|
45
|
-
console.warn(`Skipping ASE frame ${idx + 1}/${n_items}: missing ${!numbers ? `numbers` : `positions`}`);
|
|
46
|
-
continue;
|
|
47
|
-
}
|
|
48
|
-
const elements = convert_atomic_numbers(numbers);
|
|
49
|
-
const metadata = { step: idx, ...frame_data.calculator, ...frame_data.info };
|
|
50
|
-
frames.push(create_trajectory_frame(positions, elements, frame_data.cell ? validate_3x3_matrix(frame_data.cell) : undefined, frame_data.pbc ?? [true, true, true], idx, metadata));
|
|
63
|
+
const { frame, numbers } = decode_ase_frame(view, buffer, frame_offsets[idx], idx, global_numbers, MAX_SAFE_STRING_LENGTH);
|
|
64
|
+
global_numbers = numbers;
|
|
65
|
+
frames.push(frame);
|
|
51
66
|
}
|
|
52
67
|
catch (error) {
|
|
53
68
|
console.warn(`Error processing frame ${idx + 1}/${n_items}:`, error);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { to_error } from '../../utils';
|
|
2
|
+
// Collector for non-fatal trajectory parse warnings (skipped atoms, dropped frames, plot-metadata extraction failures, ...) so they reach the UI not just the console. Reset at the start of each top-level parse call; format parsers append via traj_warn (mirrored to console.warn). Fatal failures throw — see parse_trajectory_data.
|
|
3
|
+
let traj_parse_warnings = [];
|
|
4
|
+
// Read-only snapshot of warnings since the last top-level parse (attached to trajectory metadata by parse/index.ts for UI surfacing)
|
|
5
|
+
export const get_traj_parse_warnings = () => [...traj_parse_warnings];
|
|
6
|
+
export const reset_traj_parse_warnings = () => void (traj_parse_warnings = []);
|
|
7
|
+
export const traj_warn = (message, error) => {
|
|
8
|
+
const detail = error === undefined ? `` : `: ${to_error(error).message}`;
|
|
9
|
+
traj_parse_warnings.push(`${message}${detail}`);
|
|
10
|
+
if (error === undefined)
|
|
11
|
+
console.warn(message);
|
|
12
|
+
else
|
|
13
|
+
console.warn(`${message}:`, error);
|
|
14
|
+
};
|
|
@@ -9,7 +9,7 @@ export async function parse_torch_sim_hdf5(buffer, filename) {
|
|
|
9
9
|
const file_basename = filename
|
|
10
10
|
?.split(`/`)
|
|
11
11
|
.at(-1)
|
|
12
|
-
?.
|
|
12
|
+
?.replaceAll(/[^\w.-]/g, `_`) ?? `temp`;
|
|
13
13
|
const unique_suffix = `${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
14
14
|
const temp_filename = `${file_basename}-${unique_suffix}.h5`;
|
|
15
15
|
FS.writeFile(temp_filename, new Uint8Array(buffer));
|
|
@@ -2,7 +2,7 @@ import { is_trajectory_file } from '../format-detect';
|
|
|
2
2
|
import { TrajFrameReader } from '../frame-reader';
|
|
3
3
|
import type { FrameLoader, ParseProgress, TrajectoryType } from '../index';
|
|
4
4
|
import type { AtomTypeMapping, LoadingOptions } from '../types';
|
|
5
|
-
export {
|
|
5
|
+
export { LARGE_FILE_THRESHOLD, MAX_BIN_FILE_SIZE, MAX_TEXT_FILE_SIZE, } from '../constants';
|
|
6
6
|
export type { AtomTypeMapping, LoadingOptions } from '../types';
|
|
7
7
|
export { is_trajectory_file, TrajFrameReader };
|
|
8
8
|
export declare function parse_trajectory_data(data: unknown, filename?: string, atom_type_mapping?: AtomTypeMapping): Promise<TrajectoryType>;
|
|
@@ -1,21 +1,31 @@
|
|
|
1
|
+
// Parsing functions for trajectory data from various formats
|
|
1
2
|
import { is_binary } from '../../io/is-binary';
|
|
2
|
-
import
|
|
3
|
-
import { parse_xyz } from '../../structure/parse';
|
|
3
|
+
import { is_plain_object } from '../../utils';
|
|
4
|
+
import { is_parsed_structure, parse_xyz } from '../../structure/parse';
|
|
4
5
|
import { INDEX_SAMPLE_RATE, LARGE_FILE_THRESHOLD } from '../constants';
|
|
5
|
-
import {
|
|
6
|
+
import { strip_compression_extensions } from '../../io';
|
|
7
|
+
import { ext_hint, FORMAT_PATTERNS, is_trajectory_file } from '../format-detect';
|
|
6
8
|
import { TrajFrameReader } from '../frame-reader';
|
|
7
|
-
import {
|
|
9
|
+
import { count_xyz_frames } from '../helpers';
|
|
8
10
|
import { parse_ase_trajectory } from './ase';
|
|
11
|
+
import { get_traj_parse_warnings, reset_traj_parse_warnings, traj_warn } from './diagnostics';
|
|
9
12
|
import { parse_torch_sim_hdf5 } from './hdf5';
|
|
10
13
|
import { parse_lammps_trajectory } from './lammps';
|
|
14
|
+
import { parse_pymatgen_trajectory } from './pymatgen';
|
|
11
15
|
import { parse_vasp_xdatcar } from './vasp';
|
|
12
16
|
import { parse_xyz_trajectory } from './xyz';
|
|
13
|
-
//
|
|
14
|
-
const
|
|
17
|
+
// Throw on a trajectory frame whose structure isn't a valid parsed structure (non-empty sites with species + coords)
|
|
18
|
+
const assert_frame_structure = (structure, label) => {
|
|
19
|
+
if (!is_parsed_structure(structure)) {
|
|
20
|
+
const context = typeof label === `number` ? `trajectory frame ${label}` : label;
|
|
21
|
+
throw new Error(`Invalid structure in ${context}: expected non-empty 'sites' array with species and coordinates`);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
15
24
|
// Re-export constants and types for consumers
|
|
16
|
-
export {
|
|
25
|
+
export { LARGE_FILE_THRESHOLD, MAX_BIN_FILE_SIZE, MAX_TEXT_FILE_SIZE, } from '../constants';
|
|
17
26
|
export { is_trajectory_file, TrajFrameReader };
|
|
18
27
|
export async function parse_trajectory_data(data, filename, atom_type_mapping) {
|
|
28
|
+
reset_traj_parse_warnings();
|
|
19
29
|
if (data instanceof ArrayBuffer) {
|
|
20
30
|
if (FORMAT_PATTERNS.ase(data, filename))
|
|
21
31
|
return parse_ase_trajectory(data, filename);
|
|
@@ -33,8 +43,10 @@ export async function parse_trajectory_data(data, filename, atom_type_mapping) {
|
|
|
33
43
|
if (FORMAT_PATTERNS.lammpstrj(content, filename)) {
|
|
34
44
|
return parse_lammps_trajectory(content, filename, atom_type_mapping);
|
|
35
45
|
}
|
|
36
|
-
// Single XYZ fallback
|
|
37
|
-
|
|
46
|
+
// Single XYZ fallback (content-sniffed when the filename gives no format hint,
|
|
47
|
+
// e.g. blob: object URLs whose basenames are UUIDs)
|
|
48
|
+
const xyz_hint = ext_hint(filename, /\.(xyz|extxyz)$/);
|
|
49
|
+
if (xyz_hint || (xyz_hint === null && count_xyz_frames(content) === 1)) {
|
|
38
50
|
try {
|
|
39
51
|
const structure = parse_xyz(content);
|
|
40
52
|
if (structure) {
|
|
@@ -44,127 +56,62 @@ export async function parse_trajectory_data(data, filename, atom_type_mapping) {
|
|
|
44
56
|
};
|
|
45
57
|
}
|
|
46
58
|
}
|
|
47
|
-
catch
|
|
59
|
+
catch {
|
|
48
60
|
// Single-frame XYZ parsing failed, continue to JSON parsing.
|
|
49
|
-
log_parse_debug(`Single XYZ parse fallback failed for ${filename ?? `unknown file`}:`, error);
|
|
50
61
|
}
|
|
51
62
|
}
|
|
52
63
|
try {
|
|
53
64
|
data = JSON.parse(content);
|
|
54
65
|
}
|
|
55
66
|
catch (error) {
|
|
56
|
-
log_parse_debug(`JSON parse failed for ${filename ?? `unknown file`}:`, error);
|
|
57
67
|
throw new Error(`Unsupported text format`, { cause: error });
|
|
58
68
|
}
|
|
59
69
|
}
|
|
60
|
-
if (!data || typeof data !== `object`)
|
|
61
|
-
throw new Error(`Invalid data format`);
|
|
62
70
|
// Handle JSON formats
|
|
63
71
|
if (Array.isArray(data)) {
|
|
64
72
|
const frames = data.map((frame_data, idx) => {
|
|
65
73
|
const frame_obj = frame_data;
|
|
66
74
|
const frame_step = frame_obj.step;
|
|
75
|
+
const structure = frame_obj.structure ?? frame_obj;
|
|
76
|
+
assert_frame_structure(structure, idx);
|
|
67
77
|
return {
|
|
68
|
-
structure:
|
|
78
|
+
structure: structure,
|
|
69
79
|
step: typeof frame_step === `number` ? frame_step : idx,
|
|
70
80
|
metadata: frame_obj.metadata || {},
|
|
71
81
|
};
|
|
72
82
|
});
|
|
73
83
|
return { frames, metadata: { source_format: `array`, frame_count: frames.length } };
|
|
74
84
|
}
|
|
75
|
-
|
|
85
|
+
if (!is_plain_object(data))
|
|
86
|
+
throw new Error(`Invalid data format`);
|
|
76
87
|
// Pymatgen format
|
|
77
|
-
if (
|
|
78
|
-
|
|
79
|
-
const frame_elements = species.map((specie) => specie.element);
|
|
80
|
-
const coords = obj.coords;
|
|
81
|
-
const matrix = validate_3x3_matrix(obj.lattice);
|
|
82
|
-
const frame_properties = obj.frame_properties || [];
|
|
83
|
-
const frac_to_cart = math.create_frac_to_cart(matrix);
|
|
84
|
-
const frames = coords.map((frame_coords, idx) => {
|
|
85
|
-
const positions = frame_coords.map((abc) => frac_to_cart(abc));
|
|
86
|
-
// Process frame properties to extract numpy arrays
|
|
87
|
-
const raw_properties = frame_properties[idx] || {};
|
|
88
|
-
const processed_properties = {};
|
|
89
|
-
Object.entries(raw_properties).forEach(([key, value]) => {
|
|
90
|
-
if (value &&
|
|
91
|
-
typeof value === `object` &&
|
|
92
|
-
value[`@class`] === `array`) {
|
|
93
|
-
// Extract numpy array data
|
|
94
|
-
const array_obj = value;
|
|
95
|
-
processed_properties[key] = array_obj.data;
|
|
96
|
-
// Calculate force statistics for forces
|
|
97
|
-
if (key === `forces` && Array.isArray(array_obj.data)) {
|
|
98
|
-
const forces = array_obj.data;
|
|
99
|
-
const force_magnitudes = forces.map((force) => Math.hypot(...force));
|
|
100
|
-
if (force_magnitudes.length > 0) {
|
|
101
|
-
processed_properties.force_max = force_magnitudes.reduce((max_val, magnitude) => (magnitude > max_val ? magnitude : max_val), force_magnitudes[0]);
|
|
102
|
-
processed_properties.force_norm = Math.sqrt(force_magnitudes.reduce((sum, f) => sum + f ** 2, 0) / force_magnitudes.length);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
// Calculate stress statistics for stress tensor
|
|
106
|
-
if (key === `stress` && Array.isArray(array_obj.data)) {
|
|
107
|
-
const stress_tensor = array_obj.data;
|
|
108
|
-
if (!math.is_square_matrix(stress_tensor, 3)) {
|
|
109
|
-
console.warn(`Invalid stress tensor structure in frame ${idx}`);
|
|
110
|
-
}
|
|
111
|
-
else {
|
|
112
|
-
// Calculate stress components (diagonal elements represent normal stresses)
|
|
113
|
-
const normal_stresses = [
|
|
114
|
-
stress_tensor[0][0],
|
|
115
|
-
stress_tensor[1][1],
|
|
116
|
-
stress_tensor[2][2],
|
|
117
|
-
];
|
|
118
|
-
processed_properties.stress_max = Math.max(...normal_stresses.map(Math.abs));
|
|
119
|
-
// Calculate hydrostatic pressure (negative of mean normal stress)
|
|
120
|
-
processed_properties.pressure =
|
|
121
|
-
-(normal_stresses[0] + normal_stresses[1] + normal_stresses[2]) / 3;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
else {
|
|
126
|
-
processed_properties[key] = value;
|
|
127
|
-
}
|
|
128
|
-
});
|
|
129
|
-
return create_trajectory_frame(positions, frame_elements, matrix, [true, true, true], idx, processed_properties);
|
|
130
|
-
});
|
|
131
|
-
return {
|
|
132
|
-
frames,
|
|
133
|
-
metadata: {
|
|
134
|
-
filename,
|
|
135
|
-
source_format: `pymatgen_trajectory`,
|
|
136
|
-
frame_count: frames.length,
|
|
137
|
-
species_list: [...new Set(species.map((specie) => specie.element))],
|
|
138
|
-
periodic_boundary_conditions: [true, true, true],
|
|
139
|
-
},
|
|
140
|
-
};
|
|
88
|
+
if (data[`@class`] === `Trajectory` && data.species && data.coords && data.lattice) {
|
|
89
|
+
return parse_pymatgen_trajectory(data, filename);
|
|
141
90
|
}
|
|
142
91
|
// Object with frames
|
|
143
|
-
if (Array.isArray(
|
|
144
|
-
const metadata = (
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
};
|
|
92
|
+
if (Array.isArray(data.frames)) {
|
|
93
|
+
const metadata = (data.metadata ?? {});
|
|
94
|
+
const frames = data.frames;
|
|
95
|
+
frames.forEach((frame, idx) => assert_frame_structure(frame?.structure, idx));
|
|
96
|
+
return { frames, metadata: { ...metadata, source_format: `object_with_frames` } };
|
|
149
97
|
}
|
|
150
|
-
// Single structure
|
|
151
|
-
if (
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
};
|
|
98
|
+
// Single structure (treated as a 1-frame trajectory)
|
|
99
|
+
if (data.sites) {
|
|
100
|
+
assert_frame_structure(data, `single structure`);
|
|
101
|
+
const frames = [{ structure: data, step: 0, metadata: {} }];
|
|
102
|
+
const metadata = { source_format: `single_structure`, frame_count: 1 };
|
|
103
|
+
return { frames, metadata };
|
|
156
104
|
}
|
|
157
105
|
throw new Error(`Unrecognized trajectory format`);
|
|
158
106
|
}
|
|
159
107
|
export function get_unsupported_format_message(filename, content) {
|
|
160
108
|
const lower = filename.toLowerCase();
|
|
161
109
|
// Check for unsupported compression formats first
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
]
|
|
167
|
-
for (const { ext, name } of unsupported_compression) {
|
|
110
|
+
for (const [ext, name] of [
|
|
111
|
+
[`.bz2`, `BZ2`],
|
|
112
|
+
[`.xz`, `XZ`],
|
|
113
|
+
[`.zip`, `ZIP`],
|
|
114
|
+
]) {
|
|
168
115
|
if (lower.endsWith(ext)) {
|
|
169
116
|
return `🚫 ${name} compression not supported in browser\nPlease decompress the file first`;
|
|
170
117
|
}
|
|
@@ -185,10 +132,20 @@ export function get_unsupported_format_message(filename, content) {
|
|
|
185
132
|
? `🚫 Binary format not supported${filename ? `: ${filename}` : ``}`
|
|
186
133
|
: null;
|
|
187
134
|
}
|
|
135
|
+
// Attach non-fatal parse warnings (skipped atoms, dropped frames, plot-metadata
|
|
136
|
+
// extraction failures, ...) collected during parsing to the trajectory metadata so
|
|
137
|
+
// the UI can surface them instead of leaving them in the console only.
|
|
138
|
+
function attach_parse_warnings(trajectory) {
|
|
139
|
+
const parse_warnings = get_traj_parse_warnings();
|
|
140
|
+
if (parse_warnings.length === 0)
|
|
141
|
+
return trajectory;
|
|
142
|
+
return { ...trajectory, metadata: { ...trajectory.metadata, parse_warnings } };
|
|
143
|
+
}
|
|
188
144
|
// Unified async parser with streaming support
|
|
189
145
|
export async function parse_trajectory_async(data, filename, on_progress, options = {}) {
|
|
190
146
|
const { use_indexing, index_sample_rate = INDEX_SAMPLE_RATE, extract_plot_metadata = true, atom_type_mapping, } = options;
|
|
191
147
|
const update_progress = (current, stage) => on_progress?.({ current, total: 100, stage });
|
|
148
|
+
reset_traj_parse_warnings();
|
|
192
149
|
try {
|
|
193
150
|
update_progress(0, `Detecting format...`);
|
|
194
151
|
const data_size = data instanceof ArrayBuffer ? data.byteLength : new TextEncoder().encode(data).byteLength;
|
|
@@ -198,18 +155,21 @@ export async function parse_trajectory_async(data, filename, on_progress, option
|
|
|
198
155
|
update_progress(5, `Large file detected (${Math.round(data_size / 1024 / 1024)}MB)`);
|
|
199
156
|
}
|
|
200
157
|
// Use indexed loading for supported large files (including compressed names).
|
|
158
|
+
// When the filename gives no format hint (e.g. blob: URLs), sniff a content
|
|
159
|
+
// prefix for XYZ frames so large extensionless files still get indexed.
|
|
201
160
|
const base_filename = strip_compression_extensions(filename);
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
161
|
+
const can_index = /\.(xyz|extxyz|traj)$/.test(base_filename) ||
|
|
162
|
+
(typeof data === `string` &&
|
|
163
|
+
ext_hint(filename, /\.(xyz|extxyz)$/) === null &&
|
|
164
|
+
count_xyz_frames(data.slice(0, 2 ** 20)) >= 1);
|
|
165
|
+
if (should_use_indexing && can_index) {
|
|
166
|
+
return attach_parse_warnings(await parse_with_unified_loader(data, filename, { index_sample_rate, extract_plot_metadata }, on_progress));
|
|
207
167
|
}
|
|
208
168
|
// Fallback to direct parsing
|
|
209
169
|
update_progress(10, `Parsing trajectory...`);
|
|
210
170
|
const result = await parse_trajectory_data(data, filename, atom_type_mapping);
|
|
211
171
|
update_progress(100, `Complete`);
|
|
212
|
-
return result;
|
|
172
|
+
return attach_parse_warnings(result);
|
|
213
173
|
}
|
|
214
174
|
catch (error) {
|
|
215
175
|
const error_message = error instanceof Error ? error.message : `Unknown error`;
|
|
@@ -251,7 +211,7 @@ async function parse_with_unified_loader(data, filename, options, on_progress) {
|
|
|
251
211
|
});
|
|
252
212
|
}
|
|
253
213
|
catch (error) {
|
|
254
|
-
|
|
214
|
+
traj_warn(`Failed to extract plot metadata`, error);
|
|
255
215
|
}
|
|
256
216
|
}
|
|
257
217
|
const stage = `Ready: ${total_frames} frames indexed`;
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import * as math from '../../math';
|
|
2
1
|
import type { TrajectoryType } from '../index';
|
|
3
2
|
import type { AtomTypeMapping } from '../types';
|
|
4
|
-
export declare function parse_lammps_box(box_lines: string[], is_triclinic: boolean): math.Matrix3x3 | null;
|
|
5
3
|
export declare function parse_lammps_trajectory(content: string, filename?: string, atom_type_mapping?: AtomTypeMapping): TrajectoryType;
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { ELEM_SYMBOLS } from '../../labels';
|
|
2
2
|
import * as math from '../../math';
|
|
3
|
-
import {
|
|
3
|
+
import { coerce_elem_symbol } from '../../element';
|
|
4
|
+
import { create_trajectory_frame } from '../helpers';
|
|
5
|
+
import { traj_warn } from './diagnostics';
|
|
4
6
|
const is_periodic = (token) => token.toLowerCase().startsWith(`p`);
|
|
5
7
|
// Parse LAMMPS box bounds → lattice matrix. Handles orthogonal and triclinic boxes.
|
|
6
8
|
// Triclinic: converts bounding box to actual dims per https://docs.lammps.org/Howto_triclinic.html
|
|
7
9
|
// Lattice vectors: a=(lx,0,0), b=(xy,ly,0), c=(xz,yz,lz)
|
|
8
|
-
|
|
10
|
+
function parse_lammps_box(box_lines, is_triclinic) {
|
|
9
11
|
if (box_lines.length !== 3)
|
|
10
12
|
return null;
|
|
11
13
|
const bounds = box_lines.map((line) => line.split(/\s+/).map(Number));
|
|
@@ -100,7 +102,7 @@ export function parse_lammps_trajectory(content, filename, atom_type_mapping) {
|
|
|
100
102
|
if (pos_cols.some((col_idx) => col_idx === undefined))
|
|
101
103
|
continue;
|
|
102
104
|
if (type_col === undefined && element_col === undefined && id_col === undefined) {
|
|
103
|
-
|
|
105
|
+
traj_warn(`Skipping LAMMPS frame at timestep ${timestep}: missing type/element/id column`);
|
|
104
106
|
continue;
|
|
105
107
|
}
|
|
106
108
|
// Parse atom data
|
|
@@ -125,9 +127,9 @@ export function parse_lammps_trajectory(content, filename, atom_type_mapping) {
|
|
|
125
127
|
const raw_symbol = parts[element_col];
|
|
126
128
|
if (!raw_symbol)
|
|
127
129
|
continue;
|
|
128
|
-
element_symbol =
|
|
130
|
+
element_symbol = coerce_elem_symbol(raw_symbol);
|
|
129
131
|
if (!element_symbol) {
|
|
130
|
-
|
|
132
|
+
traj_warn(`Skipping LAMMPS atom with unknown element symbol "${raw_symbol}" at timestep ${timestep}`);
|
|
131
133
|
continue;
|
|
132
134
|
}
|
|
133
135
|
}
|
|
@@ -135,7 +137,7 @@ export function parse_lammps_trajectory(content, filename, atom_type_mapping) {
|
|
|
135
137
|
const atom_id = parseInt(parts[id_col], 10) || 1;
|
|
136
138
|
atom_types_found.add(atom_id);
|
|
137
139
|
if (!id_fallback_warning_emitted) {
|
|
138
|
-
|
|
140
|
+
traj_warn(`LAMMPS parser fallback: mapping atom IDs to elements from ID column; this may be incorrect for large or sequential IDs. Prefer a TYPE column when available.`);
|
|
139
141
|
id_fallback_warning_emitted = true;
|
|
140
142
|
}
|
|
141
143
|
element_symbol = get_element(atom_id);
|