Skip to content
Snippets Groups Projects
Commit b3c368d5 authored by Alexander Rose's avatar Alexander Rose
Browse files

use FileHandle and SimpleBuffer in volume server

parent b73c3b6b
No related branches found
No related tags found
No related merge requests found
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
*/ */
import * as UTF8 from 'mol-io/common/utf8' import * as UTF8 from 'mol-io/common/utf8'
import { SimpleBuffer } from 'mol-io/common/simple-buffer';
export type Bool = { kind: 'bool' } export type Bool = { kind: 'bool' }
export type Int = { kind: 'int' } export type Int = { kind: 'int' }
...@@ -105,7 +106,7 @@ export function encode(element: Element, src: any): Buffer { ...@@ -105,7 +106,7 @@ export function encode(element: Element, src: any): Buffer {
return write(element, src); return write(element, src);
} }
function decodeElement(e: Element, buffer: Buffer, offset: number, target: { value: any }) { function decodeElement(e: Element, buffer: SimpleBuffer, offset: number, target: { value: any }) {
switch (e.kind) { switch (e.kind) {
case 'bool': target.value = !!buffer.readInt8(offset); offset += 1; break; case 'bool': target.value = !!buffer.readInt8(offset); offset += 1; break;
case 'int': target.value = buffer.readInt32LE(offset); offset += 4; break; case 'int': target.value = buffer.readInt32LE(offset); offset += 4; break;
...@@ -147,7 +148,7 @@ function decodeElement(e: Element, buffer: Buffer, offset: number, target: { val ...@@ -147,7 +148,7 @@ function decodeElement(e: Element, buffer: Buffer, offset: number, target: { val
return offset; return offset;
} }
export function decode<T>(element: Element, buffer: Buffer, offset?: number) { export function decode<T>(element: Element, buffer: SimpleBuffer, offset?: number) {
const target = { value: void 0 as any }; const target = { value: void 0 as any };
decodeElement(element, buffer, offset! | 0, target); decodeElement(element, buffer, offset! | 0, target);
return target.value as T; return target.value as T;
......
...@@ -6,8 +6,8 @@ ...@@ -6,8 +6,8 @@
* @author David Sehnal <david.sehnal@gmail.com> * @author David Sehnal <david.sehnal@gmail.com>
*/ */
import * as File from './file'
import * as Schema from './binary-schema' import * as Schema from './binary-schema'
import { FileHandle } from 'mol-io/common/file-handle';
export type ValueType = 'float32' | 'int8' | 'int16' export type ValueType = 'float32' | 'int8' | 'int16'
...@@ -121,12 +121,12 @@ export function encodeHeader(header: Header) { ...@@ -121,12 +121,12 @@ export function encodeHeader(header: Header) {
return Schema.encode(headerSchema, header); return Schema.encode(headerSchema, header);
} }
export async function readHeader(file: number): Promise<{ header: Header, dataOffset: number }> { export async function readHeader(file: FileHandle): Promise<{ header: Header, dataOffset: number }> {
let { buffer } = await File.readBuffer(file, 0, 4 * 4096); let { buffer } = await file.readBuffer(0, 4 * 4096);
const headerSize = buffer.readInt32LE(0); const headerSize = buffer.readInt32LE(0);
if (headerSize > buffer.byteLength - 4) { if (headerSize > buffer.byteLength - 4) {
buffer = (await File.readBuffer(file, 0, headerSize + 4)).buffer; buffer = (await file.readBuffer(0, headerSize + 4)).buffer;
} }
const header = Schema.decode<Header>(headerSchema, buffer, 4); const header = Schema.decode<Header>(headerSchema, buffer, 4);
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
import * as fs from 'fs' import * as fs from 'fs'
import * as path from 'path' import * as path from 'path'
import * as DataFormat from './data-format' import * as DataFormat from './data-format'
import { FileHandle } from 'mol-io/common/file-handle';
import { SimpleBuffer } from 'mol-io/common/simple-buffer';
export const IsNativeEndianLittle = new Uint16Array(new Uint8Array([0x12, 0x34]).buffer)[0] === 0x3412; export const IsNativeEndianLittle = new Uint16Array(new Uint8Array([0x12, 0x34]).buffer)[0] === 0x3412;
...@@ -29,43 +31,6 @@ export async function openRead(filename: string) { ...@@ -29,43 +31,6 @@ export async function openRead(filename: string) {
}); });
} }
export function readBuffer(file: number, position: number, sizeOrBuffer: Buffer | number, size?: number, byteOffset?: number): Promise<{ bytesRead: number, buffer: Buffer }> {
return new Promise((res, rej) => {
if (typeof sizeOrBuffer === 'number') {
let buff = new Buffer(new ArrayBuffer(sizeOrBuffer));
fs.read(file, buff, 0, sizeOrBuffer, position, (err, bytesRead, buffer) => {
if (err) {
rej(err);
return;
}
res({ bytesRead, buffer });
});
} else {
if (size === void 0) {
rej('readBuffer: Specify size.');
return;
}
fs.read(file, sizeOrBuffer, byteOffset ? +byteOffset : 0, size, position, (err, bytesRead, buffer) => {
if (err) {
rej(err);
return;
}
res({ bytesRead, buffer });
});
}
})
}
export function writeBuffer(file: number, position: number, buffer: Buffer, size?: number): Promise<number> {
return new Promise<number>((res, rej) => {
fs.write(file, buffer, 0, size !== void 0 ? size : buffer.length, position, (err, written) => {
if (err) rej(err);
else res(written);
})
})
}
function makeDir(path: string, root?: string): boolean { function makeDir(path: string, root?: string): boolean {
let dirs = path.split(/\/|\\/g), let dirs = path.split(/\/|\\/g),
dir = dirs.shift(); dir = dirs.shift();
...@@ -95,19 +60,10 @@ export function createFile(filename: string) { ...@@ -95,19 +60,10 @@ export function createFile(filename: string) {
}); });
} }
const __emptyFunc = function () { }; const smallBuffer = SimpleBuffer.fromBuffer(new Buffer(8));
export function close(file: number | undefined) { export async function writeInt(file: FileHandle, value: number, position: number) {
try {
if (file !== void 0) fs.close(file, __emptyFunc);
} catch (e) {
}
}
const smallBuffer = new Buffer(8);
export async function writeInt(file: number, value: number, position: number) {
smallBuffer.writeInt32LE(value, 0); smallBuffer.writeInt32LE(value, 0);
await writeBuffer(file, position, smallBuffer, 4); await file.writeBuffer(position, smallBuffer, 4);
} }
export interface TypedArrayBufferContext { export interface TypedArrayBufferContext {
...@@ -144,7 +100,7 @@ export function createTypedArrayBufferContext(size: number, type: DataFormat.Val ...@@ -144,7 +100,7 @@ export function createTypedArrayBufferContext(size: number, type: DataFormat.Val
}; };
} }
function flipByteOrder(source: Buffer, target: Uint8Array, byteCount: number, elementByteSize: number, offset: number) { function flipByteOrder(source: SimpleBuffer, target: Uint8Array, byteCount: number, elementByteSize: number, offset: number) {
for (let i = 0, n = byteCount; i < n; i += elementByteSize) { for (let i = 0, n = byteCount; i < n; i += elementByteSize) {
for (let j = 0; j < elementByteSize; j++) { for (let j = 0; j < elementByteSize; j++) {
target[offset + i + elementByteSize - j - 1] = source[offset + i + j]; target[offset + i + elementByteSize - j - 1] = source[offset + i + j];
...@@ -152,11 +108,11 @@ function flipByteOrder(source: Buffer, target: Uint8Array, byteCount: number, el ...@@ -152,11 +108,11 @@ function flipByteOrder(source: Buffer, target: Uint8Array, byteCount: number, el
} }
} }
export async function readTypedArray(ctx: TypedArrayBufferContext, file: number, position: number, count: number, valueOffset: number, littleEndian?: boolean) { export async function readTypedArray(ctx: TypedArrayBufferContext, file: FileHandle, position: number, count: number, valueOffset: number, littleEndian?: boolean) {
let byteCount = ctx.elementByteSize * count; let byteCount = ctx.elementByteSize * count;
let byteOffset = ctx.elementByteSize * valueOffset; let byteOffset = ctx.elementByteSize * valueOffset;
await readBuffer(file, position, ctx.readBuffer, byteCount, byteOffset); await file.readBuffer(position, ctx.readBuffer, byteCount, byteOffset);
if (ctx.elementByteSize > 1 && ((littleEndian !== void 0 && littleEndian !== IsNativeEndianLittle) || !IsNativeEndianLittle)) { if (ctx.elementByteSize > 1 && ((littleEndian !== void 0 && littleEndian !== IsNativeEndianLittle) || !IsNativeEndianLittle)) {
// fix the endian // fix the endian
flipByteOrder(ctx.readBuffer, ctx.valuesBuffer, byteCount, ctx.elementByteSize, byteOffset); flipByteOrder(ctx.readBuffer, ctx.valuesBuffer, byteCount, ctx.elementByteSize, byteOffset);
...@@ -164,7 +120,7 @@ export async function readTypedArray(ctx: TypedArrayBufferContext, file: number, ...@@ -164,7 +120,7 @@ export async function readTypedArray(ctx: TypedArrayBufferContext, file: number,
return ctx.values; return ctx.values;
} }
export function ensureLittleEndian(source: Buffer, target: Buffer, byteCount: number, elementByteSize: number, offset: number) { export function ensureLittleEndian(source: SimpleBuffer, target: SimpleBuffer, byteCount: number, elementByteSize: number, offset: number) {
if (IsNativeEndianLittle) return; if (IsNativeEndianLittle) return;
if (!byteCount || elementByteSize <= 1) return; if (!byteCount || elementByteSize <= 1) return;
flipByteOrder(source, target, byteCount, elementByteSize, offset); flipByteOrder(source, target, byteCount, elementByteSize, offset);
......
/** /**
* Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
* *
* Taken/adapted from DensityServer (https://github.com/dsehnal/DensityServer) * Taken/adapted from DensityServer (https://github.com/dsehnal/DensityServer)
* *
* @author David Sehnal <david.sehnal@gmail.com> * @author David Sehnal <david.sehnal@gmail.com>
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/ */
import * as File from '../common/file' import * as File from '../common/file'
import * as DataFormat from '../common/data-format' import * as DataFormat from '../common/data-format'
import { FileHandle } from 'mol-io/common/file-handle';
import { readCcp4Header } from 'mol-io/reader/ccp4/parser';
export const enum Mode { Int8 = 0, Int16 = 1, Float32 = 2 } export const enum Mode { Int8 = 0, Int16 = 1, Float32 = 2 }
...@@ -40,7 +43,7 @@ export interface SliceBuffer { ...@@ -40,7 +43,7 @@ export interface SliceBuffer {
export interface Data { export interface Data {
header: Header, header: Header,
file: number, file: FileHandle,
slices: SliceBuffer slices: SliceBuffer
} }
...@@ -84,47 +87,24 @@ export function compareHeaders(a: Header, b: Header) { ...@@ -84,47 +87,24 @@ export function compareHeaders(a: Header, b: Header) {
return true; return true;
} }
function getArray(r: (offset: number) => number, offset: number, count: number) { async function readHeader(name: string, file: FileHandle) {
const ret: number[] = []; const { header: ccp4Header, littleEndian } = await readCcp4Header(file)
for (let i = 0; i < count; i++) {
ret[i] = r(offset + i);
}
return ret;
}
async function readHeader(name: string, file: number) {
const headerSize = 1024;
const { buffer: data } = await File.readBuffer(file, 0, headerSize);
let littleEndian = true;
let mode = data.readInt32LE(3 * 4);
if (mode < 0 || mode > 2) {
littleEndian = false;
mode = data.readInt32BE(3 * 4, true);
if (mode < 0 || mode > 2) {
throw Error('Only CCP4 modes 0, 1, and 2 are supported.');
}
}
const readInt = littleEndian ? (o: number) => data.readInt32LE(o * 4) : (o: number) => data.readInt32BE(o * 4);
const readFloat = littleEndian ? (o: number) => data.readFloatLE(o * 4) : (o: number) => data.readFloatBE(o * 4);
const origin2k = getArray(readFloat, 49, 3); const origin2k = [ccp4Header.originX, ccp4Header.originY, ccp4Header.originZ];
const nxyzStart = getArray(readInt, 4, 3); const nxyzStart = [ccp4Header.NCSTART, ccp4Header.NRSTART, ccp4Header.NSSTART];
const header: Header = { const header: Header = {
name, name,
mode, mode: ccp4Header.MODE,
grid: getArray(readInt, 7, 3), grid: [ccp4Header.NX, ccp4Header.NY, ccp4Header.NZ],
axisOrder: getArray(readInt, 16, 3).map(i => i - 1), axisOrder: [ccp4Header.MAPC, ccp4Header.MAPR, ccp4Header.MAPS].map(i => i - 1),
extent: getArray(readInt, 0, 3), extent: [ccp4Header.NC, ccp4Header.NR, ccp4Header.NS],
origin: origin2k[0] === 0.0 && origin2k[1] === 0.0 && origin2k[2] === 0.0 ? nxyzStart : origin2k, origin: origin2k[0] === 0.0 && origin2k[1] === 0.0 && origin2k[2] === 0.0 ? nxyzStart : origin2k,
spacegroupNumber: readInt(22), spacegroupNumber: ccp4Header.ISPG,
cellSize: getArray(readFloat, 10, 3), cellSize: [ccp4Header.xLength, ccp4Header.yLength, ccp4Header.zLength],
cellAngles: getArray(readFloat, 13, 3), cellAngles: [ccp4Header.alpha, ccp4Header.beta, ccp4Header.gamma],
// mean: readFloat(21), // mean: readFloat(21),
littleEndian, littleEndian,
dataOffset: headerSize + readInt(23) /* symBytes */ dataOffset: 256 * 4 + ccp4Header.NSYMBT /* symBytes */
}; };
// "normalize" the grid axis order // "normalize" the grid axis order
header.grid = [header.grid[header.axisOrder[0]], header.grid[header.axisOrder[1]], header.grid[header.axisOrder[2]]]; header.grid = [header.grid[header.axisOrder[0]], header.grid[header.axisOrder[1]], header.grid[header.axisOrder[2]]];
...@@ -153,7 +133,8 @@ export async function readSlices(data: Data) { ...@@ -153,7 +133,8 @@ export async function readSlices(data: Data) {
} }
export async function open(name: string, filename: string): Promise<Data> { export async function open(name: string, filename: string): Promise<Data> {
const file = await File.openRead(filename); const descriptor = await File.openRead(filename);
const file = FileHandle.fromDescriptor(descriptor)
const header = await readHeader(name, file); const header = await readHeader(name, file);
return { return {
header, header,
......
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
*/ */
import * as CCP4 from './ccp4' import * as CCP4 from './ccp4'
import * as DataFormat from '../common/data-format' import * as DataFormat from '../common/data-format'
import { FileHandle } from 'mol-io/common/file-handle';
import { SimpleBuffer } from 'mol-io/common/simple-buffer';
const FORMAT_VERSION = '1.0.0'; const FORMAT_VERSION = '1.0.0';
...@@ -24,7 +26,7 @@ export interface ValuesInfo { ...@@ -24,7 +26,7 @@ export interface ValuesInfo {
export interface BlockBuffer { export interface BlockBuffer {
values: DataFormat.ValueArray[], values: DataFormat.ValueArray[],
buffers: Buffer[], buffers: SimpleBuffer[],
slicesWritten: number slicesWritten: number
} }
...@@ -68,7 +70,7 @@ export interface Kernel { ...@@ -68,7 +70,7 @@ export interface Kernel {
export interface Context { export interface Context {
/** Output file handle */ /** Output file handle */
file: number, file: FileHandle,
/** Periodic are x-ray density files that cover the entire grid and have [0,0,0] origin */ /** Periodic are x-ray density files that cover the entire grid and have [0,0,0] origin */
isPeriodic: boolean, isPeriodic: boolean,
...@@ -77,9 +79,9 @@ export interface Context { ...@@ -77,9 +79,9 @@ export interface Context {
valueType: DataFormat.ValueType, valueType: DataFormat.ValueType,
blockSize: number, blockSize: number,
/** Able to store channels.length * blockSize^3 values. */ /** Able to store channels.length * blockSize^3 values. */
cubeBuffer: Buffer, cubeBuffer: SimpleBuffer,
/** All values are stored in little endian format which might not be the native endian of the system */ /** All values are stored in little endian format which might not be the native endian of the system */
litteEndianCubeBuffer: Buffer, litteEndianCubeBuffer: SimpleBuffer,
kernel: Kernel, kernel: Kernel,
sampling: Sampling[], sampling: Sampling[],
......
...@@ -11,7 +11,7 @@ import * as File from '../common/file' ...@@ -11,7 +11,7 @@ import * as File from '../common/file'
import * as Data from './data-model' import * as Data from './data-model'
import * as Sampling from './sampling' import * as Sampling from './sampling'
import * as DataFormat from '../common/data-format' import * as DataFormat from '../common/data-format'
import * as fs from 'fs' import { FileHandle } from 'mol-io/common/file-handle';
export default async function pack(input: { name: string, filename: string }[], blockSize: number, isPeriodic: boolean, outputFilename: string) { export default async function pack(input: { name: string, filename: string }[], blockSize: number, isPeriodic: boolean, outputFilename: string) {
try { try {
...@@ -44,7 +44,7 @@ async function allocateFile(ctx: Data.Context) { ...@@ -44,7 +44,7 @@ async function allocateFile(ctx: Data.Context) {
const progress: Data.Progress = { current: 0, max: Math.ceil(totalByteSize / buffer.byteLength) }; const progress: Data.Progress = { current: 0, max: Math.ceil(totalByteSize / buffer.byteLength) };
let written = 0; let written = 0;
while (written < totalByteSize) { while (written < totalByteSize) {
written += fs.writeSync(file, buffer, 0, Math.min(totalByteSize - written, buffer.byteLength)); written += file.writeBufferSync(written, buffer, Math.min(totalByteSize - written, buffer.byteLength));
updateAllocationProgress(progress, 1); updateAllocationProgress(progress, 1);
} }
} }
...@@ -66,7 +66,7 @@ function determineBlockSize(data: CCP4.Data, blockSize: number) { ...@@ -66,7 +66,7 @@ function determineBlockSize(data: CCP4.Data, blockSize: number) {
async function writeHeader(ctx: Data.Context) { async function writeHeader(ctx: Data.Context) {
const header = DataFormat.encodeHeader(Data.createHeader(ctx)); const header = DataFormat.encodeHeader(Data.createHeader(ctx));
await File.writeInt(ctx.file, header.byteLength, 0); await File.writeInt(ctx.file, header.byteLength, 0);
await File.writeBuffer(ctx.file, 4, header); await ctx.file.writeBuffer(4, header);
} }
async function create(filename: string, sourceDensities: { name: string, filename: string }[], sourceBlockSize: number, isPeriodic: boolean) { async function create(filename: string, sourceDensities: { name: string, filename: string }[], sourceBlockSize: number, isPeriodic: boolean) {
...@@ -81,7 +81,7 @@ async function create(filename: string, sourceDensities: { name: string, filenam ...@@ -81,7 +81,7 @@ async function create(filename: string, sourceDensities: { name: string, filenam
} }
process.stdout.write('Initializing... '); process.stdout.write('Initializing... ');
const files: number[] = []; const files: FileHandle[] = [];
try { try {
// Step 1a: Read the CCP4 headers // Step 1a: Read the CCP4 headers
const channels: CCP4.Data[] = []; const channels: CCP4.Data[] = [];
...@@ -123,7 +123,7 @@ async function create(filename: string, sourceDensities: { name: string, filenam ...@@ -123,7 +123,7 @@ async function create(filename: string, sourceDensities: { name: string, filenam
const time = getTime() - startedTime; const time = getTime() - startedTime;
console.log(`[Done] ${time.toFixed(0)}ms.`); console.log(`[Done] ${time.toFixed(0)}ms.`);
} finally { } finally {
for (let f of files) File.close(f); for (let f of files) f.close();
// const ff = await File.openRead(filename); // const ff = await File.openRead(filename);
// const hh = await DataFormat.readHeader(ff); // const hh = await DataFormat.readHeader(ff);
......
...@@ -12,6 +12,7 @@ import * as File from '../common/file' ...@@ -12,6 +12,7 @@ import * as File from '../common/file'
import * as Downsampling from './downsampling' import * as Downsampling from './downsampling'
import * as Writer from './writer' import * as Writer from './writer'
import * as DataFormat from '../common/data-format' import * as DataFormat from '../common/data-format'
import { FileHandle } from 'mol-io/common/file-handle';
export async function createContext(filename: string, channels: CCP4.Data[], blockSize: number, isPeriodic: boolean): Promise<Data.Context> { export async function createContext(filename: string, channels: CCP4.Data[], blockSize: number, isPeriodic: boolean): Promise<Data.Context> {
const header = channels[0].header; const header = channels[0].header;
...@@ -29,7 +30,7 @@ export async function createContext(filename: string, channels: CCP4.Data[], blo ...@@ -29,7 +30,7 @@ export async function createContext(filename: string, channels: CCP4.Data[], blo
} }
const ctx: Data.Context = { const ctx: Data.Context = {
file: await File.createFile(filename), file: FileHandle.fromDescriptor(await File.createFile(filename)),
isPeriodic, isPeriodic,
channels, channels,
valueType, valueType,
......
...@@ -19,7 +19,7 @@ export async function writeBlockLayer(ctx: Data.Context, sampling: Data.Sampling ...@@ -19,7 +19,7 @@ export async function writeBlockLayer(ctx: Data.Context, sampling: Data.Sampling
for (let v = 0; v < nV; v++) { for (let v = 0; v < nV; v++) {
for (let u = 0; u < nU; u++) { for (let u = 0; u < nU; u++) {
const size = fillCubeBuffer(ctx, sampling, u, v); const size = fillCubeBuffer(ctx, sampling, u, v);
await File.writeBuffer(ctx.file, startOffset + sampling.writeByteOffset, ctx.litteEndianCubeBuffer, size); await ctx.file.writeBuffer(startOffset + sampling.writeByteOffset, ctx.litteEndianCubeBuffer, size);
sampling.writeByteOffset += size; sampling.writeByteOffset += size;
updateProgress(ctx.progress, 1); updateProgress(ctx.progress, 1);
} }
...@@ -46,7 +46,8 @@ function fillCubeBuffer(ctx: Data.Context, sampling: Data.Sampling, u: number, v ...@@ -46,7 +46,8 @@ function fillCubeBuffer(ctx: Data.Context, sampling: Data.Sampling, u: number, v
for (let k = offsetK; k < maxK; k++) { for (let k = offsetK; k < maxK; k++) {
// copying the bytes direct is faster than using buffer.write* functions. // copying the bytes direct is faster than using buffer.write* functions.
const start = (l * sizeHK + k * sizeH + offsetH) * elementSize; const start = (l * sizeHK + k * sizeH + offsetH) * elementSize;
src.copy(cubeBuffer, writeOffset, start, start + copyH); // TODO
cubeBuffer.set(src.subarray(start, start + copyH), writeOffset)
writeOffset += copyH; writeOffset += copyH;
} }
} }
......
...@@ -12,6 +12,7 @@ import * as Data from './query/data-model' ...@@ -12,6 +12,7 @@ import * as Data from './query/data-model'
import { ConsoleLogger } from 'mol-util/console-logger' import { ConsoleLogger } from 'mol-util/console-logger'
import * as DataFormat from '../common/data-format' import * as DataFormat from '../common/data-format'
import ServerConfig from '../server-config' import ServerConfig from '../server-config'
import { FileHandle } from 'mol-io/common/file-handle';
export function getOutputFilename(source: string, id: string, { asBinary, box, detail, forcedSamplingLevel }: Data.QueryParams) { export function getOutputFilename(source: string, id: string, { asBinary, box, detail, forcedSamplingLevel }: Data.QueryParams) {
function n(s: string) { return (s || '').replace(/[ \n\t]/g, '').toLowerCase() } function n(s: string) { return (s || '').replace(/[ \n\t]/g, '').toLowerCase() }
...@@ -57,16 +58,16 @@ export async function queryBox(params: Data.QueryParams, outputProvider: () => D ...@@ -57,16 +58,16 @@ export async function queryBox(params: Data.QueryParams, outputProvider: () => D
} }
async function readHeader(filename: string | undefined, sourceId: string) { async function readHeader(filename: string | undefined, sourceId: string) {
let file: number | undefined = void 0; let file: FileHandle | undefined;
try { try {
if (!filename) return void 0; if (!filename) return void 0;
file = await File.openRead(filename); file = FileHandle.fromDescriptor(await File.openRead(filename));
const header = await DataFormat.readHeader(file); const header = await DataFormat.readHeader(file);
return header.header; return header.header;
} catch (e) { } catch (e) {
ConsoleLogger.error(`Info ${sourceId}`, e); ConsoleLogger.error(`Info ${sourceId}`, e);
return void 0; return void 0;
} finally { } finally {
File.close(file); if (file) file.close();
} }
} }
\ No newline at end of file
...@@ -11,6 +11,7 @@ import * as Coords from '../algebra/coordinate' ...@@ -11,6 +11,7 @@ import * as Coords from '../algebra/coordinate'
import * as Box from '../algebra/box' import * as Box from '../algebra/box'
import Writer from 'mol-io/writer/writer' import Writer from 'mol-io/writer/writer'
import { SpacegroupCell } from 'mol-math/geometry'; import { SpacegroupCell } from 'mol-math/geometry';
import { FileHandle } from 'mol-io/common/file-handle';
////////////////////////////////////// //////////////////////////////////////
// DATA // DATA
...@@ -25,7 +26,7 @@ export interface Sampling { ...@@ -25,7 +26,7 @@ export interface Sampling {
} }
export interface DataContext { export interface DataContext {
file: number, file: FileHandle,
header: DataFormat.Header, header: DataFormat.Header,
spacegroup: SpacegroupCell, spacegroup: SpacegroupCell,
dataBox: Box.Fractional, dataBox: Box.Fractional,
......
...@@ -21,6 +21,7 @@ import encode from './encode' ...@@ -21,6 +21,7 @@ import encode from './encode'
import { SpacegroupCell } from 'mol-math/geometry'; import { SpacegroupCell } from 'mol-math/geometry';
import { Vec3 } from 'mol-math/linear-algebra'; import { Vec3 } from 'mol-math/linear-algebra';
import { UUID } from 'mol-util'; import { UUID } from 'mol-util';
import { FileHandle } from 'mol-io/common/file-handle';
export default async function execute(params: Data.QueryParams, outputProvider: () => Data.QueryOutputStream) { export default async function execute(params: Data.QueryParams, outputProvider: () => Data.QueryOutputStream) {
const start = getTime(); const start = getTime();
...@@ -30,16 +31,16 @@ export default async function execute(params: Data.QueryParams, outputProvider: ...@@ -30,16 +31,16 @@ export default async function execute(params: Data.QueryParams, outputProvider:
params.detail = Math.min(Math.max(0, params.detail | 0), ServerConfig.limits.maxOutputSizeInVoxelCountByPrecisionLevel.length - 1); params.detail = Math.min(Math.max(0, params.detail | 0), ServerConfig.limits.maxOutputSizeInVoxelCountByPrecisionLevel.length - 1);
ConsoleLogger.logId(guid, 'Info', `id=${params.sourceId},encoding=${params.asBinary ? 'binary' : 'text'},detail=${params.detail},${queryBoxToString(params.box)}`); ConsoleLogger.logId(guid, 'Info', `id=${params.sourceId},encoding=${params.asBinary ? 'binary' : 'text'},detail=${params.detail},${queryBoxToString(params.box)}`);
let sourceFile: number | undefined = void 0; let sourceFile: FileHandle | undefined;
try { try {
sourceFile = await File.openRead(params.sourceFilename); sourceFile = FileHandle.fromDescriptor(await File.openRead(params.sourceFilename));
await _execute(sourceFile, params, guid, outputProvider); await _execute(sourceFile, params, guid, outputProvider);
return true; return true;
} catch (e) { } catch (e) {
ConsoleLogger.errorId(guid, e); ConsoleLogger.errorId(guid, e);
return false; return false;
} finally { } finally {
File.close(sourceFile); if (sourceFile) sourceFile.close();
ConsoleLogger.logId(guid, 'Time', `${Math.round(getTime() - start)}ms`); ConsoleLogger.logId(guid, 'Time', `${Math.round(getTime() - start)}ms`);
State.pendingQueries--; State.pendingQueries--;
} }
...@@ -80,7 +81,7 @@ function createSampling(header: DataFormat.Header, index: number, dataOffset: nu ...@@ -80,7 +81,7 @@ function createSampling(header: DataFormat.Header, index: number, dataOffset: nu
} }
} }
async function createDataContext(file: number): Promise<Data.DataContext> { async function createDataContext(file: FileHandle): Promise<Data.DataContext> {
const { header, dataOffset } = await DataFormat.readHeader(file); const { header, dataOffset } = await DataFormat.readHeader(file);
const origin = Coords.fractional(header.origin[0], header.origin[1], header.origin[2]); const origin = Coords.fractional(header.origin[0], header.origin[1], header.origin[2]);
...@@ -185,7 +186,7 @@ function createQueryContext(data: Data.DataContext, params: Data.QueryParams, gu ...@@ -185,7 +186,7 @@ function createQueryContext(data: Data.DataContext, params: Data.QueryParams, gu
} }
async function _execute(file: number, params: Data.QueryParams, guid: string, outputProvider: () => Data.QueryOutputStream) { async function _execute(file: FileHandle, params: Data.QueryParams, guid: string, outputProvider: () => Data.QueryOutputStream) {
let output: any = void 0; let output: any = void 0;
try { try {
// Step 1a: Create data context // Step 1a: Create data context
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment