Skip to content
47 changes: 46 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@
"ml-array-mean": "^2.0.0",
"ml-array-median": "^2.0.0",
"ml-conrec": "^6.0.0",
"ml-gsd": "^14.0.1",
"ml-gsd": "^14.1.0",
"ml-signal-processing": "^2.2.1",
"ml-spectra-processing": "^14.29.0",
"ml-tree-similarity": "^2.2.0",
Expand Down
3 changes: 2 additions & 1 deletion src/component/1d/peaks/usePeakShapesPath.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,13 @@ export function usePeakShapesPath(spectrum: Spectrum1D) {

const frequency = spectrum.info.originFrequency;
let pathSeries: DataXY | null = null;

switch (target) {
case 'peakShape': {
const { peak } = options;
pathSeries = peakToXY(peak, {
frequency,
nbPoints: 1024,
nbPoints: Math.ceil(width * 3),
from: peak.x - (peak.width / frequency) * 9,
to: peak.x + (peak.width / frequency) * 9,
});
Expand Down
4 changes: 2 additions & 2 deletions src/component/panels/PeaksPanel/PeaksPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,11 @@ function PeaksPanelInner(props: PeaksPanelInnerProps) {
const filterPeaks = peaks.values.filter((peak) =>
isInRange(peak.x, { from, to }),
);
if (filterPeaks.length <= 4) {
if (filterPeaks.length <= 15) {
dispatch({ type: 'OPTIMIZE_PEAKS', payload: { peaks: filterPeaks } });
} else {
toaster.show({
message: 'optimization can be done on no more than 4 peaks',
message: 'optimization can be done on no more than 15 peaks',
intent: 'danger',
});
}
Expand Down
4 changes: 2 additions & 2 deletions src/component/reducer/actions/PeaksActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ function handleAddPeak(draft: Draft<State>, action: AddPeakAction) {
x: candidatePeak.x,
y: candidatePeak.y,
width: 1,
shape: defaultPeakShape,
shape: { ...defaultPeakShape },
};
spectrum.peaks.values.push(...mapPeaks([peak], spectrum));
}
Expand Down Expand Up @@ -131,7 +131,7 @@ function handleAddPeaks(draft: Draft<State>, action: AddPeaksAction) {
x: peak.x,
y: peak.y,
width: 1,
shape: defaultPeakShape,
shape: { ...defaultPeakShape },
};
spectrum.peaks.values.push(newPeak);
}
Expand Down
112 changes: 109 additions & 3 deletions src/data/data1d/Spectrum1D/peaks/optimizePeaks.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Peak1D } from '@zakodium/nmr-types';
import type { Spectrum1D } from '@zakodium/nmrium-core';
import { xFindClosestIndex } from 'ml-spectra-processing';
import { mapPeaks, xyPeaksOptimization } from 'nmr-processing';
import { mapPeaks, xyPeaksOptimizationByStages } from 'nmr-processing';

interface OptimizePeaksOptions {
from: number;
Expand Down Expand Up @@ -31,10 +31,116 @@ export function optimizePeaks(
x = x.subarray(fromIndex, ToIndex);
re = re.subarray(fromIndex, ToIndex);

const newPeaks = xyPeaksOptimization({ x, y: re }, peaks, {
const newPeaks = xyPeaksOptimizationByStages({ x, y: re }, peaks, {
frequency,
groupingFactor: 3,
groupingFactor: 10,
stages: [
{
optimization: {
kind: 'lm',
options: { maxIterations: 20, errorTolerance: 1e-3 },
},
parameters: {
fwhm: {
optimize: true,
min: (peak: any) => (peak.shape?.fwhm ?? 0) / 2,
max: (peak: any) => (peak.shape?.fwhm ?? 0) * 2,
},
mu: { optimize: false },
x: { optimize: false },
y: {
optimize: true,
init: (peak: any) => peak.y * 0.8,
},
},
},
{
optimization: {
kind: 'lm',
options: { maxIterations: 20, errorTolerance: 5e-4 },
},
parameters: {
fwhm: {
optimize: true,
min: (peak: any) => (peak.shape?.fwhm ?? 0) / 2,
max: (peak: any) => (peak.shape?.fwhm ?? 0) * 2,
},
mu: { optimize: false },
x: { optimize: false },
y: {
optimize: true,
},
},
},
{
optimization: {
kind: 'lm',
options: { maxIterations: 20, errorTolerance: 1e-5 },
},
parameters: {
fwhm: {
optimize: true,
min: (peak: any) => (peak.shape?.fwhm ?? 0) / 2,
max: (peak: any) => (peak.shape?.fwhm ?? 0) * 2,
},
mu: { optimize: true },
x: { optimize: false },
y: {
optimize: true,
},
},
},
{
optimization: {
kind: 'lm',
options: { maxIterations: 20, errorTolerance: 5e-4 },
},
parameters: {
fwhm: {
optimize: true,
min: (peak: any) => (peak.shape?.fwhm ?? 0) / 3,
max: (peak: any) => (peak.shape?.fwhm ?? 0) * 3,
},
mu: { optimize: true },
x: { optimize: true },
y: { optimize: true },
},
},
{
optimization: {
kind: 'lm',
options: { maxIterations: 20, errorTolerance: 1e-4 },
},
parameters: {
fwhm: {
optimize: true,
min: (peak: any) => (peak.shape?.fwhm ?? 0) / 2,
max: (peak: any) => (peak.shape?.fwhm ?? 0) * 2,
},
mu: { optimize: false },
x: { optimize: true },
y: { optimize: true },
},
},
{
optimization: {
kind: 'lm',
options: { maxIterations: 20, errorTolerance: 1e-8 },
},
parameters: {
fwhm: {
optimize: true,
min: (peak: any) => (peak.shape?.fwhm ?? 0) / 2,
max: (peak: any) => (peak.shape?.fwhm ?? 0) * 2,
},
mu: { optimize: true },
x: { optimize: true },
y: { optimize: true },
},
},
],
});

return mapPeaks(spectrum.peaks.values.concat(newPeaks), spectrum, {
checkIsExisting: false,
});
Expand Down
Loading