definma-ui/src/app/prediction/prediction.component.ts

130 lines
4.1 KiB
TypeScript
Raw Normal View History

2020-08-12 15:15:31 +02:00
import { Component, OnInit } from '@angular/core';
import {ChartOptions} from 'chart.js';
import {ApiService} from '../services/api.service';
import {animate, style, transition, trigger} from '@angular/animations';
import cloneDeep from 'lodash/cloneDeep';
2020-08-28 08:14:57 +02:00
import omit from 'lodash/omit';
import {DataService} from '../services/data.service';
import {ModelItemModel} from '../models/model-item.model';
2020-08-12 15:15:31 +02:00
@Component({
selector: 'app-prediction',
templateUrl: './prediction.component.html',
styleUrls: ['./prediction.component.scss'],
animations: [
trigger(
'inOut', [
transition(':enter', [
style({height: 0, opacity: 0}),
animate('0.5s ease-out', style({height: '*', opacity: 1}))
]),
transition(':leave', [
style({height: '*', opacity: 1}),
animate('0.5s ease-in', style({height: 0, opacity: 0}))
])
]
)
]
})
export class PredictionComponent implements OnInit {
2020-09-03 15:51:53 +02:00
result: {predictions: string[], mean: string}; // prediction result from python container
2020-08-12 15:15:31 +02:00
loading = false;
activeGroup: ModelItemModel = new ModelItemModel();
activeModelIndex = 0;
2020-09-03 15:51:53 +02:00
// if true, spectra belong to different samples, otherwise multiple spectra from the same sample are given
multipleSamples = false;
spectrumNames: string[] = [];
2020-08-12 15:15:31 +02:00
spectrum: string[][] = [[]];
flattenedSpectra = [];
chart = [];
readonly chartInit = {
2020-08-12 15:15:31 +02:00
data: [],
label: 'Spectrum',
showLine: true,
fill: false,
pointRadius: 0,
borderColor: '#00a8b0',
borderWidth: 2
};
2020-08-12 15:15:31 +02:00
readonly chartOptions: ChartOptions = {
scales: {
xAxes: [{ticks: {min: 400, max: 4000, stepSize: 400, reverse: true}}],
2020-09-03 15:51:53 +02:00
yAxes: [{ticks: {}}]
2020-08-12 15:15:31 +02:00
},
responsive: true,
tooltips: {enabled: false},
hover: {mode: null},
maintainAspectRatio: true,
plugins: {datalabels: {display: false}}
};
constructor(
private api: ApiService,
public d: DataService
) {
this.chart[0] = cloneDeep(this.chartInit);
}
2020-08-12 15:15:31 +02:00
ngOnInit(): void {
this.d.load('modelGroups', () => {
this.activeGroup = this.d.arr.modelGroups[0];
});
2020-08-12 15:15:31 +02:00
}
fileToArray(files) {
this.loading = true;
this.flattenedSpectra = [];
this.chart = [];
let load = files.length;
this.spectrumNames = files.map(e => e.name);
for (const i in files) {
if (files.hasOwnProperty(i)) {
const fileReader = new FileReader();
fileReader.onload = () => {
2020-09-03 15:51:53 +02:00
// parse to database spectrum representation
2020-08-26 19:25:31 +02:00
this.spectrum = fileReader.result.toString().split('\r\n').map(e => e.split(',').map(el => parseFloat(el)))
.filter(el => el.length === 2) as any;
2020-09-03 15:51:53 +02:00
// flatten to format needed for prediction
this.flattenedSpectra[i] = {labels: this.spectrum.map(e => e[0]), values: this.spectrum.map(e => e[1])};
2020-09-03 15:51:53 +02:00
// add to chart
this.chart[i] = cloneDeep(this.chartInit);
this.chart[i].data = this.spectrum.map(e => ({x: parseFloat(e[0]), y: parseFloat(e[1])}));
load --;
2020-09-03 15:51:53 +02:00
if (load <= 0) { // all loaded
this.loadPrediction();
}
};
fileReader.readAsText(files[i]);
}
}
2020-08-12 15:15:31 +02:00
}
loadPrediction() {
this.loading = true;
2020-08-28 08:14:57 +02:00
this.api.post<any>(this.activeGroup.models[this.activeModelIndex].url, this.flattenedSpectra, data => {
2020-09-03 15:51:53 +02:00
this.result = { // parse result into prediction and mean string
2020-08-28 08:14:57 +02:00
predictions: Object.entries(omit(data, ['mean', 'std', 'label']))
.map((p: any) => p[1].map(e => `${p[0]}: ${e} ${data.label[p[0]]}`))
.reduce((s, e) => s.map((el, i) => this.clip(el) + ', ' + e[i])),
mean: Object.keys(data.mean).map(e =>
2020-09-03 15:51:53 +02:00
this.clip(`${e}: ${data.mean[e]} ${data.label[e]}`) +
(data.std[e] !== '' ? ` (standard deviation: ${data.std[e]})` : '')
2020-08-28 08:14:57 +02:00
).join(', ')
};
this.loading = false;
});
}
2020-09-03 15:51:53 +02:00
groupChange(index) { // group was changed
this.activeGroup = this.d.arr.modelGroups[index];
2020-08-31 16:14:47 +02:00
this.activeModelIndex = 0;
this.result = undefined;
}
2020-08-28 08:14:57 +02:00
clip(str) { // clip spaces at start and end
return str.replace(/^\s*(.*?)\s*$/, '$1');
}
2020-08-12 15:15:31 +02:00
}