123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- /**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * Taken/adapted from DensityServer (https://github.com/dsehnal/DensityServer)
- *
- * @author David Sehnal <david.sehnal@gmail.com>
- */
- import * as Schema from './binary-schema'
- import { FileHandle } from 'mol-io/common/file-handle';
- import { TypedArrayValueType } from 'mol-io/common/typed-array';
- export interface Spacegroup {
- number: number,
- size: number[],
- angles: number[],
- /** Determine if the data should be treated as periodic or not. (e.g. X-ray = periodic, EM = not periodic) */
- isPeriodic: boolean,
- }
- export interface ValuesInfo {
- mean: number,
- sigma: number,
- min: number,
- max: number
- }
- export interface Sampling {
- byteOffset: number,
- /** How many values along each axis were collapsed into 1 */
- rate: number,
- valuesInfo: ValuesInfo[],
- /** Number of samples along each axis, in axisOrder */
- sampleCount: number[]
- }
- export interface Header {
- /** Format version number */
- formatVersion: string,
- /** Axis order from the slowest to fastest moving, same as in CCP4 */
- axisOrder: number[],
- /** Origin in fractional coordinates, in axisOrder */
- origin: number[],
- /** Dimensions in fractional coordinates, in axisOrder */
- dimensions: number[],
- spacegroup: Spacegroup,
- channels: string[],
- /** Determines the data type of the values */
- valueType: TypedArrayValueType,
- /** The value are stored in blockSize^3 cubes */
- blockSize: number,
- sampling: Sampling[]
- }
- namespace _schema {
- const { array, obj, int, bool, float, str } = Schema
- export const schema = obj<Header>([
- ['formatVersion', str],
- ['axisOrder', array(int)],
- ['origin', array(float)],
- ['dimensions', array(float)],
- ['spacegroup', obj<Spacegroup>([
- ['number', int],
- ['size', array(float)],
- ['angles', array(float)],
- ['isPeriodic', bool],
- ])],
- ['channels', array(str)],
- ['valueType', str],
- ['blockSize', int],
- ['sampling', array(obj<Sampling>([
- ['byteOffset', float],
- ['rate', int],
- ['valuesInfo', array(obj<ValuesInfo>([
- ['mean', float],
- ['sigma', float],
- ['min', float],
- ['max', float]
- ]))],
- ['sampleCount', array(int)]
- ]))]
- ]);
- }
- const headerSchema = _schema.schema;
- export function encodeHeader(header: Header) {
- return Schema.encode(headerSchema, header);
- }
- export async function readHeader(file: FileHandle): Promise<{ header: Header, dataOffset: number }> {
- let { buffer } = await file.readBuffer(0, 4 * 4096);
- const headerSize = buffer.readInt32LE(0);
- if (headerSize > buffer.byteLength - 4) {
- buffer = (await file.readBuffer(0, headerSize + 4)).buffer;
- }
- const header = Schema.decode<Header>(headerSchema, buffer, 4);
- return { header, dataOffset: headerSize + 4 };
- }
|