annotate src/app/services/feature-extraction/feature-extraction.service.ts @ 349:bf038a51f7e3

Restore some of the feature related logic from waveform.component into a utilities module. Introduce some additional types for representing reshaped features. A work in progress.
author Lucas Thompson <dev@lucas.im>
date Thu, 25 May 2017 17:57:03 +0100
parents e401995304a7
children 524f5cd75737
rev   line source
dev@74 1 import {Injectable, Inject} from '@angular/core';
dev@47 2 import {
dev@226 3 ListResponse
dev@236 4 } from 'piper';
dev@64 5 import {
dev@226 6 SimpleRequest,
dev@226 7 SimpleResponse
dev@236 8 } from 'piper/HigherLevelUtilities';
dev@236 9 import {Subject} from 'rxjs/Subject';
dev@236 10 import {Observable} from 'rxjs/Observable';
dev@324 11 import {Http} from '@angular/http';
dev@226 12 import {
dev@226 13 countingIdProvider,
dev@226 14 WebWorkerStreamingClient
dev@236 15 } from 'piper/client-stubs/WebWorkerStreamingClient';
dev@236 16 import {RequestId} from 'piper/protocols/WebWorkerProtocol';
dev@316 17 import {collect, StreamingConfiguration} from 'piper/StreamingService';
dev@349 18 import {
dev@349 19 KnownShapedFeature,
dev@349 20 toKnownShape
dev@349 21 } from '../../visualisations/FeatureUtilities';
dev@40 22
dev@74 23 type RepoUri = string;
dev@74 24 export interface AvailableLibraries {
dev@74 25 [libraryKey: string]: RepoUri;
dev@74 26 }
dev@74 27
dev@226 28 export interface Progress {
dev@226 29 id: RequestId;
dev@226 30 value: number; // between 0 and 100, for material-ui
dev@226 31 }
dev@226 32
dev@40 33 @Injectable()
dev@40 34 export class FeatureExtractionService {
dev@40 35
dev@40 36 private worker: Worker;
dev@349 37 private featuresExtracted: Subject<KnownShapedFeature>;
dev@349 38 featuresExtracted$: Observable<KnownShapedFeature>;
dev@74 39 private librariesUpdated: Subject<ListResponse>;
dev@74 40 librariesUpdated$: Observable<ListResponse>;
dev@226 41 private progressUpdated: Subject<Progress>;
dev@226 42 progressUpdated$: Observable<Progress>;
dev@226 43 private client: WebWorkerStreamingClient;
dev@44 44
dev@236 45 constructor(private http: Http,
dev@236 46 @Inject('PiperRepoUri') private repositoryUri: RepoUri) {
dev@40 47 this.worker = new Worker('bootstrap-feature-extraction-worker.js');
dev@349 48 this.featuresExtracted = new Subject<KnownShapedFeature>();
dev@51 49 this.featuresExtracted$ = this.featuresExtracted.asObservable();
dev@74 50 this.librariesUpdated = new Subject<ListResponse>();
dev@74 51 this.librariesUpdated$ = this.librariesUpdated.asObservable();
dev@226 52 this.progressUpdated = new Subject<Progress>();
dev@226 53 this.progressUpdated$ = this.progressUpdated.asObservable();
dev@74 54 this.worker.addEventListener('message', (ev: MessageEvent) => {
dev@74 55 const isValidResponse = ev.data.method === 'import'
dev@226 56 && ev.data.result && ev.data.result.available ;
dev@74 57 if (isValidResponse) {
dev@226 58 (ev as Event).stopImmediatePropagation();
dev@74 59 this.librariesUpdated.next(ev.data.result);
dev@74 60 }
dev@226 61 }, true);
dev@226 62
dev@226 63 this.client = new WebWorkerStreamingClient(
dev@226 64 this.worker,
dev@226 65 countingIdProvider(0)
dev@236 66 );
dev@40 67 }
dev@40 68
dev@47 69 list(): Promise<ListResponse> {
dev@326 70 return this.client.list({});
dev@40 71 }
dev@40 72
dev@226 73 extract(analysisItemId: string, request: SimpleRequest): Promise<void> {
dev@305 74 let config: StreamingConfiguration;
dev@305 75 return collect(this.client.process(request), val => {
dev@305 76 if (val.configuration) {
dev@305 77 config = val.configuration;
dev@305 78 }
dev@305 79 const progress = val.progress;
dev@305 80 if (progress.totalBlockCount > 0) {
dev@305 81 this.progressUpdated.next({
dev@305 82 id: analysisItemId,
dev@305 83 value: (progress.processedBlockCount / progress.totalBlockCount) * 100
dev@305 84 });
dev@305 85 }
dev@305 86 }).then(features => {
dev@349 87 const shaped = toKnownShape({
dev@305 88 features: features,
dev@305 89 outputDescriptor: config.outputDescriptor
dev@226 90 });
dev@349 91 console.warn(shaped.shape);
dev@349 92 this.featuresExtracted.next(shaped);
dev@305 93 });
dev@62 94 }
dev@62 95
dev@324 96 updateAvailableLibraries(): void {
dev@324 97 this.http.get(this.repositoryUri)
dev@324 98 .toPromise() // just turn into a promise for now to subscribe / execute
dev@324 99 .then(res => {
dev@74 100 this.worker.postMessage({
dev@74 101 method: 'addRemoteLibraries',
dev@324 102 params: res.json()
dev@349 103 });
dev@74 104 })
dev@324 105 .catch(console.error); // TODO Report error to user
dev@74 106 }
dev@74 107
dev@74 108 load(libraryKey: string): void {
dev@74 109 this.worker.postMessage({method: 'import', params: libraryKey});
dev@74 110 }
dev@40 111 }