From 7a7832fc2598e2acab84ab9e01d6ec7ac7fa2820 Mon Sep 17 00:00:00 2001 From: Salma Baig <76014459+hydrowoxy@users.noreply.github.com> Date: Wed, 1 Oct 2025 14:38:19 -0400 Subject: [PATCH 01/14] added strict smooth prim/sec analyzer for sgolay and stricttimestamp simultaneously --- .../analyzer/SmoothStrictPrimAnalyzer.java | 54 ++++++++++ .../analyzer/SmoothStrictSecAnalyzer.java | 54 ++++++++++ .../com/mcmasterbaja/model/AnalyzerType.java | 4 +- .../src/pages/Homepage/dataSelect.module.scss | 51 +++++++++ front-end/src/pages/Homepage/dataSelect.tsx | 101 ++++++++++++++++++ front-end/src/types/AnalyzerTypes.ts | 26 ++++- front-end/src/types/ApiTypes.ts | 3 +- 7 files changed, 290 insertions(+), 3 deletions(-) create mode 100644 backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictPrimAnalyzer.java create mode 100644 backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictSecAnalyzer.java create mode 100644 front-end/src/pages/Homepage/dataSelect.module.scss create mode 100644 front-end/src/pages/Homepage/dataSelect.tsx diff --git a/backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictPrimAnalyzer.java b/backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictPrimAnalyzer.java new file mode 100644 index 00000000..468e4744 --- /dev/null +++ b/backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictPrimAnalyzer.java @@ -0,0 +1,54 @@ +package com.mcmasterbaja.analyzer; + +import com.mcmasterbaja.annotations.OnAnalyzerException; +import com.mcmasterbaja.model.AnalyzerParams; +import com.mcmasterbaja.model.AnalyzerType; +import jakarta.enterprise.context.Dependent; +import jakarta.inject.Inject; +import lombok.SneakyThrows; +import org.jboss.logging.Logger; + +@Dependent +@AnalyzerQualifier(AnalyzerType.SMOOTH_STRICT_PRIM) +@OnAnalyzerException +public class SmoothStrictPrimAnalyzer extends Analyzer { + + @Inject + private Logger logger; + @Inject + private AnalyzerFactory factory; + + @Override + @SneakyThrows + public void analyze(AnalyzerParams params) { + extractParams(params); + logger.info("Running pipeline: StrictTimestamp -> sGolay (single file RPM)"); + + // Single file and column + String file = params.getInputFiles()[0]; + String col = params.getInputColumns()[0]; + + // 1) StrictTimestamp for the single file/column + Analyzer strict = factory.getAnalyzer(AnalyzerType.STRICT_TIMESTAMP); + AnalyzerParams sp = new AnalyzerParams(); + sp.setInputFiles(new String[] { file }); + sp.setInputColumns(new String[] { col }); + sp.setType(AnalyzerType.STRICT_TIMESTAMP); + sp.setOptions(new String[0]); + sp.generateOutputFileNames(); + strict.analyze(sp); + String strictOut = sp.getOutputFiles()[0]; + + // 2) Savitzky-Golay for the strict timestamp output + Analyzer sGolay = factory.getAnalyzer(AnalyzerType.SGOLAY); + AnalyzerParams sg = new AnalyzerParams(); + sg.setInputFiles(new String[] { strictOut, strictOut }); + sg.setInputColumns(new String[] { "Timestamp (ms)", "RPM PRIM" }); + sg.setType(AnalyzerType.SGOLAY); + sg.setOptions(new String[] { "101", "3" }); + sg.setOutputFiles(params.getOutputFiles()); + sGolay.analyze(sg); + + logger.info("Completed pipeline: StrictTimestamp -> sGolay for single file RPM"); + } +} diff --git a/backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictSecAnalyzer.java b/backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictSecAnalyzer.java new file mode 100644 index 00000000..47bb4562 --- /dev/null +++ b/backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictSecAnalyzer.java @@ -0,0 +1,54 @@ +package com.mcmasterbaja.analyzer; + +import com.mcmasterbaja.annotations.OnAnalyzerException; +import com.mcmasterbaja.model.AnalyzerParams; +import com.mcmasterbaja.model.AnalyzerType; +import jakarta.enterprise.context.Dependent; +import jakarta.inject.Inject; +import lombok.SneakyThrows; +import org.jboss.logging.Logger; + +@Dependent +@AnalyzerQualifier(AnalyzerType.SMOOTH_STRICT_SEC) +@OnAnalyzerException +public class SmoothStrictSecAnalyzer extends Analyzer { + + @Inject + private Logger logger; + @Inject + private AnalyzerFactory factory; + + @Override + @SneakyThrows + public void analyze(AnalyzerParams params) { + extractParams(params); + logger.info("Running pipeline: StrictTimestamp -> sGolay (single file RPM)"); + + // Single file and column + String file = params.getInputFiles()[0]; + String col = params.getInputColumns()[0]; + + // 1) StrictTimestamp for the single file/column + Analyzer strict = factory.getAnalyzer(AnalyzerType.STRICT_TIMESTAMP); + AnalyzerParams sp = new AnalyzerParams(); + sp.setInputFiles(new String[] { file }); + sp.setInputColumns(new String[] { col }); + sp.setType(AnalyzerType.STRICT_TIMESTAMP); + sp.setOptions(new String[0]); + sp.generateOutputFileNames(); + strict.analyze(sp); + String strictOut = sp.getOutputFiles()[0]; + + // 2) Savitzky-Golay for the strict timestamp output + Analyzer sGolay = factory.getAnalyzer(AnalyzerType.SGOLAY); + AnalyzerParams sg = new AnalyzerParams(); + sg.setInputFiles(new String[] { strictOut, strictOut }); + sg.setInputColumns(new String[] { "Timestamp (ms)", "RPM SEC" }); + sg.setType(AnalyzerType.SGOLAY); + sg.setOptions(new String[] { "101", "3" }); + sg.setOutputFiles(params.getOutputFiles()); + sGolay.analyze(sg); + + logger.info("Completed pipeline: StrictTimestamp -> sGolay for single file RPM"); + } +} diff --git a/backend/src/main/java/com/mcmasterbaja/model/AnalyzerType.java b/backend/src/main/java/com/mcmasterbaja/model/AnalyzerType.java index 82a2960b..c624fe60 100644 --- a/backend/src/main/java/com/mcmasterbaja/model/AnalyzerType.java +++ b/backend/src/main/java/com/mcmasterbaja/model/AnalyzerType.java @@ -13,7 +13,9 @@ public enum AnalyzerType { SPLIT, CONSTANT_ADDER, STRICT_TIMESTAMP, - SHIFT_CURVE; + SHIFT_CURVE, + SMOOTH_STRICT_PRIM, + SMOOTH_STRICT_SEC; public String toString() { return this.name(); diff --git a/front-end/src/pages/Homepage/dataSelect.module.scss b/front-end/src/pages/Homepage/dataSelect.module.scss new file mode 100644 index 00000000..7d582751 --- /dev/null +++ b/front-end/src/pages/Homepage/dataSelect.module.scss @@ -0,0 +1,51 @@ +@use '@styles/mixins'; + +.dataSelect { + display: flex; + flex-direction: column; + gap: 0.75rem; + padding: 0.5rem; + border-radius: 4px; +} + +.row { + display: flex; + gap: 0.5rem; +} + +.inputGroup { + flex: 1; + display: flex; + flex-direction: column; + gap: 0.25rem; + + label { + @include fonts.text-small; + color: var(--text-secondary); + } +} + +.analyzerRow { + display: flex; + flex-direction: column; + gap: 0.25rem; + + label { + @include fonts.text-small; + color: var(--text-secondary); + } + + .analyzerControl { + cursor: pointer; + display: flex; + align-items: center; + gap: 0.5rem; + color: var(--accent-colour); + font-weight: 500; + + .analyzerIcon { + width: 16px; + height: 16px; + } + } +} \ No newline at end of file diff --git a/front-end/src/pages/Homepage/dataSelect.tsx b/front-end/src/pages/Homepage/dataSelect.tsx new file mode 100644 index 00000000..e73c38df --- /dev/null +++ b/front-end/src/pages/Homepage/dataSelect.tsx @@ -0,0 +1,101 @@ +import { useState } from 'react'; +import styles from './dataSelect.module.scss'; +import { Dropdown } from '@components/ui/dropdown/Dropdown'; +import { Column, analyzerConfig } from '@types'; +import { sigmaIcon } from '@assets/icons'; +import { useDashboard } from '@contexts/DashboardContext'; +import { useModal } from '@contexts/ModalContext'; + +interface DataSelectProps { + sources: { value: string; label: string }[]; + dataTypes: { value: string; label: string }[]; + columnKey: 'x' | 'y'; + seriesIndex: number; + chartId: string; + onColumnUpdate: (column: 'x' | 'y', updatedColumn: Partial) => void; + onAnalyzerUpdate: (newAnalyzerType: string | null, newAnalyzerValues: unknown[] | undefined) => void; +} + +export const DataSelect = ({ + sources, + dataTypes, + columnKey, + seriesIndex, + chartId, + onColumnUpdate, + onAnalyzerUpdate +}: DataSelectProps) => { + const { openModal } = useModal(); + const { charts } = useDashboard(); + + const chart = charts.find(c => c.id === chartId); + const series = chart?.series[seriesIndex]; + + if (!series) { + return null; + } + + const currentColumn = series[columnKey]; + const currentAnalyzer = series.analyzer; + + const [selectedSource, setSelectedSource] = useState(currentColumn?.source || ''); + const [selectedDataType, setSelectedDataType] = useState(currentColumn?.dataType || ''); + + const handleSourceChange = (source: string) => { + setSelectedSource(source); + onColumnUpdate(columnKey, { source }); + }; + + const handleDataTypeChange = (dataType: string) => { + setSelectedDataType(dataType); + onColumnUpdate(columnKey, { dataType }); + }; + + const handleAnalyzerClick = () => { + openModal('analyzer', { + initialType: currentAnalyzer?.type, + initialValues: currentAnalyzer?.options, + onSubmit: onAnalyzerUpdate + }); + }; + + const getAnalyzerName = () => { + if (!currentAnalyzer?.type) return 'None'; + const config = analyzerConfig[currentAnalyzer.type]; + return config?.name || 'Unknown'; + }; + + return ( +
+
+
+ + +
+
+ + +
+
+ {columnKey === 'y' && ( +
+ +
+ Analyzer + {getAnalyzerName()} +
+
+ )} +
+ ); +}; \ No newline at end of file diff --git a/front-end/src/types/AnalyzerTypes.ts b/front-end/src/types/AnalyzerTypes.ts index 4ba8ea3e..191f58a7 100644 --- a/front-end/src/types/AnalyzerTypes.ts +++ b/front-end/src/types/AnalyzerTypes.ts @@ -231,4 +231,28 @@ export const analyzerConfig: Record = { }, links: [{ title: 'Cubic Function (Wiki)', url: 'https://en.wikipedia.org/wiki/Cubic_function' }], }, -}; \ No newline at end of file + + [AnalyzerType.SMOOTH_STRICT_PRIM]: { + title: 'Smooth Strict PRIM', + description: + 'Runs StrictTimstamp and Sgolay for RPM PRIM', + isJoinBased: false, + image: { + src: placeholderImage, + alt: 'Strict timestamp demo', + }, + links: [{ title: 'Timestamp (Wiki)', url: 'https://en.wikipedia.org/wiki/Timestamp' }], + }, + + [AnalyzerType.SMOOTH_STRICT_SEC]: { + title: 'Smooth Strict SEC', + description: + 'Runs StrictTimstamp and Sgolay for RPM SEC', + isJoinBased: false, + image: { + src: placeholderImage, + alt: 'Strict timestamp demo', + }, + links: [{ title: 'Timestamp (Wiki)', url: 'https://en.wikipedia.org/wiki/Timestamp' }], + }, +}; \ No newline at end of file diff --git a/front-end/src/types/ApiTypes.ts b/front-end/src/types/ApiTypes.ts index 73fc3ecf..2680db84 100644 --- a/front-end/src/types/ApiTypes.ts +++ b/front-end/src/types/ApiTypes.ts @@ -1,4 +1,3 @@ - export interface FileInformation { key: string; name: string; @@ -38,6 +37,8 @@ export enum AnalyzerType { DELETE_OUTLIER = 'DELETE_OUTLIER', STRICT_TIMESTAMP = 'STRICT_TIMESTAMP', SHIFT_CURVE = 'SHIFT_CURVE', + SMOOTH_STRICT_PRIM = 'SMOOTH_STRICT_PRIM', + SMOOTH_STRICT_SEC = 'SMOOTH_STRICT_SEC', } // Define the constant array with all valid values From cee0540ce445038d57074694db504610a3111d93 Mon Sep 17 00:00:00 2001 From: Salma Baig <76014459+hydrowoxy@users.noreply.github.com> Date: Wed, 1 Oct 2025 14:40:47 -0400 Subject: [PATCH 02/14] lint --- .../analyzer/SmoothStrictPrimAnalyzer.java | 74 +++++++++---------- .../analyzer/SmoothStrictSecAnalyzer.java | 74 +++++++++---------- 2 files changed, 72 insertions(+), 76 deletions(-) diff --git a/backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictPrimAnalyzer.java b/backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictPrimAnalyzer.java index 468e4744..5334e786 100644 --- a/backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictPrimAnalyzer.java +++ b/backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictPrimAnalyzer.java @@ -13,42 +13,40 @@ @OnAnalyzerException public class SmoothStrictPrimAnalyzer extends Analyzer { - @Inject - private Logger logger; - @Inject - private AnalyzerFactory factory; - - @Override - @SneakyThrows - public void analyze(AnalyzerParams params) { - extractParams(params); - logger.info("Running pipeline: StrictTimestamp -> sGolay (single file RPM)"); - - // Single file and column - String file = params.getInputFiles()[0]; - String col = params.getInputColumns()[0]; - - // 1) StrictTimestamp for the single file/column - Analyzer strict = factory.getAnalyzer(AnalyzerType.STRICT_TIMESTAMP); - AnalyzerParams sp = new AnalyzerParams(); - sp.setInputFiles(new String[] { file }); - sp.setInputColumns(new String[] { col }); - sp.setType(AnalyzerType.STRICT_TIMESTAMP); - sp.setOptions(new String[0]); - sp.generateOutputFileNames(); - strict.analyze(sp); - String strictOut = sp.getOutputFiles()[0]; - - // 2) Savitzky-Golay for the strict timestamp output - Analyzer sGolay = factory.getAnalyzer(AnalyzerType.SGOLAY); - AnalyzerParams sg = new AnalyzerParams(); - sg.setInputFiles(new String[] { strictOut, strictOut }); - sg.setInputColumns(new String[] { "Timestamp (ms)", "RPM PRIM" }); - sg.setType(AnalyzerType.SGOLAY); - sg.setOptions(new String[] { "101", "3" }); - sg.setOutputFiles(params.getOutputFiles()); - sGolay.analyze(sg); - - logger.info("Completed pipeline: StrictTimestamp -> sGolay for single file RPM"); - } + @Inject private Logger logger; + @Inject private AnalyzerFactory factory; + + @Override + @SneakyThrows + public void analyze(AnalyzerParams params) { + extractParams(params); + logger.info("Running pipeline: StrictTimestamp -> sGolay (single file RPM)"); + + // Single file and column + String file = params.getInputFiles()[0]; + String col = params.getInputColumns()[0]; + + // 1) StrictTimestamp for the single file/column + Analyzer strict = factory.getAnalyzer(AnalyzerType.STRICT_TIMESTAMP); + AnalyzerParams sp = new AnalyzerParams(); + sp.setInputFiles(new String[] {file}); + sp.setInputColumns(new String[] {col}); + sp.setType(AnalyzerType.STRICT_TIMESTAMP); + sp.setOptions(new String[0]); + sp.generateOutputFileNames(); + strict.analyze(sp); + String strictOut = sp.getOutputFiles()[0]; + + // 2) Savitzky-Golay for the strict timestamp output + Analyzer sGolay = factory.getAnalyzer(AnalyzerType.SGOLAY); + AnalyzerParams sg = new AnalyzerParams(); + sg.setInputFiles(new String[] {strictOut, strictOut}); + sg.setInputColumns(new String[] {"Timestamp (ms)", "RPM PRIM"}); + sg.setType(AnalyzerType.SGOLAY); + sg.setOptions(new String[] {"101", "3"}); + sg.setOutputFiles(params.getOutputFiles()); + sGolay.analyze(sg); + + logger.info("Completed pipeline: StrictTimestamp -> sGolay for single file RPM"); + } } diff --git a/backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictSecAnalyzer.java b/backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictSecAnalyzer.java index 47bb4562..6a9e134f 100644 --- a/backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictSecAnalyzer.java +++ b/backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictSecAnalyzer.java @@ -13,42 +13,40 @@ @OnAnalyzerException public class SmoothStrictSecAnalyzer extends Analyzer { - @Inject - private Logger logger; - @Inject - private AnalyzerFactory factory; - - @Override - @SneakyThrows - public void analyze(AnalyzerParams params) { - extractParams(params); - logger.info("Running pipeline: StrictTimestamp -> sGolay (single file RPM)"); - - // Single file and column - String file = params.getInputFiles()[0]; - String col = params.getInputColumns()[0]; - - // 1) StrictTimestamp for the single file/column - Analyzer strict = factory.getAnalyzer(AnalyzerType.STRICT_TIMESTAMP); - AnalyzerParams sp = new AnalyzerParams(); - sp.setInputFiles(new String[] { file }); - sp.setInputColumns(new String[] { col }); - sp.setType(AnalyzerType.STRICT_TIMESTAMP); - sp.setOptions(new String[0]); - sp.generateOutputFileNames(); - strict.analyze(sp); - String strictOut = sp.getOutputFiles()[0]; - - // 2) Savitzky-Golay for the strict timestamp output - Analyzer sGolay = factory.getAnalyzer(AnalyzerType.SGOLAY); - AnalyzerParams sg = new AnalyzerParams(); - sg.setInputFiles(new String[] { strictOut, strictOut }); - sg.setInputColumns(new String[] { "Timestamp (ms)", "RPM SEC" }); - sg.setType(AnalyzerType.SGOLAY); - sg.setOptions(new String[] { "101", "3" }); - sg.setOutputFiles(params.getOutputFiles()); - sGolay.analyze(sg); - - logger.info("Completed pipeline: StrictTimestamp -> sGolay for single file RPM"); - } + @Inject private Logger logger; + @Inject private AnalyzerFactory factory; + + @Override + @SneakyThrows + public void analyze(AnalyzerParams params) { + extractParams(params); + logger.info("Running pipeline: StrictTimestamp -> sGolay (single file RPM)"); + + // Single file and column + String file = params.getInputFiles()[0]; + String col = params.getInputColumns()[0]; + + // 1) StrictTimestamp for the single file/column + Analyzer strict = factory.getAnalyzer(AnalyzerType.STRICT_TIMESTAMP); + AnalyzerParams sp = new AnalyzerParams(); + sp.setInputFiles(new String[] {file}); + sp.setInputColumns(new String[] {col}); + sp.setType(AnalyzerType.STRICT_TIMESTAMP); + sp.setOptions(new String[0]); + sp.generateOutputFileNames(); + strict.analyze(sp); + String strictOut = sp.getOutputFiles()[0]; + + // 2) Savitzky-Golay for the strict timestamp output + Analyzer sGolay = factory.getAnalyzer(AnalyzerType.SGOLAY); + AnalyzerParams sg = new AnalyzerParams(); + sg.setInputFiles(new String[] {strictOut, strictOut}); + sg.setInputColumns(new String[] {"Timestamp (ms)", "RPM SEC"}); + sg.setType(AnalyzerType.SGOLAY); + sg.setOptions(new String[] {"101", "3"}); + sg.setOutputFiles(params.getOutputFiles()); + sGolay.analyze(sg); + + logger.info("Completed pipeline: StrictTimestamp -> sGolay for single file RPM"); + } } From 0eff7545d7c6cd6b2ec610430b64690d52878dd4 Mon Sep 17 00:00:00 2001 From: Salma Baig <76014459+hydrowoxy@users.noreply.github.com> Date: Wed, 1 Oct 2025 14:41:37 -0400 Subject: [PATCH 03/14] remove redundant logs --- .../java/com/mcmasterbaja/analyzer/SmoothStrictSecAnalyzer.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictSecAnalyzer.java b/backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictSecAnalyzer.java index 6a9e134f..221307c4 100644 --- a/backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictSecAnalyzer.java +++ b/backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictSecAnalyzer.java @@ -46,7 +46,5 @@ public void analyze(AnalyzerParams params) { sg.setOptions(new String[] {"101", "3"}); sg.setOutputFiles(params.getOutputFiles()); sGolay.analyze(sg); - - logger.info("Completed pipeline: StrictTimestamp -> sGolay for single file RPM"); } } From 7f05d682a0134258b40d33814a4ee2ab6cee8641 Mon Sep 17 00:00:00 2001 From: Salma Baig <76014459+hydrowoxy@users.noreply.github.com> Date: Wed, 1 Oct 2025 14:44:30 -0400 Subject: [PATCH 04/14] Fix syntax error in ApiTypes.ts --- front-end/src/types/ApiTypes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/front-end/src/types/ApiTypes.ts b/front-end/src/types/ApiTypes.ts index 2680db84..a3f8cc55 100644 --- a/front-end/src/types/ApiTypes.ts +++ b/front-end/src/types/ApiTypes.ts @@ -38,7 +38,7 @@ export enum AnalyzerType { STRICT_TIMESTAMP = 'STRICT_TIMESTAMP', SHIFT_CURVE = 'SHIFT_CURVE', SMOOTH_STRICT_PRIM = 'SMOOTH_STRICT_PRIM', - SMOOTH_STRICT_SEC = 'SMOOTH_STRICT_SEC', + SMOOTH_STRICT_SEC = 'SMOOTH_STRICT_SEC'; } // Define the constant array with all valid values From a2e705c9934b15981247ae149b6fd81437d73e37 Mon Sep 17 00:00:00 2001 From: Salma Baig <76014459+hydrowoxy@users.noreply.github.com> Date: Wed, 1 Oct 2025 14:45:09 -0400 Subject: [PATCH 05/14] Delete front-end/src/pages/Homepage/dataSelect.tsx --- front-end/src/pages/Homepage/dataSelect.tsx | 101 -------------------- 1 file changed, 101 deletions(-) delete mode 100644 front-end/src/pages/Homepage/dataSelect.tsx diff --git a/front-end/src/pages/Homepage/dataSelect.tsx b/front-end/src/pages/Homepage/dataSelect.tsx deleted file mode 100644 index e73c38df..00000000 --- a/front-end/src/pages/Homepage/dataSelect.tsx +++ /dev/null @@ -1,101 +0,0 @@ -import { useState } from 'react'; -import styles from './dataSelect.module.scss'; -import { Dropdown } from '@components/ui/dropdown/Dropdown'; -import { Column, analyzerConfig } from '@types'; -import { sigmaIcon } from '@assets/icons'; -import { useDashboard } from '@contexts/DashboardContext'; -import { useModal } from '@contexts/ModalContext'; - -interface DataSelectProps { - sources: { value: string; label: string }[]; - dataTypes: { value: string; label: string }[]; - columnKey: 'x' | 'y'; - seriesIndex: number; - chartId: string; - onColumnUpdate: (column: 'x' | 'y', updatedColumn: Partial) => void; - onAnalyzerUpdate: (newAnalyzerType: string | null, newAnalyzerValues: unknown[] | undefined) => void; -} - -export const DataSelect = ({ - sources, - dataTypes, - columnKey, - seriesIndex, - chartId, - onColumnUpdate, - onAnalyzerUpdate -}: DataSelectProps) => { - const { openModal } = useModal(); - const { charts } = useDashboard(); - - const chart = charts.find(c => c.id === chartId); - const series = chart?.series[seriesIndex]; - - if (!series) { - return null; - } - - const currentColumn = series[columnKey]; - const currentAnalyzer = series.analyzer; - - const [selectedSource, setSelectedSource] = useState(currentColumn?.source || ''); - const [selectedDataType, setSelectedDataType] = useState(currentColumn?.dataType || ''); - - const handleSourceChange = (source: string) => { - setSelectedSource(source); - onColumnUpdate(columnKey, { source }); - }; - - const handleDataTypeChange = (dataType: string) => { - setSelectedDataType(dataType); - onColumnUpdate(columnKey, { dataType }); - }; - - const handleAnalyzerClick = () => { - openModal('analyzer', { - initialType: currentAnalyzer?.type, - initialValues: currentAnalyzer?.options, - onSubmit: onAnalyzerUpdate - }); - }; - - const getAnalyzerName = () => { - if (!currentAnalyzer?.type) return 'None'; - const config = analyzerConfig[currentAnalyzer.type]; - return config?.name || 'Unknown'; - }; - - return ( -
-
-
- - -
-
- - -
-
- {columnKey === 'y' && ( -
- -
- Analyzer - {getAnalyzerName()} -
-
- )} -
- ); -}; \ No newline at end of file From a0709d0ecf7a8b0e7c2852b09921a1edae013787 Mon Sep 17 00:00:00 2001 From: Salma Baig <76014459+hydrowoxy@users.noreply.github.com> Date: Wed, 1 Oct 2025 14:45:23 -0400 Subject: [PATCH 06/14] Delete front-end/src/pages/Homepage/dataSelect.module.scss --- .../src/pages/Homepage/dataSelect.module.scss | 51 ------------------- 1 file changed, 51 deletions(-) delete mode 100644 front-end/src/pages/Homepage/dataSelect.module.scss diff --git a/front-end/src/pages/Homepage/dataSelect.module.scss b/front-end/src/pages/Homepage/dataSelect.module.scss deleted file mode 100644 index 7d582751..00000000 --- a/front-end/src/pages/Homepage/dataSelect.module.scss +++ /dev/null @@ -1,51 +0,0 @@ -@use '@styles/mixins'; - -.dataSelect { - display: flex; - flex-direction: column; - gap: 0.75rem; - padding: 0.5rem; - border-radius: 4px; -} - -.row { - display: flex; - gap: 0.5rem; -} - -.inputGroup { - flex: 1; - display: flex; - flex-direction: column; - gap: 0.25rem; - - label { - @include fonts.text-small; - color: var(--text-secondary); - } -} - -.analyzerRow { - display: flex; - flex-direction: column; - gap: 0.25rem; - - label { - @include fonts.text-small; - color: var(--text-secondary); - } - - .analyzerControl { - cursor: pointer; - display: flex; - align-items: center; - gap: 0.5rem; - color: var(--accent-colour); - font-weight: 500; - - .analyzerIcon { - width: 16px; - height: 16px; - } - } -} \ No newline at end of file From d44993b32fb4c796f2f47854abdf5458e3ccc2b1 Mon Sep 17 00:00:00 2001 From: Salma Baig <76014459+hydrowoxy@users.noreply.github.com> Date: Wed, 1 Oct 2025 14:48:39 -0400 Subject: [PATCH 07/14] Fix syntax error in ApiTypes.ts --- front-end/src/types/ApiTypes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/front-end/src/types/ApiTypes.ts b/front-end/src/types/ApiTypes.ts index a3f8cc55..2680db84 100644 --- a/front-end/src/types/ApiTypes.ts +++ b/front-end/src/types/ApiTypes.ts @@ -38,7 +38,7 @@ export enum AnalyzerType { STRICT_TIMESTAMP = 'STRICT_TIMESTAMP', SHIFT_CURVE = 'SHIFT_CURVE', SMOOTH_STRICT_PRIM = 'SMOOTH_STRICT_PRIM', - SMOOTH_STRICT_SEC = 'SMOOTH_STRICT_SEC'; + SMOOTH_STRICT_SEC = 'SMOOTH_STRICT_SEC', } // Define the constant array with all valid values From fb8e011b87bf14594c433662fc955bec6cfaf1e4 Mon Sep 17 00:00:00 2001 From: Salma Baig <76014459+hydrowoxy@users.noreply.github.com> Date: Wed, 1 Oct 2025 17:59:35 -0400 Subject: [PATCH 08/14] fix timestamp typo --- .../java/com/mcmasterbaja/analyzer/SmoothStrictPrimAnalyzer.java | 1 - 1 file changed, 1 deletion(-) diff --git a/backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictPrimAnalyzer.java b/backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictPrimAnalyzer.java index 5334e786..7cda17c6 100644 --- a/backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictPrimAnalyzer.java +++ b/backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictPrimAnalyzer.java @@ -47,6 +47,5 @@ public void analyze(AnalyzerParams params) { sg.setOutputFiles(params.getOutputFiles()); sGolay.analyze(sg); - logger.info("Completed pipeline: StrictTimestamp -> sGolay for single file RPM"); } } From 0de9be8a40b6d4bb5bc0f632f47882a8a5651a69 Mon Sep 17 00:00:00 2001 From: Salma Baig <76014459+hydrowoxy@users.noreply.github.com> Date: Wed, 1 Oct 2025 18:11:16 -0400 Subject: [PATCH 09/14] added presets --- .../analyzer/SmoothStrictPrimAnalyzer.java | 1 - front-end/src/lib/subteamGraphPresets.ts | 30 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictPrimAnalyzer.java b/backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictPrimAnalyzer.java index 7cda17c6..e12d5758 100644 --- a/backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictPrimAnalyzer.java +++ b/backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictPrimAnalyzer.java @@ -46,6 +46,5 @@ public void analyze(AnalyzerParams params) { sg.setOptions(new String[] {"101", "3"}); sg.setOutputFiles(params.getOutputFiles()); sGolay.analyze(sg); - } } diff --git a/front-end/src/lib/subteamGraphPresets.ts b/front-end/src/lib/subteamGraphPresets.ts index 4f5c13d0..32808059 100644 --- a/front-end/src/lib/subteamGraphPresets.ts +++ b/front-end/src/lib/subteamGraphPresets.ts @@ -31,6 +31,36 @@ export const subteamGraphPresets: DataViewerPreset[] = [ }, ], }, + { + name: 'Smooth Primary RPM with Strict Timestamp', + description: 'Smooths PRIM RPM with strict timestamp outlier removal', + graphs: [ + { + axes: [ + { source: 'RPM PRIM.csv', dataType: 'Timestamp (ms)' }, + { source: 'RPM PRIM.csv', dataType: 'RPM PRIM' }, + ], + analyzer: AnalyzerType.SMOOTH_STRICT_PRIM, + analyzerOptions: [], + graphType: 'line', + }, + ], + }, + { + name: 'Smooth Secondary RPM with Strict Timestamp', + description: 'Smooths SEC RPM with strict timestamp outlier removal', + graphs: [ + { + axes: [ + { source: 'RPM SEC.csv', dataType: 'Timestamp (ms)' }, + { source: 'RPM SEC.csv', dataType: 'RPM SEC' }, + ], + analyzer: AnalyzerType.SMOOTH_STRICT_SEC, + analyzerOptions: [], + graphType: 'line', + }, + ], + }, { name: 'Goated Shift Curve', description: 'Primary RPM vs Secondary RPM with GPS Speed', From 7a4004be319002afca2997a21708d01b503bf071 Mon Sep 17 00:00:00 2001 From: Salma Baig <76014459+hydrowoxy@users.noreply.github.com> Date: Wed, 1 Oct 2025 18:23:18 -0400 Subject: [PATCH 10/14] added combined preset --- front-end/src/lib/subteamGraphPresets.ts | 26 +++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/front-end/src/lib/subteamGraphPresets.ts b/front-end/src/lib/subteamGraphPresets.ts index 32808059..1c78bad7 100644 --- a/front-end/src/lib/subteamGraphPresets.ts +++ b/front-end/src/lib/subteamGraphPresets.ts @@ -31,6 +31,30 @@ export const subteamGraphPresets: DataViewerPreset[] = [ }, ], }, + { + name: 'Smooth Strict RPM', + description: 'Primary and Secondary RPM vs Timestamp (ms) smoothened with strict timestamp outlier removal', + graphs: [ + { + axes: [ + { source: 'RPM PRIM.csv', dataType: 'Timestamp (ms)' }, + { source: 'RPM PRIM.csv', dataType: 'RPM PRIM' }, + ], + analyzer: AnalyzerType.SMOOTH_STRICT_PRIM, + analyzerOptions: [], + graphType: 'line', + }, + { + axes: [ + { source: 'RPM SEC.csv', dataType: 'Timestamp (ms)' }, + { source: 'RPM SEC.csv', dataType: 'RPM SEC' }, + ], + analyzer: AnalyzerType.SMOOTH_STRICT_SEC, + analyzerOptions: [], + graphType: 'line', + }, + ], + }, { name: 'Smooth Primary RPM with Strict Timestamp', description: 'Smooths PRIM RPM with strict timestamp outlier removal', @@ -90,5 +114,5 @@ export const subteamGraphPresets: DataViewerPreset[] = [ graphType: 'line', }, ] - } + }, ]; From 2d3ff4a6738130a4ee8f3491f9c6348ab916d4ad Mon Sep 17 00:00:00 2001 From: Salma Baig <76014459+hydrowoxy@users.noreply.github.com> Date: Wed, 1 Oct 2025 18:24:48 -0400 Subject: [PATCH 11/14] rearranged presets --- front-end/src/lib/subteamGraphPresets.ts | 44 ++++++++++++------------ 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/front-end/src/lib/subteamGraphPresets.ts b/front-end/src/lib/subteamGraphPresets.ts index 1c78bad7..9d2d725a 100644 --- a/front-end/src/lib/subteamGraphPresets.ts +++ b/front-end/src/lib/subteamGraphPresets.ts @@ -56,63 +56,63 @@ export const subteamGraphPresets: DataViewerPreset[] = [ ], }, { - name: 'Smooth Primary RPM with Strict Timestamp', - description: 'Smooths PRIM RPM with strict timestamp outlier removal', + name: 'Goated Shift Curve', + description: 'Primary RPM vs Secondary RPM with GPS Speed', graphs: [ { axes: [ - { source: 'RPM PRIM.csv', dataType: 'Timestamp (ms)' }, + { source: 'RPM SEC.csv', dataType: 'RPM SEC' }, { source: 'RPM PRIM.csv', dataType: 'RPM PRIM' }, ], - analyzer: AnalyzerType.SMOOTH_STRICT_PRIM, + analyzer: AnalyzerType.SHIFT_CURVE, analyzerOptions: [], graphType: 'line', }, - ], + ] }, { - name: 'Smooth Secondary RPM with Strict Timestamp', - description: 'Smooths SEC RPM with strict timestamp outlier removal', + name: 'Map', + description: 'Map of GPS coordinates', graphs: [ { axes: [ - { source: 'RPM SEC.csv', dataType: 'Timestamp (ms)' }, - { source: 'RPM SEC.csv', dataType: 'RPM SEC' }, + { source: 'GPS LATITUDE.csv', dataType: 'GPS LATITUDE' }, + { source: 'GPS LONGITUDE.csv', dataType: 'GPS LONGITUDE' }, ], - analyzer: AnalyzerType.SMOOTH_STRICT_SEC, + analyzer: AnalyzerType.SHIFT_CURVE, analyzerOptions: [], graphType: 'line', }, - ], + ] }, { - name: 'Goated Shift Curve', - description: 'Primary RPM vs Secondary RPM with GPS Speed', + name: 'Smooth Primary RPM with Strict Timestamp', + description: 'Smooths PRIM RPM with strict timestamp outlier removal', graphs: [ { axes: [ - { source: 'RPM SEC.csv', dataType: 'RPM SEC' }, + { source: 'RPM PRIM.csv', dataType: 'Timestamp (ms)' }, { source: 'RPM PRIM.csv', dataType: 'RPM PRIM' }, ], - analyzer: AnalyzerType.SHIFT_CURVE, + analyzer: AnalyzerType.SMOOTH_STRICT_PRIM, analyzerOptions: [], graphType: 'line', }, - ] + ], }, { - name: 'Map', - description: 'Map of GPS coordinates', + name: 'Smooth Secondary RPM with Strict Timestamp', + description: 'Smooths SEC RPM with strict timestamp outlier removal', graphs: [ { axes: [ - { source: 'GPS LATITUDE.csv', dataType: 'GPS LATITUDE' }, - { source: 'GPS LONGITUDE.csv', dataType: 'GPS LONGITUDE' }, + { source: 'RPM SEC.csv', dataType: 'Timestamp (ms)' }, + { source: 'RPM SEC.csv', dataType: 'RPM SEC' }, ], - analyzer: AnalyzerType.SHIFT_CURVE, + analyzer: AnalyzerType.SMOOTH_STRICT_SEC, analyzerOptions: [], graphType: 'line', }, - ] + ], }, ]; From 0e6688b9fb3e43aea92f59f90c43429b3a90034a Mon Sep 17 00:00:00 2001 From: Salma Baig <76014459+hydrowoxy@users.noreply.github.com> Date: Wed, 1 Oct 2025 18:56:47 -0400 Subject: [PATCH 12/14] added outlier removal to the pipeline for values >20k --- .../analyzer/SmoothStrictPrimAnalyzer.java | 25 ++++++++++++++++--- .../analyzer/SmoothStrictSecAnalyzer.java | 25 ++++++++++++++++--- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictPrimAnalyzer.java b/backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictPrimAnalyzer.java index e12d5758..936681e8 100644 --- a/backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictPrimAnalyzer.java +++ b/backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictPrimAnalyzer.java @@ -20,7 +20,7 @@ public class SmoothStrictPrimAnalyzer extends Analyzer { @SneakyThrows public void analyze(AnalyzerParams params) { extractParams(params); - logger.info("Running pipeline: StrictTimestamp -> sGolay (single file RPM)"); + logger.info("Running pipeline: StrictTimestamp -> Outlier Removal -> sGolay (PRIM RPM)"); // Single file and column String file = params.getInputFiles()[0]; @@ -37,14 +37,33 @@ public void analyze(AnalyzerParams params) { strict.analyze(sp); String strictOut = sp.getOutputFiles()[0]; - // 2) Savitzky-Golay for the strict timestamp output + // 2) Outlier removal for RPM > 20000 + Analyzer outlierRemoval = factory.getAnalyzer(AnalyzerType.DELETE_OUTLIER); + AnalyzerParams or = new AnalyzerParams(); + or.setInputFiles(new String[] {strictOut}); + or.setInputColumns(new String[] {"Timestamp (ms)", "RPM PRIM"}); + or.setType(AnalyzerType.DELETE_OUTLIER); + or.setOptions( + new String[] { + "0", // minX (minimum timestamp - keep all) + "999999999", // maxX (maximum timestamp - keep all) + "0", // minY (minimum RPM - keep all above 0) + "20000" // maxY (maximum RPM - remove above 20000) + }); + or.generateOutputFileNames(); + outlierRemoval.analyze(or); + String outlierOut = or.getOutputFiles()[0]; + + // 3) Savitzky-Golay for the outlier-removed output Analyzer sGolay = factory.getAnalyzer(AnalyzerType.SGOLAY); AnalyzerParams sg = new AnalyzerParams(); - sg.setInputFiles(new String[] {strictOut, strictOut}); + sg.setInputFiles(new String[] {outlierOut, outlierOut}); sg.setInputColumns(new String[] {"Timestamp (ms)", "RPM PRIM"}); sg.setType(AnalyzerType.SGOLAY); sg.setOptions(new String[] {"101", "3"}); sg.setOutputFiles(params.getOutputFiles()); sGolay.analyze(sg); + + logger.info("Completed pipeline: StrictTimestamp -> Outlier Removal -> sGolay for PRIM RPM"); } } diff --git a/backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictSecAnalyzer.java b/backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictSecAnalyzer.java index 221307c4..f40296a7 100644 --- a/backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictSecAnalyzer.java +++ b/backend/src/main/java/com/mcmasterbaja/analyzer/SmoothStrictSecAnalyzer.java @@ -20,7 +20,7 @@ public class SmoothStrictSecAnalyzer extends Analyzer { @SneakyThrows public void analyze(AnalyzerParams params) { extractParams(params); - logger.info("Running pipeline: StrictTimestamp -> sGolay (single file RPM)"); + logger.info("Running pipeline: StrictTimestamp -> Outlier Removal -> sGolay (SEC RPM)"); // Single file and column String file = params.getInputFiles()[0]; @@ -37,14 +37,33 @@ public void analyze(AnalyzerParams params) { strict.analyze(sp); String strictOut = sp.getOutputFiles()[0]; - // 2) Savitzky-Golay for the strict timestamp output + // 2) Outlier removal for RPM > 20000 + Analyzer outlierRemoval = factory.getAnalyzer(AnalyzerType.DELETE_OUTLIER); + AnalyzerParams or = new AnalyzerParams(); + or.setInputFiles(new String[] {strictOut}); + or.setInputColumns(new String[] {"Timestamp (ms)", "RPM SEC"}); + or.setType(AnalyzerType.DELETE_OUTLIER); + or.setOptions( + new String[] { + "0", // minX (minimum timestamp - keep all) + "999999999", // maxX (maximum timestamp - keep all) + "0", // minY (minimum RPM - keep all above 0) + "20000" // maxY (maximum RPM - remove above 20000) + }); + or.generateOutputFileNames(); + outlierRemoval.analyze(or); + String outlierOut = or.getOutputFiles()[0]; + + // 3) Savitzky-Golay for the outlier-removed output Analyzer sGolay = factory.getAnalyzer(AnalyzerType.SGOLAY); AnalyzerParams sg = new AnalyzerParams(); - sg.setInputFiles(new String[] {strictOut, strictOut}); + sg.setInputFiles(new String[] {outlierOut, outlierOut}); sg.setInputColumns(new String[] {"Timestamp (ms)", "RPM SEC"}); sg.setType(AnalyzerType.SGOLAY); sg.setOptions(new String[] {"101", "3"}); sg.setOutputFiles(params.getOutputFiles()); sGolay.analyze(sg); + + logger.info("Completed pipeline: StrictTimestamp -> Outlier Removal -> sGolay for SEC RPM"); } } From 7ecd2dee09ad713336c8b6fdf2c2d7d57c5b45ad Mon Sep 17 00:00:00 2001 From: Salma Baig <76014459+hydrowoxy@users.noreply.github.com> Date: Wed, 1 Oct 2025 19:02:20 -0400 Subject: [PATCH 13/14] Update AnalyzerTypes.ts --- front-end/src/types/AnalyzerTypes.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/front-end/src/types/AnalyzerTypes.ts b/front-end/src/types/AnalyzerTypes.ts index 191f58a7..af3117c1 100644 --- a/front-end/src/types/AnalyzerTypes.ts +++ b/front-end/src/types/AnalyzerTypes.ts @@ -235,7 +235,7 @@ export const analyzerConfig: Record = { [AnalyzerType.SMOOTH_STRICT_PRIM]: { title: 'Smooth Strict PRIM', description: - 'Runs StrictTimstamp and Sgolay for RPM PRIM', + 'Runs StrictTimestamp and Sgolay for RPM PRIM', isJoinBased: false, image: { src: placeholderImage, @@ -247,7 +247,7 @@ export const analyzerConfig: Record = { [AnalyzerType.SMOOTH_STRICT_SEC]: { title: 'Smooth Strict SEC', description: - 'Runs StrictTimstamp and Sgolay for RPM SEC', + 'Runs StrictTimestamp and Sgolay for RPM SEC', isJoinBased: false, image: { src: placeholderImage, @@ -255,4 +255,4 @@ export const analyzerConfig: Record = { }, links: [{ title: 'Timestamp (Wiki)', url: 'https://en.wikipedia.org/wiki/Timestamp' }], }, -}; \ No newline at end of file +}; From 0b178b9225c6c11145fcdf5950ee769a80a12686 Mon Sep 17 00:00:00 2001 From: Salma Baig <76014459+hydrowoxy@users.noreply.github.com> Date: Wed, 1 Oct 2025 19:02:50 -0400 Subject: [PATCH 14/14] Refactor RPM preset names and descriptions Updated names and descriptions for RPM presets to enhance clarity. --- front-end/src/lib/subteamGraphPresets.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/front-end/src/lib/subteamGraphPresets.ts b/front-end/src/lib/subteamGraphPresets.ts index 9d2d725a..43ec4f94 100644 --- a/front-end/src/lib/subteamGraphPresets.ts +++ b/front-end/src/lib/subteamGraphPresets.ts @@ -33,7 +33,7 @@ export const subteamGraphPresets: DataViewerPreset[] = [ }, { name: 'Smooth Strict RPM', - description: 'Primary and Secondary RPM vs Timestamp (ms) smoothened with strict timestamp outlier removal', + description: 'Primary and Secondary RPM vs Timestamp (ms) smoothened + outlier removal + strict timestamp', graphs: [ { axes: [ @@ -86,8 +86,8 @@ export const subteamGraphPresets: DataViewerPreset[] = [ ] }, { - name: 'Smooth Primary RPM with Strict Timestamp', - description: 'Smooths PRIM RPM with strict timestamp outlier removal', + name: 'Smooth Strict PRIM RPM', + description: 'Smooths PRIM RPM with strict timestamp + outlier removal', graphs: [ { axes: [ @@ -101,8 +101,8 @@ export const subteamGraphPresets: DataViewerPreset[] = [ ], }, { - name: 'Smooth Secondary RPM with Strict Timestamp', - description: 'Smooths SEC RPM with strict timestamp outlier removal', + name: 'Smooth Strict SEC RPM', + description: 'Smooths SEC RPM with strict timestamp + outlier removal', graphs: [ { axes: [