state.service.ts 7.19 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;
30
  public loadingText = '';
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
31
32
33
34
35

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

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
40
41
42
  /**
   * 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
43
44
45
  public onNewData: EventEmitter<void> = new EventEmitter<void>();
  public onNewWindows: EventEmitter<void> = new EventEmitter<void>();
  public onNewQuery: EventEmitter<void> = new EventEmitter<void>();
46
  public onNewLshData: EventEmitter<void> = new EventEmitter<void>();
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
47
48
49
50

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

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

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
58
59
60
  /**
   * 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
61
62
63
  async initialize(): Promise<void> {
    this.loadingProgress = 0;
    await this.getRawData();
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
64
65
    // this.loadingProgress = 50;
    // await this.createWindows();
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
66
67
68
    this.loadingProgress = 100;
  }

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
69
70
71
  /**
   * This function resets the application. It re-creates the windows
   */
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
72
73
74
75
76
77
  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
78
79
80
  /**
   * This function retrieves the raw data
   */
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
81
82
  async getRawData(): Promise<void> {
    this.rawData = await this.api.readFile();
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
83
84
    console.log('Printing raw data:');
    console.log(this.rawData);
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
85
86
  }

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
87
88
89
  /**
   * This function creates the windows on the server side
   */
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
90
91
92
93
94
  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
95
96
97
  /**
   * This function performs the first iteration of LSH
   */
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
98
  async lshInitial(): Promise<void> {
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
99
    this._weights = Array(this._queryWindow.length).fill(1);
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
100
    const t0 = new Date().getTime();
101
    this.loadingText = 'Creating LSH model';
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
102
    this.lshData = await this.api.lshInitial(this._queryWindow);
103
    this.loadingText = '';
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
104
    this.computedTime = new Date().getTime() - t0;
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
105
    this._lshParameters = this.lshData.parameters;
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
106
107
  }

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
108
109
110
  /**
   * This function performs every other iteration of LSH
   */
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
111
  async update(labels, hashFunctions): Promise<void> {
112
    this.loadingText = 'Calculating new model parameters';
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
113
    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
114
    const t0 = new Date().getTime();
115
    this.loadingText = 'Creating LSH model';
116
    this.lshData = await this.api.lshUpdate(this._queryWindow, this._weights, this._lshParameters);
117
    this.loadingText = '';
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
118
    this.computedTime = new Date().getTime() - t0;
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
119
120
  }

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
121
122
123
  /**
   * This function retrieves additional information given a table
   */
124
125
  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
126
127
  }

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
128
129
130
  /**
   * This function retrieves the query
   */
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
131
132
  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
133
    console.log('Printing query:');
134
    console.log(this.queryWindow);
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
135
136
137
    return this._queryWindow;
  }

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
138
139
140
  /**
   * This function retrieves the window given the window index
   */
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
141
  async getWindow(indices: number[]): Promise<number[][][]> {
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
142
143
144
    return await this.api.getWindowByIndices(indices);
  }

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
145
  public async saveState() {
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
146
147
148
149
150
151
152
153
154
155
    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,
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
156
      image: undefined,
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
157
158
      children: undefined
    };
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
159
    console.log(this.states[this.maxStateIndex]);
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
160
161
162
163
164
165
166
167
168
169
170
171
172
    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
173
174
175
  /**
   * These are all setters and getters
   */
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
176
  public set rawData(v: RawData[]) {
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
177
178
179
180
    this._rawData = v;
    this.onNewData.emit();
  }

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
181
  public get rawData(): RawData []{
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
182
183
184
185
186
    return this._rawData;
  }

  public set lshData(v: LshData) {
    this._lshData = v;
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
187
188
    this.saveState();
    console.log(this.states);
189
    this.onNewLshData.emit();
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
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
215
216
217
218
219
220
221
222
  }

  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;
  }

223
224
225
226
227
228
229
230
231
  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
232
  public set queryWindow(v: number[][]) {
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
233
234
235
236
    this._queryWindow = v;
    this.onNewQuery.emit();
  }

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
237
  public get queryWindow(): number[][] {
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
238
239
240
    return this._queryWindow;
  }

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
241
242
243
244
  public get lshParameters(): number[] {
    return this._lshParameters;
  }

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
245
  public get parameters(): Parameters {
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
246
247
248
249
250
251
252
    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
253

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
254
255
256
257
258
259
  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
260
261
262
263
264
265
266
267
  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
268
}