From 0dd037e8e489220bb575f4d6613626889878ef32 Mon Sep 17 00:00:00 2001 From: Saleema Amershi Date: Thu, 23 Feb 2017 15:48:24 -0800 Subject: [PATCH] Strip suggestion code --- app/img/accelerometer_icon.png | Bin 8649 -> 0 bytes app/img/gyroscope_icon.png | Bin 39881 -> 0 bytes app/img/magnetometer_icon.png | Bin 19005 -> 0 bytes app/img/video_icon.png | Bin 15457 -> 0 bytes app/templates/dtw/dtwArduino.txt | 99 ------ app/templates/dtw/dtwMicrobit.txt | 98 ------ app/ts/components/App.tsx | 4 - .../components/common/AutocorrelogramPlot.tsx | 2 +- .../components/deployment/DeploymentPanel.tsx | 218 ------------ .../deployment/DeploymentToolbar.tsx | 40 --- app/ts/components/deployment/ScriptEditor.tsx | 54 --- .../components/deployment/ToolOutputPanel.tsx | 38 -- .../components/labeling/LabelingToolbar.tsx | 2 - .../labeling/SuggestionsToolbar.tsx | 117 ------ app/ts/stores/DtwModelStore.ts | 19 - app/ts/stores/LabelingStore.ts | 110 +----- app/ts/stores/LabelingUiStore.ts | 10 +- .../dataStructures}/Autocorrelation.ts | 0 .../dataStructures}/fft.ts | 0 app/ts/stores/stores.ts | 5 - app/ts/suggestion/DTWDeployment.ts | 318 ----------------- .../suggestion/DtwSuggestionModelBuilder.ts | 182 ---------- app/ts/suggestion/ELLDtwModelGeneration.ts | 81 ----- app/ts/suggestion/LabelingSuggestionEngine.ts | 181 ---------- .../suggestion/LabelingSuggestionGenerator.ts | 183 ---------- app/ts/suggestion/LabelingSuggestionLogic.ts | 267 -------------- app/ts/suggestion/LabelingSuggestionModel.ts | 38 -- app/ts/suggestion/algorithms/DBA.ts | 168 --------- app/ts/suggestion/algorithms/RC4.ts | 76 ---- .../suggestion/algorithms/SpringAlgorithm.ts | 332 ------------------ app/ts/suggestion/algorithms/pelt.ts | 121 ------- app/ts/suggestion/worker/DtwAlgorithm.ts | 328 ----------------- .../suggestion/worker/DtwSuggestionWorker.ts | 109 ------ .../worker/SuggestionWorkerMessage.ts | 63 ---- arduino/BluefruitConfig.h | 56 --- arduino/dtw.ino | 193 ---------- arduino/dtw_ELL.ino | 227 ------------ arduino/dtw_ELL_BACKUP.ino | 124 ------- arduino/dtw_TEST.ino | 38 -- arduino/model.asm | 236 ------------- package.json | 4 +- 41 files changed, 5 insertions(+), 4136 deletions(-) delete mode 100644 app/img/accelerometer_icon.png delete mode 100644 app/img/gyroscope_icon.png delete mode 100644 app/img/magnetometer_icon.png delete mode 100644 app/img/video_icon.png delete mode 100644 app/templates/dtw/dtwArduino.txt delete mode 100644 app/templates/dtw/dtwMicrobit.txt delete mode 100644 app/ts/components/deployment/DeploymentPanel.tsx delete mode 100644 app/ts/components/deployment/DeploymentToolbar.tsx delete mode 100644 app/ts/components/deployment/ScriptEditor.tsx delete mode 100644 app/ts/components/deployment/ToolOutputPanel.tsx delete mode 100644 app/ts/components/labeling/SuggestionsToolbar.tsx delete mode 100644 app/ts/stores/DtwModelStore.ts rename app/ts/{suggestion/algorithms => stores/dataStructures}/Autocorrelation.ts (100%) rename app/ts/{suggestion/algorithms => stores/dataStructures}/fft.ts (100%) delete mode 100644 app/ts/suggestion/DTWDeployment.ts delete mode 100644 app/ts/suggestion/DtwSuggestionModelBuilder.ts delete mode 100644 app/ts/suggestion/ELLDtwModelGeneration.ts delete mode 100644 app/ts/suggestion/LabelingSuggestionEngine.ts delete mode 100644 app/ts/suggestion/LabelingSuggestionGenerator.ts delete mode 100644 app/ts/suggestion/LabelingSuggestionLogic.ts delete mode 100644 app/ts/suggestion/LabelingSuggestionModel.ts delete mode 100644 app/ts/suggestion/algorithms/DBA.ts delete mode 100644 app/ts/suggestion/algorithms/RC4.ts delete mode 100644 app/ts/suggestion/algorithms/SpringAlgorithm.ts delete mode 100644 app/ts/suggestion/algorithms/pelt.ts delete mode 100644 app/ts/suggestion/worker/DtwAlgorithm.ts delete mode 100644 app/ts/suggestion/worker/DtwSuggestionWorker.ts delete mode 100644 app/ts/suggestion/worker/SuggestionWorkerMessage.ts delete mode 100644 arduino/BluefruitConfig.h delete mode 100644 arduino/dtw.ino delete mode 100644 arduino/dtw_ELL.ino delete mode 100644 arduino/dtw_ELL_BACKUP.ino delete mode 100644 arduino/dtw_TEST.ino delete mode 100644 arduino/model.asm diff --git a/app/img/accelerometer_icon.png b/app/img/accelerometer_icon.png deleted file mode 100644 index 555ad5cb6804d6f6f3bc710b76a3d6c1d3e18e2e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8649 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 z 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⪚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 diff --git a/app/img/magnetometer_icon.png b/app/img/magnetometer_icon.png deleted file mode 100644 index 194a851c6323745447319af7de2e125b193d60f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19005 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 diff --git a/app/templates/dtw/dtwArduino.txt b/app/templates/dtw/dtwArduino.txt deleted file mode 100644 index 31de91e..0000000 --- a/app/templates/dtw/dtwArduino.txt +++ /dev/null @@ -1,99 +0,0 @@ -// HOWTO: -// Call setupRecognizer(0.2) first. -// Then, call String className = recognize(sample); -// 'NONE' will be returned if nothing is detected. -// sample should be a float array, in the same order you put the training data in the tool. - -struct DTWInfo { - int dim; // The dimension of the signal. - float* prototype; // The data for the prototype. - int* s; // Matching array: start points. - float* d; // Matching array: distances. - int prototypeSize; // The length of the prototype. - int t; // Current time in samples. - float variance; // The variance. - float bestMatchEndsAtTDistance; // The distance of the best match that ends at t. - int bestMatchEndsAtTStart; // The start of the best match that ends at t. -}; - -float DTWDistanceFunction(int dim, float* a, float* b) { - int s = 0; - for(int i = 0; i < dim; i++) { - s += abs(a[i] - b[i]); - } - return s; -} - -void DTWInit(struct DTWInfo* DTW, int dim, float* prototype, int prototypeSize, float variance) { - DTW->dim = dim; - DTW->prototypeSize = prototypeSize; - DTW->prototype = prototype; - DTW->d = new float[prototypeSize + 1]; - DTW->s = new int[prototypeSize + 1]; - DTW->t = 0; - DTW->variance = variance; - for(int i = 0; i <= prototypeSize; i++) { - DTW->d[i] = 1e10; - DTW->s[i] = 0; - } - DTW->d[0] = 0; -} - -void DTWReset(struct DTWInfo* DTW) { - for(int i = 0; i <= DTW->prototypeSize; i++) { - DTW->d[i] = 1e10; - DTW->s[i] = 0; - } - DTW->d[0] = 0; -} - -void DTWFeed(struct DTWInfo* DTW, float* sample) { - float* d = DTW->d; - int* s = DTW->s; - DTW->t += 1; - d[0] = 0; - s[0] = DTW->t; - float dp = d[0]; - int sp = s[0]; - for(int i = 1; i <= DTW->prototypeSize; i++) { - float dist = DTWDistanceFunction(DTW->dim, DTW->prototype + (i - 1) * DTW->dim, sample); - float d_i_minus_1 = d[i - 1]; int s_i_minus_1 = s[i - 1]; - float d_i_p = d[i]; int s_i_p = s[i]; - float d_i_p_minus_1 = dp; int s_i_p_minus_1 = sp; - dp = d[i]; - sp = s[i]; - if(d_i_minus_1 <= d_i_p && d_i_minus_1 <= d_i_p_minus_1) { - d[i] = dist + d_i_minus_1; - s[i] = s_i_minus_1; - } else if(d_i_p <= d_i_minus_1 && d_i_p <= d_i_p_minus_1) { - d[i] = dist + d_i_p; - s[i] = s_i_p; - } else { - d[i] = dist + d_i_p_minus_1; - s[i] = s_i_p_minus_1; - } - } - DTW->bestMatchEndsAtTDistance = d[DTW->prototypeSize] / DTW->variance; - DTW->bestMatchEndsAtTStart = s[DTW->prototypeSize]; - if(DTW->t - DTW->bestMatchEndsAtTStart > DTW->prototypeSize * 0.8 && DTW->t - DTW->bestMatchEndsAtTStart < DTW->prototypeSize * 1.2) { - } else DTW->bestMatchEndsAtTDistance = 1e10; -} - -%%GLOBAL%% - -void setupRecognizer(float confidenceThreshold) { - float threshold = sqrt(-2 * log(confidenceThreshold)); -%%SETUP%% -} - -void resetRecognizer() { -%%RESET%% -} - -String recognize(float* sample) { -%%MATCH%% - String minClass = 'NONE'; - float minClassScore = 1e10; -%%MATCH_COMPARISON%% - return minClass; -} diff --git a/app/templates/dtw/dtwMicrobit.txt b/app/templates/dtw/dtwMicrobit.txt deleted file mode 100644 index 5a46513..0000000 --- a/app/templates/dtw/dtwMicrobit.txt +++ /dev/null @@ -1,98 +0,0 @@ -// HOWTO: -// Call setupRecognizer() first. -// Then, call let className = recognize([ input.acceleration(Dimension.X), input.acceleration(Dimension.Y), input.acceleration(Dimension.Z) ]); -// 'NONE' will be returned if nothing is detected. -// An example is at the end of this file. - -// IMPORTANT: All number in microbit are integers. -function DTWDistanceFunction(dim: number, a: number[], astart: number, b: number[]) { - let s = 0; - for (let i = 0; i < dim; i++) { - s += (a[i + astart] - b[i]) * (a[i + astart] - b[i]); - } - return Math.sqrt(s); -} -class DTWInfo { - public dim: number; - public prototype: number[]; - public s: number[]; - public d: number[]; - public prototypeSize: number; - public t: number; - public bestMatchEndsAtTDistance: number; - // The distance of the best match that ends at t. - public variance: number; - // The variance computed. - public bestMatchEndsAtTStart: number; - // The start of the best match that ends at t. - constructor(dim: number, prototype: number[], prototypeSize: number, variance: number) { - this.dim = dim; - this.prototypeSize = prototypeSize; - this.prototype = prototype; - this.d = %%ARRAY_INITIALIZATION%%; - this.s = %%ARRAY_INITIALIZATION%%; - this.t = 0; - this.variance = variance; - for (let i = 0; i <= prototypeSize; i++) { - this.d[i] = 500000000; - this.s[i] = 0; - } - this.d[0] = 0; - } - public feed(sample: number[]) { - let d = this.d; - let s = this.s; - this.t += 1; - d[0] = 0; - s[0] = this.t; - let dp = d[0]; - let sp = s[0]; - for (let i = 1; i <= this.prototypeSize; i++) { - let dist = DTWDistanceFunction(this.dim, this.prototype, (i - 1) * this.dim, sample); - let d_i_minus_1 = d[i - 1]; - let s_i_minus_1 = s[i - 1]; - let d_i_p = d[i]; - let s_i_p = s[i]; - let d_i_p_minus_1 = dp; - let s_i_p_minus_1 = sp; - dp = d[i]; - sp = s[i]; - if (d_i_minus_1 <= d_i_p && d_i_minus_1 <= d_i_p_minus_1) { - d[i] = dist + d_i_minus_1; - s[i] = s_i_minus_1; - } else if (d_i_p <= d_i_minus_1 && d_i_p <= d_i_p_minus_1) { - d[i] = dist + d_i_p; - s[i] = s_i_p; - } else { - d[i] = dist + d_i_p_minus_1; - s[i] = s_i_p_minus_1; - } - } - this.bestMatchEndsAtTDistance = d[this.prototypeSize] / this.variance; - this.bestMatchEndsAtTStart = s[this.prototypeSize]; - } -} - -%%GLOBAL%% - -function setupRecognizer() { - let threshold = 1794; // confidenceThreshold = 0.2 -%%SETUP%% -} - -function recognize(sample: number[]): string { -%%MATCH%% - let minClass = 'NONE'; - let minClassScore = 5000000; -%%MATCH_COMPARISON%% - return minClass; -} - -// Example application code: -setupRecognizer(); -basic.forever(() => { - // Recognize the gesture. - let className = recognize([input.acceleration(Dimension.X), input.acceleration(Dimension.Y), input.acceleration(Dimension.Z)]); - // Send the result over serial. - serial.writeLine(className); -} diff --git a/app/ts/components/App.tsx b/app/ts/components/App.tsx index c9fc0ec..5694a49 100644 --- a/app/ts/components/App.tsx +++ b/app/ts/components/App.tsx @@ -2,7 +2,6 @@ import { TabID } from '../stores/dataStructures/types'; import * as stores from '../stores/stores'; import { NavigationColumn, NavigationColumnItem } from './common/NavigationColumn'; import { SharedAlignmentLabelingPane } from './common/SharedAlignmentLabelingPane'; -import { DeploymentPanel } from './deployment/DeploymentPanel'; import { HomeMenu } from './home/HomeMenu'; import { remote } from 'electron'; import { observer } from 'mobx-react'; @@ -82,9 +81,6 @@ export class App extends React.Component<{}, {}> { - - - ); diff --git a/app/ts/components/common/AutocorrelogramPlot.tsx b/app/ts/components/common/AutocorrelogramPlot.tsx index 7fdd444..488eeb6 100644 --- a/app/ts/components/common/AutocorrelogramPlot.tsx +++ b/app/ts/components/common/AutocorrelogramPlot.tsx @@ -1,5 +1,5 @@ +import {autocorrelogram} from '../../stores/dataStructures/Autocorrelation'; import {SensorTimeSeries} from '../../stores/dataStructures/dataset'; -import {autocorrelogram} from '../../suggestion/algorithms/Autocorrelation'; import * as d3 from 'd3'; import * as React from 'react'; diff --git a/app/ts/components/deployment/DeploymentPanel.tsx b/app/ts/components/deployment/DeploymentPanel.tsx deleted file mode 100644 index b985afe..0000000 --- a/app/ts/components/deployment/DeploymentPanel.tsx +++ /dev/null @@ -1,218 +0,0 @@ -import * as stores from '../../stores/stores'; -import { labelingSuggestionGenerator } from '../../stores/stores'; -import { generateEllModel } from '../../suggestion/ELLDtwModelGeneration'; -import { DeploymentToolbar } from './DeploymentToolbar'; -import { ScriptEditor } from './ScriptEditor'; -import { ToolOutputPanel } from './ToolOutputPanel'; -import { execFileSync, spawn } from 'child_process'; -import * as fs from 'fs'; -import * as os from 'os'; -import * as path from 'path'; -import * as React from 'react'; - - -// Configuration -const useEllModel = true; // vs. Donghao model -const confidenceThreshold = 0.2; -const useStoredModel = false; - -// utility function for copying file -function copyTextFile(sourceFilename: string, targetFilename: string): void { - const text = fs.readFileSync(sourceFilename, 'utf-8'); - fs.writeFileSync(targetFilename, text); -} - -interface Tab { - isReadOnly: boolean; - label: string; - text: string; -} - -interface DeploymentPanelProps { - toolbarHeight: number; -} - -interface DeploymentPanelState { - arduinoAppCodeTemplate?: string; - arduinoModelCode?: string; - microbitAppCodeTemplate?: string; - microbitModelCode?: string; - width?: number; - height?: number; - tabs?: Tab[]; - currentTab?: Tab; - toolOutput?: string; -} - -export class DeploymentPanel extends React.Component { - public refs: { - [key: string]: Element, - container: Element, - }; - - private toolOutputPanel: ToolOutputPanel; - - constructor(props: DeploymentPanelProps, context: any) { - super(props, context); - let appCode: string; - let modelCodeFilename: string; - if (useEllModel) { - appCode = fs.readFileSync('arduino/dtw_ELL.ino', 'utf-8'); - modelCodeFilename = 'model.asm'; - } else { - appCode = fs.readFileSync('arduino/dtw.ino', 'utf-8'); - modelCodeFilename = 'model.ino'; - } - // let appCode = fs.readFileSync('arduino/dtw_TEST.ino', 'utf-8'); - const tabs = [ - { - label: 'dtw.ino', - isReadOnly: false, - text: appCode - }, - { - label: modelCodeFilename, - isReadOnly: true, - text: '' - } - ]; - this.state = { - arduinoAppCodeTemplate: appCode, - arduinoModelCode: '', - microbitAppCodeTemplate: appCode, - microbitModelCode: '', - tabs: tabs, - currentTab: tabs[0], - toolOutput: '' - }; - this.compile = this.compile.bind(this); - this.deploy = this.deploy.bind(this); - } - - public componentDidMount(): void { - const prototypes = stores.dtwModelStore.prototypes; - if (prototypes.length === 0) { return; } - const sampleRate = stores.dtwModelStore.prototypeSampleRate; - const model = generateEllModel(sampleRate, 30, prototypes, confidenceThreshold); - const ellModelCode = model.GetCodeString(); - const header = model.GetHeaderString(); - labelingSuggestionGenerator.getDeploymentCode('arduino', oldModelCode => { - const modelCode = useEllModel ? ellModelCode : oldModelCode; - // #### hack: replace code passed in with current code from the store - const appCode = this.state.arduinoAppCodeTemplate.replace('// %%HEADER%%', header); - this.setState({ arduinoModelCode: modelCode }); - const modelCodeFilename = useEllModel ? 'model.asm' : 'model.ino'; - this.state.tabs - .filter(t => t.label === modelCodeFilename) - .forEach(t => t.text = modelCode); - this.state.tabs - .filter(t => t.label === 'dtw.ino') - .forEach(t => t.text = appCode); - }); - labelingSuggestionGenerator.getDeploymentCode('microbit', oldModelCode => { - const modelCode = useEllModel ? ellModelCode : oldModelCode; - // #### hack: replace code passed in with current code from the store - // let appCode = this.state.microbitAppCodeTemplate.replace('// %%HEADER%%', header); - this.setState({ microbitModelCode: modelCode }); - // TODO: set code tabs - }); - const containerWidth = this.refs.container.getBoundingClientRect().width; - const containerHeight = 500; // this.refs.container.getBoundingClientRect().height; - this.setState({ width: containerWidth, height: containerHeight }); - } - - private compile(): void { - this.runScript('--verify'); - } - - private deploy(): void { - this.runScript('--upload'); - } - - private runScript(mode: string): void { - // Create a temp sketch with our files. - const mainTempDir = os.tmpdir() + path.sep + 'DTWSketches'; - if (!fs.existsSync(mainTempDir)) { - fs.mkdirSync(mainTempDir); - } - const topdir = fs.mkdtempSync(os.tmpdir() + path.sep + 'DTWSketches' + path.sep + 'sketch-'); - const tmpdir = topdir + path.sep + 'dtw'; - fs.mkdirSync(tmpdir); - copyTextFile('arduino/BluefruitConfig.h', tmpdir + path.sep + 'BluefruitConfig.h'); - this.state.tabs.forEach(tab => { - const filename = tab.label; - const asmExt = '.asm'; - if (filename.indexOf(asmExt, filename.length - asmExt.length) !== -1) { - if (useStoredModel) { - copyTextFile('arduino/model.asm', tmpdir + path.sep + filename); - } else { - fs.writeFileSync(tmpdir + path.sep + filename, tab.text); - } - const llcArgs = [ - '-mtriple=armv6m-unknown-none-eabi', - '-march=thumb -mcpu=cortex-m0', - '-float-abi=soft', - '-mattr=+armv6-m,+v6m', - '-filetype=asm -asm-verbose=0', - '-o=model.S', - 'model.asm' - ]; - const cmdOutput = execFileSync('llc', llcArgs, { cwd: tmpdir }); - } else { - fs.writeFileSync(tmpdir + path.sep + tab.label, tab.text); - } - }); - this.setState({ toolOutput: '' }); - // Run the arduino command line tool. - const arduinoCmd = 'C:\\Program Files (x86)\\Arduino\\arduino_debug.exe'; - const board = 'adafruit:samd:adafruit_feather_m0'; - const port = 'COM8'; - const proc = spawn( - arduinoCmd, - [mode, 'dtw.ino', '--board', board, '--port', port, '--verbose-upload'], - { cwd: tmpdir }); - const report = (line: string, isError: boolean) => { - this.setState({ toolOutput: this.state.toolOutput + line }); - }; - proc.stdout.on('data', data => report(data.toString(), false)); - proc.stderr.on('data', data => report(data.toString(), true)); - proc.on('close', m => report('Done', false)); - this.toolOutputPanel.open(); - } - - - public render(): JSX.Element { - return ( -
-
- -
- - - this.toolOutputPanel = e} - titleText='Deployment Output' - outputText={this.state.toolOutput} /> -
- ); - } -} diff --git a/app/ts/components/deployment/DeploymentToolbar.tsx b/app/ts/components/deployment/DeploymentToolbar.tsx deleted file mode 100644 index b668bf3..0000000 --- a/app/ts/components/deployment/DeploymentToolbar.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import * as React from 'react'; - -export interface DeploymentToolbarProps { - top: number; - left: number; - viewWidth: number; - viewHeight: number; - compileClick: () => void; - deployClick: () => void; -} - -export class DeploymentToolbar extends React.Component { - public render(): JSX.Element { - return ( -
-
- - -
- - -
- ); - } -} diff --git a/app/ts/components/deployment/ScriptEditor.tsx b/app/ts/components/deployment/ScriptEditor.tsx deleted file mode 100644 index ee75cdd..0000000 --- a/app/ts/components/deployment/ScriptEditor.tsx +++ /dev/null @@ -1,54 +0,0 @@ -// tslint:disable:no-reference -/// -// tslint:enable:no-reference -import * as React from 'react'; - -export interface ScriptEditorProps { - width: number; - height: number; - text: string; - readOnly: boolean; -} - -export class ScriptEditor extends React.Component { - private editor: monaco.editor.IStandaloneCodeEditor; - - public refs: { - [key: string]: Element, - container: HTMLElement - }; - - constructor(props: ScriptEditorProps, context: any) { - super(props, context); - } - - public componentDidMount(): void { - const monaco = (global as any).monaco; - this.editor = monaco.editor.create(this.refs.container, { - value: '', - language: 'c', - lineNumbers: false, - glyphMargin: false, - parameterHints: true, - suggestOnTriggerCharacters: true - }); - } - - public componentWillReceiveProps(newProps: ScriptEditorProps): void { - this.editor.getModel().setValue(newProps.text); - this.editor.updateOptions({ readOnly: newProps.readOnly }); - } - - public render(): JSX.Element { - return ( -
-
-
-
- ); - } -} diff --git a/app/ts/components/deployment/ToolOutputPanel.tsx b/app/ts/components/deployment/ToolOutputPanel.tsx deleted file mode 100644 index 56aa7f7..0000000 --- a/app/ts/components/deployment/ToolOutputPanel.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import * as $ from 'jquery'; -import * as React from 'react'; - - -export interface ToolOutputPanelProps { - titleText: string; - outputText: string; -} - -export class ToolOutputPanel extends React.Component { - public refs: { - [key: string]: Element, - collapser: Element, - }; - public open(): void { - if (!$('.panel-collapse').hasClass('in')) { - ($('.collapse') as any).collapse('toggle'); - } - } - public render(): JSX.Element { - return ( -
-
-
- {this.props.titleText} - - - - -
-
-
-
{this.props.outputText}
-
-
- ); - } -} diff --git a/app/ts/components/labeling/LabelingToolbar.tsx b/app/ts/components/labeling/LabelingToolbar.tsx index a5e7a92..cad7158 100644 --- a/app/ts/components/labeling/LabelingToolbar.tsx +++ b/app/ts/components/labeling/LabelingToolbar.tsx @@ -1,7 +1,6 @@ import * as stores from '../../stores/stores'; import { OptionsToolbar } from '../common/OptionsToolbar'; import { InlineClassesListView } from './ClassesListView'; -import { SuggestionsToolbar } from './SuggestionsToolbar'; import { observer } from 'mobx-react'; import * as React from 'react'; @@ -43,7 +42,6 @@ export class LabelingToolbar extends React.Component { - ); } diff --git a/app/ts/components/labeling/SuggestionsToolbar.tsx b/app/ts/components/labeling/SuggestionsToolbar.tsx deleted file mode 100644 index be133bc..0000000 --- a/app/ts/components/labeling/SuggestionsToolbar.tsx +++ /dev/null @@ -1,117 +0,0 @@ -import * as stores from '../../stores/stores'; -import { labelingSuggestionGenerator } from '../../stores/stores'; -import { LabelingSuggestionLogicType } from '../../suggestion/LabelingSuggestionLogic'; -import { ConfidenceSlider } from '../common/ConfidenceSlider'; -import { observer } from 'mobx-react'; -import * as React from 'react'; - - -@observer -export class SuggestionsToolbar extends React.Component<{}, {}> { - private setSuggestionLogicThunk: { [logicType: number]: () => void } = {}; - - constructor(props: {}, context: any) { - super(props, context); - - Object.keys(LabelingSuggestionLogicType).forEach(name => { - const val = LabelingSuggestionLogicType[name]; - this.setSuggestionLogicThunk[val] = this.setSuggestionLogic.bind(this, val); - }); - } - - private setSuggestionLogic(logicType: LabelingSuggestionLogicType): void { - stores.labelingUiStore.setSuggestionLogic(logicType); - } - - private setConfidenceThreshold(value: number): void { - stores.labelingUiStore.setSuggestionConfidenceThreshold(Math.max(0.001, Math.min(0.999, Math.pow(value, 1.0 / 0.3)))); - } - - public render(): JSX.Element { - const logicClassName = (log: LabelingSuggestionLogicType) => { - return stores.labelingUiStore.suggestionLogic.getType() === log ? 'visible' : 'hidden'; - }; - - return ( -
- Suggestions: - - - - - -
- -
    -
  • Suggestion Confidence Threshold
  • - {stores.labelingUiStore.suggestionEnabled ? ( -
    - -
    - ) : null} -
  • -
  • Suggestion Logic
  • -
  • - - Suggest Anywhere, Manual Confirm -
  • -
  • - - Suggest Forward, Manual Confirm -
  • -
  • - - Suggest Forward, Auto Confirm Inbetween -
  • -
  • - - Suggest Forward, Auto Reject Inbetween -
  • -
-
-
- ); - } -} diff --git a/app/ts/stores/DtwModelStore.ts b/app/ts/stores/DtwModelStore.ts deleted file mode 100644 index 13dfc79..0000000 --- a/app/ts/stores/DtwModelStore.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { observable } from 'mobx'; - -// The set of prototypes to use for the DTW classifier - -export interface ReferenceLabel { - series: number[][]; - variance: number; - className: string; -} - -export class DtwModelStore { - @observable public prototypes: ReferenceLabel[]; - @observable public prototypeSampleRate: number; - - constructor() { - this.prototypes = []; - this.prototypeSampleRate = 30; - } -} diff --git a/app/ts/stores/LabelingStore.ts b/app/ts/stores/LabelingStore.ts index f43f6cf..12e03e3 100644 --- a/app/ts/stores/LabelingStore.ts +++ b/app/ts/stores/LabelingStore.ts @@ -27,7 +27,6 @@ export class LabelingStore { private _labelsIndex: TimeRangeIndex