Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 2d apodization #3299

Merged
merged 2 commits into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions 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 @@ -88,7 +88,7 @@
"ml-tree-similarity": "^2.2.0",
"multiplet-analysis": "^2.1.2",
"nmr-correlation": "^2.3.3",
"nmr-load-save": "^2.0.4",
"nmr-load-save": "^2.1.0",
"nmr-processing": "^14.0.3",
"nmredata": "^0.9.11",
"numeral": "^2.0.6",
Expand Down
11 changes: 6 additions & 5 deletions src/component/1d/ApodizationLine.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import {
} from 'nmr-processing';

import { useChartData } from '../context/ChartContext.js';
import { useFilterSyncOptions } from '../context/FilterSyncOptionsContext.js';
import { useScaleChecked } from '../context/ScaleContext.js';
import { useActiveSpectrum } from '../hooks/useActiveSpectrum.js';
import useSpectrum from '../hooks/useSpectrum.js';
import { useVerticalAlign } from '../hooks/useVerticalAlign.js';
import useXYReduce, { XYReducerDomainAxis } from '../hooks/useXYReduce.js';
import type { ApodizationOptions } from '../panels/filtersPanel/Filters/hooks/useSharedApodization.js';
import { PathBuilder } from '../utility/PathBuilder.js';

import { getYScale } from './utilities/scale.js';
Expand All @@ -32,16 +34,15 @@ function useWindowYScale() {

export function ApodizationLine() {
const {
toolOptions: {
selectedTool,
data: { apodizationOptions: externalApodizationOptions },
},
toolOptions: { selectedTool },
} = useChartData();
const activeSpectrum = useActiveSpectrum();
const { scaleX } = useScaleChecked();
const spectrum = useSpectrum({ emptyData }) as Spectrum1D;
const xyReduce = useXYReduce(XYReducerDomainAxis.XAxis);
const scaleY = useWindowYScale();
const { sharedFilterOptions: externalApodizationOptions } =
useFilterSyncOptions<ApodizationOptions>();

if (!activeSpectrum?.id || selectedTool !== Filters1D.apodization.name) {
return null;
Expand All @@ -53,7 +54,7 @@ export function ApodizationLine() {

const apodizationOptions = merge(
default1DApodization,
externalApodizationOptions,
externalApodizationOptions?.options,
);
const length = re.length;
const dw = (x[length - 1] - x[0]) / (length - 1);
Expand Down
104 changes: 104 additions & 0 deletions src/component/header/BaseSimpleApodizationOptionsPanel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { Checkbox } from '@blueprintjs/core';

import { useToaster } from '../context/ToasterContext.js';
import ActionButtons from '../elements/ActionButtons.js';
import Label from '../elements/Label.js';
import { NumberInput2Controller } from '../elements/NumberInput2Controller.js';
import { useSharedApodization } from '../panels/filtersPanel/Filters/hooks/useSharedApodization.js';
import type {
ApodizationFilterOptions,
UseSharedApodizationOptions,
} from '../panels/filtersPanel/Filters/hooks/useSharedApodization.js';

import { headerLabelStyle } from './Header.js';
import { HeaderWrapper } from './HeaderWrapper.js';

interface BaseSimpleApodizationOptionsPanelProps
extends Pick<
UseSharedApodizationOptions,
'onApplyDispatch' | 'onChangeDispatch'
> {
filter: ApodizationFilterOptions | null;
}

export function BaseSimpleApodizationOptionsPanel(
props: BaseSimpleApodizationOptionsPanelProps,
) {
const toaster = useToaster();

const { filter, onApplyDispatch, onChangeDispatch } = props;

const { formMethods, submitHandler, handleApplyFilter, handleCancelFilter } =
useSharedApodization(filter, {
applyFilterOnload: true,
onApplyDispatch,
onChangeDispatch,
});

const {
register,
handleSubmit,
control,
formState: { isValid },
watch,
} = formMethods;

const isExponentialActive = watch('options.exponential.apply') || false;

const { onChange: onLivePreviewFieldChange, ...livePreviewFieldOptions } =
register('livePreview');

function handleClick() {
if (!isExponentialActive) {
toaster.show({
intent: 'danger',
message:
'Activate "Exponential" filter from the Processing panel first',
});
}
}

function handleConfirm() {
void handleSubmit((values) => handleApplyFilter(values))();
}

function handleCancel() {
handleCancelFilter();
}

return (
<HeaderWrapper>
<Label title="Line broadening:" shortTitle="LB:" style={headerLabelStyle}>
<NumberInput2Controller
control={control}
name="options.exponential.options.lineBroadening"
debounceTime={250}
stepSize={0.1}
style={{ width: '60px' }}
onValueChange={() => {
submitHandler();
}}
readOnly={!isExponentialActive}
onClick={handleClick}
/>
</Label>

<Label title="Live preview" style={{ label: { padding: '0 5px' } }}>
<Checkbox
{...livePreviewFieldOptions}
onChange={(event) => {
void onLivePreviewFieldChange(event);
submitHandler();
}}
style={{ margin: 0 }}
/>
</Label>

<ActionButtons
disabledDone={!isValid}
onDone={handleConfirm}
onCancel={handleCancel}
/>
</HeaderWrapper>
);
}
6 changes: 6 additions & 0 deletions src/component/header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ import { options } from '../toolbar/ToolTypes.js';
import { AutoPeakPickingOptionPanel } from './AutoPeakPickingOptionPanel.js';
import { HeaderWrapper } from './HeaderWrapper.js';
import RangesPickingOptionPanel from './RangesPickingOptionPanel.js';
import { SimpleApodizationDimensionOneOptionsPanel } from './SimpleApodizationDimensionOneOptionsPanel.js';
import { SimpleApodizationDimensionTwoOptionsPanel } from './SimpleApodizationDimensionTwoOptionsPanel.js';
import { SimpleApodizationOptionsPanel } from './SimpleApodizationOptionsPanel.js';
import { SimpleBaseLineCorrectionOptionsPanel } from './SimpleBaseLineCorrectionOptionsPanel.js';
import { SimplePhaseCorrectionOptionsPanel } from './SimplePhaseCorrectionOptionsPanel.js';
Expand Down Expand Up @@ -104,6 +106,10 @@ function HeaderInner(props: HeaderInnerProps) {
switch (selectedOptionPanel) {
case options.apodization.id:
return <SimpleApodizationOptionsPanel />;
case options.apodizationDimension1.id:
return <SimpleApodizationDimensionOneOptionsPanel />;
case options.apodizationDimension2.id:
return <SimpleApodizationDimensionTwoOptionsPanel />;
case options.zeroFilling.id:
return <SimpleZeroFillingOptionsPanel />;
case options.phaseCorrection.id:
Expand Down
54 changes: 54 additions & 0 deletions src/component/header/SimpleApodizationDimensionOneOptionsPanel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { memo, useCallback } from 'react';

import type { ExtractFilterEntry } from '../../data/types/common/ExtractFilterEntry.js';
import { useDispatch } from '../context/DispatchContext.js';
import { useFilter } from '../hooks/useFilter.js';

import { BaseSimpleApodizationOptionsPanel } from './BaseSimpleApodizationOptionsPanel.js';

interface ApodizationOptionsInnerPanelProps {
filter: ExtractFilterEntry<'apodizationDimension1'> | null;
}

function ApodizationOptionsInnerPanel(
props: ApodizationOptionsInnerPanelProps,
) {
const dispatch = useDispatch();

const applyHandler = useCallback(
(data) => {
const { options } = data;
dispatch({
type: 'APPLY_APODIZATION_DIMENSION_ONE_FILTER',
payload: { options },
});
},
[dispatch],
);
const changeHandler = useCallback(
(data) => {
const { livePreview, options } = data;

dispatch({
type: 'CALCULATE_APODIZATION_DIMENSION_ONE_FILTER',
payload: { livePreview, options: structuredClone(options) },
});
},
[dispatch],
);

return (
<BaseSimpleApodizationOptionsPanel
filter={props.filter}
onApplyDispatch={applyHandler}
onChangeDispatch={changeHandler}
/>
);
}

const MemoizedApodizationPanel = memo(ApodizationOptionsInnerPanel);

export function SimpleApodizationDimensionOneOptionsPanel() {
const filter = useFilter('apodizationDimension1');
return <MemoizedApodizationPanel filter={filter} />;
}
54 changes: 54 additions & 0 deletions src/component/header/SimpleApodizationDimensionTwoOptionsPanel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { memo, useCallback } from 'react';

import type { ExtractFilterEntry } from '../../data/types/common/ExtractFilterEntry.js';
import { useDispatch } from '../context/DispatchContext.js';
import { useFilter } from '../hooks/useFilter.js';

import { BaseSimpleApodizationOptionsPanel } from './BaseSimpleApodizationOptionsPanel.js';

interface ApodizationOptionsInnerPanelProps {
filter: ExtractFilterEntry<'apodizationDimension2'> | null;
}

function ApodizationOptionsInnerPanel(
props: ApodizationOptionsInnerPanelProps,
) {
const dispatch = useDispatch();

const applyHandler = useCallback(
(data) => {
const { options } = data;
dispatch({
type: 'APPLY_APODIZATION_DIMENSION_TWO_FILTER',
payload: { options },
});
},
[dispatch],
);
const changeHandler = useCallback(
(data) => {
const { livePreview, options } = data;

dispatch({
type: 'CALCULATE_APODIZATION_DIMENSION_TWO_FILTER',
payload: { livePreview, options: structuredClone(options) },
});
},
[dispatch],
);

return (
<BaseSimpleApodizationOptionsPanel
filter={props.filter}
onApplyDispatch={applyHandler}
onChangeDispatch={changeHandler}
/>
);
}

const MemoizedApodizationPanel = memo(ApodizationOptionsInnerPanel);

export function SimpleApodizationDimensionTwoOptionsPanel() {
const filter = useFilter('apodizationDimension2');
return <MemoizedApodizationPanel filter={filter} />;
}
Loading
Loading