Kaynağa Gözat

Fixed parsing density server data

David Sehnal 6 yıl önce
ebeveyn
işleme
1a04125463

+ 21 - 0
src/mol-math/linear-algebra/tensor.ts

@@ -202,4 +202,25 @@ export namespace Tensor {
         }
         return o;
     }
+
+    // Convers "slow to fast" axis order to "fast to slow" and vice versa.
+    export function invertAxisOrder(v: number[]) {
+        const ret: number[] = [];
+        for (let i = 0; i < v.length; i++) {
+            ret[i] = v[v.length - i - 1];
+        }
+        return ret;
+    }
+
+    export function getCanonicalAxisIndicesFastToSlow(order: number[]) {
+        const indices = new Int32Array(order.length) as any as number[];
+        for (let i = 0; i < order.length; i++) indices[order[i]] = i;
+        return indices;
+    }
+
+    export function getCanonicalAxisIndicesSlowToFast(order: number[]) {
+        const indices = new Int32Array(order.length) as any as number[];
+        for (let i = 0; i < order.length; i++) indices[order[order.length - i - 1]] = i;
+        return indices;
+    }
 }

+ 16 - 4
src/mol-model/volume/formats/density-server.ts

@@ -10,6 +10,10 @@ import { Task } from 'mol-task';
 import { SpacegroupCell, Box3D } from 'mol-math/geometry';
 import { Tensor, Vec3 } from 'mol-math/linear-algebra';
 
+function normalizeOrder(v: number[], indices: number[]) {
+    return Vec3.create(v[indices[0]], v[indices[1]], v[indices[2]])
+}
+
 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;
@@ -19,11 +23,19 @@ function parseDensityServerData(source: DensityServer_Data_Database): Task<Volum
             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 axis_order_fast_to_slow = info.axis_order.value(0);
+
+        const indices = Tensor.getCanonicalAxisIndicesFastToSlow(axis_order_fast_to_slow);
+
+        // sample count is in "axis order" and needs to be reordered
+        const sample_count = normalizeOrder(info.sample_count.value(0), indices);
+        const tensorSpace = Tensor.Space(sample_count, Tensor.invertAxisOrder(axis_order_fast_to_slow), Float32Array);
+
+        const data = Tensor.create(tensorSpace, Tensor.Data1(values.values.toArray({ array: Float32Array })));
 
-        const origin = Vec3.ofArray(info.origin.value(0))
-        const dimensions = Vec3.ofArray(info.dimensions.value(0));
+        // origin and dimensions are in "axis order" and need to be reordered
+        const origin = normalizeOrder(info.origin.value(0), indices)
+        const dimensions = normalizeOrder(info.dimensions.value(0), indices);
 
         return {
             cell,