diff --git a/src/app/app.module.ts b/src/app/app.module.ts index b3d8a75..48598f8 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -32,6 +32,7 @@ import { ServiceWorkerModule } from '@angular/service-worker'; import { environment } from '../environments/environment'; import { HelpComponent } from './help/help.component'; import { ModelTemplatesComponent } from './model-templates/model-templates.component'; +import { SizePipe } from './size.pipe'; @NgModule({ declarations: [ @@ -54,7 +55,8 @@ import { ModelTemplatesComponent } from './model-templates/model-templates.compo DocumentationDatabaseComponent, PredictionComponent, HelpComponent, - ModelTemplatesComponent + ModelTemplatesComponent, + SizePipe ], imports: [ LocalStorageModule.forRoot({ diff --git a/src/app/model-templates/model-templates.component.html b/src/app/model-templates/model-templates.component.html index 89fb48b..6fb2fac 100644 --- a/src/app/model-templates/model-templates.component.html +++ b/src/app/model-templates/model-templates.component.html @@ -15,9 +15,6 @@ {{nameInput.errors.failure}} Cannot be empty - - {{labelInput.errors.failure}} - {{urlInput.errors.failure}} Cannot be empty @@ -28,10 +25,9 @@ - + Name - Label URL @@ -41,7 +37,6 @@ {{group.group}} {{modelItem.name}} - {{modelItem.label}} {{modelItem.url}} + (click)="delete(modalDeleteConfirm, modelItem.name, group.group)"> + + + Model files + + + + + {{file.name}} + {{file.size | size:'M'}} + + + + - Do you really want to delete this model? + Do you really want to delete? diff --git a/src/app/model-templates/model-templates.component.ts b/src/app/model-templates/model-templates.component.ts index 8af9457..bab3aee 100644 --- a/src/app/model-templates/model-templates.component.ts +++ b/src/app/model-templates/model-templates.component.ts @@ -35,13 +35,14 @@ export class ModelTemplatesComponent implements OnInit { this.d.load('modelGroups', () => { this.groups = this.d.arr.modelGroups.map(e => e.group); }); + this.d.load('modelFiles'); } saveModel() { console.log(this.modelGroup); console.log(this.oldModelGroup); if (this.oldModelGroup !== '' && this.modelGroup !== this.oldModelGroup) { // group was changed, delete model in old group - this.deleteModel(this.oldModelGroup, this.oldModelName); + this.deleteModel(null, this.oldModelGroup, this.oldModelName); } this.api.post('/model/' + this.modelGroup, this.model, () => { this.newModel = false; @@ -53,7 +54,7 @@ export class ModelTemplatesComponent implements OnInit { }); } - deleteModel(group, name, modal = null) { + delete(modal, name, group = null) { new Promise(resolve => { if (modal) { this.modal.open(modal).then(result => { @@ -65,9 +66,16 @@ export class ModelTemplatesComponent implements OnInit { } }).then(res => { if (res) { - this.api.delete(`/model/${group}/${name}`, () => { - this.loadGroups(); - }); + if (group) { // delete group + this.api.delete(`/model/${group}/${name}`, () => { + this.loadGroups(); + }); + } + else { // delete file + this.api.delete(`/model/file/${name}`, () => { + this.d.arr.modelFiles.splice(this.d.arr.modelFiles.findIndex(e => e.name === name), 1); + }); + } } }); } diff --git a/src/app/models/model-file.model.spec.ts b/src/app/models/model-file.model.spec.ts new file mode 100644 index 0000000..6b1f9f3 --- /dev/null +++ b/src/app/models/model-file.model.spec.ts @@ -0,0 +1,7 @@ +import { ModelFileModel } from './model-file.model'; + +describe('ModelFile.Model', () => { + it('should create an instance', () => { + expect(new ModelFileModel()).toBeTruthy(); + }); +}); diff --git a/src/app/models/model-file.model.ts b/src/app/models/model-file.model.ts new file mode 100644 index 0000000..4235376 --- /dev/null +++ b/src/app/models/model-file.model.ts @@ -0,0 +1,6 @@ +import {BaseModel} from './base.model'; + +export class ModelFileModel extends BaseModel { + name = ''; + size = 0; +} diff --git a/src/app/models/model-item.model.ts b/src/app/models/model-item.model.ts index 4c3c5d7..86f8302 100644 --- a/src/app/models/model-item.model.ts +++ b/src/app/models/model-item.model.ts @@ -4,7 +4,6 @@ export class ModelItemModel extends BaseModel { group = ''; models = [{ name: '', - url: '', - label: '' + url: '' }]; } diff --git a/src/app/prediction/prediction.component.html b/src/app/prediction/prediction.component.html index cce80cd..46a4359 100644 --- a/src/app/prediction/prediction.component.html +++ b/src/app/prediction/prediction.component.html @@ -13,21 +13,17 @@

- {{spectrumNames[i]}}: {{prediction}} {{activeGroup.models[activeModelIndex].label}} - # + {{spectrumNames[i]}}: {{prediction}}#

- Average result: {{result.meanPrediction}} {{activeGroup.models[activeModelIndex].label}} - #, - standard deviation: {{result.std}}# + Average result: {{result.mean}}#

Details

- {{spectrumNames[i]}}: {{prediction}} {{activeGroup.models[activeModelIndex].label}} - # + {{spectrumNames[i]}}: {{prediction}}#

diff --git a/src/app/prediction/prediction.component.ts b/src/app/prediction/prediction.component.ts index 075c150..d6cb0c2 100644 --- a/src/app/prediction/prediction.component.ts +++ b/src/app/prediction/prediction.component.ts @@ -3,15 +3,10 @@ import {ChartOptions} from 'chart.js'; import {ApiService} from '../services/api.service'; import {animate, style, transition, trigger} from '@angular/animations'; import cloneDeep from 'lodash/cloneDeep'; +import omit from 'lodash/omit'; import {DataService} from '../services/data.service'; import {ModelItemModel} from '../models/model-item.model'; -import {HttpClient} from '@angular/common/http'; -interface PredictionResult { - meanPrediction: string; - std: string; - predictions: string[]; -} @Component({ selector: 'app-prediction', @@ -34,7 +29,7 @@ interface PredictionResult { }) export class PredictionComponent implements OnInit { - result: PredictionResult; + result: {predictions: string[], mean: string}; loading = false; activeGroup: ModelItemModel = new ModelItemModel(); activeModelIndex = 0; @@ -104,9 +99,16 @@ export class PredictionComponent implements OnInit { loadPrediction() { this.loading = true; - console.log(this.activeModelIndex); - this.api.post(this.activeGroup.models[this.activeModelIndex].url, this.flattenedSpectra, data => { - this.result = data; + this.api.post(this.activeGroup.models[this.activeModelIndex].url, this.flattenedSpectra, data => { + this.result = { + 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 => + this.clip(`${e}: ${data.mean[e]} ${data.label[e]}`) + (data.std[e] !== '' ? ` (standard deviation: ${data.std[e]})` : '') + ).join(', ') + }; + console.log(this.result); this.loading = false; }); } @@ -115,4 +117,8 @@ export class PredictionComponent implements OnInit { this.activeGroup = this.d.arr.modelGroups[index]; this.result = undefined; } + + clip(str) { // clip spaces at start and end + return str.replace(/^\s*(.*?)\s*$/, '$1'); + } } diff --git a/src/app/sample/sample.component.html b/src/app/sample/sample.component.html index 3448b5b..98a6b8d 100644 --- a/src/app/sample/sample.component.html +++ b/src/app/sample/sample.component.html @@ -238,7 +238,7 @@ [(ngModel)]="measurement.measurement_template" (ngModelChange)="clearMeasurement(gIndex, mIndex)"> @@ -330,7 +330,7 @@ - Do you really want to delete {{samples.length > 1 ? 'these samples' : 'this sample'}}? + Do you really want to delete {{(samples.length > 1 ? 'samples ' : 'sample ') + sampleNames()}}? diff --git a/src/app/sample/sample.component.ts b/src/app/sample/sample.component.ts index 9fa4ba0..554620f 100644 --- a/src/app/sample/sample.component.ts +++ b/src/app/sample/sample.component.ts @@ -613,6 +613,10 @@ export class SampleComponent implements OnInit, AfterContentChecked { return this.sampleReferenceList.bind(this); } + sampleNames() { + return this.samples.map(e => e.number).join(', '); + } + uniqueCfValues(index) { // returns all names until index for unique check return this.customFields ? this.customFields.slice(0, index).map(e => e[0]) : []; } diff --git a/src/app/services/data.service.ts b/src/app/services/data.service.ts index 3e76e0a..e1425a0 100644 --- a/src/app/services/data.service.ts +++ b/src/app/services/data.service.ts @@ -5,6 +5,7 @@ import {MaterialModel} from '../models/material.model'; import {BaseModel} from '../models/base.model'; import {UserModel} from '../models/user.model'; import {ModelItemModel} from '../models/model-item.model'; +import {ModelFileModel} from '../models/model-file.model'; @Injectable({ providedIn: 'root' @@ -25,6 +26,7 @@ export class DataService { sampleNotesFields: {path: '/sample/notes/fields', model: TemplateModel, type: 'idArray'}, users: {path: '/users', model: UserModel, type: 'idArray'}, modelGroups: {path: '/model/groups', model: ModelItemModel, type: 'array'}, + modelFiles: {path: '/model/files', model: ModelFileModel, type: 'array'}, user: {path: '/user', model: UserModel, type: 'string'}, userKey: {path: '/user/key', model: BaseModel, type: 'string'} }; diff --git a/src/app/size.pipe.spec.ts b/src/app/size.pipe.spec.ts new file mode 100644 index 0000000..5a0238e --- /dev/null +++ b/src/app/size.pipe.spec.ts @@ -0,0 +1,8 @@ +import { SizePipe } from './size.pipe'; + +describe('SizePipe', () => { + it('create an instance', () => { + const pipe = new SizePipe(); + expect(pipe).toBeTruthy(); + }); +}); diff --git a/src/app/size.pipe.ts b/src/app/size.pipe.ts new file mode 100644 index 0000000..ea3cbe8 --- /dev/null +++ b/src/app/size.pipe.ts @@ -0,0 +1,16 @@ +import { Pipe, PipeTransform } from '@angular/core'; + +@Pipe({ + name: 'size' +}) +export class SizePipe implements PipeTransform { + + transform(value: number, exp: string): string { + const divide = ['', 'k', 'M', 'G', 'T'].indexOf(exp); + for (let i = 0; i < divide; i ++) { + value = value / 1024; + } + return `${value.toFixed(2)} ${exp}B`; + } + +}