nmr-processing 8.1.0 → 8.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/lib/assignment/utils/getAssignment/checkIDs.d.ts +1 -1
  2. package/lib/assignment/utils/getAssignment/checkIDs.js.map +1 -1
  3. package/lib/index.d.ts +2 -0
  4. package/lib/index.js +2 -0
  5. package/lib/index.js.map +1 -1
  6. package/lib/peaks/peaksToRanges.d.ts +16 -0
  7. package/lib/peaks/peaksToRanges.js +2 -1
  8. package/lib/peaks/peaksToRanges.js.map +1 -1
  9. package/lib/peaks/solventSuppression.d.ts +1 -1
  10. package/lib/peaks/solventSuppression.js +34 -26
  11. package/lib/peaks/solventSuppression.js.map +1 -1
  12. package/lib/peaks/util/jAnalyzer.js +3 -2
  13. package/lib/peaks/util/jAnalyzer.js.map +1 -1
  14. package/lib/ranges/markSolventSignal.d.ts +3 -0
  15. package/lib/ranges/markSolventSignal.js +107 -0
  16. package/lib/ranges/markSolventSignal.js.map +1 -0
  17. package/lib/xyz/util/formatZone.d.ts +3 -0
  18. package/lib/xyz/util/formatZone.js +38 -0
  19. package/lib/xyz/util/formatZone.js.map +1 -0
  20. package/lib/xyz/xyzAutoZonesPicking.d.ts +1 -2
  21. package/lib/xyz/xyzAutoZonesPicking.js +2 -34
  22. package/lib/xyz/xyzAutoZonesPicking.js.map +1 -1
  23. package/lib/xyz/xyzJResAnalyzer.d.ts +6 -1
  24. package/lib/xyz/xyzJResAnalyzer.js +9 -8
  25. package/lib/xyz/xyzJResAnalyzer.js.map +1 -1
  26. package/lib-esm/assignment/utils/getAssignment/checkIDs.js.map +1 -1
  27. package/lib-esm/index.js +2 -0
  28. package/lib-esm/index.js.map +1 -1
  29. package/lib-esm/peaks/peaksToRanges.js +1 -1
  30. package/lib-esm/peaks/peaksToRanges.js.map +1 -1
  31. package/lib-esm/peaks/solventSuppression.js +32 -21
  32. package/lib-esm/peaks/solventSuppression.js.map +1 -1
  33. package/lib-esm/peaks/util/jAnalyzer.js +3 -2
  34. package/lib-esm/peaks/util/jAnalyzer.js.map +1 -1
  35. package/lib-esm/ranges/markSolventSignal.js +100 -0
  36. package/lib-esm/ranges/markSolventSignal.js.map +1 -0
  37. package/lib-esm/xyz/util/formatZone.js +34 -0
  38. package/lib-esm/xyz/util/formatZone.js.map +1 -0
  39. package/lib-esm/xyz/xyzAutoZonesPicking.js +1 -33
  40. package/lib-esm/xyz/xyzAutoZonesPicking.js.map +1 -1
  41. package/lib-esm/xyz/xyzJResAnalyzer.js +9 -8
  42. package/lib-esm/xyz/xyzJResAnalyzer.js.map +1 -1
  43. package/package.json +2 -2
  44. package/src/assignment/utils/getAssignment/checkIDs.ts +1 -1
  45. package/src/index.ts +3 -0
  46. package/src/peaks/peaksToRanges.ts +1 -1
  47. package/src/peaks/solventSuppression.ts +57 -34
  48. package/src/peaks/util/jAnalyzer.ts +4 -2
  49. package/src/ranges/markSolventSignal.ts +121 -0
  50. package/src/xyz/util/formatZone.ts +36 -0
  51. package/src/xyz/xyzAutoZonesPicking.ts +1 -35
  52. package/src/xyz/xyzJResAnalyzer.ts +14 -7
@@ -0,0 +1,121 @@
1
+ import { NMRRangeWithIds, NMRSignal1DWithId } from '../assignment/nmrAssigment';
2
+ import generateID from '../assignment/utils/generateID';
3
+ import { addIDs } from '../assignment/utils/getAssignment/checkIDs';
4
+ import { NMRPeak1D } from '../peaks/NMRPeak1D';
5
+ import { detectSignals } from '../peaks/peaksToRanges';
6
+ import { solventSuppression } from '../peaks/solventSuppression';
7
+ import { SignalIntern } from '../peaks/util/jAnalyzer';
8
+ import { NMRSignal1D } from '../signals/NMRSignal1D';
9
+ import { NMRRange } from '../xy/NMRRange';
10
+
11
+ interface NMRPeak1DWithSignalID extends NMRPeak1D {
12
+ signalID: string;
13
+ rangeID: string;
14
+ }
15
+
16
+ export function markSolventPeaks<T extends NMRRange>(
17
+ input: T[],
18
+ solventSignals: NMRSignal1D[],
19
+ options: any = {},
20
+ ) {
21
+ const { frequency = 400 } = options;
22
+ const ranges = addIDs([...input]) as NMRRangeWithIds[];
23
+
24
+ let peakList: NMRPeak1DWithSignalID[] = [];
25
+ for (const range of ranges) {
26
+ const rangeID = range.id;
27
+ for (const signal of range.signals || []) {
28
+ const signalID = signal.id;
29
+ for (let peak of signal.peaks || []) {
30
+ peakList.push({
31
+ ...peak,
32
+ rangeID,
33
+ signalID,
34
+ });
35
+ }
36
+ }
37
+ }
38
+
39
+ const peaks = solventSuppression(peakList, solventSignals, {
40
+ markSolventPeaks: true,
41
+ });
42
+
43
+ const signalsWithSolvent = getSignalIDsWithSolvent(peaks);
44
+ for (let range of ranges) {
45
+ if (!range.signals) continue;
46
+ for (let signal of range.signals) {
47
+ if (!signalsWithSolvent.includes(signal.id)) continue;
48
+ const signalPeaks = [];
49
+ const solventSignalPeaks = [];
50
+ for (let peak of peaks) {
51
+ if (peak.signalID === signal.id) {
52
+ const { signalID, rangeID, ...newPeak } = peak;
53
+ if (peak.kind === 'solvent') {
54
+ solventSignalPeaks.push(newPeak);
55
+ } else {
56
+ signalPeaks.push(newPeak);
57
+ }
58
+ }
59
+ }
60
+ const newSignals =
61
+ signalPeaks.length > 0
62
+ ? detectSignals({ x: [], y: [] }, signalPeaks, {
63
+ integralType: 'peak',
64
+ frequency,
65
+ })
66
+ : [];
67
+ solventSignalPeaks.sort((a, b) => a.x - b.x);
68
+ const lowPPMValue = solventSignalPeaks[0].x;
69
+ const highPPMValue = solventSignalPeaks[solventSignalPeaks.length - 1].x;
70
+ const newSolventSignals = detectSignals(
71
+ { x: [], y: [] },
72
+ solventSignalPeaks,
73
+ {
74
+ integralType: 'peak',
75
+ frequencyCluster: (highPPMValue - lowPPMValue) * frequency,
76
+ frequency,
77
+ },
78
+ );
79
+
80
+ range.signals = [
81
+ ...adaptSignals(newSignals),
82
+ ...adaptSignals(newSolventSignals),
83
+ ...range.signals.filter((currSignal) => currSignal.id !== signal.id),
84
+ ];
85
+ }
86
+ }
87
+ return ranges as T[];
88
+ }
89
+
90
+ function getSignalIDsWithSolvent(solventPeaks: NMRPeak1DWithSignalID[]) {
91
+ const uniqueSignalID = new Set();
92
+ for (let peak of solventPeaks) {
93
+ if (peak.kind !== 'solvent') continue;
94
+ uniqueSignalID.add(peak.signalID);
95
+ }
96
+ return Array.from(uniqueSignalID);
97
+ }
98
+
99
+ function adaptSignals(signals: SignalIntern[]) {
100
+ const newSignals = [];
101
+ for (let signal of signals) {
102
+ const signalResult: NMRSignal1DWithId = {
103
+ id: generateID(),
104
+ delta: signal.delta,
105
+ kind: signal.kind || 'signal',
106
+ multiplicity: signal.multiplicity,
107
+ integration: signal.integralData.value,
108
+ };
109
+ signalResult.peaks = signal.peaks.map((peak) => {
110
+ const newResult: any = {
111
+ y: peak.intensity,
112
+ ...peak,
113
+ };
114
+ delete newResult.intensity;
115
+ return newResult as NMRPeak1D;
116
+ });
117
+ signalResult.js = signal.nmrJs || [];
118
+ newSignals.push(signalResult);
119
+ }
120
+ return newSignals;
121
+ }
@@ -0,0 +1,36 @@
1
+ import { NMRSignal2D } from '../NMRSignal2D';
2
+ import { NMRZone } from '../NMRZone';
3
+
4
+ export function formatZones(signals: NMRSignal2D[]) {
5
+ let zones: NMRZone[] = [];
6
+ for (const signal of signals) {
7
+ let minMax1 = [Number.MAX_VALUE, 0];
8
+ let minMax2 = [Number.MAX_VALUE, 0];
9
+ for (const peak of signal.peaks || []) {
10
+ if (peak.minX < minMax1[0]) {
11
+ minMax1[0] = peak.minX;
12
+ }
13
+ if (peak.maxX > minMax1[1]) {
14
+ minMax1[1] = peak.maxX;
15
+ }
16
+ if (peak.minY < minMax2[0]) {
17
+ minMax2[0] = peak.minY;
18
+ }
19
+ if (peak.maxY > minMax2[1]) {
20
+ minMax2[1] = peak.maxY;
21
+ }
22
+ }
23
+ zones.push({
24
+ x: {
25
+ from: minMax1[0],
26
+ to: minMax1[1],
27
+ },
28
+ y: {
29
+ from: minMax2[0],
30
+ to: minMax2[1],
31
+ },
32
+ signals: [signal],
33
+ });
34
+ }
35
+ return zones;
36
+ }
@@ -4,13 +4,13 @@ import * as matrixPeakFinders from 'ml-matrix-peaks-finder';
4
4
  import type { Peak2D } from 'ml-matrix-peaks-finder';
5
5
  import simpleClustering from 'ml-simple-clustering';
6
6
 
7
- import { NMRZone } from '..';
8
7
  import { determineRealTop } from '../peaks/util/determineRealTop';
9
8
  import { getKernel } from '../peaks/util/getKernel';
10
9
  import type { GetKernelOptions } from '../peaks/util/getKernel';
11
10
  import * as PeakOptimizer from '../peaks/util/peakOptimizer';
12
11
 
13
12
  import type { NMRSignal2D } from './NMRSignal2D';
13
+ import { formatZones } from './util/formatZone';
14
14
 
15
15
  const smallFilter = [
16
16
  [0, 0, 1, 2, 2, 2, 1, 0, 0],
@@ -183,40 +183,6 @@ export function xyzAutoZonesPicking(
183
183
  return formatZones(signals);
184
184
  }
185
185
 
186
- function formatZones(signals: NMRSignal2D[]) {
187
- let zones: NMRZone[] = [];
188
- for (const signal of signals) {
189
- let minMax1 = [Number.MAX_VALUE, 0];
190
- let minMax2 = [Number.MAX_VALUE, 0];
191
- for (const peak of signal.peaks || []) {
192
- if (peak.minX < minMax1[0]) {
193
- minMax1[0] = peak.minX;
194
- }
195
- if (peak.maxX > minMax1[1]) {
196
- minMax1[1] = peak.maxX;
197
- }
198
- if (peak.minY < minMax2[0]) {
199
- minMax2[0] = peak.minY;
200
- }
201
- if (peak.maxY > minMax2[1]) {
202
- minMax2[1] = peak.maxY;
203
- }
204
- }
205
- zones.push({
206
- x: {
207
- from: minMax1[0],
208
- to: minMax1[1],
209
- },
210
- y: {
211
- from: minMax2[0],
212
- to: minMax2[1],
213
- },
214
- signals: [signal],
215
- });
216
- }
217
- return zones;
218
- }
219
-
220
186
  /**
221
187
  * This function converts a set of 2D-peaks in 2D-signals. Each signal could be composed
222
188
  * of many 2D-peaks, and it has some additional information related to the NMR spectrum.
@@ -6,6 +6,7 @@ import jAnalyzer from '../peaks/util/jAnalyzer';
6
6
  import type { MakeMandatory } from '../utilities/MakeMandatory';
7
7
 
8
8
  import type { NMRSignal2D } from './NMRSignal2D';
9
+ import { formatZones } from './util/formatZone';
9
10
 
10
11
  interface CompilePatternOptions {
11
12
  observedFrequencies?: number[] | Float64Array;
@@ -25,6 +26,11 @@ interface XYZJResAnalyzerOptions extends CompilePatternOptions {
25
26
  * @default 0
26
27
  */
27
28
  reference?: number;
29
+ /**
30
+ * if it is true returns zones instead of signals 2D
31
+ * @default false
32
+ */
33
+ getZones?: boolean;
28
34
  }
29
35
 
30
36
  type CompilePatternOptionsMandatory = MakeMandatory<
@@ -38,6 +44,7 @@ export function xyzJResAnalyzer(
38
44
  ) {
39
45
  let {
40
46
  reference = 0,
47
+ getZones = false,
41
48
  referenceMaxShiftError = 0.08,
42
49
  tolerances = [10, 100],
43
50
  nuclei = ['1H', '1H'],
@@ -46,20 +53,20 @@ export function xyzJResAnalyzer(
46
53
  jAxisKey: { jAxis: 'y', intensity: 'z' },
47
54
  },
48
55
  } = options;
49
- let temporalSignals = compilePattern(signals, {
56
+ let temporalSignals = compilePattern([...signals], {
50
57
  observedFrequencies,
51
58
  tolerances,
52
59
  nuclei,
53
60
  jAnalyzer,
54
61
  });
55
62
  //check if the signal are symmetric around the reference
56
- let result = [];
63
+ let signals2D = [];
57
64
  for (const tempSignal of temporalSignals) {
58
65
  let delta = tempSignal.y.delta;
59
66
  if (Math.abs(delta - reference) > referenceMaxShiftError) continue;
60
- result.push(tempSignal);
67
+ signals2D.push(tempSignal);
61
68
  }
62
- return result;
69
+ return getZones ? formatZones(signals2D) : signals2D;
63
70
  }
64
71
 
65
72
  function compilePattern(
@@ -122,10 +129,10 @@ function compilePattern(
122
129
  }
123
130
  if (peaksO.length > 0) {
124
131
  peaksO.reverse();
125
- let ranges = createSignals2D(peaksO, signalOptions);
132
+ let signals2D = createSignals2D(peaksO, signalOptions);
126
133
 
127
- for (const range of ranges) {
128
- newSignals.push(range);
134
+ for (const signal of signals2D) {
135
+ newSignals.push(signal);
129
136
  }
130
137
  }
131
138
  }