Skip to content

Commit

Permalink
fix: phase correction 2D slices (#2748)
Browse files Browse the repository at this point in the history
* fix: phase correction 2D slices

* refactor: slicing function

---------

Co-authored-by: hamed musallam <[email protected]>
  • Loading branch information
jobo322 and hamed-musallam authored Nov 13, 2023
1 parent a2736cf commit 110998a
Showing 1 changed file with 69 additions and 39 deletions.
108 changes: 69 additions & 39 deletions src/data/data2d/Spectrum2D/getSlice.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import type { NmrData1D, NmrData2DFid, NmrData2DFt } from 'cheminfo-types';
import type {
NmrData1D,
NmrData2D,
NmrData2DFid,
NmrData2DFt,
} from 'cheminfo-types';
import { zoneToX } from 'ml-spectra-processing';
import type { Spectrum1D, Spectrum2D } from 'nmr-load-save';
import { Info2D } from 'nmr-processing';

import { TraceDirection } from '../../../component/reducer/Reducer';
import { initiateDatum1D } from '../../data1d/Spectrum1D';
Expand All @@ -15,6 +21,12 @@ interface SlicePosition {
y: number;
}

const BASE_INFO = {
isFid: false,
isComplex: false, // if isComplex is true that mean it contains real/ imaginary x set, if not hid re/im button .
dimension: 1,
};

interface SliceOptions {
sliceType?: 'real' | 'imaginary' | 'both';
}
Expand All @@ -26,73 +38,91 @@ export function getSlice(
): Record<TraceDirection, Spectrum1D> | undefined {
const { sliceType = 'real' } = options;
const { data: spectraData, info } = spectrum;
const realData = info.isFid
? (spectraData as NmrData2DFid).re
: (spectraData as NmrData2DFt).rr;
const imaginaryData = info.isFid
? (spectraData as NmrData2DFid).im
: (spectraData as NmrData2DFt).ir;

const xLength = realData.z[0].length;
const yLength = realData.z.length;
const real = getRealData(spectraData, info);
const imaginary = getImaginaryData(spectraData, info);

const xLength = real.z[0].length;
const yLength = real.z.length;

const xStep = (realData.maxX - realData.minX) / (xLength - 1);
const yStep = (realData.maxY - realData.minY) / (yLength - 1);
const xIndex = Math.floor((position.x - realData.minX) / xStep);
const yIndex = Math.floor((position.y - realData.minY) / yStep);
const xStep = (real.maxX - real.minX) / (xLength - 1);
const yStep = (real.maxY - real.minY) / (yLength - 1);
const xIndex = Math.floor((position.x - real.minX) / xStep);
const yIndex = Math.floor((position.y - real.minY) / yStep);

if (xIndex < 0 || xIndex >= realData.z[0].length) return;
if (yIndex < 0 || yIndex >= realData.z.length) return;
if (xIndex < 0 || xIndex >= real.z[0].length) return;
if (yIndex < 0 || yIndex >= real.z.length) return;

const infoX = {
nucleus: info.nucleus[0], // 1H, 13C, 19F, ...
isFid: false,
isComplex: false, // if isComplex is true that mean it contains real/ imaginary x set, if not hid re/im button .
dimension: 1,
...BASE_INFO,
};

const infoY = {
nucleus: info.nucleus[1], // 1H, 13C, 19F, ...
isFid: false,
isComplex: false, // if isComplex is true that mean it contains real/ imaginary x set, if not hid re/im button .
dimension: 1,
};

const dataX: NmrData1D = {
x: zoneToX({ from: realData.minX, to: realData.maxX }, xLength),
re: new Float64Array(xLength),
...BASE_INFO,
};

const dataY: NmrData1D = {
x: zoneToX({ from: realData.minY, to: realData.maxY }, yLength),
re: new Float64Array(yLength),
};
const dataX = initiateData(real.minX, real.maxX, xLength);
const dataY = initiateData(real.minY, real.maxY, yLength);

if (['real', 'both'].includes(sliceType)) {
for (let i = 0; i < xLength; i++) {
dataX.re[i] += realData.z[yIndex][i];
dataX.re[i] += real.z[yIndex][i];
}
for (let i = 0; i < yLength; i++) {
dataY.re[i] += realData.z[i][xIndex];
dataY.re[i] += real.z[i][xIndex];
}
}

if (imaginaryData && ['imaginary', 'both'].includes(sliceType)) {
if (imaginary && ['imaginary', 'both'].includes(sliceType)) {
infoX.isComplex = true;
infoY.isComplex = true;
dataX.im = new Float64Array(xLength);
dataY.im = new Float64Array(yLength);

for (let i = 0; i < xLength; i++) {
dataX.im[i] += imaginaryData.z[yIndex][i];
dataX.im[i] += imaginary.z[yIndex][i];
}

for (let i = 0; i < yLength; i++) {
dataY.im[i] += imaginaryData.z[i][xIndex];
//FT spectra vertical slicing should use ri instead of ir
const imaginaryVerticalData = getImaginaryData(spectraData, info, {
ftObjectKey: 'ri',
});

if (imaginaryVerticalData) {
infoY.isComplex = true;
for (let i = 0; i < yLength; i++) {
dataY.im = new Float64Array(yLength);
dataY.im[i] += imaginaryVerticalData.z[i][xIndex];
}
}
}

const horizontal = initiateDatum1D({ info: infoX, data: dataX });
const vertical = initiateDatum1D({ info: infoY, data: dataY });
return { horizontal, vertical };
}

function initiateData(from: number, to: number, length: number): NmrData1D {
return {
x: zoneToX({ from, to }, length),
re: new Float64Array(length),
};
}

function getRealData(data: NmrData2D, info: Info2D) {
if (info.isFid) {
return (data as NmrData2DFid).re;
}
return (data as NmrData2DFt).rr;
}
function getImaginaryData(
data: NmrData2D,
info: Info2D,
options: { ftObjectKey?: 'ir' | 'ri' } = {},
) {
if (info.isFid) {
return (data as NmrData2DFid).im;
}
const { ftObjectKey = 'ir' } = options;

return (data as NmrData2DFt)?.[ftObjectKey];
}

0 comments on commit 110998a

Please sign in to comment.