-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathBufferedTomDataW.ts
More file actions
113 lines (97 loc) · 3.44 KB
/
BufferedTomDataW.ts
File metadata and controls
113 lines (97 loc) · 3.44 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
104
105
106
107
108
109
110
111
112
113
import { Vector3 } from 'three';
import { TOM_HEADER_NUM_BYTES } from './Defaults';
import { DeepReadonly } from 'ts-essentials';
import { TomTypedArray, TomType } from './types';
import { writeTomHeaderToBuffer } from './io';
import { dataSizeForType, safeDeleteFile } from './utils';
import { openSync, closeSync, writeSync } from 'fs';
const headerBuffer = Buffer.alloc(TOM_HEADER_NUM_BYTES);
/**
* Buffered data that must be dynamically loaded
* (too big to fit in memory at once)
* This is a Read-Only view into the file.
*/
export class BufferedTomDataW {
// File parameters
protected dim: DeepReadonly<Vector3>;
protected type: Readonly<TomType>;
protected useNull: Readonly<boolean>;
protected numElementsPerVoxel: Readonly<number>;
protected buffer: Buffer;
protected file: Readonly<number>;
protected data: TomTypedArray;
// Precomputed values.
protected dataSize: Readonly<number>;
protected layerDim: Readonly<number>;
/**
* @constructor
* @param {string} path filename where data is stored
* @param {string} filename filename where data is stored
*/
constructor(path: string, filename: string, type: TomType, dimensions: Vector3, numElements = 1, useNull = false) {
const fullPath = `${path}${filename}.tom`;
// Delete old file if it exists.
safeDeleteFile(fullPath);
// Create new file and open in write mode.
this.file = this.openFile(fullPath);
// Save params.
this.type = type;
this.dim = dimensions;
this.numElementsPerVoxel = numElements;
this.useNull = useNull;
// Write a header.
writeTomHeaderToBuffer(fullPath, headerBuffer, type, dimensions, numElements, useNull);
writeSync(this.file, headerBuffer, 0, headerBuffer.length, 0);
// Init other params.
this.dataSize = dataSizeForType(type);
this.layerDim = dimensions.x * dimensions.y * numElements;
this.buffer = Buffer.alloc(this.layerDim * this.dataSize);
switch (type) {
case 'uint8':
this.data = new Uint8Array(this.buffer.buffer);
break;
case 'float32':
this.data = new Float32Array(this.buffer.buffer);
break;
case 'int32':
this.data = new Int32Array(this.buffer.buffer);
break;
case 'uint32':
this.data = new Uint32Array(this.buffer.buffer);
break;
default:
throw new Error(`Unsupported type ${type}.`);
}
}
/**
* Opens file in write mode by default.
* @private
* @param {string} fullPath fullPath where data is stored
*/
protected openFile(fullPath: string) {
// Would be better to open in append mode 'a', but not supported by all systems.
return openSync(fullPath, 'w');
}
changeFile(fullPath: string) {
this.close();
this.file = this.openFile(fullPath);
// Because we are in write mode and not append mode, we must rewrite the header.
// Write a header.
writeTomHeaderToBuffer(fullPath, headerBuffer, this.type, this.dim, this.numElementsPerVoxel, this.useNull);
writeSync(this.file, headerBuffer, 0, headerBuffer.length, 0);
}
writeLayer(z: number) {
// Save buffer to disk.
const offset = z * this.layerDim * this.dataSize;
writeSync(this.file, this.buffer, 0, this.buffer.length, offset + TOM_HEADER_NUM_BYTES);
}
getData() {
return this.data;
}
/**
* Closes file, clears all memory for garbage collection.
*/
close() {
closeSync(this.file);
}
}