Skip to content

Commit

Permalink
feat: improve 1D apodization (#3260)
Browse files Browse the repository at this point in the history
* fix: typo in the type name

* fix: add shape to manual peak added

* fix: apodization 1D options

* chore: correct use of generalized lorentzian

* chore: update format apodization

* chore: update nmr deps

* chore: include gamma

* fix: split back apodization 2D into dimensions

* chore: force nmr-load-save v13.0.2

* chore: fix prettier

* chore: work in progress to new splitted FilterManages

* Update package.json

Co-authored-by: Luc Patiny <[email protected]>

* chore: use pre release nmr-processing

* chore: work in progress refactor

* chore: adapt defaultApodizationOptions but there is a bug in nmr-processing

* chore: refactor to use both Filters1DManager n Filters2DManager

* chore: missing typing corrections

* chore: refactor FiltersActions

* refactor: adaptation to Filters with types

* chore: pass draft data directly to the filter

* refactor: adapt to typed Filters

* chore: update pre-release nmr-processing

* chore: update nmr-processing and nmr-load-save to pre-release

* refactor: filters and types

* chore: update nmr-processing and nmr-load-save

* refactor: apodization line component

* feat: improve apodization

* fix: apodization guide line

* chore: update nmr-processing and nmr-load-save

* fix: autprocessing filter and getFilterLabel by name

* chore: prerelease nmr-processing fixing filters

* fix: show filter error message and set background color red

* chore(eslint): disable switch-exhaustiveness-check rule

* chore: update nmr-processing

* chore: fix eslint

* chore: update nmr-load-save to version 2.0.1

* test: fix apodization test

* refactor: repalce useWatch hook with watch

* refactor: prevent change the line boroadening if the exponential filter not activated

* fix: remove Nucleus/Nuclei from types

* fix eslint

* fix: matrix generation types

---------

Co-authored-by: hamed musallam <[email protected]>
Co-authored-by: Michaël Zasso <[email protected]>
Co-authored-by: Luc Patiny <[email protected]>
  • Loading branch information
4 people authored Nov 20, 2024
1 parent e5071fe commit 797fea4
Show file tree
Hide file tree
Showing 80 changed files with 1,614 additions and 1,588 deletions.
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"typescript.tsdk": "node_modules/typescript/lib",
"references.preferredLocation": "view"
"references.preferredLocation": "view",
}
7 changes: 1 addition & 6 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,7 @@ export default [
},
{
rules: {
//todo remove the following rules once fixed: https://github.com/eslint/eslint/issues/19134
// start
'@typescript-eslint/no-unused-expressions': 'off',
'@typescript-eslint/dot-notation': 'off',
'@typescript-eslint/no-empty-function': 'off',
//end
'@typescript-eslint/switch-exhaustiveness-check': 'off',
'import/default': 'off',
'import/no-unresolved': 'off',
'react-refresh/only-export-components': 'off',
Expand Down
1,294 changes: 498 additions & 796 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@
"ml-tree-similarity": "^2.2.0",
"multiplet-analysis": "^2.1.2",
"nmr-correlation": "^2.3.3",
"nmr-load-save": "^1.2.0",
"nmr-processing": "^12.12.3",
"nmr-load-save": "^2.0.4",
"nmr-processing": "^14.0.3",
"nmredata": "^0.9.11",
"numeral": "^2.0.6",
"openchemlib": "^8.17.0",
Expand Down
55 changes: 19 additions & 36 deletions src/component/1d/ApodizationLine.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import merge from 'lodash/merge.js';
import type { Spectrum1D } from 'nmr-load-save';
import { apodization, Filters } from 'nmr-processing';
import {
Filters1D,
createApodizationWindowData,
default1DApodization,
} from 'nmr-processing';

import { defaultApodizationOptions } from '../../data/constants/DefaultApodizationOptions.js';
import { useChartData } from '../context/ChartContext.js';
import { useScaleChecked } from '../context/ScaleContext.js';
import { useActiveSpectrum } from '../hooks/useActiveSpectrum.js';
Expand All @@ -26,11 +30,11 @@ function useWindowYScale() {
});
}

function ApodizationLine() {
export function ApodizationLine() {
const {
toolOptions: {
selectedTool,
data: { apodizationOptions },
data: { apodizationOptions: externalApodizationOptions },
},
} = useChartData();
const activeSpectrum = useActiveSpectrum();
Expand All @@ -39,44 +43,25 @@ function ApodizationLine() {
const xyReduce = useXYReduce(XYReducerDomainAxis.XAxis);
const scaleY = useWindowYScale();

if (!activeSpectrum?.id || selectedTool !== Filters.apodization.id) {
if (!activeSpectrum?.id || selectedTool !== Filters1D.apodization.name) {
return null;
}

const paths = () => {
const pathBuilder = new PathBuilder();
const { re, im = [], x } = spectrum.data;

const { lineBroadening, gaussBroadening, lineBroadeningCenter } =
apodizationOptions || defaultApodizationOptions;
const { re, x } = spectrum.data;

const apodizationOptions = merge(
default1DApodization,
externalApodizationOptions,
);
const length = re.length;
const dw = (x[length - 1] - x[0]) / (length - 1);
const { windowData: y } = apodization(
{ re, im },
{
apply: false,
compose: {
length,
shapes: [
{
start: 0,
shape: {
kind: 'lorentzToGauss',
options: {
length,
dw,
exponentialHz:
gaussBroadening > 0 ? lineBroadening : -lineBroadening,
gaussianHz: gaussBroadening,
center: lineBroadeningCenter,
},
},
},
],
},
},
);

const y = createApodizationWindowData({
windowOptions: { dw, length },
shapes: apodizationOptions,
});

if (x && y) {
const pathPoints = xyReduce({ x, y });
Expand All @@ -102,5 +87,3 @@ function ApodizationLine() {
/>
);
}

export default ApodizationLine;
2 changes: 1 addition & 1 deletion src/component/1d/Chart1D.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import SpectrumInfoBlock from '../1d-2d/components/SpectrumInfoBlock.js';
import { usePreferences } from '../context/PreferencesContext.js';

import ApodizationLine from './ApodizationLine.js';
import { ApodizationLine } from './ApodizationLine.js';
import ExclusionZonesAnnotations from './ExclusionZonesAnnotations.js';
import LinesSeries from './LinesSeries.js';
import SimilarityTree from './SimilarityTree.js';
Expand Down
6 changes: 3 additions & 3 deletions src/component/1d/ExclusionZoneAnnotation.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react';
import { Filters } from 'nmr-processing';
import { Filters1D } from 'nmr-processing';
import { memo } from 'react';

import type { ExclusionZone } from '../../data/types/data1d/ExclusionZone.js';
Expand Down Expand Up @@ -31,7 +31,7 @@ function ExclusionZoneAnnotation({
}: ExclusionZoneProps) {
const { scaleX, scaleY } = useScaleChecked();
const type =
filterId === Filters.signalProcessing.id
filterId === Filters1D.signalProcessing.name
? HighlightEventSource.MATRIX_GENERATION_EXCLUSION_ZONE
: HighlightEventSource.EXCLUSION_ZONE;
const highlight = useHighlight([], {
Expand All @@ -50,7 +50,7 @@ function ExclusionZoneAnnotation({
width={`${scaleX()(zone.from) - scaleX()(zone.to)}`}
height="10px"
style={{
fill: filterId === Filters.signalProcessing.id ? 'gray' : color,
fill: filterId === Filters1D.signalProcessing.name ? 'gray' : color,
opacity,
}}
{...highlight.onHover}
Expand Down
13 changes: 8 additions & 5 deletions src/component/1d/ExclusionZonesAnnotations.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Spectrum1D } from 'nmr-load-save';
import { Filters } from 'nmr-processing';
import { Filters1D } from 'nmr-processing';
import { memo } from 'react';

import type { ExclusionZone } from '../../data/types/data1d/ExclusionZone.js';
Expand Down Expand Up @@ -76,11 +76,14 @@ function getExclusionZones(
): Array<{ id: string; zones: ExclusionZone[] }> {
const zones: Array<{ id: string; zones: ExclusionZone[] }> = [];
for (const filter of data.filters) {
if (filter.name === Filters.exclusionZones.id && filter.flag) {
zones.push({ id: Filters.exclusionZones.id, zones: filter.value });
} else if (filter.name === Filters.signalProcessing.id && filter.flag) {
if (filter.name === Filters1D.exclusionZones.name && filter.enabled) {
zones.push({ id: Filters1D.exclusionZones.name, zones: filter.value });
} else if (
filter.name === Filters1D.signalProcessing.name &&
filter.enabled
) {
zones.push({
id: Filters.signalProcessing.id,
id: Filters1D.signalProcessing.name,
zones: filter.value.exclusionsZones,
});
}
Expand Down
7 changes: 2 additions & 5 deletions src/component/1d/matrix/useMatrix.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import type { NumberArray } from 'cheminfo-types';
import type { Spectrum } from 'nmr-load-save';
import { Filters } from 'nmr-processing';
import { useMemo } from 'react';

import { isSpectrum1D } from '../../../data/data1d/Spectrum1D/index.js';
import { useChartData } from '../../context/ChartContext.js';
import useSpectraByActiveNucleus from '../../hooks/useSpectraPerNucleus.js';

const { signalProcessing } = Filters;

/**
* This method will slice the array from the fromIndex to the toIndex and add the first and last element of the original array
* if needed
Expand Down Expand Up @@ -53,9 +50,9 @@ export function useMatrix() {
for (let i = 0; i < spectra.length; i++) {
const spectrum = spectra[i];
const filter = spectrum.filters.find(
(filter) => filter.name === signalProcessing.id,
(filter) => filter.name === 'signalProcessing',
);
if (isSpectrum1D(spectrum) && filter?.flag) {
if (isSpectrum1D(spectrum) && filter?.enabled) {
matrixY[i] = spectrum.data.re;
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/component/1d/multiAnalysis/MultiAnalysisRanges.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { SpectraAnalysisColumns } from 'nmr-load-save';
import { AnalysisColumnsTypes } from 'nmr-load-save';
import { ANALYSIS_COLUMN_TYPES } from 'nmr-load-save';
import { memo } from 'react';

import { useChartData } from '../../context/ChartContext.js';
Expand All @@ -19,7 +19,7 @@ function MultiAnalysisRangesInner({
activeTab,
}: MultiAnalysisRangesInnerProps) {
const ranges = Object.keys(columns).filter(
(key) => columns[key].type !== AnalysisColumnsTypes.FORMULA,
(key) => columns[key].type !== ANALYSIS_COLUMN_TYPES.FORMULA,
);

if (!ranges || ranges.length === 0) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Spectrum1D, Spectrum2D } from 'nmr-load-save';
import { Filters } from 'nmr-processing';
import { Filters1D } from 'nmr-processing';
import type { ReactNode } from 'react';

import { getSlice } from '../../../../data/data2d/Spectrum2D/index.js';
Expand Down Expand Up @@ -143,7 +143,7 @@ function InnerSpectrumPhaseTrace(props: InnerSpectrumPhaseTraceProps) {
info: { isComplex: true, isFid: false },
};

Filters.phaseCorrection.apply(spectrum as unknown as Spectrum1D, {
Filters1D.phaseCorrection.apply(spectrum as Spectrum1D, {
ph0,
ph1,
});
Expand Down
4 changes: 1 addition & 3 deletions src/component/2d/utilities/DimensionLayout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,7 @@ interface StartEndProps {
endY?: number;
}

type DimensionType = {
[key in Layout]: Required<StartEndProps>;
};
type DimensionType = Record<Layout, Required<StartEndProps>>;

function getLayoutID(
dimension: DimensionType,
Expand Down
37 changes: 27 additions & 10 deletions src/component/elements/Sections.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ import { createContext, useContext, useMemo } from 'react';
interface SelectionsContextState {
overflow: boolean;
renderActiveSectionContentOnly: boolean;
matchContentHeight: boolean;
}

const selectionState: SelectionsContextState = {
overflow: false,
renderActiveSectionContentOnly: false,
matchContentHeight: false,
};

const SectionsContext = createContext<SelectionsContextState>(selectionState);
Expand All @@ -36,10 +38,13 @@ interface ActiveProps {
overflow?: boolean;
}

const Container = styled.div<{ overflow: boolean }>(
({ overflow }) => `
const Container = styled.div<{
overflow: boolean;
matchContentHeight: boolean;
}>(
({ overflow, matchContentHeight }) => `
width: 100%;
height: 100%;
height: ${matchContentHeight ? 'auto' : '100%'};
display: flex;
flex-direction: column;
overflow: ${overflow ? 'auto' : 'hidden'};
Expand Down Expand Up @@ -139,6 +144,7 @@ interface BaseSectionProps {
rightElement?: ReactNode | ((isOpen) => ReactNode);
leftElement?: ReactNode | ((isOpen) => ReactNode);
headerStyle?: CSSProperties;
arrowProps?: { style?: CSSProperties; hide?: boolean };
}

interface SectionItemProps extends BaseSectionProps {
Expand All @@ -147,28 +153,31 @@ interface SectionItemProps extends BaseSectionProps {
children?: ReactNode | ((options: { isOpen?: boolean }) => ReactNode);
isOpen: boolean;
sticky?: boolean;
matchContentHeight?: boolean;
}

interface SectionProps {
children?: ReactNode;
overflow?: boolean;
renderActiveSectionContentOnly?: boolean;
matchContentHeight?: boolean;
}

export function Sections(props: SectionProps) {
const {
children,
overflow = false,
renderActiveSectionContentOnly = false,
matchContentHeight = false,
} = props;

const state = useMemo(() => {
return { overflow, renderActiveSectionContentOnly };
}, [overflow, renderActiveSectionContentOnly]);
return { overflow, renderActiveSectionContentOnly, matchContentHeight };
}, [overflow, renderActiveSectionContentOnly, matchContentHeight]);
return (
<SectionsContext.Provider value={state}>
<Container overflow={overflow}>{children}</Container>
<Container overflow={overflow} matchContentHeight={matchContentHeight}>
{children}
</Container>
</SectionsContext.Provider>
);
}
Expand Down Expand Up @@ -196,10 +205,10 @@ function SectionItem(props: SectionItemProps) {
headerStyle,
isOpen,
sticky = false,
matchContentHeight = false,
arrowProps = { hide: false, style: {} },
} = props;

const { overflow } = useSections();
const { overflow, matchContentHeight } = useSections();

return (
<SectionWrapper
Expand All @@ -216,6 +225,7 @@ function SectionItem(props: SectionItemProps) {
leftElement={leftElement}
headerStyle={headerStyle}
sticky={sticky}
arrowProps={arrowProps}
/>
<Wrapper isOpen={isOpen}>{children}</Wrapper>
</SectionWrapper>
Expand Down Expand Up @@ -260,6 +270,7 @@ function MainSectionHeader(props: MainSectionHeaderProps) {
leftElement,
headerStyle = {},
sticky,
arrowProps,
} = props;
return (
<Header
Expand Down Expand Up @@ -292,7 +303,13 @@ function MainSectionHeader(props: MainSectionHeaderProps) {
? rightElement(isOpen)
: rightElement}
</ElementsContainer>
<OpenIcon icon="chevron-right" isOpen={isOpen} />
{!arrowProps?.hide && (
<OpenIcon
icon="chevron-right"
isOpen={isOpen}
style={arrowProps?.style}
/>
)}
</ElementsContainer>
</Header>
);
Expand Down
Loading

0 comments on commit 797fea4

Please sign in to comment.