-
Notifications
You must be signed in to change notification settings - Fork 95
Expand file tree
/
Copy pathdatasets-images.ts
More file actions
103 lines (88 loc) · 3.32 KB
/
datasets-images.ts
File metadata and controls
103 lines (88 loc) · 3.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import { defineStore } from 'pinia';
import { vec3, mat3, mat4 } from 'gl-matrix';
import { vtkImageData } from '@kitware/vtk.js/Common/DataModel/ImageData';
import type { Bounds } from '@kitware/vtk.js/types';
import { useIdStore } from '@/src/store/id';
import { defaultLPSDirections, getLPSDirections } from '../utils/lps';
import { removeFromArray } from '../utils';
import { StateFile, DatasetType } from '../io/state-file/schema';
import { serializeData } from '../io/state-file/utils';
import { useFileStore } from './datasets-files';
import { ImageMetadata } from '../types/image';
import { compareImageSpaces } from '../utils/imageSpace';
export const defaultImageMetadata = () => ({
name: '(none)',
orientation: mat3.create(),
lpsOrientation: defaultLPSDirections(),
spacing: vec3.fromValues(1, 1, 1),
origin: vec3.create(),
dimensions: vec3.fromValues(1, 1, 1),
worldBounds: [0, 1, 0, 1, 0, 1] as Bounds,
worldToIndex: mat4.create(),
indexToWorld: mat4.create(),
});
interface State {
idList: string[]; // list of IDs
dataIndex: Record<string, vtkImageData>; // ID -> VTK object
metadata: Record<string, ImageMetadata>; // ID -> metadata
}
export const useImageStore = defineStore('images', {
state: (): State => ({
idList: [],
dataIndex: Object.create(null),
metadata: Object.create(null),
}),
actions: {
addVTKImageData(name: string, imageData: vtkImageData, useId?: string) {
if (useId && useId in this.dataIndex) {
throw new Error('ID already exists');
}
const id = useId || useIdStore().nextId();
this.idList.push(id);
this.dataIndex[id] = imageData;
this.metadata[id] = { ...defaultImageMetadata(), name };
this.updateData(id, imageData);
return id;
},
updateData(id: string, imageData: vtkImageData) {
if (id in this.metadata) {
const metadata: ImageMetadata = {
name: this.metadata[id].name,
dimensions: imageData.getDimensions() as vec3,
spacing: imageData.getSpacing() as vec3,
origin: imageData.getOrigin() as vec3,
orientation: imageData.getDirection(),
lpsOrientation: getLPSDirections(imageData.getDirection()),
worldBounds: imageData.getBounds(),
worldToIndex: imageData.getWorldToIndex(),
indexToWorld: imageData.getIndexToWorld(),
};
this.metadata[id] = metadata;
this.dataIndex[id] = imageData;
}
this.dataIndex[id] = imageData;
},
deleteData(id: string) {
if (id in this.dataIndex) {
delete this.dataIndex[id];
delete this.metadata[id];
removeFromArray(this.idList, id);
}
},
checkAllImagesSameSpace() {
if (this.idList.length < 2) return false;
const dataFirst = this.dataIndex[this.idList[0]];
const allEqual = this.idList.slice(1).every((id) => {
return compareImageSpaces(this.dataIndex[id], dataFirst);
});
return allEqual;
},
async serialize(stateFile: StateFile) {
const fileStore = useFileStore();
// We want to filter out volume images (which are generated and don't have
// input files in fileStore with matching imageID.)
const dataIDs = this.idList.filter((id) => id in fileStore.byDataID);
await serializeData(stateFile, dataIDs, DatasetType.IMAGE);
},
},
});