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.
Files changed (140) hide show
  1. package/lib/2d/add2D.d.ts +2 -0
  2. package/lib/2d/add2D.d.ts.map +1 -0
  3. package/lib/2d/add2D.js +17 -0
  4. package/lib/2d/add2D.js.map +1 -0
  5. package/lib/2d/convertTo3DZ.d.ts +11 -0
  6. package/lib/2d/convertTo3DZ.d.ts.map +1 -0
  7. package/lib/2d/convertTo3DZ.js +59 -0
  8. package/lib/2d/convertTo3DZ.js.map +1 -0
  9. package/lib/2d/generateContourLines.d.ts +8 -0
  10. package/lib/2d/generateContourLines.d.ts.map +1 -0
  11. package/lib/2d/generateContourLines.js +163 -0
  12. package/lib/2d/generateContourLines.js.map +1 -0
  13. package/lib/complexChromatogram.d.ts +4 -0
  14. package/lib/complexChromatogram.d.ts.map +1 -0
  15. package/lib/complexChromatogram.js +49 -0
  16. package/lib/complexChromatogram.js.map +1 -0
  17. package/lib/convert.d.ts +139 -0
  18. package/lib/convert.d.ts.map +1 -0
  19. package/lib/convert.js +383 -0
  20. package/lib/convert.js.map +1 -0
  21. package/lib/convertToFloatArray.d.ts +2 -0
  22. package/lib/convertToFloatArray.d.ts.map +1 -0
  23. package/lib/convertToFloatArray.js +11 -0
  24. package/lib/convertToFloatArray.js.map +1 -0
  25. package/lib/createTree.d.ts +29 -0
  26. package/lib/createTree.d.ts.map +1 -0
  27. package/lib/createTree.js +98 -0
  28. package/lib/createTree.js.map +1 -0
  29. package/lib/index.d.ts +3 -0
  30. package/lib/index.d.ts.map +1 -0
  31. package/lib/index.js +8 -1214
  32. package/lib/index.js.map +1 -0
  33. package/lib/parse/fastParseXYData.d.ts +2 -0
  34. package/lib/parse/fastParseXYData.d.ts.map +1 -0
  35. package/lib/parse/fastParseXYData.js +192 -0
  36. package/lib/parse/fastParseXYData.js.map +1 -0
  37. package/lib/parse/parsePeakTable.d.ts +2 -0
  38. package/lib/parse/parsePeakTable.d.ts.map +1 -0
  39. package/lib/parse/parsePeakTable.js +67 -0
  40. package/lib/parse/parsePeakTable.js.map +1 -0
  41. package/lib/parse/parseXYA.d.ts +2 -0
  42. package/lib/parse/parseXYA.d.ts.map +1 -0
  43. package/lib/parse/parseXYA.js +17 -0
  44. package/lib/parse/parseXYA.js.map +1 -0
  45. package/lib/postProcessing.d.ts +2 -0
  46. package/lib/postProcessing.d.ts.map +1 -0
  47. package/lib/postProcessing.js +50 -0
  48. package/lib/postProcessing.js.map +1 -0
  49. package/lib/postProcessingNMR.d.ts +2 -0
  50. package/lib/postProcessingNMR.d.ts.map +1 -0
  51. package/lib/postProcessingNMR.js +94 -0
  52. package/lib/postProcessingNMR.js.map +1 -0
  53. package/lib/prepareNtuplesDatatable.d.ts +2 -0
  54. package/lib/prepareNtuplesDatatable.d.ts.map +1 -0
  55. package/lib/prepareNtuplesDatatable.js +87 -0
  56. package/lib/prepareNtuplesDatatable.js.map +1 -0
  57. package/lib/prepareSpectrum.d.ts +2 -0
  58. package/lib/prepareSpectrum.d.ts.map +1 -0
  59. package/lib/prepareSpectrum.js +10 -0
  60. package/lib/prepareSpectrum.js.map +1 -0
  61. package/lib/profiling.d.ts +2 -0
  62. package/lib/profiling.d.ts.map +1 -0
  63. package/lib/profiling.js +12 -0
  64. package/lib/profiling.js.map +1 -0
  65. package/lib/simpleChromatogram.d.ts +2 -0
  66. package/lib/simpleChromatogram.d.ts.map +1 -0
  67. package/lib/simpleChromatogram.js +16 -0
  68. package/lib/simpleChromatogram.js.map +1 -0
  69. package/lib-esm/2d/add2D.d.ts +2 -0
  70. package/lib-esm/2d/add2D.d.ts.map +1 -0
  71. package/lib-esm/2d/add2D.js +11 -0
  72. package/lib-esm/2d/add2D.js.map +1 -0
  73. package/lib-esm/2d/convertTo3DZ.d.ts +11 -0
  74. package/lib-esm/2d/convertTo3DZ.d.ts.map +1 -0
  75. package/lib-esm/2d/convertTo3DZ.js +53 -0
  76. package/lib-esm/2d/convertTo3DZ.js.map +1 -0
  77. package/lib-esm/2d/generateContourLines.d.ts +8 -0
  78. package/lib-esm/2d/generateContourLines.d.ts.map +1 -0
  79. package/lib-esm/2d/generateContourLines.js +160 -0
  80. package/lib-esm/2d/generateContourLines.js.map +1 -0
  81. package/lib-esm/complexChromatogram.d.ts +4 -0
  82. package/lib-esm/complexChromatogram.d.ts.map +1 -0
  83. package/lib-esm/complexChromatogram.js +43 -0
  84. package/lib-esm/complexChromatogram.js.map +1 -0
  85. package/lib-esm/convert.d.ts +139 -0
  86. package/lib-esm/convert.d.ts.map +1 -0
  87. package/lib-esm/convert.js +376 -0
  88. package/lib-esm/convert.js.map +1 -0
  89. package/lib-esm/convertToFloatArray.d.ts +2 -0
  90. package/lib-esm/convertToFloatArray.d.ts.map +1 -0
  91. package/lib-esm/convertToFloatArray.js +8 -0
  92. package/lib-esm/convertToFloatArray.js.map +1 -0
  93. package/lib-esm/createTree.d.ts +29 -0
  94. package/lib-esm/createTree.d.ts.map +1 -0
  95. package/lib-esm/createTree.js +94 -0
  96. package/lib-esm/createTree.js.map +1 -0
  97. package/lib-esm/index.d.ts +3 -0
  98. package/lib-esm/index.d.ts.map +1 -0
  99. package/lib-esm/index.js +3 -0
  100. package/lib-esm/index.js.map +1 -0
  101. package/lib-esm/parse/fastParseXYData.d.ts +2 -0
  102. package/lib-esm/parse/fastParseXYData.d.ts.map +1 -0
  103. package/lib-esm/parse/fastParseXYData.js +189 -0
  104. package/lib-esm/parse/fastParseXYData.js.map +1 -0
  105. package/lib-esm/parse/parsePeakTable.d.ts +2 -0
  106. package/lib-esm/parse/parsePeakTable.d.ts.map +1 -0
  107. package/lib-esm/parse/parsePeakTable.js +64 -0
  108. package/lib-esm/parse/parsePeakTable.js.map +1 -0
  109. package/lib-esm/parse/parseXYA.d.ts +2 -0
  110. package/lib-esm/parse/parseXYA.d.ts.map +1 -0
  111. package/lib-esm/parse/parseXYA.js +14 -0
  112. package/lib-esm/parse/parseXYA.js.map +1 -0
  113. package/lib-esm/postProcessing.d.ts +2 -0
  114. package/lib-esm/postProcessing.d.ts.map +1 -0
  115. package/lib-esm/postProcessing.js +44 -0
  116. package/lib-esm/postProcessing.js.map +1 -0
  117. package/lib-esm/postProcessingNMR.d.ts +2 -0
  118. package/lib-esm/postProcessingNMR.d.ts.map +1 -0
  119. package/lib-esm/postProcessingNMR.js +91 -0
  120. package/lib-esm/postProcessingNMR.js.map +1 -0
  121. package/lib-esm/prepareNtuplesDatatable.d.ts +2 -0
  122. package/lib-esm/prepareNtuplesDatatable.d.ts.map +1 -0
  123. package/lib-esm/prepareNtuplesDatatable.js +84 -0
  124. package/lib-esm/prepareNtuplesDatatable.js.map +1 -0
  125. package/lib-esm/prepareSpectrum.d.ts +2 -0
  126. package/lib-esm/prepareSpectrum.d.ts.map +1 -0
  127. package/lib-esm/prepareSpectrum.js +7 -0
  128. package/lib-esm/prepareSpectrum.js.map +1 -0
  129. package/lib-esm/profiling.d.ts +2 -0
  130. package/lib-esm/profiling.d.ts.map +1 -0
  131. package/lib-esm/profiling.js +9 -0
  132. package/lib-esm/profiling.js.map +1 -0
  133. package/lib-esm/simpleChromatogram.d.ts +2 -0
  134. package/lib-esm/simpleChromatogram.d.ts.map +1 -0
  135. package/lib-esm/simpleChromatogram.js +13 -0
  136. package/lib-esm/simpleChromatogram.js.map +1 -0
  137. package/package.json +22 -17
  138. package/src/convert.js +57 -13
  139. package/src/createTree.js +16 -3
  140. package/CHANGELOG.md +0 -427
package/lib/index.js CHANGED
@@ -1,1214 +1,8 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- var ensureString = require('ensure-string');
6
- var dynamicTyping = require('dynamic-typing');
7
- var getMedian = require('ml-array-median');
8
- var nmrProcessing = require('nmr-processing');
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