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,26 @@
|
|
|
1
|
+
import { GYROMAGNETIC_RATIO } from '../constants/gyromagneticRatio';
|
|
2
|
+
/**
|
|
3
|
+
* calculate the frequency of a nucleus with respect to a reference nucleus
|
|
4
|
+
*/
|
|
5
|
+
export function getFrequency(
|
|
6
|
+
/**
|
|
7
|
+
* nucleus to calculate the frequency
|
|
8
|
+
*/
|
|
9
|
+
nucleus, observedNucleusData) {
|
|
10
|
+
const { nucleus: obsNucleus, frequency } = observedNucleusData;
|
|
11
|
+
checkExistence(nucleus, obsNucleus);
|
|
12
|
+
return ((frequency * GYROMAGNETIC_RATIO[nucleus]) /
|
|
13
|
+
GYROMAGNETIC_RATIO[obsNucleus]);
|
|
14
|
+
}
|
|
15
|
+
function checkExistence(...nucleus) {
|
|
16
|
+
let nuclei = [];
|
|
17
|
+
for (const n of nucleus) {
|
|
18
|
+
if (!(n in GYROMAGNETIC_RATIO)) {
|
|
19
|
+
nuclei.push(n);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
if (nuclei.length !== 0) {
|
|
23
|
+
throw new Error(`${nuclei.join(' , ')} is not supported`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=getFrequency.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getFrequency.js","sourceRoot":"","sources":["../../src/utilities/getFrequency.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAU,MAAM,gCAAgC,CAAC;AAgB5E;;GAEG;AACH,MAAM,UAAU,YAAY;AAC1B;;GAEG;AACH,OAAgB,EAChB,mBAAwC;IAExC,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,mBAAmB,CAAC;IAE/D,cAAc,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IAEpC,OAAO,CACL,CAAC,SAAS,GAAG,kBAAkB,CAAC,OAAiB,CAAC,CAAC;QACnD,kBAAkB,CAAC,UAAoB,CAAC,CACzC,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,GAAG,OAAkB;IAC3C,IAAI,MAAM,GAAa,EAAE,CAAC;IAC1B,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE;QACvB,IAAI,CAAC,CAAC,CAAC,IAAI,kBAAkB,CAAC,EAAE;YAC9B,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;SAChB;KACF;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;QACvB,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;KAC3D;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nmr-processing",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.4.0",
|
|
4
4
|
"description": "Pure functions allowing to process NMR spectra.",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"module": "./lib-esm/index.js",
|
|
@@ -41,18 +41,18 @@
|
|
|
41
41
|
"@types/jest": "^27.4.1",
|
|
42
42
|
"cheminfo-build": "^1.1.11",
|
|
43
43
|
"cheminfo-types": "^1.1.0",
|
|
44
|
-
"eslint": "^8.
|
|
45
|
-
"eslint-config-cheminfo-typescript": "^10.
|
|
44
|
+
"eslint": "^8.11.0",
|
|
45
|
+
"eslint-config-cheminfo-typescript": "^10.4.0",
|
|
46
46
|
"jest": "^27.5.1",
|
|
47
47
|
"jest-matcher-deep-close-to": "^3.0.2",
|
|
48
48
|
"md5": "^2.3.0",
|
|
49
49
|
"ml-array-median": "^1.1.6",
|
|
50
50
|
"nmr-xy-testdata": "^0.5.1",
|
|
51
51
|
"openchemlib": "^7.4.3",
|
|
52
|
-
"prettier": "^2.
|
|
52
|
+
"prettier": "^2.6.1",
|
|
53
53
|
"rimraf": "^3.0.2",
|
|
54
|
-
"ts-jest": "^27.1.
|
|
55
|
-
"typescript": "^4.6.
|
|
54
|
+
"ts-jest": "^27.1.4",
|
|
55
|
+
"typescript": "^4.6.3"
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
58
|
"binary-search": "^1.3.6",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"ml-array-rescale": "^1.3.7",
|
|
64
64
|
"ml-array-sequential-fill": "^1.1.8",
|
|
65
65
|
"ml-array-sum": "^1.1.6",
|
|
66
|
-
"ml-gsd": "^10.
|
|
66
|
+
"ml-gsd": "^10.2.0",
|
|
67
67
|
"ml-hclust": "^3.1.0",
|
|
68
68
|
"ml-levenberg-marquardt": "^4.1.0",
|
|
69
69
|
"ml-matrix": "^6.9.0",
|
|
@@ -72,9 +72,10 @@
|
|
|
72
72
|
"ml-peak-shape-generator": "^4.1.1",
|
|
73
73
|
"ml-simple-clustering": "^0.1.0",
|
|
74
74
|
"ml-sparse-matrix": "^2.1.0",
|
|
75
|
-
"ml-spectra-processing": "^11.
|
|
75
|
+
"ml-spectra-processing": "^11.1.0",
|
|
76
76
|
"ml-tree-set": "^0.1.1",
|
|
77
|
-
"
|
|
77
|
+
"nmr-correlation": "^2.2.5",
|
|
78
|
+
"openchemlib-utils": "^1.10.0",
|
|
78
79
|
"spectrum-generator": "^8.0.0"
|
|
79
80
|
}
|
|
80
81
|
}
|
|
@@ -12,7 +12,7 @@ import type {
|
|
|
12
12
|
NMRSignal1DWithAtomsAndDiaIDs,
|
|
13
13
|
Targets,
|
|
14
14
|
} from './get1HAssignments';
|
|
15
|
-
import {
|
|
15
|
+
import { RestrictionByCS1D, buildAssignments } from './utils/buildAssignments';
|
|
16
16
|
import generateID from './utils/generateID';
|
|
17
17
|
|
|
18
18
|
function checkAtomsAndDiaIDs(
|
|
@@ -33,7 +33,7 @@ function checkIntegration(ranges: NMRRange[]) {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
export interface Get13CAssignmentsOptions {
|
|
36
|
-
restrictionByCS?: Partial<
|
|
36
|
+
restrictionByCS?: Partial<RestrictionByCS1D>;
|
|
37
37
|
/**
|
|
38
38
|
* min score to accept an assignment
|
|
39
39
|
* @default 1
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
import type { NMRSignal1D } from '../signals/NMRSignal1D';
|
|
10
10
|
import { MakeMandatory } from '../utilities/MakeMandatory';
|
|
11
11
|
|
|
12
|
-
import { buildAssignments,
|
|
12
|
+
import { buildAssignments, RestrictionByCS1D } from './utils/buildAssignments';
|
|
13
13
|
import generateID from './utils/generateID';
|
|
14
14
|
|
|
15
15
|
export type NMRSignal1DWithAtomsAndDiaIDs = MakeMandatory<
|
|
@@ -40,7 +40,7 @@ function checkForIntegration(
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
export interface Get1HAssignmentsOptions {
|
|
43
|
-
restrictionByCS?: Partial<
|
|
43
|
+
restrictionByCS?: Partial<RestrictionByCS1D>;
|
|
44
44
|
/**
|
|
45
45
|
* min score to accept an assignment
|
|
46
46
|
* @default 1
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { Molecule } from 'openchemlib';
|
|
2
|
+
import { addDiastereotopicMissingChirality } from 'openchemlib-utils';
|
|
3
|
+
|
|
4
|
+
import { NMRSignal1D } from '..';
|
|
5
|
+
import type { PredictCarbonOptions } from '../prediction/predictCarbon';
|
|
6
|
+
import type { PredictProtonOptions } from '../prediction/predictProton';
|
|
7
|
+
import { NMRRange } from '../xy/NMRRange';
|
|
8
|
+
import { NMRZone } from '../xyz/NMRZone';
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
AtomTypes,
|
|
12
|
+
buildAssignments,
|
|
13
|
+
RestrictionByCS,
|
|
14
|
+
} from './utils/getAssignment/buildAssignments';
|
|
15
|
+
import { checkIDs } from './utils/getAssignment/checkIDs';
|
|
16
|
+
import { getTargetsAndCorrelations } from './utils/getAssignment/getTargetsAndCorrelations';
|
|
17
|
+
import getWorkFlow from './utils/getAssignment/getWorkFlow';
|
|
18
|
+
|
|
19
|
+
export interface SpectraData1D {
|
|
20
|
+
id?: string;
|
|
21
|
+
ranges: NMRRange[];
|
|
22
|
+
info?: any;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface SpectraData2D {
|
|
26
|
+
id?: string;
|
|
27
|
+
zones: NMRZone[];
|
|
28
|
+
info?: any;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export type SpectraData = SpectraData1D | SpectraData2D;
|
|
32
|
+
|
|
33
|
+
export interface GetAutoAssignmentInput {
|
|
34
|
+
/**
|
|
35
|
+
* It has the number of each atoms in the chemical structure. e.g. { C: 6, H: 6 }
|
|
36
|
+
*/
|
|
37
|
+
atoms?: { [key: string]: number };
|
|
38
|
+
|
|
39
|
+
spectra: SpectraData[];
|
|
40
|
+
/**
|
|
41
|
+
* Instance of Molecule
|
|
42
|
+
*/
|
|
43
|
+
molecule: Molecule;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface GetAssignmentsOptions {
|
|
47
|
+
justAssign?: Array<AtomTypes[]>;
|
|
48
|
+
|
|
49
|
+
restrictionByCS?: Partial<RestrictionByCS>;
|
|
50
|
+
/**
|
|
51
|
+
* min score to accept an assignment
|
|
52
|
+
* @default 1
|
|
53
|
+
*/
|
|
54
|
+
minScore?: number;
|
|
55
|
+
/**
|
|
56
|
+
* maximal number of assignments to return
|
|
57
|
+
* @default 10
|
|
58
|
+
*/
|
|
59
|
+
maxSolutions?: number;
|
|
60
|
+
/**
|
|
61
|
+
* number of allowed unassignment signals
|
|
62
|
+
* @default 0
|
|
63
|
+
*/
|
|
64
|
+
nbAllowedUnAssigned?: { [key: string]: number };
|
|
65
|
+
/**
|
|
66
|
+
* time limit in miliseconds to finish the assignment procedure.
|
|
67
|
+
* @default 6000
|
|
68
|
+
*/
|
|
69
|
+
timeout?: number;
|
|
70
|
+
/**
|
|
71
|
+
* predictions
|
|
72
|
+
*/
|
|
73
|
+
predictions?: {
|
|
74
|
+
H?: NMRSignal1D[];
|
|
75
|
+
C?: NMRSignal1D[];
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* prediction options
|
|
79
|
+
*/
|
|
80
|
+
predictionOptions?: {
|
|
81
|
+
H?: PredictProtonOptions;
|
|
82
|
+
C?: PredictCarbonOptions;
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* correlation options
|
|
86
|
+
*/
|
|
87
|
+
correlation?: {
|
|
88
|
+
tolerance?: number;
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export async function getAssignments(
|
|
93
|
+
input: GetAutoAssignmentInput,
|
|
94
|
+
options: GetAssignmentsOptions = {},
|
|
95
|
+
) {
|
|
96
|
+
let {
|
|
97
|
+
restrictionByCS = {},
|
|
98
|
+
justAssign,
|
|
99
|
+
minScore = 1,
|
|
100
|
+
maxSolutions = 10,
|
|
101
|
+
nbAllowedUnAssigned,
|
|
102
|
+
timeout = 6000,
|
|
103
|
+
predictionOptions = {},
|
|
104
|
+
predictions = {},
|
|
105
|
+
correlation: correlationOptions = {},
|
|
106
|
+
} = options;
|
|
107
|
+
|
|
108
|
+
const {
|
|
109
|
+
tolerance = { H: 0.2, C: 1 },
|
|
110
|
+
useChemicalShiftScore = false,
|
|
111
|
+
chemicalShiftRestriction = true,
|
|
112
|
+
} = restrictionByCS;
|
|
113
|
+
|
|
114
|
+
const molecule = input.molecule;
|
|
115
|
+
|
|
116
|
+
if (!molecule) throw new Error('It is needed a molecule to assign');
|
|
117
|
+
|
|
118
|
+
molecule.addImplicitHydrogens();
|
|
119
|
+
addDiastereotopicMissingChirality(molecule);
|
|
120
|
+
|
|
121
|
+
const spectra = checkIDs(input.spectra);
|
|
122
|
+
|
|
123
|
+
const { targets, correlations } = getTargetsAndCorrelations(
|
|
124
|
+
spectra,
|
|
125
|
+
correlationOptions,
|
|
126
|
+
);
|
|
127
|
+
const { assignmentOrder } = getWorkFlow(correlations, justAssign);
|
|
128
|
+
|
|
129
|
+
const solutions = await buildAssignments({
|
|
130
|
+
restrictionByCS: {
|
|
131
|
+
tolerance,
|
|
132
|
+
useChemicalShiftScore,
|
|
133
|
+
chemicalShiftRestriction,
|
|
134
|
+
},
|
|
135
|
+
spectra,
|
|
136
|
+
molecule,
|
|
137
|
+
timeout,
|
|
138
|
+
minScore,
|
|
139
|
+
maxSolutions,
|
|
140
|
+
assignmentOrder,
|
|
141
|
+
nbAllowedUnAssigned,
|
|
142
|
+
correlations,
|
|
143
|
+
targets,
|
|
144
|
+
predictionOptions,
|
|
145
|
+
predictions,
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
return solutions;
|
|
149
|
+
}
|
|
@@ -10,14 +10,14 @@ const comparator = (a: SolutionAssignment, b: SolutionAssignment) => {
|
|
|
10
10
|
return b.score - a.score;
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
-
export interface
|
|
13
|
+
export interface RestrictionByCS1D {
|
|
14
14
|
chemicalShiftRestriction: boolean;
|
|
15
15
|
tolerance: number;
|
|
16
16
|
useChemicalShiftScore: boolean;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export interface BuildAssignmentsProps {
|
|
20
|
-
restrictionByCS?: Partial<
|
|
20
|
+
restrictionByCS?: Partial<RestrictionByCS1D>;
|
|
21
21
|
timeout: number;
|
|
22
22
|
minScore: number;
|
|
23
23
|
useIntegrationRestriction: boolean;
|
|
@@ -37,7 +37,7 @@ export interface Predictions1Dassignments {
|
|
|
37
37
|
[key: string]: Signals1DAssignment;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
export interface
|
|
40
|
+
export interface StoreAssignments {
|
|
41
41
|
solutions: treeSet;
|
|
42
42
|
nSolutions: number;
|
|
43
43
|
}
|
|
@@ -63,7 +63,7 @@ export async function buildAssignments(props: BuildAssignmentsProps) {
|
|
|
63
63
|
let date = new Date();
|
|
64
64
|
let timeStart = date.getTime();
|
|
65
65
|
|
|
66
|
-
let store:
|
|
66
|
+
let store: StoreAssignments = {
|
|
67
67
|
solutions: new treeSet(comparator),
|
|
68
68
|
nSolutions: 0,
|
|
69
69
|
};
|
|
@@ -2,12 +2,12 @@ import { MakeMandatory } from '../../utilities/MakeMandatory';
|
|
|
2
2
|
import type { Targets } from '../get1HAssignments';
|
|
3
3
|
|
|
4
4
|
import type {
|
|
5
|
-
|
|
5
|
+
RestrictionByCS1D,
|
|
6
6
|
Predictions1Dassignments,
|
|
7
7
|
} from './buildAssignments';
|
|
8
8
|
|
|
9
9
|
type RestrictionByCSMandatory = MakeMandatory<
|
|
10
|
-
|
|
10
|
+
RestrictionByCS1D,
|
|
11
11
|
'chemicalShiftRestriction' | 'tolerance' | 'useChemicalShiftScore'
|
|
12
12
|
>;
|
|
13
13
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { Targets } from '../get1HAssignments';
|
|
2
2
|
|
|
3
3
|
import type {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
RestrictionByCS1D,
|
|
5
|
+
StoreAssignments,
|
|
6
6
|
Predictions1Dassignments,
|
|
7
7
|
} from './buildAssignments';
|
|
8
8
|
import type { PossibleAssignmentMap } from './createMapPossibleAssignments';
|
|
@@ -10,7 +10,7 @@ import { partialScore } from './partialScore';
|
|
|
10
10
|
|
|
11
11
|
export interface ExploreTreeRecProps {
|
|
12
12
|
nSources: number;
|
|
13
|
-
restrictionByCS:
|
|
13
|
+
restrictionByCS: RestrictionByCS1D;
|
|
14
14
|
timeout: number;
|
|
15
15
|
timeStart: number;
|
|
16
16
|
maxSolutions: number;
|
|
@@ -26,7 +26,7 @@ export function exploreTreeRec(
|
|
|
26
26
|
props: ExploreTreeRecProps,
|
|
27
27
|
currentIndex: number,
|
|
28
28
|
partial: Array<string | null>,
|
|
29
|
-
store:
|
|
29
|
+
store: StoreAssignments,
|
|
30
30
|
) {
|
|
31
31
|
const {
|
|
32
32
|
nSources,
|
|
@@ -107,7 +107,7 @@ interface AddSolutionProps {
|
|
|
107
107
|
predictions: Predictions1Dassignments;
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
function addSolution(store:
|
|
110
|
+
function addSolution(store: StoreAssignments, props: AddSolutionProps) {
|
|
111
111
|
let { score, maxSolutions, partial, predictions } = props;
|
|
112
112
|
score /= doubleAssignmentPenalty(partial, predictions);
|
|
113
113
|
store.nSolutions++;
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
import treeSet from 'ml-tree-set';
|
|
2
|
+
import { Values } from 'nmr-correlation';
|
|
3
|
+
import { Molecule } from 'openchemlib';
|
|
4
|
+
import { getConnectivityMatrix } from 'openchemlib-utils';
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
NMRSignal1D,
|
|
8
|
+
PredictCarbonOptions,
|
|
9
|
+
PredictProtonOptions,
|
|
10
|
+
} from '../../..';
|
|
11
|
+
import { predictCarbon } from '../../../prediction/predictCarbon';
|
|
12
|
+
import { predictProton } from '../../../prediction/predictProton';
|
|
13
|
+
import { MakeMandatory } from '../../../utilities/MakeMandatory';
|
|
14
|
+
import { StoreAssignments } from '../buildAssignments';
|
|
15
|
+
|
|
16
|
+
import { SpectraDataWithIds } from './checkIDs';
|
|
17
|
+
import {
|
|
18
|
+
createMapPossibleAssignment,
|
|
19
|
+
MapPossibleAssignments,
|
|
20
|
+
} from './createMapPossibleAssignment';
|
|
21
|
+
import { AssignmentSolution, exploreTree } from './exploreTree';
|
|
22
|
+
import { TargetsByAtomType } from './getTargetsAndCorrelations';
|
|
23
|
+
import { isSpectraData1D } from './isSpectraData1D';
|
|
24
|
+
import { searchIndices } from './searchIndices';
|
|
25
|
+
|
|
26
|
+
const comparator = (a: AssignmentSolution, b: AssignmentSolution) => {
|
|
27
|
+
return b.score - a.score;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const predictor = { H: predictProton, C: predictCarbon };
|
|
31
|
+
|
|
32
|
+
export type AtomTypes = 'H' | 'C';
|
|
33
|
+
export type CurrentAtoms = Array<AtomTypes>;
|
|
34
|
+
export interface Partial {
|
|
35
|
+
[key: string]: Array<string | null>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface DiaIDPeerPossibleAssignment {
|
|
39
|
+
[key: string]: string[];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface RestrictionByCS {
|
|
43
|
+
chemicalShiftRestriction: boolean;
|
|
44
|
+
tolerance: { [key: string]: number };
|
|
45
|
+
useChemicalShiftScore: boolean;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface BuildAssignmentInput {
|
|
49
|
+
spectra: SpectraDataWithIds[];
|
|
50
|
+
molecule: Molecule;
|
|
51
|
+
restrictionByCS: RestrictionByCS;
|
|
52
|
+
timeout: number;
|
|
53
|
+
minScore: number;
|
|
54
|
+
nbAllowedUnAssigned?: { [key: string]: number };
|
|
55
|
+
maxSolutions: number;
|
|
56
|
+
correlations: Values;
|
|
57
|
+
assignmentOrder: Array<Array<AtomTypes>>;
|
|
58
|
+
predictions: {
|
|
59
|
+
H?: NMRSignal1D[];
|
|
60
|
+
C?: NMRSignal1D[];
|
|
61
|
+
};
|
|
62
|
+
predictionOptions: {
|
|
63
|
+
H?: PredictProtonOptions;
|
|
64
|
+
C?: PredictCarbonOptions;
|
|
65
|
+
};
|
|
66
|
+
targets: TargetsByAtomType;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
type NMRSignal1DFromPrediction = MakeMandatory<
|
|
70
|
+
NMRSignal1D,
|
|
71
|
+
'nbAtoms' | 'diaIDs' | 'atoms'
|
|
72
|
+
>;
|
|
73
|
+
|
|
74
|
+
function checkNMRSignal1D(
|
|
75
|
+
signals: NMRSignal1D[],
|
|
76
|
+
): asserts signals is NMRSignal1DFromPrediction[] {
|
|
77
|
+
const keys: Array<'nbAtoms' | 'diaIDs' | 'atoms'> = [
|
|
78
|
+
'nbAtoms',
|
|
79
|
+
'diaIDs',
|
|
80
|
+
'atoms',
|
|
81
|
+
];
|
|
82
|
+
for (const signal of signals) {
|
|
83
|
+
for (let key of keys) {
|
|
84
|
+
if (!signal[key]) throw new Error(`property ${key} does not exist`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export interface Prediction extends NMRSignal1DFromPrediction {
|
|
90
|
+
diaIDIndex: number;
|
|
91
|
+
allHydrogens: number;
|
|
92
|
+
protonsCount: number;
|
|
93
|
+
pathLength: number[];
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export interface Predictions {
|
|
97
|
+
[key: string]: Prediction;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export interface PredictionsByAtomType {
|
|
101
|
+
[key: string]: Predictions;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export interface InfoByAtomType {
|
|
105
|
+
[key: string]: {
|
|
106
|
+
nSources: number;
|
|
107
|
+
currentIndex: number;
|
|
108
|
+
nbAllowedUnAssigned: number;
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export const getAllHydrogens = {
|
|
113
|
+
C: (m: Molecule, i: number) => m.getAllHydrogens(i),
|
|
114
|
+
H: () => 1,
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
export async function buildAssignments(props: BuildAssignmentInput) {
|
|
118
|
+
const {
|
|
119
|
+
spectra,
|
|
120
|
+
molecule,
|
|
121
|
+
restrictionByCS,
|
|
122
|
+
timeout,
|
|
123
|
+
minScore,
|
|
124
|
+
nbAllowedUnAssigned = {},
|
|
125
|
+
maxSolutions,
|
|
126
|
+
correlations,
|
|
127
|
+
assignmentOrder,
|
|
128
|
+
predictionOptions,
|
|
129
|
+
predictions: inputPrediction = {},
|
|
130
|
+
targets,
|
|
131
|
+
} = props;
|
|
132
|
+
|
|
133
|
+
let date = new Date();
|
|
134
|
+
let timeStart = date.getTime();
|
|
135
|
+
let lowerBoundScore = minScore;
|
|
136
|
+
|
|
137
|
+
let store: StoreAssignments = {
|
|
138
|
+
solutions: new treeSet(comparator),
|
|
139
|
+
nSolutions: 0,
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
const pathLengthMatrix = getConnectivityMatrix(molecule, {
|
|
143
|
+
pathLength: true,
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
let infoByAtomType: InfoByAtomType = {};
|
|
147
|
+
const predictions: PredictionsByAtomType = {};
|
|
148
|
+
let possibleAssignmentMap: MapPossibleAssignments = {};
|
|
149
|
+
let diaIDPeerPossibleAssignment: DiaIDPeerPossibleAssignment = {};
|
|
150
|
+
|
|
151
|
+
for (const atomTypesToPredict of assignmentOrder) {
|
|
152
|
+
for (const atomType of atomTypesToPredict) {
|
|
153
|
+
const options = predictionOptions[atomType];
|
|
154
|
+
const predictedSignals = inputPrediction[atomType];
|
|
155
|
+
let { joinedSignals } = predictedSignals
|
|
156
|
+
? { joinedSignals: predictedSignals }
|
|
157
|
+
: await predictor[atomType](molecule, options);
|
|
158
|
+
|
|
159
|
+
checkNMRSignal1D(joinedSignals);
|
|
160
|
+
|
|
161
|
+
if (!predictions[atomType]) predictions[atomType] = {};
|
|
162
|
+
for (let prediction of joinedSignals) {
|
|
163
|
+
const diaID = prediction.diaIDs[0];
|
|
164
|
+
const index = prediction.atoms[0];
|
|
165
|
+
const allHydrogens = getAllHydrogens[atomType](molecule, index);
|
|
166
|
+
predictions[atomType][diaID] = {
|
|
167
|
+
...prediction,
|
|
168
|
+
diaIDIndex: index,
|
|
169
|
+
allHydrogens: prediction.nbAtoms * allHydrogens,
|
|
170
|
+
protonsCount: allHydrogens,
|
|
171
|
+
pathLength: pathLengthMatrix[index] as number[],
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
infoByAtomType[atomType] = {
|
|
175
|
+
nSources: joinedSignals.length,
|
|
176
|
+
currentIndex: 0,
|
|
177
|
+
nbAllowedUnAssigned: nbAllowedUnAssigned[atomType] || 0,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
possibleAssignmentMap = createMapPossibleAssignment(possibleAssignmentMap, {
|
|
182
|
+
restrictionByCS,
|
|
183
|
+
predictions,
|
|
184
|
+
targets,
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
diaIDPeerPossibleAssignment = {};
|
|
188
|
+
for (const atomType in possibleAssignmentMap) {
|
|
189
|
+
diaIDPeerPossibleAssignment[atomType] = Object.keys(
|
|
190
|
+
possibleAssignmentMap[atomType],
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
let sourceOfPartials = getSourceOfPartials(
|
|
195
|
+
store,
|
|
196
|
+
infoByAtomType,
|
|
197
|
+
atomTypesToPredict,
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
store = {
|
|
201
|
+
solutions: new treeSet(comparator),
|
|
202
|
+
nSolutions: 0,
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
for (let partial of sourceOfPartials) {
|
|
206
|
+
exploreTree(
|
|
207
|
+
{
|
|
208
|
+
currentAtomTypes: atomTypesToPredict,
|
|
209
|
+
restrictionByCS,
|
|
210
|
+
timeout,
|
|
211
|
+
timeStart,
|
|
212
|
+
targets,
|
|
213
|
+
predictions,
|
|
214
|
+
correlations,
|
|
215
|
+
maxSolutions,
|
|
216
|
+
lowerBoundScore,
|
|
217
|
+
possibleAssignmentMap,
|
|
218
|
+
diaIDPeerPossibleAssignment,
|
|
219
|
+
},
|
|
220
|
+
infoByAtomType,
|
|
221
|
+
partial,
|
|
222
|
+
store,
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return annotateSpectraData({
|
|
227
|
+
store,
|
|
228
|
+
spectra,
|
|
229
|
+
diaIDPeerPossibleAssignment,
|
|
230
|
+
targets,
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
interface AnnotateSpectraDataInput {
|
|
235
|
+
store: StoreAssignments;
|
|
236
|
+
spectra: SpectraDataWithIds[];
|
|
237
|
+
targets: TargetsByAtomType;
|
|
238
|
+
diaIDPeerPossibleAssignment: DiaIDPeerPossibleAssignment;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function annotateSpectraData(input: AnnotateSpectraDataInput) {
|
|
242
|
+
const { store, spectra, diaIDPeerPossibleAssignment, targets } = input;
|
|
243
|
+
const { solutions } = store;
|
|
244
|
+
const mapSignalId: any = {};
|
|
245
|
+
const atomTypes = Object.keys(targets) as AtomTypes[];
|
|
246
|
+
for (const atomType of atomTypes) {
|
|
247
|
+
const targetByAtomType = targets[atomType];
|
|
248
|
+
for (const targetId in targetByAtomType) {
|
|
249
|
+
let target = targetByAtomType[targetId];
|
|
250
|
+
for (const link of target.link) {
|
|
251
|
+
const signalId = link.signal.id;
|
|
252
|
+
if (mapSignalId[signalId]) continue;
|
|
253
|
+
mapSignalId[link.signal.id] = searchIndices(signalId, spectra);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
const result = [];
|
|
259
|
+
for (let solution of solutions.elements) {
|
|
260
|
+
const spectraResult = JSON.parse(
|
|
261
|
+
JSON.stringify(spectra),
|
|
262
|
+
) as SpectraDataWithIds[];
|
|
263
|
+
const { assignment, score } = solution;
|
|
264
|
+
const atomTypes = Object.keys(assignment) as AtomTypes[];
|
|
265
|
+
for (const atomType of atomTypes) {
|
|
266
|
+
const targetByAtomType = targets[atomType];
|
|
267
|
+
const assignmentPeerAtomType = assignment[atomType];
|
|
268
|
+
for (let index = 0; index < assignmentPeerAtomType.length; index++) {
|
|
269
|
+
const targetID = assignmentPeerAtomType[index];
|
|
270
|
+
|
|
271
|
+
if (targetID === '*' || !targetID) continue;
|
|
272
|
+
|
|
273
|
+
const target = targetByAtomType[targetID];
|
|
274
|
+
const diaId = diaIDPeerPossibleAssignment[atomType][index];
|
|
275
|
+
|
|
276
|
+
for (let link of target.link) {
|
|
277
|
+
const { spectrumIndex, elementIndex, signalIndex } =
|
|
278
|
+
mapSignalId[link.signal.id];
|
|
279
|
+
const spectrum = spectraResult[spectrumIndex];
|
|
280
|
+
|
|
281
|
+
if (isSpectraData1D(spectrum)) {
|
|
282
|
+
let { ranges } = spectrum;
|
|
283
|
+
let range = ranges[elementIndex];
|
|
284
|
+
let signal = range.signals[signalIndex];
|
|
285
|
+
if (!signal.diaIDs) signal.diaIDs = [];
|
|
286
|
+
signal.diaIDs.push(diaId);
|
|
287
|
+
} else {
|
|
288
|
+
const axis = link.axis as 'x' | 'y';
|
|
289
|
+
const signal = spectrum.zones[elementIndex].signals[signalIndex];
|
|
290
|
+
if (!signal[axis].diaIDs) signal[axis].diaIDs = [];
|
|
291
|
+
signal[axis].diaIDs?.push(diaId);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
result.push({
|
|
297
|
+
score,
|
|
298
|
+
assignment: spectraResult,
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
return result;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
function getSourceOfPartials(
|
|
305
|
+
store: StoreAssignments,
|
|
306
|
+
infoByAtomType: InfoByAtomType,
|
|
307
|
+
currentAtoms: CurrentAtoms,
|
|
308
|
+
) {
|
|
309
|
+
return store.nSolutions > 0
|
|
310
|
+
? store.solutions.elements.map((e) => {
|
|
311
|
+
let currentAssignment = e.assignment;
|
|
312
|
+
for (const atom of currentAtoms) {
|
|
313
|
+
currentAssignment[atom] = fillPartial(infoByAtomType[atom].nSources);
|
|
314
|
+
}
|
|
315
|
+
return currentAssignment;
|
|
316
|
+
})
|
|
317
|
+
: initializePartials(infoByAtomType, currentAtoms);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
function initializePartials(
|
|
321
|
+
infoByAtomType: InfoByAtomType,
|
|
322
|
+
currentAtoms: CurrentAtoms,
|
|
323
|
+
) {
|
|
324
|
+
const partial: Partial = {};
|
|
325
|
+
const atomsType = Object.keys(infoByAtomType) as CurrentAtoms;
|
|
326
|
+
for (const atom of atomsType) {
|
|
327
|
+
const value = currentAtoms.includes(atom) ? null : '*';
|
|
328
|
+
partial[atom] = fillPartial(infoByAtomType[atom].nSources, value);
|
|
329
|
+
}
|
|
330
|
+
return [partial];
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
function fillPartial(nSources: number, value: string | null = null) {
|
|
334
|
+
const partial: Array<string | null> = new Array(nSources);
|
|
335
|
+
for (let i = 0; i < nSources; i++) {
|
|
336
|
+
partial[i] = value;
|
|
337
|
+
}
|
|
338
|
+
return partial;
|
|
339
|
+
}
|