jcampconverter 8.2.0 → 8.2.4

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