Bladeren bron

ccp4 parser fixes

Alexander Rose 6 jaren geleden
bovenliggende
commit
7089e0fd31

+ 10 - 12
src/mol-io/reader/ccp4/parser.ts

@@ -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`);
     }

+ 8 - 8
src/mol-io/reader/ccp4/schema.ts

@@ -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[]

+ 1 - 1
src/mol-model/volume/data.ts

@@ -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,

+ 6 - 3
src/mol-model/volume/formats/density-server.ts

@@ -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,