matterviz 0.3.5 → 0.3.6
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/.vscode/launch.json +13 -0
- package/.vscodeignore +7 -0
- package/dist/assets/STLExporter-BpTH3YHE.js +8 -0
- package/dist/assets/browser-DdDecX_W.js +1 -0
- package/dist/assets/export-qgn-H9y6.js +2 -0
- package/dist/assets/main-DiKYzti2.css +1 -0
- package/dist/assets/moyo_wasm_bg-0ocwg7xY.wasm +0 -0
- package/dist/extension.js +31293 -0
- package/dist/src/lib/FilePicker.svelte +360 -0
- package/dist/src/lib/MillerIndexInput.svelte +66 -0
- package/dist/src/lib/api/mp.ts +26 -0
- package/dist/src/lib/api/optimade.ts +204 -0
- package/dist/src/lib/brillouin/BrillouinZone.svelte +549 -0
- package/dist/src/lib/brillouin/BrillouinZoneControls.svelte +144 -0
- package/dist/src/lib/brillouin/BrillouinZoneExportPane.svelte +146 -0
- package/dist/src/lib/brillouin/BrillouinZoneInfoPane.svelte +146 -0
- package/dist/src/lib/brillouin/BrillouinZoneScene.svelte +476 -0
- package/dist/src/lib/brillouin/BrillouinZoneTooltip.svelte +92 -0
- package/dist/src/lib/brillouin/compute.ts +529 -0
- package/dist/src/lib/brillouin/index.ts +8 -0
- package/dist/src/lib/brillouin/types.ts +51 -0
- package/dist/src/lib/chempot-diagram/ChemPotDiagram.svelte +327 -0
- package/dist/src/lib/chempot-diagram/ChemPotDiagram2D.svelte +846 -0
- package/dist/src/lib/chempot-diagram/ChemPotDiagram3D.svelte +3193 -0
- package/dist/src/lib/chempot-diagram/async-compute.svelte.ts +94 -0
- package/dist/src/lib/chempot-diagram/chempot-worker.ts +11 -0
- package/dist/src/lib/chempot-diagram/color.ts +42 -0
- package/dist/src/lib/chempot-diagram/compute.ts +1014 -0
- package/dist/src/lib/chempot-diagram/index.ts +6 -0
- package/dist/src/lib/chempot-diagram/pointer.ts +56 -0
- package/dist/src/lib/chempot-diagram/temperature.ts +77 -0
- package/dist/src/lib/chempot-diagram/types.ts +130 -0
- package/dist/src/lib/colors/index.ts +249 -0
- package/dist/src/lib/composition/BarChart.svelte +297 -0
- package/dist/src/lib/composition/BubbleChart.svelte +218 -0
- package/dist/src/lib/composition/Composition.svelte +165 -0
- package/dist/src/lib/composition/Formula.svelte +268 -0
- package/dist/src/lib/composition/FormulaFilter.svelte +1257 -0
- package/dist/src/lib/composition/PieChart.svelte +323 -0
- package/dist/src/lib/composition/format.ts +155 -0
- package/dist/src/lib/composition/index.ts +37 -0
- package/dist/src/lib/composition/parse.ts +605 -0
- package/dist/src/lib/constants.ts +134 -0
- package/dist/src/lib/controls.ts +42 -0
- package/dist/src/lib/convex-hull/ConvexHull.svelte +157 -0
- package/dist/src/lib/convex-hull/ConvexHull2D.svelte +825 -0
- package/dist/src/lib/convex-hull/ConvexHull3D.svelte +1801 -0
- package/dist/src/lib/convex-hull/ConvexHull4D.svelte +1398 -0
- package/dist/src/lib/convex-hull/ConvexHullControls.svelte +535 -0
- package/dist/src/lib/convex-hull/ConvexHullInfoPane.svelte +125 -0
- package/dist/src/lib/convex-hull/ConvexHullStats.svelte +929 -0
- package/dist/src/lib/convex-hull/ConvexHullTooltip.svelte +131 -0
- package/dist/src/lib/convex-hull/GasPressureControls.svelte +247 -0
- package/dist/src/lib/convex-hull/StructurePopup.svelte +151 -0
- package/dist/src/lib/convex-hull/TemperatureSlider.svelte +140 -0
- package/dist/src/lib/convex-hull/barycentric-coords.ts +246 -0
- package/dist/src/lib/convex-hull/demo-temperature.ts +63 -0
- package/dist/src/lib/convex-hull/gas-thermodynamics.ts +405 -0
- package/dist/src/lib/convex-hull/helpers.ts +932 -0
- package/dist/src/lib/convex-hull/index.ts +202 -0
- package/dist/src/lib/convex-hull/thermodynamics.ts +2192 -0
- package/dist/src/lib/convex-hull/types.ts +267 -0
- package/dist/src/lib/coordination/CoordinationBarPlot.svelte +311 -0
- package/dist/src/lib/coordination/calc-coordination.ts +93 -0
- package/dist/src/lib/coordination/index.ts +9 -0
- package/dist/src/lib/effects.svelte.ts +48 -0
- package/dist/src/lib/element/BohrAtom.svelte +147 -0
- package/dist/src/lib/element/ElementHeading.svelte +26 -0
- package/dist/src/lib/element/ElementPhoto.svelte +57 -0
- package/dist/src/lib/element/ElementStats.svelte +80 -0
- package/dist/src/lib/element/ElementTile.svelte +484 -0
- package/dist/src/lib/element/data.json.gz.d.ts +4 -0
- package/dist/src/lib/element/data.ts +14 -0
- package/dist/src/lib/element/index.ts +8 -0
- package/dist/src/lib/element/types.ts +62 -0
- package/dist/src/lib/feedback/ClickFeedback.svelte +58 -0
- package/dist/src/lib/feedback/DragOverlay.svelte +42 -0
- package/dist/src/lib/feedback/index.ts +4 -0
- package/dist/src/lib/fermi-surface/FermiSlice.svelte +189 -0
- package/dist/src/lib/fermi-surface/FermiSurface.svelte +600 -0
- package/dist/src/lib/fermi-surface/FermiSurfaceControls.svelte +448 -0
- package/dist/src/lib/fermi-surface/FermiSurfaceScene.svelte +794 -0
- package/dist/src/lib/fermi-surface/FermiSurfaceTooltip.svelte +111 -0
- package/dist/src/lib/fermi-surface/compute.ts +728 -0
- package/dist/src/lib/fermi-surface/constants.ts +32 -0
- package/dist/src/lib/fermi-surface/export.ts +64 -0
- package/dist/src/lib/fermi-surface/index.ts +14 -0
- package/dist/src/lib/fermi-surface/marching-cubes.ts +3 -0
- package/dist/src/lib/fermi-surface/parse.ts +574 -0
- package/dist/src/lib/fermi-surface/symmetry.ts +56 -0
- package/dist/src/lib/fermi-surface/types.ts +159 -0
- package/dist/src/lib/heatmap-matrix/HeatmapMatrix.svelte +1545 -0
- package/dist/src/lib/heatmap-matrix/HeatmapMatrixControls.svelte +225 -0
- package/dist/src/lib/heatmap-matrix/index.ts +167 -0
- package/dist/src/lib/heatmap-matrix/shared.ts +7 -0
- package/dist/src/lib/icons.ts +650 -0
- package/dist/src/lib/index.ts +61 -0
- package/dist/src/lib/io/decompress.ts +92 -0
- package/dist/src/lib/io/export.ts +385 -0
- package/dist/src/lib/io/fetch.ts +46 -0
- package/dist/src/lib/io/file-drop.ts +51 -0
- package/dist/src/lib/io/index.ts +7 -0
- package/dist/src/lib/io/is-binary.ts +24 -0
- package/dist/src/lib/io/types.ts +8 -0
- package/dist/src/lib/io/url-drop.ts +141 -0
- package/dist/src/lib/isosurface/Isosurface.svelte +285 -0
- package/dist/src/lib/isosurface/IsosurfaceControls.svelte +277 -0
- package/dist/src/lib/isosurface/index.ts +7 -0
- package/dist/src/lib/isosurface/parse.ts +656 -0
- package/dist/src/lib/isosurface/slice.ts +175 -0
- package/dist/src/lib/isosurface/types.ts +309 -0
- package/dist/src/lib/labels.ts +320 -0
- package/dist/src/lib/layout/FullscreenToggle.svelte +50 -0
- package/dist/src/lib/layout/InfoCard.svelte +120 -0
- package/dist/src/lib/layout/InfoTag.svelte +185 -0
- package/dist/src/lib/layout/PropertyFilter.svelte +246 -0
- package/dist/src/lib/layout/SettingsSection.svelte +148 -0
- package/dist/src/lib/layout/SubpageGrid.svelte +82 -0
- package/dist/src/lib/layout/fullscreen.ts +65 -0
- package/dist/src/lib/layout/index.ts +11 -0
- package/dist/src/lib/layout/json-tree/JsonNode.svelte +548 -0
- package/dist/src/lib/layout/json-tree/JsonTree.svelte +1230 -0
- package/dist/src/lib/layout/json-tree/JsonValue.svelte +334 -0
- package/dist/src/lib/layout/json-tree/index.ts +3 -0
- package/dist/src/lib/layout/json-tree/types.ts +126 -0
- package/dist/src/lib/layout/json-tree/utils.ts +682 -0
- package/dist/src/lib/marching-cubes.ts +614 -0
- package/dist/src/lib/math.ts +1081 -0
- package/dist/src/lib/overlays/ContextMenu.svelte +162 -0
- package/dist/src/lib/overlays/CopyButton.svelte +45 -0
- package/dist/src/lib/overlays/DragControlTab.svelte +98 -0
- package/dist/src/lib/overlays/DraggablePane.svelte +487 -0
- package/dist/src/lib/overlays/InfoPaneCards.svelte +149 -0
- package/dist/src/lib/overlays/index.ts +3 -0
- package/dist/src/lib/periodic-table/PeriodicTable.svelte +469 -0
- package/dist/src/lib/periodic-table/PeriodicTableControls.svelte +557 -0
- package/dist/src/lib/periodic-table/PropertySelect.svelte +37 -0
- package/dist/src/lib/periodic-table/index.ts +12 -0
- package/dist/src/lib/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +1086 -0
- package/dist/src/lib/phase-diagram/PhaseDiagramControls.svelte +444 -0
- package/dist/src/lib/phase-diagram/PhaseDiagramEditorPane.svelte +126 -0
- package/dist/src/lib/phase-diagram/PhaseDiagramExportPane.svelte +184 -0
- package/dist/src/lib/phase-diagram/PhaseDiagramTooltip.svelte +391 -0
- package/dist/src/lib/phase-diagram/TdbInfoPanel.svelte +203 -0
- package/dist/src/lib/phase-diagram/build-diagram.ts +186 -0
- package/dist/src/lib/phase-diagram/colors.ts +58 -0
- package/dist/src/lib/phase-diagram/diagram-input.ts +40 -0
- package/dist/src/lib/phase-diagram/index.ts +13 -0
- package/dist/src/lib/phase-diagram/parse.ts +348 -0
- package/dist/src/lib/phase-diagram/svg-to-diagram.ts +1023 -0
- package/dist/src/lib/phase-diagram/types.ts +144 -0
- package/dist/src/lib/phase-diagram/utils.ts +775 -0
- package/dist/src/lib/plot/AxisLabel.svelte +51 -0
- package/dist/src/lib/plot/BarPlot.svelte +2113 -0
- package/dist/src/lib/plot/BarPlotControls.svelte +66 -0
- package/dist/src/lib/plot/BinnedScatterPlot.svelte +1114 -0
- package/dist/src/lib/plot/ColorBar.svelte +721 -0
- package/dist/src/lib/plot/ColorScaleSelect.svelte +54 -0
- package/dist/src/lib/plot/ElementScatter.svelte +63 -0
- package/dist/src/lib/plot/FillArea.svelte +223 -0
- package/dist/src/lib/plot/Histogram.svelte +1558 -0
- package/dist/src/lib/plot/HistogramControls.svelte +212 -0
- package/dist/src/lib/plot/InteractiveAxisLabel.svelte +96 -0
- package/dist/src/lib/plot/Line.svelte +84 -0
- package/dist/src/lib/plot/PlotAxis.svelte +169 -0
- package/dist/src/lib/plot/PlotControls.svelte +537 -0
- package/dist/src/lib/plot/PlotLegend.svelte +569 -0
- package/dist/src/lib/plot/PlotTooltip.svelte +67 -0
- package/dist/src/lib/plot/PortalSelect.svelte +253 -0
- package/dist/src/lib/plot/ReferenceLine3D.svelte +156 -0
- package/dist/src/lib/plot/ReferencePlane.svelte +175 -0
- package/dist/src/lib/plot/ScatterPlot.svelte +2778 -0
- package/dist/src/lib/plot/ScatterPlot3D.svelte +529 -0
- package/dist/src/lib/plot/ScatterPlot3DControls.svelte +437 -0
- package/dist/src/lib/plot/ScatterPlot3DScene.svelte +912 -0
- package/dist/src/lib/plot/ScatterPlotControls.svelte +306 -0
- package/dist/src/lib/plot/ScatterPoint.svelte +182 -0
- package/dist/src/lib/plot/SpacegroupBarPlot.svelte +293 -0
- package/dist/src/lib/plot/Surface3D.svelte +197 -0
- package/dist/src/lib/plot/ZeroLines.svelte +97 -0
- package/dist/src/lib/plot/ZoomRect.svelte +23 -0
- package/dist/src/lib/plot/adaptive-density.ts +316 -0
- package/dist/src/lib/plot/auto-place.ts +184 -0
- package/dist/src/lib/plot/axis-utils.ts +122 -0
- package/dist/src/lib/plot/binned-scatter-types.ts +83 -0
- package/dist/src/lib/plot/data-cleaning.ts +1069 -0
- package/dist/src/lib/plot/data-transform.ts +69 -0
- package/dist/src/lib/plot/defaults.ts +9 -0
- package/dist/src/lib/plot/fill-utils.ts +494 -0
- package/dist/src/lib/plot/hover-lock.svelte.ts +60 -0
- package/dist/src/lib/plot/index.ts +53 -0
- package/dist/src/lib/plot/interactions.ts +119 -0
- package/dist/src/lib/plot/layout.ts +425 -0
- package/dist/src/lib/plot/reference-line.ts +426 -0
- package/dist/src/lib/plot/scales.ts +654 -0
- package/dist/src/lib/plot/svg.ts +23 -0
- package/dist/src/lib/plot/types.ts +1144 -0
- package/dist/src/lib/plot/utils/label-placement.ts +541 -0
- package/dist/src/lib/plot/utils/series-visibility.ts +140 -0
- package/dist/src/lib/plot/utils.ts +11 -0
- package/dist/src/lib/rdf/RdfPlot.svelte +247 -0
- package/dist/src/lib/rdf/calc-rdf.ts +167 -0
- package/dist/src/lib/rdf/index.ts +27 -0
- package/dist/src/lib/sanitize.ts +126 -0
- package/dist/src/lib/settings.ts +1479 -0
- package/dist/src/lib/spectral/Bands.svelte +1040 -0
- package/dist/src/lib/spectral/BandsAndDos.svelte +134 -0
- package/dist/src/lib/spectral/BrillouinBandsDos.svelte +252 -0
- package/dist/src/lib/spectral/Dos.svelte +697 -0
- package/dist/src/lib/spectral/helpers.ts +1381 -0
- package/dist/src/lib/spectral/index.ts +8 -0
- package/dist/src/lib/spectral/types.ts +112 -0
- package/dist/src/lib/state.svelte.ts +64 -0
- package/dist/src/lib/structure/Arrow.svelte +72 -0
- package/dist/src/lib/structure/AtomLegend.svelte +815 -0
- package/dist/src/lib/structure/Bond.svelte +140 -0
- package/dist/src/lib/structure/CanvasTooltip.svelte +33 -0
- package/dist/src/lib/structure/CellSelect.svelte +349 -0
- package/dist/src/lib/structure/Cylinder.svelte +45 -0
- package/dist/src/lib/structure/Lattice.svelte +196 -0
- package/dist/src/lib/structure/Structure.svelte +2248 -0
- package/dist/src/lib/structure/StructureControls.svelte +1273 -0
- package/dist/src/lib/structure/StructureExportPane.svelte +252 -0
- package/dist/src/lib/structure/StructureInfoPane.svelte +737 -0
- package/dist/src/lib/structure/StructureScene.svelte +2255 -0
- package/dist/src/lib/structure/atom-properties.ts +316 -0
- package/dist/src/lib/structure/bond-order-perception.ts +447 -0
- package/dist/src/lib/structure/bonding.ts +944 -0
- package/dist/src/lib/structure/export.ts +861 -0
- package/dist/src/lib/structure/index.ts +291 -0
- package/dist/src/lib/structure/label-placement.ts +130 -0
- package/dist/src/lib/structure/measure.ts +45 -0
- package/dist/src/lib/structure/parse.ts +1705 -0
- package/dist/src/lib/structure/partial-occupancy.ts +183 -0
- package/dist/src/lib/structure/pbc.ts +164 -0
- package/dist/src/lib/structure/supercell.ts +226 -0
- package/dist/src/lib/structure/validation.ts +11 -0
- package/dist/src/lib/symmetry/SymmetryStats.svelte +226 -0
- package/dist/src/lib/symmetry/WyckoffTable.svelte +120 -0
- package/dist/src/lib/symmetry/cell-transform.ts +118 -0
- package/dist/src/lib/symmetry/index.ts +348 -0
- package/dist/src/lib/symmetry/spacegroups.ts +404 -0
- package/dist/src/lib/table/HeatmapTable.svelte +1833 -0
- package/dist/src/lib/table/ToggleMenu.svelte +385 -0
- package/dist/src/lib/table/index.ts +139 -0
- package/dist/src/lib/theme/ThemeControl.svelte +53 -0
- package/dist/src/lib/theme/index.ts +107 -0
- package/dist/src/lib/theme/themes.mjs +297 -0
- package/dist/src/lib/time.ts +71 -0
- package/dist/src/lib/tooltip/TooltipContent.svelte +58 -0
- package/dist/src/lib/tooltip/index.ts +2 -0
- package/dist/src/lib/tooltip/types.ts +13 -0
- package/dist/src/lib/trajectory/Trajectory.svelte +1545 -0
- package/dist/src/lib/trajectory/TrajectoryError.svelte +128 -0
- package/dist/src/lib/trajectory/TrajectoryExportPane.svelte +357 -0
- package/dist/src/lib/trajectory/TrajectoryInfoPane.svelte +313 -0
- package/dist/src/lib/trajectory/constants.ts +7 -0
- package/dist/src/lib/trajectory/extract.ts +196 -0
- package/dist/src/lib/trajectory/format-detect.ts +96 -0
- package/dist/src/lib/trajectory/frame-reader.ts +456 -0
- package/dist/src/lib/trajectory/helpers.ts +217 -0
- package/dist/src/lib/trajectory/index.ts +218 -0
- package/dist/src/lib/trajectory/parse/ase.ts +109 -0
- package/dist/src/lib/trajectory/parse/hdf5.ts +173 -0
- package/dist/src/lib/trajectory/parse/index.ts +411 -0
- package/dist/src/lib/trajectory/parse/lammps.ts +215 -0
- package/dist/src/lib/trajectory/parse/vasp.ts +102 -0
- package/dist/src/lib/trajectory/parse/xyz.ts +143 -0
- package/dist/src/lib/trajectory/plotting.ts +599 -0
- package/dist/src/lib/trajectory/types.ts +13 -0
- package/dist/src/lib/utils.ts +56 -0
- package/dist/src/lib/xrd/XrdPlot.svelte +615 -0
- package/dist/src/lib/xrd/broadening.ts +130 -0
- package/dist/src/lib/xrd/calc-xrd.ts +397 -0
- package/dist/src/lib/xrd/index.ts +38 -0
- package/dist/src/lib/xrd/parse.ts +858 -0
- package/dist/webview.js +29421 -0
- package/icon.png +0 -0
- package/license +1 -1
- package/matterviz-0.3.2.vsix +0 -0
- package/matterviz-0.3.4.vsix +0 -0
- package/matterviz-0.3.5.vsix +0 -0
- package/package.json +1460 -215
- package/readme.md +171 -98
- package/scripts/sync-config.ts +101 -0
- package/src/declarations.d.ts +2 -0
- package/src/extension.ts +972 -0
- package/src/node-io.ts +65 -0
- package/src/types.ts +17 -0
- package/src/webview/JsonBrowser.svelte +1079 -0
- package/src/webview/PlotPanel.svelte +346 -0
- package/src/webview/detect.ts +444 -0
- package/src/webview/main.ts +764 -0
- package/src/webview/plot-utils.ts +250 -0
- package/test-fixtures/all-viz-types.json.gz +0 -0
- package/test-fixtures/plot-demo-data.json.gz +0 -0
- package/tests/detect.test.ts +604 -0
- package/tests/extension.test.ts +2041 -0
- package/tests/node-io.test.ts +39 -0
- package/tests/plot-utils.test.ts +302 -0
- package/tests/vite-plugin-json-gz.test.ts +114 -0
- package/tests/vscode-mock.ts +18 -0
- package/tests/webview.test.ts +231 -0
- package/tsconfig.json +20 -0
- package/vite-plugin-json-gz.ts +29 -0
- package/vite.config.ts +34 -0
- package/vite.extension.config.ts +34 -0
- package/dist/EmptyState.svelte.d.ts +0 -9
- package/dist/FilePicker.svelte +0 -360
- package/dist/FilePicker.svelte.d.ts +0 -17
- package/dist/Icon.svelte.d.ts +0 -13
- package/dist/MillerIndexInput.svelte +0 -66
- package/dist/MillerIndexInput.svelte.d.ts +0 -7
- package/dist/api/mp.d.ts +0 -6
- package/dist/api/mp.js +0 -22
- package/dist/api/optimade.d.ts +0 -45
- package/dist/api/optimade.js +0 -135
- package/dist/brillouin/BrillouinZone.svelte +0 -546
- package/dist/brillouin/BrillouinZone.svelte.d.ts +0 -83
- package/dist/brillouin/BrillouinZoneControls.svelte +0 -144
- package/dist/brillouin/BrillouinZoneControls.svelte.d.ts +0 -17
- package/dist/brillouin/BrillouinZoneExportPane.svelte +0 -148
- package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +0 -15
- package/dist/brillouin/BrillouinZoneInfoPane.svelte +0 -146
- package/dist/brillouin/BrillouinZoneInfoPane.svelte.d.ts +0 -13
- package/dist/brillouin/BrillouinZoneScene.svelte +0 -476
- package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +0 -48
- package/dist/brillouin/BrillouinZoneTooltip.svelte +0 -92
- package/dist/brillouin/BrillouinZoneTooltip.svelte.d.ts +0 -8
- package/dist/brillouin/compute.d.ts +0 -17
- package/dist/brillouin/compute.js +0 -426
- package/dist/brillouin/index.d.ts +0 -8
- package/dist/brillouin/index.js +0 -8
- package/dist/brillouin/types.d.ts +0 -48
- package/dist/brillouin/types.js +0 -1
- package/dist/chempot-diagram/ChemPotDiagram.svelte +0 -327
- package/dist/chempot-diagram/ChemPotDiagram.svelte.d.ts +0 -13
- package/dist/chempot-diagram/ChemPotDiagram2D.svelte +0 -847
- package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +0 -16
- package/dist/chempot-diagram/ChemPotDiagram3D.svelte +0 -3194
- package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +0 -16
- package/dist/chempot-diagram/ChemPotScene3D.svelte.d.ts +0 -7
- package/dist/chempot-diagram/async-compute.svelte.d.ts +0 -3
- package/dist/chempot-diagram/async-compute.svelte.js +0 -78
- package/dist/chempot-diagram/chempot-worker.d.ts +0 -1
- package/dist/chempot-diagram/chempot-worker.js +0 -11
- package/dist/chempot-diagram/color.d.ts +0 -10
- package/dist/chempot-diagram/color.js +0 -32
- package/dist/chempot-diagram/compute.d.ts +0 -48
- package/dist/chempot-diagram/compute.js +0 -812
- package/dist/chempot-diagram/index.d.ts +0 -6
- package/dist/chempot-diagram/index.js +0 -6
- package/dist/chempot-diagram/pointer.d.ts +0 -16
- package/dist/chempot-diagram/pointer.js +0 -40
- package/dist/chempot-diagram/temperature.d.ts +0 -15
- package/dist/chempot-diagram/temperature.js +0 -36
- package/dist/chempot-diagram/types.d.ts +0 -86
- package/dist/chempot-diagram/types.js +0 -28
- package/dist/colors/index.d.ts +0 -47
- package/dist/colors/index.js +0 -203
- package/dist/composition/BarChart.svelte +0 -297
- package/dist/composition/BarChart.svelte.d.ts +0 -39
- package/dist/composition/BubbleChart.svelte +0 -218
- package/dist/composition/BubbleChart.svelte.d.ts +0 -28
- package/dist/composition/Composition.svelte +0 -164
- package/dist/composition/Composition.svelte.d.ts +0 -15
- package/dist/composition/Formula.svelte +0 -265
- package/dist/composition/Formula.svelte.d.ts +0 -19
- package/dist/composition/FormulaFilter.svelte +0 -1259
- package/dist/composition/FormulaFilter.svelte.d.ts +0 -51
- package/dist/composition/PieChart.svelte +0 -323
- package/dist/composition/PieChart.svelte.d.ts +0 -37
- package/dist/composition/format.d.ts +0 -15
- package/dist/composition/format.js +0 -109
- package/dist/composition/index.d.ts +0 -20
- package/dist/composition/index.js +0 -14
- package/dist/composition/parse.d.ts +0 -55
- package/dist/composition/parse.js +0 -459
- package/dist/constants.d.ts +0 -29
- package/dist/constants.js +0 -99
- package/dist/controls.d.ts +0 -14
- package/dist/controls.js +0 -30
- package/dist/convex-hull/ConvexHull.svelte +0 -157
- package/dist/convex-hull/ConvexHull.svelte.d.ts +0 -13
- package/dist/convex-hull/ConvexHull2D.svelte +0 -814
- package/dist/convex-hull/ConvexHull2D.svelte.d.ts +0 -11
- package/dist/convex-hull/ConvexHull3D.svelte +0 -1790
- package/dist/convex-hull/ConvexHull3D.svelte.d.ts +0 -8
- package/dist/convex-hull/ConvexHull4D.svelte +0 -1386
- package/dist/convex-hull/ConvexHull4D.svelte.d.ts +0 -8
- package/dist/convex-hull/ConvexHullControls.svelte +0 -546
- package/dist/convex-hull/ConvexHullControls.svelte.d.ts +0 -48
- package/dist/convex-hull/ConvexHullInfoPane.svelte +0 -122
- package/dist/convex-hull/ConvexHullInfoPane.svelte.d.ts +0 -18
- package/dist/convex-hull/ConvexHullStats.svelte +0 -922
- package/dist/convex-hull/ConvexHullStats.svelte.d.ts +0 -15
- package/dist/convex-hull/ConvexHullTooltip.svelte +0 -131
- package/dist/convex-hull/ConvexHullTooltip.svelte.d.ts +0 -33
- package/dist/convex-hull/GasPressureControls.svelte +0 -247
- package/dist/convex-hull/GasPressureControls.svelte.d.ts +0 -11
- package/dist/convex-hull/StructurePopup.svelte +0 -116
- package/dist/convex-hull/StructurePopup.svelte.d.ts +0 -18
- package/dist/convex-hull/TemperatureSlider.svelte +0 -137
- package/dist/convex-hull/TemperatureSlider.svelte.d.ts +0 -8
- package/dist/convex-hull/barycentric-coords.d.ts +0 -18
- package/dist/convex-hull/barycentric-coords.js +0 -182
- package/dist/convex-hull/demo-temperature.d.ts +0 -6
- package/dist/convex-hull/demo-temperature.js +0 -40
- package/dist/convex-hull/gas-thermodynamics.d.ts +0 -16
- package/dist/convex-hull/gas-thermodynamics.js +0 -316
- package/dist/convex-hull/helpers.d.ts +0 -103
- package/dist/convex-hull/helpers.js +0 -689
- package/dist/convex-hull/index.d.ts +0 -118
- package/dist/convex-hull/index.js +0 -57
- package/dist/convex-hull/thermodynamics.d.ts +0 -66
- package/dist/convex-hull/thermodynamics.js +0 -1752
- package/dist/convex-hull/types.d.ts +0 -162
- package/dist/convex-hull/types.js +0 -36
- package/dist/coordination/CoordinationBarPlot.svelte +0 -311
- package/dist/coordination/CoordinationBarPlot.svelte.d.ts +0 -30
- package/dist/coordination/calc-coordination.d.ts +0 -15
- package/dist/coordination/calc-coordination.js +0 -63
- package/dist/coordination/index.d.ts +0 -8
- package/dist/coordination/index.js +0 -7
- package/dist/element/BohrAtom.svelte +0 -147
- package/dist/element/BohrAtom.svelte.d.ts +0 -20
- package/dist/element/ElementHeading.svelte +0 -26
- package/dist/element/ElementHeading.svelte.d.ts +0 -8
- package/dist/element/ElementPhoto.svelte +0 -57
- package/dist/element/ElementPhoto.svelte.d.ts +0 -9
- package/dist/element/ElementStats.svelte +0 -80
- package/dist/element/ElementStats.svelte.d.ts +0 -8
- package/dist/element/ElementTile.svelte +0 -484
- package/dist/element/ElementTile.svelte.d.ts +0 -29
- package/dist/element/Nucleus.svelte.d.ts +0 -17
- package/dist/element/data.d.ts +0 -2
- package/dist/element/data.js +0 -2
- package/dist/element/data.json.gz.d.ts +0 -2
- package/dist/element/index.d.ts +0 -8
- package/dist/element/index.js +0 -8
- package/dist/element/types.d.ts +0 -57
- package/dist/element/types.js +0 -1
- package/dist/feedback/ClickFeedback.svelte +0 -58
- package/dist/feedback/ClickFeedback.svelte.d.ts +0 -12
- package/dist/feedback/DragOverlay.svelte +0 -42
- package/dist/feedback/DragOverlay.svelte.d.ts +0 -7
- package/dist/feedback/Spinner.svelte.d.ts +0 -7
- package/dist/feedback/StatusMessage.svelte.d.ts +0 -9
- package/dist/feedback/index.d.ts +0 -4
- package/dist/feedback/index.js +0 -4
- package/dist/fermi-surface/FermiSlice.svelte +0 -189
- package/dist/fermi-surface/FermiSlice.svelte.d.ts +0 -24
- package/dist/fermi-surface/FermiSurface.svelte +0 -600
- package/dist/fermi-surface/FermiSurface.svelte.d.ts +0 -83
- package/dist/fermi-surface/FermiSurfaceControls.svelte +0 -452
- package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +0 -35
- package/dist/fermi-surface/FermiSurfaceScene.svelte +0 -792
- package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +0 -50
- package/dist/fermi-surface/FermiSurfaceTooltip.svelte +0 -111
- package/dist/fermi-surface/FermiSurfaceTooltip.svelte.d.ts +0 -8
- package/dist/fermi-surface/compute.d.ts +0 -5
- package/dist/fermi-surface/compute.js +0 -538
- package/dist/fermi-surface/constants.d.ts +0 -9
- package/dist/fermi-surface/constants.js +0 -27
- package/dist/fermi-surface/export.d.ts +0 -5
- package/dist/fermi-surface/export.js +0 -63
- package/dist/fermi-surface/index.d.ts +0 -12
- package/dist/fermi-surface/index.js +0 -13
- package/dist/fermi-surface/marching-cubes.d.ts +0 -2
- package/dist/fermi-surface/marching-cubes.js +0 -2
- package/dist/fermi-surface/parse.d.ts +0 -2
- package/dist/fermi-surface/parse.js +0 -495
- package/dist/fermi-surface/symmetry.d.ts +0 -3
- package/dist/fermi-surface/symmetry.js +0 -46
- package/dist/fermi-surface/types.d.ts +0 -113
- package/dist/fermi-surface/types.js +0 -4
- package/dist/heatmap-matrix/HeatmapMatrix.svelte +0 -1527
- package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +0 -110
- package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +0 -225
- package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +0 -30
- package/dist/heatmap-matrix/index.d.ts +0 -53
- package/dist/heatmap-matrix/index.js +0 -100
- package/dist/heatmap-matrix/shared.d.ts +0 -2
- package/dist/heatmap-matrix/shared.js +0 -4
- package/dist/icons.d.ts +0 -569
- package/dist/icons.js +0 -648
- package/dist/index.d.ts +0 -39
- package/dist/index.js +0 -39
- package/dist/io/decompress.d.ts +0 -10
- package/dist/io/decompress.js +0 -74
- package/dist/io/export.d.ts +0 -16
- package/dist/io/export.js +0 -316
- package/dist/io/fetch.d.ts +0 -5
- package/dist/io/fetch.js +0 -39
- package/dist/io/file-drop.d.ts +0 -7
- package/dist/io/file-drop.js +0 -43
- package/dist/io/index.d.ts +0 -7
- package/dist/io/index.js +0 -7
- package/dist/io/is-binary.d.ts +0 -1
- package/dist/io/is-binary.js +0 -20
- package/dist/io/types.d.ts +0 -8
- package/dist/io/types.js +0 -1
- package/dist/io/url-drop.d.ts +0 -2
- package/dist/io/url-drop.js +0 -117
- package/dist/isosurface/Isosurface.svelte +0 -285
- package/dist/isosurface/Isosurface.svelte.d.ts +0 -8
- package/dist/isosurface/IsosurfaceControls.svelte +0 -291
- package/dist/isosurface/IsosurfaceControls.svelte.d.ts +0 -9
- package/dist/isosurface/index.d.ts +0 -5
- package/dist/isosurface/index.js +0 -6
- package/dist/isosurface/parse.d.ts +0 -6
- package/dist/isosurface/parse.js +0 -553
- package/dist/isosurface/slice.d.ts +0 -11
- package/dist/isosurface/slice.js +0 -140
- package/dist/isosurface/types.d.ts +0 -56
- package/dist/isosurface/types.js +0 -227
- package/dist/labels.d.ts +0 -53
- package/dist/labels.js +0 -274
- package/dist/layout/FullscreenToggle.svelte +0 -50
- package/dist/layout/FullscreenToggle.svelte.d.ts +0 -7
- package/dist/layout/InfoCard.svelte +0 -120
- package/dist/layout/InfoCard.svelte.d.ts +0 -21
- package/dist/layout/InfoTag.svelte +0 -183
- package/dist/layout/InfoTag.svelte.d.ts +0 -19
- package/dist/layout/PropertyFilter.svelte +0 -244
- package/dist/layout/PropertyFilter.svelte.d.ts +0 -24
- package/dist/layout/SettingsSection.svelte +0 -148
- package/dist/layout/SettingsSection.svelte.d.ts +0 -17
- package/dist/layout/SubpageGrid.svelte +0 -82
- package/dist/layout/SubpageGrid.svelte.d.ts +0 -14
- package/dist/layout/fullscreen.d.ts +0 -9
- package/dist/layout/fullscreen.js +0 -53
- package/dist/layout/index.d.ts +0 -10
- package/dist/layout/index.js +0 -8
- package/dist/layout/json-tree/JsonNode.svelte +0 -548
- package/dist/layout/json-tree/JsonNode.svelte.d.ts +0 -11
- package/dist/layout/json-tree/JsonTree.svelte +0 -1222
- package/dist/layout/json-tree/JsonTree.svelte.d.ts +0 -6
- package/dist/layout/json-tree/JsonValue.svelte +0 -334
- package/dist/layout/json-tree/JsonValue.svelte.d.ts +0 -9
- package/dist/layout/json-tree/index.d.ts +0 -3
- package/dist/layout/json-tree/index.js +0 -3
- package/dist/layout/json-tree/types.d.ts +0 -73
- package/dist/layout/json-tree/types.js +0 -3
- package/dist/layout/json-tree/utils.d.ts +0 -29
- package/dist/layout/json-tree/utils.js +0 -649
- package/dist/marching-cubes.d.ts +0 -14
- package/dist/marching-cubes.js +0 -542
- package/dist/math.d.ts +0 -91
- package/dist/math.js +0 -896
- package/dist/overlays/ContextMenu.svelte +0 -162
- package/dist/overlays/ContextMenu.svelte.d.ts +0 -25
- package/dist/overlays/CopyButton.svelte +0 -45
- package/dist/overlays/CopyButton.svelte.d.ts +0 -8
- package/dist/overlays/DraggablePane.svelte +0 -564
- package/dist/overlays/DraggablePane.svelte.d.ts +0 -36
- package/dist/overlays/InfoPaneCards.svelte +0 -149
- package/dist/overlays/InfoPaneCards.svelte.d.ts +0 -22
- package/dist/overlays/index.d.ts +0 -2
- package/dist/overlays/index.js +0 -2
- package/dist/periodic-table/PeriodicTable.svelte +0 -469
- package/dist/periodic-table/PeriodicTable.svelte.d.ts +0 -55
- package/dist/periodic-table/PeriodicTableControls.svelte +0 -557
- package/dist/periodic-table/PeriodicTableControls.svelte.d.ts +0 -24
- package/dist/periodic-table/PropertySelect.svelte +0 -37
- package/dist/periodic-table/PropertySelect.svelte.d.ts +0 -13
- package/dist/periodic-table/TableInset.svelte.d.ts +0 -9
- package/dist/periodic-table/index.d.ts +0 -10
- package/dist/periodic-table/index.js +0 -4
- package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +0 -1084
- package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +0 -44
- package/dist/phase-diagram/PhaseDiagramControls.svelte +0 -449
- package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +0 -30
- package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +0 -126
- package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +0 -15
- package/dist/phase-diagram/PhaseDiagramExportPane.svelte +0 -192
- package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +0 -19
- package/dist/phase-diagram/PhaseDiagramTooltip.svelte +0 -392
- package/dist/phase-diagram/PhaseDiagramTooltip.svelte.d.ts +0 -16
- package/dist/phase-diagram/TdbInfoPanel.svelte +0 -203
- package/dist/phase-diagram/TdbInfoPanel.svelte.d.ts +0 -12
- package/dist/phase-diagram/build-diagram.d.ts +0 -11
- package/dist/phase-diagram/build-diagram.js +0 -167
- package/dist/phase-diagram/colors.d.ts +0 -35
- package/dist/phase-diagram/colors.js +0 -51
- package/dist/phase-diagram/diagram-input.d.ts +0 -33
- package/dist/phase-diagram/diagram-input.js +0 -3
- package/dist/phase-diagram/index.d.ts +0 -13
- package/dist/phase-diagram/index.js +0 -13
- package/dist/phase-diagram/parse.d.ts +0 -55
- package/dist/phase-diagram/parse.js +0 -276
- package/dist/phase-diagram/svg-to-diagram.d.ts +0 -2
- package/dist/phase-diagram/svg-to-diagram.js +0 -867
- package/dist/phase-diagram/types.d.ts +0 -99
- package/dist/phase-diagram/types.js +0 -1
- package/dist/phase-diagram/utils.d.ts +0 -118
- package/dist/phase-diagram/utils.js +0 -606
- package/dist/plot/AxisLabel.svelte +0 -51
- package/dist/plot/AxisLabel.svelte.d.ts +0 -16
- package/dist/plot/BarPlot.svelte +0 -2265
- package/dist/plot/BarPlot.svelte.d.ts +0 -83
- package/dist/plot/BarPlotControls.svelte +0 -66
- package/dist/plot/BarPlotControls.svelte.d.ts +0 -18
- package/dist/plot/ColorBar.svelte +0 -719
- package/dist/plot/ColorBar.svelte.d.ts +0 -31
- package/dist/plot/ColorScaleSelect.svelte +0 -54
- package/dist/plot/ColorScaleSelect.svelte.d.ts +0 -15
- package/dist/plot/ElementScatter.svelte +0 -63
- package/dist/plot/ElementScatter.svelte.d.ts +0 -14
- package/dist/plot/FillArea.svelte +0 -225
- package/dist/plot/FillArea.svelte.d.ts +0 -21
- package/dist/plot/Histogram.svelte +0 -1672
- package/dist/plot/Histogram.svelte.d.ts +0 -50
- package/dist/plot/HistogramControls.svelte +0 -212
- package/dist/plot/HistogramControls.svelte.d.ts +0 -22
- package/dist/plot/InteractiveAxisLabel.svelte +0 -94
- package/dist/plot/InteractiveAxisLabel.svelte.d.ts +0 -14
- package/dist/plot/Line.svelte +0 -84
- package/dist/plot/Line.svelte.d.ts +0 -15
- package/dist/plot/PlotControls.svelte +0 -537
- package/dist/plot/PlotControls.svelte.d.ts +0 -4
- package/dist/plot/PlotLegend.svelte +0 -569
- package/dist/plot/PlotLegend.svelte.d.ts +0 -29
- package/dist/plot/PlotTooltip.svelte +0 -67
- package/dist/plot/PlotTooltip.svelte.d.ts +0 -17
- package/dist/plot/PortalSelect.svelte +0 -253
- package/dist/plot/PortalSelect.svelte.d.ts +0 -16
- package/dist/plot/ReferenceLine.svelte.d.ts +0 -20
- package/dist/plot/ReferenceLine3D.svelte +0 -154
- package/dist/plot/ReferenceLine3D.svelte.d.ts +0 -14
- package/dist/plot/ReferencePlane.svelte +0 -178
- package/dist/plot/ReferencePlane.svelte.d.ts +0 -14
- package/dist/plot/ScatterPlot.svelte +0 -2845
- package/dist/plot/ScatterPlot.svelte.d.ts +0 -93
- package/dist/plot/ScatterPlot3D.svelte +0 -502
- package/dist/plot/ScatterPlot3D.svelte.d.ts +0 -94
- package/dist/plot/ScatterPlot3DControls.svelte +0 -437
- package/dist/plot/ScatterPlot3DControls.svelte.d.ts +0 -20
- package/dist/plot/ScatterPlot3DScene.svelte +0 -912
- package/dist/plot/ScatterPlot3DScene.svelte.d.ts +0 -74
- package/dist/plot/ScatterPlotControls.svelte +0 -307
- package/dist/plot/ScatterPlotControls.svelte.d.ts +0 -17
- package/dist/plot/ScatterPoint.svelte +0 -191
- package/dist/plot/ScatterPoint.svelte.d.ts +0 -21
- package/dist/plot/SpacegroupBarPlot.svelte +0 -293
- package/dist/plot/SpacegroupBarPlot.svelte.d.ts +0 -9
- package/dist/plot/Surface3D.svelte +0 -200
- package/dist/plot/Surface3D.svelte.d.ts +0 -13
- package/dist/plot/ZeroLines.svelte +0 -96
- package/dist/plot/ZeroLines.svelte.d.ts +0 -32
- package/dist/plot/ZoomRect.svelte +0 -23
- package/dist/plot/ZoomRect.svelte.d.ts +0 -8
- package/dist/plot/axis-utils.d.ts +0 -19
- package/dist/plot/axis-utils.js +0 -80
- package/dist/plot/data-cleaning.d.ts +0 -37
- package/dist/plot/data-cleaning.js +0 -855
- package/dist/plot/data-transform.d.ts +0 -16
- package/dist/plot/data-transform.js +0 -45
- package/dist/plot/defaults.d.ts +0 -19
- package/dist/plot/defaults.js +0 -9
- package/dist/plot/fill-utils.d.ts +0 -51
- package/dist/plot/fill-utils.js +0 -337
- package/dist/plot/hover-lock.svelte.d.ts +0 -14
- package/dist/plot/hover-lock.svelte.js +0 -46
- package/dist/plot/index.d.ts +0 -37
- package/dist/plot/index.js +0 -37
- package/dist/plot/interactions.d.ts +0 -12
- package/dist/plot/interactions.js +0 -100
- package/dist/plot/layout.d.ts +0 -60
- package/dist/plot/layout.js +0 -230
- package/dist/plot/reference-line.d.ts +0 -60
- package/dist/plot/reference-line.js +0 -316
- package/dist/plot/scales.d.ts +0 -48
- package/dist/plot/scales.js +0 -484
- package/dist/plot/svg.d.ts +0 -1
- package/dist/plot/svg.js +0 -11
- package/dist/plot/types.d.ts +0 -859
- package/dist/plot/types.js +0 -103
- package/dist/plot/utils/label-placement.d.ts +0 -47
- package/dist/plot/utils/label-placement.js +0 -256
- package/dist/plot/utils/series-visibility.d.ts +0 -9
- package/dist/plot/utils/series-visibility.js +0 -67
- package/dist/plot/utils.d.ts +0 -1
- package/dist/plot/utils.js +0 -14
- package/dist/rdf/RdfPlot.svelte +0 -247
- package/dist/rdf/RdfPlot.svelte.d.ts +0 -27
- package/dist/rdf/calc-rdf.d.ts +0 -4
- package/dist/rdf/calc-rdf.js +0 -111
- package/dist/rdf/index.d.ts +0 -23
- package/dist/rdf/index.js +0 -2
- package/dist/sanitize.d.ts +0 -4
- package/dist/sanitize.js +0 -114
- package/dist/settings.d.ts +0 -255
- package/dist/settings.js +0 -1132
- package/dist/spectral/Bands.svelte +0 -1040
- package/dist/spectral/Bands.svelte.d.ts +0 -40
- package/dist/spectral/BandsAndDos.svelte +0 -128
- package/dist/spectral/BandsAndDos.svelte.d.ts +0 -18
- package/dist/spectral/BrillouinBandsDos.svelte +0 -248
- package/dist/spectral/BrillouinBandsDos.svelte.d.ts +0 -20
- package/dist/spectral/Dos.svelte +0 -697
- package/dist/spectral/Dos.svelte.d.ts +0 -29
- package/dist/spectral/helpers.d.ts +0 -117
- package/dist/spectral/helpers.js +0 -1023
- package/dist/spectral/index.d.ts +0 -6
- package/dist/spectral/index.js +0 -7
- package/dist/spectral/types.d.ts +0 -84
- package/dist/spectral/types.js +0 -2
- package/dist/state.svelte.d.ts +0 -25
- package/dist/state.svelte.js +0 -45
- package/dist/structure/Arrow.svelte +0 -72
- package/dist/structure/Arrow.svelte.d.ts +0 -15
- package/dist/structure/AtomLegend.svelte +0 -798
- package/dist/structure/AtomLegend.svelte.d.ts +0 -34
- package/dist/structure/Bond.svelte +0 -140
- package/dist/structure/Bond.svelte.d.ts +0 -9
- package/dist/structure/CanvasTooltip.svelte +0 -33
- package/dist/structure/CanvasTooltip.svelte.d.ts +0 -12
- package/dist/structure/CellSelect.svelte +0 -351
- package/dist/structure/CellSelect.svelte.d.ts +0 -13
- package/dist/structure/Cylinder.svelte +0 -45
- package/dist/structure/Cylinder.svelte.d.ts +0 -10
- package/dist/structure/Lattice.svelte +0 -196
- package/dist/structure/Lattice.svelte.d.ts +0 -17
- package/dist/structure/Structure.svelte +0 -1999
- package/dist/structure/Structure.svelte.d.ts +0 -87
- package/dist/structure/StructureControls.svelte +0 -1298
- package/dist/structure/StructureControls.svelte.d.ts +0 -31
- package/dist/structure/StructureExportPane.svelte +0 -251
- package/dist/structure/StructureExportPane.svelte.d.ts +0 -17
- package/dist/structure/StructureInfoPane.svelte +0 -735
- package/dist/structure/StructureInfoPane.svelte.d.ts +0 -19
- package/dist/structure/StructureScene.svelte +0 -1905
- package/dist/structure/StructureScene.svelte.d.ts +0 -108
- package/dist/structure/atom-properties.d.ts +0 -37
- package/dist/structure/atom-properties.js +0 -200
- package/dist/structure/bond-order-perception.d.ts +0 -13
- package/dist/structure/bond-order-perception.js +0 -367
- package/dist/structure/bonding.d.ts +0 -42
- package/dist/structure/bonding.js +0 -525
- package/dist/structure/export.d.ts +0 -20
- package/dist/structure/export.js +0 -727
- package/dist/structure/index.d.ts +0 -125
- package/dist/structure/index.js +0 -171
- package/dist/structure/label-placement.d.ts +0 -14
- package/dist/structure/label-placement.js +0 -72
- package/dist/structure/measure.d.ts +0 -6
- package/dist/structure/measure.js +0 -29
- package/dist/structure/parse.d.ts +0 -66
- package/dist/structure/parse.js +0 -1363
- package/dist/structure/partial-occupancy.d.ts +0 -25
- package/dist/structure/partial-occupancy.js +0 -99
- package/dist/structure/pbc.d.ts +0 -9
- package/dist/structure/pbc.js +0 -123
- package/dist/structure/supercell.d.ts +0 -8
- package/dist/structure/supercell.js +0 -170
- package/dist/structure/validation.d.ts +0 -2
- package/dist/structure/validation.js +0 -10
- package/dist/symmetry/SymmetryStats.svelte +0 -226
- package/dist/symmetry/SymmetryStats.svelte.d.ts +0 -21
- package/dist/symmetry/WyckoffTable.svelte +0 -113
- package/dist/symmetry/WyckoffTable.svelte.d.ts +0 -11
- package/dist/symmetry/cell-transform.d.ts +0 -12
- package/dist/symmetry/cell-transform.js +0 -91
- package/dist/symmetry/index.d.ts +0 -43
- package/dist/symmetry/index.js +0 -229
- package/dist/symmetry/spacegroups.d.ts +0 -9
- package/dist/symmetry/spacegroups.js +0 -394
- package/dist/table/HeatmapTable.svelte +0 -1854
- package/dist/table/HeatmapTable.svelte.d.ts +0 -49
- package/dist/table/ToggleMenu.svelte +0 -376
- package/dist/table/ToggleMenu.svelte.d.ts +0 -11
- package/dist/table/index.d.ts +0 -74
- package/dist/table/index.js +0 -38
- package/dist/theme/ThemeControl.svelte +0 -53
- package/dist/theme/ThemeControl.svelte.d.ts +0 -9
- package/dist/theme/index.d.ts +0 -29
- package/dist/theme/index.js +0 -79
- package/dist/theme/themes.mjs +0 -285
- package/dist/time.d.ts +0 -4
- package/dist/time.js +0 -70
- package/dist/tooltip/TooltipContent.svelte +0 -58
- package/dist/tooltip/TooltipContent.svelte.d.ts +0 -31
- package/dist/tooltip/index.d.ts +0 -2
- package/dist/tooltip/index.js +0 -2
- package/dist/tooltip/types.d.ts +0 -8
- package/dist/tooltip/types.js +0 -1
- package/dist/trajectory/Trajectory.svelte +0 -1517
- package/dist/trajectory/Trajectory.svelte.d.ts +0 -77
- package/dist/trajectory/TrajectoryError.svelte +0 -128
- package/dist/trajectory/TrajectoryError.svelte.d.ts +0 -13
- package/dist/trajectory/TrajectoryExportPane.svelte +0 -357
- package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +0 -17
- package/dist/trajectory/TrajectoryInfoPane.svelte +0 -313
- package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +0 -17
- package/dist/trajectory/constants.d.ts +0 -6
- package/dist/trajectory/constants.js +0 -7
- package/dist/trajectory/extract.d.ts +0 -5
- package/dist/trajectory/extract.js +0 -162
- package/dist/trajectory/format-detect.d.ts +0 -9
- package/dist/trajectory/format-detect.js +0 -76
- package/dist/trajectory/frame-reader.d.ts +0 -17
- package/dist/trajectory/frame-reader.js +0 -332
- package/dist/trajectory/helpers.d.ts +0 -14
- package/dist/trajectory/helpers.js +0 -172
- package/dist/trajectory/index.d.ts +0 -63
- package/dist/trajectory/index.js +0 -126
- package/dist/trajectory/parse/ase.d.ts +0 -2
- package/dist/trajectory/parse/ase.js +0 -73
- package/dist/trajectory/parse/hdf5.d.ts +0 -2
- package/dist/trajectory/parse/hdf5.js +0 -127
- package/dist/trajectory/parse/index.d.ts +0 -12
- package/dist/trajectory/parse/index.js +0 -299
- package/dist/trajectory/parse/lammps.d.ts +0 -5
- package/dist/trajectory/parse/lammps.js +0 -179
- package/dist/trajectory/parse/vasp.d.ts +0 -2
- package/dist/trajectory/parse/vasp.js +0 -68
- package/dist/trajectory/parse/xyz.d.ts +0 -2
- package/dist/trajectory/parse/xyz.js +0 -110
- package/dist/trajectory/plotting.d.ts +0 -28
- package/dist/trajectory/plotting.js +0 -423
- package/dist/trajectory/types.d.ts +0 -11
- package/dist/trajectory/types.js +0 -1
- package/dist/utils.d.ts +0 -5
- package/dist/utils.js +0 -36
- package/dist/xrd/XrdPlot.svelte +0 -615
- package/dist/xrd/XrdPlot.svelte.d.ts +0 -28
- package/dist/xrd/broadening.d.ts +0 -20
- package/dist/xrd/broadening.js +0 -97
- package/dist/xrd/calc-xrd.d.ts +0 -37
- package/dist/xrd/calc-xrd.js +0 -337
- package/dist/xrd/index.d.ts +0 -37
- package/dist/xrd/index.js +0 -4
- package/dist/xrd/parse.d.ts +0 -13
- package/dist/xrd/parse.js +0 -749
- /package/dist/{EmptyState.svelte → src/lib/EmptyState.svelte} +0 -0
- /package/dist/{Icon.svelte → src/lib/Icon.svelte} +0 -0
- /package/dist/{app.css → src/lib/app.css} +0 -0
- /package/dist/{chempot-diagram → src/lib/chempot-diagram}/ChemPotScene3D.svelte +0 -0
- /package/dist/{colors → src/lib/colors}/alloy-colors.json +0 -0
- /package/dist/{colors → src/lib/colors}/dark-mode-colors.json +0 -0
- /package/dist/{colors → src/lib/colors}/jmol-colors.json +0 -0
- /package/dist/{colors → src/lib/colors}/muted-colors.json +0 -0
- /package/dist/{colors → src/lib/colors}/pastel-colors.json +0 -0
- /package/dist/{colors → src/lib/colors}/vesta-colors.json +0 -0
- /package/dist/{element → src/lib/element}/Nucleus.svelte +0 -0
- /package/dist/{element → src/lib/element}/data.json +0 -0
- /package/dist/{element → src/lib/element}/data.json.gz +0 -0
- /package/dist/{element → src/lib/element}/data.schema.json +0 -0
- /package/dist/{element-image-urls.json → src/lib/element-image-urls.json} +0 -0
- /package/dist/{feedback → src/lib/feedback}/Spinner.svelte +0 -0
- /package/dist/{feedback → src/lib/feedback}/StatusMessage.svelte +0 -0
- /package/dist/{periodic-table → src/lib/periodic-table}/TableInset.svelte +0 -0
- /package/dist/{plot → src/lib/plot}/ReferenceLine.svelte +0 -0
- /package/dist/{xrd → src/lib/xrd}/atomic_scattering_params.json +0 -0
|
@@ -0,0 +1,1069 @@
|
|
|
1
|
+
// Data cleaning utilities for plot data
|
|
2
|
+
// Detects oscillations, enforces physical bounds, and handles multi-dimensional datasets
|
|
3
|
+
|
|
4
|
+
import { apply_gaussian_smearing } from '$lib/spectral/helpers'
|
|
5
|
+
import type {
|
|
6
|
+
CleaningConfig,
|
|
7
|
+
CleaningQuality,
|
|
8
|
+
CleaningResult,
|
|
9
|
+
DataSeries,
|
|
10
|
+
InstabilityResult,
|
|
11
|
+
InvalidValueMode,
|
|
12
|
+
LocalOutlierConfig,
|
|
13
|
+
LocalOutlierResult,
|
|
14
|
+
PhysicalBounds,
|
|
15
|
+
SmoothingConfig,
|
|
16
|
+
} from './types'
|
|
17
|
+
|
|
18
|
+
// Default configuration values
|
|
19
|
+
const DEFAULT_WINDOW_SIZE = 5
|
|
20
|
+
const DEFAULT_OSCILLATION_THRESHOLD = 3.0
|
|
21
|
+
const DEFAULT_POLYNOMIAL_ORDER = 2
|
|
22
|
+
|
|
23
|
+
// --- Core Detection Functions ---
|
|
24
|
+
|
|
25
|
+
// Compute rolling variance using Welford's online algorithm - O(n)
|
|
26
|
+
// Returns variance for each point based on surrounding window
|
|
27
|
+
export function compute_local_variance(values: number[], window_size: number): number[] {
|
|
28
|
+
const len = values.length
|
|
29
|
+
if (len === 0) return []
|
|
30
|
+
if (len === 1) return [0]
|
|
31
|
+
|
|
32
|
+
const half_window = Math.floor(window_size / 2)
|
|
33
|
+
const result: number[] = Array(len)
|
|
34
|
+
|
|
35
|
+
// Single pass for each index, no slice allocation (avoids O(n × window) allocations)
|
|
36
|
+
for (let idx = 0; idx < len; idx++) {
|
|
37
|
+
const start = Math.max(0, idx - half_window)
|
|
38
|
+
const end = Math.min(len, idx + half_window + 1)
|
|
39
|
+
|
|
40
|
+
// Welford's online variance calculation
|
|
41
|
+
let [mean, m2, count] = [0, 0, 0]
|
|
42
|
+
for (let jdx = start; jdx < end; jdx++) {
|
|
43
|
+
const val = values[jdx]
|
|
44
|
+
if (!Number.isFinite(val)) continue
|
|
45
|
+
count++
|
|
46
|
+
const delta = val - mean
|
|
47
|
+
mean += delta / count
|
|
48
|
+
const delta2 = val - mean
|
|
49
|
+
m2 += delta * delta2
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
result[idx] = count > 1 ? m2 / (count - 1) : 0
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return result
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Compute first-order finite differences (discrete derivative)
|
|
59
|
+
function compute_derivatives(values: number[]): number[] {
|
|
60
|
+
if (values.length < 2) return []
|
|
61
|
+
const derivs: number[] = Array(values.length - 1)
|
|
62
|
+
for (let idx = 0; idx < values.length - 1; idx++) {
|
|
63
|
+
derivs[idx] = values[idx + 1] - values[idx]
|
|
64
|
+
}
|
|
65
|
+
return derivs
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Detect derivative variance spikes (method 1)
|
|
69
|
+
// Returns onset index where derivative variance exceeds threshold
|
|
70
|
+
function detect_derivative_variance(
|
|
71
|
+
values: number[],
|
|
72
|
+
window_size: number,
|
|
73
|
+
threshold_multiplier: number,
|
|
74
|
+
): { onset_index: number; score: number } {
|
|
75
|
+
const derivs = compute_derivatives(values)
|
|
76
|
+
if (derivs.length < window_size) {
|
|
77
|
+
return { onset_index: -1, score: 0 }
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const local_var = compute_local_variance(derivs, window_size)
|
|
81
|
+
|
|
82
|
+
// Compute baseline variance from first stable portion
|
|
83
|
+
const baseline_end = Math.min(Math.floor(derivs.length / 4), 50)
|
|
84
|
+
const baseline_vars = local_var.slice(0, Math.max(baseline_end, window_size))
|
|
85
|
+
const baseline_median = median(baseline_vars.filter((val) => val > 0))
|
|
86
|
+
|
|
87
|
+
if (baseline_median === 0) {
|
|
88
|
+
return { onset_index: -1, score: 0 }
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Find first point where variance exceeds threshold
|
|
92
|
+
let max_score = 0
|
|
93
|
+
for (let idx = baseline_end; idx < local_var.length; idx++) {
|
|
94
|
+
const ratio = local_var[idx] / baseline_median
|
|
95
|
+
if (ratio > max_score) max_score = ratio
|
|
96
|
+
if (ratio > threshold_multiplier) {
|
|
97
|
+
return { onset_index: idx + 1, score: ratio } // +1 to convert from deriv index to value index
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return { onset_index: -1, score: max_score }
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Detect exponential amplitude growth (method 2)
|
|
105
|
+
// Looks for values growing exponentially from their mean
|
|
106
|
+
function detect_amplitude_growth(
|
|
107
|
+
values: number[],
|
|
108
|
+
window_size: number,
|
|
109
|
+
): { onset_index: number; score: number } {
|
|
110
|
+
if (values.length < window_size * 3) {
|
|
111
|
+
return { onset_index: -1, score: 0 }
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Compute running amplitude (deviation from local mean)
|
|
115
|
+
const amplitudes: number[] = []
|
|
116
|
+
const half_window = Math.floor(window_size / 2)
|
|
117
|
+
|
|
118
|
+
for (let idx = half_window; idx < values.length - half_window; idx++) {
|
|
119
|
+
const start = idx - half_window
|
|
120
|
+
const end = idx + half_window + 1
|
|
121
|
+
const window_len = end - start
|
|
122
|
+
|
|
123
|
+
// Compute local mean without slice allocation
|
|
124
|
+
let sum = 0
|
|
125
|
+
for (let jdx = start; jdx < end; jdx++) sum += values[jdx]
|
|
126
|
+
const local_mean = sum / window_len
|
|
127
|
+
|
|
128
|
+
// Find max deviation without slice allocation
|
|
129
|
+
let max_deviation = 0
|
|
130
|
+
for (let jdx = start; jdx < end; jdx++) {
|
|
131
|
+
const deviation = Math.abs(values[jdx] - local_mean)
|
|
132
|
+
if (deviation > max_deviation) max_deviation = deviation
|
|
133
|
+
}
|
|
134
|
+
amplitudes.push(max_deviation)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (amplitudes.length < 10) {
|
|
138
|
+
return { onset_index: -1, score: 0 }
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Detect exponential growth by checking if amplitude ratio increases
|
|
142
|
+
const baseline_amp = median(amplitudes.slice(0, Math.floor(amplitudes.length / 4)))
|
|
143
|
+
if (baseline_amp === 0) {
|
|
144
|
+
return { onset_index: -1, score: 0 }
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
let max_score = 0
|
|
148
|
+
for (let idx = Math.floor(amplitudes.length / 4); idx < amplitudes.length; idx++) {
|
|
149
|
+
const ratio = amplitudes[idx] / baseline_amp
|
|
150
|
+
if (ratio > max_score) max_score = ratio
|
|
151
|
+
|
|
152
|
+
// Exponential growth threshold: amplitude 10x baseline
|
|
153
|
+
if (ratio > 10) {
|
|
154
|
+
return { onset_index: idx + half_window, score: ratio / 10 }
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return { onset_index: -1, score: max_score / 10 }
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Count derivative sign changes per window (method 3)
|
|
162
|
+
// Detects high-frequency oscillations
|
|
163
|
+
function detect_sign_change_frequency(
|
|
164
|
+
values: number[],
|
|
165
|
+
window_size: number,
|
|
166
|
+
max_changes_per_window: number = 3,
|
|
167
|
+
): { onset_index: number; score: number } {
|
|
168
|
+
const derivs = compute_derivatives(values)
|
|
169
|
+
if (derivs.length < window_size * 2) {
|
|
170
|
+
return { onset_index: -1, score: 0 }
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Count sign changes in sliding windows
|
|
174
|
+
const half_window = Math.floor(window_size / 2)
|
|
175
|
+
let max_score = 0
|
|
176
|
+
|
|
177
|
+
for (let idx = half_window; idx < derivs.length - half_window; idx++) {
|
|
178
|
+
const start = idx - half_window
|
|
179
|
+
const end = idx + half_window + 1
|
|
180
|
+
let sign_changes = 0
|
|
181
|
+
|
|
182
|
+
// Count sign changes without slice allocation
|
|
183
|
+
for (let jdx = start + 1; jdx < end; jdx++) {
|
|
184
|
+
if (derivs[jdx] * derivs[jdx - 1] < 0) {
|
|
185
|
+
sign_changes++
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const normalized_score = sign_changes / max_changes_per_window
|
|
190
|
+
if (normalized_score > max_score) max_score = normalized_score
|
|
191
|
+
|
|
192
|
+
if (sign_changes > max_changes_per_window) {
|
|
193
|
+
return { onset_index: idx + 1, score: normalized_score }
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return { onset_index: -1, score: max_score }
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Combined detection with configurable weights
|
|
201
|
+
export function detect_instability(
|
|
202
|
+
x_values: readonly number[],
|
|
203
|
+
y_values: readonly number[],
|
|
204
|
+
config: Pick<
|
|
205
|
+
CleaningConfig,
|
|
206
|
+
`oscillation_weights` | `oscillation_threshold` | `window_size`
|
|
207
|
+
> = {},
|
|
208
|
+
): InstabilityResult {
|
|
209
|
+
const window_size = config.window_size ?? DEFAULT_WINDOW_SIZE
|
|
210
|
+
const threshold = config.oscillation_threshold ?? DEFAULT_OSCILLATION_THRESHOLD
|
|
211
|
+
const weights = {
|
|
212
|
+
derivative_variance: config.oscillation_weights?.derivative_variance ?? 1.0,
|
|
213
|
+
amplitude_growth: config.oscillation_weights?.amplitude_growth ?? 1.0,
|
|
214
|
+
sign_changes: config.oscillation_weights?.sign_changes ?? 1.0,
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Filter out invalid values for detection
|
|
218
|
+
const valid_indices: number[] = []
|
|
219
|
+
const valid_y: number[] = []
|
|
220
|
+
for (let idx = 0; idx < y_values.length; idx++) {
|
|
221
|
+
if (Number.isFinite(y_values[idx])) {
|
|
222
|
+
valid_indices.push(idx)
|
|
223
|
+
valid_y.push(y_values[idx])
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (valid_y.length < window_size * 2) {
|
|
228
|
+
const method_scores = { derivative_variance: 0, amplitude_growth: 0, sign_changes: 0 }
|
|
229
|
+
const detected = false
|
|
230
|
+
return { detected, onset_index: -1, onset_x: NaN, combined_score: 0, method_scores }
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Run all three detection methods
|
|
234
|
+
const deriv_result = detect_derivative_variance(valid_y, window_size, threshold)
|
|
235
|
+
const amp_result = detect_amplitude_growth(valid_y, window_size)
|
|
236
|
+
const sign_result = detect_sign_change_frequency(valid_y, window_size)
|
|
237
|
+
|
|
238
|
+
const method_scores = {
|
|
239
|
+
derivative_variance: deriv_result.score,
|
|
240
|
+
amplitude_growth: amp_result.score,
|
|
241
|
+
sign_changes: sign_result.score,
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Compute weighted combined score
|
|
245
|
+
const total_weight =
|
|
246
|
+
weights.derivative_variance + weights.amplitude_growth + weights.sign_changes
|
|
247
|
+
const combined_score =
|
|
248
|
+
total_weight > 0
|
|
249
|
+
? (weights.derivative_variance * deriv_result.score +
|
|
250
|
+
weights.amplitude_growth * amp_result.score +
|
|
251
|
+
weights.sign_changes * sign_result.score) /
|
|
252
|
+
total_weight
|
|
253
|
+
: 0
|
|
254
|
+
|
|
255
|
+
// Find earliest onset across all methods that exceeded threshold
|
|
256
|
+
const onset_candidates = [
|
|
257
|
+
{
|
|
258
|
+
idx: deriv_result.onset_index,
|
|
259
|
+
score: deriv_result.score * weights.derivative_variance,
|
|
260
|
+
},
|
|
261
|
+
{ idx: amp_result.onset_index, score: amp_result.score * weights.amplitude_growth },
|
|
262
|
+
{ idx: sign_result.onset_index, score: sign_result.score * weights.sign_changes },
|
|
263
|
+
].filter((candidate) => candidate.idx >= 0)
|
|
264
|
+
|
|
265
|
+
let onset_index = -1
|
|
266
|
+
if (onset_candidates.length > 0) {
|
|
267
|
+
// Take earliest detected onset
|
|
268
|
+
onset_index = Math.min(...onset_candidates.map((candidate) => candidate.idx))
|
|
269
|
+
// Map back to original index if we filtered values
|
|
270
|
+
if (onset_index >= 0 && onset_index < valid_indices.length) {
|
|
271
|
+
onset_index = valid_indices[onset_index]
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const detected = combined_score >= threshold || onset_index >= 0
|
|
276
|
+
const onset_x =
|
|
277
|
+
onset_index >= 0 && onset_index < x_values.length ? x_values[onset_index] : NaN
|
|
278
|
+
|
|
279
|
+
return { detected, onset_index, onset_x, combined_score, method_scores }
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// --- Smoothing Functions ---
|
|
283
|
+
|
|
284
|
+
// Moving average - O(n)
|
|
285
|
+
export function smooth_moving_average(values: number[], window: number): number[] {
|
|
286
|
+
if (values.length === 0 || window <= 1) return [...values]
|
|
287
|
+
|
|
288
|
+
const result: number[] = Array(values.length)
|
|
289
|
+
const half_window = Math.floor(window / 2)
|
|
290
|
+
|
|
291
|
+
for (let idx = 0; idx < values.length; idx++) {
|
|
292
|
+
const start = Math.max(0, idx - half_window)
|
|
293
|
+
const end = Math.min(values.length, idx + half_window + 1)
|
|
294
|
+
let [sum, count] = [0, 0]
|
|
295
|
+
|
|
296
|
+
for (let jdx = start; jdx < end; jdx++) {
|
|
297
|
+
if (Number.isFinite(values[jdx])) {
|
|
298
|
+
sum += values[jdx]
|
|
299
|
+
count++
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
result[idx] = count > 0 ? sum / count : values[idx]
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
return result
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// Savitzky-Golay filter coefficients for polynomial smoothing
|
|
310
|
+
// Uses least-squares polynomial fitting in each window
|
|
311
|
+
function compute_savgol_coefficients(window: number, order: number): number[] {
|
|
312
|
+
// Ensure window is odd
|
|
313
|
+
const half = Math.floor(window / 2)
|
|
314
|
+
const size = 2 * half + 1
|
|
315
|
+
|
|
316
|
+
// Build Vandermonde matrix for polynomial fitting
|
|
317
|
+
const vandermonde: number[][] = []
|
|
318
|
+
for (let idx = -half; idx <= half; idx++) {
|
|
319
|
+
const row: number[] = []
|
|
320
|
+
for (let power = 0; power <= order; power++) {
|
|
321
|
+
row.push(Math.pow(idx, power))
|
|
322
|
+
}
|
|
323
|
+
vandermonde.push(row)
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// Compute (V^T V)^-1 V^T using simple pseudoinverse
|
|
327
|
+
// For smoothing, we only need the first row (constant term coefficients)
|
|
328
|
+
const vtv = multiply_matrices(transpose(vandermonde), vandermonde)
|
|
329
|
+
const vtv_inv = invert_matrix(vtv)
|
|
330
|
+
if (!vtv_inv) {
|
|
331
|
+
// Fallback to uniform weights
|
|
332
|
+
return Array(size).fill(1 / size)
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
const vt = transpose(vandermonde)
|
|
336
|
+
const coeffs_matrix = multiply_matrices(vtv_inv, vt)
|
|
337
|
+
|
|
338
|
+
// First row gives smoothing coefficients
|
|
339
|
+
return coeffs_matrix[0]
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// Savitzky-Golay filter (derivative-preserving) - O(n * window)
|
|
343
|
+
export function smooth_savitzky_golay(
|
|
344
|
+
values: number[],
|
|
345
|
+
window: number,
|
|
346
|
+
polynomial_order: number = DEFAULT_POLYNOMIAL_ORDER,
|
|
347
|
+
): number[] {
|
|
348
|
+
if (values.length === 0) return []
|
|
349
|
+
|
|
350
|
+
// Ensure window is odd and >= polynomial_order + 1
|
|
351
|
+
let actual_window = window % 2 === 0 ? window + 1 : window
|
|
352
|
+
actual_window = Math.max(actual_window, polynomial_order + 2)
|
|
353
|
+
actual_window = Math.min(actual_window, values.length)
|
|
354
|
+
|
|
355
|
+
if (actual_window < 3) return [...values]
|
|
356
|
+
|
|
357
|
+
const coeffs = compute_savgol_coefficients(actual_window, polynomial_order)
|
|
358
|
+
const half = Math.floor(actual_window / 2)
|
|
359
|
+
const result: number[] = Array(values.length)
|
|
360
|
+
// Cache coefficient sum to avoid O(n × window) redundant reductions in loop
|
|
361
|
+
const coeffs_sum = coeffs.reduce((a, b) => a + b, 0)
|
|
362
|
+
|
|
363
|
+
for (let idx = 0; idx < values.length; idx++) {
|
|
364
|
+
let [sum, weight_sum] = [0, 0]
|
|
365
|
+
|
|
366
|
+
for (let jdx = 0; jdx < actual_window; jdx++) {
|
|
367
|
+
const data_idx = idx - half + jdx
|
|
368
|
+
if (data_idx >= 0 && data_idx < values.length && Number.isFinite(values[data_idx])) {
|
|
369
|
+
sum += coeffs[jdx] * values[data_idx]
|
|
370
|
+
weight_sum += coeffs[jdx]
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
result[idx] = weight_sum !== 0 ? (sum / weight_sum) * coeffs_sum : values[idx]
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
return result
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// Apply smoothing based on config
|
|
381
|
+
function apply_smoothing(
|
|
382
|
+
x_values: number[],
|
|
383
|
+
y_values: number[],
|
|
384
|
+
config: SmoothingConfig,
|
|
385
|
+
): number[] {
|
|
386
|
+
if (config.type === `moving_avg`) {
|
|
387
|
+
return smooth_moving_average(y_values, config.window)
|
|
388
|
+
} else if (config.type === `savgol`) {
|
|
389
|
+
return smooth_savitzky_golay(
|
|
390
|
+
y_values,
|
|
391
|
+
config.window,
|
|
392
|
+
config.polynomial_order ?? DEFAULT_POLYNOMIAL_ORDER,
|
|
393
|
+
)
|
|
394
|
+
} else if (config.type === `gaussian`) {
|
|
395
|
+
return apply_gaussian_smearing(x_values, y_values, config.sigma)
|
|
396
|
+
}
|
|
397
|
+
return y_values
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// --- Local Outlier Detection ---
|
|
401
|
+
|
|
402
|
+
// Default values for local outlier detection
|
|
403
|
+
const DEFAULT_LOCAL_WINDOW_HALF = 7
|
|
404
|
+
const DEFAULT_LOCAL_MAD_THRESHOLD = 2.0
|
|
405
|
+
const DEFAULT_LOCAL_MAX_ITERATIONS = 5
|
|
406
|
+
|
|
407
|
+
// Compute local median within a window, excluding the center point
|
|
408
|
+
// This allows detecting if the center point is an outlier relative to its neighbors
|
|
409
|
+
function compute_local_median_excluding_center(
|
|
410
|
+
values: number[],
|
|
411
|
+
center_idx: number,
|
|
412
|
+
window_half: number,
|
|
413
|
+
): number {
|
|
414
|
+
const window_values: number[] = []
|
|
415
|
+
const start = Math.max(0, center_idx - window_half)
|
|
416
|
+
const end = Math.min(values.length - 1, center_idx + window_half)
|
|
417
|
+
|
|
418
|
+
for (let idx = start; idx <= end; idx++) {
|
|
419
|
+
if (idx !== center_idx && Number.isFinite(values[idx])) {
|
|
420
|
+
window_values.push(values[idx])
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
if (window_values.length === 0) return values[center_idx]
|
|
425
|
+
return median(window_values)
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// Compute local MAD (median absolute deviation) within a window, excluding center
|
|
429
|
+
function compute_local_mad_excluding_center(
|
|
430
|
+
values: number[],
|
|
431
|
+
center_idx: number,
|
|
432
|
+
window_half: number,
|
|
433
|
+
local_median: number,
|
|
434
|
+
): number {
|
|
435
|
+
const abs_devs: number[] = []
|
|
436
|
+
const start = Math.max(0, center_idx - window_half)
|
|
437
|
+
const end = Math.min(values.length - 1, center_idx + window_half)
|
|
438
|
+
|
|
439
|
+
for (let idx = start; idx <= end; idx++) {
|
|
440
|
+
if (idx !== center_idx && Number.isFinite(values[idx])) {
|
|
441
|
+
abs_devs.push(Math.abs(values[idx] - local_median))
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
if (abs_devs.length === 0) return 0
|
|
446
|
+
return median(abs_devs)
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// Remove local outliers using iterative sliding window MAD-based detection
|
|
450
|
+
// Detects points that deviate significantly from their local neighborhood
|
|
451
|
+
// Returns only the indices to keep, preserving good data before AND after bad regions
|
|
452
|
+
export function remove_local_outliers(
|
|
453
|
+
y_values: readonly number[],
|
|
454
|
+
config: LocalOutlierConfig = {},
|
|
455
|
+
): LocalOutlierResult {
|
|
456
|
+
const window_half = config.window_half ?? DEFAULT_LOCAL_WINDOW_HALF
|
|
457
|
+
const mad_threshold = config.mad_threshold ?? DEFAULT_LOCAL_MAD_THRESHOLD
|
|
458
|
+
const max_iterations = config.max_iterations ?? DEFAULT_LOCAL_MAX_ITERATIONS
|
|
459
|
+
|
|
460
|
+
const len = y_values.length
|
|
461
|
+
if (len === 0) {
|
|
462
|
+
return { kept_indices: [], removed_indices: [], iterations_used: 0 }
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// Need enough neighbors for meaningful local statistics
|
|
466
|
+
const min_points_needed = window_half * 2 + 1
|
|
467
|
+
if (len < min_points_needed) {
|
|
468
|
+
return {
|
|
469
|
+
kept_indices: Array.from({ length: len }, (_, idx) => idx),
|
|
470
|
+
removed_indices: [],
|
|
471
|
+
iterations_used: 0,
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
let kept_mask = Array(len).fill(true)
|
|
476
|
+
let iterations_used = 0
|
|
477
|
+
|
|
478
|
+
for (let iter = 0; iter < max_iterations; iter++) {
|
|
479
|
+
let removed_any = false
|
|
480
|
+
const new_kept_mask = [...kept_mask]
|
|
481
|
+
// Note: Local statistics are computed from original values, not filtered values.
|
|
482
|
+
// This prevents cascading removals where one outlier's removal dramatically
|
|
483
|
+
// shifts statistics and causes false positives on neighboring points.
|
|
484
|
+
for (let idx = 0; idx < len; idx++) {
|
|
485
|
+
if (!kept_mask[idx]) continue // Already removed
|
|
486
|
+
if (!Number.isFinite(y_values[idx])) continue // Skip invalid values
|
|
487
|
+
|
|
488
|
+
const local_median = compute_local_median_excluding_center(
|
|
489
|
+
y_values as number[],
|
|
490
|
+
idx,
|
|
491
|
+
window_half,
|
|
492
|
+
)
|
|
493
|
+
const local_mad = compute_local_mad_excluding_center(
|
|
494
|
+
y_values as number[],
|
|
495
|
+
idx,
|
|
496
|
+
window_half,
|
|
497
|
+
local_median,
|
|
498
|
+
)
|
|
499
|
+
|
|
500
|
+
// Cannot compute robust threshold if MAD is zero (all neighbors identical)
|
|
501
|
+
if (local_mad === 0) continue
|
|
502
|
+
|
|
503
|
+
const threshold = local_mad * mad_threshold
|
|
504
|
+
const deviation = Math.abs(y_values[idx] - local_median)
|
|
505
|
+
|
|
506
|
+
if (deviation > threshold) {
|
|
507
|
+
new_kept_mask[idx] = false
|
|
508
|
+
removed_any = true
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
kept_mask = new_kept_mask
|
|
513
|
+
iterations_used = iter + 1
|
|
514
|
+
|
|
515
|
+
if (!removed_any) break
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
const kept_indices: number[] = []
|
|
519
|
+
const removed_indices: number[] = []
|
|
520
|
+
|
|
521
|
+
for (let idx = 0; idx < len; idx++) {
|
|
522
|
+
if (kept_mask[idx]) {
|
|
523
|
+
kept_indices.push(idx)
|
|
524
|
+
} else {
|
|
525
|
+
removed_indices.push(idx)
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
return { kept_indices, removed_indices, iterations_used }
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
// --- Helper Functions ---
|
|
533
|
+
|
|
534
|
+
// Handle NaN/Infinity based on mode
|
|
535
|
+
export function handle_invalid_values(
|
|
536
|
+
values: number[],
|
|
537
|
+
mode: InvalidValueMode,
|
|
538
|
+
): { cleaned: number[]; removed_indices: number[]; invalid_count: number } {
|
|
539
|
+
const removed_indices: number[] = []
|
|
540
|
+
let invalid_count = 0
|
|
541
|
+
|
|
542
|
+
if (mode === `propagate`) {
|
|
543
|
+
for (const val of values) {
|
|
544
|
+
if (!Number.isFinite(val)) invalid_count++
|
|
545
|
+
}
|
|
546
|
+
return { cleaned: [...values], removed_indices: [], invalid_count }
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
if (mode === `remove`) {
|
|
550
|
+
const cleaned: number[] = []
|
|
551
|
+
for (let idx = 0; idx < values.length; idx++) {
|
|
552
|
+
if (Number.isFinite(values[idx])) {
|
|
553
|
+
cleaned.push(values[idx])
|
|
554
|
+
} else {
|
|
555
|
+
removed_indices.push(idx)
|
|
556
|
+
invalid_count++
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
return { cleaned, removed_indices, invalid_count }
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
// Interpolate mode
|
|
563
|
+
const cleaned = [...values]
|
|
564
|
+
for (let idx = 0; idx < cleaned.length; idx++) {
|
|
565
|
+
if (!Number.isFinite(cleaned[idx])) {
|
|
566
|
+
invalid_count++
|
|
567
|
+
// Find nearest valid neighbors
|
|
568
|
+
let left_idx = idx - 1
|
|
569
|
+
while (left_idx >= 0 && !Number.isFinite(cleaned[left_idx])) left_idx--
|
|
570
|
+
|
|
571
|
+
let right_idx = idx + 1
|
|
572
|
+
while (right_idx < cleaned.length && !Number.isFinite(cleaned[right_idx])) {
|
|
573
|
+
right_idx++
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
if (left_idx >= 0 && right_idx < cleaned.length) {
|
|
577
|
+
// Linear interpolation
|
|
578
|
+
const t = (idx - left_idx) / (right_idx - left_idx)
|
|
579
|
+
cleaned[idx] = cleaned[left_idx] + t * (cleaned[right_idx] - cleaned[left_idx])
|
|
580
|
+
} else if (left_idx >= 0) {
|
|
581
|
+
cleaned[idx] = cleaned[left_idx]
|
|
582
|
+
} else if (right_idx < cleaned.length) {
|
|
583
|
+
cleaned[idx] = cleaned[right_idx]
|
|
584
|
+
} else {
|
|
585
|
+
cleaned[idx] = 0
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
return { cleaned, removed_indices: [], invalid_count }
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
// Apply physical bounds
|
|
594
|
+
export function apply_bounds(
|
|
595
|
+
x_values: readonly number[],
|
|
596
|
+
y_values: number[],
|
|
597
|
+
bounds: PhysicalBounds,
|
|
598
|
+
): { y: number[]; violations: number; filtered_indices: number[] } {
|
|
599
|
+
const result = [...y_values]
|
|
600
|
+
const filtered_indices: number[] = []
|
|
601
|
+
let violations = 0
|
|
602
|
+
|
|
603
|
+
for (let idx = 0; idx < result.length; idx++) {
|
|
604
|
+
const x_val = x_values[idx]
|
|
605
|
+
const y_val = result[idx]
|
|
606
|
+
|
|
607
|
+
const min_bound = typeof bounds.min === `function` ? bounds.min(x_val) : bounds.min
|
|
608
|
+
const max_bound = typeof bounds.max === `function` ? bounds.max(x_val) : bounds.max
|
|
609
|
+
|
|
610
|
+
let violated = false
|
|
611
|
+
if (min_bound !== undefined && y_val < min_bound) violated = true
|
|
612
|
+
if (max_bound !== undefined && y_val > max_bound) violated = true
|
|
613
|
+
|
|
614
|
+
if (violated) {
|
|
615
|
+
violations++
|
|
616
|
+
const mode = bounds.mode ?? `clamp`
|
|
617
|
+
|
|
618
|
+
if (mode === `clamp`) {
|
|
619
|
+
if (min_bound !== undefined && y_val < min_bound) result[idx] = min_bound
|
|
620
|
+
if (max_bound !== undefined && y_val > max_bound) result[idx] = max_bound
|
|
621
|
+
} else if (mode === `filter`) {
|
|
622
|
+
filtered_indices.push(idx)
|
|
623
|
+
} else if (mode === `null`) {
|
|
624
|
+
result[idx] = NaN
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
return { y: result, violations, filtered_indices }
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
// Sync metadata arrays with filtered data
|
|
633
|
+
export function sync_metadata<M>(
|
|
634
|
+
metadata: M[] | M | undefined,
|
|
635
|
+
kept_indices: number[],
|
|
636
|
+
): M[] | M | undefined {
|
|
637
|
+
if (metadata === undefined) return undefined
|
|
638
|
+
if (!Array.isArray(metadata)) return metadata // Scalar metadata unchanged
|
|
639
|
+
|
|
640
|
+
return kept_indices.map((idx) => metadata[idx])
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
// Filter arrays by kept indices
|
|
644
|
+
function filter_by_indices<T>(arr: readonly T[], kept_indices: number[]): T[] {
|
|
645
|
+
return kept_indices.map((idx) => arr[idx])
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
// Check if value is within bounds (static or x-dependent)
|
|
649
|
+
function is_in_bounds(val: number, x_val: number, bounds: PhysicalBounds): boolean {
|
|
650
|
+
const min = typeof bounds.min === `function` ? bounds.min(x_val) : bounds.min
|
|
651
|
+
const max = typeof bounds.max === `function` ? bounds.max(x_val) : bounds.max
|
|
652
|
+
if (min !== undefined && val < min) return false
|
|
653
|
+
if (max !== undefined && val > max) return false
|
|
654
|
+
return true
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
// Compute kept indices by excluding removed indices
|
|
658
|
+
function kept_indices_excluding(length: number, removed: number[]): number[] {
|
|
659
|
+
const removed_set = new Set(removed)
|
|
660
|
+
return Array.from({ length }, (_, idx) => idx).filter((idx) => !removed_set.has(idx))
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
// --- Main API ---
|
|
664
|
+
|
|
665
|
+
// Clean a single series - main entry point
|
|
666
|
+
export function clean_series<T extends DataSeries>(
|
|
667
|
+
series: T,
|
|
668
|
+
config: CleaningConfig = {},
|
|
669
|
+
): CleaningResult<T> {
|
|
670
|
+
const in_place = config.in_place ?? true
|
|
671
|
+
const invalid_mode = config.invalid_values ?? `remove`
|
|
672
|
+
const truncation_mode = config.truncation_mode ?? `mark_unstable`
|
|
673
|
+
|
|
674
|
+
// Always work with copies initially
|
|
675
|
+
let x_arr = [...series.x]
|
|
676
|
+
let y_arr = [...series.y]
|
|
677
|
+
let metadata = series.metadata
|
|
678
|
+
let color_values = series.color_values ? [...series.color_values] : undefined
|
|
679
|
+
let size_values = series.size_values ? [...series.size_values] : undefined
|
|
680
|
+
|
|
681
|
+
const quality: CleaningQuality = {
|
|
682
|
+
points_removed: 0,
|
|
683
|
+
invalid_values_found: 0,
|
|
684
|
+
oscillation_detected: false,
|
|
685
|
+
bounds_violations: 0,
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
// Helper to apply filtering to all arrays
|
|
689
|
+
const apply_filter = (kept: number[], removed_count: number) => {
|
|
690
|
+
x_arr = filter_by_indices(x_arr, kept)
|
|
691
|
+
y_arr = filter_by_indices(y_arr, kept)
|
|
692
|
+
if (Array.isArray(metadata)) {
|
|
693
|
+
metadata = filter_by_indices(metadata, kept)
|
|
694
|
+
}
|
|
695
|
+
if (color_values) color_values = filter_by_indices(color_values, kept)
|
|
696
|
+
if (size_values) size_values = filter_by_indices(size_values, kept)
|
|
697
|
+
quality.points_removed += removed_count
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
// Step 1: Handle invalid values
|
|
701
|
+
const invalid_result = handle_invalid_values(y_arr, invalid_mode)
|
|
702
|
+
quality.invalid_values_found = invalid_result.invalid_count
|
|
703
|
+
|
|
704
|
+
if (invalid_mode === `remove` && invalid_result.removed_indices.length > 0) {
|
|
705
|
+
const kept = kept_indices_excluding(x_arr.length, invalid_result.removed_indices)
|
|
706
|
+
apply_filter(kept, invalid_result.removed_indices.length)
|
|
707
|
+
} else {
|
|
708
|
+
y_arr = invalid_result.cleaned
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
// Step 2: Apply physical bounds
|
|
712
|
+
if (config.bounds) {
|
|
713
|
+
const bounds_result = apply_bounds(x_arr, y_arr, config.bounds)
|
|
714
|
+
y_arr = bounds_result.y
|
|
715
|
+
quality.bounds_violations = bounds_result.violations
|
|
716
|
+
|
|
717
|
+
if (config.bounds.mode === `filter` && bounds_result.filtered_indices.length > 0) {
|
|
718
|
+
const kept = kept_indices_excluding(x_arr.length, bounds_result.filtered_indices)
|
|
719
|
+
apply_filter(kept, bounds_result.filtered_indices.length)
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
// Step 3: Remove local outliers (if configured)
|
|
724
|
+
if (config.local_outliers) {
|
|
725
|
+
const outlier_result = remove_local_outliers(y_arr, config.local_outliers)
|
|
726
|
+
quality.outliers_removed = outlier_result.removed_indices.length
|
|
727
|
+
|
|
728
|
+
if (outlier_result.removed_indices.length > 0) {
|
|
729
|
+
apply_filter(outlier_result.kept_indices, outlier_result.removed_indices.length)
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
// Step 4: Apply smoothing
|
|
734
|
+
if (config.smooth) {
|
|
735
|
+
y_arr = apply_smoothing(x_arr, y_arr, config.smooth)
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
// Step 5: Detect instability
|
|
739
|
+
const instability = detect_instability(x_arr, y_arr, config)
|
|
740
|
+
quality.oscillation_detected = instability.detected
|
|
741
|
+
quality.oscillation_score = instability.combined_score
|
|
742
|
+
|
|
743
|
+
if (instability.detected && instability.onset_index >= 0) {
|
|
744
|
+
if (truncation_mode === `hard_cut`) {
|
|
745
|
+
const kept = Array.from({ length: instability.onset_index }, (_, idx) => idx)
|
|
746
|
+
quality.truncated_at_x = instability.onset_x
|
|
747
|
+
apply_filter(kept, x_arr.length - instability.onset_index)
|
|
748
|
+
} else {
|
|
749
|
+
quality.stable_range = [x_arr[0], instability.onset_x]
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
// Build result series
|
|
754
|
+
const result_series = in_place ? series : { ...series }
|
|
755
|
+
;(result_series as DataSeries).x = x_arr
|
|
756
|
+
;(result_series as DataSeries).y = y_arr
|
|
757
|
+
if (metadata !== undefined) (result_series as DataSeries).metadata = metadata
|
|
758
|
+
if (color_values) (result_series as DataSeries).color_values = color_values
|
|
759
|
+
if (size_values) (result_series as DataSeries).size_values = size_values
|
|
760
|
+
|
|
761
|
+
return { series: result_series, quality }
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
// Clean multiple y-series with shared x, filtering to intersection of valid indices
|
|
765
|
+
export function clean_multi_series(
|
|
766
|
+
x_values: readonly number[],
|
|
767
|
+
y_arrays: number[][],
|
|
768
|
+
config: CleaningConfig = {},
|
|
769
|
+
): { x: number[]; cleaned_y: number[][]; quality: CleaningQuality[] } {
|
|
770
|
+
if (y_arrays.length === 0) {
|
|
771
|
+
return { x: [...x_values], cleaned_y: [], quality: [] }
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
const invalid_mode = config.invalid_values ?? `remove`
|
|
775
|
+
const length = Math.min(x_values.length, ...y_arrays.map((arr) => arr.length))
|
|
776
|
+
const { bounds, smooth } = config
|
|
777
|
+
|
|
778
|
+
// Find indices valid across ALL y series (remove mode filters invalid values)
|
|
779
|
+
let kept_indices = Array.from({ length }, (_, idx) => idx)
|
|
780
|
+
if (invalid_mode === `remove`) {
|
|
781
|
+
kept_indices = kept_indices.filter((idx) =>
|
|
782
|
+
y_arrays.every((y_arr) => Number.isFinite(y_arr[idx])),
|
|
783
|
+
)
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
// Apply bounds filter across all series
|
|
787
|
+
if (bounds?.mode === `filter`) {
|
|
788
|
+
kept_indices = kept_indices.filter((idx) => {
|
|
789
|
+
const x_val = x_values[idx]
|
|
790
|
+
return y_arrays.every((y_arr) => is_in_bounds(y_arr[idx], x_val, bounds))
|
|
791
|
+
})
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
const filtered_x = kept_indices.map((idx) => x_values[idx])
|
|
795
|
+
const cleaned_y: number[][] = []
|
|
796
|
+
const quality_reports: CleaningQuality[] = []
|
|
797
|
+
|
|
798
|
+
for (const y_arr of y_arrays) {
|
|
799
|
+
let filtered_y = kept_indices.map((idx) => y_arr[idx])
|
|
800
|
+
// Count invalid values only in aligned prefix (not beyond length)
|
|
801
|
+
let invalid_count = 0
|
|
802
|
+
for (let idx = 0; idx < length; idx++) {
|
|
803
|
+
if (!Number.isFinite(y_arr[idx])) invalid_count++
|
|
804
|
+
}
|
|
805
|
+
const quality: CleaningQuality = {
|
|
806
|
+
points_removed: length - kept_indices.length,
|
|
807
|
+
invalid_values_found: invalid_count,
|
|
808
|
+
oscillation_detected: false,
|
|
809
|
+
bounds_violations: 0,
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
if (invalid_mode === `interpolate`) {
|
|
813
|
+
filtered_y = handle_invalid_values(filtered_y, `interpolate`).cleaned
|
|
814
|
+
}
|
|
815
|
+
if (bounds && bounds.mode !== `filter`) {
|
|
816
|
+
const result = apply_bounds(filtered_x, filtered_y, bounds)
|
|
817
|
+
filtered_y = result.y
|
|
818
|
+
quality.bounds_violations = result.violations
|
|
819
|
+
}
|
|
820
|
+
if (smooth) {
|
|
821
|
+
filtered_y = apply_smoothing(filtered_x, filtered_y, smooth)
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
cleaned_y.push(filtered_y)
|
|
825
|
+
quality_reports.push(quality)
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
return { x: filtered_x, cleaned_y, quality: quality_reports }
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
// Clean correlated x/y/z for 3D data
|
|
832
|
+
// All three arrays are filtered to the intersection of valid indices
|
|
833
|
+
export function clean_xyz(
|
|
834
|
+
x_values: readonly number[],
|
|
835
|
+
y_values: readonly number[],
|
|
836
|
+
z_values: readonly number[],
|
|
837
|
+
config: CleaningConfig & { primary_axis?: `x` | `y` | `z` } = {},
|
|
838
|
+
): { x: number[]; y: number[]; z: number[]; quality: CleaningQuality } {
|
|
839
|
+
const invalid_mode = config.invalid_values ?? `remove`
|
|
840
|
+
const length = Math.min(x_values.length, y_values.length, z_values.length)
|
|
841
|
+
|
|
842
|
+
const all_arrays = [x_values, y_values, z_values] as const
|
|
843
|
+
const { bounds, smooth } = config
|
|
844
|
+
|
|
845
|
+
// Count invalid values across all arrays
|
|
846
|
+
let invalid_count = 0
|
|
847
|
+
for (let idx = 0; idx < length; idx++) {
|
|
848
|
+
if (!all_arrays.every((arr) => Number.isFinite(arr[idx]))) invalid_count++
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
// Find indices where ALL values are valid (remove mode filters)
|
|
852
|
+
let kept_indices = Array.from({ length }, (_, idx) => idx)
|
|
853
|
+
if (invalid_mode === `remove`) {
|
|
854
|
+
kept_indices = kept_indices.filter((idx) =>
|
|
855
|
+
all_arrays.every((arr) => Number.isFinite(arr[idx])),
|
|
856
|
+
)
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
let filtered = {
|
|
860
|
+
x: kept_indices.map((idx) => x_values[idx]),
|
|
861
|
+
y: kept_indices.map((idx) => y_values[idx]),
|
|
862
|
+
z: kept_indices.map((idx) => z_values[idx]),
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
const quality: CleaningQuality = {
|
|
866
|
+
points_removed: length - kept_indices.length,
|
|
867
|
+
invalid_values_found: invalid_count,
|
|
868
|
+
oscillation_detected: false,
|
|
869
|
+
bounds_violations: 0,
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
if (invalid_mode === `interpolate`) {
|
|
873
|
+
filtered.x = handle_invalid_values(filtered.x, `interpolate`).cleaned
|
|
874
|
+
filtered.y = handle_invalid_values(filtered.y, `interpolate`).cleaned
|
|
875
|
+
filtered.z = handle_invalid_values(filtered.z, `interpolate`).cleaned
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
// Apply bounds filter on primary axis
|
|
879
|
+
if (bounds?.mode === `filter`) {
|
|
880
|
+
const primary = config.primary_axis ?? `x`
|
|
881
|
+
const bounds_kept: number[] = []
|
|
882
|
+
for (let idx = 0; idx < filtered.x.length; idx++) {
|
|
883
|
+
const primary_val = filtered[primary][idx]
|
|
884
|
+
// Use x-axis value for dynamic bounds computation (e.g., max: (x_val) => x_val * 2)
|
|
885
|
+
if (is_in_bounds(primary_val, filtered.x[idx], bounds)) {
|
|
886
|
+
bounds_kept.push(idx)
|
|
887
|
+
} else {
|
|
888
|
+
quality.bounds_violations++
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
filtered = {
|
|
892
|
+
x: bounds_kept.map((idx) => filtered.x[idx]),
|
|
893
|
+
y: bounds_kept.map((idx) => filtered.y[idx]),
|
|
894
|
+
z: bounds_kept.map((idx) => filtered.z[idx]),
|
|
895
|
+
}
|
|
896
|
+
quality.points_removed += kept_indices.length - bounds_kept.length
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
// Smooth dependent axes (y, z) using x as independent reference
|
|
900
|
+
// x-axis is never smoothed as it's typically the independent variable (time, index, etc.)
|
|
901
|
+
if (smooth) {
|
|
902
|
+
filtered.y = apply_smoothing(filtered.x, filtered.y, smooth)
|
|
903
|
+
filtered.z = apply_smoothing(filtered.x, filtered.z, smooth)
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
return { ...filtered, quality }
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
// Clean trajectory properties, filtering to intersection of valid indices
|
|
910
|
+
export function clean_trajectory_props(
|
|
911
|
+
props: Record<string, number[]>,
|
|
912
|
+
config: CleaningConfig & { independent_axis?: string } = {},
|
|
913
|
+
): { props: Record<string, number[]>; quality: Record<string, CleaningQuality> } {
|
|
914
|
+
const entries = Object.entries(props)
|
|
915
|
+
if (entries.length === 0) {
|
|
916
|
+
return { props: {}, quality: {} }
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
const independent_axis = config.independent_axis ?? `Step`
|
|
920
|
+
const invalid_mode = config.invalid_values ?? `remove`
|
|
921
|
+
const { smooth } = config
|
|
922
|
+
const length = Math.min(...entries.map(([, arr]) => arr.length))
|
|
923
|
+
|
|
924
|
+
// Use existing or generate independent axis
|
|
925
|
+
const x_values = props[independent_axis] ?? Array.from({ length }, (_, idx) => idx)
|
|
926
|
+
|
|
927
|
+
// Count invalid values per property (only within aligned prefix)
|
|
928
|
+
const invalid_counts: Record<string, number> = Object.fromEntries(
|
|
929
|
+
entries.map(([key, arr]) => {
|
|
930
|
+
let count = 0
|
|
931
|
+
for (let idx = 0; idx < length; idx++) {
|
|
932
|
+
if (!Number.isFinite(arr[idx])) count++
|
|
933
|
+
}
|
|
934
|
+
return [key, count]
|
|
935
|
+
}),
|
|
936
|
+
)
|
|
937
|
+
|
|
938
|
+
// Find indices valid across ALL properties (remove mode filters)
|
|
939
|
+
let kept_indices = Array.from({ length }, (_, idx) => idx)
|
|
940
|
+
if (invalid_mode === `remove`) {
|
|
941
|
+
kept_indices = kept_indices.filter((idx) =>
|
|
942
|
+
entries.every(([, arr]) => Number.isFinite(arr[idx])),
|
|
943
|
+
)
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
const filtered_x = kept_indices.map((idx) => x_values[idx])
|
|
947
|
+
const result_props: Record<string, number[]> = {}
|
|
948
|
+
const quality_reports: Record<string, CleaningQuality> = {}
|
|
949
|
+
|
|
950
|
+
for (const [key, arr] of entries) {
|
|
951
|
+
let filtered = kept_indices.map((idx) => arr[idx])
|
|
952
|
+
const quality: CleaningQuality = {
|
|
953
|
+
points_removed: length - kept_indices.length,
|
|
954
|
+
invalid_values_found: invalid_counts[key],
|
|
955
|
+
oscillation_detected: false,
|
|
956
|
+
bounds_violations: 0,
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
if (invalid_mode === `interpolate`) {
|
|
960
|
+
filtered = handle_invalid_values(filtered, `interpolate`).cleaned
|
|
961
|
+
}
|
|
962
|
+
if (smooth && key !== independent_axis) {
|
|
963
|
+
filtered = apply_smoothing(filtered_x, filtered, smooth)
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
result_props[key] = filtered
|
|
967
|
+
quality_reports[key] = quality
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
// Add independent axis if not in original props
|
|
971
|
+
if (!props[independent_axis]) {
|
|
972
|
+
result_props[independent_axis] = filtered_x
|
|
973
|
+
quality_reports[independent_axis] = {
|
|
974
|
+
points_removed: length - kept_indices.length,
|
|
975
|
+
invalid_values_found: 0,
|
|
976
|
+
oscillation_detected: false,
|
|
977
|
+
bounds_violations: 0,
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
return { props: result_props, quality: quality_reports }
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
// --- Utility Functions ---
|
|
985
|
+
|
|
986
|
+
function median(values: number[]): number {
|
|
987
|
+
if (values.length === 0) return 0
|
|
988
|
+
const sorted = [...values].sort((a, b) => a - b)
|
|
989
|
+
const mid = Math.floor(sorted.length / 2)
|
|
990
|
+
return sorted.length % 2 !== 0 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
// Simple matrix operations for Savitzky-Golay
|
|
994
|
+
function transpose(matrix: number[][]): number[][] {
|
|
995
|
+
if (matrix.length === 0) return []
|
|
996
|
+
const rows = matrix.length
|
|
997
|
+
const cols = matrix[0].length
|
|
998
|
+
const result: number[][] = Array.from({ length: cols }, () => Array(rows).fill(0))
|
|
999
|
+
for (let row = 0; row < rows; row++) {
|
|
1000
|
+
for (let col = 0; col < cols; col++) {
|
|
1001
|
+
result[col][row] = matrix[row][col]
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
return result
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
function multiply_matrices(a: number[][], b: number[][]): number[][] {
|
|
1008
|
+
const rows_a = a.length
|
|
1009
|
+
const cols_a = a[0]?.length ?? 0
|
|
1010
|
+
const cols_b = b[0]?.length ?? 0
|
|
1011
|
+
|
|
1012
|
+
const result: number[][] = Array.from({ length: rows_a }, () => Array(cols_b).fill(0))
|
|
1013
|
+
|
|
1014
|
+
for (let row = 0; row < rows_a; row++) {
|
|
1015
|
+
for (let col = 0; col < cols_b; col++) {
|
|
1016
|
+
for (let k = 0; k < cols_a; k++) {
|
|
1017
|
+
result[row][col] += a[row][k] * b[k][col]
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
return result
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
function invert_matrix(matrix: number[][]): number[][] | null {
|
|
1026
|
+
const n = matrix.length
|
|
1027
|
+
if (n === 0 || matrix[0].length !== n) return null
|
|
1028
|
+
|
|
1029
|
+
// Create augmented matrix [A | I]
|
|
1030
|
+
const aug: number[][] = matrix.map((row, idx) => [
|
|
1031
|
+
...row,
|
|
1032
|
+
...Array.from({ length: n }, (_, jdx) => (idx === jdx ? 1 : 0)),
|
|
1033
|
+
])
|
|
1034
|
+
|
|
1035
|
+
// Gaussian elimination with partial pivoting
|
|
1036
|
+
for (let col = 0; col < n; col++) {
|
|
1037
|
+
// Find pivot
|
|
1038
|
+
let max_row = col
|
|
1039
|
+
for (let row = col + 1; row < n; row++) {
|
|
1040
|
+
if (Math.abs(aug[row][col]) > Math.abs(aug[max_row][col])) {
|
|
1041
|
+
max_row = row
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
if (Math.abs(aug[max_row][col]) < 1e-10) {
|
|
1046
|
+
return null // Singular
|
|
1047
|
+
} // Swap rows
|
|
1048
|
+
|
|
1049
|
+
;[aug[col], aug[max_row]] = [aug[max_row], aug[col]]
|
|
1050
|
+
|
|
1051
|
+
// Eliminate column
|
|
1052
|
+
const pivot = aug[col][col]
|
|
1053
|
+
for (let jdx = 0; jdx < 2 * n; jdx++) {
|
|
1054
|
+
aug[col][jdx] /= pivot
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
for (let row = 0; row < n; row++) {
|
|
1058
|
+
if (row !== col) {
|
|
1059
|
+
const factor = aug[row][col]
|
|
1060
|
+
for (let jdx = 0; jdx < 2 * n; jdx++) {
|
|
1061
|
+
aug[row][jdx] -= factor * aug[col][jdx]
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
// Extract inverse
|
|
1068
|
+
return aug.map((row) => row.slice(n))
|
|
1069
|
+
}
|