state.service.ts 6.89 KB
Newer Older
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
1
import {EventEmitter, Injectable} from '@angular/core';
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
2
import {ApiService, LshData, Parameters, RawData, State, StateNode, TableInfoData} from './api.service';
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
3
4
5
6

@Injectable({
  providedIn: 'root'
})
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
7
8
9
10
/**
 * This service acts as the state of the entire application. Components can subscribe to EventEmitters within this state to update their
 * contents.
 */
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
11
export class StateService {
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
12
13
14
  /**
   * These are all LSH specific variables. The variables can be accessed using the getters and setters
   */
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
15
16
17
  public currStateIndex = 0;
  public maxStateIndex = 0;
  public states: {[idx: number]: StateNode} = {};
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
18
  private _rawData: RawData[];
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
19
  private _lshData: LshData;
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
20
  private _queryWindow: number[][];
21
  private _weights: number[];
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
22
  private _labels = {};
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
23
  private _lshParameters: number[];
24
  private _selection: number[];
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
25
  public computedTime = 0;
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
26
27
28
29
  public windowSize = 120;
  public nrOfTables = 5;
  public hashSize = 5;
  public stepSize = 200;
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
30
31
32
33
34

  /**
   * These are all GUI variables
   */
  public loadingProgress = 0;
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
35
  public querySelectionMode = true;
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
36
37
  private _currentTab: number;
  private _sliderValue;
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
38

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
39
40
41
  /**
   * These are all EventEmitters. Subscribe to these if you want to be informed about an update in state.
   */
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
42
43
44
  public onNewData: EventEmitter<void> = new EventEmitter<void>();
  public onNewWindows: EventEmitter<void> = new EventEmitter<void>();
  public onNewQuery: EventEmitter<void> = new EventEmitter<void>();
45
  public onNewLshData: EventEmitter<void> = new EventEmitter<void>();
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
46
47
48
49

  public onNewLabels: EventEmitter<void> = new EventEmitter<void>();
  public onNewTab: EventEmitter<void> = new EventEmitter<void>();
  public onNewSlider: EventEmitter<number> = new EventEmitter<number>();
50
  public onNewSelection: EventEmitter<number[]> = new EventEmitter<number[]>();
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
51
52

  constructor(private api: ApiService) {
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
53
     this._selection = [0];
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
54
55
56
     this.initialize();
  }

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
57
58
59
  /**
   * This function initializes the application. It retrieves the raw data and creates windows.
   */
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
60
61
62
  async initialize(): Promise<void> {
    this.loadingProgress = 0;
    await this.getRawData();
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
63
64
    // this.loadingProgress = 50;
    // await this.createWindows();
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
65
66
67
    this.loadingProgress = 100;
  }

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
68
69
70
  /**
   * This function resets the application. It re-creates the windows
   */
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
71
72
73
74
75
76
  async reset(): Promise<void> {
    this.loadingProgress = 50;
    await this.createWindows();
    this.loadingProgress = 100;
  }

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
77
78
79
  /**
   * This function retrieves the raw data
   */
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
80
81
  async getRawData(): Promise<void> {
    this.rawData = await this.api.readFile();
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
82
83
    console.log('Printing raw data:');
    console.log(this.rawData);
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
84
85
  }

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
86
87
88
  /**
   * This function creates the windows on the server side
   */
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
89
90
91
92
93
  async createWindows(): Promise<void> {
    await this.api.createWindows(this.parameters);
    this.onNewWindows.emit();
  }

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
94
95
96
  /**
   * This function performs the first iteration of LSH
   */
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
97
  async lshInitial(): Promise<void> {
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
98
    this._weights = Array(this._queryWindow.length).fill(1);
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
99
    const t0 = new Date().getTime();
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
100
    this.lshData = await this.api.lshInitial(this._queryWindow);
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
101
    this.computedTime = new Date().getTime() - t0;
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
102
    this._lshParameters = this.lshData.parameters;
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
103
104
  }

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
105
106
107
  /**
   * This function performs every other iteration of LSH
   */
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
108
109
  async update(labels, hashFunctions): Promise<void> {
    this._weights = await this.api.getWeights(this._queryWindow, labels, this._weights, hashFunctions);
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
110
    const t0 = new Date().getTime();
111
    this.lshData = await this.api.lshUpdate(this._queryWindow, this._weights, this._lshParameters);
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
112
    this.computedTime = new Date().getTime() - t0;
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
113
114
  }

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
115
116
117
  /**
   * This function retrieves additional information given a table
   */
118
119
  async getTableInfo(table: number[][]): Promise<TableInfoData> {
    return await this.api.getTableInfo(table);
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
120
121
  }

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
122
123
124
  /**
   * This function retrieves the query
   */
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
125
126
  async getQueryWindow(windowIndex: number | {[index: number]: boolean}, querySize, startIndex): Promise<number[][]> {
    this.queryWindow = await this.api.getQueryWindow(windowIndex, querySize, startIndex);
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
127
    console.log('Printing query:');
128
    console.log(this.queryWindow);
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
129
130
131
    return this._queryWindow;
  }

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
132
133
134
  /**
   * This function retrieves the window given the window index
   */
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
135
  async getWindow(indices: number[]): Promise<number[][][]> {
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
136
137
138
    return await this.api.getWindowByIndices(indices);
  }

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
  public saveState() {
    this.maxStateIndex++;
    if (this.currStateIndex > 0) {
      if (!this.states[this.currStateIndex].children) {
        this.states[this.currStateIndex].children = [];
      }
      this.states[this.currStateIndex].children.push(this.maxStateIndex);
    }
    this.states[this.maxStateIndex] = {
      id: this.maxStateIndex,
      state: this.state,
      children: undefined
    };
    this.currStateIndex = this.maxStateIndex;
  }

  public loadState(stateIndex) {
    const stateNode = this.states[stateIndex];
    this.currStateIndex = Number(stateNode.id);
    this._lshData = stateNode.state.lshData;
    this.queryWindow = stateNode.state.queryWindow;
    this._weights = stateNode.state.weights;
    this.labels = stateNode.state.labels;
    this.onNewLshData.emit();
  }

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
165
166
167
  /**
   * These are all setters and getters
   */
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
168
  public set rawData(v: RawData[]) {
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
169
170
171
172
    this._rawData = v;
    this.onNewData.emit();
  }

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
173
  public get rawData(): RawData []{
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
174
175
176
177
178
    return this._rawData;
  }

  public set lshData(v: LshData) {
    this._lshData = v;
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
179
180
    this.saveState();
    console.log(this.states);
181
    this.onNewLshData.emit();
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
  }

  public get lshData(): LshData {
    return this._lshData;
  }

  public set labels(v) {
    this._labels = v;
    this.onNewLabels.emit();
  }

  public get labels() {
    return this._labels;
  }

  public set currentTab(v: number) {
    this._currentTab = v;
    this.onNewTab.emit();
  }

  public get currentTab(): number {
    return this._currentTab;
  }

  public set sliderValue(v: number) {
    this._sliderValue = v;
    this.onNewSlider.emit(v);
  }

  public get sliderValue(): number {
    return this._sliderValue;
  }

215
216
217
218
219
220
221
222
223
  public set selection(v: number[]) {
    this._selection = v;
    this.onNewSelection.emit(v);
  }

  public get selection(): number[] {
    return this._selection;
  }

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
224
  public set queryWindow(v: number[][]) {
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
225
226
227
228
    this._queryWindow = v;
    this.onNewQuery.emit();
  }

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
229
  public get queryWindow(): number[][] {
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
230
231
232
    return this._queryWindow;
  }

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
233
234
235
236
  public get lshParameters(): number[] {
    return this._lshParameters;
  }

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
237
  public get parameters(): Parameters {
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
238
239
240
241
242
243
244
    return {
      windowsize: this.windowSize,
      hashsize: this.hashSize,
      tablesize: this.nrOfTables,
      stepsize: this.stepSize
    };
  }
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
245

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
246
247
248
249
250
251
  public get colors(): string[] {
    return ['#377eb8', '#ff7f00', '#4daf4a',
      '#f781bf', '#a65628', '#984ea3',
      '#999999', '#e41a1c', '#dede00'];
  }

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
252
253
254
255
256
257
258
259
  public get state(): State {
    return {
      lshData: this.lshData,
      queryWindow: this.queryWindow,
      weights: this._weights,
      labels: this.labels
    };
  }
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
260
}