nmr-processing 8.2.0 → 8.3.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 (127) hide show
  1. package/lib/apodization/apodization.d.ts +22 -0
  2. package/lib/apodization/apodization.js +18 -0
  3. package/lib/apodization/apodization.js.map +1 -0
  4. package/lib/apodization/applyWindow.d.ts +28 -0
  5. package/lib/apodization/applyWindow.js +20 -0
  6. package/lib/apodization/applyWindow.js.map +1 -0
  7. package/lib/apodization/compose.d.ts +23 -0
  8. package/lib/apodization/compose.js +25 -0
  9. package/lib/apodization/compose.js.map +1 -0
  10. package/lib/apodization/getFunction.d.ts +2 -0
  11. package/lib/apodization/getFunction.js +18 -0
  12. package/lib/apodization/getFunction.js.map +1 -0
  13. package/lib/apodization/shapes/WindowFunctions.d.ts +12 -0
  14. package/lib/apodization/shapes/WindowFunctions.js +3 -0
  15. package/lib/apodization/shapes/WindowFunctions.js.map +1 -0
  16. package/lib/apodization/shapes/exponential.d.ts +11 -0
  17. package/lib/apodization/shapes/exponential.js +10 -0
  18. package/lib/apodization/shapes/exponential.js.map +1 -0
  19. package/lib/apodization/shapes/lorentzToGauss.d.ts +26 -0
  20. package/lib/apodization/shapes/lorentzToGauss.js +15 -0
  21. package/lib/apodization/shapes/lorentzToGauss.js.map +1 -0
  22. package/lib/apodization/utils/getData.d.ts +4 -0
  23. package/lib/apodization/utils/getData.js +21 -0
  24. package/lib/apodization/utils/getData.js.map +1 -0
  25. package/lib/assignment/utils/buildAssignments.d.ts +2 -2
  26. package/lib/assignment/utils/exploreTreeRec.js +1 -1
  27. package/lib/assignment/utils/exploreTreeRec.js.map +1 -1
  28. package/lib/databases/DatabaseNMREntry.d.ts +2 -0
  29. package/lib/index.d.ts +2 -0
  30. package/lib/index.js +2 -0
  31. package/lib/index.js.map +1 -1
  32. package/lib/peaks/peaksToRanges.js +1 -1
  33. package/lib/peaks/peaksToRanges.js.map +1 -1
  34. package/lib/peaks/solventSuppression.d.ts +4 -1
  35. package/lib/peaks/solventSuppression.js +10 -7
  36. package/lib/peaks/solventSuppression.js.map +1 -1
  37. package/lib/peaks/util/jAnalyzer.js +23 -29
  38. package/lib/peaks/util/jAnalyzer.js.map +1 -1
  39. package/lib/peaks/util/peakOptimizer.js +12 -16
  40. package/lib/peaks/util/peakOptimizer.js.map +1 -1
  41. package/lib/prediction/predictAllSpectra.js +7 -9
  42. package/lib/prediction/predictAllSpectra.js.map +1 -1
  43. package/lib/prediction/predictCarbon.js +1 -1
  44. package/lib/prediction/predictCarbon.js.map +1 -1
  45. package/lib/prediction/utils/queryByHOSE.js +1 -1
  46. package/lib/prediction/utils/queryByHOSE.js.map +1 -1
  47. package/lib/ranges/rangesToACS.js +8 -4
  48. package/lib/ranges/rangesToACS.js.map +1 -1
  49. package/lib/signals/simulation/getPauliMatrix.js.map +1 -1
  50. package/lib/signals/simulation/splitSpinSystem.js +11 -13
  51. package/lib/signals/simulation/splitSpinSystem.js.map +1 -1
  52. package/lib/utilities/rangeFromSignal.d.ts +9 -5
  53. package/lib/utilities/rangeFromSignal.js +7 -7
  54. package/lib/utilities/rangeFromSignal.js.map +1 -1
  55. package/lib/utilities/resurrectRange.js +4 -7
  56. package/lib/utilities/resurrectRange.js.map +1 -1
  57. package/lib-esm/apodization/apodization.js +14 -0
  58. package/lib-esm/apodization/apodization.js.map +1 -0
  59. package/lib-esm/apodization/applyWindow.js +16 -0
  60. package/lib-esm/apodization/applyWindow.js.map +1 -0
  61. package/lib-esm/apodization/compose.js +21 -0
  62. package/lib-esm/apodization/compose.js.map +1 -0
  63. package/lib-esm/apodization/getFunction.js +14 -0
  64. package/lib-esm/apodization/getFunction.js.map +1 -0
  65. package/lib-esm/apodization/shapes/WindowFunctions.js +2 -0
  66. package/lib-esm/apodization/shapes/WindowFunctions.js.map +1 -0
  67. package/lib-esm/apodization/shapes/exponential.js +6 -0
  68. package/lib-esm/apodization/shapes/exponential.js.map +1 -0
  69. package/lib-esm/apodization/shapes/lorentzToGauss.js +11 -0
  70. package/lib-esm/apodization/shapes/lorentzToGauss.js.map +1 -0
  71. package/lib-esm/apodization/utils/getData.js +17 -0
  72. package/lib-esm/apodization/utils/getData.js.map +1 -0
  73. package/lib-esm/assignment/utils/buildAssignments.js +3 -3
  74. package/lib-esm/assignment/utils/exploreTreeRec.js +1 -1
  75. package/lib-esm/assignment/utils/exploreTreeRec.js.map +1 -1
  76. package/lib-esm/assignment/utils/getAssignment/buildAssignments.js +3 -3
  77. package/lib-esm/index.js +2 -0
  78. package/lib-esm/index.js.map +1 -1
  79. package/lib-esm/peaks/peaksToRanges.js +1 -1
  80. package/lib-esm/peaks/peaksToRanges.js.map +1 -1
  81. package/lib-esm/peaks/solventSuppression.js +10 -7
  82. package/lib-esm/peaks/solventSuppression.js.map +1 -1
  83. package/lib-esm/peaks/util/jAnalyzer.js +23 -29
  84. package/lib-esm/peaks/util/jAnalyzer.js.map +1 -1
  85. package/lib-esm/peaks/util/peakOptimizer.js +12 -16
  86. package/lib-esm/peaks/util/peakOptimizer.js.map +1 -1
  87. package/lib-esm/prediction/predictAllSpectra.js +7 -9
  88. package/lib-esm/prediction/predictAllSpectra.js.map +1 -1
  89. package/lib-esm/prediction/predictCarbon.js +1 -1
  90. package/lib-esm/prediction/predictCarbon.js.map +1 -1
  91. package/lib-esm/prediction/utils/queryByHOSE.js +1 -1
  92. package/lib-esm/prediction/utils/queryByHOSE.js.map +1 -1
  93. package/lib-esm/ranges/rangesToACS.js +8 -4
  94. package/lib-esm/ranges/rangesToACS.js.map +1 -1
  95. package/lib-esm/signals/simulation/getPauliMatrix.js.map +1 -1
  96. package/lib-esm/signals/simulation/splitSpinSystem.js +11 -13
  97. package/lib-esm/signals/simulation/splitSpinSystem.js.map +1 -1
  98. package/lib-esm/utilities/rangeFromSignal.js +7 -7
  99. package/lib-esm/utilities/rangeFromSignal.js.map +1 -1
  100. package/lib-esm/utilities/resurrectRange.js +4 -7
  101. package/lib-esm/utilities/resurrectRange.js.map +1 -1
  102. package/package.json +13 -13
  103. package/src/apodization/apodization.ts +34 -0
  104. package/src/apodization/applyWindow.ts +51 -0
  105. package/src/apodization/compose.ts +47 -0
  106. package/src/apodization/getFunction.ts +15 -0
  107. package/src/apodization/shapes/WindowFunctions.ts +14 -0
  108. package/src/apodization/shapes/exponential.ts +16 -0
  109. package/src/apodization/shapes/lorentzToGauss.ts +41 -0
  110. package/src/apodization/utils/getData.ts +15 -0
  111. package/src/assignment/utils/buildAssignments.ts +4 -4
  112. package/src/assignment/utils/exploreTreeRec.ts +1 -1
  113. package/src/assignment/utils/getAssignment/buildAssignments.ts +3 -3
  114. package/src/databases/DatabaseNMREntry.ts +3 -0
  115. package/src/index.ts +3 -0
  116. package/src/peaks/peaksToRanges.ts +1 -1
  117. package/src/peaks/solventSuppression.ts +13 -8
  118. package/src/peaks/util/jAnalyzer.ts +22 -28
  119. package/src/peaks/util/peakOptimizer.ts +11 -15
  120. package/src/prediction/predictAllSpectra.ts +6 -8
  121. package/src/prediction/predictCarbon.ts +1 -1
  122. package/src/prediction/utils/queryByHOSE.ts +1 -1
  123. package/src/ranges/rangesToACS.ts +9 -10
  124. package/src/signals/simulation/getPauliMatrix.ts +1 -1
  125. package/src/signals/simulation/splitSpinSystem.ts +10 -12
  126. package/src/utilities/rangeFromSignal.ts +19 -11
  127. package/src/utilities/resurrectRange.ts +4 -7
@@ -113,7 +113,7 @@ function addSolution(store: StoreAssignments, props: AddSolutionProps) {
113
113
  store.nSolutions++;
114
114
  let solution: SolutionAssignment = {
115
115
  assignment: JSON.parse(JSON.stringify(partial)),
116
- score: score,
116
+ score,
117
117
  };
118
118
 
119
119
  if (store.nSolutions >= maxSolutions) {
@@ -1,4 +1,4 @@
1
- import treeSet from 'ml-tree-set';
1
+ import TreeSet from 'ml-tree-set';
2
2
  import { Values } from 'nmr-correlation';
3
3
  import { Molecule } from 'openchemlib';
4
4
  import { getConnectivityMatrix } from 'openchemlib-utils';
@@ -135,7 +135,7 @@ export async function buildAssignments(props: BuildAssignmentInput) {
135
135
  let lowerBoundScore = minScore;
136
136
 
137
137
  let store: StoreAssignments = {
138
- solutions: new treeSet(comparator),
138
+ solutions: new TreeSet(comparator),
139
139
  nSolutions: 0,
140
140
  };
141
141
 
@@ -204,7 +204,7 @@ export async function buildAssignments(props: BuildAssignmentInput) {
204
204
  );
205
205
 
206
206
  store = {
207
- solutions: new treeSet(comparator),
207
+ solutions: new TreeSet(comparator),
208
208
  nSolutions: 0,
209
209
  };
210
210
 
@@ -1,6 +1,9 @@
1
+ import { OCLMolecule } from 'cheminfo-types';
2
+
1
3
  import { NMRRange } from '../xy/NMRRange';
2
4
 
3
5
  export interface DatabaseNMREntry {
6
+ ocl?: OCLMolecule;
4
7
  smiles?: string;
5
8
  solvent: string;
6
9
  nucleus: string;
package/src/index.ts CHANGED
@@ -40,6 +40,9 @@ export * from './databases/protonImpurities';
40
40
  export * from './peaks/solventSuppression';
41
41
  export * from './ranges/markSolventSignal';
42
42
 
43
+ export * from './apodization/apodization';
44
+ export * from './apodization/compose';
45
+
43
46
  export type { NMRSignal1D } from './signals/NMRSignal1D';
44
47
  export type { NMRSignal2D, Signal2DProjection } from './xyz/NMRSignal2D';
45
48
  export type { NMRRange } from './xy/NMRRange';
@@ -174,7 +174,7 @@ export function peaksToRanges(
174
174
  let peaksO = [];
175
175
  for (let j = signal.maskPattern.length - 1; j >= 0; j--) {
176
176
  sum += computeArea(signal.peaks[j]);
177
- if (signal.maskPattern[j] === false) {
177
+ if (!signal.maskPattern[j]) {
178
178
  let peakR = signal.peaks.splice(j, 1)[0];
179
179
  peaksO.push({
180
180
  x: peakR.x,
@@ -15,7 +15,7 @@ import { NMRPeak1D } from './NMRPeak1D';
15
15
  export function solventSuppression<T extends NMRPeak1D>(
16
16
  peakList: T[],
17
17
  solvent: NMRSignal1D[],
18
- options: any = {},
18
+ options: { markSolventPeaks?: boolean; solventZoneExtension?: number } = {},
19
19
  ) {
20
20
  const peaks = [...peakList].sort((a, b) => a.x - b.x);
21
21
 
@@ -38,9 +38,9 @@ export function solventSuppression<T extends NMRPeak1D>(
38
38
  solventXYPeaks[0].x - solventZoneExtension,
39
39
  );
40
40
 
41
- if (upIndex === lowIndex) continue;
42
- const nearPeaks = peaks.slice(lowIndex, upIndex + 1);
43
-
41
+ const nearPeaks = peaks.filter(
42
+ (peak, index) => index >= lowIndex && index <= upIndex,
43
+ );
44
44
  const amplitudeResiduals = [];
45
45
  const deltaResiduals = [];
46
46
  const positionResiduals = [];
@@ -76,9 +76,14 @@ export function solventSuppression<T extends NMRPeak1D>(
76
76
  positionResiduals.push(positionResidual);
77
77
  }
78
78
 
79
- const maxAmplitude = xMaxValue(amplitudeResiduals);
80
- const maxDelta = xMaxValue(deltaResiduals);
81
- const maxPosition = xMaxValue(positionResiduals);
79
+ const [maxAmplitude, maxDelta, maxPosition] = [
80
+ amplitudeResiduals,
81
+ deltaResiduals,
82
+ positionResiduals,
83
+ ].map((data) => {
84
+ const max = xMaxValue(data);
85
+ return max === 0 ? 1 : max;
86
+ });
82
87
 
83
88
  let minIndex = -1;
84
89
  let minScore = Number.MAX_SAFE_INTEGER;
@@ -98,7 +103,7 @@ export function solventSuppression<T extends NMRPeak1D>(
98
103
  }
99
104
  }
100
105
 
101
- if (minScore < 0) {
106
+ if (minScore < 0 || minIndex < 0) {
102
107
  new Error('There is not a correct match with the pattern');
103
108
  return peaks;
104
109
  }
@@ -120,10 +120,8 @@ export default {
120
120
  // Lets check if the signal could be a singulet.
121
121
  if (peaks.length === 1 && n === 0) {
122
122
  validPattern = true;
123
- } else {
124
- if (peaks.length <= 1) {
125
- continue;
126
- }
123
+ } else if (peaks.length <= 1) {
124
+ continue;
127
125
  }
128
126
  // 1.3 Establish a range for the Heights Hi [peaks.intensity*0.85,peaks.intensity*1.15];
129
127
  let ranges = getRanges(peaks);
@@ -399,7 +397,7 @@ function getRanges(peaks: Peak1DIntern[]): GetRanges {
399
397
  }
400
398
  currentIndex[i] = 0;
401
399
  }
402
- return { values: ranges, currentIndex: currentIndex, active: 0 };
400
+ return { values: ranges, currentIndex, active: 0 };
403
401
  }
404
402
  /**
405
403
  * Performs a symmetrization of the signal by using different aproximations to the center.
@@ -533,20 +531,20 @@ function symmetrize(
533
531
  if (Math.abs(diffL - diffR) < maxError) {
534
532
  avg = Math.min(peaks[left].intensity, peaks[right].intensity);
535
533
  avgWidth = Math.min(peaks[left].width, peaks[right].width);
536
- peaks[left].intensity = peaks[right].intensity = avg;
537
- peaks[left].width = peaks[right].width = avgWidth;
534
+ peaks[left].intensity = avg;
535
+ peaks[right].intensity = avg;
536
+ peaks[left].width = avgWidth;
537
+ peaks[right].width = avgWidth;
538
538
  middle = [
539
539
  middle[0] + (peaks[right].x + peaks[left].x) / 2,
540
540
  middle[1] + 1,
541
541
  ];
542
+ } else if (Math.max(diffL, diffR) === diffR) {
543
+ mask[right] = false;
544
+ left--;
542
545
  } else {
543
- if (Math.max(diffL, diffR) === diffR) {
544
- mask[right] = false;
545
- left--;
546
- } else {
547
- mask[left] = false;
548
- right++;
549
- }
546
+ mask[left] = false;
547
+ right++;
550
548
  }
551
549
  }
552
550
  }
@@ -595,10 +593,8 @@ function symmetrize(
595
593
  weight += peaks[i].intensity;
596
594
  }
597
595
  symFactor /= weight;
598
- } else {
599
- if (peaks.length === 1) {
600
- symFactor = 1;
601
- }
596
+ } else if (peaks.length === 1) {
597
+ symFactor = 1;
602
598
  }
603
599
  let newSumHeights = 0;
604
600
  for (const peak of peaks) {
@@ -608,15 +604,13 @@ function symmetrize(
608
604
  // Sometimes we need a second opinion after the first symmetrization.
609
605
  if (symFactor > 0.8 && symFactor < 0.97 && iteration < 2) {
610
606
  return symmetrize(newSignal, maxErrorIter2, 2, key);
611
- } else {
607
+ } else if (peaks.length > 1) {
612
608
  // Center the given pattern at cs and symmetrize x
613
- if (peaks.length > 1) {
614
- let dxi;
615
- for (let i = Math.ceil(peaks.length / 2) - 1; i >= 0; i--) {
616
- dxi = (peaks[i].x - peaks[peaks.length - 1 - i].x) / 2.0;
617
- peaks[i].x = cs + dxi;
618
- peaks[peaks.length - 1 - i].x = cs - dxi;
619
- }
609
+ let dxi;
610
+ for (let i = Math.ceil(peaks.length / 2) - 1; i >= 0; i--) {
611
+ dxi = (peaks[i].x - peaks[peaks.length - 1 - i].x) / 2.0;
612
+ peaks[i].x = cs + dxi;
613
+ peaks[peaks.length - 1 - i].x = cs - dxi;
620
614
  }
621
615
  }
622
616
  newSignal.symRank = symFactor;
@@ -660,7 +654,7 @@ function normalize(signal: SignalInternMandatory, n: number) {
660
654
  let index = signal.mask2.length - 1;
661
655
  for (let i = peaks.length - 1; i >= 0; i--) {
662
656
  peaks[i].intensity *= norm;
663
- while (index >= 0 && signal.mask2[index] === false) {
657
+ while (index >= 0 && !signal.mask2[index]) {
664
658
  index--;
665
659
  }
666
660
  if (peaks[i].intensity < 0.75) {
@@ -691,7 +685,7 @@ function chemicalShift(peaks: Peak1DIntern[], mask: boolean[] = []) {
691
685
  let area;
692
686
  if (mask.length > 0) {
693
687
  for (let i = 0; i < peaks.length; i++) {
694
- if (mask[i] === true) {
688
+ if (mask[i]) {
695
689
  area = getArea(peaks[i]);
696
690
  sum += area;
697
691
  cs += area * peaks[i].x;
@@ -138,7 +138,7 @@ function completeMissingIfNeeded(
138
138
  }
139
139
  }
140
140
  }
141
- if (diagX === false) {
141
+ if (!diagX) {
142
142
  newSignal = {
143
143
  x: {
144
144
  delta: thisSignal.y.delta,
@@ -158,7 +158,7 @@ function completeMissingIfNeeded(
158
158
  properties.push(tmpProp);
159
159
  addedPeaks++;
160
160
  }
161
- if (diagY === false) {
161
+ if (!diagY) {
162
162
  newSignal = {
163
163
  x: {
164
164
  delta: thisSignal.y.delta,
@@ -202,15 +202,13 @@ function checkCrossPeaks(
202
202
  }
203
203
  crossPeaksX.push(i);
204
204
  shift += cross.x.delta;
205
- } else {
206
- if (Math.abs(cross.y.delta - signal.y.delta) < diagonalError) {
207
- hits++;
208
- if (updateProperties) {
209
- properties[i][1]++;
210
- }
211
- crossPeaksY.push(i);
212
- shift += cross.y.delta;
205
+ } else if (Math.abs(cross.y.delta - signal.y.delta) < diagonalError) {
206
+ hits++;
207
+ if (updateProperties) {
208
+ properties[i][1]++;
213
209
  }
210
+ crossPeaksY.push(i);
211
+ shift += cross.y.delta;
214
212
  }
215
213
  }
216
214
  }
@@ -278,12 +276,10 @@ function initializeProperties(signals: NMRSignal2D[]) {
278
276
  let shift = (signals[i].x.delta * 2 + signals[i].y.delta) / 3.0;
279
277
  signals[i].x.delta = shift;
280
278
  signals[i].y.delta = shift;
279
+ } else if (signals[i].x.delta - signals[i].y.delta > 0) {
280
+ signalsProperties[i][0] = 1;
281
281
  } else {
282
- if (signals[i].x.delta - signals[i].y.delta > 0) {
283
- signalsProperties[i][0] = 1;
284
- } else {
285
- signalsProperties[i][0] = -1;
286
- }
282
+ signalsProperties[i][0] = -1;
287
283
  }
288
284
  }
289
285
  return signalsProperties;
@@ -172,14 +172,12 @@ function calculateFrequency(
172
172
  ): number | string {
173
173
  if (typeof nucleus === 'string') {
174
174
  return getFrequency(nucleus, { nucleus: '1H', frequency });
175
+ } else if (nucleus[0] === nucleus[1]) {
176
+ return `${frequency},${frequency}`;
175
177
  } 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
- }
178
+ return `${frequency},${getFrequency(nucleus[1], {
179
+ nucleus: nucleus[0],
180
+ frequency,
181
+ })}`;
184
182
  }
185
183
  }
@@ -119,7 +119,7 @@ function formatSignals(predictions: Prediction[]) {
119
119
  const signal = {
120
120
  delta: delta || NaN,
121
121
  atoms,
122
- diaIDs: diaIDs,
122
+ diaIDs,
123
123
  multiplicity: 's',
124
124
  nbAtoms,
125
125
  statistic,
@@ -40,7 +40,7 @@ export function queryByHose(
40
40
  delta: res ? res[0] : null,
41
41
  atoms: [atomNumber],
42
42
  nbAtoms: 1,
43
- level: level,
43
+ level,
44
44
  statistic:
45
45
  res && res.length > 1
46
46
  ? {
@@ -72,12 +72,12 @@ export function rangesToACS(
72
72
  if (!options.nucleus) options.nucleus = '1H';
73
73
  const nucleus = options.nucleus.toLowerCase().replace(/[0-9]/g, '');
74
74
  const defaultOptions = globalOptions[nucleus];
75
- options = Object.assign(
76
- {},
77
- defaultOptions,
78
- { ascending: false, format: 'IMJA' },
79
- options,
80
- );
75
+ options = {
76
+ ...defaultOptions,
77
+ ascending: false,
78
+ format: 'IMJA',
79
+ ...options,
80
+ };
81
81
 
82
82
  ranges = JSON.parse(JSON.stringify(ranges));
83
83
  if (options.ascending === true) {
@@ -188,14 +188,13 @@ function pushDelta(range: NMRRange, acsRanges: string[], options: any) {
188
188
  acsRanges.push(strings);
189
189
  }
190
190
 
191
- function getIntegral(range: NMRRange, options: any) {
191
+ function getIntegral(range: NMRRange, options: { nucleus: string[] }) {
192
192
  let integration = '';
193
193
  if (range.pubIntegral) {
194
194
  integration = String(range.pubIntegral);
195
195
  } else if (range.integration) {
196
- integration =
197
- range.integration.toFixed(0) +
198
- options.nucleus[options.nucleus.length - 1];
196
+ const { nucleus } = options;
197
+ integration = range.integration.toFixed(0) + nucleus[nucleus.length - 1];
199
198
  }
200
199
  return integration;
201
200
  }
@@ -2,7 +2,7 @@ import { SparseMatrix } from 'ml-sparse-matrix';
2
2
 
3
3
  function createPauli(mult: number) {
4
4
  const spin = (mult - 1) / 2;
5
- const prjs = new Array(mult);
5
+ const prjs: number[] = new Array(mult);
6
6
  const temp = new Array(mult);
7
7
  for (let i = 0; i < mult; i++) {
8
8
  prjs[i] = mult - 1 - i - spin;
@@ -80,19 +80,17 @@ function splitCluster(
80
80
  }
81
81
  if (count <= maxClusterSize) {
82
82
  clusterList.push(members);
83
+ } else if (child.index < 0) {
84
+ splitCluster(child, clusterList, {
85
+ maxClusterSize,
86
+ force: true,
87
+ nSpins,
88
+ connectivity,
89
+ });
83
90
  } else {
84
- if (child.index < 0) {
85
- splitCluster(child, clusterList, {
86
- maxClusterSize,
87
- force: true,
88
- nSpins,
89
- connectivity,
90
- });
91
- } else {
92
- // We have to threat this spin alone and use the resurrection algorithm instead of the simulation
93
- members[child.index] = 2;
94
- clusterList.push(members);
95
- }
91
+ // We have to threat this spin alone and use the resurrection algorithm instead of the simulation
92
+ members[child.index] = 2;
93
+ clusterList.push(members);
96
94
  }
97
95
  } else {
98
96
  splitCluster(child, clusterList, {
@@ -6,24 +6,32 @@ export interface RangeFromSignalOptions {
6
6
  * nucleus
7
7
  * @default '1h'
8
8
  */
9
- nucleus: string;
9
+ nucleus?: string;
10
10
  /**
11
- * frequency observed
11
+ * frequency observedhttps://www.wiley.com/en-us/NMR+Data+Processing-p-9780471039006#content-section
12
12
  * @default 400
13
13
  */
14
- frequency: number;
14
+ frequency?: number;
15
+ /**
16
+ * tolerance to the halfWidth, default depends of the nucleus
17
+ */
18
+ tolerance?: number;
15
19
  }
16
20
 
17
- export function rangeFromSignal(signal: NMRSignal1D, options: any = {}) {
21
+ export function rangeFromSignal(
22
+ signal: NMRSignal1D,
23
+ options: RangeFromSignalOptions,
24
+ ) {
18
25
  const { nucleus = '1h', frequency = 400 } = options;
19
26
  const { tolerance = getTolerance(nucleus) / frequency } = options;
20
- let halfWidth =
21
- (signal.js || []).reduce((total, j) => {
22
- const { coupling, multiplicity = 'd' } = j;
23
- return total + (couplingValues[multiplicity] * coupling) / frequency;
24
- }, 0) /
25
- 2 +
26
- tolerance;
27
+
28
+ let halfWidth = 0;
29
+ for (const js of signal.js || []) {
30
+ const { coupling, multiplicity = 'd' } = js;
31
+ halfWidth += (couplingValues[multiplicity] * coupling) / frequency;
32
+ }
33
+
34
+ halfWidth = tolerance + halfWidth / 2;
27
35
  return {
28
36
  from: signal.delta - halfWidth,
29
37
  to: signal.delta + halfWidth,
@@ -46,13 +46,10 @@ export function resurrectRange(part: string, options: any = {}) {
46
46
  signal.delta = from;
47
47
  signal.multiplicity = multiplicity;
48
48
  }
49
- } else {
50
- // looks like a real multiplicity, s, d, dd, etc..
51
- if (!isARange) {
52
- // a complex signal
53
- signal.delta = from;
54
- signal.multiplicity = multiplicity;
55
- }
49
+ } else if (!isARange) {
50
+ // a complex signal
51
+ signal.delta = from;
52
+ signal.multiplicity = multiplicity;
56
53
  }
57
54
  }
58
55