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.
- package/lib/assignment/utils/getAssignment/checkIDs.d.ts +1 -1
- package/lib/assignment/utils/getAssignment/checkIDs.js.map +1 -1
- package/lib/index.d.ts +2 -0
- package/lib/index.js +2 -0
- package/lib/index.js.map +1 -1
- package/lib/peaks/peaksToRanges.d.ts +16 -0
- package/lib/peaks/peaksToRanges.js +2 -1
- package/lib/peaks/peaksToRanges.js.map +1 -1
- package/lib/peaks/solventSuppression.d.ts +1 -1
- package/lib/peaks/solventSuppression.js +34 -26
- package/lib/peaks/solventSuppression.js.map +1 -1
- package/lib/peaks/util/jAnalyzer.js +3 -2
- package/lib/peaks/util/jAnalyzer.js.map +1 -1
- package/lib/ranges/markSolventSignal.d.ts +3 -0
- package/lib/ranges/markSolventSignal.js +107 -0
- package/lib/ranges/markSolventSignal.js.map +1 -0
- package/lib/xyz/util/formatZone.d.ts +3 -0
- package/lib/xyz/util/formatZone.js +38 -0
- package/lib/xyz/util/formatZone.js.map +1 -0
- package/lib/xyz/xyzAutoZonesPicking.d.ts +1 -2
- package/lib/xyz/xyzAutoZonesPicking.js +2 -34
- package/lib/xyz/xyzAutoZonesPicking.js.map +1 -1
- package/lib/xyz/xyzJResAnalyzer.d.ts +6 -1
- package/lib/xyz/xyzJResAnalyzer.js +9 -8
- package/lib/xyz/xyzJResAnalyzer.js.map +1 -1
- package/lib-esm/assignment/utils/getAssignment/checkIDs.js.map +1 -1
- package/lib-esm/index.js +2 -0
- package/lib-esm/index.js.map +1 -1
- package/lib-esm/peaks/peaksToRanges.js +1 -1
- package/lib-esm/peaks/peaksToRanges.js.map +1 -1
- package/lib-esm/peaks/solventSuppression.js +32 -21
- package/lib-esm/peaks/solventSuppression.js.map +1 -1
- package/lib-esm/peaks/util/jAnalyzer.js +3 -2
- package/lib-esm/peaks/util/jAnalyzer.js.map +1 -1
- package/lib-esm/ranges/markSolventSignal.js +100 -0
- package/lib-esm/ranges/markSolventSignal.js.map +1 -0
- package/lib-esm/xyz/util/formatZone.js +34 -0
- package/lib-esm/xyz/util/formatZone.js.map +1 -0
- package/lib-esm/xyz/xyzAutoZonesPicking.js +1 -33
- package/lib-esm/xyz/xyzAutoZonesPicking.js.map +1 -1
- package/lib-esm/xyz/xyzJResAnalyzer.js +9 -8
- package/lib-esm/xyz/xyzJResAnalyzer.js.map +1 -1
- package/package.json +2 -2
- package/src/assignment/utils/getAssignment/checkIDs.ts +1 -1
- package/src/index.ts +3 -0
- package/src/peaks/peaksToRanges.ts +1 -1
- package/src/peaks/solventSuppression.ts +57 -34
- package/src/peaks/util/jAnalyzer.ts +4 -2
- package/src/ranges/markSolventSignal.ts +121 -0
- package/src/xyz/util/formatZone.ts +36 -0
- package/src/xyz/xyzAutoZonesPicking.ts +1 -35
- 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
|
|
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
|
-
|
|
67
|
+
signals2D.push(tempSignal);
|
|
61
68
|
}
|
|
62
|
-
return
|
|
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
|
|
132
|
+
let signals2D = createSignals2D(peaksO, signalOptions);
|
|
126
133
|
|
|
127
|
-
for (const
|
|
128
|
-
newSignals.push(
|
|
134
|
+
for (const signal of signals2D) {
|
|
135
|
+
newSignals.push(signal);
|
|
129
136
|
}
|
|
130
137
|
}
|
|
131
138
|
}
|