nmr-processing 7.4.3 → 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/getAssignments.js +1 -1
- package/lib/assignment/getAssignments.js.map +1 -1
- package/lib/assignment/utils/getAssignment/checkIDs.d.ts +1 -1
- package/lib/assignment/utils/getAssignment/checkIDs.js.map +1 -1
- package/lib/databases/getDatabase.d.ts +6 -1
- package/lib/databases/getDatabase.js +13 -3
- package/lib/databases/getDatabase.js.map +1 -1
- package/lib/index.d.ts +4 -2
- package/lib/index.js +3 -1
- package/lib/index.js.map +1 -1
- package/lib/peaks/NMRPeak1D.d.ts +0 -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 +3 -0
- package/lib/peaks/solventSuppression.js +155 -0
- package/lib/peaks/solventSuppression.js.map +1 -0
- package/lib/peaks/util/jAnalyzer.d.ts +1 -1
- package/lib/peaks/util/jAnalyzer.js +3 -2
- package/lib/peaks/util/jAnalyzer.js.map +1 -1
- package/lib/prediction/predictAllSpectra.d.ts +22 -4
- package/lib/prediction/predictAllSpectra.js +102 -16
- package/lib/prediction/predictAllSpectra.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/ranges/rangesToXY.js +27 -3
- package/lib/ranges/rangesToXY.js.map +1 -1
- package/lib/signals/addDummySignals.d.ts +2 -0
- package/lib/signals/addDummySignals.js +56 -0
- package/lib/signals/addDummySignals.js.map +1 -0
- package/lib/signals/hackSignalsToXY.js +2 -48
- package/lib/signals/hackSignalsToXY.js.map +1 -1
- package/lib/signals/simulation/simulate1D.d.ts +1 -39
- package/lib/signals/simulation/simulate1D.js +13 -240
- package/lib/signals/simulation/simulate1D.js.map +1 -1
- package/lib/signals/simulation/simulateXYPeaks.d.ts +47 -0
- package/lib/signals/simulation/simulateXYPeaks.js +246 -0
- package/lib/signals/simulation/simulateXYPeaks.js.map +1 -0
- package/lib/utilities/getFrequency.d.ts +1 -1
- package/lib/utilities/getFrequency.js +4 -4
- package/lib/utilities/getFrequency.js.map +1 -1
- package/lib/xyz/NMRSignal2D.d.ts +3 -3
- 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/getAssignments.js +1 -1
- package/lib-esm/assignment/getAssignments.js.map +1 -1
- package/lib-esm/assignment/utils/getAssignment/checkIDs.js.map +1 -1
- package/lib-esm/databases/getDatabase.js +13 -3
- package/lib-esm/databases/getDatabase.js.map +1 -1
- package/lib-esm/index.js +3 -1
- 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 +151 -0
- package/lib-esm/peaks/solventSuppression.js.map +1 -0
- package/lib-esm/peaks/util/jAnalyzer.js +3 -2
- package/lib-esm/peaks/util/jAnalyzer.js.map +1 -1
- package/lib-esm/prediction/predictAllSpectra.js +102 -16
- package/lib-esm/prediction/predictAllSpectra.js.map +1 -1
- package/lib-esm/ranges/markSolventSignal.js +100 -0
- package/lib-esm/ranges/markSolventSignal.js.map +1 -0
- package/lib-esm/ranges/rangesToXY.js +27 -3
- package/lib-esm/ranges/rangesToXY.js.map +1 -1
- package/lib-esm/signals/addDummySignals.js +52 -0
- package/lib-esm/signals/addDummySignals.js.map +1 -0
- package/lib-esm/signals/hackSignalsToXY.js +2 -48
- package/lib-esm/signals/hackSignalsToXY.js.map +1 -1
- package/lib-esm/signals/simulation/simulate1D.js +14 -238
- package/lib-esm/signals/simulation/simulate1D.js.map +1 -1
- package/lib-esm/signals/simulation/simulateXYPeaks.js +239 -0
- package/lib-esm/signals/simulation/simulateXYPeaks.js.map +1 -0
- package/lib-esm/utilities/getFrequency.js +1 -1
- package/lib-esm/utilities/getFrequency.js.map +1 -1
- 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 +14 -12
- package/src/assignment/getAssignments.ts +1 -1
- package/src/assignment/utils/getAssignment/checkIDs.ts +1 -1
- package/src/databases/getDatabase.ts +19 -2
- package/src/index.ts +5 -2
- package/src/peaks/NMRPeak1D.ts +0 -1
- package/src/peaks/peaksToRanges.ts +1 -1
- package/src/peaks/solventSuppression.ts +209 -0
- package/src/peaks/util/jAnalyzer.ts +5 -3
- package/src/prediction/predictAllSpectra.ts +151 -14
- package/src/ranges/markSolventSignal.ts +121 -0
- package/src/ranges/rangesToXY.ts +33 -4
- package/src/signals/addDummySignals.ts +77 -0
- package/src/signals/hackSignalsToXY.ts +2 -72
- package/src/signals/simulation/simulate1D.ts +14 -319
- package/src/signals/simulation/simulateXYPeaks.ts +332 -0
- package/src/utilities/getFrequency.ts +1 -1
- package/src/xyz/NMRSignal2D.ts +3 -3
- package/src/xyz/util/formatZone.ts +36 -0
- package/src/xyz/xyzAutoZonesPicking.ts +1 -35
- package/src/xyz/xyzJResAnalyzer.ts +14 -7
- package/lib/constants/gyromagneticRatio.d.ts +0 -6
- package/lib/constants/gyromagneticRatio.js +0 -26
- package/lib/constants/gyromagneticRatio.js.map +0 -1
- package/lib-esm/constants/gyromagneticRatio.js +0 -23
- package/lib-esm/constants/gyromagneticRatio.js.map +0 -1
- package/src/constants/gyromagneticRatio.ts +0 -49
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import { FromTo, PointXY } from 'cheminfo-types';
|
|
1
2
|
import type { Molecule } from 'openchemlib';
|
|
2
3
|
|
|
4
|
+
import { signals2DToZ } from '../signals/signals2DToZ';
|
|
3
5
|
import { OptionsSignalsToXY, signalsToXY } from '../signals/signalsToXY';
|
|
6
|
+
import { getFrequency } from '../utilities/getFrequency';
|
|
4
7
|
|
|
5
8
|
import { PredictAllOptions, predictAll } from './predictAll';
|
|
6
9
|
/**
|
|
@@ -10,39 +13,173 @@ import { PredictAllOptions, predictAll } from './predictAll';
|
|
|
10
13
|
* @param options
|
|
11
14
|
*/
|
|
12
15
|
|
|
16
|
+
interface OneDOptions {
|
|
17
|
+
proton: FromTo;
|
|
18
|
+
carbon: FromTo;
|
|
19
|
+
nbPoints: number;
|
|
20
|
+
lineWidth: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface TwoDOptions {
|
|
24
|
+
from: PointXY;
|
|
25
|
+
to: PointXY;
|
|
26
|
+
nbPoints: PointXY;
|
|
27
|
+
}
|
|
28
|
+
interface SimulationOptions {
|
|
29
|
+
frequency: number;
|
|
30
|
+
oneD?: Partial<OneDOptions>;
|
|
31
|
+
twoD?: Partial<TwoDOptions>;
|
|
32
|
+
}
|
|
33
|
+
interface PredictAllSpectraOptions {
|
|
34
|
+
prediction?: PredictAllOptions;
|
|
35
|
+
simulation?: SimulationOptions;
|
|
36
|
+
}
|
|
37
|
+
|
|
13
38
|
export async function predictAllSpectra(
|
|
14
39
|
molecule: Molecule,
|
|
15
|
-
options: {
|
|
16
|
-
prediction?: PredictAllOptions;
|
|
17
|
-
simulation?: OptionsSignalsToXY;
|
|
18
|
-
} = {},
|
|
40
|
+
options: PredictAllSpectraOptions = {},
|
|
19
41
|
) {
|
|
20
|
-
const
|
|
42
|
+
const {
|
|
43
|
+
simulation: simulationOptions = { oneD: {}, twoD: {} } as SimulationOptions,
|
|
44
|
+
prediction: predictionOptions = {},
|
|
45
|
+
} = options;
|
|
46
|
+
|
|
47
|
+
const predictions = await predictAll(molecule, predictionOptions);
|
|
21
48
|
const spectra: any[] = [];
|
|
22
49
|
const result = { spectra, molecules: [{ molfile: predictions.molfile }] };
|
|
23
|
-
|
|
50
|
+
|
|
51
|
+
const oneDOptions: OneDOptions = {
|
|
52
|
+
...{
|
|
53
|
+
proton: { from: 0, to: 14 },
|
|
54
|
+
carbon: { from: 0, to: 200 },
|
|
55
|
+
nbPoints: 4098,
|
|
56
|
+
lineWidth: 0.03,
|
|
57
|
+
},
|
|
58
|
+
...(simulationOptions.oneD || {}),
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const twoDOptions: TwoDOptions = {
|
|
62
|
+
...{
|
|
63
|
+
from: { x: oneDOptions.proton.from, y: oneDOptions.carbon.from },
|
|
64
|
+
to: { x: oneDOptions.proton.to, y: oneDOptions.carbon.to },
|
|
65
|
+
nbPoints: { x: 1024, y: 1024 },
|
|
66
|
+
},
|
|
67
|
+
...(simulationOptions.twoD || {}),
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
for (const experiment in predictions) {
|
|
71
|
+
switch (experiment) {
|
|
72
|
+
case 'carbon':
|
|
73
|
+
case 'proton': {
|
|
74
|
+
spectra.push(
|
|
75
|
+
get1DSpectrum(predictions[experiment], {
|
|
76
|
+
nbPoints: oneDOptions.nbPoints,
|
|
77
|
+
lineWidth: oneDOptions.lineWidth,
|
|
78
|
+
...oneDOptions[experiment],
|
|
79
|
+
experiment,
|
|
80
|
+
frequency: simulationOptions.frequency,
|
|
81
|
+
}),
|
|
82
|
+
);
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
case 'cosy':
|
|
86
|
+
case 'hsqc':
|
|
87
|
+
case 'hmbc': {
|
|
88
|
+
spectra.push(
|
|
89
|
+
get2DSpectrum(predictions[experiment], {
|
|
90
|
+
...twoDOptions,
|
|
91
|
+
experiment,
|
|
92
|
+
frequency: simulationOptions.frequency,
|
|
93
|
+
}),
|
|
94
|
+
);
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
default:
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
24
101
|
|
|
25
102
|
return result;
|
|
26
103
|
}
|
|
27
104
|
|
|
28
|
-
|
|
29
|
-
|
|
105
|
+
type Get2DSpectrumOptions = TwoDOptions & {
|
|
106
|
+
experiment: string;
|
|
107
|
+
frequency: number;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
function get2DSpectrum(prediction: any, options: Get2DSpectrumOptions) {
|
|
111
|
+
const { signals, zones, nuclei } = prediction;
|
|
112
|
+
const { frequency: baseFrequency, experiment } = options;
|
|
113
|
+
|
|
114
|
+
const width = get2DWidth(nuclei);
|
|
115
|
+
const frequency = calculateFrequency(nuclei, baseFrequency);
|
|
116
|
+
|
|
117
|
+
const spectrumData = signals2DToZ(signals, {
|
|
118
|
+
...options,
|
|
119
|
+
width,
|
|
120
|
+
factor: 3,
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
const spectrum = {
|
|
124
|
+
data: { ...spectrumData, noise: 0.01 },
|
|
125
|
+
info: {
|
|
126
|
+
nucleus: nuclei,
|
|
127
|
+
originFrequency: frequency,
|
|
128
|
+
baseFrequency: frequency,
|
|
129
|
+
pulseSequence: experiment,
|
|
130
|
+
experiment: '2d',
|
|
131
|
+
},
|
|
132
|
+
zones: { values: zones },
|
|
133
|
+
};
|
|
134
|
+
return spectrum;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function get2DWidth(nucleus: string[]) {
|
|
138
|
+
return nucleus[0] === nucleus[1] ? 0.02 : { x: 0.02, y: 0.2133 };
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
type Get1DSpectrumOptions = OptionsSignalsToXY & { experiment: string };
|
|
142
|
+
|
|
143
|
+
function get1DSpectrum(prediction: any, options: Get1DSpectrumOptions) {
|
|
144
|
+
const { frequency = 400, experiment } = options;
|
|
145
|
+
const { signals, nucleus } = prediction;
|
|
146
|
+
const realFrequency = calculateFrequency(nucleus, frequency) as number;
|
|
147
|
+
const { x, y } = signalsToXY(signals, {
|
|
148
|
+
...options,
|
|
149
|
+
frequency: realFrequency,
|
|
150
|
+
});
|
|
30
151
|
const spectrum = {
|
|
31
|
-
id: '',
|
|
32
152
|
// todo Array.from is temporary for the developement
|
|
33
153
|
data: { x: Array.from(x), re: Array.from(y), im: null },
|
|
34
154
|
info: {
|
|
35
155
|
nucleus: prediction.nucleus,
|
|
36
156
|
dimension: 1,
|
|
37
|
-
originFrequency:
|
|
38
|
-
baseFrequency:
|
|
157
|
+
originFrequency: realFrequency,
|
|
158
|
+
baseFrequency: realFrequency,
|
|
39
159
|
pulseSequence: 'prediction',
|
|
40
|
-
experiment
|
|
160
|
+
experiment,
|
|
41
161
|
isFt: true,
|
|
42
162
|
},
|
|
43
|
-
|
|
44
|
-
//ranges: { values: prediction.ranges },
|
|
163
|
+
ranges: { values: prediction.ranges },
|
|
45
164
|
};
|
|
46
165
|
|
|
47
166
|
return spectrum;
|
|
48
167
|
}
|
|
168
|
+
|
|
169
|
+
function calculateFrequency(
|
|
170
|
+
nucleus: string | string[],
|
|
171
|
+
frequency: number,
|
|
172
|
+
): number | string {
|
|
173
|
+
if (typeof nucleus === 'string') {
|
|
174
|
+
return getFrequency(nucleus, { nucleus: '1H', frequency });
|
|
175
|
+
} else {
|
|
176
|
+
if (nucleus[0] === nucleus[1]) {
|
|
177
|
+
return `${frequency},${frequency}`;
|
|
178
|
+
} else {
|
|
179
|
+
return `${frequency},${getFrequency(nucleus[1], {
|
|
180
|
+
nucleus: nucleus[0],
|
|
181
|
+
frequency,
|
|
182
|
+
})}`;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
@@ -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
|
+
}
|
package/src/ranges/rangesToXY.ts
CHANGED
|
@@ -49,13 +49,21 @@ function checkForSignals(
|
|
|
49
49
|
if (!range.signals) throw new Error('range has not signals');
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
+
|
|
53
|
+
const defaultFromTo = (nucleus = '') => {
|
|
54
|
+
switch (nucleus.toUpperCase()) {
|
|
55
|
+
case '13C':
|
|
56
|
+
return { from: -5, to: 206 };
|
|
57
|
+
default:
|
|
58
|
+
return { from: -0.5, to: 10.5 };
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
|
|
52
62
|
export function rangesToXY(ranges: NMRRange[], options: any = {}) {
|
|
53
63
|
checkForSignals(ranges);
|
|
54
64
|
let {
|
|
55
65
|
frequency = 400,
|
|
56
66
|
lineWidth = 1,
|
|
57
|
-
from = 0,
|
|
58
|
-
to = 10,
|
|
59
67
|
nbPoints = 16 * 1024,
|
|
60
68
|
shape = { kind: 'gaussian' },
|
|
61
69
|
} = options;
|
|
@@ -66,9 +74,10 @@ export function rangesToXY(ranges: NMRRange[], options: any = {}) {
|
|
|
66
74
|
}
|
|
67
75
|
};
|
|
68
76
|
|
|
77
|
+
const { from, to } = getFromTo(ranges, options);
|
|
69
78
|
const spectrumOptions = {
|
|
70
|
-
from,
|
|
71
79
|
to,
|
|
80
|
+
from,
|
|
72
81
|
nbPoints,
|
|
73
82
|
shape,
|
|
74
83
|
lineWidth,
|
|
@@ -139,7 +148,7 @@ function peaksOfMultiplet(delta: number, options: any) {
|
|
|
139
148
|
const {
|
|
140
149
|
frequency,
|
|
141
150
|
lineWidth,
|
|
142
|
-
intensities = [1, 2, 5, 4, 5,
|
|
151
|
+
intensities = [1, 2, 5, 4, 5, 7, 5, 4, 5, 2, 1],
|
|
143
152
|
} = options;
|
|
144
153
|
|
|
145
154
|
const lineWidthPpm = lineWidth / frequency;
|
|
@@ -182,3 +191,23 @@ function normalizeSpectrum(
|
|
|
182
191
|
}
|
|
183
192
|
}
|
|
184
193
|
}
|
|
194
|
+
|
|
195
|
+
function getFromTo(ranges: NMRRange[], options: any) {
|
|
196
|
+
const { from: defaultFrom, to: defaultTo } = defaultFromTo(options.nucleus);
|
|
197
|
+
|
|
198
|
+
let rangesFrom = Number.MAX_SAFE_INTEGER;
|
|
199
|
+
let rangesTo = Number.MIN_SAFE_INTEGER;
|
|
200
|
+
for (const range of ranges) {
|
|
201
|
+
for (const signal of range.signals || []) {
|
|
202
|
+
if (rangesFrom > signal.delta) rangesFrom = signal.delta;
|
|
203
|
+
if (rangesTo < signal.delta) rangesTo = signal.delta;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const {
|
|
208
|
+
from = Math.min(rangesFrom - 0.5, defaultFrom),
|
|
209
|
+
to = Math.max(rangesTo + 0.5, defaultTo),
|
|
210
|
+
} = options;
|
|
211
|
+
|
|
212
|
+
return { from, to };
|
|
213
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { couplingPatterns } from '../constants/couplingPatterns';
|
|
2
|
+
|
|
3
|
+
import { NMRSignal1D } from './NMRSignal1D';
|
|
4
|
+
import type { Jcoupling } from './jcoupling';
|
|
5
|
+
|
|
6
|
+
export function addDummySignals(signals: NMRSignal1D[]) {
|
|
7
|
+
let newSignals: NMRSignal1D[] = JSON.parse(JSON.stringify(signals));
|
|
8
|
+
|
|
9
|
+
signals.forEach((signal, s) => {
|
|
10
|
+
const { js: jCouplings = [], atoms: signalAssignment = [s] } = signal;
|
|
11
|
+
|
|
12
|
+
let { newCouplings, tempSignals } = checkCouplings(
|
|
13
|
+
jCouplings,
|
|
14
|
+
newSignals,
|
|
15
|
+
signalAssignment,
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
if (tempSignals.length > 0) newSignals.push(...tempSignals);
|
|
19
|
+
|
|
20
|
+
newSignals[s].js = newCouplings;
|
|
21
|
+
newSignals[s].atoms = signalAssignment;
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
return newSignals.sort((a, b) => a.delta - b.delta);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function checkCouplings(
|
|
28
|
+
jCouplings: Jcoupling[],
|
|
29
|
+
signals: NMRSignal1D[],
|
|
30
|
+
signalAssignment: number[],
|
|
31
|
+
) {
|
|
32
|
+
let newSignalAssignment = signals.length - 1;
|
|
33
|
+
let tempSignals: NMRSignal1D[] = [];
|
|
34
|
+
const newCouplings = jCouplings.reduce<Jcoupling[]>(
|
|
35
|
+
(newCouplings, jCoupling) => {
|
|
36
|
+
const { atoms = [], multiplicity, coupling } = jCoupling;
|
|
37
|
+
if (atoms.length === 0) {
|
|
38
|
+
if (coupling && multiplicity) {
|
|
39
|
+
let tempCouplings: Jcoupling[] = [];
|
|
40
|
+
const nbLinks = couplingPatterns.indexOf(multiplicity);
|
|
41
|
+
for (let i = 0; i < nbLinks; i++) {
|
|
42
|
+
newSignalAssignment++;
|
|
43
|
+
tempCouplings.push({
|
|
44
|
+
coupling,
|
|
45
|
+
atoms: [newSignalAssignment],
|
|
46
|
+
});
|
|
47
|
+
tempSignals.push(
|
|
48
|
+
formatSignal(coupling, [newSignalAssignment], signalAssignment),
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
} else {
|
|
52
|
+
newCouplings.push(jCoupling);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return newCouplings;
|
|
56
|
+
},
|
|
57
|
+
[],
|
|
58
|
+
);
|
|
59
|
+
return { newCouplings, tempSignals };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function formatSignal(
|
|
63
|
+
coupling: number,
|
|
64
|
+
newSignalAssignment: number[],
|
|
65
|
+
signalAssignment: number[],
|
|
66
|
+
) {
|
|
67
|
+
return {
|
|
68
|
+
delta: 100000,
|
|
69
|
+
atoms: newSignalAssignment,
|
|
70
|
+
js: [
|
|
71
|
+
{
|
|
72
|
+
coupling,
|
|
73
|
+
atoms: signalAssignment,
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
};
|
|
77
|
+
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import { couplingPatterns } from '../constants/couplingPatterns';
|
|
2
|
-
|
|
3
1
|
import type { NMRSignal1D } from './NMRSignal1D';
|
|
4
|
-
import
|
|
2
|
+
import { addDummySignals } from './addDummySignals';
|
|
5
3
|
import { OptionsSignalsToXY, signalsToXY } from './signalsToXY';
|
|
6
4
|
|
|
7
5
|
/**
|
|
@@ -13,74 +11,6 @@ export function hackSignalsToXY(
|
|
|
13
11
|
signals: NMRSignal1D[],
|
|
14
12
|
options: OptionsSignalsToXY = {},
|
|
15
13
|
) {
|
|
16
|
-
let newSignals =
|
|
17
|
-
|
|
18
|
-
signals.forEach((signal, s) => {
|
|
19
|
-
const { js: jCouplings = [], atoms: signalAssignment = [s] } = signal;
|
|
20
|
-
|
|
21
|
-
let { newCouplings, tempSignals } = checkCouplings(
|
|
22
|
-
jCouplings,
|
|
23
|
-
newSignals,
|
|
24
|
-
signalAssignment,
|
|
25
|
-
);
|
|
26
|
-
|
|
27
|
-
if (tempSignals.length > 0) newSignals.push(...tempSignals);
|
|
28
|
-
|
|
29
|
-
newSignals[s].js = newCouplings;
|
|
30
|
-
newSignals[s].atoms = signalAssignment;
|
|
31
|
-
});
|
|
32
|
-
|
|
14
|
+
let newSignals = addDummySignals(signals);
|
|
33
15
|
return signalsToXY(newSignals, options);
|
|
34
16
|
}
|
|
35
|
-
|
|
36
|
-
function checkCouplings(
|
|
37
|
-
jCouplings: Jcoupling[],
|
|
38
|
-
signals: NMRSignal1D[],
|
|
39
|
-
signalAssignment: number[],
|
|
40
|
-
) {
|
|
41
|
-
let newSignalAssignment = signals.length - 1;
|
|
42
|
-
let tempSignals: NMRSignal1D[] = [];
|
|
43
|
-
const newCouplings = jCouplings.reduce<Jcoupling[]>(
|
|
44
|
-
(newCouplings, jCoupling) => {
|
|
45
|
-
const { atoms = [], multiplicity, coupling } = jCoupling;
|
|
46
|
-
if (atoms.length === 0) {
|
|
47
|
-
if (coupling && multiplicity) {
|
|
48
|
-
let tempCouplings: Jcoupling[] = [];
|
|
49
|
-
const nbLinks = couplingPatterns.indexOf(multiplicity);
|
|
50
|
-
for (let i = 0; i < nbLinks; i++) {
|
|
51
|
-
newSignalAssignment++;
|
|
52
|
-
tempCouplings.push({
|
|
53
|
-
coupling,
|
|
54
|
-
atoms: [newSignalAssignment],
|
|
55
|
-
});
|
|
56
|
-
tempSignals.push(
|
|
57
|
-
formatSignal(coupling, [newSignalAssignment], signalAssignment),
|
|
58
|
-
);
|
|
59
|
-
}
|
|
60
|
-
} else {
|
|
61
|
-
newCouplings.push(jCoupling);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
return newCouplings;
|
|
65
|
-
},
|
|
66
|
-
[],
|
|
67
|
-
);
|
|
68
|
-
return { newCouplings, tempSignals };
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function formatSignal(
|
|
72
|
-
coupling: number,
|
|
73
|
-
newSignalAssignment: number[],
|
|
74
|
-
signalAssignment: number[],
|
|
75
|
-
) {
|
|
76
|
-
return {
|
|
77
|
-
delta: 100000,
|
|
78
|
-
atoms: newSignalAssignment,
|
|
79
|
-
js: [
|
|
80
|
-
{
|
|
81
|
-
coupling,
|
|
82
|
-
atoms: signalAssignment,
|
|
83
|
-
},
|
|
84
|
-
],
|
|
85
|
-
};
|
|
86
|
-
}
|