|
@@ -1,7 +1,5 @@
|
|
|
/**
|
|
|
- * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
|
|
- *
|
|
|
- * Taken/adapted from DensityServer (https://github.com/dsehnal/DensityServer)
|
|
|
+ * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
|
|
*
|
|
|
* @author David Sehnal <david.sehnal@gmail.com>
|
|
|
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
|
@@ -10,7 +8,7 @@
|
|
|
import * as File from '../common/file'
|
|
|
import * as DataFormat from '../common/data-format'
|
|
|
import { FileHandle } from 'mol-io/common/file-handle';
|
|
|
-import { readCcp4Header } from 'mol-io/reader/ccp4/parser';
|
|
|
+import { Ccp4Provider } from './format/ccp4';
|
|
|
|
|
|
export const enum Mode { Int8 = 0, Int16 = 1, Float32 = 2 }
|
|
|
|
|
@@ -47,6 +45,16 @@ export interface Data {
|
|
|
slices: SliceBuffer
|
|
|
}
|
|
|
|
|
|
+export interface Provider {
|
|
|
+ readHeader: (name: string, file: FileHandle) => Promise<Header>,
|
|
|
+ readSlices: (data: Data) => Promise<void>
|
|
|
+}
|
|
|
+
|
|
|
+export interface Context {
|
|
|
+ data: Data,
|
|
|
+ provider: Provider
|
|
|
+}
|
|
|
+
|
|
|
export function getValueType(header: Header) {
|
|
|
if (header.mode === Mode.Float32) return DataFormat.ValueType.Float32;
|
|
|
if (header.mode === Mode.Int16) return DataFormat.ValueType.Int16;
|
|
@@ -87,58 +95,20 @@ export function compareHeaders(a: Header, b: Header) {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-async function readHeader(name: string, file: FileHandle) {
|
|
|
- const { header: ccp4Header, littleEndian } = await readCcp4Header(file)
|
|
|
-
|
|
|
- const origin2k = [ccp4Header.originX, ccp4Header.originY, ccp4Header.originZ];
|
|
|
- const nxyzStart = [ccp4Header.NCSTART, ccp4Header.NRSTART, ccp4Header.NSSTART];
|
|
|
- const header: Header = {
|
|
|
- name,
|
|
|
- mode: ccp4Header.MODE,
|
|
|
- grid: [ccp4Header.NX, ccp4Header.NY, ccp4Header.NZ],
|
|
|
- axisOrder: [ccp4Header.MAPC, ccp4Header.MAPR, ccp4Header.MAPS].map(i => i - 1),
|
|
|
- extent: [ccp4Header.NC, ccp4Header.NR, ccp4Header.NS],
|
|
|
- origin: origin2k[0] === 0.0 && origin2k[1] === 0.0 && origin2k[2] === 0.0 ? nxyzStart : origin2k,
|
|
|
- spacegroupNumber: ccp4Header.ISPG,
|
|
|
- cellSize: [ccp4Header.xLength, ccp4Header.yLength, ccp4Header.zLength],
|
|
|
- cellAngles: [ccp4Header.alpha, ccp4Header.beta, ccp4Header.gamma],
|
|
|
- // mean: readFloat(21),
|
|
|
- littleEndian,
|
|
|
- dataOffset: 256 * 4 + ccp4Header.NSYMBT /* symBytes */
|
|
|
- };
|
|
|
- // "normalize" the grid axis order
|
|
|
- header.grid = [header.grid[header.axisOrder[0]], header.grid[header.axisOrder[1]], header.grid[header.axisOrder[2]]];
|
|
|
- return header;
|
|
|
-}
|
|
|
-
|
|
|
-export async function readSlices(data: Data) {
|
|
|
- const { slices, header } = data;
|
|
|
- if (slices.isFinished) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- const { extent } = header;
|
|
|
- const sliceSize = extent[0] * extent[1];
|
|
|
- const sliceByteOffset = slices.buffer.elementByteSize * sliceSize * slices.slicesRead;
|
|
|
- const sliceCount = Math.min(slices.sliceCapacity, extent[2] - slices.slicesRead);
|
|
|
- const sliceByteCount = sliceCount * sliceSize;
|
|
|
-
|
|
|
- await File.readTypedArray(slices.buffer, data.file, header.dataOffset + sliceByteOffset, sliceByteCount, 0, header.littleEndian);
|
|
|
- slices.slicesRead += sliceCount;
|
|
|
- slices.sliceCount = sliceCount;
|
|
|
+export type Type = 'ccp4' // | 'dsn6'
|
|
|
|
|
|
- if (slices.slicesRead >= extent[2]) {
|
|
|
- slices.isFinished = true;
|
|
|
+export function getProviderFromType(type: Type): Provider {
|
|
|
+ switch (type) {
|
|
|
+ case 'ccp4': return Ccp4Provider
|
|
|
+ // case 'dsn6': return Dsn6Provider
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-export async function open(name: string, filename: string): Promise<Data> {
|
|
|
+export async function open(name: string, filename: string, type: Type = 'ccp4'): Promise<Context> {
|
|
|
+ const provider = getProviderFromType(type)
|
|
|
const descriptor = await File.openRead(filename);
|
|
|
const file = FileHandle.fromDescriptor(descriptor)
|
|
|
- const header = await readHeader(name, file);
|
|
|
- return {
|
|
|
- header,
|
|
|
- file,
|
|
|
- slices: void 0 as any
|
|
|
- };
|
|
|
+ const header = await provider.readHeader(name, file);
|
|
|
+ const data = { header, file, slices: void 0 as any }
|
|
|
+ return { data, provider };
|
|
|
}
|