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';
import * as Schema from './schema'
import Result from '../result'
import { FileHandle } from '../../common/file-handle';
import { flipByteOrder } from '../../common/binary';
async function parseInternal(file: FileHandle, ctx: RuntimeContext): Promise<Result<Schema.Ccp4File>> {
await ctx.update({ message: 'Parsing CCP4 file...' });
......@@ -32,9 +31,12 @@ async function parseInternal(file: FileHandle, ctx: RuntimeContext): Promise<Res
// 54 MACHST Machine stamp indicating machine type which wrote file
// 17 and 17 for big-endian or 68 and 65 for little-endian
const MACHST = [ dv.getUint8(53 * 4), dv.getUint8(53 * 4 + 1) ]
if (MACHST[ 0 ] === 17 && MACHST[ 1 ] === 17) {
flipByteOrder(buffer, buffer.length)
// found MRC files that don't have the MACHST stamp set and are big-endian
if (MACHST[0] !== 68 && MACHST[1] !== 65) {
// 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 = {
......@@ -91,17 +93,13 @@ async function parseInternal(file: FileHandle, ctx: RuntimeContext): Promise<Res
// TODO bytes 57-256 LABEL
}
const offset = 256 * 4 + header.NSYMBT
const count = header.NC * header.NR * header.NS
let values
if (header.MODE === 2) {
values = new Float32Array(
bin, 256 * 4 + header.NSYMBT,
header.NX * header.NY * header.NZ
)
values = new Float32Array(bin, offset, count)
} else if (header.MODE === 0) {
values = new Float32Array(new Int8Array(
bin, 256 * 4 + header.NSYMBT,
header.NX * header.NY * header.NZ
))
values = new Int8Array(bin, offset, count)
} else {
return Result.error(`ccp4 mode '${header.MODE}' unsupported`);
}
......
......@@ -6,11 +6,11 @@
*/
export interface Ccp4Header {
/** columns (fastest changing) */
/** number of columns (fastest changing) */
NC: number
/** rows */
/** number of rows */
NR: number
/** sections (slowest changing) */
/** number of sections (slowest changing) */
NS: number
/**
* 0 image : signed 8-bit bytes range -128 to 127
......@@ -49,11 +49,11 @@ export interface Ccp4Header {
beta: number
/** gamma cell angle (Degrees) */
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
/** axis corresponds for rows (1,2,3 for X,Y,Z) */
/** axis corresponds to rows (1,2,3 for X,Y,Z) */
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
/** minimum density value */
AMIN: number
......@@ -67,8 +67,8 @@ export interface Ccp4Header {
NSYMBT: number
/** flag for skew transformation, =0 none, =1 if foll */
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
*/
SKWMAT: number[]
......
......@@ -7,8 +7,8 @@
import { SpacegroupCell, Box3D } from 'mol-math/geometry'
import { Tensor, Mat4, Vec3 } from 'mol-math/linear-algebra'
/** The basic unit cell that contains the data. */
interface VolumeData {
// The basic unit cell that contains the data.
readonly cell: SpacegroupCell,
readonly fractionalBox: Box3D,
readonly data: Tensor,
......
......@@ -13,14 +13,17 @@ import { Tensor, Vec3 } from 'mol-math/linear-algebra';
function parseDensityServerData(source: DensityServer_Data_Database): Task<VolumeData> {
return Task.create<VolumeData>('Parse Volume Data', async ctx => {
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.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 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 {
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