@complat/react-spectra-editor 1.7.0 → 1.8.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/CHANGELOG.md +28 -0
- package/LICENSE +21 -662
- package/README.md +5 -0
- package/dist/__tests__/fixtures/lc_ms_jcamp.js +2329 -0
- package/dist/__tests__/fixtures/lc_ms_jcamp_2.js +2874 -0
- package/dist/__tests__/fixtures/lc_ms_jcamp_mz_chemstation.js +3242 -0
- package/dist/__tests__/fixtures/lc_ms_jcamp_tic_chemstation.js +854 -0
- package/dist/__tests__/fixtures/lc_ms_jcamp_tic_neg.js +1233 -0
- package/dist/__tests__/fixtures/lc_ms_jcamp_tic_pos.js +1233 -0
- package/dist/__tests__/fixtures/lc_ms_jcamp_uvvis.js +48908 -0
- package/dist/__tests__/fixtures/lc_ms_jcamp_uvvis_chemstation.js +15424 -0
- package/dist/__tests__/units/components/cmd_bar/r05_submit_btn.test.js +158 -3
- package/dist/__tests__/units/components/d3_line_rect.test.js +85 -0
- package/dist/__tests__/units/components/d3_multi/multi_focus.test.js +43 -0
- package/dist/__tests__/units/components/hplc_viewer.test.js +123 -0
- package/dist/__tests__/units/components/panel/info.test.js +55 -15
- package/dist/__tests__/units/features/lc-ms/parsing/lcmsCategory.test.js +73 -0
- package/dist/__tests__/units/features/lc-ms/submit/peaks.test.js +310 -0
- package/dist/actions/curve.js +5 -2
- package/dist/actions/hplc_ms.js +66 -0
- package/dist/actions/integration.js +17 -2
- package/dist/actions/ui.js +39 -11
- package/dist/app.js +21 -8
- package/dist/components/cmd_bar/01_viewer.js +15 -11
- package/dist/components/cmd_bar/03_peak.js +25 -16
- package/dist/components/cmd_bar/04_integration.js +116 -17
- package/dist/components/cmd_bar/08_peak_group.js +83 -0
- package/dist/components/cmd_bar/collapsible_toolbar_group.js +101 -0
- package/dist/components/cmd_bar/common.js +4 -3
- package/dist/components/cmd_bar/index.js +76 -18
- package/dist/components/cmd_bar/r01_layout.js +6 -0
- package/dist/components/cmd_bar/r02_scan.js +15 -11
- package/dist/components/cmd_bar/r03_threshold.js +19 -3
- package/dist/components/cmd_bar/r04_submit.js +61 -6
- package/dist/components/cmd_bar/r05_submit_btn.js +60 -13
- package/dist/components/cmd_bar/r06_predict_btn.js +4 -4
- package/dist/components/cmd_bar/r07_wavelength_btn.js +10 -9
- package/dist/components/cmd_bar/r09_detector.js +2 -2
- package/dist/components/cmd_bar/tri_btn.js +4 -1
- package/dist/components/common/draw.js +6 -5
- package/dist/components/d3_line/index.js +70 -15
- package/dist/components/d3_line/line_focus.js +104 -67
- package/dist/components/d3_line_rect/index.js +836 -0
- package/dist/components/d3_line_rect/line_focus.js +526 -0
- package/dist/components/d3_line_rect/multi_focus.js +433 -0
- package/dist/components/d3_line_rect/rect_focus.js +247 -0
- package/dist/components/d3_multi/index.js +154 -163
- package/dist/components/d3_multi/multi_focus.js +117 -68
- package/dist/components/d3_rect/index.js +6 -0
- package/dist/components/d3_rect/rect_focus.js +17 -5
- package/dist/components/hplc_viewer.js +169 -0
- package/dist/components/lc_ms_uv_tools_bar.js +175 -0
- package/dist/components/multi_jcamps_viewer.js +17 -5
- package/dist/components/panel/compare.js +84 -62
- package/dist/components/panel/cyclic_voltamery_data.js +15 -14
- package/dist/components/panel/graph_selection.js +32 -30
- package/dist/components/panel/index.js +28 -22
- package/dist/components/panel/info.js +90 -31
- package/dist/constants/action_type.js +23 -2
- package/dist/constants/list_graph.js +16 -0
- package/dist/constants/list_layout.js +2 -1
- package/dist/constants/list_ui.js +5 -2
- package/dist/features/lc-ms/entities/extractEntityLCMS.js +187 -0
- package/dist/features/lc-ms/parsing/chemstation.js +108 -0
- package/dist/features/lc-ms/parsing/index.js +46 -0
- package/dist/features/lc-ms/parsing/lcmsCategory.js +44 -0
- package/dist/features/lc-ms/parsing/lcmsJcampInfo.js +18 -0
- package/dist/features/lc-ms/parsing/lcmsMsPage.js +241 -0
- package/dist/features/lc-ms/parsing/pageValue.js +27 -0
- package/dist/features/lc-ms/submit/index.js +24 -0
- package/dist/features/lc-ms/submit/peaks.js +66 -0
- package/dist/features/lc-ms/ui/wavelengthSelect.js +54 -0
- package/dist/fn.js +4 -1
- package/dist/helpers/brush.js +74 -19
- package/dist/helpers/calc.js +4 -2
- package/dist/helpers/cfg.js +5 -4
- package/dist/helpers/chem.js +449 -71
- package/dist/helpers/compass.js +181 -17
- package/dist/helpers/extractEntityLCMS.js +24 -0
- package/dist/helpers/extractParams.js +118 -33
- package/dist/helpers/extractPeaksEdit.js +29 -9
- package/dist/helpers/format.js +189 -4
- package/dist/helpers/init.js +25 -5
- package/dist/helpers/integration.js +130 -17
- package/dist/helpers/integration_draft.js +43 -0
- package/dist/helpers/integration_focus.js +155 -0
- package/dist/helpers/integration_jcamp.js +68 -0
- package/dist/helpers/integration_split.js +202 -0
- package/dist/helpers/mount.js +8 -1
- package/dist/helpers/sweep.js +39 -0
- package/dist/index.js +284 -26
- package/dist/layer_content.js +17 -3
- package/dist/layer_init.js +124 -14
- package/dist/layer_prism.js +31 -5
- package/dist/reducers/index.js +3 -1
- package/dist/reducers/reducer_curve.js +54 -36
- package/dist/reducers/reducer_hplc_ms/hydrate.js +289 -0
- package/dist/reducers/reducer_hplc_ms/index.js +122 -0
- package/dist/reducers/reducer_hplc_ms/persistence.js +74 -0
- package/dist/reducers/reducer_hplc_ms/tic.js +70 -0
- package/dist/reducers/reducer_hplc_ms/utils.js +70 -0
- package/dist/reducers/reducer_hplc_ms/uvvis.js +377 -0
- package/dist/reducers/reducer_integration.js +265 -7
- package/dist/reducers/reducer_layout.js +1 -1
- package/dist/reducers/reducer_submit.js +2 -1
- package/dist/reducers/reducer_ui.js +149 -13
- package/dist/reducers/undo_redo_config.js +2 -2
- package/dist/sagas/saga_lcms_ui.js +85 -0
- package/dist/sagas/saga_ui.js +177 -74
- package/dist/setupTests.js +5 -5
- package/package.json +10 -7
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.updateLcmsData = void 0;
|
|
7
|
+
var _extractEntityLCMS = require("../../helpers/extractEntityLCMS");
|
|
8
|
+
var _utils = require("./utils");
|
|
9
|
+
var _persistence = require("./persistence");
|
|
10
|
+
var _uvvis = require("./uvvis");
|
|
11
|
+
var _pageValue = require("../../features/lc-ms/parsing/pageValue");
|
|
12
|
+
/* eslint-disable prefer-object-spread, import/prefer-default-export */
|
|
13
|
+
|
|
14
|
+
const updateLcmsData = (state, action) => {
|
|
15
|
+
const {
|
|
16
|
+
payload,
|
|
17
|
+
meta: actionMeta
|
|
18
|
+
} = action;
|
|
19
|
+
if (!payload || payload.length === 0) return state;
|
|
20
|
+
const meta = actionMeta && typeof actionMeta === 'object' ? actionMeta : {};
|
|
21
|
+
const normalizeFeatures = curve => {
|
|
22
|
+
if (Array.isArray(curve?.features)) return curve.features;
|
|
23
|
+
if (Array.isArray(curve?.spectra)) return curve.spectra;
|
|
24
|
+
if (curve?.feature) return [curve.feature];
|
|
25
|
+
if (curve?.entity?.features) {
|
|
26
|
+
if (Array.isArray(curve.entity.features)) return curve.entity.features;
|
|
27
|
+
if (typeof curve.entity.features === 'object') {
|
|
28
|
+
return Object.values(curve.entity.features).filter(f => f?.data?.[0]);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (curve?.features && typeof curve.features === 'object') {
|
|
32
|
+
return Object.values(curve.features).filter(f => f?.data?.[0]);
|
|
33
|
+
}
|
|
34
|
+
return [];
|
|
35
|
+
};
|
|
36
|
+
let ticPosData = {
|
|
37
|
+
x: [],
|
|
38
|
+
y: []
|
|
39
|
+
};
|
|
40
|
+
let ticNegData = {
|
|
41
|
+
x: [],
|
|
42
|
+
y: []
|
|
43
|
+
};
|
|
44
|
+
let ticNeutralData = {
|
|
45
|
+
x: [],
|
|
46
|
+
y: []
|
|
47
|
+
};
|
|
48
|
+
let uvvisCurve = null;
|
|
49
|
+
const mzPosFeatures = [];
|
|
50
|
+
const mzNegFeatures = [];
|
|
51
|
+
const mzNeutralFeatures = [];
|
|
52
|
+
payload.forEach(curve => {
|
|
53
|
+
const {
|
|
54
|
+
kind,
|
|
55
|
+
polarity
|
|
56
|
+
} = (0, _extractEntityLCMS.getLcMsInfo)(curve);
|
|
57
|
+
const featuresArr = normalizeFeatures(curve);
|
|
58
|
+
if (kind === 'tic') {
|
|
59
|
+
const [feature] = featuresArr;
|
|
60
|
+
const featureData = feature?.data?.[0];
|
|
61
|
+
if (!featureData || !featureData.x || featureData.x.length === 0) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
if (polarity === 'negative') {
|
|
65
|
+
ticNegData = featureData;
|
|
66
|
+
} else if (polarity === 'positive') {
|
|
67
|
+
ticPosData = featureData;
|
|
68
|
+
} else {
|
|
69
|
+
ticNeutralData = featureData;
|
|
70
|
+
}
|
|
71
|
+
} else if (kind === 'uvvis') {
|
|
72
|
+
uvvisCurve = {
|
|
73
|
+
...curve,
|
|
74
|
+
features: featuresArr
|
|
75
|
+
};
|
|
76
|
+
} else if (kind === 'mz') {
|
|
77
|
+
if (featuresArr.length === 0) return;
|
|
78
|
+
if (polarity === 'negative') {
|
|
79
|
+
mzNegFeatures.push(...featuresArr);
|
|
80
|
+
} else if (polarity === 'positive') {
|
|
81
|
+
mzPosFeatures.push(...featuresArr);
|
|
82
|
+
} else {
|
|
83
|
+
mzNeutralFeatures.push(...featuresArr);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
if (!uvvisCurve || !uvvisCurve.features) return state;
|
|
88
|
+
const {
|
|
89
|
+
features
|
|
90
|
+
} = uvvisCurve;
|
|
91
|
+
const getPageValue = fe => {
|
|
92
|
+
let raw = fe.pageSymbol || fe.page || fe.pageValue;
|
|
93
|
+
if (typeof raw === 'string') {
|
|
94
|
+
raw = raw.split('\n')[0].trim();
|
|
95
|
+
const match = raw.match(/[=:]\s*([0-9.+-]+)/);
|
|
96
|
+
if (match) {
|
|
97
|
+
const [, value] = match;
|
|
98
|
+
raw = value;
|
|
99
|
+
} else {
|
|
100
|
+
raw = raw.replace(/[^0-9.+-]/g, '');
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const value = parseFloat(raw);
|
|
104
|
+
return Number.isFinite(value) ? value : 0;
|
|
105
|
+
};
|
|
106
|
+
const filteredFeatures = features.filter(fe => fe.data && fe.data[0] && fe.data[0].x && fe.data[0].x.length > 0 && fe.data[0].y && fe.data[0].y.length > 0);
|
|
107
|
+
const listWaveLength = filteredFeatures.map(fe => getPageValue(fe));
|
|
108
|
+
const prevUvvis = state.uvvis || {};
|
|
109
|
+
const nextDatasetKey = meta.idDt ?? meta.datasetId ?? state.lcmsDatasetKey ?? null;
|
|
110
|
+
const sameDatasetScope = nextDatasetKey === state.lcmsDatasetKey || nextDatasetKey == null && state.lcmsDatasetKey == null;
|
|
111
|
+
const prevSpectraById = (() => {
|
|
112
|
+
const map = new Map();
|
|
113
|
+
if (!sameDatasetScope) return map;
|
|
114
|
+
const prevList = prevUvvis.spectraList || [];
|
|
115
|
+
const prevWls = prevUvvis.listWaveLength || [];
|
|
116
|
+
for (let i = 0; i < prevList.length; i += 1) {
|
|
117
|
+
const sp = prevList[i];
|
|
118
|
+
if (!sp) continue; // eslint-disable-line no-continue
|
|
119
|
+
const wl = prevWls[i];
|
|
120
|
+
const id = (0, _utils.normalizeSpectrumId)(wl ?? sp.pageValue);
|
|
121
|
+
map.set(id, sp);
|
|
122
|
+
}
|
|
123
|
+
return map;
|
|
124
|
+
})();
|
|
125
|
+
const spectraList = filteredFeatures.map(fe => {
|
|
126
|
+
const pageValue = getPageValue(fe);
|
|
127
|
+
const id = (0, _utils.normalizeSpectrumId)(pageValue);
|
|
128
|
+
const fromServer = {
|
|
129
|
+
data: fe.data[0],
|
|
130
|
+
integrations: fe.integrations || [],
|
|
131
|
+
peaks: fe.peaks || [],
|
|
132
|
+
pageValue
|
|
133
|
+
};
|
|
134
|
+
const prevSp = prevSpectraById.get(id);
|
|
135
|
+
if (!prevSp) {
|
|
136
|
+
return fromServer;
|
|
137
|
+
}
|
|
138
|
+
return {
|
|
139
|
+
...fromServer,
|
|
140
|
+
data: fe.data[0],
|
|
141
|
+
integrations: JSON.parse(JSON.stringify(prevSp.integrations || [])),
|
|
142
|
+
peaks: (prevSp.peaks || []).map(p => ({
|
|
143
|
+
...p
|
|
144
|
+
}))
|
|
145
|
+
};
|
|
146
|
+
});
|
|
147
|
+
const normalizedNew = listWaveLength.map(w => (0, _utils.normalizeSpectrumId)(w));
|
|
148
|
+
const metaWlHint = (0, _utils.readFiniteNumber)(meta.lcmsUvvisWavelength ?? meta.lcms_uvvis_wavelength);
|
|
149
|
+
const curveWlHint = (() => {
|
|
150
|
+
const c = uvvisCurve;
|
|
151
|
+
const v = (0, _utils.readFiniteNumber)(c?.lcms_uvvis_wavelength ?? c?.lcmsUvvisWavelength) ?? (0, _utils.readFiniteNumber)(c?.entity?.lcms_uvvis_wavelength ?? c?.entity?.lcmsUvvisWavelength);
|
|
152
|
+
return v;
|
|
153
|
+
})();
|
|
154
|
+
let wavelengthIdx = 0;
|
|
155
|
+
let resolvedFromPrev = false;
|
|
156
|
+
if (prevUvvis.selectedWaveLength != null) {
|
|
157
|
+
const idx = normalizedNew.indexOf((0, _utils.normalizeSpectrumId)(prevUvvis.selectedWaveLength));
|
|
158
|
+
if (idx >= 0) {
|
|
159
|
+
wavelengthIdx = idx;
|
|
160
|
+
resolvedFromPrev = true;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
if (!resolvedFromPrev) {
|
|
164
|
+
const persistedWl = (0, _persistence.readPersistedLcmsUvvisWavelength)(nextDatasetKey);
|
|
165
|
+
const persistedLastWl = (0, _persistence.readPersistedLastLcmsUvvisWavelength)();
|
|
166
|
+
const hinted = metaWlHint ?? curveWlHint ?? persistedWl ?? persistedLastWl ?? null;
|
|
167
|
+
if (hinted != null) {
|
|
168
|
+
const idx = normalizedNew.indexOf((0, _utils.normalizeSpectrumId)(hinted));
|
|
169
|
+
if (idx >= 0) {
|
|
170
|
+
wavelengthIdx = idx;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
const selectedWaveLength = listWaveLength[wavelengthIdx];
|
|
175
|
+
const currentSpectrum = spectraList[wavelengthIdx];
|
|
176
|
+
(0, _persistence.persistLcmsUvvisWavelength)(nextDatasetKey, selectedWaveLength);
|
|
177
|
+
const newUvvis = {
|
|
178
|
+
...state.uvvis,
|
|
179
|
+
listWaveLength,
|
|
180
|
+
selectedWaveLength,
|
|
181
|
+
wavelengthIdx,
|
|
182
|
+
spectraList,
|
|
183
|
+
currentSpectrum
|
|
184
|
+
};
|
|
185
|
+
const toMsPayload = fts => {
|
|
186
|
+
const peaks = [];
|
|
187
|
+
const pageValues = [];
|
|
188
|
+
fts.forEach(feature => {
|
|
189
|
+
const data = feature?.data?.[0] || {};
|
|
190
|
+
const xValues = Array.isArray(data.x) ? data.x : [];
|
|
191
|
+
const yValues = Array.isArray(data.y) ? data.y : [];
|
|
192
|
+
const length = Math.min(xValues.length, yValues.length);
|
|
193
|
+
peaks.push(xValues.slice(0, length).map((x, i) => ({
|
|
194
|
+
x,
|
|
195
|
+
y: yValues[i] || 0
|
|
196
|
+
})));
|
|
197
|
+
pageValues.push((0, _pageValue.parseFeaturePageValue)(feature));
|
|
198
|
+
});
|
|
199
|
+
return {
|
|
200
|
+
peaks,
|
|
201
|
+
pageValues
|
|
202
|
+
};
|
|
203
|
+
};
|
|
204
|
+
const available = {
|
|
205
|
+
positive: ticPosData?.x?.length > 0,
|
|
206
|
+
negative: ticNegData?.x?.length > 0,
|
|
207
|
+
neutral: ticNeutralData?.x?.length > 0
|
|
208
|
+
};
|
|
209
|
+
const preferredOrder = ['positive', 'negative', 'neutral'];
|
|
210
|
+
const fallbackPolarity = preferredOrder.find(pol => available[pol]) || 'positive';
|
|
211
|
+
const readMetaPolarity = () => (0, _utils.normalizeHintPolarity)(meta.lcmsPolarity ?? meta.lcms_polarity ?? meta.ticPolarity);
|
|
212
|
+
const metaPol = readMetaPolarity();
|
|
213
|
+
const persistedTicHints = (0, _persistence.readPersistedLcmsTicHints)(nextDatasetKey);
|
|
214
|
+
const polarityCandidates = sameDatasetScope ? [(0, _utils.normalizeHintPolarity)(state.tic?.polarity), (0, _utils.normalizeHintPolarity)(persistedTicHints?.polarity), metaPol] : [metaPol, (0, _utils.normalizeHintPolarity)(persistedTicHints?.polarity), (0, _utils.normalizeHintPolarity)(state.tic?.polarity)];
|
|
215
|
+
const selectedPolarity = (0, _utils.pickFirstAvailablePolarity)(available, polarityCandidates) || fallbackPolarity;
|
|
216
|
+
const ticXsFor = pol => {
|
|
217
|
+
if (pol === 'negative') return ticNegData?.x;
|
|
218
|
+
if (pol === 'neutral') return ticNeutralData?.x;
|
|
219
|
+
return ticPosData?.x;
|
|
220
|
+
};
|
|
221
|
+
const nextRtXs = ticXsFor(selectedPolarity) || [];
|
|
222
|
+
const rtHintFromMzCurve = pol => {
|
|
223
|
+
const c = payload.find(curve => {
|
|
224
|
+
const inf = (0, _extractEntityLCMS.getLcMsInfo)(curve);
|
|
225
|
+
return inf.kind === 'mz' && inf.polarity === pol;
|
|
226
|
+
});
|
|
227
|
+
if (!c) return null;
|
|
228
|
+
return (0, _utils.readFiniteNumber)(c.lcms_mz_page ?? c.lcmsMzPage ?? c.entity?.lcms_mz_page ?? c.entity?.lcmsMzPage);
|
|
229
|
+
};
|
|
230
|
+
const rtFromMzFeature = pol => {
|
|
231
|
+
const findIn = list => {
|
|
232
|
+
if (!Array.isArray(list)) return null;
|
|
233
|
+
for (let i = 0; i < list.length; i += 1) {
|
|
234
|
+
const v = (0, _pageValue.parseFeaturePageValue)(list[i]);
|
|
235
|
+
if (Number.isFinite(v)) return v;
|
|
236
|
+
}
|
|
237
|
+
return null;
|
|
238
|
+
};
|
|
239
|
+
if (pol === 'negative') return findIn(mzNegFeatures);
|
|
240
|
+
if (pol === 'neutral') return findIn(mzNeutralFeatures);
|
|
241
|
+
return findIn(mzPosFeatures);
|
|
242
|
+
};
|
|
243
|
+
const metaRt = (0, _utils.readFiniteNumber)(meta.lcms_mz_page ?? meta.lcmsMzPage);
|
|
244
|
+
const curveRt = rtHintFromMzCurve(selectedPolarity);
|
|
245
|
+
const uvvisRtHint = (0, _utils.readFiniteNumber)(uvvisCurve?.lcms_mz_page ?? uvvisCurve?.lcmsMzPage ?? uvvisCurve?.entity?.lcms_mz_page ?? uvvisCurve?.entity?.lcmsMzPage);
|
|
246
|
+
const mzFeatureRt = rtFromMzFeature(selectedPolarity) ?? rtFromMzFeature('positive') ?? rtFromMzFeature('negative') ?? rtFromMzFeature('neutral');
|
|
247
|
+
const fromHints = (0, _utils.pickFirstRtOnAxis)([metaRt, uvvisRtHint, curveRt], nextRtXs) ?? nextRtXs[0] ?? null;
|
|
248
|
+
const persistedMzPage = (0, _utils.readFiniteNumber)(persistedTicHints?.mzPage);
|
|
249
|
+
const prevPageFromState = sameDatasetScope ? (0, _utils.readFiniteNumber)(state.tic?.currentPageValue) : null;
|
|
250
|
+
let nextCurrentPageValue = fromHints;
|
|
251
|
+
const snappedState = (0, _utils.snapRtToAxis)(prevPageFromState, nextRtXs);
|
|
252
|
+
const snappedPersisted = (0, _utils.snapRtToAxis)(persistedMzPage, nextRtXs);
|
|
253
|
+
if (snappedState != null) {
|
|
254
|
+
nextCurrentPageValue = snappedState;
|
|
255
|
+
} else if (snappedPersisted != null) {
|
|
256
|
+
nextCurrentPageValue = snappedPersisted;
|
|
257
|
+
}
|
|
258
|
+
if (Number.isFinite(mzFeatureRt)) {
|
|
259
|
+
nextCurrentPageValue = mzFeatureRt;
|
|
260
|
+
}
|
|
261
|
+
const sameDataset = nextDatasetKey != null && state.lcmsDatasetKey != null && nextDatasetKey === state.lcmsDatasetKey;
|
|
262
|
+
return {
|
|
263
|
+
...state,
|
|
264
|
+
lcmsDatasetKey: nextDatasetKey,
|
|
265
|
+
uvvis: newUvvis,
|
|
266
|
+
uvvisEditHistory: sameDataset ? state.uvvisEditHistory || (0, _uvvis.emptyUvvisHistory)() : (0, _uvvis.emptyUvvisHistory)(),
|
|
267
|
+
ms: {
|
|
268
|
+
positive: toMsPayload(mzPosFeatures),
|
|
269
|
+
negative: toMsPayload(mzNegFeatures),
|
|
270
|
+
neutral: toMsPayload(mzNeutralFeatures)
|
|
271
|
+
},
|
|
272
|
+
tic: {
|
|
273
|
+
...state.tic,
|
|
274
|
+
currentPageValue: nextCurrentPageValue,
|
|
275
|
+
polarity: selectedPolarity,
|
|
276
|
+
available,
|
|
277
|
+
positive: {
|
|
278
|
+
data: ticPosData
|
|
279
|
+
},
|
|
280
|
+
negative: {
|
|
281
|
+
data: ticNegData
|
|
282
|
+
},
|
|
283
|
+
neutral: {
|
|
284
|
+
data: ticNeutralData
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
};
|
|
289
|
+
exports.updateLcmsData = updateLcmsData;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.initialState = exports.default = void 0;
|
|
7
|
+
var _action_type = require("../../constants/action_type");
|
|
8
|
+
var _utils = require("./utils");
|
|
9
|
+
var _hydrate = require("./hydrate");
|
|
10
|
+
var _uvvis = require("./uvvis");
|
|
11
|
+
var _tic = require("./tic");
|
|
12
|
+
/* eslint-disable default-param-last */
|
|
13
|
+
|
|
14
|
+
const initialState = exports.initialState = {
|
|
15
|
+
uvvis: {
|
|
16
|
+
listWaveLength: null,
|
|
17
|
+
selectedWaveLength: null,
|
|
18
|
+
wavelengthIdx: 0,
|
|
19
|
+
spectraList: [],
|
|
20
|
+
currentSpectrum: null
|
|
21
|
+
},
|
|
22
|
+
ms: {
|
|
23
|
+
positive: {
|
|
24
|
+
peaks: [],
|
|
25
|
+
pageValues: []
|
|
26
|
+
},
|
|
27
|
+
negative: {
|
|
28
|
+
peaks: [],
|
|
29
|
+
pageValues: []
|
|
30
|
+
},
|
|
31
|
+
neutral: {
|
|
32
|
+
peaks: [],
|
|
33
|
+
pageValues: []
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
uvvisEditHistory: {
|
|
37
|
+
past: [],
|
|
38
|
+
future: []
|
|
39
|
+
},
|
|
40
|
+
tic: {
|
|
41
|
+
currentPageValue: null,
|
|
42
|
+
polarity: 'positive',
|
|
43
|
+
available: {
|
|
44
|
+
positive: false,
|
|
45
|
+
negative: false,
|
|
46
|
+
neutral: false
|
|
47
|
+
},
|
|
48
|
+
positive: {
|
|
49
|
+
data: {
|
|
50
|
+
x: [],
|
|
51
|
+
y: []
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
negative: {
|
|
55
|
+
data: {
|
|
56
|
+
x: [],
|
|
57
|
+
y: []
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
neutral: {
|
|
61
|
+
data: {
|
|
62
|
+
x: [],
|
|
63
|
+
y: []
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
threshold: {
|
|
68
|
+
isEdit: false,
|
|
69
|
+
value: 5,
|
|
70
|
+
originalValue: 5
|
|
71
|
+
},
|
|
72
|
+
lcmsIntegrationsExport: 'percent',
|
|
73
|
+
lcmsDatasetKey: null,
|
|
74
|
+
layout: 'LC/MS'
|
|
75
|
+
};
|
|
76
|
+
const clearState = state => ({
|
|
77
|
+
...initialState,
|
|
78
|
+
lcmsIntegrationsExport: state?.lcmsIntegrationsExport ?? initialState.lcmsIntegrationsExport
|
|
79
|
+
});
|
|
80
|
+
const hplcMsReducer = (state = initialState, action) => {
|
|
81
|
+
switch (action.type) {
|
|
82
|
+
case _action_type.HPLC_MS.SET_LCMS_INTEGRATIONS_EXPORT:
|
|
83
|
+
{
|
|
84
|
+
const next = (0, _utils.normalizeLcmsIntegrationsExport)(action.payload?.lcmsIntegrationsExport);
|
|
85
|
+
return {
|
|
86
|
+
...state,
|
|
87
|
+
lcmsIntegrationsExport: next
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
case _action_type.CURVE.SET_ALL_CURVES:
|
|
91
|
+
return (0, _hydrate.updateLcmsData)(state, action);
|
|
92
|
+
case _action_type.HPLC_MS.UPDATE_UVVIS_WAVE_LENGTH:
|
|
93
|
+
return (0, _uvvis.updateWavelength)(state, action);
|
|
94
|
+
case _action_type.HPLC_MS.SELECT_TIC_CURVE:
|
|
95
|
+
return (0, _tic.updateTic)(state, action);
|
|
96
|
+
case _action_type.HPLC_MS.UPDATE_CURRENT_PAGE_VALUE:
|
|
97
|
+
return (0, _tic.updateCurrentPageValue)(state, action);
|
|
98
|
+
case _action_type.HPLC_MS.UVVIS_UNDO:
|
|
99
|
+
return (0, _uvvis.uvvisUndo)(state);
|
|
100
|
+
case _action_type.HPLC_MS.UVVIS_REDO:
|
|
101
|
+
return (0, _uvvis.uvvisRedo)(state);
|
|
102
|
+
case _action_type.HPLC_MS.UPDATE_HPLCMS_INTEGRATIONS:
|
|
103
|
+
return (0, _uvvis.updateHplcMsIntegrations)(state, action);
|
|
104
|
+
case _action_type.HPLC_MS.UPDATE_HPLCMS_PEAKS:
|
|
105
|
+
return (0, _uvvis.updateHplcMsPeaks)(state, action);
|
|
106
|
+
case _action_type.HPLC_MS.REMOVE_HPLCMS_PEAK:
|
|
107
|
+
return (0, _uvvis.removeHplcMsPeak)(state, action);
|
|
108
|
+
case _action_type.HPLC_MS.CLEAR_INTEGRATION_ALL_HPLCMS:
|
|
109
|
+
return (0, _uvvis.clearIntegrationAllHplcMs)(state, action);
|
|
110
|
+
case _action_type.THRESHOLD.UPDATE_VALUE:
|
|
111
|
+
return (0, _tic.updateThresholdValue)(state, action);
|
|
112
|
+
case _action_type.THRESHOLD.RESET_VALUE:
|
|
113
|
+
return (0, _tic.resetThresholdValue)(state);
|
|
114
|
+
case _action_type.HPLC_MS.CLEAR_ALL_PEAKS_HPLCMS:
|
|
115
|
+
return (0, _uvvis.clearAllPeaksHplcMs)(state, action);
|
|
116
|
+
case _action_type.HPLC_MS.CLEAR_STATE:
|
|
117
|
+
return clearState(state);
|
|
118
|
+
default:
|
|
119
|
+
return state;
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
var _default = exports.default = hplcMsReducer;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.readPersistedLcmsUvvisWavelength = exports.readPersistedLcmsTicHints = exports.readPersistedLastLcmsUvvisWavelength = exports.persistLcmsUvvisWavelength = exports.persistLcmsTicHints = void 0;
|
|
7
|
+
var _utils = require("./utils");
|
|
8
|
+
const LC_WL_STORAGE_PREFIX = 'rsEditor.lcmsUvvisWl:';
|
|
9
|
+
const LC_WL_GLOBAL_STORAGE_KEY = 'rsEditor.lcmsUvvisWl:last';
|
|
10
|
+
const persistLcmsUvvisWavelength = (datasetKey, wavelength) => {
|
|
11
|
+
if (wavelength == null) return;
|
|
12
|
+
try {
|
|
13
|
+
const normalized = String((0, _utils.normalizeSpectrumId)(wavelength));
|
|
14
|
+
sessionStorage.setItem(LC_WL_GLOBAL_STORAGE_KEY, normalized);
|
|
15
|
+
if (datasetKey != null) {
|
|
16
|
+
sessionStorage.setItem(`${LC_WL_STORAGE_PREFIX}${datasetKey}`, normalized);
|
|
17
|
+
}
|
|
18
|
+
} catch (_e) {
|
|
19
|
+
/* sessionStorage may be unavailable */
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
exports.persistLcmsUvvisWavelength = persistLcmsUvvisWavelength;
|
|
23
|
+
const readPersistedLcmsUvvisWavelength = datasetKey => {
|
|
24
|
+
if (datasetKey == null) return null;
|
|
25
|
+
try {
|
|
26
|
+
const raw = sessionStorage.getItem(`${LC_WL_STORAGE_PREFIX}${datasetKey}`);
|
|
27
|
+
if (raw == null || raw === '') return null;
|
|
28
|
+
const n = Number(raw);
|
|
29
|
+
return Number.isFinite(n) ? n : raw;
|
|
30
|
+
} catch (e) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
exports.readPersistedLcmsUvvisWavelength = readPersistedLcmsUvvisWavelength;
|
|
35
|
+
const readPersistedLastLcmsUvvisWavelength = () => {
|
|
36
|
+
try {
|
|
37
|
+
const raw = sessionStorage.getItem(LC_WL_GLOBAL_STORAGE_KEY);
|
|
38
|
+
if (raw == null || raw === '') return null;
|
|
39
|
+
const n = Number(raw);
|
|
40
|
+
return Number.isFinite(n) ? n : raw;
|
|
41
|
+
} catch (e) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
exports.readPersistedLastLcmsUvvisWavelength = readPersistedLastLcmsUvvisWavelength;
|
|
46
|
+
const LC_TIC_STORAGE_PREFIX = 'rsEditor.lcmsTic:';
|
|
47
|
+
const persistLcmsTicHints = (datasetKey, partial) => {
|
|
48
|
+
if (datasetKey == null) return;
|
|
49
|
+
try {
|
|
50
|
+
const key = `${LC_TIC_STORAGE_PREFIX}${datasetKey}`;
|
|
51
|
+
let cur = {};
|
|
52
|
+
const raw = sessionStorage.getItem(key);
|
|
53
|
+
if (raw) {
|
|
54
|
+
cur = JSON.parse(raw) || {};
|
|
55
|
+
}
|
|
56
|
+
sessionStorage.setItem(key, JSON.stringify({
|
|
57
|
+
...cur,
|
|
58
|
+
...partial
|
|
59
|
+
}));
|
|
60
|
+
} catch (_e) {
|
|
61
|
+
/* sessionStorage may be unavailable */
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
exports.persistLcmsTicHints = persistLcmsTicHints;
|
|
65
|
+
const readPersistedLcmsTicHints = datasetKey => {
|
|
66
|
+
if (datasetKey == null) return {};
|
|
67
|
+
try {
|
|
68
|
+
const raw = sessionStorage.getItem(`${LC_TIC_STORAGE_PREFIX}${datasetKey}`);
|
|
69
|
+
return raw ? JSON.parse(raw) : {};
|
|
70
|
+
} catch (e) {
|
|
71
|
+
return {};
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
exports.readPersistedLcmsTicHints = readPersistedLcmsTicHints;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.updateTic = exports.updateThresholdValue = exports.updateCurrentPageValue = exports.resetThresholdValue = void 0;
|
|
7
|
+
var _persistence = require("./persistence");
|
|
8
|
+
/* eslint-disable prefer-object-spread */
|
|
9
|
+
|
|
10
|
+
const updateTic = (state, action) => {
|
|
11
|
+
const {
|
|
12
|
+
polarity
|
|
13
|
+
} = action.payload;
|
|
14
|
+
(0, _persistence.persistLcmsTicHints)(state.lcmsDatasetKey, {
|
|
15
|
+
polarity
|
|
16
|
+
});
|
|
17
|
+
return {
|
|
18
|
+
...state,
|
|
19
|
+
tic: {
|
|
20
|
+
...state.tic,
|
|
21
|
+
polarity
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
exports.updateTic = updateTic;
|
|
26
|
+
const updateCurrentPageValue = (state, action) => {
|
|
27
|
+
const {
|
|
28
|
+
currentPageValue
|
|
29
|
+
} = action.payload || {};
|
|
30
|
+
(0, _persistence.persistLcmsTicHints)(state.lcmsDatasetKey, {
|
|
31
|
+
mzPage: currentPageValue
|
|
32
|
+
});
|
|
33
|
+
return {
|
|
34
|
+
...state,
|
|
35
|
+
tic: {
|
|
36
|
+
...state.tic,
|
|
37
|
+
currentPageValue
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
exports.updateCurrentPageValue = updateCurrentPageValue;
|
|
42
|
+
const updateThresholdValue = (state, action) => {
|
|
43
|
+
const {
|
|
44
|
+
payload
|
|
45
|
+
} = action;
|
|
46
|
+
if (payload) {
|
|
47
|
+
const {
|
|
48
|
+
value
|
|
49
|
+
} = payload;
|
|
50
|
+
return {
|
|
51
|
+
...state,
|
|
52
|
+
threshold: {
|
|
53
|
+
isEdit: true,
|
|
54
|
+
value,
|
|
55
|
+
originalValue: state.threshold.originalValue ?? value
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
return state;
|
|
60
|
+
};
|
|
61
|
+
exports.updateThresholdValue = updateThresholdValue;
|
|
62
|
+
const resetThresholdValue = state => ({
|
|
63
|
+
...state,
|
|
64
|
+
threshold: {
|
|
65
|
+
isEdit: true,
|
|
66
|
+
value: state.threshold.originalValue,
|
|
67
|
+
originalValue: state.threshold.originalValue
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
exports.resetThresholdValue = resetThresholdValue;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.snapRtToAxis = exports.readFiniteNumber = exports.pickFirstRtOnAxis = exports.pickFirstAvailablePolarity = exports.normalizeSpectrumId = exports.normalizeLcmsIntegrationsExport = exports.normalizeHintPolarity = void 0;
|
|
7
|
+
const normalizeSpectrumId = value => {
|
|
8
|
+
if (value == null) return null;
|
|
9
|
+
const numericValue = Number(value);
|
|
10
|
+
if (Number.isFinite(numericValue)) return numericValue;
|
|
11
|
+
return String(value);
|
|
12
|
+
};
|
|
13
|
+
exports.normalizeSpectrumId = normalizeSpectrumId;
|
|
14
|
+
const readFiniteNumber = v => {
|
|
15
|
+
if (v == null || v === '') return null;
|
|
16
|
+
const n = Number(v);
|
|
17
|
+
return Number.isFinite(n) ? n : null;
|
|
18
|
+
};
|
|
19
|
+
exports.readFiniteNumber = readFiniteNumber;
|
|
20
|
+
const normalizeHintPolarity = v => {
|
|
21
|
+
if (v == null || v === '') return null;
|
|
22
|
+
if (v === 0 || v === '0') return 'positive';
|
|
23
|
+
if (v === 1 || v === '1') return 'negative';
|
|
24
|
+
if (v === 2 || v === '2') return 'neutral';
|
|
25
|
+
const s = String(v).toLowerCase();
|
|
26
|
+
if (s === 'positive' || s === 'pos') return 'positive';
|
|
27
|
+
if (s === 'negative' || s === 'neg') return 'negative';
|
|
28
|
+
if (s === 'neutral' || s === 'neu') return 'neutral';
|
|
29
|
+
return null;
|
|
30
|
+
};
|
|
31
|
+
exports.normalizeHintPolarity = normalizeHintPolarity;
|
|
32
|
+
const pickFirstAvailablePolarity = (available, candidates) => {
|
|
33
|
+
for (let i = 0; i < candidates.length; i += 1) {
|
|
34
|
+
const p = candidates[i];
|
|
35
|
+
if (p && available[p]) return p;
|
|
36
|
+
}
|
|
37
|
+
return null;
|
|
38
|
+
};
|
|
39
|
+
exports.pickFirstAvailablePolarity = pickFirstAvailablePolarity;
|
|
40
|
+
const pickFirstRtOnAxis = (candidates, xs) => {
|
|
41
|
+
if (!Array.isArray(xs) || xs.length === 0) return null;
|
|
42
|
+
for (let i = 0; i < candidates.length; i += 1) {
|
|
43
|
+
const r = candidates[i];
|
|
44
|
+
if (Number.isFinite(r) && xs.some(x => Math.abs(x - r) < 1e-5)) {
|
|
45
|
+
return r;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return null;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/** Align an RT (e.g. user click) onto the TIC axis after a data refresh. */
|
|
52
|
+
exports.pickFirstRtOnAxis = pickFirstRtOnAxis;
|
|
53
|
+
const snapRtToAxis = (rt, xs) => {
|
|
54
|
+
if (!Number.isFinite(rt) || !Array.isArray(xs) || xs.length === 0) return null;
|
|
55
|
+
const exact = xs.find(x => Math.abs(x - rt) < 1e-5);
|
|
56
|
+
if (exact !== undefined) return exact;
|
|
57
|
+
let best = xs[0];
|
|
58
|
+
let bestD = Math.abs(xs[0] - rt);
|
|
59
|
+
for (let i = 1; i < xs.length; i += 1) {
|
|
60
|
+
const d = Math.abs(xs[i] - rt);
|
|
61
|
+
if (d < bestD) {
|
|
62
|
+
bestD = d;
|
|
63
|
+
best = xs[i];
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return best;
|
|
67
|
+
};
|
|
68
|
+
exports.snapRtToAxis = snapRtToAxis;
|
|
69
|
+
const normalizeLcmsIntegrationsExport = value => ['percent', 'area', 'both'].includes(value) ? value : 'percent';
|
|
70
|
+
exports.normalizeLcmsIntegrationsExport = normalizeLcmsIntegrationsExport;
|