nmr-processing 7.1.0 → 7.4.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/get13CAssignments.d.ts +3 -3
- package/lib/assignment/get13CAssignments.js.map +1 -1
- package/lib/assignment/get1HAssignments.d.ts +3 -3
- package/lib/assignment/get1HAssignments.js.map +1 -1
- package/lib/assignment/getAssignments.d.ts +81 -0
- package/lib/assignment/getAssignments.js +44 -0
- package/lib/assignment/getAssignments.js.map +1 -0
- package/lib/assignment/utils/buildAssignments.d.ts +4 -4
- package/lib/assignment/utils/buildAssignments.js.map +1 -1
- package/lib/assignment/utils/createMapPossibleAssignments.d.ts +2 -2
- package/lib/assignment/utils/exploreTreeRec.d.ts +3 -3
- package/lib/assignment/utils/exploreTreeRec.js.map +1 -1
- package/lib/assignment/utils/getAssignment/buildAssignments.d.ts +72 -0
- package/lib/assignment/utils/getAssignment/buildAssignments.js +205 -0
- package/lib/assignment/utils/getAssignment/buildAssignments.js.map +1 -0
- package/lib/assignment/utils/getAssignment/checkIDs.d.ts +23 -0
- package/lib/assignment/utils/getAssignment/checkIDs.js +57 -0
- package/lib/assignment/utils/getAssignment/checkIDs.js.map +1 -0
- package/lib/assignment/utils/getAssignment/createMapPossibleAssignment.d.ts +15 -0
- package/lib/assignment/utils/getAssignment/createMapPossibleAssignment.js +55 -0
- package/lib/assignment/utils/getAssignment/createMapPossibleAssignment.js.map +1 -0
- package/lib/assignment/utils/getAssignment/exploreTree.d.ts +22 -0
- package/lib/assignment/utils/getAssignment/exploreTree.js +93 -0
- package/lib/assignment/utils/getAssignment/exploreTree.js.map +1 -0
- package/lib/assignment/utils/getAssignment/formatData.d.ts +14 -0
- package/lib/assignment/utils/getAssignment/formatData.js +20 -0
- package/lib/assignment/utils/getAssignment/formatData.js.map +1 -0
- package/lib/assignment/utils/getAssignment/getIntegrationOfAttachedProtons.d.ts +3 -0
- package/lib/assignment/utils/getAssignment/getIntegrationOfAttachedProtons.js +14 -0
- package/lib/assignment/utils/getAssignment/getIntegrationOfAttachedProtons.js.map +1 -0
- package/lib/assignment/utils/getAssignment/getTargetsAndCorrelations.d.ts +18 -0
- package/lib/assignment/utils/getAssignment/getTargetsAndCorrelations.js +37 -0
- package/lib/assignment/utils/getAssignment/getTargetsAndCorrelations.js.map +1 -0
- package/lib/assignment/utils/getAssignment/getWorkFlow.d.ts +19 -0
- package/lib/assignment/utils/getAssignment/getWorkFlow.js +52 -0
- package/lib/assignment/utils/getAssignment/getWorkFlow.js.map +1 -0
- package/lib/assignment/utils/getAssignment/groupCarbonTargetByIntegrationZone.d.ts +7 -0
- package/lib/assignment/utils/getAssignment/groupCarbonTargetByIntegrationZone.js +43 -0
- package/lib/assignment/utils/getAssignment/groupCarbonTargetByIntegrationZone.js.map +1 -0
- package/lib/assignment/utils/getAssignment/isSpectraData1D.d.ts +2 -0
- package/lib/assignment/utils/getAssignment/isSpectraData1D.js +8 -0
- package/lib/assignment/utils/getAssignment/isSpectraData1D.js.map +1 -0
- package/lib/assignment/utils/getAssignment/partialScore.d.ts +13 -0
- package/lib/assignment/utils/getAssignment/partialScore.js +221 -0
- package/lib/assignment/utils/getAssignment/partialScore.js.map +1 -0
- package/lib/assignment/utils/getAssignment/searchIndices.d.ts +6 -0
- package/lib/assignment/utils/getAssignment/searchIndices.js +21 -0
- package/lib/assignment/utils/getAssignment/searchIndices.js.map +1 -0
- package/lib/assignment/utils/partialScore.d.ts +2 -2
- package/lib/constants/gyromagneticRatio.d.ts +5 -19
- package/lib/constants/gyromagneticRatio.js +2 -3
- package/lib/constants/gyromagneticRatio.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.js +1 -0
- package/lib/peaks/peaksToRanges.js.map +1 -1
- package/lib/prediction/utils/predict2D.d.ts +0 -2
- package/lib/prediction/utils/predict2D.js +13 -12
- package/lib/prediction/utils/predict2D.js.map +1 -1
- package/lib/signals/signals2DToZ.d.ts +1 -0
- package/lib/signals/signals2DToZ.js +19 -4
- package/lib/signals/signals2DToZ.js.map +1 -1
- package/lib/utilities/getFrequency.d.ts +21 -0
- package/lib/utilities/getFrequency.js +30 -0
- package/lib/utilities/getFrequency.js.map +1 -0
- package/lib-esm/assignment/get13CAssignments.js.map +1 -1
- package/lib-esm/assignment/get1HAssignments.js.map +1 -1
- package/lib-esm/assignment/getAssignments.js +37 -0
- package/lib-esm/assignment/getAssignments.js.map +1 -0
- package/lib-esm/assignment/utils/buildAssignments.js.map +1 -1
- package/lib-esm/assignment/utils/exploreTreeRec.js.map +1 -1
- package/lib-esm/assignment/utils/getAssignment/buildAssignments.js +198 -0
- package/lib-esm/assignment/utils/getAssignment/buildAssignments.js.map +1 -0
- package/lib-esm/assignment/utils/getAssignment/checkIDs.js +48 -0
- package/lib-esm/assignment/utils/getAssignment/checkIDs.js.map +1 -0
- package/lib-esm/assignment/utils/getAssignment/createMapPossibleAssignment.js +51 -0
- package/lib-esm/assignment/utils/getAssignment/createMapPossibleAssignment.js.map +1 -0
- package/lib-esm/assignment/utils/getAssignment/exploreTree.js +89 -0
- package/lib-esm/assignment/utils/getAssignment/exploreTree.js.map +1 -0
- package/lib-esm/assignment/utils/getAssignment/formatData.js +16 -0
- package/lib-esm/assignment/utils/getAssignment/formatData.js.map +1 -0
- package/lib-esm/assignment/utils/getAssignment/getIntegrationOfAttachedProtons.js +10 -0
- package/lib-esm/assignment/utils/getAssignment/getIntegrationOfAttachedProtons.js.map +1 -0
- package/lib-esm/assignment/utils/getAssignment/getTargetsAndCorrelations.js +33 -0
- package/lib-esm/assignment/utils/getAssignment/getTargetsAndCorrelations.js.map +1 -0
- package/lib-esm/assignment/utils/getAssignment/getWorkFlow.js +50 -0
- package/lib-esm/assignment/utils/getAssignment/getWorkFlow.js.map +1 -0
- package/lib-esm/assignment/utils/getAssignment/groupCarbonTargetByIntegrationZone.js +41 -0
- package/lib-esm/assignment/utils/getAssignment/groupCarbonTargetByIntegrationZone.js.map +1 -0
- package/lib-esm/assignment/utils/getAssignment/isSpectraData1D.js +4 -0
- package/lib-esm/assignment/utils/getAssignment/isSpectraData1D.js.map +1 -0
- package/lib-esm/assignment/utils/getAssignment/partialScore.js +214 -0
- package/lib-esm/assignment/utils/getAssignment/partialScore.js.map +1 -0
- package/lib-esm/assignment/utils/getAssignment/searchIndices.js +17 -0
- package/lib-esm/assignment/utils/getAssignment/searchIndices.js.map +1 -0
- package/lib-esm/constants/gyromagneticRatio.js +1 -2
- package/lib-esm/constants/gyromagneticRatio.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 -0
- package/lib-esm/peaks/peaksToRanges.js.map +1 -1
- package/lib-esm/prediction/utils/predict2D.js +13 -12
- package/lib-esm/prediction/utils/predict2D.js.map +1 -1
- package/lib-esm/signals/signals2DToZ.js +19 -4
- package/lib-esm/signals/signals2DToZ.js.map +1 -1
- package/lib-esm/utilities/getFrequency.js +26 -0
- package/lib-esm/utilities/getFrequency.js.map +1 -0
- package/package.json +10 -9
- package/src/assignment/get13CAssignments.ts +2 -2
- package/src/assignment/get1HAssignments.ts +2 -2
- package/src/assignment/getAssignments.ts +149 -0
- package/src/assignment/utils/buildAssignments.ts +4 -4
- package/src/assignment/utils/createMapPossibleAssignments.ts +2 -2
- package/src/assignment/utils/exploreTreeRec.ts +5 -5
- package/src/assignment/utils/getAssignment/buildAssignments.ts +339 -0
- package/src/assignment/utils/getAssignment/checkIDs.ts +76 -0
- package/src/assignment/utils/getAssignment/createMapPossibleAssignment.ts +85 -0
- package/src/assignment/utils/getAssignment/data/correlations.js +713 -0
- package/src/assignment/utils/getAssignment/data/predictions.js +34 -0
- package/src/assignment/utils/getAssignment/exploreTree.ts +171 -0
- package/src/assignment/utils/getAssignment/formatData.ts +35 -0
- package/src/assignment/utils/getAssignment/getIntegrationOfAttachedProtons.ts +16 -0
- package/src/assignment/utils/getAssignment/getTargetsAndCorrelations.ts +63 -0
- package/src/assignment/utils/getAssignment/getWorkFlow.ts +72 -0
- package/src/assignment/utils/getAssignment/groupCarbonTargetByIntegrationZone.ts +55 -0
- package/src/assignment/utils/getAssignment/isSpectraData1D.ts +7 -0
- package/src/assignment/utils/getAssignment/partialScore.ts +308 -0
- package/src/assignment/utils/getAssignment/searchIndices.ts +19 -0
- package/src/assignment/utils/partialScore.ts +2 -2
- package/src/constants/gyromagneticRatio.ts +25 -1
- package/src/index.ts +2 -0
- package/src/ml-tree-set.d.ts +1 -1
- package/src/peaks/peaksToRanges.ts +1 -0
- package/src/prediction/utils/predict2D.ts +16 -16
- package/src/signals/signals2DToZ.ts +29 -5
- package/src/utilities/getFrequency.ts +47 -0
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
import { getCorrelationDelta } from 'nmr-correlation';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
AtomTypes,
|
|
5
|
+
InfoByAtomType,
|
|
6
|
+
Partial,
|
|
7
|
+
PredictionsByAtomType,
|
|
8
|
+
RestrictionByCS,
|
|
9
|
+
} from './buildAssignments';
|
|
10
|
+
import {
|
|
11
|
+
CorrelationWithIntegration,
|
|
12
|
+
TargetsByAtomType,
|
|
13
|
+
} from './getTargetsAndCorrelations';
|
|
14
|
+
import groupCarbonTargetByIntegrationZone from './groupCarbonTargetByIntegrationZone';
|
|
15
|
+
|
|
16
|
+
export interface PartialScoreOptions {
|
|
17
|
+
diaIDPeerPossibleAssignment: { [key: string]: string[] };
|
|
18
|
+
restrictionByCS: RestrictionByCS;
|
|
19
|
+
infoByAtomTypes: InfoByAtomType;
|
|
20
|
+
correlations: CorrelationWithIntegration[];
|
|
21
|
+
predictions: PredictionsByAtomType;
|
|
22
|
+
targets: TargetsByAtomType;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
interface ObjectStringArray {
|
|
26
|
+
[key: string]: string[];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface ObjectObjectStringArray {
|
|
30
|
+
[key: string]: ObjectStringArray;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function partialScore(partial: Partial, props: PartialScoreOptions) {
|
|
34
|
+
const {
|
|
35
|
+
diaIDPeerPossibleAssignment,
|
|
36
|
+
infoByAtomTypes,
|
|
37
|
+
restrictionByCS,
|
|
38
|
+
predictions,
|
|
39
|
+
targets,
|
|
40
|
+
correlations,
|
|
41
|
+
} = props;
|
|
42
|
+
|
|
43
|
+
const { tolerance: toleranceCS, useChemicalShiftScore } = restrictionByCS;
|
|
44
|
+
let totalStarts = 0;
|
|
45
|
+
let totalPartial = 0;
|
|
46
|
+
let partialInverse: ObjectObjectStringArray = {};
|
|
47
|
+
let activeDomainOnPrediction: { [key: string]: number[] } = {};
|
|
48
|
+
const atomTypes = Object.keys(partial) as AtomTypes[];
|
|
49
|
+
for (const atomType of atomTypes) {
|
|
50
|
+
let countStars = 0;
|
|
51
|
+
const { nbAllowedUnAssigned } = infoByAtomTypes[atomType];
|
|
52
|
+
const currentPartialInverse: ObjectStringArray = {};
|
|
53
|
+
const partialAssignment = partial[atomType] || [];
|
|
54
|
+
partialInverse[atomType] = currentPartialInverse;
|
|
55
|
+
activeDomainOnPrediction[atomType] = [];
|
|
56
|
+
totalPartial += partialAssignment.length;
|
|
57
|
+
for (let i = 0; i < partialAssignment.length; i++) {
|
|
58
|
+
const targetID = partialAssignment[i];
|
|
59
|
+
if (targetID && targetID !== '*') {
|
|
60
|
+
activeDomainOnPrediction[atomType].push(i);
|
|
61
|
+
if (!currentPartialInverse[targetID]) {
|
|
62
|
+
currentPartialInverse[targetID] = [];
|
|
63
|
+
}
|
|
64
|
+
currentPartialInverse[targetID].push(
|
|
65
|
+
diaIDPeerPossibleAssignment[atomType][i],
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
if (targetID === '*') countStars++;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (countStars > nbAllowedUnAssigned) return 0;
|
|
72
|
+
totalStarts += countStars;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const activeDomainOnTarget: ObjectStringArray = {};
|
|
76
|
+
for (const atomType in partialInverse) {
|
|
77
|
+
activeDomainOnTarget[atomType] = Object.keys(partialInverse[atomType]);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const valuesActiveDomainOnTarget = Object.values(activeDomainOnTarget);
|
|
81
|
+
if (
|
|
82
|
+
valuesActiveDomainOnTarget.reduce(
|
|
83
|
+
(sum, e) => (e.length === 0 ? sum + 1 : sum),
|
|
84
|
+
0,
|
|
85
|
+
) === valuesActiveDomainOnTarget.length
|
|
86
|
+
) {
|
|
87
|
+
return 0;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const getPredictionByDiaID = getPrediction.bind({}, predictions);
|
|
91
|
+
// check the integration
|
|
92
|
+
const targetByIntegral: {
|
|
93
|
+
atomType: string;
|
|
94
|
+
targetIDs: string[];
|
|
95
|
+
integration: number;
|
|
96
|
+
}[] = [];
|
|
97
|
+
|
|
98
|
+
for (const atomType in partial) {
|
|
99
|
+
if (atomType === 'C' && activeDomainOnTarget[atomType].length > 0) {
|
|
100
|
+
targetByIntegral.push(
|
|
101
|
+
...groupCarbonTargetByIntegrationZone(
|
|
102
|
+
activeDomainOnTarget[atomType],
|
|
103
|
+
targets[atomType],
|
|
104
|
+
correlations,
|
|
105
|
+
),
|
|
106
|
+
);
|
|
107
|
+
} else {
|
|
108
|
+
for (let targetID of activeDomainOnTarget[atomType]) {
|
|
109
|
+
targetByIntegral.push({
|
|
110
|
+
atomType,
|
|
111
|
+
targetIDs: [targetID],
|
|
112
|
+
integration: targets.H[targetID].integration,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
for (const group of targetByIntegral) {
|
|
118
|
+
const { integration, atomType } = group;
|
|
119
|
+
|
|
120
|
+
if (integration === undefined || isNaN(integration)) continue;
|
|
121
|
+
|
|
122
|
+
let total = 0;
|
|
123
|
+
for (let targetID of group.targetIDs) {
|
|
124
|
+
let targetToSource = partialInverse[atomType][targetID];
|
|
125
|
+
for (const diaID of targetToSource) {
|
|
126
|
+
const { prediction, atomType: atomOfPrediction } =
|
|
127
|
+
getPredictionByDiaID(diaID);
|
|
128
|
+
if (atomType === atomOfPrediction) total += prediction.allHydrogens;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
if (total - integration >= 0.5) {
|
|
132
|
+
return 0;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
//chemical shift score
|
|
137
|
+
let count = 1;
|
|
138
|
+
let chemicalShiftScore = 1;
|
|
139
|
+
if (useChemicalShiftScore) {
|
|
140
|
+
chemicalShiftScore = 0;
|
|
141
|
+
count = 0;
|
|
142
|
+
for (const atomType of Object.keys(partial) as AtomTypes[]) {
|
|
143
|
+
const partialPeerAtomType = partial[atomType];
|
|
144
|
+
const targetsPeerAtomType = targets[atomType];
|
|
145
|
+
for (let index = 0; index < partialPeerAtomType.length; index++) {
|
|
146
|
+
const targetID = partialPeerAtomType[index];
|
|
147
|
+
if (targetID && targetID !== '*') {
|
|
148
|
+
count++;
|
|
149
|
+
let diaID = diaIDPeerPossibleAssignment[atomType][index];
|
|
150
|
+
let source = predictions[atomType][diaID];
|
|
151
|
+
let target = targetsPeerAtomType[targetID];
|
|
152
|
+
let error = toleranceCS[atomType];
|
|
153
|
+
// if (source.error) {
|
|
154
|
+
// error = Math.max(source.error, toleranceCS);
|
|
155
|
+
// }
|
|
156
|
+
if (typeof source.delta === 'undefined') {
|
|
157
|
+
// Chemical shift is not a restriction
|
|
158
|
+
chemicalShiftScore += 1;
|
|
159
|
+
} else {
|
|
160
|
+
const targetDelta = getCorrelationDelta(target);
|
|
161
|
+
|
|
162
|
+
if (targetDelta === undefined) {
|
|
163
|
+
throw new Error('correlation has not delta');
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
let diff = Math.abs(source.delta - targetDelta);
|
|
167
|
+
if (diff < error) {
|
|
168
|
+
//@TODO: check for a better discriminant
|
|
169
|
+
chemicalShiftScore += 1;
|
|
170
|
+
} else {
|
|
171
|
+
diff = Math.abs(diff - error);
|
|
172
|
+
chemicalShiftScore += (-0.25 / error) * diff + 1;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
if (count > 0) {
|
|
179
|
+
chemicalShiftScore /= count;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
let scoreOn2D = 0;
|
|
184
|
+
|
|
185
|
+
if (howManyActived(activeDomainOnTarget) > 1) {
|
|
186
|
+
let andConstrains: { [key: string]: number } = {};
|
|
187
|
+
let activeDomain: Array<{ index: number; atomType: AtomTypes }> = [];
|
|
188
|
+
|
|
189
|
+
for (const atomType of Object.keys(
|
|
190
|
+
activeDomainOnPrediction,
|
|
191
|
+
) as AtomTypes[]) {
|
|
192
|
+
activeDomain = activeDomain.concat(
|
|
193
|
+
activeDomainOnPrediction[atomType].map((e) => ({ index: e, atomType })),
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
for (let i = 0; i < activeDomain.length; i++) {
|
|
198
|
+
const { atomType: atomTypeI, index: indexI } = activeDomain[i];
|
|
199
|
+
const predictionI =
|
|
200
|
+
predictions[atomTypeI][diaIDPeerPossibleAssignment[atomTypeI][indexI]];
|
|
201
|
+
for (let j = i + 1; j < activeDomain.length; j++) {
|
|
202
|
+
const { atomType: atomTypeJ, index: indexJ } = activeDomain[j];
|
|
203
|
+
const predictionJ =
|
|
204
|
+
predictions[atomTypeJ][
|
|
205
|
+
diaIDPeerPossibleAssignment[atomTypeJ][indexJ]
|
|
206
|
+
];
|
|
207
|
+
let pathLength = predictionI.pathLength[predictionJ.diaIDIndex];
|
|
208
|
+
let isPossible = pathLength < 5;
|
|
209
|
+
|
|
210
|
+
let partialI = partial[atomTypeI][indexI];
|
|
211
|
+
let partialJ = partial[atomTypeJ][indexJ];
|
|
212
|
+
|
|
213
|
+
if (!partialI || !partialJ) continue;
|
|
214
|
+
|
|
215
|
+
let keyOnTargertMap =
|
|
216
|
+
partialI > partialJ
|
|
217
|
+
? `${partialJ} ${partialI}`
|
|
218
|
+
: `${partialI} ${partialJ}`;
|
|
219
|
+
|
|
220
|
+
let areLinked = checkLinking(
|
|
221
|
+
{
|
|
222
|
+
from: {
|
|
223
|
+
targetID: partialI,
|
|
224
|
+
atomType: atomTypeI,
|
|
225
|
+
},
|
|
226
|
+
to: {
|
|
227
|
+
targetID: partialJ,
|
|
228
|
+
atomType: atomTypeJ,
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
targets,
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
let partialScore2D = isPossible
|
|
235
|
+
? areLinked
|
|
236
|
+
? 1
|
|
237
|
+
: 0
|
|
238
|
+
: !areLinked
|
|
239
|
+
? 1
|
|
240
|
+
: 0;
|
|
241
|
+
|
|
242
|
+
andConstrains[keyOnTargertMap] = andConstrains[keyOnTargertMap]
|
|
243
|
+
? Math.max(andConstrains[keyOnTargertMap], partialScore2D)
|
|
244
|
+
: partialScore2D;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
let sumAnd = 0;
|
|
249
|
+
for (let key in andConstrains) {
|
|
250
|
+
sumAnd += andConstrains[key];
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
scoreOn2D =
|
|
254
|
+
sumAnd / ((activeDomain.length * (activeDomain.length - 1)) / 2);
|
|
255
|
+
}
|
|
256
|
+
const penaltyByStarts = totalStarts / totalPartial;
|
|
257
|
+
if (chemicalShiftScore === 0) return scoreOn2D - penaltyByStarts;
|
|
258
|
+
|
|
259
|
+
if (scoreOn2D === 0) return chemicalShiftScore - penaltyByStarts;
|
|
260
|
+
return (chemicalShiftScore + scoreOn2D) / 2 - penaltyByStarts;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
interface CheckLinkingFromTo {
|
|
264
|
+
from: {
|
|
265
|
+
targetID: string;
|
|
266
|
+
atomType: AtomTypes;
|
|
267
|
+
};
|
|
268
|
+
to: {
|
|
269
|
+
targetID: string;
|
|
270
|
+
atomType: AtomTypes;
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
function checkLinking(
|
|
275
|
+
partials: CheckLinkingFromTo,
|
|
276
|
+
correlations: TargetsByAtomType,
|
|
277
|
+
) {
|
|
278
|
+
const { from, to } = partials;
|
|
279
|
+
if (from.targetID === to.targetID) return true;
|
|
280
|
+
let correlationI = correlations[from.atomType][from.targetID];
|
|
281
|
+
let correlationJ = correlations[to.atomType][to.targetID];
|
|
282
|
+
for (const linkJ of correlationJ.link) {
|
|
283
|
+
for (const link of correlationI.link) {
|
|
284
|
+
if (link.signal.id === linkJ.signal.id) return true;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return false;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
function getPrediction(predictions: PredictionsByAtomType, diaID: string) {
|
|
291
|
+
const atomTypes = Object.keys(predictions) as AtomTypes[];
|
|
292
|
+
for (const atomType of atomTypes) {
|
|
293
|
+
const predictionByAtomType = predictions[atomType];
|
|
294
|
+
if (!predictionByAtomType) throw new Error(`prediction by ${atomType}`);
|
|
295
|
+
if (predictionByAtomType[diaID]) {
|
|
296
|
+
return { atomType, prediction: predictionByAtomType[diaID] };
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
throw new Error(`There is not prediction for ${diaID}`);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
function howManyActived(actived: ObjectStringArray) {
|
|
303
|
+
let sum = 0;
|
|
304
|
+
for (const atom in actived) {
|
|
305
|
+
sum += actived[atom].length;
|
|
306
|
+
}
|
|
307
|
+
return sum;
|
|
308
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { SpectraData } from '../../getAssignments';
|
|
2
|
+
|
|
3
|
+
import { isSpectraData1D } from './isSpectraData1D';
|
|
4
|
+
|
|
5
|
+
export function searchIndices(signalId: string, spectra: SpectraData[]) {
|
|
6
|
+
for (let spectrumIndex = 0; spectrumIndex < spectra.length; spectrumIndex++) {
|
|
7
|
+
const spectrum = spectra[spectrumIndex];
|
|
8
|
+
const data = isSpectraData1D(spectrum) ? spectrum.ranges : spectrum.zones;
|
|
9
|
+
for (let elementIndex = 0; elementIndex < data.length; elementIndex++) {
|
|
10
|
+
const signals = data[elementIndex].signals || [];
|
|
11
|
+
for (let signalIndex = 0; signalIndex < signals.length; signalIndex++) {
|
|
12
|
+
if (signalId === signals[signalIndex].id) {
|
|
13
|
+
return { spectrumIndex, signalIndex, elementIndex };
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
throw new Error(`There is not a signal with ${signalId} ID`);
|
|
19
|
+
}
|
|
@@ -2,11 +2,11 @@ import { Targets } from '../get1HAssignments';
|
|
|
2
2
|
|
|
3
3
|
import type {
|
|
4
4
|
Predictions1Dassignments,
|
|
5
|
-
|
|
5
|
+
RestrictionByCS1D,
|
|
6
6
|
} from './buildAssignments';
|
|
7
7
|
|
|
8
8
|
interface PartialScoreOptions {
|
|
9
|
-
restrictionByCS:
|
|
9
|
+
restrictionByCS: RestrictionByCS1D;
|
|
10
10
|
/**
|
|
11
11
|
* number of allowed unassignment signals
|
|
12
12
|
* @default 0
|
|
@@ -3,7 +3,31 @@
|
|
|
3
3
|
|
|
4
4
|
// TODO: #13 can we have a better source and more digits ? @jwist
|
|
5
5
|
|
|
6
|
-
export
|
|
6
|
+
export type Nuclei =
|
|
7
|
+
| '1H'
|
|
8
|
+
| '2H'
|
|
9
|
+
| '3H'
|
|
10
|
+
| '3He'
|
|
11
|
+
| '7Li'
|
|
12
|
+
| '13C'
|
|
13
|
+
| '14N'
|
|
14
|
+
| '15N'
|
|
15
|
+
| '17O'
|
|
16
|
+
| '19F'
|
|
17
|
+
| '23Na'
|
|
18
|
+
| '27Al'
|
|
19
|
+
| '29Si'
|
|
20
|
+
| '31P'
|
|
21
|
+
| '57Fe'
|
|
22
|
+
| '63Cu'
|
|
23
|
+
| '67Zn'
|
|
24
|
+
| '129Xe';
|
|
25
|
+
|
|
26
|
+
type GyromagneticRatio = {
|
|
27
|
+
[key in Nuclei]: number;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const GYROMAGNETIC_RATIO: GyromagneticRatio = {
|
|
7
31
|
'1H': 267.52218744e6,
|
|
8
32
|
'2H': 41.065e6,
|
|
9
33
|
'3H': 285.3508e6,
|
package/src/index.ts
CHANGED
|
@@ -14,6 +14,7 @@ export * from './prediction/predictAllSpectra';
|
|
|
14
14
|
|
|
15
15
|
export * from './assignment/get1HAssignments';
|
|
16
16
|
export * from './assignment/get13CAssignments';
|
|
17
|
+
export * from './assignment/getAssignments';
|
|
17
18
|
|
|
18
19
|
export * from './ranges/rangesToACS';
|
|
19
20
|
export * from './ranges/rangesToXY';
|
|
@@ -24,6 +25,7 @@ export * from './signals/signals2DToZ';
|
|
|
24
25
|
|
|
25
26
|
export * from './utilities/resurrect';
|
|
26
27
|
export * from './utilities/rangeFromSignal';
|
|
28
|
+
export * from './utilities/getFrequency';
|
|
27
29
|
|
|
28
30
|
export * from './xy/xyAutoPeaksPicking';
|
|
29
31
|
export * from './xy/xyAutoRangesPicking';
|
package/src/ml-tree-set.d.ts
CHANGED
|
@@ -242,6 +242,7 @@ export function peaksToRanges(
|
|
|
242
242
|
delta: signal.delta,
|
|
243
243
|
kind: signal.kind || 'signal',
|
|
244
244
|
multiplicity: signal.multiplicity,
|
|
245
|
+
integration: signal.integralData.value,
|
|
245
246
|
};
|
|
246
247
|
if (keepPeaks) {
|
|
247
248
|
signalResult.peaks = signal.peaks.map((peak) => {
|
|
@@ -94,12 +94,10 @@ export interface PredictOptions {
|
|
|
94
94
|
|
|
95
95
|
export interface Predictions {
|
|
96
96
|
[key: string]: Prediction1D | undefined;
|
|
97
|
-
H?: Prediction1D;
|
|
98
|
-
C?: Prediction1D;
|
|
99
97
|
}
|
|
100
98
|
|
|
101
99
|
type GroupDiastereotopicAtomIDsWithAtomInfo = GroupDiastereotopicAtomIDs & {
|
|
102
|
-
|
|
100
|
+
pathInfo: PathInfo;
|
|
103
101
|
};
|
|
104
102
|
|
|
105
103
|
type PredictHMBCOptionsWithFromTo = MakeMandatory<
|
|
@@ -141,7 +139,7 @@ export async function predict2D(
|
|
|
141
139
|
|
|
142
140
|
let diaIDs = getGroupedDiastereotopicAtomIDs(molecule);
|
|
143
141
|
|
|
144
|
-
const
|
|
142
|
+
const pathsInfo = getPathsInfo(molecule, {
|
|
145
143
|
fromLabel: from,
|
|
146
144
|
toLabel: to,
|
|
147
145
|
minLength,
|
|
@@ -152,7 +150,9 @@ export async function predict2D(
|
|
|
152
150
|
for (let diaID of diaIDs) {
|
|
153
151
|
diaIDswithAtomInfo.push({
|
|
154
152
|
...diaID,
|
|
155
|
-
|
|
153
|
+
pathInfo: JSON.parse(
|
|
154
|
+
JSON.stringify(pathsInfo[diaID.atoms[0]]),
|
|
155
|
+
) as PathInfo,
|
|
156
156
|
});
|
|
157
157
|
}
|
|
158
158
|
|
|
@@ -194,26 +194,25 @@ export async function predict2D(
|
|
|
194
194
|
signalsByDiaID[axis][signal.diaIDs[0]] = signal;
|
|
195
195
|
}
|
|
196
196
|
}
|
|
197
|
-
|
|
198
197
|
let group: { [key: string]: NMRSignal2D } = {};
|
|
199
198
|
for (const diaID of diaIDswithAtomInfo) {
|
|
200
|
-
const
|
|
201
|
-
if (
|
|
199
|
+
const pathInfo = diaID.pathInfo;
|
|
200
|
+
if (pathInfo.paths.length < 1) continue;
|
|
202
201
|
|
|
203
|
-
if (!signalsByDiaID.x[
|
|
202
|
+
if (!signalsByDiaID.x[pathInfo.oclID]) continue;
|
|
204
203
|
|
|
205
|
-
const currentPaths =
|
|
204
|
+
const currentPaths = pathInfo.paths;
|
|
206
205
|
for (const path of currentPaths) {
|
|
207
|
-
if (!signalsByDiaID.y[
|
|
206
|
+
if (!signalsByDiaID.y[pathsInfo[path.to].oclID]) continue;
|
|
208
207
|
|
|
209
208
|
let fromToDiaID: { [key: string]: AtomInfo } = {
|
|
210
|
-
x:
|
|
211
|
-
y:
|
|
209
|
+
x: pathInfo,
|
|
210
|
+
y: pathsInfo[path.to],
|
|
212
211
|
};
|
|
213
212
|
|
|
214
213
|
const key = `${fromToDiaID.x.oclID}-${fromToDiaID.y.oclID}`;
|
|
215
214
|
|
|
216
|
-
if (key === `${
|
|
215
|
+
if (key === `${pathInfo.oclID}-${pathInfo.oclID}` || group[key]) {
|
|
217
216
|
continue;
|
|
218
217
|
}
|
|
219
218
|
|
|
@@ -228,12 +227,13 @@ export async function predict2D(
|
|
|
228
227
|
}
|
|
229
228
|
|
|
230
229
|
signal.peaks = [peak];
|
|
231
|
-
|
|
232
230
|
group[key] = signal as NMRSignal2D;
|
|
233
231
|
}
|
|
234
232
|
}
|
|
235
233
|
|
|
236
|
-
if (includeDiagonal)
|
|
234
|
+
if (includeDiagonal) {
|
|
235
|
+
addSelftCorrelation(group, { paths: pathsInfo, signalsByDiaID });
|
|
236
|
+
}
|
|
237
237
|
|
|
238
238
|
// clusterize signals by distance
|
|
239
239
|
const joinedSignals = Object.values(group);
|
|
@@ -26,6 +26,7 @@ interface Signals2DToZOptions {
|
|
|
26
26
|
* @default 0.02
|
|
27
27
|
*/
|
|
28
28
|
width?: number | XYNumber;
|
|
29
|
+
factor?: number | XYNumber;
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
export interface Peak2DSeries {
|
|
@@ -38,7 +39,13 @@ export function signals2DToZ(
|
|
|
38
39
|
signals: NMRSignal2D[],
|
|
39
40
|
options: Signals2DToZOptions = {},
|
|
40
41
|
) {
|
|
41
|
-
let {
|
|
42
|
+
let {
|
|
43
|
+
from = -1,
|
|
44
|
+
to = 12,
|
|
45
|
+
nbPoints = 512,
|
|
46
|
+
width = 0.02,
|
|
47
|
+
factor = 3,
|
|
48
|
+
} = options;
|
|
42
49
|
|
|
43
50
|
const peaks = signals.reduce<Peak2DSeries>(
|
|
44
51
|
(acc, { x, y }) => {
|
|
@@ -51,7 +58,8 @@ export function signals2DToZ(
|
|
|
51
58
|
);
|
|
52
59
|
|
|
53
60
|
width = ensureXYNumber(width);
|
|
54
|
-
|
|
61
|
+
|
|
62
|
+
return generateSpectrum2D(mergeClosePeaks(peaks), {
|
|
55
63
|
generator: {
|
|
56
64
|
from: ensureXYNumber(from),
|
|
57
65
|
to: ensureXYNumber(to),
|
|
@@ -59,11 +67,27 @@ export function signals2DToZ(
|
|
|
59
67
|
},
|
|
60
68
|
peaks: {
|
|
61
69
|
width,
|
|
70
|
+
factor,
|
|
62
71
|
},
|
|
63
72
|
});
|
|
64
73
|
}
|
|
65
74
|
|
|
66
|
-
function ensureXYNumber(input: number | XYNumber)
|
|
67
|
-
|
|
68
|
-
|
|
75
|
+
function ensureXYNumber(input: number | XYNumber) {
|
|
76
|
+
return typeof input !== 'object' ? { x: input, y: input } : { ...input };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function mergeClosePeaks(peaksIn: Peak2DSeries) {
|
|
80
|
+
let peaks = JSON.parse(JSON.stringify(peaksIn));
|
|
81
|
+
for (let i = 0; i < peaks.x.length; i++) {
|
|
82
|
+
for (let j = i + 1; j < peaks.x.length; j++) {
|
|
83
|
+
if (peaks.x[i] === peaks.x[j] && peaks.y[i] === peaks.y[j]) {
|
|
84
|
+
peaks.z[i] += peaks.z[j];
|
|
85
|
+
peaks.x.splice(j, 1);
|
|
86
|
+
peaks.y.splice(j, 1);
|
|
87
|
+
peaks.z.splice(j, 1);
|
|
88
|
+
j--;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return peaks;
|
|
69
93
|
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { GYROMAGNETIC_RATIO, Nuclei } from '../constants/gyromagneticRatio';
|
|
2
|
+
|
|
3
|
+
export interface ObjervedNucleusData {
|
|
4
|
+
/**
|
|
5
|
+
* nucleus to use as reference in the calculation of frequency
|
|
6
|
+
*/
|
|
7
|
+
nucleus: Nucleus;
|
|
8
|
+
/**
|
|
9
|
+
* frequency of the reference nucleus
|
|
10
|
+
*/
|
|
11
|
+
frequency: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
//Literal type is extends string and when union it with string we lose the autocomplete and to solve this we distinguish string
|
|
15
|
+
type Nucleus = Nuclei | (string & Record<never, never>);
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* calculate the frequency of a nucleus with respect to a reference nucleus
|
|
19
|
+
*/
|
|
20
|
+
export function getFrequency(
|
|
21
|
+
/**
|
|
22
|
+
* nucleus to calculate the frequency
|
|
23
|
+
*/
|
|
24
|
+
nucleus: Nucleus,
|
|
25
|
+
observedNucleusData: ObjervedNucleusData,
|
|
26
|
+
) {
|
|
27
|
+
const { nucleus: obsNucleus, frequency } = observedNucleusData;
|
|
28
|
+
|
|
29
|
+
checkExistence(nucleus, obsNucleus);
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
(frequency * GYROMAGNETIC_RATIO[nucleus as Nuclei]) /
|
|
33
|
+
GYROMAGNETIC_RATIO[obsNucleus as Nuclei]
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function checkExistence(...nucleus: Nucleus[]) {
|
|
38
|
+
let nuclei: string[] = [];
|
|
39
|
+
for (const n of nucleus) {
|
|
40
|
+
if (!(n in GYROMAGNETIC_RATIO)) {
|
|
41
|
+
nuclei.push(n);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (nuclei.length !== 0) {
|
|
45
|
+
throw new Error(`${nuclei.join(' , ')} is not supported`);
|
|
46
|
+
}
|
|
47
|
+
}
|