react-cheminfo 0.69.0 → 0.71.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +70 -2
- package/lib/about/core/providers.d.ts +6 -0
- package/lib/about/core/providers.d.ts.map +1 -1
- package/lib/about/core/providers.js +7 -0
- package/lib/about/core/providers.js.map +1 -1
- package/lib/about/ui/AboutProvidedBy.js +34 -0
- package/lib/about/ui/AboutProvidedBy.js.map +1 -1
- package/lib/chart/ui/useChartPointer.d.ts +9 -1
- package/lib/chart/ui/useChartPointer.d.ts.map +1 -1
- package/lib/chart/ui/useChartPointer.js +11 -3
- package/lib/chart/ui/useChartPointer.js.map +1 -1
- package/lib/credits/core/credits.d.ts +41 -0
- package/lib/credits/core/credits.d.ts.map +1 -1
- package/lib/credits/core/credits.js +50 -0
- package/lib/credits/core/credits.js.map +1 -1
- package/lib/download/core/drawingMarkup.d.ts +8 -1
- package/lib/download/core/drawingMarkup.d.ts.map +1 -1
- package/lib/download/core/drawingMarkup.js +13 -1
- package/lib/download/core/drawingMarkup.js.map +1 -1
- package/lib/download/core/figurePng.d.ts +14 -0
- package/lib/download/core/figurePng.d.ts.map +1 -1
- package/lib/download/core/figurePng.js +21 -6
- package/lib/download/core/figurePng.js.map +1 -1
- package/lib/download/core/figureSvg.d.ts.map +1 -1
- package/lib/download/core/figureSvg.js +5 -3
- package/lib/download/core/figureSvg.js.map +1 -1
- package/lib/download/core/figureTarget.d.ts +13 -0
- package/lib/download/core/figureTarget.d.ts.map +1 -1
- package/lib/download/core/figureTarget.js +25 -5
- package/lib/download/core/figureTarget.js.map +1 -1
- package/lib/download/core/svgBounds.d.ts +15 -0
- package/lib/download/core/svgBounds.d.ts.map +1 -1
- package/lib/download/core/svgBounds.js +20 -0
- package/lib/download/core/svgBounds.js.map +1 -1
- package/lib/download/core/svgToPng.d.ts.map +1 -1
- package/lib/download/core/svgToPng.js +4 -2
- package/lib/download/core/svgToPng.js.map +1 -1
- package/lib/format/core/relativeTime.d.ts +8 -3
- package/lib/format/core/relativeTime.d.ts.map +1 -1
- package/lib/format/core/relativeTime.js +19 -7
- package/lib/format/core/relativeTime.js.map +1 -1
- package/lib/host/core/connectHost.d.ts +25 -34
- package/lib/host/core/connectHost.d.ts.map +1 -1
- package/lib/host/core/connectHost.js +43 -89
- package/lib/host/core/connectHost.js.map +1 -1
- package/lib/host/core/hostOutputs.d.ts +58 -0
- package/lib/host/core/hostOutputs.d.ts.map +1 -0
- package/lib/host/core/hostOutputs.js +151 -0
- package/lib/host/core/hostOutputs.js.map +1 -0
- package/lib/host/core/index.d.ts +9 -3
- package/lib/host/core/index.d.ts.map +1 -1
- package/lib/host/core/index.js +4 -1
- package/lib/host/core/index.js.map +1 -1
- package/lib/host/core/irKinds.d.ts +124 -0
- package/lib/host/core/irKinds.d.ts.map +1 -0
- package/lib/host/core/irKinds.js +46 -0
- package/lib/host/core/irKinds.js.map +1 -0
- package/lib/host/core/kinds.d.ts +13 -5
- package/lib/host/core/kinds.d.ts.map +1 -1
- package/lib/host/core/kinds.js +11 -5
- package/lib/host/core/kinds.js.map +1 -1
- package/lib/host/core/protocol.d.ts +50 -7
- package/lib/host/core/protocol.d.ts.map +1 -1
- package/lib/host/core/protocol.js +10 -6
- package/lib/host/core/protocol.js.map +1 -1
- package/lib/host/core/selectInputs.d.ts +37 -0
- package/lib/host/core/selectInputs.d.ts.map +1 -0
- package/lib/host/core/selectInputs.js +110 -0
- package/lib/host/core/selectInputs.js.map +1 -0
- package/lib/host/testing/sciPeaks.d.ts +31 -0
- package/lib/host/testing/sciPeaks.d.ts.map +1 -1
- package/lib/host/testing/sciPeaks.js +73 -0
- package/lib/host/testing/sciPeaks.js.map +1 -1
- package/lib/host/testing/standInHost.d.ts +9 -1
- package/lib/host/testing/standInHost.d.ts.map +1 -1
- package/lib/host/testing/standInHost.js +19 -1
- package/lib/host/testing/standInHost.js.map +1 -1
- package/lib/host/ui/useHostConnection.d.ts +13 -5
- package/lib/host/ui/useHostConnection.d.ts.map +1 -1
- package/lib/host/ui/useHostConnection.js +4 -3
- package/lib/host/ui/useHostConnection.js.map +1 -1
- package/lib/host-testing.d.ts +2 -2
- package/lib/host-testing.d.ts.map +1 -1
- package/lib/host-testing.js +2 -2
- package/lib/host-testing.js.map +1 -1
- package/lib/i18n/core/chromeCatalog.d.ts +1 -1
- package/lib/i18n/core/chromeCatalog.d.ts.map +1 -1
- package/lib/ir/core/handPicking.d.ts +58 -0
- package/lib/ir/core/handPicking.d.ts.map +1 -0
- package/lib/ir/core/handPicking.js +130 -0
- package/lib/ir/core/handPicking.js.map +1 -0
- package/lib/ir/core/index.d.ts +3 -0
- package/lib/ir/core/index.d.ts.map +1 -1
- package/lib/ir/core/index.js +3 -0
- package/lib/ir/core/index.js.map +1 -1
- package/lib/ir/core/irBandState.d.ts +57 -0
- package/lib/ir/core/irBandState.d.ts.map +1 -0
- package/lib/ir/core/irBandState.js +119 -0
- package/lib/ir/core/irBandState.js.map +1 -0
- package/lib/ir/core/irCommands.d.ts +11 -0
- package/lib/ir/core/irCommands.d.ts.map +1 -1
- package/lib/ir/core/irCommands.js +6 -0
- package/lib/ir/core/irCommands.js.map +1 -1
- package/lib/ir/core/irPeaks.d.ts +28 -0
- package/lib/ir/core/irPeaks.d.ts.map +1 -0
- package/lib/ir/core/irPeaks.js +66 -0
- package/lib/ir/core/irPeaks.js.map +1 -0
- package/lib/ir/core/irReducer.d.ts +8 -0
- package/lib/ir/core/irReducer.d.ts.map +1 -1
- package/lib/ir/core/irReducer.js +15 -32
- package/lib/ir/core/irReducer.js.map +1 -1
- package/lib/ir/core/irSpectrum.d.ts +15 -0
- package/lib/ir/core/irSpectrum.d.ts.map +1 -1
- package/lib/ir/core/irSpectrum.js.map +1 -1
- package/lib/ir/core/irState.d.ts +9 -6
- package/lib/ir/core/irState.d.ts.map +1 -1
- package/lib/ir/core/irState.js +10 -6
- package/lib/ir/core/irState.js.map +1 -1
- package/lib/ir/core/pickBands.d.ts +14 -0
- package/lib/ir/core/pickBands.d.ts.map +1 -1
- package/lib/ir/core/pickBands.js +39 -33
- package/lib/ir/core/pickBands.js.map +1 -1
- package/lib/ir/core/ramanBands.d.ts +9 -1
- package/lib/ir/core/ramanBands.d.ts.map +1 -1
- package/lib/ir/core/ramanBands.js +2 -2
- package/lib/ir/core/ramanBands.js.map +1 -1
- package/lib/ir/core/spectrumBands.d.ts +46 -0
- package/lib/ir/core/spectrumBands.d.ts.map +1 -0
- package/lib/ir/core/spectrumBands.js +98 -0
- package/lib/ir/core/spectrumBands.js.map +1 -0
- package/lib/ir/ui/BandRow.d.ts +5 -0
- package/lib/ir/ui/BandRow.d.ts.map +1 -1
- package/lib/ir/ui/BandRow.js +4 -3
- package/lib/ir/ui/BandRow.js.map +1 -1
- package/lib/ir/ui/BandsPanel.d.ts +5 -0
- package/lib/ir/ui/BandsPanel.d.ts.map +1 -1
- package/lib/ir/ui/BandsPanel.js +36 -16
- package/lib/ir/ui/BandsPanel.js.map +1 -1
- package/lib/ir/ui/BandsToolbar.d.ts +9 -0
- package/lib/ir/ui/BandsToolbar.d.ts.map +1 -0
- package/lib/ir/ui/BandsToolbar.js +61 -0
- package/lib/ir/ui/BandsToolbar.js.map +1 -0
- package/lib/ir/ui/IrCanvas.d.ts +2 -1
- package/lib/ir/ui/IrCanvas.d.ts.map +1 -1
- package/lib/ir/ui/IrCanvas.js +19 -5
- package/lib/ir/ui/IrCanvas.js.map +1 -1
- package/lib/ir/ui/IrChart.d.ts.map +1 -1
- package/lib/ir/ui/IrChart.js +8 -1
- package/lib/ir/ui/IrChart.js.map +1 -1
- package/lib/ir/ui/IrDocumentationDialog.js +1 -1
- package/lib/ir/ui/IrDocumentationDialog.js.map +1 -1
- package/lib/ir/ui/IrEditor.d.ts +4 -2
- package/lib/ir/ui/IrEditor.d.ts.map +1 -1
- package/lib/ir/ui/IrEditor.js.map +1 -1
- package/lib/ir/ui/IrShell.d.ts.map +1 -1
- package/lib/ir/ui/IrShell.js +6 -0
- package/lib/ir/ui/IrShell.js.map +1 -1
- package/lib/ir/ui/IrStatusBar.d.ts.map +1 -1
- package/lib/ir/ui/IrStatusBar.js +1 -1
- package/lib/ir/ui/IrStatusBar.js.map +1 -1
- package/lib/ir/ui/IrToolbar.d.ts +4 -3
- package/lib/ir/ui/IrToolbar.d.ts.map +1 -1
- package/lib/ir/ui/IrToolbar.js +5 -4
- package/lib/ir/ui/IrToolbar.js.map +1 -1
- package/lib/ir/ui/VibrationalEditor.d.ts +2 -1
- package/lib/ir/ui/VibrationalEditor.d.ts.map +1 -1
- package/lib/ir/ui/VibrationalEditor.js.map +1 -1
- package/lib/ir/ui/irActions.d.ts +5 -0
- package/lib/ir/ui/irActions.d.ts.map +1 -1
- package/lib/ir/ui/irActions.js +6 -0
- package/lib/ir/ui/irActions.js.map +1 -1
- package/lib/ir/ui/irChartProps.d.ts +4 -1
- package/lib/ir/ui/irChartProps.d.ts.map +1 -1
- package/lib/ir/ui/useIrEditor.d.ts +5 -11
- package/lib/ir/ui/useIrEditor.d.ts.map +1 -1
- package/lib/ir/ui/useIrEditor.js +17 -18
- package/lib/ir/ui/useIrEditor.js.map +1 -1
- package/lib/locales/de.json +63 -0
- package/lib/locales/en.json +63 -0
- package/lib/locales/es.json +63 -0
- package/lib/locales/fr.json +63 -0
- package/lib/locales/it.json +63 -0
- package/lib/mass/core/analyseSpectrum.d.ts +85 -0
- package/lib/mass/core/analyseSpectrum.d.ts.map +1 -0
- package/lib/mass/core/analyseSpectrum.js +101 -0
- package/lib/mass/core/analyseSpectrum.js.map +1 -0
- package/lib/mass/core/ascendingTrace.d.ts +24 -0
- package/lib/mass/core/ascendingTrace.d.ts.map +1 -0
- package/lib/mass/core/ascendingTrace.js +57 -0
- package/lib/mass/core/ascendingTrace.js.map +1 -0
- package/lib/mass/core/centroidPeaks.d.ts +77 -0
- package/lib/mass/core/centroidPeaks.d.ts.map +1 -0
- package/lib/mass/core/centroidPeaks.js +62 -0
- package/lib/mass/core/centroidPeaks.js.map +1 -0
- package/lib/mass/core/detectMassFormat.d.ts +24 -0
- package/lib/mass/core/detectMassFormat.d.ts.map +1 -0
- package/lib/mass/core/detectMassFormat.js +105 -0
- package/lib/mass/core/detectMassFormat.js.map +1 -0
- package/lib/mass/core/downloadSpectra.d.ts +24 -0
- package/lib/mass/core/downloadSpectra.d.ts.map +1 -0
- package/lib/mass/core/downloadSpectra.js +35 -0
- package/lib/mass/core/downloadSpectra.js.map +1 -0
- package/lib/mass/core/fromJcamp.d.ts +46 -0
- package/lib/mass/core/fromJcamp.d.ts.map +1 -0
- package/lib/mass/core/fromJcamp.js +123 -0
- package/lib/mass/core/fromJcamp.js.map +1 -0
- package/lib/mass/core/fromText.d.ts +30 -0
- package/lib/mass/core/fromText.d.ts.map +1 -0
- package/lib/mass/core/fromText.js +39 -0
- package/lib/mass/core/fromText.js.map +1 -0
- package/lib/mass/core/index.d.ts +70 -0
- package/lib/mass/core/index.d.ts.map +1 -0
- package/lib/mass/core/index.js +42 -0
- package/lib/mass/core/index.js.map +1 -0
- package/lib/mass/core/jcampTechnique.d.ts +38 -0
- package/lib/mass/core/jcampTechnique.d.ts.map +1 -0
- package/lib/mass/core/jcampTechnique.js +70 -0
- package/lib/mass/core/jcampTechnique.js.map +1 -0
- package/lib/mass/core/labelStackBox.d.ts +49 -0
- package/lib/mass/core/labelStackBox.d.ts.map +1 -0
- package/lib/mass/core/labelStackBox.js +44 -0
- package/lib/mass/core/labelStackBox.js.map +1 -0
- package/lib/mass/core/labelledPeaks.d.ts +79 -0
- package/lib/mass/core/labelledPeaks.d.ts.map +1 -0
- package/lib/mass/core/labelledPeaks.js +74 -0
- package/lib/mass/core/labelledPeaks.js.map +1 -0
- package/lib/mass/core/loadMassSpectra.d.ts +57 -0
- package/lib/mass/core/loadMassSpectra.d.ts.map +1 -0
- package/lib/mass/core/loadMassSpectra.js +45 -0
- package/lib/mass/core/loadMassSpectra.js.map +1 -0
- package/lib/mass/core/loadedMassSpectrum.d.ts +42 -0
- package/lib/mass/core/loadedMassSpectrum.d.ts.map +1 -0
- package/lib/mass/core/loadedMassSpectrum.js +15 -0
- package/lib/mass/core/loadedMassSpectrum.js.map +1 -0
- package/lib/mass/core/massCommands.d.ts +170 -0
- package/lib/mass/core/massCommands.d.ts.map +1 -0
- package/lib/mass/core/massCommands.js +95 -0
- package/lib/mass/core/massCommands.js.map +1 -0
- package/lib/mass/core/massDomain.d.ts +121 -0
- package/lib/mass/core/massDomain.d.ts.map +1 -0
- package/lib/mass/core/massDomain.js +179 -0
- package/lib/mass/core/massDomain.js.map +1 -0
- package/lib/mass/core/massEditorApi.d.ts +65 -0
- package/lib/mass/core/massEditorApi.d.ts.map +1 -0
- package/lib/mass/core/massEditorApi.js +10 -0
- package/lib/mass/core/massEditorApi.js.map +1 -0
- package/lib/mass/core/massFormat.d.ts +78 -0
- package/lib/mass/core/massFormat.d.ts.map +1 -0
- package/lib/mass/core/massFormat.js +168 -0
- package/lib/mass/core/massFormat.js.map +1 -0
- package/lib/mass/core/massMeta.d.ts +85 -0
- package/lib/mass/core/massMeta.d.ts.map +1 -0
- package/lib/mass/core/massMeta.js +182 -0
- package/lib/mass/core/massMeta.js.map +1 -0
- package/lib/mass/core/massReducer.d.ts +82 -0
- package/lib/mass/core/massReducer.d.ts.map +1 -0
- package/lib/mass/core/massReducer.js +163 -0
- package/lib/mass/core/massReducer.js.map +1 -0
- package/lib/mass/core/massResolution.d.ts +92 -0
- package/lib/mass/core/massResolution.d.ts.map +1 -0
- package/lib/mass/core/massResolution.js +126 -0
- package/lib/mass/core/massResolution.js.map +1 -0
- package/lib/mass/core/massSidePanels.d.ts +28 -0
- package/lib/mass/core/massSidePanels.d.ts.map +1 -0
- package/lib/mass/core/massSidePanels.js +12 -0
- package/lib/mass/core/massSidePanels.js.map +1 -0
- package/lib/mass/core/massSpectrum.d.ts +206 -0
- package/lib/mass/core/massSpectrum.d.ts.map +1 -0
- package/lib/mass/core/massSpectrum.js +41 -0
- package/lib/mass/core/massSpectrum.js.map +1 -0
- package/lib/mass/core/massState.d.ts +145 -0
- package/lib/mass/core/massState.d.ts.map +1 -0
- package/lib/mass/core/massState.js +102 -0
- package/lib/mass/core/massState.js.map +1 -0
- package/lib/mass/core/massStateEdits.d.ts +51 -0
- package/lib/mass/core/massStateEdits.d.ts.map +1 -0
- package/lib/mass/core/massStateEdits.js +90 -0
- package/lib/mass/core/massStateEdits.js.map +1 -0
- package/lib/mass/core/massSummary.d.ts +77 -0
- package/lib/mass/core/massSummary.d.ts.map +1 -0
- package/lib/mass/core/massSummary.js +174 -0
- package/lib/mass/core/massSummary.js.map +1 -0
- package/lib/mass/core/mzDecimalsSetting.d.ts +36 -0
- package/lib/mass/core/mzDecimalsSetting.d.ts.map +1 -0
- package/lib/mass/core/mzDecimalsSetting.js +42 -0
- package/lib/mass/core/mzDecimalsSetting.js.map +1 -0
- package/lib/mass/core/nearestPeak.d.ts +75 -0
- package/lib/mass/core/nearestPeak.d.ts.map +1 -0
- package/lib/mass/core/nearestPeak.js +99 -0
- package/lib/mass/core/nearestPeak.js.map +1 -0
- package/lib/mass/core/peakLabelLines.d.ts +77 -0
- package/lib/mass/core/peakLabelLines.d.ts.map +1 -0
- package/lib/mass/core/peakLabelLines.js +54 -0
- package/lib/mass/core/peakLabelLines.js.map +1 -0
- package/lib/mass/core/peakLabelPlan.d.ts +109 -0
- package/lib/mass/core/peakLabelPlan.d.ts.map +1 -0
- package/lib/mass/core/peakLabelPlan.js +143 -0
- package/lib/mass/core/peakLabelPlan.js.map +1 -0
- package/lib/mass/core/peakTable.d.ts +54 -0
- package/lib/mass/core/peakTable.d.ts.map +1 -0
- package/lib/mass/core/peakTable.js +53 -0
- package/lib/mass/core/peakTable.js.map +1 -0
- package/lib/mass/core/resolutionOf.d.ts +60 -0
- package/lib/mass/core/resolutionOf.d.ts.map +1 -0
- package/lib/mass/core/resolutionOf.js +84 -0
- package/lib/mass/core/resolutionOf.js.map +1 -0
- package/lib/mass/core/scanFilter.d.ts +25 -0
- package/lib/mass/core/scanFilter.d.ts.map +1 -0
- package/lib/mass/core/scanFilter.js +107 -0
- package/lib/mass/core/scanFilter.js.map +1 -0
- package/lib/mass/core/spectrumJcamp.d.ts +47 -0
- package/lib/mass/core/spectrumJcamp.d.ts.map +1 -0
- package/lib/mass/core/spectrumJcamp.js +167 -0
- package/lib/mass/core/spectrumJcamp.js.map +1 -0
- package/lib/mass/core/toMassSpectrum.d.ts +67 -0
- package/lib/mass/core/toMassSpectrum.d.ts.map +1 -0
- package/lib/mass/core/toMassSpectrum.js +78 -0
- package/lib/mass/core/toMassSpectrum.js.map +1 -0
- package/lib/mass/core/traceIcon.d.ts +82 -0
- package/lib/mass/core/traceIcon.d.ts.map +1 -0
- package/lib/mass/core/traceIcon.js +66 -0
- package/lib/mass/core/traceIcon.js.map +1 -0
- package/lib/mass/core/writtenResolution.d.ts +40 -0
- package/lib/mass/core/writtenResolution.d.ts.map +1 -0
- package/lib/mass/core/writtenResolution.js +77 -0
- package/lib/mass/core/writtenResolution.js.map +1 -0
- package/lib/mass/ui/MassAboutDialog.d.ts +16 -0
- package/lib/mass/ui/MassAboutDialog.d.ts.map +1 -0
- package/lib/mass/ui/MassAboutDialog.js +44 -0
- package/lib/mass/ui/MassAboutDialog.js.map +1 -0
- package/lib/mass/ui/MassCanvas.d.ts +46 -0
- package/lib/mass/ui/MassCanvas.d.ts.map +1 -0
- package/lib/mass/ui/MassCanvas.js +84 -0
- package/lib/mass/ui/MassCanvas.js.map +1 -0
- package/lib/mass/ui/MassChart.d.ts +21 -0
- package/lib/mass/ui/MassChart.d.ts.map +1 -0
- package/lib/mass/ui/MassChart.js +139 -0
- package/lib/mass/ui/MassChart.js.map +1 -0
- package/lib/mass/ui/MassCommandProvider.d.ts +15 -0
- package/lib/mass/ui/MassCommandProvider.d.ts.map +1 -0
- package/lib/mass/ui/MassCommandProvider.js +14 -0
- package/lib/mass/ui/MassCommandProvider.js.map +1 -0
- package/lib/mass/ui/MassCommandTooltip.d.ts +16 -0
- package/lib/mass/ui/MassCommandTooltip.d.ts.map +1 -0
- package/lib/mass/ui/MassCommandTooltip.js +22 -0
- package/lib/mass/ui/MassCommandTooltip.js.map +1 -0
- package/lib/mass/ui/MassDocumentationDialog.d.ts +18 -0
- package/lib/mass/ui/MassDocumentationDialog.d.ts.map +1 -0
- package/lib/mass/ui/MassDocumentationDialog.js +70 -0
- package/lib/mass/ui/MassDocumentationDialog.js.map +1 -0
- package/lib/mass/ui/MassEditor.d.ts +78 -0
- package/lib/mass/ui/MassEditor.d.ts.map +1 -0
- package/lib/mass/ui/MassEditor.js +42 -0
- package/lib/mass/ui/MassEditor.js.map +1 -0
- package/lib/mass/ui/MassHeader.d.ts +12 -0
- package/lib/mass/ui/MassHeader.d.ts.map +1 -0
- package/lib/mass/ui/MassHeader.js +20 -0
- package/lib/mass/ui/MassHeader.js.map +1 -0
- package/lib/mass/ui/MassLogo.d.ts +21 -0
- package/lib/mass/ui/MassLogo.d.ts.map +1 -0
- package/lib/mass/ui/MassLogo.js +36 -0
- package/lib/mass/ui/MassLogo.js.map +1 -0
- package/lib/mass/ui/MassPointerTracker.d.ts +44 -0
- package/lib/mass/ui/MassPointerTracker.d.ts.map +1 -0
- package/lib/mass/ui/MassPointerTracker.js +29 -0
- package/lib/mass/ui/MassPointerTracker.js.map +1 -0
- package/lib/mass/ui/MassShell.d.ts +29 -0
- package/lib/mass/ui/MassShell.d.ts.map +1 -0
- package/lib/mass/ui/MassShell.js +133 -0
- package/lib/mass/ui/MassShell.js.map +1 -0
- package/lib/mass/ui/MassSidePanel.d.ts +32 -0
- package/lib/mass/ui/MassSidePanel.d.ts.map +1 -0
- package/lib/mass/ui/MassSidePanel.js +44 -0
- package/lib/mass/ui/MassSidePanel.js.map +1 -0
- package/lib/mass/ui/MassStateProvider.d.ts +19 -0
- package/lib/mass/ui/MassStateProvider.d.ts.map +1 -0
- package/lib/mass/ui/MassStateProvider.js +16 -0
- package/lib/mass/ui/MassStateProvider.js.map +1 -0
- package/lib/mass/ui/MassStatusBar.d.ts +15 -0
- package/lib/mass/ui/MassStatusBar.d.ts.map +1 -0
- package/lib/mass/ui/MassStatusBar.js +50 -0
- package/lib/mass/ui/MassStatusBar.js.map +1 -0
- package/lib/mass/ui/MassToolbar.d.ts +24 -0
- package/lib/mass/ui/MassToolbar.d.ts.map +1 -0
- package/lib/mass/ui/MassToolbar.js +36 -0
- package/lib/mass/ui/MassToolbar.js.map +1 -0
- package/lib/mass/ui/MetadataPanel.d.ts +35 -0
- package/lib/mass/ui/MetadataPanel.d.ts.map +1 -0
- package/lib/mass/ui/MetadataPanel.js +100 -0
- package/lib/mass/ui/MetadataPanel.js.map +1 -0
- package/lib/mass/ui/MzDecimalsMenu.d.ts +28 -0
- package/lib/mass/ui/MzDecimalsMenu.d.ts.map +1 -0
- package/lib/mass/ui/MzDecimalsMenu.js +40 -0
- package/lib/mass/ui/MzDecimalsMenu.js.map +1 -0
- package/lib/mass/ui/PeakLabels.d.ts +93 -0
- package/lib/mass/ui/PeakLabels.d.ts.map +1 -0
- package/lib/mass/ui/PeakLabels.js +91 -0
- package/lib/mass/ui/PeakLabels.js.map +1 -0
- package/lib/mass/ui/PeakTable.d.ts +34 -0
- package/lib/mass/ui/PeakTable.d.ts.map +1 -0
- package/lib/mass/ui/PeakTable.js +49 -0
- package/lib/mass/ui/PeakTable.js.map +1 -0
- package/lib/mass/ui/PeaksPanel.d.ts +31 -0
- package/lib/mass/ui/PeaksPanel.d.ts.map +1 -0
- package/lib/mass/ui/PeaksPanel.js +53 -0
- package/lib/mass/ui/PeaksPanel.js.map +1 -0
- package/lib/mass/ui/SpectraPanel.d.ts +17 -0
- package/lib/mass/ui/SpectraPanel.d.ts.map +1 -0
- package/lib/mass/ui/SpectraPanel.js +76 -0
- package/lib/mass/ui/SpectraPanel.js.map +1 -0
- package/lib/mass/ui/SpectrumRow.d.ts +26 -0
- package/lib/mass/ui/SpectrumRow.d.ts.map +1 -0
- package/lib/mass/ui/SpectrumRow.js +141 -0
- package/lib/mass/ui/SpectrumRow.js.map +1 -0
- package/lib/mass/ui/SpectrumTrace.d.ts +46 -0
- package/lib/mass/ui/SpectrumTrace.d.ts.map +1 -0
- package/lib/mass/ui/SpectrumTrace.js +68 -0
- package/lib/mass/ui/SpectrumTrace.js.map +1 -0
- package/lib/mass/ui/index.d.ts +69 -0
- package/lib/mass/ui/index.d.ts.map +1 -0
- package/lib/mass/ui/index.js +42 -0
- package/lib/mass/ui/index.js.map +1 -0
- package/lib/mass/ui/massActions.d.ts +52 -0
- package/lib/mass/ui/massActions.d.ts.map +1 -0
- package/lib/mass/ui/massActions.js +62 -0
- package/lib/mass/ui/massActions.js.map +1 -0
- package/lib/mass/ui/massChartProps.d.ts +128 -0
- package/lib/mass/ui/massChartProps.d.ts.map +1 -0
- package/lib/mass/ui/massChartProps.js +14 -0
- package/lib/mass/ui/massChartProps.js.map +1 -0
- package/lib/mass/ui/massCommandContext.d.ts +36 -0
- package/lib/mass/ui/massCommandContext.d.ts.map +1 -0
- package/lib/mass/ui/massCommandContext.js +45 -0
- package/lib/mass/ui/massCommandContext.js.map +1 -0
- package/lib/mass/ui/massHostPanels.d.ts +48 -0
- package/lib/mass/ui/massHostPanels.d.ts.map +1 -0
- package/lib/mass/ui/massHostPanels.js +41 -0
- package/lib/mass/ui/massHostPanels.js.map +1 -0
- package/lib/mass/ui/massStateContext.d.ts +26 -0
- package/lib/mass/ui/massStateContext.d.ts.map +1 -0
- package/lib/mass/ui/massStateContext.js +37 -0
- package/lib/mass/ui/massStateContext.js.map +1 -0
- package/lib/mass/ui/useIntensityZoom.d.ts +20 -0
- package/lib/mass/ui/useIntensityZoom.d.ts.map +1 -0
- package/lib/mass/ui/useIntensityZoom.js +42 -0
- package/lib/mass/ui/useIntensityZoom.js.map +1 -0
- package/lib/mass/ui/useMassEditor.d.ts +52 -0
- package/lib/mass/ui/useMassEditor.d.ts.map +1 -0
- package/lib/mass/ui/useMassEditor.js +93 -0
- package/lib/mass/ui/useMassEditor.js.map +1 -0
- package/lib/mass/ui/useMassFiles.d.ts +22 -0
- package/lib/mass/ui/useMassFiles.d.ts.map +1 -0
- package/lib/mass/ui/useMassFiles.js +71 -0
- package/lib/mass/ui/useMassFiles.js.map +1 -0
- package/lib/mass/ui/useMassHandle.d.ts +15 -0
- package/lib/mass/ui/useMassHandle.d.ts.map +1 -0
- package/lib/mass/ui/useMassHandle.js +35 -0
- package/lib/mass/ui/useMassHandle.js.map +1 -0
- package/lib/mass/ui/useMassPointer.d.ts +70 -0
- package/lib/mass/ui/useMassPointer.d.ts.map +1 -0
- package/lib/mass/ui/useMassPointer.js +57 -0
- package/lib/mass/ui/useMassPointer.js.map +1 -0
- package/lib/mass/ui/useMassShortcuts.d.ts +21 -0
- package/lib/mass/ui/useMassShortcuts.d.ts.map +1 -0
- package/lib/mass/ui/useMassShortcuts.js +66 -0
- package/lib/mass/ui/useMassShortcuts.js.map +1 -0
- package/lib/mass/ui/useMassSide.d.ts +27 -0
- package/lib/mass/ui/useMassSide.d.ts.map +1 -0
- package/lib/mass/ui/useMassSide.js +45 -0
- package/lib/mass/ui/useMassSide.js.map +1 -0
- package/lib/mass/ui/useMassZoom.d.ts +92 -0
- package/lib/mass/ui/useMassZoom.d.ts.map +1 -0
- package/lib/mass/ui/useMassZoom.js +65 -0
- package/lib/mass/ui/useMassZoom.js.map +1 -0
- package/lib/mass.d.ts +16 -0
- package/lib/mass.d.ts.map +1 -0
- package/lib/mass.js +16 -0
- package/lib/mass.js.map +1 -0
- package/lib/panel/ui/PanelRail.d.ts.map +1 -1
- package/lib/panel/ui/PanelRail.js +6 -1
- package/lib/panel/ui/PanelRail.js.map +1 -1
- package/lib/slides/ui/slideSanitizeSchema.d.ts +3 -2
- package/lib/slides/ui/slideSanitizeSchema.d.ts.map +1 -1
- package/lib/slides/ui/slideSanitizeSchema.js +82 -2
- package/lib/slides/ui/slideSanitizeSchema.js.map +1 -1
- package/package.json +6 -1
- package/src/about/core/providers.ts +7 -0
- package/src/about/ui/AboutProvidedBy.tsx +49 -0
- package/src/chart/ui/useChartPointer.ts +18 -4
- package/src/credits/core/credits.ts +53 -0
- package/src/download/core/drawingMarkup.ts +18 -1
- package/src/download/core/figurePng.ts +21 -8
- package/src/download/core/figureSvg.ts +5 -2
- package/src/download/core/figureTarget.ts +28 -3
- package/src/download/core/svgBounds.ts +21 -0
- package/src/download/core/svgToPng.ts +3 -4
- package/src/format/core/relativeTime.ts +29 -7
- package/src/host/core/connectHost.ts +77 -120
- package/src/host/core/hostOutputs.ts +197 -0
- package/src/host/core/index.ts +13 -7
- package/src/host/core/irKinds.ts +92 -0
- package/src/host/core/kinds.ts +16 -6
- package/src/host/core/protocol.ts +50 -8
- package/src/host/core/selectInputs.ts +145 -0
- package/src/host/testing/sciPeaks.ts +140 -0
- package/src/host/testing/standInHost.ts +30 -5
- package/src/host/ui/useHostConnection.ts +17 -8
- package/src/host-testing.ts +4 -0
- package/src/ir/core/handPicking.ts +154 -0
- package/src/ir/core/index.ts +14 -0
- package/src/ir/core/irBandState.ts +155 -0
- package/src/ir/core/irCommands.ts +7 -0
- package/src/ir/core/irPeaks.ts +79 -0
- package/src/ir/core/irReducer.ts +27 -34
- package/src/ir/core/irSpectrum.ts +16 -0
- package/src/ir/core/irState.ts +15 -8
- package/src/ir/core/pickBands.ts +46 -39
- package/src/ir/core/ramanBands.ts +2 -2
- package/src/ir/core/spectrumBands.ts +113 -0
- package/src/ir/ui/BandRow.tsx +20 -2
- package/src/ir/ui/BandsPanel.tsx +46 -88
- package/src/ir/ui/BandsToolbar.tsx +152 -0
- package/src/ir/ui/IrCanvas.tsx +22 -11
- package/src/ir/ui/IrChart.tsx +10 -1
- package/src/ir/ui/IrDocumentationDialog.tsx +7 -0
- package/src/ir/ui/IrEditor.tsx +4 -2
- package/src/ir/ui/IrShell.tsx +5 -0
- package/src/ir/ui/IrStatusBar.tsx +4 -1
- package/src/ir/ui/IrToolbar.tsx +14 -5
- package/src/ir/ui/VibrationalEditor.tsx +2 -1
- package/src/ir/ui/irActions.ts +11 -0
- package/src/ir/ui/irChartProps.ts +4 -1
- package/src/ir/ui/useIrEditor.ts +21 -21
- package/src/locales/de.json +63 -0
- package/src/locales/en.json +63 -0
- package/src/locales/es.json +63 -0
- package/src/locales/fr.json +63 -0
- package/src/locales/it.json +63 -0
- package/src/mass/core/analyseSpectrum.ts +191 -0
- package/src/mass/core/ascendingTrace.ts +62 -0
- package/src/mass/core/centroidPeaks.ts +114 -0
- package/src/mass/core/detectMassFormat.ts +113 -0
- package/src/mass/core/downloadSpectra.ts +52 -0
- package/src/mass/core/fromJcamp.ts +151 -0
- package/src/mass/core/fromText.ts +58 -0
- package/src/mass/core/index.ts +194 -0
- package/src/mass/core/jcampTechnique.ts +87 -0
- package/src/mass/core/labelStackBox.ts +75 -0
- package/src/mass/core/labelledPeaks.ts +135 -0
- package/src/mass/core/loadMassSpectra.ts +86 -0
- package/src/mass/core/loadedMassSpectrum.ts +43 -0
- package/src/mass/core/massCommands.ts +156 -0
- package/src/mass/core/massDomain.ts +229 -0
- package/src/mass/core/massEditorApi.ts +68 -0
- package/src/mass/core/massFormat.ts +187 -0
- package/src/mass/core/massMeta.ts +239 -0
- package/src/mass/core/massReducer.ts +232 -0
- package/src/mass/core/massResolution.ts +169 -0
- package/src/mass/core/massSidePanels.ts +27 -0
- package/src/mass/core/massSpectrum.ts +220 -0
- package/src/mass/core/massState.ts +206 -0
- package/src/mass/core/massStateEdits.ts +104 -0
- package/src/mass/core/massSummary.ts +213 -0
- package/src/mass/core/mzDecimalsSetting.ts +52 -0
- package/src/mass/core/nearestPeak.ts +130 -0
- package/src/mass/core/peakLabelLines.ts +112 -0
- package/src/mass/core/peakLabelPlan.ts +246 -0
- package/src/mass/core/peakTable.ts +82 -0
- package/src/mass/core/resolutionOf.ts +100 -0
- package/src/mass/core/scanFilter.ts +119 -0
- package/src/mass/core/spectrumJcamp.ts +186 -0
- package/src/mass/core/toMassSpectrum.ts +126 -0
- package/src/mass/core/traceIcon.ts +105 -0
- package/src/mass/core/writtenResolution.ts +81 -0
- package/src/mass/ui/MassAboutDialog.tsx +89 -0
- package/src/mass/ui/MassCanvas.tsx +170 -0
- package/src/mass/ui/MassChart.tsx +266 -0
- package/src/mass/ui/MassCommandProvider.tsx +34 -0
- package/src/mass/ui/MassCommandTooltip.tsx +36 -0
- package/src/mass/ui/MassDocumentationDialog.tsx +136 -0
- package/src/mass/ui/MassEditor.tsx +130 -0
- package/src/mass/ui/MassHeader.tsx +38 -0
- package/src/mass/ui/MassLogo.tsx +84 -0
- package/src/mass/ui/MassPointerTracker.tsx +72 -0
- package/src/mass/ui/MassShell.tsx +237 -0
- package/src/mass/ui/MassSidePanel.tsx +107 -0
- package/src/mass/ui/MassStateProvider.tsx +32 -0
- package/src/mass/ui/MassStatusBar.tsx +108 -0
- package/src/mass/ui/MassToolbar.tsx +120 -0
- package/src/mass/ui/MetadataPanel.tsx +201 -0
- package/src/mass/ui/MzDecimalsMenu.tsx +86 -0
- package/src/mass/ui/PeakLabels.tsx +242 -0
- package/src/mass/ui/PeakTable.tsx +199 -0
- package/src/mass/ui/PeaksPanel.tsx +182 -0
- package/src/mass/ui/SpectraPanel.tsx +153 -0
- package/src/mass/ui/SpectrumRow.tsx +246 -0
- package/src/mass/ui/SpectrumTrace.tsx +119 -0
- package/src/mass/ui/index.ts +69 -0
- package/src/mass/ui/massActions.ts +109 -0
- package/src/mass/ui/massChartProps.ts +130 -0
- package/src/mass/ui/massCommandContext.tsx +65 -0
- package/src/mass/ui/massHostPanels.ts +71 -0
- package/src/mass/ui/massStateContext.ts +48 -0
- package/src/mass/ui/useIntensityZoom.ts +55 -0
- package/src/mass/ui/useMassEditor.ts +156 -0
- package/src/mass/ui/useMassFiles.ts +91 -0
- package/src/mass/ui/useMassHandle.ts +58 -0
- package/src/mass/ui/useMassPointer.ts +120 -0
- package/src/mass/ui/useMassShortcuts.ts +85 -0
- package/src/mass/ui/useMassSide.ts +63 -0
- package/src/mass/ui/useMassZoom.ts +157 -0
- package/src/mass.ts +16 -0
- package/src/panel/ui/PanelRail.tsx +5 -1
- package/src/slides/ui/slideSanitizeSchema.ts +86 -2
- package/styles/chrome.css +7 -0
- package/styles/slides.css +47 -0
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where every labelled peak's numbers go, worked out before anything is drawn.
|
|
3
|
+
*
|
|
4
|
+
* Which peaks are labelled is `selectLabelledPeaks`, and the slots it makes that
|
|
5
|
+
* choice with are cut from the *window*: ten of them, whatever the chart is. A
|
|
6
|
+
* label is not — it is a number set at a fixed size, and `527.1607` is fifty
|
|
7
|
+
* pixels wide on a plot of any width. So a chart narrow enough for its slots to
|
|
8
|
+
* be thinner than that hands back two peaks whose stacks are written one across
|
|
9
|
+
* the other, and the two masses that result are neither.
|
|
10
|
+
*
|
|
11
|
+
* What settles it: **the taller peak keeps the room, and the fainter one goes
|
|
12
|
+
* without**. Never a nudge sideways — on a chart, distance from a stick is the
|
|
13
|
+
* only thing saying which stick a number belongs to, and a mass slid clear of
|
|
14
|
+
* its neighbour is a mass now hanging over somebody else's peak. The peak that
|
|
15
|
+
* loses its numbers keeps the mark on its tip, so it is not read as a peak the
|
|
16
|
+
* spectrum lacks, and a zoom widens the room and brings its stack straight back.
|
|
17
|
+
*
|
|
18
|
+
* Kept out of the component so that which peak was labelled, and at what pixel,
|
|
19
|
+
* is worth a test that no browser has to stand by for.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import type { PlotRect } from '../../chart/core/chartGeometry.ts';
|
|
23
|
+
import type { ChartScale } from '../../chart/core/chartScale.ts';
|
|
24
|
+
import { chartPixel, chartValue } from '../../chart/core/chartScale.ts';
|
|
25
|
+
import { PEAK_LABEL } from '../../chart/core/chartTheme.ts';
|
|
26
|
+
import { labelStackBaselines } from '../../chart/core/labelStack.ts';
|
|
27
|
+
|
|
28
|
+
import type { StackBox } from './labelStackBox.ts';
|
|
29
|
+
import { labelStackBox } from './labelStackBox.ts';
|
|
30
|
+
import type { LabelledPeak } from './labelledPeaks.ts';
|
|
31
|
+
import { selectLabelledPeaks } from './labelledPeaks.ts';
|
|
32
|
+
import type { MassSpectrum } from './massSpectrum.ts';
|
|
33
|
+
import type { PeakLabelLine } from './peakLabelLines.ts';
|
|
34
|
+
import { peakKey, peakLabelLines } from './peakLabelLines.ts';
|
|
35
|
+
|
|
36
|
+
/** The clear space kept between two stacks standing side by side. */
|
|
37
|
+
export const LABEL_SPACING = 4;
|
|
38
|
+
|
|
39
|
+
/** One labelled peak: its stick, its numbers, and where both are drawn. */
|
|
40
|
+
export interface PeakLabelPlan {
|
|
41
|
+
/** The peak being labelled. */
|
|
42
|
+
peak: LabelledPeak;
|
|
43
|
+
/** `${spectrumId}:${index}`, which is how anything said about it is found. */
|
|
44
|
+
key: string;
|
|
45
|
+
/** Where its stick stands, in pixels across the SVG. */
|
|
46
|
+
tipX: number;
|
|
47
|
+
/** Where the tip of that stick is, in pixels down the SVG. */
|
|
48
|
+
tipY: number;
|
|
49
|
+
/**
|
|
50
|
+
* Where the stack is centred, which is over the tip unless the peak stands so
|
|
51
|
+
* near the edge of the plot that its numbers would be written half outside it.
|
|
52
|
+
* `NaN` for a peak crowded out of its numbers by a taller neighbour, which is
|
|
53
|
+
* still marked — it simply is not written.
|
|
54
|
+
*/
|
|
55
|
+
labelX: number;
|
|
56
|
+
/** What the stack says, farthest line from the peak first. */
|
|
57
|
+
lines: PeakLabelLine[];
|
|
58
|
+
/** Where each of those lines is written, in the order the lines are in. */
|
|
59
|
+
baselines: Float64Array;
|
|
60
|
+
/** The room the stack takes, which is what answers the pointer. */
|
|
61
|
+
box: StackBox;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** What a set of stacks is planned against. */
|
|
65
|
+
export interface PlanPeakLabelsOptions {
|
|
66
|
+
/** The spectrum whose peaks are labelled, as it is drawn. */
|
|
67
|
+
spectrum: MassSpectrum;
|
|
68
|
+
/** Where the plot sits, which is what a stack may not be written outside of. */
|
|
69
|
+
plot: PlotRect;
|
|
70
|
+
/** The m/z axis as it is currently zoomed. */
|
|
71
|
+
xScale: ChartScale;
|
|
72
|
+
/** The intensity axis as it is currently zoomed. */
|
|
73
|
+
yScale: ChartScale;
|
|
74
|
+
/**
|
|
75
|
+
* How many peaks are labelled at most, the most intense first.
|
|
76
|
+
* @default the selection's own default
|
|
77
|
+
*/
|
|
78
|
+
limit?: number;
|
|
79
|
+
/**
|
|
80
|
+
* Whether a peak whose charge was established says so.
|
|
81
|
+
* @default false
|
|
82
|
+
*/
|
|
83
|
+
showCharges?: boolean;
|
|
84
|
+
/**
|
|
85
|
+
* How many decimals the masses on screen are written with.
|
|
86
|
+
* @default 4
|
|
87
|
+
*/
|
|
88
|
+
mzDecimals?: number;
|
|
89
|
+
/**
|
|
90
|
+
* What explains each peak, keyed as `peakKey` keys it.
|
|
91
|
+
* @default undefined
|
|
92
|
+
*/
|
|
93
|
+
annotationLabels?: ReadonlyMap<string, string>;
|
|
94
|
+
/**
|
|
95
|
+
* Whether the stacks hang under the sticks rather than standing over them,
|
|
96
|
+
* which is what the lower half of a mirrored pair wants.
|
|
97
|
+
* @default false
|
|
98
|
+
*/
|
|
99
|
+
below?: boolean;
|
|
100
|
+
/**
|
|
101
|
+
* What one unit of the measured intensity is written as.
|
|
102
|
+
* @default 1
|
|
103
|
+
*/
|
|
104
|
+
intensityScale?: number;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Plan the stacks for the window on screen.
|
|
109
|
+
*
|
|
110
|
+
* The crowding is settled before a single line is composed, and settled in
|
|
111
|
+
* descending intensity: the tallest peak of the window asks for its stretch of
|
|
112
|
+
* the axis first and keeps it, and every fainter peak standing closer than a
|
|
113
|
+
* label is wide loses its `labelX`. What comes back is in ascending m/z, so the
|
|
114
|
+
* drawing order is the axis order and a stack keeps its key from one render to
|
|
115
|
+
* the next.
|
|
116
|
+
* @param options - The spectrum, the axes, and what the stacks may say.
|
|
117
|
+
* @returns One plan per peak that earned a label, in ascending m/z, those
|
|
118
|
+
* crowded out among them.
|
|
119
|
+
*/
|
|
120
|
+
export function planPeakLabels(
|
|
121
|
+
options: PlanPeakLabelsOptions,
|
|
122
|
+
): PeakLabelPlan[] {
|
|
123
|
+
const {
|
|
124
|
+
spectrum,
|
|
125
|
+
plot,
|
|
126
|
+
xScale,
|
|
127
|
+
yScale,
|
|
128
|
+
limit,
|
|
129
|
+
showCharges = false,
|
|
130
|
+
mzDecimals,
|
|
131
|
+
annotationLabels,
|
|
132
|
+
below = false,
|
|
133
|
+
intensityScale = 1,
|
|
134
|
+
} = options;
|
|
135
|
+
|
|
136
|
+
const peaks = selectLabelledPeaks(spectrum, {
|
|
137
|
+
from: chartValue(xScale, plot.left),
|
|
138
|
+
to: chartValue(xScale, plot.right),
|
|
139
|
+
// The far edge of the half this spectrum is drawn in: the top of the plot
|
|
140
|
+
// for an ordinary chart, its bottom for a half drawn through a reflected
|
|
141
|
+
// scale.
|
|
142
|
+
maxValue: chartValue(yScale, below ? plot.bottom : plot.top),
|
|
143
|
+
...(limit === undefined ? {} : { limit }),
|
|
144
|
+
});
|
|
145
|
+
if (peaks.length === 0) return [];
|
|
146
|
+
|
|
147
|
+
const centres = placeStacks(peaks, plot, xScale);
|
|
148
|
+
const bounds: [number, number] = [plot.top, plot.bottom];
|
|
149
|
+
const plans: PeakLabelPlan[] = [];
|
|
150
|
+
for (let index = 0; index < peaks.length; index++) {
|
|
151
|
+
const peak = peaks[index] as LabelledPeak;
|
|
152
|
+
const key = peakKey(spectrum.id, peak.index);
|
|
153
|
+
const lines = peakLabelLines(peak, {
|
|
154
|
+
...(mzDecimals === undefined ? {} : { mzDecimals }),
|
|
155
|
+
showCharges,
|
|
156
|
+
intensityScale,
|
|
157
|
+
...(annotationLabels === undefined
|
|
158
|
+
? {}
|
|
159
|
+
: { annotationLabel: annotationLabels.get(key) }),
|
|
160
|
+
});
|
|
161
|
+
const tipY = chartPixel(yScale, peak.y);
|
|
162
|
+
const labelX = centres[index] as number;
|
|
163
|
+
const baselines = labelStackBaselines(tipY, lines.length, bounds, below);
|
|
164
|
+
plans.push({
|
|
165
|
+
peak,
|
|
166
|
+
key,
|
|
167
|
+
tipX: chartPixel(xScale, peak.x),
|
|
168
|
+
tipY,
|
|
169
|
+
labelX,
|
|
170
|
+
lines,
|
|
171
|
+
baselines,
|
|
172
|
+
box: labelStackBox(labelX, baselines),
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
return plans;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Where each stack may stand, `NaN` for one crowded out by a taller peak.
|
|
180
|
+
*
|
|
181
|
+
* A stack whose peak stands at the very edge of the plot is slid back inside it
|
|
182
|
+
* and never further, which is a different thing from clearing a neighbour: the
|
|
183
|
+
* mark stays on the stick, the number moves by a few pixels rather than by its
|
|
184
|
+
* own width, and what it avoids is being written half over the axis.
|
|
185
|
+
* @param peaks - The peaks that earned a label, in ascending m/z.
|
|
186
|
+
* @param plot - Where the plot sits inside the SVG.
|
|
187
|
+
* @param xScale - The m/z axis as it is currently zoomed.
|
|
188
|
+
* @returns The centre each stack was given, indexed as the peaks are.
|
|
189
|
+
*/
|
|
190
|
+
function placeStacks(
|
|
191
|
+
peaks: readonly LabelledPeak[],
|
|
192
|
+
plot: PlotRect,
|
|
193
|
+
xScale: ChartScale,
|
|
194
|
+
): Float64Array {
|
|
195
|
+
const half = PEAK_LABEL.hoverHalfWidth;
|
|
196
|
+
const step = half * 2 + LABEL_SPACING;
|
|
197
|
+
// A plot too narrow to hold one whole label has no inside to slide anything
|
|
198
|
+
// back into, and the clamp would put every stack in the same place.
|
|
199
|
+
const roomy = plot.width >= half * 2;
|
|
200
|
+
const centres = new Float64Array(peaks.length).fill(Number.NaN);
|
|
201
|
+
const placed: number[] = [];
|
|
202
|
+
|
|
203
|
+
for (const index of tallestFirst(peaks)) {
|
|
204
|
+
const wanted = chartPixel(xScale, (peaks[index] as LabelledPeak).x);
|
|
205
|
+
const centre = roomy
|
|
206
|
+
? Math.min(Math.max(wanted, plot.left + half), plot.right - half)
|
|
207
|
+
: wanted;
|
|
208
|
+
if (!clearOfPlaced(placed, centre, step)) continue;
|
|
209
|
+
placed.push(centre);
|
|
210
|
+
centres[index] = centre;
|
|
211
|
+
}
|
|
212
|
+
return centres;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* The indices of the peaks, the tallest first — the order the room is handed
|
|
217
|
+
* out in, so that a base peak is labelled on every chart it appears on.
|
|
218
|
+
* @param peaks - The peaks that earned a label.
|
|
219
|
+
* @returns Their indices, descending by intensity.
|
|
220
|
+
*/
|
|
221
|
+
function tallestFirst(peaks: readonly LabelledPeak[]): Uint32Array {
|
|
222
|
+
const order = new Uint32Array(peaks.length);
|
|
223
|
+
for (let index = 0; index < peaks.length; index++) order[index] = index;
|
|
224
|
+
return order.toSorted(
|
|
225
|
+
(first, second) =>
|
|
226
|
+
(peaks[second] as LabelledPeak).y - (peaks[first] as LabelledPeak).y,
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Whether a stack may stand where it wants to, given the ones already placed.
|
|
232
|
+
* @param placed - The centres already given out, in pixels.
|
|
233
|
+
* @param centre - The centre being asked for.
|
|
234
|
+
* @param step - How far apart two centres have to be for both to be readable.
|
|
235
|
+
* @returns Whether it clears every one of them.
|
|
236
|
+
*/
|
|
237
|
+
function clearOfPlaced(
|
|
238
|
+
placed: readonly number[],
|
|
239
|
+
centre: number,
|
|
240
|
+
step: number,
|
|
241
|
+
): boolean {
|
|
242
|
+
for (const taken of placed) {
|
|
243
|
+
if (Math.abs(taken - centre) < step) return false;
|
|
244
|
+
}
|
|
245
|
+
return true;
|
|
246
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The rows the peak table lists, and the text they are copied out as.
|
|
3
|
+
*
|
|
4
|
+
* The rows are the centroid's own peaks, read through `selectCentroidPeaks` —
|
|
5
|
+
* the same windowing the chart is read through — so the table and the chart
|
|
6
|
+
* can never disagree about which peaks exist.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { MassPeakObject } from './centroidPeaks.ts';
|
|
10
|
+
import { selectCentroidPeaks } from './centroidPeaks.ts';
|
|
11
|
+
import { formatIntensity, formatMz } from './massFormat.ts';
|
|
12
|
+
import type { MassDomain, MassSpectrum } from './massSpectrum.ts';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* How many rows the table lists at most, the most intense kept.
|
|
16
|
+
*
|
|
17
|
+
* Far more than anybody reads, and few enough that a centroid of fifty
|
|
18
|
+
* thousand peaks does not lay out fifty thousand rows under a pointer move.
|
|
19
|
+
*/
|
|
20
|
+
export const PEAK_TABLE_LIMIT = 1000;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The floor the table starts at, as a fraction of the base peak: where a
|
|
24
|
+
* chemist's own peak list starts, and where everything under it is the
|
|
25
|
+
* baseline the compound sits on.
|
|
26
|
+
*/
|
|
27
|
+
export const PEAK_TABLE_THRESHOLD = 0.01;
|
|
28
|
+
|
|
29
|
+
/** Which peaks the table lists. */
|
|
30
|
+
export interface PeakTableOptions {
|
|
31
|
+
/**
|
|
32
|
+
* The window the chart shows, when the table is to follow it; `null` for the
|
|
33
|
+
* whole spectrum.
|
|
34
|
+
* @default null
|
|
35
|
+
*/
|
|
36
|
+
domain?: MassDomain | null;
|
|
37
|
+
/**
|
|
38
|
+
* The floor, as a fraction of the base peak; `0` lists every peak.
|
|
39
|
+
* @default PEAK_TABLE_THRESHOLD
|
|
40
|
+
*/
|
|
41
|
+
threshold?: number;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* The peaks the table lists for one spectrum, in increasing m/z.
|
|
46
|
+
* @param spectrum - The spectrum the table is about.
|
|
47
|
+
* @param options - The window, and the floor.
|
|
48
|
+
* @returns The peaks, shared with the centroid's cache — read, never written.
|
|
49
|
+
*/
|
|
50
|
+
export function peakTableRows(
|
|
51
|
+
spectrum: MassSpectrum,
|
|
52
|
+
options: PeakTableOptions = {},
|
|
53
|
+
): MassPeakObject[] {
|
|
54
|
+
const { domain = null, threshold = PEAK_TABLE_THRESHOLD } = options;
|
|
55
|
+
return selectCentroidPeaks(spectrum.centroid, {
|
|
56
|
+
...(domain === null ? {} : { from: domain.x[0], to: domain.x[1] }),
|
|
57
|
+
threshold,
|
|
58
|
+
limit: PEAK_TABLE_LIMIT,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* The rows as tab-separated text, the way a spreadsheet takes a paste.
|
|
64
|
+
*
|
|
65
|
+
* Written to the decimals the table shows rather than as the doubles are held,
|
|
66
|
+
* so what is pasted is what was read on screen.
|
|
67
|
+
* @param peaks - The rows, in the order they are listed.
|
|
68
|
+
* @param mzDecimals - How many decimals the masses are written with.
|
|
69
|
+
* @returns A header line and one line per peak.
|
|
70
|
+
*/
|
|
71
|
+
export function peakTableToTsv(
|
|
72
|
+
peaks: readonly MassPeakObject[],
|
|
73
|
+
mzDecimals: number,
|
|
74
|
+
): string {
|
|
75
|
+
const lines = ['m/z\tintensity\tcharge'];
|
|
76
|
+
for (const peak of peaks) {
|
|
77
|
+
lines.push(
|
|
78
|
+
`${formatMz(peak.x, mzDecimals)}\t${formatIntensity(peak.y, mzDecimals)}\t${peak.charge === 0 ? '' : peak.charge}`,
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
return `${lines.join('\n')}\n`;
|
|
82
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The resolution of a spectrum as everything downstream asks for it, and the
|
|
3
|
+
* decimals every number on screen is written with.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { MassResolution } from './massResolution.ts';
|
|
7
|
+
import { MZ_DECIMALS, statedResolution } from './massResolution.ts';
|
|
8
|
+
import type { MassMeta, MassSpectrum } from './massSpectrum.ts';
|
|
9
|
+
import { writtenResolution } from './writtenResolution.ts';
|
|
10
|
+
|
|
11
|
+
/** The evidence a verdict is decided on. */
|
|
12
|
+
export interface DecideResolutionOptions {
|
|
13
|
+
/** What the peak widths measured, `null` for a peak table. */
|
|
14
|
+
measured: MassResolution | null;
|
|
15
|
+
/** What the file said about the acquisition. */
|
|
16
|
+
meta: MassMeta | null;
|
|
17
|
+
/** The m/z of every picked peak. */
|
|
18
|
+
masses: Float64Array;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The strongest verdict there is evidence for.
|
|
23
|
+
*
|
|
24
|
+
* A measurement wins outright. Otherwise the instrument the file names decides
|
|
25
|
+
* the kind, but never the decimals beyond what the masses were written with:
|
|
26
|
+
* an ion trap exporting four decimals resolves one, and a table of whole
|
|
27
|
+
* numbers stays whole whatever instrument it came off — writing `330.0` claims
|
|
28
|
+
* a decimal nobody wrote.
|
|
29
|
+
* @param options - The measurement, the file's records and the masses.
|
|
30
|
+
* @returns The verdict.
|
|
31
|
+
*/
|
|
32
|
+
export function decideResolution(
|
|
33
|
+
options: DecideResolutionOptions,
|
|
34
|
+
): MassResolution {
|
|
35
|
+
const { measured, meta, masses } = options;
|
|
36
|
+
if (measured !== null) return measured;
|
|
37
|
+
const written = writtenResolution(masses);
|
|
38
|
+
const stated = statedResolution(meta);
|
|
39
|
+
if (stated === null || written.kind === 'nominal') return written;
|
|
40
|
+
return { ...stated, decimals: Math.min(stated.decimals, written.decimals) };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* The verdict on a spectrum: the one it was read with, or else the one its file
|
|
45
|
+
* and its masses imply.
|
|
46
|
+
*
|
|
47
|
+
* A spectrum a host built itself carries no verdict, and has no peak widths to
|
|
48
|
+
* measure one from either, so what the file named and what the masses were
|
|
49
|
+
* written with are all there is. Cached per centroid, since the verdict is
|
|
50
|
+
* asked of every drawn spectrum on every change of what is drawn, and a
|
|
51
|
+
* centroid is replaced rather than written into.
|
|
52
|
+
* @param spectrum - The spectrum.
|
|
53
|
+
* @returns How finely it resolves masses.
|
|
54
|
+
*/
|
|
55
|
+
export function resolutionOf(spectrum: MassSpectrum): MassResolution {
|
|
56
|
+
if (spectrum.resolution !== undefined) return spectrum.resolution;
|
|
57
|
+
const cached = decidedCache.get(spectrum.centroid.x);
|
|
58
|
+
if (cached !== undefined) return cached;
|
|
59
|
+
const resolution = decideResolution({
|
|
60
|
+
measured: null,
|
|
61
|
+
meta: spectrum.meta,
|
|
62
|
+
masses: spectrum.centroid.x,
|
|
63
|
+
});
|
|
64
|
+
decidedCache.set(spectrum.centroid.x, resolution);
|
|
65
|
+
return resolution;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* How many decimals the masses of spectra drawn together are written with when
|
|
70
|
+
* nobody chose: high-resolution masses or nominal ones, nothing in between.
|
|
71
|
+
*
|
|
72
|
+
* A high-resolution spectrum is written to the decimals its verdict allows —
|
|
73
|
+
* four, or fewer where the file wrote fewer, since padding `330.12` out to
|
|
74
|
+
* `330.1200` claims digits nobody measured. Anything else is written as the
|
|
75
|
+
* nominal mass: a low-resolution instrument's decimals are where its noise
|
|
76
|
+
* lives, and a reader who wants them chooses a number of decimals instead.
|
|
77
|
+
*
|
|
78
|
+
* Asked of all of them at once rather than of each, so one table and one axis
|
|
79
|
+
* never disagree about how wide a number is — and the most precise spectrum
|
|
80
|
+
* wins: put a calculated isotopic pattern beside a nominal peak table and the
|
|
81
|
+
* masses go back to four decimals, because rounding the pattern to match would
|
|
82
|
+
* hide the very difference the comparison was made to show.
|
|
83
|
+
* @param spectra - The spectra being shown together.
|
|
84
|
+
* @returns The decimals; four when none of them holds a peak.
|
|
85
|
+
*/
|
|
86
|
+
export function mzDecimalsOf(spectra: readonly MassSpectrum[]): number {
|
|
87
|
+
let decimals = -1;
|
|
88
|
+
for (const spectrum of spectra) {
|
|
89
|
+
if (spectrum.centroid.x.length === 0) continue;
|
|
90
|
+
const resolution = resolutionOf(spectrum);
|
|
91
|
+
decimals = Math.max(
|
|
92
|
+
decimals,
|
|
93
|
+
resolution.kind === 'high' ? resolution.decimals : MZ_DECIMALS.nominal,
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
return decimals === -1 ? MZ_DECIMALS.high : decimals;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** The verdicts already decided, keyed by the masses they were decided on. */
|
|
100
|
+
const decidedCache = new WeakMap<Float64Array, MassResolution>();
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a Thermo scan filter states, mined for the fields the records left blank.
|
|
3
|
+
*
|
|
4
|
+
* The structured `##$` records are the polite answer and the scan filter is the
|
|
5
|
+
* honest one: a real Exploris export writes `##$IONISATION=` with nothing after
|
|
6
|
+
* the equals sign and then names `NSI` in the middle of the conditions block
|
|
7
|
+
* two lines later. So every field falls back to this, per field and never
|
|
8
|
+
* wholesale — an explicit record always wins, because the exporter that wrote
|
|
9
|
+
* it knew something the filter line does not say.
|
|
10
|
+
*
|
|
11
|
+
* A filter reads like
|
|
12
|
+
* `FTMS + p NSI Full ms2 194.5000@hcd50.00 [44.0860-220.4300]`, preceded by the
|
|
13
|
+
* raw file name and followed by `Scan #:` and `RT:` lines.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Read every field a conditions block states.
|
|
18
|
+
*
|
|
19
|
+
* Keyed by the same labels the metadata table uses, so a caller only has to
|
|
20
|
+
* look up the label it failed to fill — nothing here has to know which fields
|
|
21
|
+
* exist or what order they are shown in.
|
|
22
|
+
* @param conditions - The instrument's own scan description, verbatim.
|
|
23
|
+
* @returns The fields it states, by label; empty when it states none.
|
|
24
|
+
*/
|
|
25
|
+
export function parseScanFilter(conditions: string): Record<string, string> {
|
|
26
|
+
if (!conditions) return {};
|
|
27
|
+
const derived: Record<string, string> = {};
|
|
28
|
+
|
|
29
|
+
const analyser = group(/^(?<value>FTMS|ITMS|TOFMS)\b/m, conditions);
|
|
30
|
+
if (analyser) derived.Analyser = analyser;
|
|
31
|
+
|
|
32
|
+
const ionisation = group(/\b(?<value>ESI|NSI|APCI|MALDI)\b/, conditions);
|
|
33
|
+
if (ionisation) derived.Ionization = ionisation;
|
|
34
|
+
|
|
35
|
+
// The sign is read between the analyser and the ion source rather than on its
|
|
36
|
+
// own, because a bare `-` also separates the two ends of the scan range.
|
|
37
|
+
if (/(?:FTMS|ITMS|TOFMS) \+ /.test(conditions)) {
|
|
38
|
+
derived.Polarity = 'positive';
|
|
39
|
+
} else if (/(?:FTMS|ITMS|TOFMS) - /.test(conditions)) {
|
|
40
|
+
derived.Polarity = 'negative';
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
readFragmentation(conditions, derived);
|
|
44
|
+
|
|
45
|
+
const range = /\[(?<from>[\d.]+)-(?<to>[\d.]+)\]/.exec(conditions);
|
|
46
|
+
const from = range?.groups?.from;
|
|
47
|
+
const to = range?.groups?.to;
|
|
48
|
+
if (from !== undefined && to !== undefined) {
|
|
49
|
+
derived['Scan range'] = `${Number(from)}–${Number(to)} m/z`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const retentionTime = group(/^RT:\s*(?<value>.+)$/m, conditions);
|
|
53
|
+
if (retentionTime) derived['Retention time'] = `${retentionTime} min`;
|
|
54
|
+
|
|
55
|
+
const scans = group(/^Scan #:\s*(?<value>.+)$/m, conditions);
|
|
56
|
+
if (scans) derived.Scans = scans;
|
|
57
|
+
|
|
58
|
+
const rawFile = group(/^(?<value>\S+\.raw)$/m, conditions);
|
|
59
|
+
if (rawFile) derived['Raw file'] = rawFile;
|
|
60
|
+
|
|
61
|
+
return derived;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Read the level a scan was taken at, and what it isolated to get there.
|
|
66
|
+
*
|
|
67
|
+
* The level is read first and everything else only under it, because the
|
|
68
|
+
* isolation and the energy are the level's own clause: a survey scan that
|
|
69
|
+
* happens to be described one line below a product scan states no level of its
|
|
70
|
+
* own, and reading its `@hcd50.00` anyway would report a collision energy for a
|
|
71
|
+
* spectrum nothing was ever fragmented into.
|
|
72
|
+
*
|
|
73
|
+
* The level is not tied to the shape of that clause, though — `Full ms2
|
|
74
|
+
* 194.5000@etd` and `SIM ms [190.0000-200.0000]` are both real filters, and an
|
|
75
|
+
* MS2 that loses its level because the activation was spelled unusually loses
|
|
76
|
+
* the precursor the annotator would have searched for.
|
|
77
|
+
* @param conditions - The instrument's own scan description.
|
|
78
|
+
* @param derived - The fields read so far, added to in place.
|
|
79
|
+
*/
|
|
80
|
+
function readFragmentation(
|
|
81
|
+
conditions: string,
|
|
82
|
+
derived: Record<string, string>,
|
|
83
|
+
): void {
|
|
84
|
+
const level = /\b(?:Full|SIM|SRM) ms(?<level>\d*)\b/.exec(conditions)?.groups
|
|
85
|
+
?.level;
|
|
86
|
+
if (level === undefined) return;
|
|
87
|
+
if (level === '') {
|
|
88
|
+
derived['MS level'] = 'MS1';
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
derived['MS level'] = `MS${level}`;
|
|
92
|
+
|
|
93
|
+
// The isolation is anchored to the level the filter just stated, so an MS3
|
|
94
|
+
// reports the window it was isolated at rather than the one before it.
|
|
95
|
+
const isolation = group(
|
|
96
|
+
new RegExp(String.raw` ms${level} (?<value>\d+(?:\.\d+)?)`),
|
|
97
|
+
conditions,
|
|
98
|
+
);
|
|
99
|
+
if (isolation) derived['Isolation m/z'] = isolation;
|
|
100
|
+
|
|
101
|
+
const clause = /@(?<activation>[a-z]+)(?<energy>\d+(?:\.\d+)?)/.exec(
|
|
102
|
+
conditions,
|
|
103
|
+
);
|
|
104
|
+
const activation = clause?.groups?.activation;
|
|
105
|
+
const energy = clause?.groups?.energy;
|
|
106
|
+
if (activation !== undefined && energy !== undefined) {
|
|
107
|
+
derived['Collision energy'] = `${activation.toUpperCase()} ${energy}`;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* The `value` capture of a pattern, trimmed.
|
|
113
|
+
* @param pattern - A regular expression carrying a `value` named group.
|
|
114
|
+
* @param conditions - The text to read it out of.
|
|
115
|
+
* @returns The capture, or `''` when the pattern does not match.
|
|
116
|
+
*/
|
|
117
|
+
function group(pattern: RegExp, conditions: string): string {
|
|
118
|
+
return pattern.exec(conditions)?.groups?.value?.trim() ?? '';
|
|
119
|
+
}
|