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

ccp4 parser fixes

parent 15ea1669
No related branches found
No related tags found
No related merge requests found
...@@ -8,7 +8,6 @@ import { Task, RuntimeContext } from 'mol-task'; ...@@ -8,7 +8,6 @@ import { Task, RuntimeContext } from 'mol-task';
import * as Schema from './schema' import * as Schema from './schema'
import Result from '../result' import Result from '../result'
import { FileHandle } from '../../common/file-handle'; import { FileHandle } from '../../common/file-handle';
import { flipByteOrder } from '../../common/binary';
async function parseInternal(file: FileHandle, ctx: RuntimeContext): Promise<Result<Schema.Ccp4File>> { async function parseInternal(file: FileHandle, ctx: RuntimeContext): Promise<Result<Schema.Ccp4File>> {
await ctx.update({ message: 'Parsing CCP4 file...' }); await ctx.update({ message: 'Parsing CCP4 file...' });
...@@ -32,9 +31,12 @@ async function parseInternal(file: FileHandle, ctx: RuntimeContext): Promise<Res ...@@ -32,9 +31,12 @@ async function parseInternal(file: FileHandle, ctx: RuntimeContext): Promise<Res
// 54 MACHST Machine stamp indicating machine type which wrote file // 54 MACHST Machine stamp indicating machine type which wrote file
// 17 and 17 for big-endian or 68 and 65 for little-endian // 17 and 17 for big-endian or 68 and 65 for little-endian
const MACHST = [ dv.getUint8(53 * 4), dv.getUint8(53 * 4 + 1) ] const MACHST = [ dv.getUint8(53 * 4), dv.getUint8(53 * 4 + 1) ]
// found MRC files that don't have the MACHST stamp set and are big-endian
if (MACHST[ 0 ] === 17 && MACHST[ 1 ] === 17) { if (MACHST[0] !== 68 && MACHST[1] !== 65) {
flipByteOrder(buffer, buffer.length) // flip byte order in-place
for (let i = 0, il = bin.byteLength; i < il; i += 4) {
dv.setFloat32(i, dv.getFloat32(i), true)
}
} }
const header: Schema.Ccp4Header = { const header: Schema.Ccp4Header = {
...@@ -91,17 +93,13 @@ async function parseInternal(file: FileHandle, ctx: RuntimeContext): Promise<Res ...@@ -91,17 +93,13 @@ async function parseInternal(file: FileHandle, ctx: RuntimeContext): Promise<Res
// TODO bytes 57-256 LABEL // TODO bytes 57-256 LABEL
} }
const offset = 256 * 4 + header.NSYMBT
const count = header.NC * header.NR * header.NS
let values let values
if (header.MODE === 2) { if (header.MODE === 2) {
values = new Float32Array( values = new Float32Array(bin, offset, count)
bin, 256 * 4 + header.NSYMBT,
header.NX * header.NY * header.NZ
)
} else if (header.MODE === 0) { } else if (header.MODE === 0) {
values = new Float32Array(new Int8Array( values = new Int8Array(bin, offset, count)
bin, 256 * 4 + header.NSYMBT,
header.NX * header.NY * header.NZ
))
} else { } else {
return Result.error(`ccp4 mode '${header.MODE}' unsupported`); return Result.error(`ccp4 mode '${header.MODE}' unsupported`);
} }
......
...@@ -6,11 +6,11 @@ ...@@ -6,11 +6,11 @@
*/ */
export interface Ccp4Header { export interface Ccp4Header {
/** columns (fastest changing) */ /** number of columns (fastest changing) */
NC: number NC: number
/** rows */ /** number of rows */
NR: number NR: number
/** sections (slowest changing) */ /** number of sections (slowest changing) */
NS: number NS: number
/** /**
* 0 image : signed 8-bit bytes range -128 to 127 * 0 image : signed 8-bit bytes range -128 to 127
...@@ -49,11 +49,11 @@ export interface Ccp4Header { ...@@ -49,11 +49,11 @@ export interface Ccp4Header {
beta: number beta: number
/** gamma cell angle (Degrees) */ /** gamma cell angle (Degrees) */
gamma: number gamma: number
/** axis corresponds for columns (1,2,3 for X,Y,Z) */ /** axis corresponds to columns (1,2,3 for X,Y,Z) */
MAPC: number MAPC: number
/** axis corresponds for rows (1,2,3 for X,Y,Z) */ /** axis corresponds to rows (1,2,3 for X,Y,Z) */
MAPR: number MAPR: number
/** axis corresponds for sections (1,2,3 for X,Y,Z) */ /** axis corresponds to sections (1,2,3 for X,Y,Z) */
MAPS: number MAPS: number
/** minimum density value */ /** minimum density value */
AMIN: number AMIN: number
...@@ -67,8 +67,8 @@ export interface Ccp4Header { ...@@ -67,8 +67,8 @@ export interface Ccp4Header {
NSYMBT: number NSYMBT: number
/** flag for skew transformation, =0 none, =1 if foll */ /** flag for skew transformation, =0 none, =1 if foll */
LSKFLG: number LSKFLG: number
/** Skew matrix S (in order S11, S12, S13, S21 etc) if LSKFLG .ne. 0 /**
* * Skew matrix S (in order S11, S12, S13, S21 etc) if LSKFLG .ne. 0
* May be used in CCP4 but not in MRC * May be used in CCP4 but not in MRC
*/ */
SKWMAT: number[] SKWMAT: number[]
......
...@@ -7,8 +7,8 @@ ...@@ -7,8 +7,8 @@
import { SpacegroupCell, Box3D } from 'mol-math/geometry' import { SpacegroupCell, Box3D } from 'mol-math/geometry'
import { Tensor, Mat4, Vec3 } from 'mol-math/linear-algebra' import { Tensor, Mat4, Vec3 } from 'mol-math/linear-algebra'
/** The basic unit cell that contains the data. */
interface VolumeData { interface VolumeData {
// The basic unit cell that contains the data.
readonly cell: SpacegroupCell, readonly cell: SpacegroupCell,
readonly fractionalBox: Box3D, readonly fractionalBox: Box3D,
readonly data: Tensor, readonly data: Tensor,
......
...@@ -13,14 +13,17 @@ import { Tensor, Vec3 } from 'mol-math/linear-algebra'; ...@@ -13,14 +13,17 @@ import { Tensor, Vec3 } from 'mol-math/linear-algebra';
function parseDensityServerData(source: DensityServer_Data_Database): Task<VolumeData> { function parseDensityServerData(source: DensityServer_Data_Database): Task<VolumeData> {
return Task.create<VolumeData>('Parse Volume Data', async ctx => { return Task.create<VolumeData>('Parse Volume Data', async ctx => {
const { volume_data_3d_info: info, volume_data_3d: values } = source; const { volume_data_3d_info: info, volume_data_3d: values } = source;
const cell = SpacegroupCell.create(info.spacegroup_number.value(0), const cell = SpacegroupCell.create(
info.spacegroup_number.value(0),
Vec3.ofArray(info.spacegroup_cell_size.value(0)), Vec3.ofArray(info.spacegroup_cell_size.value(0)),
Vec3.scale(Vec3.zero(), Vec3.ofArray(info.spacegroup_cell_angles.value(0)), Math.PI / 180)); Vec3.scale(Vec3.zero(), Vec3.ofArray(info.spacegroup_cell_angles.value(0)), Math.PI / 180)
);
const tensorSpace = Tensor.Space(info.sample_count.value(0), info.axis_order.value(0), Float32Array); const tensorSpace = Tensor.Space(info.sample_count.value(0), info.axis_order.value(0), Float32Array);
const data = Tensor.create(tensorSpace, Tensor.Data1(values.values.toArray())); const data = Tensor.create(tensorSpace, Tensor.Data1(values.values.toArray()));
const origin = Vec3.ofArray(info.origin.value(0)), dimensions = Vec3.ofArray(info.dimensions.value(0)); const origin = Vec3.ofArray(info.origin.value(0))
const dimensions = Vec3.ofArray(info.dimensions.value(0));
return { return {
cell, cell,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment