Skip to content

Commit

Permalink
fix: negative peak picking
Browse files Browse the repository at this point in the history
refactor: rename function maxValue to maxAbsoluteValue
  • Loading branch information
hamed-musallam committed Dec 13, 2023
1 parent 19fd560 commit c35089f
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 74 deletions.
33 changes: 6 additions & 27 deletions src/component/1d/tool/PeakPointer.tsx
@@ -1,14 +1,13 @@
import max from 'ml-array-max';
import { Spectrum1D } from 'nmr-load-save';

import { get1DDataXY } from '../../../data/data1d/Spectrum1D/get1DDataXY';
import { useBrushTracker } from '../../EventsTrackers/BrushTracker';
import { useMouseTracker } from '../../EventsTrackers/MouseTracker';
import { useChartData } from '../../context/ChartContext';
import { useScaleChecked } from '../../context/ScaleContext';
import { useActiveSpectrum } from '../../hooks/useActiveSpectrum';
import useSpectraByActiveNucleus from '../../hooks/useSpectraPerNucleus';
import { options } from '../../toolbar/ToolTypes';
import { getClosePeak } from '../../utility/getClosePeak';

const styles = {
radius: 10,
Expand All @@ -18,31 +17,8 @@ const styles = {
SVGPadding: 1,
};

interface PeakPosition {
x: number;
y: number;
}

const LookWidth = 10;

function getClosePeak(
spectrum: Spectrum1D,
range: number[],
): PeakPosition | null {
const datum = get1DDataXY(spectrum);
const maxIndex = datum.x.findIndex((number) => number >= range[1]) - 1;
const minIndex = datum.x.findIndex((number) => number >= range[0]);

const yDataRange = datum.y.slice(minIndex, maxIndex);
if (!yDataRange || yDataRange.length === 0) return null;

const y = max(yDataRange);
const xIndex = minIndex + yDataRange.indexOf(y);
const x = datum.x[xIndex];

return { x, y };
}

function PeakPointer() {
const {
height,
Expand Down Expand Up @@ -74,14 +50,17 @@ function PeakPointer() {

if (spectrumIndex === -1) return null;

const range = [
const [from, to] = [
scaleX().invert(position.x - LookWidth),
scaleX().invert(position.x + LookWidth),
].sort((a, b) => {
return a - b;
});

const closePeak = getClosePeak(spectra[spectrumIndex] as Spectrum1D, range);
const closePeak = getClosePeak(spectra[spectrumIndex] as Spectrum1D, {
from,
to,
});
if (!closePeak) return null;

const x = scaleX()(closePeak.x);
Expand Down
7 changes: 3 additions & 4 deletions src/component/reducer/actions/PeaksActions.ts
@@ -1,5 +1,4 @@
import { v4 } from '@lukeed/uuid';
import { NmrData1D } from 'cheminfo-types';
import { Draft, original } from 'immer';
import { xFindClosestIndex } from 'ml-spectra-processing';
import {
Expand All @@ -12,7 +11,6 @@ import { Peak1D, OptionsXYAutoPeaksPicking } from 'nmr-processing';

import {
getShiftX,
lookupPeak,
autoPeakPicking,
optimizePeaks,
} from '../../../data/data1d/Spectrum1D';
Expand All @@ -23,6 +21,7 @@ import { State } from '../Reducer';
import { getActiveSpectrum } from '../helper/getActiveSpectrum';
import getRange from '../helper/getRange';
import { ActionType } from '../types/ActionType';
import { getClosePeak } from '../../utility/getClosePeak';

type AddPeakAction = ActionType<'ADD_PEAK', { x: number }>;
type AddPeaksAction = ActionType<'ADD_PEAKS', { startX: number; endX: number }>;
Expand Down Expand Up @@ -74,7 +73,7 @@ function handleAddPeak(draft: Draft<State>, action: AddPeakAction) {
const startX = mouseXPosition - xShift;
const endX = mouseXPosition + xShift;
const [from, to] = getRange(draft, { startX, endX });
const candidatePeak = lookupPeak(state.data[index].data as NmrData1D, {
const candidatePeak = getClosePeak(state.data[index] as Spectrum1D, {
from,
to,
});
Expand Down Expand Up @@ -108,7 +107,7 @@ function handleAddPeaks(draft: Draft<State>, action: AddPeaksAction) {
const [from, to] = getRange(draft, { startX, endX });

if (from !== to) {
const peak = lookupPeak(datumOriginal.data, { from, to });
const peak = getClosePeak(datumOriginal, { from, to });

const shiftX = getShiftX(draft.data[index] as Spectrum1D);

Expand Down
32 changes: 32 additions & 0 deletions src/component/utility/getClosePeak.ts
@@ -0,0 +1,32 @@
import { Spectrum1D } from 'nmr-load-save';

import { get1DDataXY } from '../../data/data1d/Spectrum1D';

import { maxAbsoluteValue } from './maxAbsoluteValue';

interface PeakPosition {
x: number;
y: number;
}

export function getClosePeak(
spectrum: Spectrum1D,
lookRange: {
from: number;
to: number;
},
): PeakPosition | null {
const { from, to } = lookRange;
const datum = get1DDataXY(spectrum);
const maxIndex = datum.x.findIndex((number) => number >= to) - 1;
const minIndex = datum.x.findIndex((number) => number >= from);

const yDataRange = datum.y.slice(minIndex, maxIndex);
if (!yDataRange || yDataRange.length === 0) return null;

const y = maxAbsoluteValue(yDataRange);
const xIndex = minIndex + yDataRange.indexOf(y);
const x = datum.x[xIndex];

return { x, y };
}
31 changes: 31 additions & 0 deletions src/component/utility/maxAbsoluteValue.ts
@@ -0,0 +1,31 @@
import { NumberArray } from 'cheminfo-types';
import {
XGetFromToIndexOptions,
xCheck,
xGetFromToIndex,
} from 'ml-spectra-processing';

//This function is an adapted version of the xMaxAbsoluteValue function from ml-spectra-processing. It identifies the maximum absolute value and returns the corresponding maximum value along with its sign
export function maxAbsoluteValue(
array: NumberArray,
options: XGetFromToIndexOptions = {},
): number {
xCheck(array);

const { fromIndex, toIndex } = xGetFromToIndex(array, options);
let maxValue = array[fromIndex];
let sign = 1;

for (let i = fromIndex + 1; i <= toIndex; i++) {
if (array[i] >= 0) {
if (array[i] > maxValue) {
maxValue = array[i];
sign = 1;
}
} else if (-array[i] > maxValue) {
maxValue = -array[i];
sign = Math.sign(array[i]);
}
}
return maxValue * sign;
}
1 change: 0 additions & 1 deletion src/data/data1d/Spectrum1D/index.ts
Expand Up @@ -5,7 +5,6 @@ export { initiateDatum1D } from './initiateDatum1D';
export { changeIntegralsRelative } from './integrals/changeIntegralsRelative';
export { isSpectrum1D } from './isSpectrum1D';
export { autoPeakPicking } from './peaks/autoPeakPicking';
export { lookupPeak } from './peaks/lookupPeak';
export { optimizePeaks } from './peaks/optimizePeaks';
export { addRange } from './ranges/addRange';
export { changeRange } from './ranges/changeRange';
Expand Down
42 changes: 0 additions & 42 deletions src/data/data1d/Spectrum1D/peaks/lookupPeak.ts

This file was deleted.

0 comments on commit c35089f

Please sign in to comment.