react-cheminfo 0.65.0 → 0.66.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 +11 -6
- package/lib/i18n/core/chromeCatalog.d.ts +1 -1
- package/lib/i18n/core/chromeCatalog.d.ts.map +1 -1
- package/lib/ir/core/analysisSpectra.d.ts +23 -6
- package/lib/ir/core/analysisSpectra.d.ts.map +1 -1
- package/lib/ir/core/analysisSpectra.js.map +1 -1
- package/lib/ir/core/bandLabelPlan.d.ts.map +1 -1
- package/lib/ir/core/bandLabelPlan.js +11 -6
- package/lib/ir/core/bandLabelPlan.js.map +1 -1
- package/lib/ir/core/index.d.ts +13 -9
- package/lib/ir/core/index.d.ts.map +1 -1
- package/lib/ir/core/index.js +9 -6
- package/lib/ir/core/index.js.map +1 -1
- package/lib/ir/core/irBand.d.ts +45 -14
- package/lib/ir/core/irBand.d.ts.map +1 -1
- package/lib/ir/core/irBand.js +28 -6
- package/lib/ir/core/irBand.js.map +1 -1
- 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 +11 -1
- package/lib/ir/core/irCommands.js.map +1 -1
- package/lib/ir/core/irDomain.d.ts +4 -3
- package/lib/ir/core/irDomain.d.ts.map +1 -1
- package/lib/ir/core/irDomain.js +10 -7
- package/lib/ir/core/irDomain.js.map +1 -1
- package/lib/ir/core/irFormat.d.ts +14 -2
- package/lib/ir/core/irFormat.d.ts.map +1 -1
- package/lib/ir/core/irFormat.js +33 -4
- package/lib/ir/core/irFormat.js.map +1 -1
- package/lib/ir/core/irMode.d.ts +35 -8
- package/lib/ir/core/irMode.d.ts.map +1 -1
- package/lib/ir/core/irMode.js +38 -10
- package/lib/ir/core/irMode.js.map +1 -1
- package/lib/ir/core/irReducer.d.ts +0 -28
- package/lib/ir/core/irReducer.d.ts.map +1 -1
- package/lib/ir/core/irReducer.js +1 -24
- package/lib/ir/core/irReducer.js.map +1 -1
- package/lib/ir/core/irSpectrum.d.ts +52 -26
- package/lib/ir/core/irSpectrum.d.ts.map +1 -1
- package/lib/ir/core/irSpectrum.js +21 -15
- package/lib/ir/core/irSpectrum.js.map +1 -1
- package/lib/ir/core/irState.d.ts +40 -2
- package/lib/ir/core/irState.d.ts.map +1 -1
- package/lib/ir/core/irState.js +38 -1
- package/lib/ir/core/irState.js.map +1 -1
- package/lib/ir/core/irTechnique.d.ts +94 -0
- package/lib/ir/core/irTechnique.d.ts.map +1 -0
- package/lib/ir/core/irTechnique.js +87 -0
- package/lib/ir/core/irTechnique.js.map +1 -0
- package/lib/ir/core/irTechniqueCommands.d.ts +26 -0
- package/lib/ir/core/irTechniqueCommands.d.ts.map +1 -0
- package/lib/ir/core/irTechniqueCommands.js +68 -0
- package/lib/ir/core/irTechniqueCommands.js.map +1 -0
- package/lib/ir/core/pickBands.d.ts +6 -5
- package/lib/ir/core/pickBands.d.ts.map +1 -1
- package/lib/ir/core/pickBands.js +49 -26
- package/lib/ir/core/pickBands.js.map +1 -1
- package/lib/ir/core/ramanBands.d.ts +30 -0
- package/lib/ir/core/ramanBands.d.ts.map +1 -0
- package/lib/ir/core/ramanBands.js +83 -0
- package/lib/ir/core/ramanBands.js.map +1 -0
- package/lib/ir/core/spectrumJcamp.d.ts +10 -5
- package/lib/ir/core/spectrumJcamp.d.ts.map +1 -1
- package/lib/ir/core/spectrumJcamp.js +63 -15
- package/lib/ir/core/spectrumJcamp.js.map +1 -1
- package/lib/ir/core/toIrSpectrum.d.ts.map +1 -1
- package/lib/ir/core/toIrSpectrum.js +17 -2
- package/lib/ir/core/toIrSpectrum.js.map +1 -1
- package/lib/ir/ui/BandRow.d.ts +30 -0
- package/lib/ir/ui/BandRow.d.ts.map +1 -0
- package/lib/ir/ui/BandRow.js +42 -0
- package/lib/ir/ui/BandRow.js.map +1 -0
- package/lib/ir/ui/BandsPanel.d.ts +4 -0
- package/lib/ir/ui/BandsPanel.d.ts.map +1 -1
- package/lib/ir/ui/BandsPanel.js +14 -59
- package/lib/ir/ui/BandsPanel.js.map +1 -1
- package/lib/ir/ui/IrAboutDialog.d.ts +7 -0
- package/lib/ir/ui/IrAboutDialog.d.ts.map +1 -1
- package/lib/ir/ui/IrAboutDialog.js +16 -3
- package/lib/ir/ui/IrAboutDialog.js.map +1 -1
- package/lib/ir/ui/IrCanvas.d.ts.map +1 -1
- package/lib/ir/ui/IrCanvas.js +2 -2
- package/lib/ir/ui/IrCanvas.js.map +1 -1
- package/lib/ir/ui/IrChart.d.ts +2 -1
- package/lib/ir/ui/IrChart.d.ts.map +1 -1
- package/lib/ir/ui/IrChart.js +18 -21
- package/lib/ir/ui/IrChart.js.map +1 -1
- package/lib/ir/ui/IrCommandProvider.d.ts +7 -0
- package/lib/ir/ui/IrCommandProvider.d.ts.map +1 -1
- package/lib/ir/ui/IrCommandProvider.js +2 -2
- package/lib/ir/ui/IrCommandProvider.js.map +1 -1
- package/lib/ir/ui/IrCommandTooltip.d.ts +7 -0
- package/lib/ir/ui/IrCommandTooltip.d.ts.map +1 -1
- package/lib/ir/ui/IrCommandTooltip.js +3 -2
- package/lib/ir/ui/IrCommandTooltip.js.map +1 -1
- package/lib/ir/ui/IrDocumentationDialog.d.ts +8 -1
- package/lib/ir/ui/IrDocumentationDialog.d.ts.map +1 -1
- package/lib/ir/ui/IrDocumentationDialog.js +30 -7
- package/lib/ir/ui/IrDocumentationDialog.js.map +1 -1
- package/lib/ir/ui/IrEditor.d.ts +3 -1
- package/lib/ir/ui/IrEditor.d.ts.map +1 -1
- package/lib/ir/ui/IrEditor.js +3 -20
- package/lib/ir/ui/IrEditor.js.map +1 -1
- package/lib/ir/ui/IrHeader.d.ts.map +1 -1
- package/lib/ir/ui/IrHeader.js +5 -1
- package/lib/ir/ui/IrHeader.js.map +1 -1
- package/lib/ir/ui/IrLogo.d.ts +11 -3
- package/lib/ir/ui/IrLogo.d.ts.map +1 -1
- package/lib/ir/ui/IrLogo.js +14 -5
- package/lib/ir/ui/IrLogo.js.map +1 -1
- package/lib/ir/ui/IrShell.d.ts.map +1 -1
- package/lib/ir/ui/IrShell.js +23 -56
- package/lib/ir/ui/IrShell.js.map +1 -1
- package/lib/ir/ui/IrStatusBar.d.ts +3 -2
- package/lib/ir/ui/IrStatusBar.d.ts.map +1 -1
- package/lib/ir/ui/IrStatusBar.js +14 -9
- package/lib/ir/ui/IrStatusBar.js.map +1 -1
- package/lib/ir/ui/IrToolbar.d.ts +3 -0
- package/lib/ir/ui/IrToolbar.d.ts.map +1 -1
- package/lib/ir/ui/IrToolbar.js +10 -3
- package/lib/ir/ui/IrToolbar.js.map +1 -1
- package/lib/ir/ui/IrTraces.d.ts +4 -1
- package/lib/ir/ui/IrTraces.d.ts.map +1 -1
- package/lib/ir/ui/IrTraces.js +2 -0
- package/lib/ir/ui/IrTraces.js.map +1 -1
- package/lib/ir/ui/RamanEditor.d.ts +46 -0
- package/lib/ir/ui/RamanEditor.d.ts.map +1 -0
- package/lib/ir/ui/RamanEditor.js +17 -0
- package/lib/ir/ui/RamanEditor.js.map +1 -0
- package/lib/ir/ui/SpectraPanel.d.ts.map +1 -1
- package/lib/ir/ui/SpectraPanel.js +2 -2
- package/lib/ir/ui/SpectraPanel.js.map +1 -1
- package/lib/ir/ui/SpectrumRow.d.ts +7 -0
- package/lib/ir/ui/SpectrumRow.d.ts.map +1 -1
- package/lib/ir/ui/SpectrumRow.js +4 -5
- package/lib/ir/ui/SpectrumRow.js.map +1 -1
- package/lib/ir/ui/VibrationalEditor.d.ts +48 -0
- package/lib/ir/ui/VibrationalEditor.d.ts.map +1 -0
- package/lib/ir/ui/VibrationalEditor.js +31 -0
- package/lib/ir/ui/VibrationalEditor.js.map +1 -0
- package/lib/ir/ui/bandsTsv.d.ts +19 -0
- package/lib/ir/ui/bandsTsv.d.ts.map +1 -0
- package/lib/ir/ui/bandsTsv.js +38 -0
- package/lib/ir/ui/bandsTsv.js.map +1 -0
- package/lib/ir/ui/irChartProps.d.ts +14 -4
- package/lib/ir/ui/irChartProps.d.ts.map +1 -1
- package/lib/ir/ui/irChartProps.js +3 -2
- package/lib/ir/ui/irChartProps.js.map +1 -1
- package/lib/ir/ui/irCommandContext.d.ts +8 -0
- package/lib/ir/ui/irCommandContext.d.ts.map +1 -1
- package/lib/ir/ui/irCommandContext.js +14 -3
- package/lib/ir/ui/irCommandContext.js.map +1 -1
- package/lib/ir/ui/useIrEditor.d.ts +3 -3
- package/lib/ir/ui/useIrEditor.d.ts.map +1 -1
- package/lib/ir/ui/useIrEditor.js +13 -4
- package/lib/ir/ui/useIrEditor.js.map +1 -1
- package/lib/ir/ui/useIrHandle.d.ts +14 -0
- package/lib/ir/ui/useIrHandle.d.ts.map +1 -0
- package/lib/ir/ui/useIrHandle.js +39 -0
- package/lib/ir/ui/useIrHandle.js.map +1 -0
- package/lib/ir/ui/useIrText.d.ts +40 -0
- package/lib/ir/ui/useIrText.d.ts.map +1 -0
- package/lib/ir/ui/useIrText.js +118 -0
- package/lib/ir/ui/useIrText.js.map +1 -0
- package/lib/ir/ui/useIrZoom.d.ts +7 -0
- package/lib/ir/ui/useIrZoom.d.ts.map +1 -1
- package/lib/ir/ui/useIrZoom.js +5 -4
- package/lib/ir/ui/useIrZoom.js.map +1 -1
- package/lib/ir/ui/useValueAxisZoom.d.ts +20 -0
- package/lib/ir/ui/useValueAxisZoom.d.ts.map +1 -0
- package/lib/ir/ui/useValueAxisZoom.js +54 -0
- package/lib/ir/ui/useValueAxisZoom.js.map +1 -0
- package/lib/ir.d.ts +3 -0
- package/lib/ir.d.ts.map +1 -1
- package/lib/ir.js +3 -0
- package/lib/ir.js.map +1 -1
- package/lib/locales/de.json +20 -1
- package/lib/locales/en.json +20 -1
- package/lib/locales/es.json +20 -1
- package/lib/locales/fr.json +20 -1
- package/lib/locales/it.json +20 -1
- package/lib/raman.d.ts +16 -0
- package/lib/raman.d.ts.map +1 -0
- package/lib/raman.js +12 -0
- package/lib/raman.js.map +1 -0
- package/package.json +2 -1
- package/src/ir/core/analysisSpectra.ts +26 -10
- package/src/ir/core/bandLabelPlan.ts +21 -10
- package/src/ir/core/index.ts +25 -5
- package/src/ir/core/irBand.ts +52 -14
- package/src/ir/core/irCommands.ts +15 -1
- package/src/ir/core/irDomain.ts +9 -7
- package/src/ir/core/irFormat.ts +39 -6
- package/src/ir/core/irMode.ts +42 -10
- package/src/ir/core/irReducer.ts +1 -49
- package/src/ir/core/irSpectrum.ts +59 -30
- package/src/ir/core/irState.ts +67 -2
- package/src/ir/core/irTechnique.ts +115 -0
- package/src/ir/core/irTechniqueCommands.ts +82 -0
- package/src/ir/core/pickBands.ts +63 -28
- package/src/ir/core/ramanBands.ts +105 -0
- package/src/ir/core/spectrumJcamp.ts +65 -16
- package/src/ir/core/toIrSpectrum.ts +20 -2
- package/src/ir/ui/BandRow.tsx +107 -0
- package/src/ir/ui/BandsPanel.tsx +32 -125
- package/src/ir/ui/IrAboutDialog.tsx +69 -28
- package/src/ir/ui/IrCanvas.tsx +2 -1
- package/src/ir/ui/IrChart.tsx +20 -24
- package/src/ir/ui/IrCommandProvider.tsx +10 -3
- package/src/ir/ui/IrCommandTooltip.tsx +11 -2
- package/src/ir/ui/IrDocumentationDialog.tsx +99 -55
- package/src/ir/ui/IrEditor.tsx +5 -36
- package/src/ir/ui/IrHeader.tsx +10 -3
- package/src/ir/ui/IrLogo.tsx +28 -9
- package/src/ir/ui/IrShell.tsx +27 -75
- package/src/ir/ui/IrStatusBar.tsx +17 -12
- package/src/ir/ui/IrToolbar.tsx +26 -15
- package/src/ir/ui/IrTraces.tsx +5 -1
- package/src/ir/ui/RamanEditor.tsx +53 -0
- package/src/ir/ui/SpectraPanel.tsx +2 -1
- package/src/ir/ui/SpectrumRow.tsx +14 -5
- package/src/ir/ui/VibrationalEditor.tsx +94 -0
- package/src/ir/ui/bandsTsv.ts +46 -0
- package/src/ir/ui/irChartProps.ts +14 -4
- package/src/ir/ui/irCommandContext.tsx +18 -3
- package/src/ir/ui/useIrEditor.ts +20 -8
- package/src/ir/ui/useIrHandle.ts +51 -0
- package/src/ir/ui/useIrText.ts +170 -0
- package/src/ir/ui/useIrZoom.ts +12 -3
- package/src/ir/ui/useValueAxisZoom.ts +67 -0
- package/src/ir.ts +3 -0
- package/src/locales/de.json +20 -1
- package/src/locales/en.json +20 -1
- package/src/locales/es.json +20 -1
- package/src/locales/fr.json +20 -1
- package/src/locales/it.json +20 -1
- package/src/raman.ts +19 -0
|
@@ -14,14 +14,31 @@ import { xySortX } from 'ml-spectra-processing';
|
|
|
14
14
|
|
|
15
15
|
import type { IrMeta, IrMode, IrOrigin } from './irSpectrum.ts';
|
|
16
16
|
|
|
17
|
-
/**
|
|
17
|
+
/**
|
|
18
|
+
* One spectrum as a reader produced it, before it is named and coloured.
|
|
19
|
+
*
|
|
20
|
+
* The readers of this package produce infrared spectra, which carry absorbance
|
|
21
|
+
* and transmittance; a host reading a Raman file builds one carrying its
|
|
22
|
+
* intensity instead.
|
|
23
|
+
*/
|
|
18
24
|
export interface LoadedIrSpectrum {
|
|
19
|
-
/** The wavenumbers, ascending. */
|
|
25
|
+
/** The wavenumbers — or, for a Raman spectrum, the Raman shifts — ascending. */
|
|
20
26
|
wavenumber: Float64Array;
|
|
21
|
-
/**
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Absorbance at each, for an infrared spectrum.
|
|
29
|
+
* @default undefined
|
|
30
|
+
*/
|
|
31
|
+
absorbance?: Float64Array;
|
|
32
|
+
/**
|
|
33
|
+
* Percent transmittance at each, for an infrared spectrum.
|
|
34
|
+
* @default undefined
|
|
35
|
+
*/
|
|
36
|
+
transmittance?: Float64Array;
|
|
37
|
+
/**
|
|
38
|
+
* Intensity at each, for a Raman spectrum.
|
|
39
|
+
* @default undefined
|
|
40
|
+
*/
|
|
41
|
+
intensity?: Float64Array;
|
|
25
42
|
/** What the file said about the acquisition, `null` when it said nothing. */
|
|
26
43
|
meta: IrMeta | null;
|
|
27
44
|
/** Where it came from. */
|
|
@@ -96,10 +113,9 @@ export function analysisSpectra(
|
|
|
96
113
|
return spectra;
|
|
97
114
|
}
|
|
98
115
|
|
|
99
|
-
/** The three arrays of one spectrum, in ascending wavenumber. */
|
|
100
|
-
type SortedTraces =
|
|
101
|
-
LoadedIrSpectrum,
|
|
102
|
-
'wavenumber' | 'absorbance' | 'transmittance'
|
|
116
|
+
/** The three arrays of one infrared spectrum, in ascending wavenumber. */
|
|
117
|
+
type SortedTraces = Required<
|
|
118
|
+
Pick<LoadedIrSpectrum, 'wavenumber' | 'absorbance' | 'transmittance'>
|
|
103
119
|
>;
|
|
104
120
|
|
|
105
121
|
/**
|
|
@@ -18,6 +18,7 @@ import { labelStackBaselines } from '../../chart/core/labelStack.ts';
|
|
|
18
18
|
import type { AssignedBand } from './assignBands.ts';
|
|
19
19
|
import { bandLabel } from './assignBands.ts';
|
|
20
20
|
import type { IrBand } from './irBand.ts';
|
|
21
|
+
import { bandHeight, bandValue } from './irBand.ts';
|
|
21
22
|
import { formatWavenumber } from './irFormat.ts';
|
|
22
23
|
import { bandsPointDown } from './irMode.ts';
|
|
23
24
|
import type { IrMode } from './irSpectrum.ts';
|
|
@@ -99,12 +100,15 @@ export function planBandLabels(options: BandLabelPlanOptions): BandLabelPlan[] {
|
|
|
99
100
|
limit = 12,
|
|
100
101
|
} = options;
|
|
101
102
|
|
|
102
|
-
const inside:
|
|
103
|
+
const inside: NamedBand[] = [];
|
|
103
104
|
for (const entry of assigned) {
|
|
105
|
+
// A band with no value on the axis being read has no tip to hang from.
|
|
106
|
+
const value = bandValue(entry.band, mode);
|
|
107
|
+
if (value === undefined) continue;
|
|
104
108
|
const pixelX = chartPixel(xScale, entry.band.wavenumber);
|
|
105
109
|
if (!Number.isFinite(pixelX)) continue;
|
|
106
110
|
if (pixelX < plot.left || pixelX > plot.right) continue;
|
|
107
|
-
inside.push(entry);
|
|
111
|
+
inside.push({ entry, value });
|
|
108
112
|
}
|
|
109
113
|
|
|
110
114
|
const named =
|
|
@@ -112,18 +116,20 @@ export function planBandLabels(options: BandLabelPlanOptions): BandLabelPlan[] {
|
|
|
112
116
|
? inside
|
|
113
117
|
: inside
|
|
114
118
|
.toSorted(
|
|
115
|
-
(first, second) =>
|
|
119
|
+
(first, second) =>
|
|
120
|
+
bandHeight(second.entry.band) - bandHeight(first.entry.band),
|
|
116
121
|
)
|
|
117
122
|
.slice(0, limit)
|
|
118
123
|
.toSorted(
|
|
119
|
-
(first, second) =>
|
|
124
|
+
(first, second) =>
|
|
125
|
+
first.entry.band.wavenumber - second.entry.band.wavenumber,
|
|
120
126
|
);
|
|
121
127
|
|
|
122
128
|
const centres = new Float64Array(named.length);
|
|
123
129
|
for (let index = 0; index < named.length; index++) {
|
|
124
130
|
centres[index] = chartPixel(
|
|
125
131
|
xScale,
|
|
126
|
-
(named[index] as
|
|
132
|
+
(named[index] as NamedBand).entry.band.wavenumber,
|
|
127
133
|
);
|
|
128
134
|
}
|
|
129
135
|
const placed = layoutAnnotationBoxes(
|
|
@@ -136,12 +142,9 @@ export function planBandLabels(options: BandLabelPlanOptions): BandLabelPlan[] {
|
|
|
136
142
|
const down = bandsPointDown(mode);
|
|
137
143
|
const plans: BandLabelPlan[] = new Array<BandLabelPlan>(named.length);
|
|
138
144
|
for (let index = 0; index < named.length; index++) {
|
|
139
|
-
const entry = named[index] as
|
|
145
|
+
const { entry, value } = named[index] as NamedBand;
|
|
140
146
|
const lines = labelLines(entry, showAssignments);
|
|
141
|
-
const tipY = chartPixel(
|
|
142
|
-
yScale,
|
|
143
|
-
mode === 'absorbance' ? entry.band.absorbance : entry.band.transmittance,
|
|
144
|
-
);
|
|
147
|
+
const tipY = chartPixel(yScale, value);
|
|
145
148
|
plans[index] = {
|
|
146
149
|
band: entry.band,
|
|
147
150
|
tipX: centres[index] as number,
|
|
@@ -161,6 +164,14 @@ export function planBandLabels(options: BandLabelPlanOptions): BandLabelPlan[] {
|
|
|
161
164
|
return plans;
|
|
162
165
|
}
|
|
163
166
|
|
|
167
|
+
/** A band inside the window, with its value on the axis being read. */
|
|
168
|
+
interface NamedBand {
|
|
169
|
+
/** The band and whatever the table said about it. */
|
|
170
|
+
entry: AssignedBand;
|
|
171
|
+
/** Where its tip is, on the value axis. */
|
|
172
|
+
value: number;
|
|
173
|
+
}
|
|
174
|
+
|
|
164
175
|
/**
|
|
165
176
|
* How wide a label is taken to be while it is being spaced out.
|
|
166
177
|
*
|
package/src/ir/core/index.ts
CHANGED
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
* transmittance and a band points the other way in each, and that a wavenumber
|
|
11
11
|
* maps to a range of vibrations rather than to one. Nothing here knows what a
|
|
12
12
|
* glycan is, and nothing should: an infrared spectrum answers for whatever was
|
|
13
|
-
* put in the beam.
|
|
13
|
+
* put in the beam. A Raman spectrum is the one other technique held, and what
|
|
14
|
+
* differs for it is in `IR_TECHNIQUE_RULES`.
|
|
14
15
|
*/
|
|
15
16
|
|
|
16
17
|
export type { LoadedIrSpectrum } from './analysisSpectra.ts';
|
|
@@ -26,16 +27,22 @@ export { downloadIrSpectra, downloadIrSpectrum } from './downloadSpectra.ts';
|
|
|
26
27
|
export type { IrJcampReadOptions } from './fromJcamp.ts';
|
|
27
28
|
export type { IrSpcReadOptions } from './fromSpc.ts';
|
|
28
29
|
export type { IrBand, IrBandStrength } from './irBand.ts';
|
|
29
|
-
export { sameIrBand } from './irBand.ts';
|
|
30
|
+
export { bandHeight, bandValue, sameIrBand } from './irBand.ts';
|
|
30
31
|
export type {
|
|
31
32
|
IrCommand,
|
|
32
33
|
IrCommandHandlers,
|
|
33
34
|
IrCommandId,
|
|
35
|
+
IrCommandTable,
|
|
34
36
|
IrGesture,
|
|
35
37
|
IrShortcut,
|
|
36
38
|
RunIrCommand,
|
|
37
39
|
} from './irCommands.ts';
|
|
38
|
-
export {
|
|
40
|
+
export {
|
|
41
|
+
irCommandEntryLabel,
|
|
42
|
+
irCommandLabel,
|
|
43
|
+
irCommands,
|
|
44
|
+
} from './irCommands.ts';
|
|
45
|
+
export { irCommandOffered, irCommandsFor } from './irTechniqueCommands.ts';
|
|
39
46
|
export {
|
|
40
47
|
LABEL_HEADROOM,
|
|
41
48
|
X_DOMAIN_PADDING,
|
|
@@ -46,9 +53,11 @@ export {
|
|
|
46
53
|
export type { IrEditorHandle, ZoomToBandOptions } from './irEditorApi.ts';
|
|
47
54
|
export {
|
|
48
55
|
ABSORBANCE_DECIMALS,
|
|
56
|
+
INTENSITY_DIGITS,
|
|
49
57
|
TRANSMITTANCE_DECIMALS,
|
|
50
58
|
formatIrValue,
|
|
51
59
|
formatWavenumber,
|
|
60
|
+
formatWavenumberRange,
|
|
52
61
|
shortModeLabel,
|
|
53
62
|
} from './irFormat.ts';
|
|
54
63
|
export {
|
|
@@ -61,8 +70,8 @@ export {
|
|
|
61
70
|
yAxisTitle,
|
|
62
71
|
zoomGestures,
|
|
63
72
|
} from './irMode.ts';
|
|
64
|
-
export type {
|
|
65
|
-
export {
|
|
73
|
+
export type { IrAction } from './irReducer.ts';
|
|
74
|
+
export { irReducer } from './irReducer.ts';
|
|
66
75
|
export type {
|
|
67
76
|
IrDomain,
|
|
68
77
|
IrFormat,
|
|
@@ -75,6 +84,7 @@ export type {
|
|
|
75
84
|
} from './irSpectrum.ts';
|
|
76
85
|
export { traceOf } from './irSpectrum.ts';
|
|
77
86
|
export type {
|
|
87
|
+
CreateIrStateOptions,
|
|
78
88
|
IrData,
|
|
79
89
|
IrSettings,
|
|
80
90
|
IrState,
|
|
@@ -89,9 +99,19 @@ export {
|
|
|
89
99
|
DEFAULT_SIDE_PANEL,
|
|
90
100
|
DEFAULT_SIDE_PANELS,
|
|
91
101
|
MAXIMUM_LABEL_LIMIT,
|
|
102
|
+
createIrState,
|
|
92
103
|
isIrWindow,
|
|
93
104
|
mergeIrSettings,
|
|
94
105
|
} from './irState.ts';
|
|
106
|
+
export type { IrTechnique, IrTechniqueRules } from './irTechnique.ts';
|
|
107
|
+
export {
|
|
108
|
+
IR_TECHNIQUES,
|
|
109
|
+
IR_TECHNIQUE_RULES,
|
|
110
|
+
defaultIrMode,
|
|
111
|
+
irModeFor,
|
|
112
|
+
irModeTechnique,
|
|
113
|
+
offersIrMode,
|
|
114
|
+
} from './irTechnique.ts';
|
|
95
115
|
export type {
|
|
96
116
|
LoadIrSpectraOptions,
|
|
97
117
|
LoadIrSpectraResult,
|
package/src/ir/core/irBand.ts
CHANGED
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* One band picked out of a spectrum.
|
|
3
3
|
*
|
|
4
|
-
* A band is the
|
|
5
|
-
* points at, names, and reads a functional group off.
|
|
6
|
-
* for the same reason
|
|
7
|
-
* transmittance and the one a table calls strongly
|
|
8
|
-
* making the caller convert to find out would be the
|
|
9
|
-
* does not do.
|
|
4
|
+
* A band is the vibrational analogue of a mass spectrum's peak: the thing a
|
|
5
|
+
* chemist points at, names, and reads a functional group off. An infrared band
|
|
6
|
+
* carries both value axes for the same reason its spectrum does — the band a
|
|
7
|
+
* reader sees at 30 percent transmittance and the one a table calls strongly
|
|
8
|
+
* absorbing are one band, and making the caller convert to find out would be the
|
|
9
|
+
* conversion this package does not do. A Raman band carries its intensity.
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
+
import type { IrMode } from './irSpectrum.ts';
|
|
13
|
+
|
|
12
14
|
/**
|
|
13
15
|
* How strong a band is, in the letters a correlation table uses.
|
|
14
16
|
*
|
|
15
|
-
* `w` weak, `m` medium, `S` strong —
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
17
|
+
* `w` weak, `m` medium, `S` strong — decided from where the band sits between
|
|
18
|
+
* the spectrum's own extremes, so the letters are relative to the spectrum in
|
|
19
|
+
* hand rather than to an absolute value. That is what a printed table means by
|
|
20
|
+
* them too. `ir-spectrum` decides it for an infrared band from its
|
|
21
|
+
* transmittance, and the same rule is applied to a Raman band's intensity.
|
|
19
22
|
*/
|
|
20
23
|
export type IrBandStrength = 'w' | 'm' | 'S';
|
|
21
24
|
|
|
@@ -25,10 +28,21 @@ export interface IrBand {
|
|
|
25
28
|
spectrumId: string;
|
|
26
29
|
/** Where it sits, in cm⁻¹. */
|
|
27
30
|
wavenumber: number;
|
|
28
|
-
/**
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Its absorbance, which an infrared band is picked as a maximum of.
|
|
33
|
+
* @default undefined
|
|
34
|
+
*/
|
|
35
|
+
absorbance?: number;
|
|
36
|
+
/**
|
|
37
|
+
* Its percent transmittance, the same infrared band read the other way up.
|
|
38
|
+
* @default undefined
|
|
39
|
+
*/
|
|
40
|
+
transmittance?: number;
|
|
41
|
+
/**
|
|
42
|
+
* Its intensity, which a Raman band is picked as a maximum of.
|
|
43
|
+
* @default undefined
|
|
44
|
+
*/
|
|
45
|
+
intensity?: number;
|
|
32
46
|
/** How strong it is, relative to the spectrum it came from. */
|
|
33
47
|
strength: IrBandStrength;
|
|
34
48
|
}
|
|
@@ -55,3 +69,27 @@ export function sameIrBand(
|
|
|
55
69
|
current.wavenumber === next.wavenumber
|
|
56
70
|
);
|
|
57
71
|
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* A band's value on the axis being read.
|
|
75
|
+
* @param band - The band.
|
|
76
|
+
* @param mode - Which value axis is being read.
|
|
77
|
+
* @returns The value, or `undefined` when its spectrum carries no such axis.
|
|
78
|
+
*/
|
|
79
|
+
export function bandValue(band: IrBand, mode: IrMode): number | undefined {
|
|
80
|
+
return band[mode];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* How tall a band stands, which is what a cut to the strongest bands ranks by.
|
|
85
|
+
*
|
|
86
|
+
* The value it was picked as a maximum of: its absorbance for an infrared band,
|
|
87
|
+
* its intensity for a Raman one. Never its transmittance, in which a stronger
|
|
88
|
+
* band is a smaller number.
|
|
89
|
+
* @param band - The band.
|
|
90
|
+
* @returns The height, or negative infinity for a band carrying neither, so it
|
|
91
|
+
* ranks last.
|
|
92
|
+
*/
|
|
93
|
+
export function bandHeight(band: IrBand): number {
|
|
94
|
+
return band.absorbance ?? band.intensity ?? Number.NEGATIVE_INFINITY;
|
|
95
|
+
}
|
|
@@ -10,6 +10,9 @@
|
|
|
10
10
|
* this one, because a module that exports a component and a constant together
|
|
11
11
|
* cannot be hot reloaded — `react-refresh/only-export-components` is the rule
|
|
12
12
|
* that says so, and the split is the fix rather than the exception.
|
|
13
|
+
*
|
|
14
|
+
* This is the infrared table; `irTechniqueCommands.ts` derives the Raman one
|
|
15
|
+
* from it.
|
|
13
16
|
*/
|
|
14
17
|
|
|
15
18
|
/** The key a command answers to. */
|
|
@@ -134,6 +137,9 @@ export const irCommands = {
|
|
|
134
137
|
/** Identity of one of the commands the viewer offers. */
|
|
135
138
|
export type IrCommandId = keyof typeof irCommands;
|
|
136
139
|
|
|
140
|
+
/** The commands a viewer offers, in the order they are reached for. */
|
|
141
|
+
export type IrCommandTable = Readonly<Partial<Record<IrCommandId, IrCommand>>>;
|
|
142
|
+
|
|
137
143
|
/** What to do when each command is run, as the shell wires them. */
|
|
138
144
|
export type IrCommandHandlers = Partial<
|
|
139
145
|
Record<IrCommandId, (() => void) | undefined>
|
|
@@ -148,7 +154,15 @@ export type RunIrCommand = (id: IrCommandId) => void;
|
|
|
148
154
|
* @returns The title, and the key in parentheses when it has one.
|
|
149
155
|
*/
|
|
150
156
|
export function irCommandLabel(id: IrCommandId): string {
|
|
151
|
-
|
|
157
|
+
return irCommandEntryLabel(irCommands[id]);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* A command's title, with its key in parentheses when it has one.
|
|
162
|
+
* @param entry - The command, as a table words it.
|
|
163
|
+
* @returns The label.
|
|
164
|
+
*/
|
|
165
|
+
export function irCommandEntryLabel(entry: IrCommand): string {
|
|
152
166
|
const key = entry.shortcut?.label?.[0] ?? entry.shortcut?.keys[0];
|
|
153
167
|
return key === undefined ? entry.title : `${entry.title} (${key})`;
|
|
154
168
|
}
|
package/src/ir/core/irDomain.ts
CHANGED
|
@@ -5,9 +5,10 @@
|
|
|
5
5
|
* something usable when it is handed nothing at all — a chart with no data is
|
|
6
6
|
* still mounted, still measured, and still builds its scales.
|
|
7
7
|
*
|
|
8
|
-
* The x window is in ascending wavenumbers even though the axis is
|
|
9
|
-
* 4000 down to 400: which way round it is read is the chart's
|
|
10
|
-
* every piece of arithmetic that moves a window expects its ends
|
|
8
|
+
* The x window is in ascending wavenumbers even though the infrared axis is
|
|
9
|
+
* drawn from 4000 down to 400: which way round it is read is the chart's
|
|
10
|
+
* business, and every piece of arithmetic that moves a window expects its ends
|
|
11
|
+
* in order.
|
|
11
12
|
*/
|
|
12
13
|
|
|
13
14
|
import { xMaxValue, xMinValue } from 'ml-spectra-processing';
|
|
@@ -57,9 +58,8 @@ export function fullDomain(
|
|
|
57
58
|
const extent =
|
|
58
59
|
traceExtent(spectra, mode, false) ?? traceExtent(spectra, mode, true);
|
|
59
60
|
if (extent === null) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
: { x: [400, 4000], y: [0, 100] };
|
|
61
|
+
// A percentage runs to 100; absorbance and intensity are open at the top.
|
|
62
|
+
return { x: [400, 4000], y: mode === 'transmittance' ? [0, 100] : [0, 1] };
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
const { xMinimum, xMaximum, yMinimum, yMaximum } = extent;
|
|
@@ -135,7 +135,9 @@ function traceExtent(
|
|
|
135
135
|
for (const spectrum of spectra) {
|
|
136
136
|
if (!spectrum.visible) continue;
|
|
137
137
|
if (!includeExcluded && spectrum.excludeFromDomain) continue;
|
|
138
|
-
const
|
|
138
|
+
const trace = traceOf(spectrum, mode);
|
|
139
|
+
if (trace === undefined) continue;
|
|
140
|
+
const { x, y } = trace;
|
|
139
141
|
if (x.length === 0 || y.length === 0) continue;
|
|
140
142
|
// The wavenumber ends are read off the first and last sample rather than
|
|
141
143
|
// searched for: the array is ascending by construction, so a scan would walk
|
package/src/ir/core/irFormat.ts
CHANGED
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
* row that calls it 1714.6 read as two bands.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
+
import { formatTrimmed } from '../../format/core/numbers.ts';
|
|
10
|
+
|
|
9
11
|
import type { IrMode } from './irSpectrum.ts';
|
|
10
12
|
|
|
11
13
|
/** How many decimals an absorbance is written to. */
|
|
@@ -14,6 +16,9 @@ export const ABSORBANCE_DECIMALS = 3;
|
|
|
14
16
|
/** How many a percent transmittance is written to. */
|
|
15
17
|
export const TRANSMITTANCE_DECIMALS = 1;
|
|
16
18
|
|
|
19
|
+
/** How many significant digits an intensity is written to. */
|
|
20
|
+
export const INTENSITY_DIGITS = 4;
|
|
21
|
+
|
|
17
22
|
/**
|
|
18
23
|
* Write a wavenumber the way a chemist quotes one.
|
|
19
24
|
*
|
|
@@ -35,23 +40,51 @@ export function formatWavenumber(wavenumber: number): string {
|
|
|
35
40
|
* Three decimals for an absorbance and one for a percent transmittance, which is
|
|
36
41
|
* roughly the same precision expressed two ways — an absorbance of 0.001 and a
|
|
37
42
|
* transmittance of 0.2 percent are both about where a real spectrum's noise
|
|
38
|
-
* sits.
|
|
43
|
+
* sits. An intensity is counts from one instrument and a fraction of the
|
|
44
|
+
* strongest band from another, so no count of decimals suits it: it keeps
|
|
45
|
+
* `INTENSITY_DIGITS` significant digits instead.
|
|
39
46
|
* @param value - The value.
|
|
40
47
|
* @param mode - Which axis it is in.
|
|
41
48
|
* @returns The number as a string, without its unit.
|
|
42
49
|
*/
|
|
43
50
|
export function formatIrValue(value: number, mode: IrMode): string {
|
|
44
51
|
if (!Number.isFinite(value)) return '';
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
52
|
+
const { decimals } = VALUE_FORMATS[mode];
|
|
53
|
+
return decimals === undefined
|
|
54
|
+
? formatTrimmed(value, { significant: INTENSITY_DIGITS })
|
|
55
|
+
: value.toFixed(decimals);
|
|
48
56
|
}
|
|
49
57
|
|
|
50
58
|
/**
|
|
51
59
|
* What the value axis is called where there is room for one word.
|
|
52
60
|
* @param mode - Which axis is being drawn.
|
|
53
|
-
* @returns `A` or
|
|
61
|
+
* @returns `A`, `%T` or `I`, as a spectrum is annotated by hand.
|
|
54
62
|
*/
|
|
55
63
|
export function shortModeLabel(mode: IrMode): string {
|
|
56
|
-
return mode
|
|
64
|
+
return VALUE_FORMATS[mode].symbol;
|
|
57
65
|
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* The range a spectrum covers, written in the order its axis is read.
|
|
69
|
+
* @param wavenumbers - Its wavenumbers, ascending.
|
|
70
|
+
* @param reversed - Whether the axis runs from high to low, as infrared's does.
|
|
71
|
+
* @returns `4000–400 cm⁻¹` on a reversed axis, `100–3200 cm⁻¹` on one that is
|
|
72
|
+
* not, and an empty string for a spectrum with no point.
|
|
73
|
+
*/
|
|
74
|
+
export function formatWavenumberRange(
|
|
75
|
+
wavenumbers: Float64Array,
|
|
76
|
+
reversed: boolean,
|
|
77
|
+
): string {
|
|
78
|
+
const lowest = wavenumbers[0];
|
|
79
|
+
const highest = wavenumbers.at(-1);
|
|
80
|
+
if (lowest === undefined || highest === undefined) return '';
|
|
81
|
+
const [first, last] = reversed ? [highest, lowest] : [lowest, highest];
|
|
82
|
+
return `${formatWavenumber(first)}–${formatWavenumber(last)} cm⁻¹`;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** How each value axis is written: its symbol, and its count of decimals. */
|
|
86
|
+
const VALUE_FORMATS: Record<IrMode, { symbol: string; decimals?: number }> = {
|
|
87
|
+
transmittance: { symbol: '%T', decimals: TRANSMITTANCE_DECIMALS },
|
|
88
|
+
absorbance: { symbol: 'A', decimals: ABSORBANCE_DECIMALS },
|
|
89
|
+
intensity: { symbol: 'I' },
|
|
90
|
+
};
|
package/src/ir/core/irMode.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Everything that differs between reading a spectrum as absorbance
|
|
3
|
-
*
|
|
2
|
+
* Everything that differs between reading a spectrum as absorbance, as percent
|
|
3
|
+
* transmittance, or — for a Raman spectrum — as intensity.
|
|
4
4
|
*
|
|
5
|
-
* The two are the same measurement drawn upside down, and nearly every
|
|
5
|
+
* The first two are the same measurement drawn upside down, and nearly every
|
|
6
6
|
* difference between them is one of a handful of facts: what the axis is called,
|
|
7
7
|
* where its baseline is, whether that baseline is held in the window, which way
|
|
8
8
|
* a band points, and which zoom gestures are worth answering. Gathering them
|
|
9
9
|
* here is what keeps the switch from being an `if (mode === …)` in the chart,
|
|
10
10
|
* the tracker, the band marks, the zoom and the fitting separately, where they
|
|
11
|
-
* would eventually disagree.
|
|
11
|
+
* would eventually disagree. Intensity is one more entry of the same facts.
|
|
12
12
|
*
|
|
13
13
|
* **No conversion happens here, or anywhere in this package.** `ir-spectrum`
|
|
14
14
|
* adds both an absorbance and a transmittance variable to every spectrum it
|
|
@@ -24,9 +24,14 @@ import type {
|
|
|
24
24
|
} from '../../chart/core/chartDomain.ts';
|
|
25
25
|
|
|
26
26
|
import type { IrMode } from './irSpectrum.ts';
|
|
27
|
+
import type { IrTechnique } from './irTechnique.ts';
|
|
28
|
+
import { IR_TECHNIQUE_RULES, irModeTechnique } from './irTechnique.ts';
|
|
27
29
|
|
|
28
|
-
/**
|
|
29
|
-
|
|
30
|
+
/**
|
|
31
|
+
* The two ways an infrared spectrum is read, in the order a control offers
|
|
32
|
+
* them.
|
|
33
|
+
*/
|
|
34
|
+
export const IR_MODES: readonly IrMode[] = IR_TECHNIQUE_RULES.infrared.modes;
|
|
30
35
|
|
|
31
36
|
/**
|
|
32
37
|
* How each mode behaves, every fact in one place.
|
|
@@ -115,6 +120,22 @@ export const IR_MODE_RULES = {
|
|
|
115
120
|
*/
|
|
116
121
|
wheelZoom: true,
|
|
117
122
|
},
|
|
123
|
+
intensity: {
|
|
124
|
+
title: 'intensity',
|
|
125
|
+
/** No light scattered is a real floor, as no light absorbed is. */
|
|
126
|
+
baseline: 0,
|
|
127
|
+
/** Not held in a dragged window, for the reason absorbance gives. */
|
|
128
|
+
keepBaseline: false,
|
|
129
|
+
/** A Raman band stands up out of the baseline under it. */
|
|
130
|
+
bandsPointDown: false,
|
|
131
|
+
/**
|
|
132
|
+
* Both drags are worth having: intensity is open at the top and its weak
|
|
133
|
+
* bands lie against zero, as absorbance's do.
|
|
134
|
+
*/
|
|
135
|
+
boxZoomOnly: false,
|
|
136
|
+
/** The wheel scales the axis about zero, bringing a weak band up. */
|
|
137
|
+
wheelZoom: true,
|
|
138
|
+
},
|
|
118
139
|
} as const satisfies Record<
|
|
119
140
|
IrMode,
|
|
120
141
|
{
|
|
@@ -199,10 +220,21 @@ export function bandsPointDown(mode: IrMode): boolean {
|
|
|
199
220
|
}
|
|
200
221
|
|
|
201
222
|
/**
|
|
202
|
-
* The
|
|
223
|
+
* The next mode, for a control that toggles between them.
|
|
224
|
+
*
|
|
225
|
+
* It never leaves the technique: an infrared viewer goes back and forth
|
|
226
|
+
* between its two axes, and a Raman one, reading intensity alone, stays where
|
|
227
|
+
* it is.
|
|
203
228
|
* @param mode - The mode in force.
|
|
204
|
-
* @
|
|
229
|
+
* @param technique - The technique whose modes are toggled through. Defaults to
|
|
230
|
+
* the one that reads `mode`.
|
|
231
|
+
* @returns The one to switch to: the technique's first when `mode` is not one
|
|
232
|
+
* of its own.
|
|
205
233
|
*/
|
|
206
|
-
export function otherIrMode(
|
|
207
|
-
|
|
234
|
+
export function otherIrMode(
|
|
235
|
+
mode: IrMode,
|
|
236
|
+
technique: IrTechnique = irModeTechnique(mode),
|
|
237
|
+
): IrMode {
|
|
238
|
+
const modes: readonly IrMode[] = IR_TECHNIQUE_RULES[technique].modes;
|
|
239
|
+
return modes[(modes.indexOf(mode) + 1) % modes.length] ?? mode;
|
|
208
240
|
}
|
package/src/ir/core/irReducer.ts
CHANGED
|
@@ -16,12 +16,7 @@
|
|
|
16
16
|
import type { IrSidePanelId } from './irSidePanels.ts';
|
|
17
17
|
import type { IrDomain, IrSpectrum } from './irSpectrum.ts';
|
|
18
18
|
import type { IrSettings, IrState, IrTool, PartialIrState } from './irState.ts';
|
|
19
|
-
import {
|
|
20
|
-
DEFAULT_SETTINGS,
|
|
21
|
-
DEFAULT_SIDE_PANELS,
|
|
22
|
-
isIrWindow,
|
|
23
|
-
mergeIrSettings,
|
|
24
|
-
} from './irState.ts';
|
|
19
|
+
import { isIrWindow, mergeIrSettings } from './irState.ts';
|
|
25
20
|
|
|
26
21
|
/** Everything that can be asked of the viewer. */
|
|
27
22
|
export type IrAction =
|
|
@@ -41,49 +36,6 @@ export type IrAction =
|
|
|
41
36
|
| { type: 'loadState'; state: PartialIrState }
|
|
42
37
|
| { type: 'clear' };
|
|
43
38
|
|
|
44
|
-
/** What a viewer opens on. */
|
|
45
|
-
export interface CreateIrStateOptions {
|
|
46
|
-
/**
|
|
47
|
-
* The spectra to open on.
|
|
48
|
-
* @default []
|
|
49
|
-
*/
|
|
50
|
-
spectra?: IrSpectrum[];
|
|
51
|
-
/**
|
|
52
|
-
* The workspace to open in.
|
|
53
|
-
* @default DEFAULT_SETTINGS
|
|
54
|
-
*/
|
|
55
|
-
settings?: Partial<IrSettings>;
|
|
56
|
-
/**
|
|
57
|
-
* The panels open to begin with.
|
|
58
|
-
* @default DEFAULT_SIDE_PANELS
|
|
59
|
-
*/
|
|
60
|
-
panelIds?: IrSidePanelId[];
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* The state a viewer opens with.
|
|
65
|
-
*
|
|
66
|
-
* The panel list is spread rather than stored by reference: a caller's array is
|
|
67
|
-
* the caller's to mutate, and a viewer holding it would find its open panels
|
|
68
|
-
* changing under it.
|
|
69
|
-
* @param options - What it opens on.
|
|
70
|
-
* @returns The state.
|
|
71
|
-
*/
|
|
72
|
-
export function createIrState(options: CreateIrStateOptions = {}): IrState {
|
|
73
|
-
const { spectra = [], settings, panelIds } = options;
|
|
74
|
-
return {
|
|
75
|
-
data: { spectra: [...spectra] },
|
|
76
|
-
view: {
|
|
77
|
-
selectedId: spectra[0]?.id ?? null,
|
|
78
|
-
domain: null,
|
|
79
|
-
tool: 'read',
|
|
80
|
-
openPanelIds: [...(panelIds ?? DEFAULT_SIDE_PANELS)],
|
|
81
|
-
error: null,
|
|
82
|
-
},
|
|
83
|
-
settings: mergeIrSettings(DEFAULT_SETTINGS, settings),
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
|
|
87
39
|
/**
|
|
88
40
|
* Fold one action into the state.
|
|
89
41
|
* @param state - The state in force.
|