jcampconverter 8.2.2 → 8.2.3
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/lib/2d/add2D.d.ts +2 -0
- package/lib/2d/add2D.d.ts.map +1 -0
- package/lib/2d/add2D.js +17 -0
- package/lib/2d/add2D.js.map +1 -0
- package/lib/2d/convertTo3DZ.d.ts +11 -0
- package/lib/2d/convertTo3DZ.d.ts.map +1 -0
- package/lib/2d/convertTo3DZ.js +59 -0
- package/lib/2d/convertTo3DZ.js.map +1 -0
- package/lib/2d/generateContourLines.d.ts +8 -0
- package/lib/2d/generateContourLines.d.ts.map +1 -0
- package/lib/2d/generateContourLines.js +163 -0
- package/lib/2d/generateContourLines.js.map +1 -0
- package/lib/complexChromatogram.d.ts +4 -0
- package/lib/complexChromatogram.d.ts.map +1 -0
- package/lib/complexChromatogram.js +49 -0
- package/lib/complexChromatogram.js.map +1 -0
- package/lib/convert.d.ts +139 -0
- package/lib/convert.d.ts.map +1 -0
- package/lib/convert.js +383 -0
- package/lib/convert.js.map +1 -0
- package/lib/convertToFloatArray.d.ts +2 -0
- package/lib/convertToFloatArray.d.ts.map +1 -0
- package/lib/convertToFloatArray.js +11 -0
- package/lib/convertToFloatArray.js.map +1 -0
- package/lib/createTree.d.ts +29 -0
- package/lib/createTree.d.ts.map +1 -0
- package/lib/createTree.js +98 -0
- package/lib/createTree.js.map +1 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +8 -1214
- package/lib/index.js.map +1 -0
- package/lib/parse/fastParseXYData.d.ts +2 -0
- package/lib/parse/fastParseXYData.d.ts.map +1 -0
- package/lib/parse/fastParseXYData.js +192 -0
- package/lib/parse/fastParseXYData.js.map +1 -0
- package/lib/parse/parsePeakTable.d.ts +2 -0
- package/lib/parse/parsePeakTable.d.ts.map +1 -0
- package/lib/parse/parsePeakTable.js +67 -0
- package/lib/parse/parsePeakTable.js.map +1 -0
- package/lib/parse/parseXYA.d.ts +2 -0
- package/lib/parse/parseXYA.d.ts.map +1 -0
- package/lib/parse/parseXYA.js +17 -0
- package/lib/parse/parseXYA.js.map +1 -0
- package/lib/postProcessing.d.ts +2 -0
- package/lib/postProcessing.d.ts.map +1 -0
- package/lib/postProcessing.js +50 -0
- package/lib/postProcessing.js.map +1 -0
- package/lib/postProcessingNMR.d.ts +2 -0
- package/lib/postProcessingNMR.d.ts.map +1 -0
- package/lib/postProcessingNMR.js +94 -0
- package/lib/postProcessingNMR.js.map +1 -0
- package/lib/prepareNtuplesDatatable.d.ts +2 -0
- package/lib/prepareNtuplesDatatable.d.ts.map +1 -0
- package/lib/prepareNtuplesDatatable.js +87 -0
- package/lib/prepareNtuplesDatatable.js.map +1 -0
- package/lib/prepareSpectrum.d.ts +2 -0
- package/lib/prepareSpectrum.d.ts.map +1 -0
- package/lib/prepareSpectrum.js +10 -0
- package/lib/prepareSpectrum.js.map +1 -0
- package/lib/profiling.d.ts +2 -0
- package/lib/profiling.d.ts.map +1 -0
- package/lib/profiling.js +12 -0
- package/lib/profiling.js.map +1 -0
- package/lib/simpleChromatogram.d.ts +2 -0
- package/lib/simpleChromatogram.d.ts.map +1 -0
- package/lib/simpleChromatogram.js +16 -0
- package/lib/simpleChromatogram.js.map +1 -0
- package/lib-esm/2d/add2D.d.ts +2 -0
- package/lib-esm/2d/add2D.d.ts.map +1 -0
- package/lib-esm/2d/add2D.js +11 -0
- package/lib-esm/2d/add2D.js.map +1 -0
- package/lib-esm/2d/convertTo3DZ.d.ts +11 -0
- package/lib-esm/2d/convertTo3DZ.d.ts.map +1 -0
- package/lib-esm/2d/convertTo3DZ.js +53 -0
- package/lib-esm/2d/convertTo3DZ.js.map +1 -0
- package/lib-esm/2d/generateContourLines.d.ts +8 -0
- package/lib-esm/2d/generateContourLines.d.ts.map +1 -0
- package/lib-esm/2d/generateContourLines.js +160 -0
- package/lib-esm/2d/generateContourLines.js.map +1 -0
- package/lib-esm/complexChromatogram.d.ts +4 -0
- package/lib-esm/complexChromatogram.d.ts.map +1 -0
- package/lib-esm/complexChromatogram.js +43 -0
- package/lib-esm/complexChromatogram.js.map +1 -0
- package/lib-esm/convert.d.ts +139 -0
- package/lib-esm/convert.d.ts.map +1 -0
- package/lib-esm/convert.js +376 -0
- package/lib-esm/convert.js.map +1 -0
- package/lib-esm/convertToFloatArray.d.ts +2 -0
- package/lib-esm/convertToFloatArray.d.ts.map +1 -0
- package/lib-esm/convertToFloatArray.js +8 -0
- package/lib-esm/convertToFloatArray.js.map +1 -0
- package/lib-esm/createTree.d.ts +29 -0
- package/lib-esm/createTree.d.ts.map +1 -0
- package/lib-esm/createTree.js +94 -0
- package/lib-esm/createTree.js.map +1 -0
- package/lib-esm/index.d.ts +3 -0
- package/lib-esm/index.d.ts.map +1 -0
- package/lib-esm/index.js +3 -0
- package/lib-esm/index.js.map +1 -0
- package/lib-esm/parse/fastParseXYData.d.ts +2 -0
- package/lib-esm/parse/fastParseXYData.d.ts.map +1 -0
- package/lib-esm/parse/fastParseXYData.js +189 -0
- package/lib-esm/parse/fastParseXYData.js.map +1 -0
- package/lib-esm/parse/parsePeakTable.d.ts +2 -0
- package/lib-esm/parse/parsePeakTable.d.ts.map +1 -0
- package/lib-esm/parse/parsePeakTable.js +64 -0
- package/lib-esm/parse/parsePeakTable.js.map +1 -0
- package/lib-esm/parse/parseXYA.d.ts +2 -0
- package/lib-esm/parse/parseXYA.d.ts.map +1 -0
- package/lib-esm/parse/parseXYA.js +14 -0
- package/lib-esm/parse/parseXYA.js.map +1 -0
- package/lib-esm/postProcessing.d.ts +2 -0
- package/lib-esm/postProcessing.d.ts.map +1 -0
- package/lib-esm/postProcessing.js +44 -0
- package/lib-esm/postProcessing.js.map +1 -0
- package/lib-esm/postProcessingNMR.d.ts +2 -0
- package/lib-esm/postProcessingNMR.d.ts.map +1 -0
- package/lib-esm/postProcessingNMR.js +91 -0
- package/lib-esm/postProcessingNMR.js.map +1 -0
- package/lib-esm/prepareNtuplesDatatable.d.ts +2 -0
- package/lib-esm/prepareNtuplesDatatable.d.ts.map +1 -0
- package/lib-esm/prepareNtuplesDatatable.js +84 -0
- package/lib-esm/prepareNtuplesDatatable.js.map +1 -0
- package/lib-esm/prepareSpectrum.d.ts +2 -0
- package/lib-esm/prepareSpectrum.d.ts.map +1 -0
- package/lib-esm/prepareSpectrum.js +7 -0
- package/lib-esm/prepareSpectrum.js.map +1 -0
- package/lib-esm/profiling.d.ts +2 -0
- package/lib-esm/profiling.d.ts.map +1 -0
- package/lib-esm/profiling.js +9 -0
- package/lib-esm/profiling.js.map +1 -0
- package/lib-esm/simpleChromatogram.d.ts +2 -0
- package/lib-esm/simpleChromatogram.d.ts.map +1 -0
- package/lib-esm/simpleChromatogram.js +13 -0
- package/lib-esm/simpleChromatogram.js.map +1 -0
- package/package.json +22 -17
- package/src/convert.js +57 -13
- package/src/createTree.js +16 -3
- package/CHANGELOG.md +0 -427
package/lib/index.js
CHANGED
|
@@ -1,1214 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
var
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
11
|
-
|
|
12
|
-
var getMedian__default = /*#__PURE__*/_interopDefaultLegacy(getMedian);
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Parse the jcamp to extract the structure as a tree.
|
|
16
|
-
*
|
|
17
|
-
* @param {string|ArrayBuffer|Uint8Array} jcamp
|
|
18
|
-
* @param {object} [options={}]
|
|
19
|
-
* @param {boolean} [options.flatten=false]
|
|
20
|
-
* @returns
|
|
21
|
-
*/
|
|
22
|
-
function createTree(jcamp, options = {}) {
|
|
23
|
-
jcamp = ensureString.ensureString(jcamp);
|
|
24
|
-
const { flatten = false } = options;
|
|
25
|
-
if (typeof jcamp !== 'string') {
|
|
26
|
-
throw new TypeError('the JCAMP should be a string');
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
let lines = jcamp.split(/[\r\n]+/);
|
|
30
|
-
let flat = [];
|
|
31
|
-
let stack = [];
|
|
32
|
-
let result = [];
|
|
33
|
-
let current;
|
|
34
|
-
let ntupleLevel = 0;
|
|
35
|
-
|
|
36
|
-
let spaces = jcamp.includes('## ');
|
|
37
|
-
|
|
38
|
-
for (let i = 0; i < lines.length; i++) {
|
|
39
|
-
let line = lines[i];
|
|
40
|
-
let labelLine = spaces ? line.replace(/ /g, '') : line;
|
|
41
|
-
|
|
42
|
-
if (labelLine.substring(0, 9) === '##NTUPLES') {
|
|
43
|
-
ntupleLevel++;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if (labelLine.substring(0, 7) === '##TITLE') {
|
|
47
|
-
let title = [labelLine.substring(8).trim()];
|
|
48
|
-
for (let j = i + 1; j < lines.length; j++) {
|
|
49
|
-
if (lines[j].startsWith('##')) {
|
|
50
|
-
break;
|
|
51
|
-
} else {
|
|
52
|
-
title.push(lines[j].trim());
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
stack.push({
|
|
56
|
-
title: title.join('\n'),
|
|
57
|
-
jcamp: `${line}\n`,
|
|
58
|
-
children: [],
|
|
59
|
-
});
|
|
60
|
-
current = stack[stack.length - 1];
|
|
61
|
-
flat.push(current);
|
|
62
|
-
} else if (labelLine.substring(0, 5) === '##END' && ntupleLevel === 0) {
|
|
63
|
-
current.jcamp += `${line}\n`;
|
|
64
|
-
let finished = stack.pop();
|
|
65
|
-
if (stack.length !== 0) {
|
|
66
|
-
current = stack[stack.length - 1];
|
|
67
|
-
current.children.push(finished);
|
|
68
|
-
} else {
|
|
69
|
-
current = undefined;
|
|
70
|
-
result.push(finished);
|
|
71
|
-
}
|
|
72
|
-
} else if (current && current.jcamp) {
|
|
73
|
-
current.jcamp += `${line}\n`;
|
|
74
|
-
let match = labelLine.match(/^##(.*?)=(.+)/);
|
|
75
|
-
if (match) {
|
|
76
|
-
let canonicDataLabel = match[1].replace(/[ _-]/g, '').toUpperCase();
|
|
77
|
-
if (canonicDataLabel === 'DATATYPE') {
|
|
78
|
-
current.dataType = match[2].trim();
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (labelLine.substring(0, 5) === '##END' && ntupleLevel > 0) {
|
|
84
|
-
ntupleLevel--;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
if (flatten) {
|
|
88
|
-
flat.forEach((entry) => {
|
|
89
|
-
entry.children = undefined;
|
|
90
|
-
});
|
|
91
|
-
return flat;
|
|
92
|
-
} else {
|
|
93
|
-
return result;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
const GC_MS_FIELDS = ['TIC', '.RIC', 'SCANNUMBER'];
|
|
98
|
-
|
|
99
|
-
function complexChromatogram(result) {
|
|
100
|
-
let spectra = result.spectra;
|
|
101
|
-
let length = spectra.length;
|
|
102
|
-
let chromatogram = {
|
|
103
|
-
times: new Array(length),
|
|
104
|
-
series: {
|
|
105
|
-
ms: {
|
|
106
|
-
dimension: 2,
|
|
107
|
-
data: new Array(length),
|
|
108
|
-
},
|
|
109
|
-
},
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
let existingGCMSFields = [];
|
|
113
|
-
for (let i = 0; i < GC_MS_FIELDS.length; i++) {
|
|
114
|
-
let label = convertMSFieldToLabel(GC_MS_FIELDS[i]);
|
|
115
|
-
if (spectra[0][label]) {
|
|
116
|
-
existingGCMSFields.push(label);
|
|
117
|
-
chromatogram.series[label] = {
|
|
118
|
-
dimension: 1,
|
|
119
|
-
data: new Array(length),
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
for (let i = 0; i < length; i++) {
|
|
125
|
-
let spectrum = spectra[i];
|
|
126
|
-
chromatogram.times[i] = spectrum.pageValue;
|
|
127
|
-
for (let j = 0; j < existingGCMSFields.length; j++) {
|
|
128
|
-
chromatogram.series[existingGCMSFields[j]].data[i] = Number(
|
|
129
|
-
spectrum[existingGCMSFields[j]],
|
|
130
|
-
);
|
|
131
|
-
}
|
|
132
|
-
if (spectrum.data) {
|
|
133
|
-
chromatogram.series.ms.data[i] = [spectrum.data.x, spectrum.data.y];
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
result.chromatogram = chromatogram;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
function isMSField(canonicDataLabel) {
|
|
140
|
-
return GC_MS_FIELDS.indexOf(canonicDataLabel) !== -1;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
function convertMSFieldToLabel(value) {
|
|
144
|
-
return value.toLowerCase().replace(/[^a-z0-9]/g, '');
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
function convertToFloatArray(stringArray) {
|
|
148
|
-
let floatArray = [];
|
|
149
|
-
for (let i = 0; i < stringArray.length; i++) {
|
|
150
|
-
floatArray.push(Number(stringArray[i]));
|
|
151
|
-
}
|
|
152
|
-
return floatArray;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
function fastParseXYData(spectrum, value) {
|
|
156
|
-
// TODO need to deal with result
|
|
157
|
-
// console.log(value);
|
|
158
|
-
// we check if deltaX is defined otherwise we calculate it
|
|
159
|
-
|
|
160
|
-
let yFactor = spectrum.yFactor;
|
|
161
|
-
let deltaX = spectrum.deltaX;
|
|
162
|
-
|
|
163
|
-
spectrum.isXYdata = true;
|
|
164
|
-
let currentData = { x: [], y: [] };
|
|
165
|
-
spectrum.data = currentData;
|
|
166
|
-
|
|
167
|
-
let currentX = spectrum.firstX;
|
|
168
|
-
let currentY = spectrum.firstY;
|
|
169
|
-
|
|
170
|
-
// we skip the first line
|
|
171
|
-
//
|
|
172
|
-
let endLine = false;
|
|
173
|
-
let ascii;
|
|
174
|
-
let i = 0;
|
|
175
|
-
for (; i < value.length; i++) {
|
|
176
|
-
ascii = value.charCodeAt(i);
|
|
177
|
-
if (ascii === 13 || ascii === 10) {
|
|
178
|
-
endLine = true;
|
|
179
|
-
} else {
|
|
180
|
-
if (endLine) break;
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
// we proceed taking the i after the first line
|
|
185
|
-
let newLine = true;
|
|
186
|
-
let isDifference = false;
|
|
187
|
-
let isLastDifference = false;
|
|
188
|
-
let lastDifference = 0;
|
|
189
|
-
let isDuplicate = false;
|
|
190
|
-
let inComment = false;
|
|
191
|
-
let currentValue = 0; // can be a difference or a duplicate
|
|
192
|
-
let lastValue = 0; // must be the real last value
|
|
193
|
-
let isNegative = false;
|
|
194
|
-
let inValue = false;
|
|
195
|
-
let skipFirstValue = false;
|
|
196
|
-
let decimalPosition = 0;
|
|
197
|
-
for (; i <= value.length; i++) {
|
|
198
|
-
if (i === value.length) ascii = 13;
|
|
199
|
-
else ascii = value.charCodeAt(i);
|
|
200
|
-
if (inComment) {
|
|
201
|
-
// we should ignore the text if we are after $$
|
|
202
|
-
if (ascii === 13 || ascii === 10) {
|
|
203
|
-
newLine = true;
|
|
204
|
-
inComment = false;
|
|
205
|
-
}
|
|
206
|
-
} else {
|
|
207
|
-
// when is it a new value ?
|
|
208
|
-
// when it is not a digit, . or comma
|
|
209
|
-
// it is a number that is either new or we continue
|
|
210
|
-
if (ascii <= 57 && ascii >= 48) {
|
|
211
|
-
// a number
|
|
212
|
-
inValue = true;
|
|
213
|
-
if (decimalPosition > 0) {
|
|
214
|
-
currentValue += (ascii - 48) / Math.pow(10, decimalPosition++);
|
|
215
|
-
} else {
|
|
216
|
-
currentValue *= 10;
|
|
217
|
-
currentValue += ascii - 48;
|
|
218
|
-
}
|
|
219
|
-
} else if (ascii === 44 || ascii === 46) {
|
|
220
|
-
// a "," or "."
|
|
221
|
-
inValue = true;
|
|
222
|
-
decimalPosition++;
|
|
223
|
-
} else {
|
|
224
|
-
if (inValue) {
|
|
225
|
-
// need to process the previous value
|
|
226
|
-
if (newLine) {
|
|
227
|
-
newLine = false; // we don't check the X value
|
|
228
|
-
// console.log("NEW LINE",isDifference, lastDifference);
|
|
229
|
-
// if new line and lastDifference, the first value is just a check !
|
|
230
|
-
// that we don't check ...
|
|
231
|
-
if (isLastDifference) skipFirstValue = true;
|
|
232
|
-
} else {
|
|
233
|
-
// need to deal with duplicate and differences
|
|
234
|
-
if (skipFirstValue) {
|
|
235
|
-
skipFirstValue = false;
|
|
236
|
-
} else {
|
|
237
|
-
if (isDifference) {
|
|
238
|
-
lastDifference = isNegative ? 0 - currentValue : currentValue;
|
|
239
|
-
isLastDifference = true;
|
|
240
|
-
isDifference = false;
|
|
241
|
-
} else if (!isDuplicate) {
|
|
242
|
-
lastValue = isNegative ? 0 - currentValue : currentValue;
|
|
243
|
-
}
|
|
244
|
-
let duplicate = isDuplicate ? currentValue - 1 : 1;
|
|
245
|
-
for (let j = 0; j < duplicate; j++) {
|
|
246
|
-
if (isLastDifference) {
|
|
247
|
-
currentY += lastDifference;
|
|
248
|
-
} else {
|
|
249
|
-
currentY = lastValue;
|
|
250
|
-
}
|
|
251
|
-
currentData.x.push(currentX);
|
|
252
|
-
currentData.y.push(currentY * yFactor);
|
|
253
|
-
currentX += deltaX;
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
isNegative = false;
|
|
258
|
-
currentValue = 0;
|
|
259
|
-
decimalPosition = 0;
|
|
260
|
-
inValue = false;
|
|
261
|
-
isDuplicate = false;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
// positive SQZ digits @ A B C D E F G H I (ascii 64-73)
|
|
265
|
-
if (ascii < 74 && ascii > 63) {
|
|
266
|
-
inValue = true;
|
|
267
|
-
isLastDifference = false;
|
|
268
|
-
currentValue = ascii - 64;
|
|
269
|
-
} else if (ascii > 96 && ascii < 106) {
|
|
270
|
-
// negative SQZ digits a b c d e f g h i (ascii 97-105)
|
|
271
|
-
inValue = true;
|
|
272
|
-
isLastDifference = false;
|
|
273
|
-
currentValue = ascii - 96;
|
|
274
|
-
isNegative = true;
|
|
275
|
-
} else if (ascii === 115) {
|
|
276
|
-
// DUP digits S T U V W X Y Z s (ascii 83-90, 115)
|
|
277
|
-
inValue = true;
|
|
278
|
-
isDuplicate = true;
|
|
279
|
-
currentValue = 9;
|
|
280
|
-
} else if (ascii > 82 && ascii < 91) {
|
|
281
|
-
inValue = true;
|
|
282
|
-
isDuplicate = true;
|
|
283
|
-
currentValue = ascii - 82;
|
|
284
|
-
} else if (ascii > 73 && ascii < 83) {
|
|
285
|
-
// positive DIF digits % J K L M N O P Q R (ascii 37, 74-82)
|
|
286
|
-
inValue = true;
|
|
287
|
-
isDifference = true;
|
|
288
|
-
currentValue = ascii - 73;
|
|
289
|
-
} else if (ascii > 105 && ascii < 115) {
|
|
290
|
-
// negative DIF digits j k l m n o p q r (ascii 106-114)
|
|
291
|
-
inValue = true;
|
|
292
|
-
isDifference = true;
|
|
293
|
-
currentValue = ascii - 105;
|
|
294
|
-
isNegative = true;
|
|
295
|
-
} else if (ascii === 36 && value.charCodeAt(i + 1) === 36) {
|
|
296
|
-
// $ sign, we need to check the next one
|
|
297
|
-
inValue = true;
|
|
298
|
-
inComment = true;
|
|
299
|
-
} else if (ascii === 37) {
|
|
300
|
-
// positive DIF digits % J K L M N O P Q R (ascii 37, 74-82)
|
|
301
|
-
inValue = true;
|
|
302
|
-
isDifference = true;
|
|
303
|
-
currentValue = 0;
|
|
304
|
-
isNegative = false;
|
|
305
|
-
} else if (ascii === 45) {
|
|
306
|
-
// a "-"
|
|
307
|
-
// check if after there is a number, decimal or comma
|
|
308
|
-
let ascii2 = value.charCodeAt(i + 1);
|
|
309
|
-
if (
|
|
310
|
-
(ascii2 >= 48 && ascii2 <= 57) ||
|
|
311
|
-
ascii2 === 44 ||
|
|
312
|
-
ascii2 === 46
|
|
313
|
-
) {
|
|
314
|
-
inValue = true;
|
|
315
|
-
if (!newLine) isLastDifference = false;
|
|
316
|
-
isNegative = true;
|
|
317
|
-
}
|
|
318
|
-
} else if (ascii === 13 || ascii === 10) {
|
|
319
|
-
newLine = true;
|
|
320
|
-
inComment = false;
|
|
321
|
-
}
|
|
322
|
-
// and now analyse the details ... space or tabulation
|
|
323
|
-
// if "+" we just don't care
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
const removeCommentRegExp = /\$\$.*/;
|
|
330
|
-
const peakTableSplitRegExp = /[,\t ]+/;
|
|
331
|
-
|
|
332
|
-
function parsePeakTable(spectrum, value, result) {
|
|
333
|
-
spectrum.isPeaktable = true;
|
|
334
|
-
|
|
335
|
-
if (!spectrum.variables || Object.keys(spectrum.variables) === 2) {
|
|
336
|
-
parseXY(spectrum, value, result);
|
|
337
|
-
} else {
|
|
338
|
-
parseXYZ(spectrum, value, result);
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
// we will add the data in the variables
|
|
342
|
-
if (spectrum.variables) {
|
|
343
|
-
for (let key in spectrum.variables) {
|
|
344
|
-
spectrum.variables[key].data = spectrum.data[key];
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
function parseXY(spectrum, value, result) {
|
|
350
|
-
let currentData = { x: [], y: [] };
|
|
351
|
-
spectrum.data = currentData;
|
|
352
|
-
|
|
353
|
-
// counts for around 20% of the time
|
|
354
|
-
let lines = value.split(/,? *,?[;\r\n]+ */);
|
|
355
|
-
|
|
356
|
-
for (let i = 1; i < lines.length; i++) {
|
|
357
|
-
let values = lines[i]
|
|
358
|
-
.trim()
|
|
359
|
-
.replace(removeCommentRegExp, '')
|
|
360
|
-
.split(peakTableSplitRegExp);
|
|
361
|
-
if (values.length % 2 === 0) {
|
|
362
|
-
for (let j = 0; j < values.length; j = j + 2) {
|
|
363
|
-
// takes around 40% of the time to add and parse the 2 values nearly exclusively because of Number
|
|
364
|
-
currentData.x.push(Number(values[j]) * spectrum.xFactor);
|
|
365
|
-
currentData.y.push(Number(values[j + 1]) * spectrum.yFactor);
|
|
366
|
-
}
|
|
367
|
-
} else {
|
|
368
|
-
result.logs.push(`Format error: ${values}`);
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
function parseXYZ(spectrum, value, result) {
|
|
374
|
-
let currentData = {};
|
|
375
|
-
let variables = Object.keys(spectrum.variables);
|
|
376
|
-
let numberOfVariables = variables.length;
|
|
377
|
-
variables.forEach((variable) => (currentData[variable] = []));
|
|
378
|
-
spectrum.data = currentData;
|
|
379
|
-
|
|
380
|
-
// counts for around 20% of the time
|
|
381
|
-
let lines = value.split(/,? *,?[;\r\n]+ */);
|
|
382
|
-
|
|
383
|
-
for (let i = 1; i < lines.length; i++) {
|
|
384
|
-
let values = lines[i]
|
|
385
|
-
.trim()
|
|
386
|
-
.replace(removeCommentRegExp, '')
|
|
387
|
-
.split(peakTableSplitRegExp);
|
|
388
|
-
if (values.length % numberOfVariables === 0) {
|
|
389
|
-
for (let j = 0; j < values.length; j++) {
|
|
390
|
-
// todo should try to find a xFactor (y, ...)
|
|
391
|
-
currentData[variables[j % numberOfVariables]].push(Number(values[j]));
|
|
392
|
-
}
|
|
393
|
-
} else {
|
|
394
|
-
result.logs.push(`Format error: ${values}`);
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
function parseXYA(spectrum, value) {
|
|
400
|
-
let removeSymbolRegExp = /(\(+|\)+|<+|>+|\s+)/g;
|
|
401
|
-
|
|
402
|
-
spectrum.isXYAdata = true;
|
|
403
|
-
let values;
|
|
404
|
-
let currentData = { x: [], y: [] };
|
|
405
|
-
spectrum.data = currentData;
|
|
406
|
-
|
|
407
|
-
let lines = value.split(/,? *,?[;\r\n]+ */);
|
|
408
|
-
|
|
409
|
-
for (let i = 1; i < lines.length; i++) {
|
|
410
|
-
values = lines[i].trim().replace(removeSymbolRegExp, '').split(',');
|
|
411
|
-
currentData.x.push(Number(values[0]));
|
|
412
|
-
currentData.y.push(Number(values[1]));
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
function convertTo3DZ(spectra) {
|
|
417
|
-
let minZ = spectra[0].data.y[0];
|
|
418
|
-
let maxZ = minZ;
|
|
419
|
-
let ySize = spectra.length;
|
|
420
|
-
let xSize = spectra[0].data.x.length;
|
|
421
|
-
|
|
422
|
-
let z = new Array(ySize);
|
|
423
|
-
for (let i = 0; i < ySize; i++) {
|
|
424
|
-
z[i] = spectra[i].data.y;
|
|
425
|
-
for (let j = 0; j < xSize; j++) {
|
|
426
|
-
let value = z[i][j];
|
|
427
|
-
if (value < minZ) minZ = value;
|
|
428
|
-
if (value > maxZ) maxZ = value;
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
const firstX = spectra[0].data.x[0];
|
|
433
|
-
const lastX = spectra[0].data.x[spectra[0].data.x.length - 1]; // has to be -2 because it is a 1D array [x,y,x,y,...]
|
|
434
|
-
const firstY = spectra[0].pageValue;
|
|
435
|
-
const lastY = spectra[ySize - 1].pageValue;
|
|
436
|
-
|
|
437
|
-
// Because the min / max value are the only information about the matrix if we invert
|
|
438
|
-
// min and max we need to invert the array
|
|
439
|
-
if (firstX > lastX) {
|
|
440
|
-
for (let spectrum of z) {
|
|
441
|
-
spectrum.reverse();
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
if (firstY > lastY) {
|
|
445
|
-
z.reverse();
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
const medians = [];
|
|
449
|
-
for (let i = 0; i < z.length; i++) {
|
|
450
|
-
const row = Float64Array.from(z[i]);
|
|
451
|
-
for (let i = 0; i < row.length; i++) {
|
|
452
|
-
if (row[i] < 0) row[i] = -row[i];
|
|
453
|
-
}
|
|
454
|
-
medians.push(getMedian__default["default"](row));
|
|
455
|
-
}
|
|
456
|
-
const median = getMedian__default["default"](medians);
|
|
457
|
-
|
|
458
|
-
return {
|
|
459
|
-
z: z,
|
|
460
|
-
minX: Math.min(firstX, lastX),
|
|
461
|
-
maxX: Math.max(firstX, lastX),
|
|
462
|
-
minY: Math.min(firstY, lastY),
|
|
463
|
-
maxY: Math.max(firstY, lastY),
|
|
464
|
-
minZ: minZ,
|
|
465
|
-
maxZ: maxZ,
|
|
466
|
-
noise: median,
|
|
467
|
-
};
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
function generateContourLines(zData, options) {
|
|
471
|
-
let noise = zData.noise;
|
|
472
|
-
let z = zData.z;
|
|
473
|
-
let povarHeight0, povarHeight1, povarHeight2, povarHeight3;
|
|
474
|
-
let isOver0, isOver1, isOver2, isOver3;
|
|
475
|
-
let nbSubSpectra = z.length;
|
|
476
|
-
let nbPovars = z[0].length;
|
|
477
|
-
let pAx, pAy, pBx, pBy;
|
|
478
|
-
|
|
479
|
-
let x0 = zData.minX;
|
|
480
|
-
let xN = zData.maxX;
|
|
481
|
-
let dx = (xN - x0) / (nbPovars - 1);
|
|
482
|
-
let y0 = zData.minY;
|
|
483
|
-
let yN = zData.maxY;
|
|
484
|
-
let dy = (yN - y0) / (nbSubSpectra - 1);
|
|
485
|
-
let minZ = zData.minZ;
|
|
486
|
-
let maxZ = zData.maxZ;
|
|
487
|
-
|
|
488
|
-
// System.out.prvarln('y0 '+y0+' yN '+yN);
|
|
489
|
-
// -------------------------
|
|
490
|
-
// Povars attribution
|
|
491
|
-
//
|
|
492
|
-
// 0----1
|
|
493
|
-
// | / |
|
|
494
|
-
// | / |
|
|
495
|
-
// 2----3
|
|
496
|
-
//
|
|
497
|
-
// ---------------------d------
|
|
498
|
-
|
|
499
|
-
let iter = options.nbContourLevels * 2;
|
|
500
|
-
let contourLevels = new Array(iter);
|
|
501
|
-
let lineZValue;
|
|
502
|
-
for (let level = 0; level < iter; level++) {
|
|
503
|
-
// multiply by 2 for positif and negatif
|
|
504
|
-
let contourLevel = {};
|
|
505
|
-
contourLevels[level] = contourLevel;
|
|
506
|
-
let side = level % 2;
|
|
507
|
-
let factor =
|
|
508
|
-
(maxZ - options.noiseMultiplier * noise) *
|
|
509
|
-
Math.exp((level >> 1) - options.nbContourLevels);
|
|
510
|
-
if (side === 0) {
|
|
511
|
-
lineZValue = factor + options.noiseMultiplier * noise;
|
|
512
|
-
} else {
|
|
513
|
-
lineZValue = 0 - factor - options.noiseMultiplier * noise;
|
|
514
|
-
}
|
|
515
|
-
let lines = [];
|
|
516
|
-
contourLevel.zValue = lineZValue;
|
|
517
|
-
contourLevel.lines = lines;
|
|
518
|
-
|
|
519
|
-
if (lineZValue <= minZ || lineZValue >= maxZ) continue;
|
|
520
|
-
|
|
521
|
-
for (let iSubSpectra = 0; iSubSpectra < nbSubSpectra - 1; iSubSpectra++) {
|
|
522
|
-
let subSpectra = z[iSubSpectra];
|
|
523
|
-
let subSpectraAfter = z[iSubSpectra + 1];
|
|
524
|
-
for (let povar = 0; povar < nbPovars - 1; povar++) {
|
|
525
|
-
povarHeight0 = subSpectra[povar];
|
|
526
|
-
povarHeight1 = subSpectra[povar + 1];
|
|
527
|
-
povarHeight2 = subSpectraAfter[povar];
|
|
528
|
-
povarHeight3 = subSpectraAfter[povar + 1];
|
|
529
|
-
|
|
530
|
-
isOver0 = povarHeight0 > lineZValue;
|
|
531
|
-
isOver1 = povarHeight1 > lineZValue;
|
|
532
|
-
isOver2 = povarHeight2 > lineZValue;
|
|
533
|
-
isOver3 = povarHeight3 > lineZValue;
|
|
534
|
-
|
|
535
|
-
// Example povar0 is over the plane and povar1 and
|
|
536
|
-
// povar2 are below, we find the varersections and add
|
|
537
|
-
// the segment
|
|
538
|
-
if (isOver0 !== isOver1 && isOver0 !== isOver2) {
|
|
539
|
-
pAx =
|
|
540
|
-
povar + (lineZValue - povarHeight0) / (povarHeight1 - povarHeight0);
|
|
541
|
-
pAy = iSubSpectra;
|
|
542
|
-
pBx = povar;
|
|
543
|
-
pBy =
|
|
544
|
-
iSubSpectra +
|
|
545
|
-
(lineZValue - povarHeight0) / (povarHeight2 - povarHeight0);
|
|
546
|
-
lines.push(pAx * dx + x0);
|
|
547
|
-
lines.push(pAy * dy + y0);
|
|
548
|
-
lines.push(pBx * dx + x0);
|
|
549
|
-
lines.push(pBy * dy + y0);
|
|
550
|
-
}
|
|
551
|
-
// remove push does not help !!!!
|
|
552
|
-
if (isOver3 !== isOver1 && isOver3 !== isOver2) {
|
|
553
|
-
pAx = povar + 1;
|
|
554
|
-
pAy =
|
|
555
|
-
iSubSpectra +
|
|
556
|
-
1 -
|
|
557
|
-
(lineZValue - povarHeight3) / (povarHeight1 - povarHeight3);
|
|
558
|
-
pBx =
|
|
559
|
-
povar +
|
|
560
|
-
1 -
|
|
561
|
-
(lineZValue - povarHeight3) / (povarHeight2 - povarHeight3);
|
|
562
|
-
pBy = iSubSpectra + 1;
|
|
563
|
-
lines.push(pAx * dx + x0);
|
|
564
|
-
lines.push(pAy * dy + y0);
|
|
565
|
-
lines.push(pBx * dx + x0);
|
|
566
|
-
lines.push(pBy * dy + y0);
|
|
567
|
-
}
|
|
568
|
-
// test around the diagonal
|
|
569
|
-
if (isOver1 !== isOver2) {
|
|
570
|
-
pAx =
|
|
571
|
-
(povar +
|
|
572
|
-
1 -
|
|
573
|
-
(lineZValue - povarHeight1) / (povarHeight2 - povarHeight1)) *
|
|
574
|
-
dx +
|
|
575
|
-
x0;
|
|
576
|
-
pAy =
|
|
577
|
-
(iSubSpectra +
|
|
578
|
-
(lineZValue - povarHeight1) / (povarHeight2 - povarHeight1)) *
|
|
579
|
-
dy +
|
|
580
|
-
y0;
|
|
581
|
-
if (isOver1 !== isOver0) {
|
|
582
|
-
pBx =
|
|
583
|
-
povar +
|
|
584
|
-
1 -
|
|
585
|
-
(lineZValue - povarHeight1) / (povarHeight0 - povarHeight1);
|
|
586
|
-
pBy = iSubSpectra;
|
|
587
|
-
lines.push(pAx);
|
|
588
|
-
lines.push(pAy);
|
|
589
|
-
lines.push(pBx * dx + x0);
|
|
590
|
-
lines.push(pBy * dy + y0);
|
|
591
|
-
}
|
|
592
|
-
if (isOver2 !== isOver0) {
|
|
593
|
-
pBx = povar;
|
|
594
|
-
pBy =
|
|
595
|
-
iSubSpectra +
|
|
596
|
-
1 -
|
|
597
|
-
(lineZValue - povarHeight2) / (povarHeight0 - povarHeight2);
|
|
598
|
-
lines.push(pAx);
|
|
599
|
-
lines.push(pAy);
|
|
600
|
-
lines.push(pBx * dx + x0);
|
|
601
|
-
lines.push(pBy * dy + y0);
|
|
602
|
-
}
|
|
603
|
-
if (isOver1 !== isOver3) {
|
|
604
|
-
pBx = povar + 1;
|
|
605
|
-
pBy =
|
|
606
|
-
iSubSpectra +
|
|
607
|
-
(lineZValue - povarHeight1) / (povarHeight3 - povarHeight1);
|
|
608
|
-
lines.push(pAx);
|
|
609
|
-
lines.push(pAy);
|
|
610
|
-
lines.push(pBx * dx + x0);
|
|
611
|
-
lines.push(pBy * dy + y0);
|
|
612
|
-
}
|
|
613
|
-
if (isOver2 !== isOver3) {
|
|
614
|
-
pBx =
|
|
615
|
-
povar +
|
|
616
|
-
(lineZValue - povarHeight2) / (povarHeight3 - povarHeight2);
|
|
617
|
-
pBy = iSubSpectra + 1;
|
|
618
|
-
lines.push(pAx);
|
|
619
|
-
lines.push(pAy);
|
|
620
|
-
lines.push(pBx * dx + x0);
|
|
621
|
-
lines.push(pBy * dy + y0);
|
|
622
|
-
}
|
|
623
|
-
}
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
return {
|
|
629
|
-
minX: zData.minX,
|
|
630
|
-
maxX: zData.maxX,
|
|
631
|
-
minY: zData.minY,
|
|
632
|
-
maxY: zData.maxY,
|
|
633
|
-
segments: contourLevels,
|
|
634
|
-
};
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
function add2D(result, options) {
|
|
638
|
-
let zData = convertTo3DZ(result.spectra);
|
|
639
|
-
if (!options.noContour) {
|
|
640
|
-
result.contourLines = generateContourLines(zData, options);
|
|
641
|
-
delete zData.z;
|
|
642
|
-
}
|
|
643
|
-
result.minMax = zData;
|
|
644
|
-
}
|
|
645
|
-
|
|
646
|
-
function postProcessingNMR(entriesFlat) {
|
|
647
|
-
// specific NMR functions
|
|
648
|
-
|
|
649
|
-
for (let entry of entriesFlat) {
|
|
650
|
-
let observeFrequency = 0;
|
|
651
|
-
let shiftOffsetVal = 0;
|
|
652
|
-
for (let spectrum of entry.spectra) {
|
|
653
|
-
if (entry.ntuples && entry.ntuples.symbol) {
|
|
654
|
-
if (!observeFrequency && spectrum.observeFrequency) {
|
|
655
|
-
observeFrequency = spectrum.observeFrequency;
|
|
656
|
-
}
|
|
657
|
-
if (!shiftOffsetVal && spectrum.shiftOffsetVal) {
|
|
658
|
-
shiftOffsetVal = spectrum.shiftOffsetVal;
|
|
659
|
-
}
|
|
660
|
-
} else {
|
|
661
|
-
observeFrequency = spectrum.observeFrequency;
|
|
662
|
-
shiftOffsetVal = spectrum.shiftOffsetVal;
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
if (observeFrequency) {
|
|
666
|
-
if (spectrum.xUnits && spectrum.xUnits.toUpperCase().includes('HZ')) {
|
|
667
|
-
spectrum.xUnits = 'PPM';
|
|
668
|
-
spectrum.xFactor = spectrum.xFactor / observeFrequency;
|
|
669
|
-
spectrum.firstX = spectrum.firstX / observeFrequency;
|
|
670
|
-
spectrum.lastX = spectrum.lastX / observeFrequency;
|
|
671
|
-
spectrum.deltaX = spectrum.deltaX / observeFrequency;
|
|
672
|
-
for (let i = 0; i < spectrum.data.x.length; i++) {
|
|
673
|
-
spectrum.data.x[i] /= observeFrequency;
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
}
|
|
677
|
-
if (shiftOffsetVal) {
|
|
678
|
-
let shift = spectrum.firstX - shiftOffsetVal;
|
|
679
|
-
spectrum.firstX = spectrum.firstX - shift;
|
|
680
|
-
spectrum.lastX = spectrum.lastX - shift;
|
|
681
|
-
for (let i = 0; i < spectrum.data.x.length; i++) {
|
|
682
|
-
spectrum.data.x[i] -= shift;
|
|
683
|
-
}
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
// we will check if some nucleus are missing ...
|
|
687
|
-
if (entry.ntuples && entry.ntuples.nucleus && entry.ntuples.symbol) {
|
|
688
|
-
for (let i = 0; i < entry.ntuples.nucleus.length; i++) {
|
|
689
|
-
let symbol = entry.ntuples.symbol[i];
|
|
690
|
-
let nucleus = entry.ntuples.nucleus[i];
|
|
691
|
-
if (symbol.startsWith('F') && !nucleus) {
|
|
692
|
-
if (symbol === 'F1') {
|
|
693
|
-
// if F1 is defined we will use F2
|
|
694
|
-
if (entry.tmp.$NUC2) {
|
|
695
|
-
entry.ntuples.nucleus[i] = entry.tmp.$NUC2;
|
|
696
|
-
} else {
|
|
697
|
-
let f2index = entry.ntuples.symbol.indexOf('F2');
|
|
698
|
-
if (f2index && entry.ntuples.nucleus[f2index]) {
|
|
699
|
-
entry.ntuples.nucleus[i] = entry.ntuples.nucleus[f2index];
|
|
700
|
-
}
|
|
701
|
-
}
|
|
702
|
-
}
|
|
703
|
-
if (symbol === 'F2') entry.ntuples.nucleus[i] = entry.tmp.$NUC1;
|
|
704
|
-
}
|
|
705
|
-
if (symbol === 'F2') {
|
|
706
|
-
entry.yType = entry.ntuples.nucleus[0];
|
|
707
|
-
}
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
|
|
711
|
-
if (
|
|
712
|
-
observeFrequency &&
|
|
713
|
-
entry.ntuples &&
|
|
714
|
-
entry.ntuples.symbol &&
|
|
715
|
-
entry.ntuples.nucleus
|
|
716
|
-
) {
|
|
717
|
-
let unit = '';
|
|
718
|
-
let pageSymbolIndex = entry.ntuples.symbol.indexOf(spectrum.pageSymbol);
|
|
719
|
-
if (entry.ntuples.units && entry.ntuples.units[pageSymbolIndex]) {
|
|
720
|
-
unit = entry.ntuples.units[pageSymbolIndex];
|
|
721
|
-
}
|
|
722
|
-
if (unit !== 'PPM') {
|
|
723
|
-
if (pageSymbolIndex !== 0) {
|
|
724
|
-
throw Error('Not sure about this ntuples format');
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
let ratio0 = nmrProcessing.gyromagneticRatio[entry.ntuples.nucleus[0]];
|
|
728
|
-
let ratio1 = nmrProcessing.gyromagneticRatio[entry.ntuples.nucleus[1]];
|
|
729
|
-
if (!ratio0 || !ratio1) {
|
|
730
|
-
throw Error('Problem with determination of gyromagnetic ratio');
|
|
731
|
-
}
|
|
732
|
-
let ratio = (ratio0 / ratio1) * observeFrequency;
|
|
733
|
-
spectrum.pageValue /= ratio;
|
|
734
|
-
}
|
|
735
|
-
}
|
|
736
|
-
}
|
|
737
|
-
}
|
|
738
|
-
}
|
|
739
|
-
|
|
740
|
-
function profiling(result, action, options) {
|
|
741
|
-
if (result.profiling) {
|
|
742
|
-
result.profiling.push({
|
|
743
|
-
action,
|
|
744
|
-
time: Date.now() - options.start,
|
|
745
|
-
});
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
function simpleChromatogram(result) {
|
|
750
|
-
let data = result.spectra[0].data;
|
|
751
|
-
result.chromatogram = {
|
|
752
|
-
times: data.x.slice(),
|
|
753
|
-
series: {
|
|
754
|
-
intensity: {
|
|
755
|
-
dimension: 1,
|
|
756
|
-
data: data.y.slice(),
|
|
757
|
-
},
|
|
758
|
-
},
|
|
759
|
-
};
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
function postProcessing(entriesFlat, result, options) {
|
|
763
|
-
// converting Hz to ppm
|
|
764
|
-
postProcessingNMR(entriesFlat);
|
|
765
|
-
|
|
766
|
-
for (let entry of entriesFlat) {
|
|
767
|
-
if (Object.keys(entry.ntuples).length > 0) {
|
|
768
|
-
let newNtuples = [];
|
|
769
|
-
let keys = Object.keys(entry.ntuples);
|
|
770
|
-
for (let i = 0; i < keys.length; i++) {
|
|
771
|
-
let key = keys[i];
|
|
772
|
-
let values = entry.ntuples[key];
|
|
773
|
-
for (let j = 0; j < values.length; j++) {
|
|
774
|
-
if (!newNtuples[j]) newNtuples[j] = {};
|
|
775
|
-
newNtuples[j][key] = values[j];
|
|
776
|
-
}
|
|
777
|
-
}
|
|
778
|
-
entry.ntuples = newNtuples;
|
|
779
|
-
}
|
|
780
|
-
|
|
781
|
-
if (entry.twoD && options.wantXY) {
|
|
782
|
-
add2D(entry, options);
|
|
783
|
-
|
|
784
|
-
profiling(result, 'Finished countour plot calculation', options);
|
|
785
|
-
|
|
786
|
-
if (!options.keepSpectra) {
|
|
787
|
-
delete entry.spectra;
|
|
788
|
-
}
|
|
789
|
-
}
|
|
790
|
-
|
|
791
|
-
// maybe it is a GC (HPLC) / MS. In this case we add a new format
|
|
792
|
-
if (options.chromatogram) {
|
|
793
|
-
if (entry.spectra.length > 1) {
|
|
794
|
-
complexChromatogram(entry);
|
|
795
|
-
} else {
|
|
796
|
-
simpleChromatogram(entry);
|
|
797
|
-
}
|
|
798
|
-
profiling(result, 'Finished chromatogram calculation', options);
|
|
799
|
-
}
|
|
800
|
-
|
|
801
|
-
delete entry.tmp;
|
|
802
|
-
}
|
|
803
|
-
}
|
|
804
|
-
|
|
805
|
-
function prepareNtuplesDatatable(currentEntry, spectrum, kind) {
|
|
806
|
-
let xIndex = -1;
|
|
807
|
-
let yIndex = -1;
|
|
808
|
-
let firstVariable = '';
|
|
809
|
-
let secondVariable = '';
|
|
810
|
-
if (kind.indexOf('++') > 0) {
|
|
811
|
-
firstVariable = kind.replace(/.*\(([a-zA-Z0-9]+)\+\+.*/, '$1');
|
|
812
|
-
secondVariable = kind.replace(/.*\.\.([a-zA-Z0-9]+).*/, '$1');
|
|
813
|
-
} else {
|
|
814
|
-
kind = kind.replace(/[^a-zA-Z]/g, '');
|
|
815
|
-
firstVariable = kind.charAt(0);
|
|
816
|
-
secondVariable = kind.charAt(1);
|
|
817
|
-
spectrum.variables = {};
|
|
818
|
-
for (let symbol of kind) {
|
|
819
|
-
let lowerCaseSymbol = symbol.toLowerCase();
|
|
820
|
-
let index = currentEntry.ntuples.symbol.indexOf(symbol);
|
|
821
|
-
if (index === -1) throw Error(`Symbol undefined: ${symbol}`);
|
|
822
|
-
spectrum.variables[lowerCaseSymbol] = {};
|
|
823
|
-
for (let key in currentEntry.ntuples) {
|
|
824
|
-
if (currentEntry.ntuples[key][index]) {
|
|
825
|
-
spectrum.variables[lowerCaseSymbol][key.replace(/^var/, '')] =
|
|
826
|
-
currentEntry.ntuples[key][index];
|
|
827
|
-
}
|
|
828
|
-
}
|
|
829
|
-
}
|
|
830
|
-
}
|
|
831
|
-
xIndex = currentEntry.ntuples.symbol.indexOf(firstVariable);
|
|
832
|
-
yIndex = currentEntry.ntuples.symbol.indexOf(secondVariable);
|
|
833
|
-
|
|
834
|
-
if (xIndex === -1) xIndex = 0;
|
|
835
|
-
if (yIndex === -1) yIndex = 0;
|
|
836
|
-
|
|
837
|
-
if (currentEntry.ntuples.first) {
|
|
838
|
-
if (currentEntry.ntuples.first.length > xIndex) {
|
|
839
|
-
spectrum.firstX = currentEntry.ntuples.first[xIndex];
|
|
840
|
-
}
|
|
841
|
-
if (currentEntry.ntuples.first.length > yIndex) {
|
|
842
|
-
spectrum.firstY = currentEntry.ntuples.first[yIndex];
|
|
843
|
-
}
|
|
844
|
-
}
|
|
845
|
-
if (currentEntry.ntuples.last) {
|
|
846
|
-
if (currentEntry.ntuples.last.length > xIndex) {
|
|
847
|
-
spectrum.lastX = currentEntry.ntuples.last[xIndex];
|
|
848
|
-
}
|
|
849
|
-
if (currentEntry.ntuples.last.length > yIndex) {
|
|
850
|
-
spectrum.lastY = currentEntry.ntuples.last[yIndex];
|
|
851
|
-
}
|
|
852
|
-
}
|
|
853
|
-
if (
|
|
854
|
-
currentEntry.ntuples.vardim &&
|
|
855
|
-
currentEntry.ntuples.vardim.length > xIndex
|
|
856
|
-
) {
|
|
857
|
-
spectrum.nbPoints = currentEntry.ntuples.vardim[xIndex];
|
|
858
|
-
}
|
|
859
|
-
if (currentEntry.ntuples.factor) {
|
|
860
|
-
if (currentEntry.ntuples.factor.length > xIndex) {
|
|
861
|
-
spectrum.xFactor = currentEntry.ntuples.factor[xIndex];
|
|
862
|
-
}
|
|
863
|
-
if (currentEntry.ntuples.factor.length > yIndex) {
|
|
864
|
-
spectrum.yFactor = currentEntry.ntuples.factor[yIndex];
|
|
865
|
-
}
|
|
866
|
-
}
|
|
867
|
-
if (currentEntry.ntuples.units) {
|
|
868
|
-
if (currentEntry.ntuples.units.length > xIndex) {
|
|
869
|
-
if (
|
|
870
|
-
currentEntry.ntuples.varname &&
|
|
871
|
-
currentEntry.ntuples.varname[xIndex]
|
|
872
|
-
) {
|
|
873
|
-
spectrum.xUnits = `${currentEntry.ntuples.varname[xIndex]} [${currentEntry.ntuples.units[xIndex]}]`;
|
|
874
|
-
} else {
|
|
875
|
-
spectrum.xUnits = currentEntry.ntuples.units[xIndex];
|
|
876
|
-
}
|
|
877
|
-
}
|
|
878
|
-
if (currentEntry.ntuples.units.length > yIndex) {
|
|
879
|
-
if (
|
|
880
|
-
currentEntry.ntuples.varname &&
|
|
881
|
-
currentEntry.ntuples.varname[yIndex]
|
|
882
|
-
) {
|
|
883
|
-
spectrum.yUnits = `${currentEntry.ntuples.varname[yIndex]} [${currentEntry.ntuples.units[yIndex]}]`;
|
|
884
|
-
} else {
|
|
885
|
-
spectrum.yUnits = currentEntry.ntuples.units[yIndex];
|
|
886
|
-
}
|
|
887
|
-
}
|
|
888
|
-
}
|
|
889
|
-
}
|
|
890
|
-
|
|
891
|
-
function prepareSpectrum(spectrum) {
|
|
892
|
-
if (!spectrum.xFactor) spectrum.xFactor = 1;
|
|
893
|
-
if (!spectrum.yFactor) spectrum.yFactor = 1;
|
|
894
|
-
}
|
|
895
|
-
|
|
896
|
-
// the following RegExp can only be used for XYdata, some peakTables have values with a "E-5" ...
|
|
897
|
-
const ntuplesSeparatorRegExp = /[ \t]*,[ \t]*/;
|
|
898
|
-
|
|
899
|
-
class Spectrum {}
|
|
900
|
-
|
|
901
|
-
const defaultOptions = {
|
|
902
|
-
keepRecordsRegExp: /^$/,
|
|
903
|
-
canonicDataLabels: true,
|
|
904
|
-
canonicMetadataLabels: false,
|
|
905
|
-
dynamicTyping: true,
|
|
906
|
-
withoutXY: false,
|
|
907
|
-
chromatogram: false,
|
|
908
|
-
keepSpectra: false,
|
|
909
|
-
noContour: false,
|
|
910
|
-
nbContourLevels: 7,
|
|
911
|
-
noiseMultiplier: 5,
|
|
912
|
-
profiling: false,
|
|
913
|
-
};
|
|
914
|
-
|
|
915
|
-
/**
|
|
916
|
-
* Parse a jcamp.
|
|
917
|
-
*
|
|
918
|
-
* @param {string|ArrayBuffer|Uint8Array} jcamp
|
|
919
|
-
* @param {object} [options]
|
|
920
|
-
* @param {number} [options.keepRecordsRegExp=/^$/] - By default we don't keep meta information.
|
|
921
|
-
* @param {number} [options.canonicDataLabels=true] - Canonize the Labels (uppercase without symbol).
|
|
922
|
-
* @param {number} [options.canonicMetadataLabels=false] - Canonize the metadata Labels (uppercase without symbol).
|
|
923
|
-
* @param {number} [options.dynamicTyping=false] - Convert numbers to Number.
|
|
924
|
-
* @param {number} [options.withoutXY=false] - Remove the XY data.
|
|
925
|
-
* @param {number} [options.chromatogram=false] - Special post-processing for GC / HPLC / MS.
|
|
926
|
-
* @param {number} [options.keepSpectra=false] - Force to keep the spectra in case of 2D.
|
|
927
|
-
* @param {number} [options.noContour=false] - Don't calculate countour in case of 2D.
|
|
928
|
-
* @param {number} [options.nbContourLevels=7] - Number of positive / negative contour levels to calculate.
|
|
929
|
-
* @param {number} [options.noiseMultiplier=5] - Define for 2D the level as 5 times the median as default.
|
|
930
|
-
* @param {number} [options.profiling=false] - Add profiling information.
|
|
931
|
-
* @returns {object}
|
|
932
|
-
*/
|
|
933
|
-
|
|
934
|
-
function convert(jcamp, options = {}) {
|
|
935
|
-
jcamp = ensureString.ensureString(jcamp);
|
|
936
|
-
options = { ...defaultOptions, ...options };
|
|
937
|
-
options.wantXY = !options.withoutXY;
|
|
938
|
-
options.start = Date.now();
|
|
939
|
-
|
|
940
|
-
let entriesFlat = [];
|
|
941
|
-
|
|
942
|
-
let result = {
|
|
943
|
-
profiling: options.profiling ? [] : false,
|
|
944
|
-
logs: [],
|
|
945
|
-
entries: [],
|
|
946
|
-
};
|
|
947
|
-
|
|
948
|
-
let tmpResult = { children: [] };
|
|
949
|
-
let currentEntry = tmpResult;
|
|
950
|
-
let parentsStack = [];
|
|
951
|
-
|
|
952
|
-
let spectrum = new Spectrum();
|
|
953
|
-
|
|
954
|
-
if (typeof jcamp !== 'string') {
|
|
955
|
-
throw new TypeError('the JCAMP should be a string');
|
|
956
|
-
}
|
|
957
|
-
|
|
958
|
-
profiling(result, 'Before split to LDRS', options);
|
|
959
|
-
|
|
960
|
-
let ldrs = jcamp.replace(/[\r\n]+##/g, '\n##').split('\n##');
|
|
961
|
-
|
|
962
|
-
profiling(result, 'Split to LDRS', options);
|
|
963
|
-
|
|
964
|
-
if (ldrs[0]) ldrs[0] = ldrs[0].replace(/^[\r\n ]*##/, '');
|
|
965
|
-
|
|
966
|
-
for (let ldr of ldrs) {
|
|
967
|
-
// This is a new LDR
|
|
968
|
-
let position = ldr.indexOf('=');
|
|
969
|
-
let dataLabel = position > 0 ? ldr.substring(0, position) : ldr;
|
|
970
|
-
let dataValue = position > 0 ? ldr.substring(position + 1).trim() : '';
|
|
971
|
-
|
|
972
|
-
let canonicDataLabel = dataLabel.replace(/[_ -]/g, '').toUpperCase();
|
|
973
|
-
|
|
974
|
-
if (canonicDataLabel === 'DATATABLE') {
|
|
975
|
-
let endLine = dataValue.indexOf('\n');
|
|
976
|
-
if (endLine === -1) endLine = dataValue.indexOf('\r');
|
|
977
|
-
if (endLine > 0) {
|
|
978
|
-
// ##DATA TABLE= (X++(I..I)), XYDATA
|
|
979
|
-
// We need to find the variables
|
|
980
|
-
|
|
981
|
-
let infos = dataValue.substring(0, endLine).split(/[ ,;\t]+/);
|
|
982
|
-
prepareNtuplesDatatable(currentEntry, spectrum, infos[0]);
|
|
983
|
-
|
|
984
|
-
spectrum.datatable = infos[0];
|
|
985
|
-
if (infos[1] && infos[1].indexOf('PEAKS') > -1) {
|
|
986
|
-
canonicDataLabel = 'PEAKTABLE';
|
|
987
|
-
} else if (
|
|
988
|
-
infos[1] &&
|
|
989
|
-
(infos[1].indexOf('XYDATA') || infos[0].indexOf('++') > 0)
|
|
990
|
-
) {
|
|
991
|
-
canonicDataLabel = 'XYDATA';
|
|
992
|
-
spectrum.deltaX =
|
|
993
|
-
(spectrum.lastX - spectrum.firstX) / (spectrum.nbPoints - 1);
|
|
994
|
-
}
|
|
995
|
-
}
|
|
996
|
-
}
|
|
997
|
-
|
|
998
|
-
if (canonicDataLabel === 'XYDATA') {
|
|
999
|
-
if (options.wantXY) {
|
|
1000
|
-
prepareSpectrum(spectrum);
|
|
1001
|
-
// well apparently we should still consider it is a PEAK TABLE if there are no '++' after
|
|
1002
|
-
if (dataValue.match(/.*\+\+.*/)) {
|
|
1003
|
-
// ex: (X++(Y..Y))
|
|
1004
|
-
spectrum.deltaX =
|
|
1005
|
-
(spectrum.lastX - spectrum.firstX) / (spectrum.nbPoints - 1);
|
|
1006
|
-
|
|
1007
|
-
fastParseXYData(spectrum, dataValue);
|
|
1008
|
-
} else {
|
|
1009
|
-
parsePeakTable(spectrum, dataValue, result);
|
|
1010
|
-
}
|
|
1011
|
-
currentEntry.spectra.push(spectrum);
|
|
1012
|
-
spectrum = new Spectrum();
|
|
1013
|
-
}
|
|
1014
|
-
continue;
|
|
1015
|
-
} else if (canonicDataLabel === 'PEAKTABLE') {
|
|
1016
|
-
if (options.wantXY) {
|
|
1017
|
-
prepareSpectrum(spectrum);
|
|
1018
|
-
parsePeakTable(spectrum, dataValue, result);
|
|
1019
|
-
currentEntry.spectra.push(spectrum);
|
|
1020
|
-
spectrum = new Spectrum();
|
|
1021
|
-
}
|
|
1022
|
-
continue;
|
|
1023
|
-
}
|
|
1024
|
-
if (canonicDataLabel === 'PEAKASSIGNMENTS') {
|
|
1025
|
-
if (options.wantXY) {
|
|
1026
|
-
if (dataValue.match(/.*(XYA).*/)) {
|
|
1027
|
-
// ex: (XYA)
|
|
1028
|
-
parseXYA(spectrum, dataValue);
|
|
1029
|
-
}
|
|
1030
|
-
currentEntry.spectra.push(spectrum);
|
|
1031
|
-
spectrum = new Spectrum();
|
|
1032
|
-
}
|
|
1033
|
-
continue;
|
|
1034
|
-
}
|
|
1035
|
-
|
|
1036
|
-
if (canonicDataLabel === 'TITLE') {
|
|
1037
|
-
let parentEntry = currentEntry;
|
|
1038
|
-
if (!parentEntry.children) {
|
|
1039
|
-
parentEntry.children = [];
|
|
1040
|
-
}
|
|
1041
|
-
currentEntry = {
|
|
1042
|
-
spectra: [],
|
|
1043
|
-
ntuples: {},
|
|
1044
|
-
info: {},
|
|
1045
|
-
meta: {},
|
|
1046
|
-
tmp: {}, // tmp information we need to keep for postprocessing
|
|
1047
|
-
};
|
|
1048
|
-
parentEntry.children.push(currentEntry);
|
|
1049
|
-
parentsStack.push(parentEntry);
|
|
1050
|
-
entriesFlat.push(currentEntry);
|
|
1051
|
-
currentEntry.title = dataValue;
|
|
1052
|
-
} else if (canonicDataLabel === 'DATATYPE') {
|
|
1053
|
-
currentEntry.dataType = dataValue;
|
|
1054
|
-
if (dataValue.match(/(^nd|\snd\s)/i)) {
|
|
1055
|
-
currentEntry.twoD = true;
|
|
1056
|
-
}
|
|
1057
|
-
} else if (canonicDataLabel === 'NTUPLES') {
|
|
1058
|
-
if (dataValue.match(/(^nd|\snd\s)/i)) {
|
|
1059
|
-
currentEntry.twoD = true;
|
|
1060
|
-
}
|
|
1061
|
-
} else if (canonicDataLabel === 'DATACLASS') {
|
|
1062
|
-
currentEntry.dataClass = dataValue;
|
|
1063
|
-
} else if (canonicDataLabel === 'XUNITS') {
|
|
1064
|
-
spectrum.xUnits = dataValue;
|
|
1065
|
-
} else if (canonicDataLabel === 'YUNITS') {
|
|
1066
|
-
spectrum.yUnits = dataValue;
|
|
1067
|
-
} else if (canonicDataLabel === 'FIRSTX') {
|
|
1068
|
-
spectrum.firstX = Number(dataValue);
|
|
1069
|
-
} else if (canonicDataLabel === 'LASTX') {
|
|
1070
|
-
spectrum.lastX = Number(dataValue);
|
|
1071
|
-
} else if (canonicDataLabel === 'FIRSTY') {
|
|
1072
|
-
spectrum.firstY = Number(dataValue);
|
|
1073
|
-
} else if (canonicDataLabel === 'LASTY') {
|
|
1074
|
-
spectrum.lastY = Number(dataValue);
|
|
1075
|
-
} else if (canonicDataLabel === 'NPOINTS') {
|
|
1076
|
-
spectrum.nbPoints = Number(dataValue);
|
|
1077
|
-
} else if (canonicDataLabel === 'XFACTOR') {
|
|
1078
|
-
spectrum.xFactor = Number(dataValue);
|
|
1079
|
-
} else if (canonicDataLabel === 'YFACTOR') {
|
|
1080
|
-
spectrum.yFactor = Number(dataValue);
|
|
1081
|
-
} else if (canonicDataLabel === 'MAXX') {
|
|
1082
|
-
spectrum.maxX = Number(dataValue);
|
|
1083
|
-
} else if (canonicDataLabel === 'MINX') {
|
|
1084
|
-
spectrum.minX = Number(dataValue);
|
|
1085
|
-
} else if (canonicDataLabel === 'MAXY') {
|
|
1086
|
-
spectrum.maxY = Number(dataValue);
|
|
1087
|
-
} else if (canonicDataLabel === 'MINY') {
|
|
1088
|
-
spectrum.minY = Number(dataValue);
|
|
1089
|
-
} else if (canonicDataLabel === 'DELTAX') {
|
|
1090
|
-
spectrum.deltaX = Number(dataValue);
|
|
1091
|
-
} else if (
|
|
1092
|
-
canonicDataLabel === '.OBSERVEFREQUENCY' ||
|
|
1093
|
-
canonicDataLabel === '$SFO1'
|
|
1094
|
-
) {
|
|
1095
|
-
if (!spectrum.observeFrequency) {
|
|
1096
|
-
spectrum.observeFrequency = Number(dataValue);
|
|
1097
|
-
}
|
|
1098
|
-
} else if (canonicDataLabel === '.OBSERVENUCLEUS') {
|
|
1099
|
-
if (!spectrum.xType) {
|
|
1100
|
-
currentEntry.xType = dataValue.replace(/[^a-zA-Z0-9]/g, '');
|
|
1101
|
-
}
|
|
1102
|
-
} else if (canonicDataLabel === '$OFFSET') {
|
|
1103
|
-
// OFFSET for Bruker spectra
|
|
1104
|
-
currentEntry.shiftOffsetNum = 0;
|
|
1105
|
-
if (!spectrum.shiftOffsetVal) {
|
|
1106
|
-
spectrum.shiftOffsetVal = Number(dataValue);
|
|
1107
|
-
}
|
|
1108
|
-
} else if (canonicDataLabel === '$REFERENCEPOINT') ; else if (canonicDataLabel === 'VARNAME') {
|
|
1109
|
-
currentEntry.ntuples.varname = dataValue.split(ntuplesSeparatorRegExp);
|
|
1110
|
-
} else if (canonicDataLabel === 'SYMBOL') {
|
|
1111
|
-
currentEntry.ntuples.symbol = dataValue.split(ntuplesSeparatorRegExp);
|
|
1112
|
-
} else if (canonicDataLabel === 'VARTYPE') {
|
|
1113
|
-
currentEntry.ntuples.vartype = dataValue.split(ntuplesSeparatorRegExp);
|
|
1114
|
-
} else if (canonicDataLabel === 'VARFORM') {
|
|
1115
|
-
currentEntry.ntuples.varform = dataValue.split(ntuplesSeparatorRegExp);
|
|
1116
|
-
} else if (canonicDataLabel === 'VARDIM') {
|
|
1117
|
-
currentEntry.ntuples.vardim = convertToFloatArray(
|
|
1118
|
-
dataValue.split(ntuplesSeparatorRegExp),
|
|
1119
|
-
);
|
|
1120
|
-
} else if (canonicDataLabel === 'UNITS') {
|
|
1121
|
-
currentEntry.ntuples.units = dataValue.split(ntuplesSeparatorRegExp);
|
|
1122
|
-
} else if (canonicDataLabel === 'FACTOR') {
|
|
1123
|
-
currentEntry.ntuples.factor = convertToFloatArray(
|
|
1124
|
-
dataValue.split(ntuplesSeparatorRegExp),
|
|
1125
|
-
);
|
|
1126
|
-
} else if (canonicDataLabel === 'FIRST') {
|
|
1127
|
-
currentEntry.ntuples.first = convertToFloatArray(
|
|
1128
|
-
dataValue.split(ntuplesSeparatorRegExp),
|
|
1129
|
-
);
|
|
1130
|
-
} else if (canonicDataLabel === 'LAST') {
|
|
1131
|
-
currentEntry.ntuples.last = convertToFloatArray(
|
|
1132
|
-
dataValue.split(ntuplesSeparatorRegExp),
|
|
1133
|
-
);
|
|
1134
|
-
} else if (canonicDataLabel === 'MIN') {
|
|
1135
|
-
currentEntry.ntuples.min = convertToFloatArray(
|
|
1136
|
-
dataValue.split(ntuplesSeparatorRegExp),
|
|
1137
|
-
);
|
|
1138
|
-
} else if (canonicDataLabel === 'MAX') {
|
|
1139
|
-
currentEntry.ntuples.max = convertToFloatArray(
|
|
1140
|
-
dataValue.split(ntuplesSeparatorRegExp),
|
|
1141
|
-
);
|
|
1142
|
-
} else if (canonicDataLabel === '.NUCLEUS') {
|
|
1143
|
-
if (currentEntry.ntuples) {
|
|
1144
|
-
currentEntry.ntuples.nucleus = dataValue.split(ntuplesSeparatorRegExp);
|
|
1145
|
-
}
|
|
1146
|
-
} else if (canonicDataLabel === 'PAGE') {
|
|
1147
|
-
spectrum.page = dataValue.trim();
|
|
1148
|
-
spectrum.pageValue = Number(dataValue.replace(/^.*=/, ''));
|
|
1149
|
-
spectrum.pageSymbol = spectrum.page.replace(/[=].*/, '');
|
|
1150
|
-
} else if (canonicDataLabel === 'RETENTIONTIME') {
|
|
1151
|
-
spectrum.pageValue = Number(dataValue);
|
|
1152
|
-
} else if (isMSField(canonicDataLabel)) {
|
|
1153
|
-
spectrum[convertMSFieldToLabel(canonicDataLabel)] = dataValue;
|
|
1154
|
-
} else if (canonicDataLabel === 'SAMPLEDESCRIPTION') {
|
|
1155
|
-
spectrum.sampleDescription = dataValue;
|
|
1156
|
-
} else if (canonicDataLabel.startsWith('$NUC')) {
|
|
1157
|
-
if (!currentEntry.tmp[canonicDataLabel] && !dataValue.includes('off')) {
|
|
1158
|
-
currentEntry.tmp[canonicDataLabel] = dataValue.replace(/[<>]/g, '');
|
|
1159
|
-
}
|
|
1160
|
-
} else if (canonicDataLabel === 'END') {
|
|
1161
|
-
currentEntry = parentsStack.pop();
|
|
1162
|
-
}
|
|
1163
|
-
|
|
1164
|
-
if (
|
|
1165
|
-
currentEntry &&
|
|
1166
|
-
currentEntry.info &&
|
|
1167
|
-
currentEntry.meta &&
|
|
1168
|
-
canonicDataLabel.match(options.keepRecordsRegExp)
|
|
1169
|
-
) {
|
|
1170
|
-
let value = dataValue.trim();
|
|
1171
|
-
let target, label;
|
|
1172
|
-
if (dataLabel.startsWith('$')) {
|
|
1173
|
-
label = options.canonicMetadataLabels
|
|
1174
|
-
? canonicDataLabel.substring(1)
|
|
1175
|
-
: dataLabel.substring(1);
|
|
1176
|
-
target = currentEntry.meta;
|
|
1177
|
-
} else {
|
|
1178
|
-
label = options.canonicDataLabels ? canonicDataLabel : dataLabel;
|
|
1179
|
-
target = currentEntry.info;
|
|
1180
|
-
}
|
|
1181
|
-
|
|
1182
|
-
if (options.dynamicTyping) {
|
|
1183
|
-
value = dynamicTyping.parseString(value);
|
|
1184
|
-
}
|
|
1185
|
-
if (target[label]) {
|
|
1186
|
-
if (!Array.isArray(target[label])) {
|
|
1187
|
-
target[label] = [target[label]];
|
|
1188
|
-
}
|
|
1189
|
-
target[label].push(value);
|
|
1190
|
-
} else {
|
|
1191
|
-
target[label] = value;
|
|
1192
|
-
}
|
|
1193
|
-
}
|
|
1194
|
-
}
|
|
1195
|
-
|
|
1196
|
-
profiling(result, 'Finished parsing', options);
|
|
1197
|
-
|
|
1198
|
-
postProcessing(entriesFlat, result, options);
|
|
1199
|
-
|
|
1200
|
-
profiling(result, 'Total time', options);
|
|
1201
|
-
|
|
1202
|
-
/*
|
|
1203
|
-
if (result.children && result.children.length>0) {
|
|
1204
|
-
result = { ...result, ...result.children[0] };
|
|
1205
|
-
}
|
|
1206
|
-
*/
|
|
1207
|
-
result.entries = tmpResult.children;
|
|
1208
|
-
result.flatten = entriesFlat;
|
|
1209
|
-
|
|
1210
|
-
return result;
|
|
1211
|
-
}
|
|
1212
|
-
|
|
1213
|
-
exports.convert = convert;
|
|
1214
|
-
exports.createTree = createTree;
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.convert = exports.createTree = void 0;
|
|
4
|
+
var createTree_1 = require("./createTree");
|
|
5
|
+
Object.defineProperty(exports, "createTree", { enumerable: true, get: function () { return createTree_1.createTree; } });
|
|
6
|
+
var convert_1 = require("./convert");
|
|
7
|
+
Object.defineProperty(exports, "convert", { enumerable: true, get: function () { return convert_1.convert; } });
|
|
8
|
+
//# sourceMappingURL=index.js.map
|