From 70ece73dd80078738f6e5ca24b5fde08d807c67d Mon Sep 17 00:00:00 2001 From: Jefferson Casimir Date: Wed, 6 Dec 2023 14:35:52 -0500 Subject: [PATCH] Added use of valid samples in last chunk to display values correctly --- .../src/eeglab/EEGLabSeriesProvider.tsx | 3 +- .../src/series/components/LineChunk.tsx | 12 ++++---- .../src/series/store/logic/fetchChunks.tsx | 28 ++++++++++++++----- .../src/series/store/state/dataset.tsx | 3 ++ 4 files changed, 33 insertions(+), 13 deletions(-) diff --git a/modules/electrophysiology_browser/jsx/react-series-data-viewer/src/eeglab/EEGLabSeriesProvider.tsx b/modules/electrophysiology_browser/jsx/react-series-data-viewer/src/eeglab/EEGLabSeriesProvider.tsx index ab79a11f815..0ada78725ca 100644 --- a/modules/electrophysiology_browser/jsx/react-series-data-viewer/src/eeglab/EEGLabSeriesProvider.tsx +++ b/modules/electrophysiology_browser/jsx/react-series-data-viewer/src/eeglab/EEGLabSeriesProvider.tsx @@ -95,12 +95,13 @@ class EEGLabSeriesProvider extends Component { Promise.race(racers(fetchJSON, chunksURL, '/index.json')).then( ({json, url}) => { if (json) { - const {channelMetadata, shapes, timeInterval, seriesRange} = json; + const {channelMetadata, shapes, timeInterval, seriesRange, validSamples} = json; this.store.dispatch( setDatasetMetadata({ chunksURL: url, channelMetadata, shapes, + validSamples, timeInterval, seriesRange, limit, diff --git a/modules/electrophysiology_browser/jsx/react-series-data-viewer/src/series/components/LineChunk.tsx b/modules/electrophysiology_browser/jsx/react-series-data-viewer/src/series/components/LineChunk.tsx index 7f1bde16625..fe3ed61d9b0 100644 --- a/modules/electrophysiology_browser/jsx/react-series-data-viewer/src/series/components/LineChunk.tsx +++ b/modules/electrophysiology_browser/jsx/react-series-data-viewer/src/series/components/LineChunk.tsx @@ -7,10 +7,12 @@ import {Group} from '@visx/group'; import {colorOrder} from '../../color'; const LineMemo = R.memoizeWith( - ({amplitudeScale, filters, channelIndex, traceIndex, - chunkIndex, isStacked, DCOffset, numChannels, - numChunks, previousPoint}) => - `${amplitudeScale},${filters.join('-')},` + ({amplitudeScale, interval, filters, + channelIndex, traceIndex, chunkIndex, + isStacked, DCOffset, numChannels, + numChunks, previousPoint, + }) => + `${amplitudeScale},${interval.join('-')},${filters.join('-')},` + `${channelIndex}-${traceIndex}-${chunkIndex},` + `${isStacked},${DCOffset},${numChannels},` + `${numChunks},${previousPoint}`, @@ -152,7 +154,7 @@ const LineChunk = ({ top={-p0[1]} > diff --git a/modules/electrophysiology_browser/jsx/react-series-data-viewer/src/series/store/logic/fetchChunks.tsx b/modules/electrophysiology_browser/jsx/react-series-data-viewer/src/series/store/logic/fetchChunks.tsx index e7066cfabb3..650952f444c 100644 --- a/modules/electrophysiology_browser/jsx/react-series-data-viewer/src/series/store/logic/fetchChunks.tsx +++ b/modules/electrophysiology_browser/jsx/react-series-data-viewer/src/series/store/logic/fetchChunks.tsx @@ -110,7 +110,7 @@ export const createFetchChunksEpic = (fromState: (any) => State) => ( Rx.map(([, state]) => fromState(state)), Rx.debounceTime(UPDATE_DEBOUNCE_TIME), Rx.concatMap(({bounds, dataset, channels}) => { - const {chunksURL, shapes, timeInterval} = dataset; + const {chunksURL, shapes, validSamples, timeInterval} = dataset; if (!chunksURL) { return of(); } @@ -123,19 +123,25 @@ export const createFetchChunksEpic = (fromState: (any) => State) => ( const shapeChunks = shapes.map((shape) => shape[shape.length - 2]); - const chunkIntervals : chunkIntervals[] = shapeChunks + const valuesPerChunk = + shapes.map((shape) => shape[shape.length - 1]); + + const chunkIntervals = shapeChunks .map((numChunks, downsampling) => { const recordingDuration = Math.abs( timeInterval[1] - timeInterval[0] ); + const filledChunks = (numChunks - 1) + + (validSamples[downsampling] / valuesPerChunk[downsampling]); + const i0 = - (numChunks * + (filledChunks * Math.floor(bounds.interval[0] - bounds.domain[0]) ) / recordingDuration; const i1 = - (numChunks * + (filledChunks * Math.ceil(bounds.interval[1] - bounds.domain[0]) ) / recordingDuration; @@ -145,7 +151,11 @@ export const createFetchChunksEpic = (fromState: (any) => State) => ( ]; return { - interval: interval, + interval: + [ + Math.floor(i0), + Math.min(Math.ceil(i1), filledChunks), + ], numChunks: numChunks, downsampling, }; @@ -164,12 +174,16 @@ export const createFetchChunksEpic = (fromState: (any) => State) => ( const chunkPromises = R.range(...finestChunks.interval).flatMap( (chunkIndex) => { const numChunks = finestChunks.numChunks; + + const filledChunks = (numChunks - 1) + + (validSamples[finestChunks.downsampling] / valuesPerChunk[finestChunks.downsampling]); + const chunkInterval = [ timeInterval[0] + - (chunkIndex / numChunks) * + (chunkIndex / filledChunks) * (timeInterval[1] - timeInterval[0]), timeInterval[0] + - ((chunkIndex + 1) / numChunks) * + ((chunkIndex + 1) / filledChunks) * (timeInterval[1] - timeInterval[0]), ]; if (chunkInterval[0] <= bounds.interval[1]) { diff --git a/modules/electrophysiology_browser/jsx/react-series-data-viewer/src/series/store/state/dataset.tsx b/modules/electrophysiology_browser/jsx/react-series-data-viewer/src/series/store/state/dataset.tsx index 08d7fa07149..399696f0b55 100644 --- a/modules/electrophysiology_browser/jsx/react-series-data-viewer/src/series/store/state/dataset.tsx +++ b/modules/electrophysiology_browser/jsx/react-series-data-viewer/src/series/store/state/dataset.tsx @@ -29,6 +29,7 @@ export type Action = chunksURL: string, channelNames: string[], shapes: number[][], + validSamples: number[], timeInterval: [number, number], seriesRange: [number, number], limit: number, @@ -46,6 +47,7 @@ export type State = { activeEpoch: number | null, physioFileID: number | null, shapes: number[][], + validSamples: number[], timeInterval: [number, number], seriesRange: [number, number], }; @@ -68,6 +70,7 @@ export const datasetReducer = ( offsetIndex: 1, limit: DEFAULT_MAX_CHANNELS, shapes: [], + validSamples: [], timeInterval: [0, 1], seriesRange: [-1, 2], },