@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
package/dist/helpers/chem.js
CHANGED
|
@@ -4,19 +4,27 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
4
4
|
Object.defineProperty(exports, "__esModule", {
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
|
-
exports.
|
|
7
|
+
exports.buildIntegFeature = exports.Topic2Seed = exports.ToThresEndPts = exports.ToShiftPeaks = exports.ToFrequency = exports.GetCyclicVoltaShiftOffset = exports.GetCyclicVoltaRatio = exports.GetCyclicVoltaPreviousShift = exports.GetCyclicVoltaPeakSeparate = exports.GetComparisons = exports.Feature2Peak = exports.Feature2MaxMinPeak = exports.ExtractJcamp = exports.Convert2Thres = exports.Convert2Scan = exports.Convert2Peak = exports.Convert2MaxMinPeak = exports.Convert2DValue = void 0;
|
|
8
|
+
Object.defineProperty(exports, "buildLcmsMsPageJcamp", {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
get: function get() {
|
|
11
|
+
return _parsing.buildLcmsMsPageJcamp;
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
exports.convertTopic = exports.convertThresEndPts = void 0;
|
|
8
15
|
var _jcampconverter = _interopRequireDefault(require("jcampconverter"));
|
|
9
16
|
var _reselect = require("reselect");
|
|
10
17
|
var _shift = require("./shift");
|
|
11
|
-
var _cfg = _interopRequireDefault(require("./cfg"));
|
|
12
18
|
var _format = _interopRequireDefault(require("./format"));
|
|
13
19
|
var _list_layout = require("../constants/list_layout");
|
|
14
20
|
var _integration = require("./integration");
|
|
21
|
+
var _parsing = require("../features/lc-ms/parsing");
|
|
15
22
|
/* eslint-disable
|
|
16
23
|
no-mixed-operators, react/function-component-definition,
|
|
17
24
|
prefer-object-spread, camelcase, no-plusplus, prefer-destructuring,
|
|
18
25
|
max-len */
|
|
19
26
|
|
|
27
|
+
const canIntegrate = layoutSt => !(_format.default.isNmrLayout(layoutSt) || _format.default.isHplcUvVisLayout(layoutSt) || _format.default.isLCMsLayout(layoutSt));
|
|
20
28
|
const getTopic = (_, props) => props.topic;
|
|
21
29
|
const getFeature = (_, props) => props.feature;
|
|
22
30
|
const getLayout = (state, _) => state.layout; // eslint-disable-line
|
|
@@ -104,12 +112,13 @@ const calcXY = (xs, ys, maxY, offset) => {
|
|
|
104
112
|
return sp;
|
|
105
113
|
};
|
|
106
114
|
const convertTopic = (topic, layout, feature, offset) => {
|
|
115
|
+
if (!feature || !topic) return [];
|
|
107
116
|
const {
|
|
108
117
|
maxY
|
|
109
|
-
} = feature;
|
|
110
|
-
const xs = topic.x;
|
|
111
|
-
const ys = topic.y;
|
|
112
|
-
const isItgDisable =
|
|
118
|
+
} = feature || {};
|
|
119
|
+
const xs = topic.x || [];
|
|
120
|
+
const ys = topic.y || [];
|
|
121
|
+
const isItgDisable = canIntegrate(layout);
|
|
113
122
|
if (!isItgDisable) return calcXYK(xs, ys, maxY, offset);
|
|
114
123
|
return calcXY(xs, ys, maxY, offset);
|
|
115
124
|
};
|
|
@@ -154,7 +163,7 @@ const convertComparisons = (layout, comparisons, feature) => {
|
|
|
154
163
|
};
|
|
155
164
|
const GetComparisons = exports.GetComparisons = (0, _reselect.createSelector)(getLayout, getOthers, getFeature, convertComparisons);
|
|
156
165
|
const convertFrequency = (layout, feature) => {
|
|
157
|
-
if (
|
|
166
|
+
if (!_format.default.isNmrLayout(layout)) return false;
|
|
158
167
|
const {
|
|
159
168
|
observeFrequency
|
|
160
169
|
} = feature;
|
|
@@ -164,6 +173,33 @@ const convertFrequency = (layout, feature) => {
|
|
|
164
173
|
const ToFrequency = exports.ToFrequency = (0, _reselect.createSelector)(getLayout, getFeature, convertFrequency);
|
|
165
174
|
const getThreshold = state => state.threshold ? state.threshold.list[state.curve.curveIdx].value * 1.0 : false;
|
|
166
175
|
const Convert2Peak = (feature, threshold, offset, upThreshold = false, lowThreshold = false) => {
|
|
176
|
+
if (feature?.operation?.layout === 'LC/MS') {
|
|
177
|
+
if (feature.peaks?.length) {
|
|
178
|
+
return feature.peaks.map(p => ({
|
|
179
|
+
x: p.x - (offset || 0),
|
|
180
|
+
y: p.y
|
|
181
|
+
}));
|
|
182
|
+
}
|
|
183
|
+
const data = feature.data[0];
|
|
184
|
+
if (!data) return [];
|
|
185
|
+
const {
|
|
186
|
+
x,
|
|
187
|
+
y
|
|
188
|
+
} = data;
|
|
189
|
+
const peaks = [];
|
|
190
|
+
const maxIntensity = Math.max(...y);
|
|
191
|
+
const thresholdValue = threshold || 0;
|
|
192
|
+
for (let i = 1; i < y.length - 1; i++) {
|
|
193
|
+
const intensity = y[i] / maxIntensity * 100;
|
|
194
|
+
if (intensity >= thresholdValue && y[i] > y[i - 1] && y[i] > y[i + 1]) {
|
|
195
|
+
peaks.push({
|
|
196
|
+
x: x[i],
|
|
197
|
+
y: y[i]
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return peaks;
|
|
202
|
+
}
|
|
167
203
|
const peak = [];
|
|
168
204
|
if (!feature || !feature.data) return peak;
|
|
169
205
|
const data = feature.data[0];
|
|
@@ -179,8 +215,6 @@ const Convert2Peak = (feature, threshold, offset, upThreshold = false, lowThresh
|
|
|
179
215
|
const {
|
|
180
216
|
layout
|
|
181
217
|
} = operation;
|
|
182
|
-
|
|
183
|
-
// if (!Format.isSECLayout(layout) && (upperThres || lowerThres)) {
|
|
184
218
|
if ((_format.default.isCyclicVoltaLayout(layout) || _format.default.isCDSLayout(layout)) && (upperThres || lowerThres)) {
|
|
185
219
|
let upperThresVal = upThreshold || upperThres;
|
|
186
220
|
if (!upperThresVal) {
|
|
@@ -291,6 +325,7 @@ const convertThresEndPts = (feature, threshold) => {
|
|
|
291
325
|
}];
|
|
292
326
|
return endPts;
|
|
293
327
|
};
|
|
328
|
+
exports.convertThresEndPts = convertThresEndPts;
|
|
294
329
|
const ToThresEndPts = exports.ToThresEndPts = (0, _reselect.createSelector)(getFeature, getThreshold, convertThresEndPts);
|
|
295
330
|
const getShiftPeak = state => {
|
|
296
331
|
const {
|
|
@@ -322,14 +357,20 @@ const ToShiftPeaks = exports.ToShiftPeaks = (0, _reselect.createSelector)(getShi
|
|
|
322
357
|
// ExtractJcamp
|
|
323
358
|
// - - - - - - - - - - - - - - - - - - - - - -
|
|
324
359
|
const readLayout = jcamp => {
|
|
360
|
+
if (jcamp.dataType?.toUpperCase?.() === 'LC/MS') {
|
|
361
|
+
return _list_layout.LIST_LAYOUT.LC_MS;
|
|
362
|
+
}
|
|
325
363
|
const {
|
|
326
364
|
xType,
|
|
327
365
|
spectra
|
|
328
366
|
} = jcamp;
|
|
329
367
|
if (xType && _format.default.isNmrLayout(xType)) return xType;
|
|
368
|
+
if (!spectra || !Array.isArray(spectra) || spectra.length === 0) {
|
|
369
|
+
return false;
|
|
370
|
+
}
|
|
330
371
|
const {
|
|
331
372
|
dataType
|
|
332
|
-
} = spectra[0];
|
|
373
|
+
} = spectra[0] || {};
|
|
333
374
|
if (dataType) {
|
|
334
375
|
if (dataType.includes('INFRARED SPECTRUM')) {
|
|
335
376
|
return _list_layout.LIST_LAYOUT.IR;
|
|
@@ -379,6 +420,9 @@ const readLayout = jcamp => {
|
|
|
379
420
|
if (dataType.includes('DLS intensity')) {
|
|
380
421
|
return _list_layout.LIST_LAYOUT.DLS_INTENSITY;
|
|
381
422
|
}
|
|
423
|
+
if (dataType.includes('LC/MS')) {
|
|
424
|
+
return _list_layout.LIST_LAYOUT.LC_MS;
|
|
425
|
+
}
|
|
382
426
|
}
|
|
383
427
|
return false;
|
|
384
428
|
};
|
|
@@ -386,30 +430,217 @@ const extrSpectraShare = (spectra, layout) => spectra.map(s => Object.assign({
|
|
|
386
430
|
layout
|
|
387
431
|
}, s)).filter(r => r != null);
|
|
388
432
|
const extrSpectraMs = (jcamp, layout) => {
|
|
389
|
-
const
|
|
390
|
-
const
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
433
|
+
const csCategories = [].concat(jcamp?.info?.$CSCATEGORY || []).map(c => String(c).toUpperCase());
|
|
434
|
+
const hasUvvisCategory = csCategories.some(c => c.includes('UVVIS'));
|
|
435
|
+
const hasUvvisDataType = jcamp?.spectra?.some(s => {
|
|
436
|
+
const dt = String(s?.dataType || '').toUpperCase();
|
|
437
|
+
return dt.includes('UV-VIS') || dt.includes('UVVIS') || dt.includes('HPLC UV');
|
|
438
|
+
});
|
|
439
|
+
const jcampDataType = String(jcamp?.dataType || '').toUpperCase();
|
|
440
|
+
const hasUvvisJcampDataType = jcampDataType.includes('UV-VIS') || jcampDataType.includes('UVVIS') || jcampDataType.includes('HPLC UV');
|
|
441
|
+
const isUvvisData = hasUvvisCategory || hasUvvisDataType || hasUvvisJcampDataType;
|
|
442
|
+
const hasTicCategory = csCategories.some(c => c.includes('TIC'));
|
|
443
|
+
const hasTicDataType = jcamp?.spectra?.some(s => {
|
|
444
|
+
const dt = String(s?.dataType || '').toUpperCase();
|
|
445
|
+
return dt.includes('MASS TIC') || dt.includes('TIC');
|
|
446
|
+
});
|
|
447
|
+
const hasTicJcampDataType = jcampDataType.includes('MASS TIC') || jcampDataType.includes('TIC');
|
|
448
|
+
const isTicData = hasTicCategory || hasTicDataType || hasTicJcampDataType;
|
|
449
|
+
const getCategory = idx => csCategories[idx] || '';
|
|
450
|
+
const finalSpectra = [];
|
|
451
|
+
const parseIntegralsString = raw => {
|
|
452
|
+
if (raw == null) return [];
|
|
453
|
+
let text = raw;
|
|
454
|
+
if (Array.isArray(text)) text = text.join(' ');
|
|
455
|
+
text = String(text).trim();
|
|
456
|
+
const groups = text.match(/\(([^)]+)\)/g) || [];
|
|
457
|
+
const out = [];
|
|
458
|
+
groups.forEach(g => {
|
|
459
|
+
const nums = g.replace(/[()]/g, '').split(/[,\s;]+/).map(s => Number(s)).filter(Number.isFinite);
|
|
460
|
+
if (nums.length >= 3) {
|
|
461
|
+
const [xL, xU, area, absMaybe] = nums;
|
|
462
|
+
out.push({
|
|
463
|
+
xL,
|
|
464
|
+
xU,
|
|
465
|
+
area,
|
|
466
|
+
absoluteArea: Number.isFinite(absMaybe) ? absMaybe : Math.abs(area),
|
|
467
|
+
xExtent: {
|
|
468
|
+
xL,
|
|
469
|
+
xU
|
|
470
|
+
}
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
});
|
|
474
|
+
return out;
|
|
475
|
+
};
|
|
476
|
+
const pickIntegralsForPair = (raw, idx) => {
|
|
477
|
+
if (raw == null) return '';
|
|
478
|
+
if (Array.isArray(raw)) return raw[idx] ?? '';
|
|
479
|
+
if (typeof raw === 'string') return idx === 0 ? raw : '';
|
|
480
|
+
return '';
|
|
481
|
+
};
|
|
482
|
+
if (isUvvisData) {
|
|
483
|
+
const spectraList = jcamp.spectra || [];
|
|
484
|
+
const uvvisSpectra = [];
|
|
485
|
+
const peakTablesByPage = new Map();
|
|
486
|
+
const hasPeakData = table => {
|
|
487
|
+
const data = table?.data?.[0];
|
|
488
|
+
if (!data) return false;
|
|
489
|
+
if (Array.isArray(data)) return data.length >= 2;
|
|
490
|
+
if (data?.x && data?.y) return data.x.length > 0 && data.y.length > 0;
|
|
491
|
+
return false;
|
|
492
|
+
};
|
|
493
|
+
const buildPeaks = source => {
|
|
494
|
+
if (!source) return [];
|
|
495
|
+
if (Array.isArray(source)) {
|
|
496
|
+
const peaks = [];
|
|
497
|
+
for (let i = 0; i < source.length - 1; i += 2) {
|
|
498
|
+
const x = Number(source[i]);
|
|
499
|
+
const y = Number(source[i + 1]);
|
|
500
|
+
if (Number.isFinite(x) && Number.isFinite(y)) peaks.push({
|
|
501
|
+
x,
|
|
502
|
+
y
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
return peaks;
|
|
506
|
+
}
|
|
507
|
+
if (source?.x && source?.y) {
|
|
508
|
+
const len = Math.min(source.x.length, source.y.length);
|
|
509
|
+
const peaks = new Array(len);
|
|
510
|
+
for (let j = 0; j < len; j++) peaks[j] = {
|
|
511
|
+
x: source.x[j],
|
|
512
|
+
y: source.y[j]
|
|
513
|
+
};
|
|
514
|
+
return peaks;
|
|
515
|
+
}
|
|
516
|
+
return [];
|
|
517
|
+
};
|
|
518
|
+
spectraList.forEach((s, idx) => {
|
|
519
|
+
if (!s) return;
|
|
520
|
+
const sDataType = String(s.dataType || '').toUpperCase();
|
|
521
|
+
const isUvvisSpectrum = s.dataType === 'LC/MS' && getCategory(idx).includes('UVVIS') || sDataType.includes('UV-VIS') || sDataType.includes('UVVIS') || sDataType.includes('HPLC UV');
|
|
522
|
+
if (isUvvisSpectrum) {
|
|
523
|
+
uvvisSpectra.push({
|
|
524
|
+
spectrum: s,
|
|
525
|
+
idx
|
|
526
|
+
});
|
|
527
|
+
}
|
|
528
|
+
if (s.dataType?.includes('PEAKTABLE')) {
|
|
529
|
+
const pageKey = s.pageValue ?? s.page;
|
|
530
|
+
if (pageKey == null) return;
|
|
531
|
+
const entry = peakTablesByPage.get(pageKey) || {};
|
|
532
|
+
const cat = getCategory(idx);
|
|
533
|
+
if (cat.includes('AUTO_PEAK')) entry.auto = s;else if (cat.includes('EDIT_PEAK')) entry.edit = s;else entry.other = s;
|
|
534
|
+
peakTablesByPage.set(pageKey, entry);
|
|
535
|
+
}
|
|
536
|
+
});
|
|
537
|
+
const container = jcamp?.info?.$OBSERVEDINTEGRALS ?? null;
|
|
538
|
+
const jcampUnitsField = String(jcamp?.info?.UNITS || '').toUpperCase();
|
|
539
|
+
const jcampUnitsIndicatesMinutes = jcampUnitsField.includes('MINUTE');
|
|
540
|
+
const jcampUnitsIndicatesSeconds = jcampUnitsField.includes('SECOND');
|
|
541
|
+
const getMaxAbsX = data => {
|
|
542
|
+
const xs = data?.[0]?.x;
|
|
543
|
+
if (!Array.isArray(xs) || xs.length === 0) return 0;
|
|
544
|
+
return xs.reduce((max, value) => {
|
|
545
|
+
const abs = Math.abs(Number(value));
|
|
546
|
+
return Number.isFinite(abs) && abs > max ? abs : max;
|
|
547
|
+
}, 0);
|
|
548
|
+
};
|
|
549
|
+
uvvisSpectra.forEach(({
|
|
550
|
+
spectrum
|
|
551
|
+
}, pairIdx) => {
|
|
552
|
+
const xUnitUpper = String(spectrum?.xUnit || '').toUpperCase();
|
|
553
|
+
const isExplicitMinutes = xUnitUpper.includes('MINUTE') || jcampUnitsIndicatesMinutes;
|
|
554
|
+
const isExplicitSeconds = xUnitUpper.includes('SECOND') || jcampUnitsIndicatesSeconds;
|
|
555
|
+
const isTimeAxis = xUnitUpper.includes('TIME') || xUnitUpper.includes('SECOND');
|
|
556
|
+
const dataLooksLikeSeconds = getMaxAbsX(spectrum?.data) > 60;
|
|
557
|
+
const needsSecToMin = isTimeAxis && !isExplicitMinutes && (isExplicitSeconds || dataLooksLikeSeconds);
|
|
558
|
+
const scaleX = value => needsSecToMin ? value / 60 : value;
|
|
559
|
+
const pageKey = spectrum.pageValue ?? spectrum.page;
|
|
560
|
+
const peakTable = peakTablesByPage.get(pageKey);
|
|
561
|
+
let selectedPeakTable = null;
|
|
562
|
+
if (hasPeakData(peakTable?.edit)) {
|
|
563
|
+
selectedPeakTable = peakTable.edit;
|
|
564
|
+
} else if (hasPeakData(peakTable?.auto)) {
|
|
565
|
+
selectedPeakTable = peakTable.auto;
|
|
566
|
+
} else if (hasPeakData(peakTable?.other)) {
|
|
567
|
+
selectedPeakTable = peakTable.other;
|
|
568
|
+
} else {
|
|
569
|
+
selectedPeakTable = peakTable?.edit || peakTable?.auto || peakTable?.other || null;
|
|
570
|
+
}
|
|
571
|
+
const originalData = spectrum?.data?.[0];
|
|
572
|
+
let normalizedData = spectrum.data;
|
|
573
|
+
if (needsSecToMin && originalData?.x) {
|
|
574
|
+
normalizedData = [{
|
|
575
|
+
...originalData,
|
|
576
|
+
x: originalData.x.map(scaleX)
|
|
577
|
+
}];
|
|
578
|
+
}
|
|
579
|
+
const mainSpectrum = {
|
|
580
|
+
...spectrum,
|
|
581
|
+
data: normalizedData,
|
|
582
|
+
peaks: [],
|
|
583
|
+
integrations: [],
|
|
584
|
+
csCategory: 'UVVIS PEAK TABLE'
|
|
585
|
+
};
|
|
586
|
+
const peakSource = selectedPeakTable?.data?.[0] || spectrum?.data?.[0];
|
|
587
|
+
const peaks = buildPeaks(peakSource).map(p => ({
|
|
588
|
+
...p,
|
|
589
|
+
x: scaleX(p.x)
|
|
590
|
+
}));
|
|
591
|
+
if (peaks.length) mainSpectrum.peaks = peaks;
|
|
592
|
+
const rawText = pickIntegralsForPair(container, pairIdx);
|
|
593
|
+
const integrals = parseIntegralsString(rawText).map(integ => ({
|
|
594
|
+
...integ,
|
|
595
|
+
xL: scaleX(integ.xL),
|
|
596
|
+
xU: scaleX(integ.xU),
|
|
597
|
+
xExtent: {
|
|
598
|
+
xL: scaleX(integ.xL),
|
|
599
|
+
xU: scaleX(integ.xU)
|
|
600
|
+
}
|
|
601
|
+
}));
|
|
602
|
+
if (integrals.length) mainSpectrum.integrations = integrals;
|
|
603
|
+
finalSpectra.push(mainSpectrum);
|
|
604
|
+
});
|
|
605
|
+
} else if (isTicData) {
|
|
606
|
+
(jcamp.spectra || []).forEach(s => {
|
|
607
|
+
const hasPoints = s?.data?.[0]?.x?.length > 0;
|
|
608
|
+
if (hasPoints) {
|
|
609
|
+
finalSpectra.push({
|
|
610
|
+
...s,
|
|
611
|
+
csCategory: (0, _parsing.inferLcMsCategory)(s, jcamp)
|
|
612
|
+
});
|
|
613
|
+
}
|
|
614
|
+
});
|
|
615
|
+
} else {
|
|
616
|
+
(jcamp.spectra || []).forEach(s => {
|
|
617
|
+
const hasPoints = s?.data?.[0]?.x?.length > 0;
|
|
618
|
+
if (hasPoints) {
|
|
619
|
+
finalSpectra.push({
|
|
620
|
+
...s,
|
|
621
|
+
csCategory: (0, _parsing.inferLcMsCategory)(s, jcamp)
|
|
622
|
+
});
|
|
623
|
+
}
|
|
624
|
+
});
|
|
625
|
+
}
|
|
626
|
+
let spectra = extrSpectraShare(finalSpectra, layout) || [];
|
|
627
|
+
const info = jcamp?.info || {};
|
|
628
|
+
if (info.UNITS && info.SYMBOL) {
|
|
629
|
+
const unitsString = Array.isArray(info.UNITS) ? info.UNITS[0] : info.UNITS;
|
|
630
|
+
const symbolString = Array.isArray(info.SYMBOL) ? info.SYMBOL[0] : info.SYMBOL;
|
|
631
|
+
const units = String(unitsString).split(',');
|
|
632
|
+
const symbols = String(symbolString).split(',');
|
|
395
633
|
let xUnit = null;
|
|
396
634
|
let yUnit = null;
|
|
397
|
-
|
|
398
|
-
const
|
|
399
|
-
if (
|
|
400
|
-
|
|
401
|
-
} else if (currSymbol === 'y') {
|
|
402
|
-
yUnit = units[idx].trim();
|
|
403
|
-
}
|
|
635
|
+
symbols.forEach((sym, idx) => {
|
|
636
|
+
const curr = String(sym).replace(' ', '').toLowerCase();
|
|
637
|
+
if (curr === 'x') xUnit = units[idx]?.trim?.() || null;
|
|
638
|
+
if (curr === 'y') yUnit = units[idx]?.trim?.() || null;
|
|
404
639
|
});
|
|
405
640
|
spectra = spectra.map(sp => {
|
|
406
641
|
const spectrum = sp;
|
|
407
|
-
if (xUnit)
|
|
408
|
-
|
|
409
|
-
}
|
|
410
|
-
if (yUnit) {
|
|
411
|
-
spectrum.yUnit = yUnit;
|
|
412
|
-
}
|
|
642
|
+
if (xUnit) spectrum.xUnit = xUnit;
|
|
643
|
+
if (yUnit) spectrum.yUnit = yUnit;
|
|
413
644
|
return spectrum;
|
|
414
645
|
});
|
|
415
646
|
}
|
|
@@ -422,21 +653,33 @@ const extrSpectraNi = (jcamp, layout) => {
|
|
|
422
653
|
return [spectrum] || [jcamp.spectra[0]];
|
|
423
654
|
};
|
|
424
655
|
const calcThresRef = (s, peakUp) => {
|
|
425
|
-
|
|
426
|
-
|
|
656
|
+
if (!s || !s.data || !Array.isArray(s.data) || !s.data[0] || !s.data[0].y) {
|
|
657
|
+
return null;
|
|
658
|
+
}
|
|
659
|
+
const ys = s.data[0].y;
|
|
660
|
+
if (!ys || !Array.isArray(ys) || ys.length === 0) return null;
|
|
427
661
|
const ref = peakUp ? Math.min(...ys.map(a => Math.abs(a))) : Math.max(...ys);
|
|
662
|
+
if (!s.maxY || s.maxY === 0) return null;
|
|
428
663
|
return peakUp ? Math.floor(ref * 100 * 100 / s.maxY) / 100 : Math.ceil(ref * 100 * 100 / s.maxY) / 100;
|
|
429
664
|
};
|
|
430
665
|
const calcUpperThres = s => {
|
|
431
|
-
|
|
432
|
-
|
|
666
|
+
if (!s || !s.data || !Array.isArray(s.data) || !s.data[0] || !s.data[0].y) {
|
|
667
|
+
return null;
|
|
668
|
+
}
|
|
669
|
+
const ys = s.data[0].y;
|
|
670
|
+
if (!ys || !Array.isArray(ys) || ys.length === 0) return null;
|
|
433
671
|
const ref = Math.max(...ys);
|
|
672
|
+
if (!s.maxY || s.maxY === 0) return null;
|
|
434
673
|
return Math.floor(ref * 100 * 100 / s.maxY) / 100;
|
|
435
674
|
};
|
|
436
675
|
const calcLowerThres = s => {
|
|
437
|
-
|
|
438
|
-
|
|
676
|
+
if (!s || !s.data || !Array.isArray(s.data) || !s.data[0] || !s.data[0].y) {
|
|
677
|
+
return null;
|
|
678
|
+
}
|
|
679
|
+
const ys = s.data[0].y;
|
|
680
|
+
if (!ys || !Array.isArray(ys) || ys.length === 0) return null;
|
|
439
681
|
const ref = Math.min(...ys);
|
|
682
|
+
if (!s.minY || s.minY === 0) return null;
|
|
440
683
|
return Math.ceil(ref * 100 * 100 / s.minY) / 100;
|
|
441
684
|
};
|
|
442
685
|
const extractShift = (s, jcamp) => {
|
|
@@ -492,13 +735,12 @@ const extractVoltammetryData = jcamp => {
|
|
|
492
735
|
return peakStack;
|
|
493
736
|
};
|
|
494
737
|
const buildPeakFeature = (jcamp, layout, peakUp, s, thresRef, upperThres = false, lowerThres = false) => {
|
|
495
|
-
// eslint-disable-line
|
|
496
738
|
const {
|
|
497
739
|
xType,
|
|
498
740
|
info
|
|
499
741
|
} = jcamp;
|
|
500
742
|
const subTyp = xType ? ` - ${xType}` : '';
|
|
501
|
-
|
|
743
|
+
const baseFeature = {
|
|
502
744
|
typ: s.dataType + subTyp,
|
|
503
745
|
peakUp,
|
|
504
746
|
thresRef,
|
|
@@ -518,8 +760,14 @@ const buildPeakFeature = (jcamp, layout, peakUp, s, thresRef, upperThres = false
|
|
|
518
760
|
scanRate: +info.$CSSCANRATE || 0.1,
|
|
519
761
|
weAreaValue: info.$CSWEAREAVALUE || '',
|
|
520
762
|
weAreaUnit: info.$CSWEAREAUNIT || '',
|
|
521
|
-
currentMode: info.$CSCURRENTMODE || ''
|
|
522
|
-
|
|
763
|
+
currentMode: info.$CSCURRENTMODE || '',
|
|
764
|
+
csCategory: info.$CSCATEGORY || s.csCategory
|
|
765
|
+
};
|
|
766
|
+
if (layout === 'LC/MS') {
|
|
767
|
+
if (s.peaks) baseFeature.peaks = s.peaks;
|
|
768
|
+
if (s.integrations) baseFeature.integrations = s.integrations;
|
|
769
|
+
}
|
|
770
|
+
return Object.assign({}, baseFeature, s);
|
|
523
771
|
};
|
|
524
772
|
const maxArray = arr => {
|
|
525
773
|
let len = arr.length;
|
|
@@ -547,23 +795,43 @@ const calcIntgRefArea = (spectra, stack) => {
|
|
|
547
795
|
raw2realRatio
|
|
548
796
|
};
|
|
549
797
|
};
|
|
798
|
+
const parseObservedIntegralGroups = rawValue => {
|
|
799
|
+
if (!rawValue) return {};
|
|
800
|
+
const tokenRegx = /[^A-Za-z0-9._-]/g;
|
|
801
|
+
const groupsByIdx = {};
|
|
802
|
+
rawValue.split('\n').forEach(line => {
|
|
803
|
+
const cells = line.split(',').map(c => c.replace(tokenRegx, ''));
|
|
804
|
+
if (cells.length < 2) return;
|
|
805
|
+
const idx = parseInt(cells[0], 10);
|
|
806
|
+
const groupId = cells[1];
|
|
807
|
+
if (!Number.isInteger(idx) || idx < 0 || !groupId) return;
|
|
808
|
+
groupsByIdx[idx] = groupId;
|
|
809
|
+
});
|
|
810
|
+
return groupsByIdx;
|
|
811
|
+
};
|
|
550
812
|
const buildIntegFeature = (jcamp, spectra) => {
|
|
551
813
|
const {
|
|
552
814
|
$OBSERVEDINTEGRALS,
|
|
553
|
-
$OBSERVEDMULTIPLETS
|
|
815
|
+
$OBSERVEDMULTIPLETS,
|
|
816
|
+
$OBSERVEDINTEGRALSGROUPS
|
|
554
817
|
} = jcamp.info;
|
|
555
818
|
const regx = /[^0-9.,-]/g;
|
|
556
819
|
let stack = [];
|
|
557
820
|
if ($OBSERVEDINTEGRALS) {
|
|
558
821
|
const its = $OBSERVEDINTEGRALS.split('\n').slice(1);
|
|
559
|
-
const
|
|
822
|
+
const groupsByIdx = parseObservedIntegralGroups($OBSERVEDINTEGRALSGROUPS);
|
|
823
|
+
const itStack = its.map((t, idx) => {
|
|
560
824
|
const ts = t.replace(regx, '').split(',');
|
|
561
|
-
|
|
825
|
+
const item = {
|
|
562
826
|
xL: parseFloat(ts[0]),
|
|
563
827
|
xU: parseFloat(ts[1]),
|
|
564
828
|
area: parseFloat(ts[2]),
|
|
565
829
|
absoluteArea: parseFloat(ts[3])
|
|
566
830
|
};
|
|
831
|
+
const groupId = groupsByIdx[idx];
|
|
832
|
+
return groupId ? Object.assign({}, item, {
|
|
833
|
+
visualSplitGroupId: groupId
|
|
834
|
+
}) : item;
|
|
567
835
|
});
|
|
568
836
|
stack = [...stack, ...itStack];
|
|
569
837
|
}
|
|
@@ -602,7 +870,7 @@ const range = (head, tail, length) => {
|
|
|
602
870
|
);
|
|
603
871
|
};
|
|
604
872
|
*/
|
|
605
|
-
|
|
873
|
+
exports.buildIntegFeature = buildIntegFeature;
|
|
606
874
|
const buildSimFeature = jcamp => {
|
|
607
875
|
const {
|
|
608
876
|
$CSSIMULATIONPEAKS
|
|
@@ -780,32 +1048,15 @@ const extrFeaturesCylicVolta = (jcamp, layout, peakUp) => {
|
|
|
780
1048
|
}).filter(r => r != null);
|
|
781
1049
|
return features;
|
|
782
1050
|
};
|
|
783
|
-
const extrFeaturesMs = (jcamp, layout, peakUp) => {
|
|
784
|
-
// const nfs = {};
|
|
785
|
-
// const category = jcamp.info.$CSCATEGORY;
|
|
786
|
-
// const scanCount = parseInt(jcamp.info.$CSSCANCOUNT, 10) - 1;
|
|
787
|
-
// if (category) {
|
|
788
|
-
// const idxEditPeak = category.indexOf('EDIT_PEAK');
|
|
789
|
-
// if (idxEditPeak >= 0) {
|
|
790
|
-
// const sEP = jcamp.spectra[idxEditPeak + scanCount];
|
|
791
|
-
// const thresRef = calcThresRef(sEP, peakUp);
|
|
792
|
-
// nfs.editPeak = buildPeakFeature(jcamp, layout, peakUp, sEP, thresRef);
|
|
793
|
-
// }
|
|
794
|
-
// const idxAutoPeak = category.indexOf('AUTO_PEAK');
|
|
795
|
-
// if (idxAutoPeak >= 0) {
|
|
796
|
-
// const sAP = jcamp.spectra[idxAutoPeak + scanCount];
|
|
797
|
-
// const thresRef = calcThresRef(sAP, peakUp);
|
|
798
|
-
// nfs.autoPeak = buildPeakFeature(jcamp, layout, peakUp, sAP, thresRef);
|
|
799
|
-
// }
|
|
800
|
-
// return nfs;
|
|
801
|
-
// }
|
|
802
|
-
// // workaround for legacy design
|
|
1051
|
+
const extrFeaturesMs = (jcamp, layout, peakUp, spectra) => {
|
|
803
1052
|
const thresRef = jcamp.info && jcamp.info.$CSTHRESHOLD * 100 || 5;
|
|
804
|
-
const
|
|
805
|
-
|
|
1053
|
+
const features = spectra.map(s => {
|
|
1054
|
+
if (!s.data || !s.data[0] || !s.data[0].x || !s.data[0].y) {
|
|
1055
|
+
return null;
|
|
1056
|
+
}
|
|
806
1057
|
const cpo = buildPeakFeature(jcamp, layout, peakUp, s, +thresRef.toFixed(4));
|
|
807
1058
|
const bnd = getBoundary(s);
|
|
808
|
-
return Object.assign({},
|
|
1059
|
+
return Object.assign({}, cpo, bnd);
|
|
809
1060
|
}).filter(r => r != null);
|
|
810
1061
|
return features;
|
|
811
1062
|
};
|
|
@@ -819,17 +1070,135 @@ const extractTemperature = jcamp => {
|
|
|
819
1070
|
}
|
|
820
1071
|
return 'xxx';
|
|
821
1072
|
};
|
|
1073
|
+
const normalizeXyData = raw => {
|
|
1074
|
+
if (!raw) return null;
|
|
1075
|
+
if (Array.isArray(raw)) {
|
|
1076
|
+
if (raw.length === 0) return null;
|
|
1077
|
+
const first = raw[0];
|
|
1078
|
+
if (first && typeof first === 'object' && !Array.isArray(first)) {
|
|
1079
|
+
const x = Array.isArray(first.x) ? first.x : [];
|
|
1080
|
+
const y = Array.isArray(first.y) ? first.y : [];
|
|
1081
|
+
if (x.length || y.length) return {
|
|
1082
|
+
x,
|
|
1083
|
+
y
|
|
1084
|
+
};
|
|
1085
|
+
}
|
|
1086
|
+
if (Array.isArray(first)) {
|
|
1087
|
+
if (raw.length === 2 && Array.isArray(raw[0]) && Array.isArray(raw[1])) {
|
|
1088
|
+
return {
|
|
1089
|
+
x: raw[0],
|
|
1090
|
+
y: raw[1]
|
|
1091
|
+
};
|
|
1092
|
+
}
|
|
1093
|
+
const x = [];
|
|
1094
|
+
const y = [];
|
|
1095
|
+
raw.forEach(pair => {
|
|
1096
|
+
if (!Array.isArray(pair) || pair.length < 2) return;
|
|
1097
|
+
const xVal = Number(pair[0]);
|
|
1098
|
+
const yVal = Number(pair[1]);
|
|
1099
|
+
if (Number.isFinite(xVal) && Number.isFinite(yVal)) {
|
|
1100
|
+
x.push(xVal);
|
|
1101
|
+
y.push(yVal);
|
|
1102
|
+
}
|
|
1103
|
+
});
|
|
1104
|
+
if (x.length || y.length) return {
|
|
1105
|
+
x,
|
|
1106
|
+
y
|
|
1107
|
+
};
|
|
1108
|
+
}
|
|
1109
|
+
} else if (typeof raw === 'object') {
|
|
1110
|
+
const x = Array.isArray(raw.x) ? raw.x : [];
|
|
1111
|
+
const y = Array.isArray(raw.y) ? raw.y : [];
|
|
1112
|
+
if (x.length || y.length) return {
|
|
1113
|
+
x,
|
|
1114
|
+
y
|
|
1115
|
+
};
|
|
1116
|
+
}
|
|
1117
|
+
return null;
|
|
1118
|
+
};
|
|
1119
|
+
const ensureSpectrumData = (spectrum, source) => {
|
|
1120
|
+
if (!spectrum) return spectrum;
|
|
1121
|
+
const result = {
|
|
1122
|
+
...spectrum
|
|
1123
|
+
};
|
|
1124
|
+
let normalized = normalizeXyData(result.data);
|
|
1125
|
+
if (!normalized && source) {
|
|
1126
|
+
normalized = normalizeXyData({
|
|
1127
|
+
x: source.x,
|
|
1128
|
+
y: source.y
|
|
1129
|
+
}) || normalizeXyData(source.data);
|
|
1130
|
+
}
|
|
1131
|
+
if (normalized) {
|
|
1132
|
+
result.data = [{
|
|
1133
|
+
x: normalized.x || [],
|
|
1134
|
+
y: normalized.y || []
|
|
1135
|
+
}];
|
|
1136
|
+
}
|
|
1137
|
+
return result;
|
|
1138
|
+
};
|
|
822
1139
|
const ExtractJcamp = source => {
|
|
823
1140
|
const jcamp = _jcampconverter.default.convert(source, {
|
|
824
1141
|
xy: true,
|
|
825
|
-
keepRecordsRegExp: /(\$CSTHRESHOLD|\$CSSCANAUTOTARGET|\$CSSCANEDITTARGET|\$CSSCANCOUNT|\$CSSOLVENTNAME|\$CSSOLVENTVALUE|\$CSSOLVENTX|\$CSCATEGORY|\$CSITAREA|\$CSITFACTOR|\$OBSERVEDINTEGRALS|\$OBSERVEDMULTIPLETS|\$OBSERVEDMULTIPLETSPEAKS|\.SOLVENTNAME|\.OBSERVEFREQUENCY|\$CSSIMULATIONPEAKS|\$CSUPPERTHRESHOLD|\$CSLOWERTHRESHOLD|\$CSCYCLICVOLTAMMETRYDATA|UNITS|SYMBOL|\$CSAUTOMETADATA|\$DETECTOR|MN|MW|D|MP|MELTINGPOINT|TG|\$CSSCANRATE|\$CSSPECTRUMDIRECTION|\$CSWEAREAVALUE|\$CSWEAREAUNIT|\$CSCURRENTMODE)/ // eslint-disable-line
|
|
1142
|
+
keepRecordsRegExp: /(\$CSTHRESHOLD|\$CSSCANAUTOTARGET|\$CSSCANEDITTARGET|\$CSSCANCOUNT|\$CSSOLVENTNAME|\$CSSOLVENTVALUE|\$CSSOLVENTX|\$CSCATEGORY|\$CSITAREA|\$CSITFACTOR|\$OBSERVEDINTEGRALS|\$OBSERVEDINTEGRALSGROUPS|\$OBSERVEDMULTIPLETS|\$OBSERVEDMULTIPLETSPEAKS|\.SOLVENTNAME|\.OBSERVEFREQUENCY|\$CSSIMULATIONPEAKS|\$CSUPPERTHRESHOLD|\$CSLOWERTHRESHOLD|\$CSCYCLICVOLTAMMETRYDATA|UNITS|SYMBOL|\$CSAUTOMETADATA|\$DETECTOR|MN|MW|D|MP|MELTINGPOINT|TG|\$CSSCANRATE|\$CSSPECTRUMDIRECTION|\$CSWEAREAVALUE|\$CSWEAREAUNIT|\$CSCURRENTMODE|\$CSLCMSMZPAGE|SCAN_MODE|SCANMODE|TYPE|SOFTWARE|DATATYPE)/ // eslint-disable-line
|
|
826
1143
|
});
|
|
827
|
-
const
|
|
1144
|
+
const isChemstation = (0, _parsing.isChemstationLcms)(source, jcamp);
|
|
1145
|
+
const parsedPages = (0, _parsing.parseChemstationPages)(source, jcamp);
|
|
1146
|
+
const spectraCount = Array.isArray(jcamp.spectra) ? jcamp.spectra.length : 0;
|
|
1147
|
+
if (parsedPages.length > 1 && spectraCount < parsedPages.length) {
|
|
1148
|
+
jcamp.spectra = parsedPages;
|
|
1149
|
+
}
|
|
1150
|
+
const hasNtuples = jcamp.ntuples && Array.isArray(jcamp.ntuples) && jcamp.ntuples.length > 0;
|
|
1151
|
+
const hasSpectra = jcamp.spectra && Array.isArray(jcamp.spectra) && jcamp.spectra.length > 0;
|
|
1152
|
+
const hasNtupleData = hasNtuples && jcamp.ntuples.some(ntuple => !!normalizeXyData(ntuple?.data) || !!normalizeXyData({
|
|
1153
|
+
x: ntuple?.x,
|
|
1154
|
+
y: ntuple?.y
|
|
1155
|
+
}));
|
|
1156
|
+
const hasSpectraData = hasSpectra && jcamp.spectra.some(spectrum => !!normalizeXyData(spectrum?.data) || !!normalizeXyData({
|
|
1157
|
+
x: spectrum?.x,
|
|
1158
|
+
y: spectrum?.y
|
|
1159
|
+
}));
|
|
1160
|
+
if (hasNtuples && hasNtupleData) {
|
|
1161
|
+
if (hasSpectra && jcamp.spectra.length === 1 && jcamp.ntuples.length > 1) {
|
|
1162
|
+
const singleSpectrum = jcamp.spectra[0];
|
|
1163
|
+
jcamp.spectra = jcamp.ntuples.map(ntuple => {
|
|
1164
|
+
const spectrum = {
|
|
1165
|
+
...singleSpectrum,
|
|
1166
|
+
...ntuple,
|
|
1167
|
+
dataType: singleSpectrum.dataType || jcamp.dataType || ntuple.dataType,
|
|
1168
|
+
xUnit: ntuple.xUnit || singleSpectrum.xUnit || jcamp.info?.XUNITS,
|
|
1169
|
+
yUnit: ntuple.yUnit || singleSpectrum.yUnit || jcamp.info?.YUNITS,
|
|
1170
|
+
pageValue: ntuple.pageValue || ntuple.page,
|
|
1171
|
+
page: ntuple.page || ntuple.pageValue,
|
|
1172
|
+
pageSymbol: ntuple.pageSymbol || ntuple.pageValue || ntuple.page
|
|
1173
|
+
};
|
|
1174
|
+
ensureSpectrumData(spectrum, ntuple);
|
|
1175
|
+
return spectrum;
|
|
1176
|
+
});
|
|
1177
|
+
} else if (!hasSpectra || !hasSpectraData || jcamp.spectra.length < jcamp.ntuples.length) {
|
|
1178
|
+
jcamp.spectra = jcamp.ntuples.map(ntuple => {
|
|
1179
|
+
const spectrum = {
|
|
1180
|
+
...ntuple,
|
|
1181
|
+
dataType: jcamp.dataType || ntuple.dataType,
|
|
1182
|
+
xUnit: ntuple.xUnit || jcamp.info?.XUNITS,
|
|
1183
|
+
yUnit: ntuple.yUnit || jcamp.info?.YUNITS,
|
|
1184
|
+
pageValue: ntuple.pageValue || ntuple.page,
|
|
1185
|
+
page: ntuple.page || ntuple.pageValue,
|
|
1186
|
+
pageSymbol: ntuple.pageSymbol || ntuple.pageValue || ntuple.page
|
|
1187
|
+
};
|
|
1188
|
+
ensureSpectrumData(spectrum, ntuple);
|
|
1189
|
+
return spectrum;
|
|
1190
|
+
});
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
let layout = readLayout(jcamp);
|
|
1194
|
+
if (isChemstation) {
|
|
1195
|
+
layout = _list_layout.LIST_LAYOUT.LC_MS;
|
|
1196
|
+
}
|
|
828
1197
|
const peakUp = !_format.default.isIrLayout(layout);
|
|
829
|
-
const spectra = _format.default.isMsLayout(layout) ? extrSpectraMs(jcamp, layout) : extrSpectraNi(jcamp, layout);
|
|
1198
|
+
const spectra = _format.default.isMsLayout(layout) || _format.default.isLCMsLayout(layout) ? extrSpectraMs(jcamp, layout) : extrSpectraNi(jcamp, layout);
|
|
830
1199
|
let features = {};
|
|
831
|
-
if (_format.default.isMsLayout(layout)) {
|
|
832
|
-
features = extrFeaturesMs(jcamp, layout, peakUp);
|
|
1200
|
+
if (_format.default.isMsLayout(layout) || _format.default.isLCMsLayout(layout)) {
|
|
1201
|
+
features = extrFeaturesMs(jcamp, layout, peakUp, spectra);
|
|
833
1202
|
} else if (_format.default.isXRDLayout(layout)) {
|
|
834
1203
|
features = extrFeaturesXrd(jcamp, layout, peakUp);
|
|
835
1204
|
const temperature = extractTemperature(jcamp);
|
|
@@ -865,6 +1234,15 @@ const ExtractJcamp = source => {
|
|
|
865
1234
|
// : ((Format.isXRDLayout(layout) || Format.isCyclicVoltaLayout(layout))
|
|
866
1235
|
// ? extrFeaturesXrd(jcamp, layout, peakUp) : extrFeaturesNi(jcamp, layout, peakUp, spectra));
|
|
867
1236
|
|
|
1237
|
+
const lcmsMzPageFromInfo = _format.default.isLCMsLayout(layout) ? (0, _parsing.readLcmsMzPageFromJcampInfo)(jcamp.info) : null;
|
|
1238
|
+
if (lcmsMzPageFromInfo != null) {
|
|
1239
|
+
return {
|
|
1240
|
+
spectra,
|
|
1241
|
+
features,
|
|
1242
|
+
layout,
|
|
1243
|
+
lcms_mz_page: lcmsMzPageFromInfo
|
|
1244
|
+
};
|
|
1245
|
+
}
|
|
868
1246
|
return {
|
|
869
1247
|
spectra,
|
|
870
1248
|
features,
|