nmr-processing 9.4.1 → 9.4.2-pre.1684301205
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/constants/MultiplicityPatterns.d.ts +1 -0
- package/lib/constants/MultiplicityPatterns.js +3 -1
- package/lib/constants/MultiplicityPatterns.js.map +1 -1
- package/lib/constants/couplingPatterns.d.ts +1 -0
- package/lib/constants/couplingPatterns.js +5 -1
- package/lib/constants/couplingPatterns.js.map +1 -1
- package/lib/index.d.ts +6 -1
- package/lib/index.js +6 -1
- package/lib/index.js.map +1 -1
- package/lib/multiplicity/checkMultiplet.d.ts +1 -0
- package/lib/multiplicity/checkMultiplet.js +13 -0
- package/lib/multiplicity/checkMultiplet.js.map +1 -0
- package/lib/multiplicity/checkMultiplicity.d.ts +1 -0
- package/lib/multiplicity/checkMultiplicity.js +17 -0
- package/lib/multiplicity/checkMultiplicity.js.map +1 -0
- package/lib/multiplicity/findMultiplet.d.ts +1 -0
- package/lib/multiplicity/findMultiplet.js +12 -0
- package/lib/multiplicity/findMultiplet.js.map +1 -0
- package/lib/multiplicity/joinPatterns.d.ts +3 -0
- package/lib/{utilities → multiplicity}/joinPatterns.js +2 -2
- package/lib/multiplicity/joinPatterns.js.map +1 -0
- package/lib/multiplicity/splitPatterns.js.map +1 -0
- package/lib/multiplicity/translateMultiplet.d.ts +1 -0
- package/lib/multiplicity/translateMultiplet.js +14 -0
- package/lib/multiplicity/translateMultiplet.js.map +1 -0
- package/lib/ranges/rangesToACS.js +1 -0
- package/lib/ranges/rangesToACS.js.map +1 -1
- package/lib/signal/signalJoinCouplings.d.ts +5 -0
- package/lib/signal/signalJoinCouplings.js +7 -6
- package/lib/signal/signalJoinCouplings.js.map +1 -1
- package/lib/signal/signalMultiplicityPattern.d.ts +3 -1
- package/lib/signal/signalMultiplicityPattern.js +6 -2
- package/lib/signal/signalMultiplicityPattern.js.map +1 -1
- package/lib/utilities/normalizeNucleus.d.ts +1 -0
- package/lib/utilities/normalizeNucleus.js +22 -0
- package/lib/utilities/normalizeNucleus.js.map +1 -0
- package/lib/utilities/nucleusMap.d.ts +5 -0
- package/lib/utilities/nucleusMap.js +22 -0
- package/lib/utilities/nucleusMap.js.map +1 -0
- package/lib/utilities/resurrectRange.js +1 -1
- package/lib/utilities/resurrectRange.js.map +1 -1
- package/lib/utilities/selectACSPattern.d.ts +1 -0
- package/lib/utilities/selectACSPattern.js +14 -0
- package/lib/utilities/selectACSPattern.js.map +1 -0
- package/lib/xyz/Data2D.d.ts +7 -0
- package/lib/xyz/Data2D.js +3 -0
- package/lib/xyz/Data2D.js.map +1 -0
- package/lib/xyz/util/formatZone.d.ts +2 -1
- package/lib/xyz/util/formatZone.js.map +1 -1
- package/lib/xyz/util/padData.d.ts +10 -0
- package/lib/xyz/util/padData.js +38 -0
- package/lib/xyz/util/padData.js.map +1 -0
- package/lib/xyz/xyzAutoSignalsPicking.d.ts +84 -0
- package/lib/xyz/xyzAutoSignalsPicking.js +193 -0
- package/lib/xyz/xyzAutoSignalsPicking.js.map +1 -0
- package/lib/xyz/xyzAutoZonesPicking.d.ts +0 -22
- package/lib/xyz/xyzAutoZonesPicking.js +2 -214
- package/lib/xyz/xyzAutoZonesPicking.js.map +1 -1
- package/lib-esm/constants/MultiplicityPatterns.js +3 -1
- package/lib-esm/constants/MultiplicityPatterns.js.map +1 -1
- package/lib-esm/constants/couplingPatterns.js +4 -0
- package/lib-esm/constants/couplingPatterns.js.map +1 -1
- package/lib-esm/index.js +6 -1
- package/lib-esm/index.js.map +1 -1
- package/lib-esm/multiplicity/checkMultiplet.js +9 -0
- package/lib-esm/multiplicity/checkMultiplet.js.map +1 -0
- package/lib-esm/multiplicity/checkMultiplicity.js +13 -0
- package/lib-esm/multiplicity/checkMultiplicity.js.map +1 -0
- package/lib-esm/multiplicity/findMultiplet.js +8 -0
- package/lib-esm/multiplicity/findMultiplet.js.map +1 -0
- package/lib-esm/{utilities → multiplicity}/joinPatterns.js +3 -3
- package/lib-esm/multiplicity/joinPatterns.js.map +1 -0
- package/lib-esm/multiplicity/splitPatterns.js.map +1 -0
- package/lib-esm/multiplicity/translateMultiplet.js +10 -0
- package/lib-esm/multiplicity/translateMultiplet.js.map +1 -0
- package/lib-esm/ranges/rangesToACS.js +1 -0
- package/lib-esm/ranges/rangesToACS.js.map +1 -1
- package/lib-esm/signal/signalJoinCouplings.js +7 -6
- package/lib-esm/signal/signalJoinCouplings.js.map +1 -1
- package/lib-esm/signal/signalMultiplicityPattern.js +6 -2
- package/lib-esm/signal/signalMultiplicityPattern.js.map +1 -1
- package/lib-esm/utilities/normalizeNucleus.js +18 -0
- package/lib-esm/utilities/normalizeNucleus.js.map +1 -0
- package/lib-esm/utilities/nucleusMap.js +19 -0
- package/lib-esm/utilities/nucleusMap.js.map +1 -0
- package/lib-esm/utilities/resurrectRange.js +1 -1
- package/lib-esm/utilities/resurrectRange.js.map +1 -1
- package/lib-esm/utilities/selectACSPattern.js +10 -0
- package/lib-esm/utilities/selectACSPattern.js.map +1 -0
- package/lib-esm/xyz/Data2D.js +2 -0
- package/lib-esm/xyz/Data2D.js.map +1 -0
- package/lib-esm/xyz/util/formatZone.js.map +1 -1
- package/lib-esm/xyz/util/padData.js +31 -0
- package/lib-esm/xyz/util/padData.js.map +1 -0
- package/lib-esm/xyz/xyzAutoSignalsPicking.js +163 -0
- package/lib-esm/xyz/xyzAutoSignalsPicking.js.map +1 -0
- package/lib-esm/xyz/xyzAutoZonesPicking.js +2 -188
- package/lib-esm/xyz/xyzAutoZonesPicking.js.map +1 -1
- package/package.json +1 -1
- package/src/constants/MultiplicityPatterns.ts +4 -1
- package/src/constants/couplingPatterns.ts +9 -0
- package/src/index.ts +7 -1
- package/src/multiplicity/checkMultiplet.ts +11 -0
- package/src/multiplicity/checkMultiplicity.ts +21 -0
- package/src/multiplicity/findMultiplet.ts +8 -0
- package/src/{utilities → multiplicity}/joinPatterns.ts +9 -3
- package/src/multiplicity/translateMultiplet.ts +11 -0
- package/src/ranges/rangesToACS.ts +1 -0
- package/src/signal/signalJoinCouplings.ts +12 -5
- package/src/signal/signalMultiplicityPattern.ts +9 -2
- package/src/utilities/normalizeNucleus.ts +24 -0
- package/src/utilities/nucleusMap.ts +40 -0
- package/src/utilities/resurrectRange.ts +1 -1
- package/src/utilities/selectACSPattern.ts +10 -0
- package/src/xyz/Data2D.ts +7 -0
- package/src/xyz/util/formatZone.ts +2 -1
- package/src/xyz/util/padData.ts +37 -0
- package/src/xyz/xyzAutoSignalsPicking.ts +309 -0
- package/src/xyz/xyzAutoZonesPicking.ts +2 -276
- package/lib/utilities/joinPatterns.d.ts +0 -1
- package/lib/utilities/joinPatterns.js.map +0 -1
- package/lib/utilities/splitPatterns.js.map +0 -1
- package/lib-esm/utilities/joinPatterns.js.map +0 -1
- package/lib-esm/utilities/splitPatterns.js.map +0 -1
- /package/lib/{utilities → multiplicity}/splitPatterns.d.ts +0 -0
- /package/lib/{utilities → multiplicity}/splitPatterns.js +0 -0
- /package/lib-esm/{utilities → multiplicity}/splitPatterns.js +0 -0
- /package/src/{utilities → multiplicity}/splitPatterns.ts +0 -0
|
@@ -1,193 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Matrix } from 'ml-matrix';
|
|
3
|
-
import * as convolution from 'ml-matrix-convolution';
|
|
4
|
-
import * as matrixPeakFinders from 'ml-matrix-peaks-finder';
|
|
5
|
-
import simpleClustering from 'ml-simple-clustering';
|
|
6
|
-
import { addMissingIDs } from '../peaks/util/addMissingIDs';
|
|
7
|
-
import { determineRealTop } from '../peaks/util/determineRealTop';
|
|
8
|
-
import { getKernel } from '../peaks/util/getKernel';
|
|
9
|
-
import * as PeakOptimizer from '../peaks/util/peakOptimizer';
|
|
1
|
+
import { xyzAutoSignalsPicking } from '..';
|
|
10
2
|
import { formatZones } from './util/formatZone';
|
|
11
|
-
const smallFilter = [
|
|
12
|
-
[0, 0, 1, 2, 2, 2, 1, 0, 0],
|
|
13
|
-
[0, 1, 4, 7, 7, 7, 4, 1, 0],
|
|
14
|
-
[1, 4, 5, 3, 0, 3, 5, 4, 1],
|
|
15
|
-
[2, 7, 3, -12, -23, -12, 3, 7, 2],
|
|
16
|
-
[2, 7, 0, -23, -40, -23, 0, 7, 2],
|
|
17
|
-
[2, 7, 3, -12, -23, -12, 3, 7, 2],
|
|
18
|
-
[1, 4, 5, 3, 0, 3, 5, 4, 1],
|
|
19
|
-
[0, 1, 3, 7, 7, 7, 3, 1, 0],
|
|
20
|
-
[0, 0, 1, 2, 2, 2, 1, 0, 0],
|
|
21
|
-
];
|
|
22
3
|
export function xyzAutoZonesPicking(spectraData, options) {
|
|
23
|
-
|
|
24
|
-
if (!Array.isArray(observedFrequencies) &&
|
|
25
|
-
!ArrayBuffer.isView(observedFrequencies)) {
|
|
26
|
-
throw new Error('observedFrequencies is mandatory');
|
|
27
|
-
}
|
|
28
|
-
thresholdFactor = thresholdFactor === 0 ? 1 : Math.abs(thresholdFactor);
|
|
29
|
-
let nbPoints = spectraData.z[0].length;
|
|
30
|
-
let nbSubSpectra = spectraData.z.length;
|
|
31
|
-
if (nbSubSpectra < sizeToPad) {
|
|
32
|
-
spectraData = padData(spectraData, { width: sizeToPad });
|
|
33
|
-
nbPoints = spectraData.z[0].length;
|
|
34
|
-
nbSubSpectra = spectraData.z.length;
|
|
35
|
-
}
|
|
36
|
-
let absoluteData = new Float64Array(nbPoints * nbSubSpectra);
|
|
37
|
-
let originalData = new Float64Array(nbPoints * nbSubSpectra);
|
|
38
|
-
for (let iSubSpectra = 0; iSubSpectra < nbSubSpectra; iSubSpectra++) {
|
|
39
|
-
let spectrum = spectraData.z[iSubSpectra];
|
|
40
|
-
for (let iCol = 0; iCol < nbPoints; iCol++) {
|
|
41
|
-
let index = iSubSpectra * nbPoints + iCol;
|
|
42
|
-
absoluteData[index] = Math.abs(spectrum[iCol]);
|
|
43
|
-
originalData[index] = spectrum[iCol]; //@todo pensar si se puede evitar originalData
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
const kernel = kernelOptions ? getKernel(kernelOptions) : smallFilter;
|
|
47
|
-
let convolutedSpectrum = convolutionByFFT
|
|
48
|
-
? convolution.fft(absoluteData, kernel, {
|
|
49
|
-
rows: nbSubSpectra,
|
|
50
|
-
cols: nbPoints,
|
|
51
|
-
})
|
|
52
|
-
: convolution.direct(absoluteData, kernel, {
|
|
53
|
-
rows: nbSubSpectra,
|
|
54
|
-
cols: nbPoints,
|
|
55
|
-
});
|
|
56
|
-
let peaksMC1 = matrixPeakFinders.findPeaks2DRegion(absoluteData, {
|
|
57
|
-
originalData,
|
|
58
|
-
filteredData: convolutedSpectrum,
|
|
59
|
-
rows: nbSubSpectra,
|
|
60
|
-
cols: nbPoints,
|
|
61
|
-
nStdDev: thresholdFactor,
|
|
62
|
-
});
|
|
63
|
-
if (clean) {
|
|
64
|
-
// Remove peaks with less than x% of the intensity of the highest peak
|
|
65
|
-
peaksMC1 = PeakOptimizer.clean(peaksMC1, maxPercentCutOff);
|
|
66
|
-
}
|
|
67
|
-
let signals = createSignals2D(addMissingIDs(peaksMC1), {
|
|
68
|
-
nRows: nbSubSpectra,
|
|
69
|
-
nCols: nbPoints,
|
|
70
|
-
minX: spectraData.minX,
|
|
71
|
-
maxX: spectraData.maxX,
|
|
72
|
-
minY: spectraData.minY,
|
|
73
|
-
maxY: spectraData.maxY,
|
|
74
|
-
absoluteData,
|
|
75
|
-
originalData,
|
|
76
|
-
tolerances,
|
|
77
|
-
nuclei,
|
|
78
|
-
observedFrequencies,
|
|
79
|
-
realTopDetection,
|
|
80
|
-
});
|
|
81
|
-
if (enhanceSymmetry) {
|
|
82
|
-
signals = PeakOptimizer.enhanceSymmetry(signals);
|
|
83
|
-
}
|
|
4
|
+
const signals = xyzAutoSignalsPicking(spectraData, options);
|
|
84
5
|
return formatZones(signals);
|
|
85
6
|
}
|
|
86
|
-
function createSignals2D(peaks, options) {
|
|
87
|
-
let { nCols, nRows, absoluteData, originalData, observedFrequencies, tolerances, nuclei, realTopDetection, minY, maxY, minX, maxX, } = options;
|
|
88
|
-
let [nucleusX, nucleusY] = nuclei;
|
|
89
|
-
let [toleranceX, toleranceY] = tolerances;
|
|
90
|
-
let [observeFrequencyX, observeFrequencyY] = observedFrequencies;
|
|
91
|
-
let dy = (maxY - minY) / (nRows - 1);
|
|
92
|
-
let dx = (maxX - minX) / (nCols - 1);
|
|
93
|
-
if (realTopDetection) {
|
|
94
|
-
peaks = determineRealTop(peaks, {
|
|
95
|
-
nCols,
|
|
96
|
-
absoluteData,
|
|
97
|
-
originalData,
|
|
98
|
-
minX,
|
|
99
|
-
maxX,
|
|
100
|
-
minY,
|
|
101
|
-
maxY,
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
for (let i = peaks.length - 1; i >= 0; i--) {
|
|
105
|
-
let { x, y } = peaks[i];
|
|
106
|
-
peaks[i].x = minX + dx * x;
|
|
107
|
-
peaks[i].y = minY + dy * y;
|
|
108
|
-
peaks[i].minX = minX + dx * peaks[i].minX;
|
|
109
|
-
peaks[i].minY = minY + dy * peaks[i].minY;
|
|
110
|
-
peaks[i].maxX = minX + dx * peaks[i].maxX;
|
|
111
|
-
peaks[i].maxY = minY + dy * peaks[i].maxY;
|
|
112
|
-
// Still having problems to correctly detect peaks on those areas. So I'm removing everything there.
|
|
113
|
-
}
|
|
114
|
-
// The connectivity matrix is an square and symmetric matrix, so we'll only store the upper diagonal in an
|
|
115
|
-
// array like form
|
|
116
|
-
let connectivity = [];
|
|
117
|
-
for (let i = 0; i < peaks.length; i++) {
|
|
118
|
-
for (let j = i; j < peaks.length; j++) {
|
|
119
|
-
if (Math.abs(peaks[i].x - peaks[j].x) * observeFrequencyX < toleranceX &&
|
|
120
|
-
Math.abs(peaks[i].y - peaks[j].y) * observeFrequencyY < toleranceY) {
|
|
121
|
-
// 24*24Hz We cannot distinguish peaks with less than 20 Hz of separation
|
|
122
|
-
connectivity.push(1);
|
|
123
|
-
}
|
|
124
|
-
else {
|
|
125
|
-
connectivity.push(0);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
let clusters = simpleClustering(connectivity);
|
|
130
|
-
let signals = [];
|
|
131
|
-
if (clusters) {
|
|
132
|
-
for (const cluster of clusters) {
|
|
133
|
-
let signal = {
|
|
134
|
-
id: generateID(),
|
|
135
|
-
x: {
|
|
136
|
-
delta: 0,
|
|
137
|
-
nucleus: nucleusX,
|
|
138
|
-
resolution: dx,
|
|
139
|
-
},
|
|
140
|
-
y: {
|
|
141
|
-
delta: 0,
|
|
142
|
-
nucleus: nucleusY,
|
|
143
|
-
resolution: dy,
|
|
144
|
-
},
|
|
145
|
-
};
|
|
146
|
-
let peaks2D = [];
|
|
147
|
-
let sumZ = 0;
|
|
148
|
-
for (let jPeak = 0; jPeak < cluster.length; jPeak++) {
|
|
149
|
-
if (cluster[jPeak] === 1) {
|
|
150
|
-
peaks2D.push(peaks[jPeak]);
|
|
151
|
-
signal.x.delta += peaks[jPeak].x * peaks[jPeak].z;
|
|
152
|
-
signal.y.delta += peaks[jPeak].y * peaks[jPeak].z;
|
|
153
|
-
sumZ += peaks[jPeak].z;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
signal.x.delta /= sumZ;
|
|
157
|
-
signal.y.delta /= sumZ;
|
|
158
|
-
signal.peaks = peaks2D;
|
|
159
|
-
signals.push(signal);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
return signals;
|
|
163
|
-
}
|
|
164
|
-
function padData(spectraData, options) {
|
|
165
|
-
let { minX, maxX, minY, maxY } = spectraData;
|
|
166
|
-
const width = options.width;
|
|
167
|
-
let nbPoints = spectraData.z[0].length;
|
|
168
|
-
let nbSubSpectra = spectraData.z.length;
|
|
169
|
-
let yInterval = (maxY - minY) / (nbSubSpectra - 1);
|
|
170
|
-
let xInterval = (maxX - minX) / (nbPoints - 1);
|
|
171
|
-
let yDiff = width - nbSubSpectra;
|
|
172
|
-
let xDiff = Math.max(width - nbPoints, 0);
|
|
173
|
-
if (xDiff % 2)
|
|
174
|
-
xDiff++;
|
|
175
|
-
if (yDiff % 2)
|
|
176
|
-
yDiff++;
|
|
177
|
-
let xOffset = xDiff / 2;
|
|
178
|
-
let yOffset = yDiff / 2;
|
|
179
|
-
let newMatrix = Matrix.zeros(nbSubSpectra + yDiff, nbPoints + xDiff);
|
|
180
|
-
for (let i = 0; i < nbSubSpectra; i++) {
|
|
181
|
-
for (let j = 0; j < nbPoints; j++) {
|
|
182
|
-
newMatrix.set(i + yOffset, j + xOffset, spectraData.z[i][j]);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
return {
|
|
186
|
-
z: newMatrix.to2DArray(),
|
|
187
|
-
minX: minX - xOffset * xInterval,
|
|
188
|
-
maxX: maxX + xOffset * xInterval,
|
|
189
|
-
minY: minY - yOffset * yInterval,
|
|
190
|
-
maxY: maxY + yOffset * yInterval,
|
|
191
|
-
};
|
|
192
|
-
}
|
|
193
7
|
//# sourceMappingURL=xyzAutoZonesPicking.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xyzAutoZonesPicking.js","sourceRoot":"","sources":["../../src/xyz/xyzAutoZonesPicking.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"xyzAutoZonesPicking.js","sourceRoot":"","sources":["../../src/xyz/xyzAutoZonesPicking.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,IAAI,CAAC;AAK3C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAmEhD,MAAM,UAAU,mBAAmB,CACjC,WAAmB,EACnB,OAAmC;IAEnC,MAAM,OAAO,GAAG,qBAAqB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC5D,OAAO,WAAW,CAAC,OAAO,CAAC,CAAC;AAC9B,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
export interface MultipletDefinition {
|
|
2
2
|
label: string;
|
|
3
3
|
value: string;
|
|
4
|
+
acs?: string;
|
|
4
5
|
names: string[];
|
|
5
6
|
multiplicity: number | null;
|
|
6
7
|
}
|
|
7
8
|
|
|
8
9
|
export const MultiplicityPatterns: MultipletDefinition[] = [
|
|
9
10
|
{ label: 'singlet', value: 's', multiplicity: 1, names: ['br s'] },
|
|
10
|
-
{ label: 'doublet', value: 'd', multiplicity: 2, names: [] },
|
|
11
11
|
{ label: 'triplet', value: 't', multiplicity: 3, names: [] },
|
|
12
|
+
{ label: 'doublet', value: 'd', multiplicity: 2, names: [] },
|
|
12
13
|
{ label: 'quartet', value: 'q', multiplicity: 4, names: [] },
|
|
13
14
|
{
|
|
14
15
|
label: 'quintet',
|
|
15
16
|
value: 'i',
|
|
17
|
+
acs: 'quint',
|
|
16
18
|
multiplicity: 5,
|
|
17
19
|
names: ['quint', 'qui', 'qnt', 'pentet', 'pnt', 'pent'],
|
|
18
20
|
},
|
|
@@ -25,6 +27,7 @@ export const MultiplicityPatterns: MultipletDefinition[] = [
|
|
|
25
27
|
{
|
|
26
28
|
label: 'septet',
|
|
27
29
|
value: 'p',
|
|
30
|
+
acs: 'sept',
|
|
28
31
|
multiplicity: 7,
|
|
29
32
|
names: ['sept', 'spt', 'heptet', 'hpt', 'hept'],
|
|
30
33
|
},
|
|
@@ -1,3 +1,12 @@
|
|
|
1
1
|
import { MultiplicityPatterns } from './MultiplicityPatterns';
|
|
2
2
|
|
|
3
|
+
MultiplicityPatterns.sort((a, b) =>
|
|
4
|
+
a.multiplicity !== null && b.multiplicity !== null
|
|
5
|
+
? a.multiplicity - b.multiplicity
|
|
6
|
+
: Number.MAX_SAFE_INTEGER,
|
|
7
|
+
);
|
|
3
8
|
export const couplingPatterns = MultiplicityPatterns.map((m) => m.value);
|
|
9
|
+
|
|
10
|
+
export const couplingACSPatterns = MultiplicityPatterns.map(
|
|
11
|
+
(m) => m.acs || m.value,
|
|
12
|
+
);
|
package/src/index.ts
CHANGED
|
@@ -29,7 +29,6 @@ export * from './signals/signalsToFID';
|
|
|
29
29
|
export * from './signal/signalJoinCouplings';
|
|
30
30
|
|
|
31
31
|
export * from './utilities/resurrect';
|
|
32
|
-
export * from './utilities/splitPatterns';
|
|
33
32
|
export * from './utilities/rangeFromSignal';
|
|
34
33
|
export * from './utilities/getFrequency';
|
|
35
34
|
|
|
@@ -38,6 +37,7 @@ export * from './xy/xyAutoRangesPicking';
|
|
|
38
37
|
export * from './xy/xyPeaksOptimization';
|
|
39
38
|
|
|
40
39
|
export * from './xyz/xyzAutoZonesPicking';
|
|
40
|
+
export * from './xyz/xyzAutoSignalsPicking';
|
|
41
41
|
export * from './xyz/xyzJResAnalyzer';
|
|
42
42
|
|
|
43
43
|
export * from './databases/getDatabase';
|
|
@@ -51,6 +51,12 @@ export * from './apodization/apodization';
|
|
|
51
51
|
|
|
52
52
|
export * from './constants/MultiplicityPatterns';
|
|
53
53
|
|
|
54
|
+
export * from './multiplicity/findMultiplet';
|
|
55
|
+
export * from './multiplicity/splitPatterns';
|
|
56
|
+
export * from './multiplicity/checkMultiplet';
|
|
57
|
+
export * from './multiplicity/checkMultiplicity';
|
|
58
|
+
export * from './multiplicity/translateMultiplet';
|
|
59
|
+
|
|
54
60
|
export type { NMRSignal1D } from './signals/NMRSignal1D';
|
|
55
61
|
export type { NMRSignal2D, Signal2DProjection } from './xyz/NMRSignal2D';
|
|
56
62
|
export type { NMRRange } from './xy/NMRRange';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { findMultiplet } from './findMultiplet';
|
|
2
|
+
|
|
3
|
+
export function checkMultiplet(string: string, rejected: string[] = []) {
|
|
4
|
+
const multiplet = findMultiplet(string);
|
|
5
|
+
return (
|
|
6
|
+
multiplet &&
|
|
7
|
+
!rejected.includes(multiplet.label) &&
|
|
8
|
+
!rejected.includes(multiplet.value) &&
|
|
9
|
+
!multiplet.names.some((name) => rejected.includes(name))
|
|
10
|
+
);
|
|
11
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { splitPatterns } from '..';
|
|
2
|
+
|
|
3
|
+
import { checkMultiplet } from './checkMultiplet';
|
|
4
|
+
|
|
5
|
+
export function checkMultiplicity(
|
|
6
|
+
multiplicity: string,
|
|
7
|
+
rejected: string[] = [],
|
|
8
|
+
) {
|
|
9
|
+
// options to determine whether a massive (m), for example, should be considered as rejected multiplicity
|
|
10
|
+
if (multiplicity === undefined || multiplicity.length === 0) {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const multiplets = splitPatterns(multiplicity);
|
|
15
|
+
const allIncluded = multiplets.join('').length === multiplicity.length;
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
allIncluded &&
|
|
19
|
+
multiplets.every((_multiplet) => checkMultiplet(_multiplet, rejected))
|
|
20
|
+
);
|
|
21
|
+
}
|
|
@@ -1,7 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
couplingACSPatterns,
|
|
3
|
+
couplingPatterns,
|
|
4
|
+
} from '../constants/couplingPatterns';
|
|
2
5
|
import { couplingValues } from '../constants/couplingValues';
|
|
3
6
|
|
|
4
|
-
export function joinPatterns(
|
|
7
|
+
export function joinPatterns(
|
|
8
|
+
patterns: string[],
|
|
9
|
+
options?: { acsFormat?: boolean },
|
|
10
|
+
) {
|
|
5
11
|
const sum = patterns.reduce((sum, pattern) => {
|
|
6
12
|
if (isNaN(couplingValues[pattern])) {
|
|
7
13
|
throw new Error(
|
|
@@ -15,5 +21,5 @@ export function joinPatterns(patterns: string[]) {
|
|
|
15
21
|
throw new Error("The joined pattern doesn't exist");
|
|
16
22
|
}
|
|
17
23
|
|
|
18
|
-
return couplingPatterns[sum];
|
|
24
|
+
return options?.acsFormat ? couplingACSPatterns[sum] : couplingPatterns[sum];
|
|
19
25
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { findMultiplet } from './findMultiplet';
|
|
2
|
+
|
|
3
|
+
export function translateMultiplet(name: string) {
|
|
4
|
+
const multiplet = findMultiplet(name);
|
|
5
|
+
|
|
6
|
+
if (!multiplet) {
|
|
7
|
+
throw new Error(`multiplet ${name} is not supported`);
|
|
8
|
+
}
|
|
9
|
+
const { value, label } = multiplet;
|
|
10
|
+
return name === label ? value : label;
|
|
11
|
+
}
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import sum from 'ml-array-sum';
|
|
2
2
|
|
|
3
|
+
import { joinPatterns } from '../multiplicity/joinPatterns';
|
|
3
4
|
import type { Jcoupling } from '../signals/Jcoupling';
|
|
4
5
|
import type { NMRSignal1D } from '../signals/NMRSignal1D';
|
|
5
6
|
import type { MakeMandatory } from '../utilities/MakeMandatory';
|
|
6
|
-
import { joinPatterns } from '../utilities/joinPatterns';
|
|
7
7
|
|
|
8
8
|
export interface SignalJoinCouplingsOptions {
|
|
9
|
+
/**
|
|
10
|
+
* if it is true the coupling pattens will normalized to ACS suggested values
|
|
11
|
+
* @default false
|
|
12
|
+
*/
|
|
13
|
+
acsFormat?: boolean;
|
|
9
14
|
/**
|
|
10
15
|
* tolerance to merge the couplings
|
|
11
16
|
* @default 0.05
|
|
@@ -52,24 +57,25 @@ export function signalJoinCouplings(
|
|
|
52
57
|
signal: NMRSignal1D,
|
|
53
58
|
options: SignalJoinCouplingsOptions = {},
|
|
54
59
|
) {
|
|
55
|
-
const { tolerance = 0.05, ignoreDiaIDs = false } = options;
|
|
60
|
+
const { tolerance = 0.05, ignoreDiaIDs = false, acsFormat = false } = options;
|
|
56
61
|
|
|
57
62
|
if (!signal.js || signal.js.length < 2) return signal;
|
|
58
63
|
|
|
59
64
|
if (ignoreDiaIDs) {
|
|
60
65
|
checkJs(signal);
|
|
61
|
-
return groupJCouplings(signal, areThanClose, tolerance);
|
|
66
|
+
return groupJCouplings(signal, areThanClose, { tolerance, acsFormat });
|
|
62
67
|
} else {
|
|
63
68
|
checkJsAndDiaID(signal);
|
|
64
|
-
return groupJCouplings(signal, takeCareDiaIDs, tolerance);
|
|
69
|
+
return groupJCouplings(signal, takeCareDiaIDs, { tolerance, acsFormat });
|
|
65
70
|
}
|
|
66
71
|
}
|
|
67
72
|
|
|
68
73
|
function groupJCouplings(
|
|
69
74
|
signal: Signal1DWidthJs,
|
|
70
75
|
comparator: any,
|
|
71
|
-
tolerance: number,
|
|
76
|
+
options: { tolerance: number; acsFormat?: boolean },
|
|
72
77
|
) {
|
|
78
|
+
const { tolerance, acsFormat } = options;
|
|
73
79
|
signal.js.sort((a, b) => b.coupling - a.coupling);
|
|
74
80
|
|
|
75
81
|
let currentGroup = [signal.js[0]];
|
|
@@ -118,6 +124,7 @@ function groupJCouplings(
|
|
|
118
124
|
group
|
|
119
125
|
.filter((group) => group.multiplicity)
|
|
120
126
|
.map((group) => group.multiplicity) as string[],
|
|
127
|
+
{ acsFormat },
|
|
121
128
|
);
|
|
122
129
|
|
|
123
130
|
let newJ: Jcoupling = {
|
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
import type { NMRSignal1D } from '../signals/NMRSignal1D';
|
|
2
|
+
import { selectACSPattern } from '../utilities/selectACSPattern';
|
|
2
3
|
/**
|
|
3
4
|
* Return
|
|
4
5
|
* @param {*} signal
|
|
5
6
|
*/
|
|
6
7
|
|
|
7
|
-
export function signalMultiplicityPattern(
|
|
8
|
+
export function signalMultiplicityPattern(
|
|
9
|
+
signal: NMRSignal1D,
|
|
10
|
+
options?: { acsFormat?: boolean },
|
|
11
|
+
) {
|
|
8
12
|
let js = signal.js;
|
|
9
13
|
let pattern = '';
|
|
10
14
|
if (js && js.length > 0) {
|
|
11
15
|
for (let coupling of js) {
|
|
12
|
-
|
|
16
|
+
const { multiplicity = '' } = coupling;
|
|
17
|
+
pattern += options?.acsFormat
|
|
18
|
+
? selectACSPattern(multiplicity)
|
|
19
|
+
: multiplicity;
|
|
13
20
|
}
|
|
14
21
|
} else if (signal.delta) {
|
|
15
22
|
pattern = '';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Nuclei, gyromagneticRatio } from 'gyromagnetic-ratio';
|
|
2
|
+
|
|
3
|
+
import { NucleusName, nucleusSymbolMap } from './nucleusMap';
|
|
4
|
+
|
|
5
|
+
export function normilizeNucleus(name: string) {
|
|
6
|
+
if (gyromagneticRatio[name as Nuclei]) {
|
|
7
|
+
return name;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const massNumber = name.replace(/\D/g, '');
|
|
11
|
+
const atomName = name.replace(/\d*\W*/g, '').toLowerCase();
|
|
12
|
+
|
|
13
|
+
const nucleusName =
|
|
14
|
+
atomName.length > 1
|
|
15
|
+
? nucleusSymbolMap[atomName as NucleusName]
|
|
16
|
+
: atomName.toUpperCase();
|
|
17
|
+
|
|
18
|
+
const symbol = `${massNumber}${nucleusName}`;
|
|
19
|
+
if (!gyromagneticRatio[symbol as Nuclei]) {
|
|
20
|
+
throw new Error(`nucleus ${name} is not supported`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return symbol;
|
|
24
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export type NucleusName =
|
|
2
|
+
| 'proton'
|
|
3
|
+
| 'hydrogen'
|
|
4
|
+
| 'helium'
|
|
5
|
+
| 'lithium'
|
|
6
|
+
| 'carbon'
|
|
7
|
+
| 'nitrogen'
|
|
8
|
+
| 'oxigen'
|
|
9
|
+
| 'fluorine'
|
|
10
|
+
| 'sodium'
|
|
11
|
+
| 'aluminum'
|
|
12
|
+
| 'silicon'
|
|
13
|
+
| 'phosphorus'
|
|
14
|
+
| 'iron'
|
|
15
|
+
| 'copper'
|
|
16
|
+
| 'zinc'
|
|
17
|
+
| 'xenon';
|
|
18
|
+
|
|
19
|
+
export type NucleusSymbolMap = {
|
|
20
|
+
[key in NucleusName]: string;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const nucleusSymbolMap: NucleusSymbolMap = {
|
|
24
|
+
proton: '1H',
|
|
25
|
+
hydrogen: 'H',
|
|
26
|
+
helium: 'He',
|
|
27
|
+
lithium: 'Li',
|
|
28
|
+
carbon: 'C',
|
|
29
|
+
nitrogen: 'N',
|
|
30
|
+
oxigen: 'O',
|
|
31
|
+
fluorine: 'F',
|
|
32
|
+
sodium: 'Na',
|
|
33
|
+
aluminum: 'Al',
|
|
34
|
+
silicon: 'Si',
|
|
35
|
+
phosphorus: 'P',
|
|
36
|
+
iron: 'Fe',
|
|
37
|
+
copper: 'Cu',
|
|
38
|
+
zinc: 'Zn',
|
|
39
|
+
xenon: 'Xe',
|
|
40
|
+
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import { splitPatterns } from '../multiplicity/splitPatterns';
|
|
1
2
|
import type { NMRSignal1D } from '../signals/NMRSignal1D';
|
|
2
3
|
import type { NMRRange } from '../xy/NMRRange';
|
|
3
4
|
|
|
4
5
|
import { rangeFromSignal } from './rangeFromSignal';
|
|
5
6
|
import { splitParenthesis } from './splitParenthesis';
|
|
6
|
-
import { splitPatterns } from './splitPatterns';
|
|
7
7
|
|
|
8
8
|
export function resurrectRange(part: string, options: any = {}) {
|
|
9
9
|
const { nucleus = '1h', frequency = 400 } = options;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { couplingACSPatterns } from '..';
|
|
2
|
+
import { couplingValues } from '../constants/couplingValues';
|
|
3
|
+
|
|
4
|
+
export function selectACSPattern(pattern: string) {
|
|
5
|
+
const multiplicity = couplingValues[pattern];
|
|
6
|
+
if (!multiplicity) {
|
|
7
|
+
throw new Error(`multiplicity pattern ${pattern} is not supported`);
|
|
8
|
+
}
|
|
9
|
+
return couplingACSPatterns[multiplicity];
|
|
10
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { v4 as generateID } from '@lukeed/uuid';
|
|
2
2
|
|
|
3
|
-
import { NMRSignal2DWithID
|
|
3
|
+
import { NMRSignal2DWithID } from '../xyzAutoSignalsPicking';
|
|
4
|
+
import { NMRZoneWithID } from '../xyzAutoZonesPicking';
|
|
4
5
|
|
|
5
6
|
export function formatZones(signals: NMRSignal2DWithID[]) {
|
|
6
7
|
let zones: NMRZoneWithID[] = [];
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import Matrix from 'ml-matrix';
|
|
2
|
+
|
|
3
|
+
import { Data2D } from '../Data2D';
|
|
4
|
+
|
|
5
|
+
export function padData(spectraData: Data2D, options: { width: number }) {
|
|
6
|
+
let { minX, maxX, minY, maxY } = spectraData;
|
|
7
|
+
|
|
8
|
+
const width = options.width;
|
|
9
|
+
|
|
10
|
+
let nbPoints = spectraData.z[0].length;
|
|
11
|
+
let nbSubSpectra = spectraData.z.length;
|
|
12
|
+
|
|
13
|
+
let yInterval = (maxY - minY) / (nbSubSpectra - 1);
|
|
14
|
+
let xInterval = (maxX - minX) / (nbPoints - 1);
|
|
15
|
+
|
|
16
|
+
let yDiff = width - nbSubSpectra;
|
|
17
|
+
let xDiff = Math.max(width - nbPoints, 0);
|
|
18
|
+
if (xDiff % 2) xDiff++;
|
|
19
|
+
if (yDiff % 2) yDiff++;
|
|
20
|
+
|
|
21
|
+
let xOffset = xDiff / 2;
|
|
22
|
+
let yOffset = yDiff / 2;
|
|
23
|
+
let newMatrix = Matrix.zeros(nbSubSpectra + yDiff, nbPoints + xDiff);
|
|
24
|
+
for (let i = 0; i < nbSubSpectra; i++) {
|
|
25
|
+
for (let j = 0; j < nbPoints; j++) {
|
|
26
|
+
newMatrix.set(i + yOffset, j + xOffset, spectraData.z[i][j]);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
z: newMatrix.to2DArray(),
|
|
32
|
+
minX: minX - xOffset * xInterval,
|
|
33
|
+
maxX: maxX + xOffset * xInterval,
|
|
34
|
+
minY: minY - yOffset * yInterval,
|
|
35
|
+
maxY: maxY + yOffset * yInterval,
|
|
36
|
+
};
|
|
37
|
+
}
|