nmr-processing 7.4.1 → 8.0.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.
Files changed (52) hide show
  1. package/lib/assignment/getAssignments.d.ts +7 -9
  2. package/lib/assignment/getAssignments.js +1 -1
  3. package/lib/assignment/getAssignments.js.map +1 -1
  4. package/lib/assignment/nmrAssigment.d.ts +19 -27
  5. package/lib/assignment/utils/getAssignment/buildAssignments.d.ts +1 -1
  6. package/lib/assignment/utils/getAssignment/buildAssignments.js +5 -0
  7. package/lib/assignment/utils/getAssignment/buildAssignments.js.map +1 -1
  8. package/lib/assignment/utils/getAssignment/checkIDs.d.ts +3 -20
  9. package/lib/assignment/utils/getAssignment/checkIDs.js +5 -9
  10. package/lib/assignment/utils/getAssignment/checkIDs.js.map +1 -1
  11. package/lib/assignment/utils/getAssignment/formatData.d.ts +1 -1
  12. package/lib/assignment/utils/getAssignment/formatData.js +30 -3
  13. package/lib/assignment/utils/getAssignment/formatData.js.map +1 -1
  14. package/lib/assignment/utils/getAssignment/getTargetsAndCorrelations.d.ts +1 -1
  15. package/lib/assignment/utils/getAssignment/getTargetsAndCorrelations.js.map +1 -1
  16. package/lib/assignment/utils/getAssignment/partialScore.js +1 -1
  17. package/lib/assignment/utils/getAssignment/partialScore.js.map +1 -1
  18. package/lib/databases/getDatabase.d.ts +6 -1
  19. package/lib/databases/getDatabase.js +13 -3
  20. package/lib/databases/getDatabase.js.map +1 -1
  21. package/lib/index.d.ts +3 -1
  22. package/lib/prediction/predictAllSpectra.d.ts +22 -4
  23. package/lib/prediction/predictAllSpectra.js +102 -16
  24. package/lib/prediction/predictAllSpectra.js.map +1 -1
  25. package/lib/xyz/NMRSignal2D.d.ts +3 -3
  26. package/lib-esm/assignment/getAssignments.js +1 -1
  27. package/lib-esm/assignment/getAssignments.js.map +1 -1
  28. package/lib-esm/assignment/utils/getAssignment/buildAssignments.js +5 -0
  29. package/lib-esm/assignment/utils/getAssignment/buildAssignments.js.map +1 -1
  30. package/lib-esm/assignment/utils/getAssignment/checkIDs.js +5 -9
  31. package/lib-esm/assignment/utils/getAssignment/checkIDs.js.map +1 -1
  32. package/lib-esm/assignment/utils/getAssignment/formatData.js +30 -3
  33. package/lib-esm/assignment/utils/getAssignment/formatData.js.map +1 -1
  34. package/lib-esm/assignment/utils/getAssignment/getTargetsAndCorrelations.js.map +1 -1
  35. package/lib-esm/assignment/utils/getAssignment/partialScore.js +1 -1
  36. package/lib-esm/assignment/utils/getAssignment/partialScore.js.map +1 -1
  37. package/lib-esm/databases/getDatabase.js +13 -3
  38. package/lib-esm/databases/getDatabase.js.map +1 -1
  39. package/lib-esm/prediction/predictAllSpectra.js +102 -16
  40. package/lib-esm/prediction/predictAllSpectra.js.map +1 -1
  41. package/package.json +12 -12
  42. package/src/assignment/getAssignments.ts +8 -9
  43. package/src/assignment/nmrAssigment.ts +23 -21
  44. package/src/assignment/utils/getAssignment/buildAssignments.ts +7 -1
  45. package/src/assignment/utils/getAssignment/checkIDs.ts +14 -36
  46. package/src/assignment/utils/getAssignment/formatData.ts +41 -4
  47. package/src/assignment/utils/getAssignment/getTargetsAndCorrelations.ts +2 -1
  48. package/src/assignment/utils/getAssignment/partialScore.ts +2 -2
  49. package/src/databases/getDatabase.ts +19 -2
  50. package/src/index.ts +9 -1
  51. package/src/prediction/predictAllSpectra.ts +151 -14
  52. package/src/xyz/NMRSignal2D.ts +3 -3
@@ -11,9 +11,9 @@ import {
11
11
  import { predictCarbon } from '../../../prediction/predictCarbon';
12
12
  import { predictProton } from '../../../prediction/predictProton';
13
13
  import { MakeMandatory } from '../../../utilities/MakeMandatory';
14
+ import { SpectraDataWithIds } from '../../nmrAssigment';
14
15
  import { StoreAssignments } from '../buildAssignments';
15
16
 
16
- import { SpectraDataWithIds } from './checkIDs';
17
17
  import {
18
18
  createMapPossibleAssignment,
19
19
  MapPossibleAssignments,
@@ -159,10 +159,13 @@ export async function buildAssignments(props: BuildAssignmentInput) {
159
159
  checkNMRSignal1D(joinedSignals);
160
160
 
161
161
  if (!predictions[atomType]) predictions[atomType] = {};
162
+
163
+ let totalHydrogens = 0;
162
164
  for (let prediction of joinedSignals) {
163
165
  const diaID = prediction.diaIDs[0];
164
166
  const index = prediction.atoms[0];
165
167
  const allHydrogens = getAllHydrogens[atomType](molecule, index);
168
+ totalHydrogens += prediction.nbAtoms * allHydrogens;
166
169
  predictions[atomType][diaID] = {
167
170
  ...prediction,
168
171
  diaIDIndex: index,
@@ -171,6 +174,9 @@ export async function buildAssignments(props: BuildAssignmentInput) {
171
174
  pathLength: pathLengthMatrix[index] as number[],
172
175
  };
173
176
  }
177
+ for (let diaID in predictions[atomType]) {
178
+ predictions[atomType][diaID].allHydrogens *= 100 / totalHydrogens;
179
+ }
174
180
  infoByAtomType[atomType] = {
175
181
  nSources: joinedSignals.length,
176
182
  currentIndex: 0,
@@ -1,50 +1,28 @@
1
- import type { NMRRange, NMRSignal1D, NMRSignal2D, NMRZone } from '../../..';
2
- import { MakeMandatory } from '../../../utilities/MakeMandatory';
1
+ import type { NMRRange, NMRZone } from '../../..';
2
+ import type { SpectraData } from '../../getAssignments';
3
3
  import type {
4
- SpectraData,
5
- SpectraData1D,
6
- SpectraData2D,
7
- } from '../../getAssignments';
4
+ SpectraDataWithIds,
5
+ NMRRangeWithIds,
6
+ NMRZoneWithIds,
7
+ } from '../../nmrAssigment';
8
8
  import generateID from '../generateID';
9
9
 
10
10
  import { isSpectraData1D } from './isSpectraData1D';
11
11
 
12
- export type NMRSignal1DWithId = MakeMandatory<NMRSignal1D, 'id'>;
13
- export type NMRSignal2DWithId = MakeMandatory<NMRSignal2D, 'id'>;
14
-
15
- export interface NMRZoneWithIds extends Omit<NMRZone, 'signals' | 'id'> {
16
- id: string;
17
- signals: Array<NMRSignal2DWithId>;
18
- }
19
-
20
- export interface NMRRangeWithIds extends Omit<NMRRange, 'id' | 'signals'> {
21
- id: string;
22
- signals: Array<NMRSignal1DWithId>;
23
- }
24
-
25
- export interface SpectraData1DWithIds extends Omit<SpectraData1D, 'ranges'> {
26
- ranges: NMRRangeWithIds[];
27
- }
28
- export interface SpectraData2DWithIds extends Omit<SpectraData2D, 'zones'> {
29
- zones: NMRZoneWithIds[];
30
- }
31
-
32
- export type SpectraDataWithIds = SpectraData1DWithIds | SpectraData2DWithIds;
33
-
34
12
  export function checkIDs(input: SpectraData[] = []): SpectraDataWithIds[] {
35
13
  let inputClone = JSON.parse(JSON.stringify(input)) as SpectraData[];
36
14
  let spectra: SpectraDataWithIds[] = [];
37
15
  for (const spectraData of inputClone) {
16
+ if (!('info' in spectraData)) {
17
+ throw new Error(
18
+ 'each spectrum should contain info properties with nucleus information',
19
+ );
20
+ }
21
+
38
22
  const { info, id } = spectraData;
39
23
  if (isSpectraData1D(spectraData)) {
40
- let data = addIDs(spectraData.ranges) as NMRRangeWithIds[];
41
- for (const element of data) {
42
- const { integration } = element;
43
- for (let signal of element.signals || []) {
44
- if (!signal.integration) signal.integration = integration;
45
- }
46
- }
47
- spectra.push({ id, info, ranges: data });
24
+ let ranges = addIDs(spectraData.ranges) as NMRRangeWithIds[];
25
+ spectra.push({ id, info, ranges });
48
26
  } else {
49
27
  let data = addIDs(spectraData.zones) as NMRZoneWithIds[];
50
28
  spectra.push({ id, info, zones: data });
@@ -4,7 +4,8 @@ import {
4
4
  SpectraData1DWithIds,
5
5
  SpectraData2DWithIds,
6
6
  SpectraDataWithIds,
7
- } from './checkIDs';
7
+ } from '../../nmrAssigment';
8
+
8
9
  import { isSpectraData1D } from './isSpectraData1D';
9
10
 
10
11
  interface SpectraData1DFormatted extends Omit<SpectraData1DWithIds, 'ranges'> {
@@ -24,12 +25,48 @@ export function formatData(
24
25
  let inputClone = JSON.parse(JSON.stringify(input)) as SpectraDataWithIds[];
25
26
  let spectra: SpectraDataFormatted[] = [];
26
27
  for (const spectraData of inputClone) {
27
- const { info } = spectraData;
28
+ const { id, info } = spectraData;
28
29
  if (isSpectraData1D(spectraData)) {
29
- spectra.push({ info, ranges: { values: spectraData.ranges } });
30
+ const ranges = rescaleIntegration({
31
+ id,
32
+ info,
33
+ ranges: spectraData.ranges,
34
+ });
35
+ spectra.push({ id, info, ranges: { values: ranges } });
30
36
  } else {
31
- spectra.push({ info, zones: { values: spectraData.zones } });
37
+ spectra.push({ id, info, zones: { values: spectraData.zones } });
32
38
  }
33
39
  }
34
40
  return spectra;
35
41
  }
42
+
43
+ function rescaleIntegration(spectrum: SpectraData1DWithIds): NMRRangeWithIds[] {
44
+ if (spectrum.info.nucleus !== '1H') return spectrum.ranges;
45
+
46
+ let totalIntegration = spectrum.ranges.reduce(
47
+ (total, range) => (range.integration ? total + range.integration : total),
48
+ 0,
49
+ );
50
+
51
+ for (let range of spectrum.ranges) {
52
+ if (range.integration) {
53
+ range.integration *= 100 / totalIntegration;
54
+ if (range.signals) {
55
+ const totalSignalIntegration = range.signals.reduce(
56
+ (total, signal) =>
57
+ signal.integration ? total + signal.integration : total,
58
+ 0,
59
+ );
60
+ for (let signal of range.signals) {
61
+ if (signal.integration) {
62
+ signal.integration *= range.integration / totalSignalIntegration;
63
+ } else {
64
+ signal.integration = range.integration;
65
+ }
66
+ }
67
+ }
68
+ }
69
+ }
70
+
71
+ return spectrum.ranges;
72
+ }
@@ -1,7 +1,8 @@
1
1
  import { buildCorrelationData } from 'nmr-correlation';
2
2
  import type { Correlation, Link } from 'nmr-correlation';
3
3
 
4
- import { SpectraDataWithIds } from './checkIDs';
4
+ import { SpectraDataWithIds } from '../../nmrAssigment';
5
+
5
6
  import { formatData } from './formatData';
6
7
  import { getIntegrationOfAttachedProtons } from './getIntegrationOfAttachedProtons';
7
8
 
@@ -114,9 +114,9 @@ export function partialScore(partial: Partial, props: PartialScoreOptions) {
114
114
  }
115
115
  }
116
116
  }
117
+
117
118
  for (const group of targetByIntegral) {
118
119
  const { integration, atomType } = group;
119
-
120
120
  if (integration === undefined || isNaN(integration)) continue;
121
121
 
122
122
  let total = 0;
@@ -128,7 +128,7 @@ export function partialScore(partial: Partial, props: PartialScoreOptions) {
128
128
  if (atomType === atomOfPrediction) total += prediction.allHydrogens;
129
129
  }
130
130
  }
131
- if (total - integration >= 0.5) {
131
+ if (total - integration >= 5) {
132
132
  return 0;
133
133
  }
134
134
  }
@@ -6,16 +6,33 @@ import { DatabaseNMREntry } from './DatabaseNMREntry';
6
6
 
7
7
  export async function getDatabase(
8
8
  url = 'https://docs.google.com/spreadsheets/d/1uwyq_L38PMRWCcT4If_EhPbHKyY3q_2tpjV8vr5_zh0/edit?usp=sharing',
9
+ options: {
10
+ /**
11
+ * @default 'tsv'
12
+ */
13
+ format?: 'tsv' | 'json';
14
+ } = {},
9
15
  ) {
16
+ const { format = 'tsv' } = options;
17
+
10
18
  if (url.includes('google.com')) {
11
19
  url = `https://googledocs.cheminfo.org/spreadsheets/d/${extractGoogleUUID(
12
20
  url,
13
21
  )}/export?format=tsv`;
14
22
  }
15
23
 
24
+ let parsed;
16
25
  const response = await fetch(url);
17
- const result = await response.text();
18
- const parsed = parseData(result);
26
+ switch (format) {
27
+ case 'tsv':
28
+ parsed = parseData(await response.text());
29
+ break;
30
+ case 'json':
31
+ parsed = await response.json();
32
+ break;
33
+ default:
34
+ throw new Error('unknown database format');
35
+ }
19
36
 
20
37
  const results = [];
21
38
 
package/src/index.ts CHANGED
@@ -38,13 +38,21 @@ export * from './databases/carbonImpurities';
38
38
  export * from './databases/protonImpurities';
39
39
 
40
40
  export type { NMRSignal1D } from './signals/NMRSignal1D';
41
- export type { NMRSignal2D } from './xyz/NMRSignal2D';
41
+ export type { NMRSignal2D, Signal2DProjection } from './xyz/NMRSignal2D';
42
42
  export type { NMRRange } from './xy/NMRRange';
43
43
  export type { NMRZone } from './xyz/NMRZone';
44
44
  export type { NMRPeak1D } from './peaks/NMRPeak1D';
45
45
  export type { Prediction1D } from './prediction/prediction1D';
46
46
  export type { Jcoupling } from './signals/jcoupling';
47
+ export type { DatabaseNMREntry } from './databases/DatabaseNMREntry';
47
48
  export type {
48
49
  DataBaseLevelStructure,
49
50
  DataBaseStructure,
50
51
  } from './prediction/dataStructure';
52
+ export type {
53
+ NMRSignal1DWithId,
54
+ NMRSignal2DWithId,
55
+ SpectraData1DWithIds,
56
+ SpectraData2DWithIds,
57
+ SpectraDataWithIds,
58
+ } from './assignment/nmrAssigment';
@@ -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 predictions = await predictAll(molecule, options.prediction);
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
- spectra.push(getProton(predictions.proton, options.simulation));
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
- function getProton(prediction: any, options?: OptionsSignalsToXY) {
29
- const { x, y } = signalsToXY(prediction.signals, options);
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: 400,
38
- baseFrequency: 400,
157
+ originFrequency: realFrequency,
158
+ baseFrequency: realFrequency,
39
159
  pulseSequence: 'prediction',
40
- experiment: 'proton',
160
+ experiment,
41
161
  isFt: true,
42
162
  },
43
- // todo: currently we disable the ranges because there is no ID
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
+ }
@@ -1,7 +1,7 @@
1
1
  import type { FromTo } from 'cheminfo-types';
2
2
  import type { Peak2D } from 'ml-matrix-peaks-finder';
3
3
 
4
- export interface Signal2DAxisData {
4
+ export interface Signal2DProjection {
5
5
  nucleus?: string;
6
6
  delta: number;
7
7
  resolution?: number;
@@ -9,8 +9,8 @@ export interface Signal2DAxisData {
9
9
  diaIDs?: string[];
10
10
  }
11
11
  export interface NMRSignal2D {
12
- x: Signal2DAxisData;
13
- y: Signal2DAxisData;
12
+ x: Signal2DProjection;
13
+ y: Signal2DProjection;
14
14
  j?: {
15
15
  pathLength?: number | FromTo;
16
16
  };