Browse Source

fix cellpack results file asset handling

Alexander Rose 3 years ago
parent
commit
b0f447adde
2 changed files with 109 additions and 111 deletions
  1. 38 37
      src/extensions/cellpack/model.ts
  2. 71 74
      src/extensions/cellpack/state.ts

+ 38 - 37
src/extensions/cellpack/model.ts

@@ -535,55 +535,48 @@ async function loadPackings(plugin: PluginContext, runtime: RuntimeContext, stat
     const ingredientFiles = params.ingredients || [];
 
     let cellPackJson: StateBuilder.To<PSO.Format.Json, StateTransformer<PSO.Data.String, PSO.Format.Json>>;
-    let modelFile: Asset.File|null = params.results;
+    let resultsFile: Asset.File | null = params.results;
     if (params.source.name === 'id') {
         const url = Asset.getUrlAsset(plugin.managers.asset, getCellPackModelUrl(params.source.params, params.baseUrl));
         cellPackJson = state.build().toRoot()
             .apply(StateTransforms.Data.Download, { url, isBinary: false, label: params.source.params }, { state: { isGhost: true } });
     } else {
         const file = params.source.params;
-        const rfile = params.results;
         if (!file?.file) {
             plugin.log.error('No file selected');
             return;
         }
 
-        let jsonFile: Asset.File;
+        let modelFile: Asset.File;
         if (file.name.toLowerCase().endsWith('.zip')) {
             const data = await readFromFile(file.file, 'zip').runInContext(runtime);
-            jsonFile = Asset.File(new File([data['model.json']], 'model.json'));
-            modelFile = Asset.File(new File([data['model.bin']], 'model.bin'));
+            if (data['model.json']) {
+                modelFile = Asset.File(new File([data['model.json']], 'model.json'));
+            } else {
+                throw new Error('model.json missing from zip file');
+            }
+            if (data['results.bin']) {
+                resultsFile = Asset.File(new File([data['results.bin']], 'results.bin'));
+            }
             objectForEach(data, (v, k) => {
                 if (k === 'model.json') return;
-                else if (k === 'model.bin') return;
+                if (k === 'results.bin') return;
                 ingredientFiles.push(Asset.File(new File([v], k)));
             });
         } else {
-            jsonFile = file;
-            modelFile = rfile;
+            modelFile = file;
         }
         cellPackJson = state.build().toRoot()
-            .apply(StateTransforms.Data.ReadFile, { file: jsonFile, isBinary: false, label: jsonFile.name }, { state: { isGhost: true } });
+            .apply(StateTransforms.Data.ReadFile, { file: modelFile, isBinary: false, label: modelFile.name }, { state: { isGhost: true } });
     }
 
     const cellPackBuilder = cellPackJson
         .apply(StateTransforms.Data.ParseJson, undefined, { state: { isGhost: true } })
-        .apply(ParseCellPack, {modelFile:modelFile, baseUrl:params.baseUrl});
+        .apply(ParseCellPack, { resultsFile, baseUrl: params.baseUrl });
 
     const cellPackObject = await state.updateTree(cellPackBuilder).runInContext(runtime);
 
-    let { packings } = cellPackObject.obj!.data;
-    /* const { options } = cell;
-    if (!modelFile && options) {
-        if (options.resultfile) {
-            const asset = await plugin.runTask(plugin.managers.asset.resolve(Asset.getUrlAsset(plugin.managers.asset, `${params.baseUrl}/results/${options.resultfile}`), 'binary', true));
-            modelFile = Asset.File(new File([asset.data], 'model.bin'));
-        }
-    }
-    if (modelFile) {
-        packings = await loadPackingResultsBinary(plugin, runtime, modelFile, cellPackObject.obj!.data);
-    }
-     */
+    const { packings } = cellPackObject.obj!.data;
     await handleHivRna(plugin, packings, params.baseUrl);
 
     for (let i = 0, il = packings.length; i < il; ++i) {
@@ -599,7 +592,7 @@ async function loadPackings(plugin: PluginContext, runtime: RuntimeContext, stat
             representation: params.preset.representation,
         };
         await CellpackPackingPreset.apply(packing, packingParams, plugin);
-        if ( packings[i].location === 'surface') {
+        if (packings[i].location === 'surface') {
             console.log('ok surface ' + params.membrane);
             if (params.membrane === 'lipids'){
                 console.log('ok packings[i].geom_type ' + packings[i].geom_type);
@@ -607,15 +600,19 @@ async function loadPackings(plugin: PluginContext, runtime: RuntimeContext, stat
                     if (packings[i].geom_type === 'file') {
                         await loadMembrane(plugin, packings[i].geom!, state, params);
                     } else if (packings[i].mb) {
-                        let nSpheres =  packings[i].mb!.positions!.length / 3;
+                        const nSpheres = packings[i].mb!.positions!.length / 3;
                         console.log('ok mb ', nSpheres);
-                        for (let j = 0;j < nSpheres;j++) {
+                        for (let j = 0; j < nSpheres; j++) {
                             await state.build()
                                 .toRoot()
-                                .apply(CreateSphere, {center:Vec3.create(packings[i].mb!.positions![j * 3 + 0],
-                                    packings[i].mb!.positions![j * 3 + 1],
-                                    packings[i].mb!.positions![j * 3 + 2]),
-                                radius:packings[i].mb!.radii![j] })
+                                .apply(CreateSphere, {
+                                    center: Vec3.create(
+                                        packings[i].mb!.positions![j * 3 + 0],
+                                        packings[i].mb!.positions![j * 3 + 1],
+                                        packings[i].mb!.positions![j * 3 + 2]
+                                    ),
+                                    radius:packings[i].mb!.radii![j]
+                                })
                                 .commit();
                         }
                     }
@@ -627,15 +624,19 @@ async function loadPackings(plugin: PluginContext, runtime: RuntimeContext, stat
                 }
             } else if (params.membrane === 'spheres'){
                 if (packings[i].mb) {
-                    let nSpheres =  packings[i].mb!.positions!.length / 3;
+                    const nSpheres = packings[i].mb!.positions!.length / 3;
                     console.log('ok mb ', nSpheres);
-                    for (let j = 0;j < nSpheres;j++) {
+                    for (let j = 0; j < nSpheres; j++) {
                         await state.build()
                             .toRoot()
-                            .apply(CreateSphere, {center:Vec3.create(packings[i].mb!.positions![j * 3 + 0],
-                                packings[i].mb!.positions![j * 3 + 1],
-                                packings[i].mb!.positions![j * 3 + 2]),
-                            radius:packings[i].mb!.radii![j] })
+                            .apply(CreateSphere, {
+                                center: Vec3.create(
+                                    packings[i].mb!.positions![j * 3 + 0],
+                                    packings[i].mb!.positions![j * 3 + 1],
+                                    packings[i].mb!.positions![j * 3 + 2]
+                                ),
+                                radius:packings[i].mb!.radii![j]
+                            })
                             .commit();
                     }
                 }
@@ -659,9 +660,9 @@ const LoadCellPackModelParams = {
         'file': PD.File({ accept: '.json,.cpr,.zip', description: 'Open model definition from .json/.cpr file or open .zip file containing model definition plus ingredients.', label: 'Recipe file' }),
     }, { options: [['id', 'Id'], ['file', 'File']] }),
     baseUrl: PD.Text(DefaultCellPackBaseUrl),
-    results : PD.File({ accept: '.bin,.json', description: 'open results file in binary format from cellpackgpu for the specified recipe', label: 'Results file'}),
+    results : PD.File({ accept: '.bin', description: 'open results file in binary format from cellpackgpu for the specified recipe', label: 'Results file'}),
     membrane: PD.Select('lipids', PD.arrayToOptions(['lipids', 'spheres', 'none'])),
-    ingredients: PD.FileList({ accept: '.cif,.bcif,.pdb', label: 'Ingredients' }),
+    ingredients: PD.FileList({ accept: '.cif,.bcif,.pdb', label: 'Ingredient files' }),
     preset: PD.Group({
         traceOnly: PD.Boolean(false),
         representation: PD.Select('gaussian-surface', PD.arrayToOptions(['spacefill', 'gaussian-surface', 'point', 'orientation']))

+ 71 - 74
src/extensions/cellpack/state.ts

@@ -19,7 +19,6 @@ import { ModelSymmetry } from '../../mol-model-formats/structure/property/symmet
 import { Vec3, Quat } from '../../mol-math/linear-algebra';
 import { StateTransformer } from '../../mol-state';
 import { MBRepresentation, MBParams } from './representation';
-import { readFromFile } from '../../mol-util/data-source';
 import { IsNativeEndianLittle, flipByteOrder } from '../../mol-io/common/binary';;
 import { getFloatValue } from './util';
 
@@ -35,7 +34,7 @@ const ParseCellPack = PluginStateTransform.BuiltIn({
     to: CellPack,
     params: a => {
         return {
-            modelFile: PD.File({accept: '.bin'}),
+            resultsFile: PD.File({ accept: '.bin' }),
             baseUrl: PD.Text(DefaultCellPackBaseUrl)
         };
     }
@@ -47,9 +46,9 @@ const ParseCellPack = PluginStateTransform.BuiltIn({
             let fiber_counter_id = 0;
             let comp_counter = 0;
             const packings: CellPacking[] = [];
-            const {compartments, cytoplasme } = cell;
+            const { compartments, cytoplasme } = cell;
             let iName = '';
-            if(!cell.mapping_ids)cell.mapping_ids = {};
+            if(!cell.mapping_ids) cell.mapping_ids = {};
             if (cytoplasme) {
                 packings.push({ name: 'Cytoplasme', location: 'cytoplasme', ingredients: cytoplasme.ingredients });
                 for (iName in cytoplasme.ingredients){
@@ -101,88 +100,87 @@ const ParseCellPack = PluginStateTransform.BuiltIn({
                 }
             }
             const { options } = cell;
-            if (!params.modelFile && options) {
-                if (options.resultfile) {
-                    const asset = await plugin.runTask(plugin.managers.asset.resolve(Asset.getUrlAsset(plugin.managers.asset, `${params.baseUrl}/results/${options.resultfile}`), 'binary', true));
-                    (cache as any).asset = asset;
-                    params.modelFile = Asset.File(new File([asset.data], 'model.bin'));
-                }
+            let resultsAsset: Asset.Wrapper<'binary'> | undefined;
+            if (params.resultsFile) {
+                resultsAsset = await plugin.runTask(plugin.managers.asset.resolve(params.resultsFile, 'binary', true));
+            } else if (options?.resultfile) {
+                const url = `${params.baseUrl}/results/${options.resultfile}`;
+                resultsAsset = await plugin.runTask(plugin.managers.asset.resolve(Asset.getUrlAsset(plugin.managers.asset, url), 'binary', true));
             }
-            if (params.modelFile && params.modelFile.file){
-                const model_data = await readFromFile(params.modelFile.file!, 'binary').runInContext(ctx);// async ?
-                let buffer = model_data.buffer;
-                if (!IsNativeEndianLittle) {
-                    // flip the byte order
-                    buffer = flipByteOrder(model_data, 4);
-                }
+            if (resultsAsset){
+                (cache as any).asset = resultsAsset;
+                const results = resultsAsset.data;
+                // flip the byte order if needed
+                const buffer = IsNativeEndianLittle ? results.buffer : flipByteOrder(results, 4);
                 const numbers = new DataView(buffer);
                 const ninst = getFloatValue(numbers, 0);
                 const npoints = getFloatValue(numbers, 4);
                 const ncurve = getFloatValue(numbers, 8);
 
-                let pos = new Float32Array();
-                let quat = new Float32Array();
-                let ctr_pos = new Float32Array();
-                let ctr_info = new Float32Array();
-                let curve_ids = new Float32Array();
-
                 let offset = 12;
+
                 if (ninst !== 0){
-                    pos = new Float32Array(buffer, offset, ninst * 4);offset += ninst * 4 * 4;
-                    quat = new Float32Array(buffer, offset, ninst * 4);offset += ninst * 4 * 4;
-                }
-                if ( npoints !== 0 ) {
-                    ctr_pos = new Float32Array(buffer, offset, npoints * 4);offset += npoints * 4 * 4;
-                    offset += npoints * 4 * 4;
-                    ctr_info = new Float32Array(buffer, offset, npoints * 4);offset += npoints * 4 * 4;
-                    curve_ids = new Float32Array(buffer, offset, ncurve * 4);offset += ncurve * 4 * 4;
-                }
+                    const pos = new Float32Array(buffer, offset, ninst * 4);
+                    offset += ninst * 4 * 4;
+                    const quat = new Float32Array(buffer, offset, ninst * 4);
+                    offset += ninst * 4 * 4;
 
-                for (let i = 0; i < ninst; i++) {
-                    const x: number =  pos[i * 4 + 0];
-                    const y: number =  pos[i * 4 + 1];
-                    const z: number =  pos[i * 4 + 2];
-                    const ingr_id = pos[i * 4 + 3] as number;
-                    const pid = cell.mapping_ids![ingr_id];
-                    if (!packings[pid[0]].ingredients[pid[1]].results) {
-                        packings[pid[0]].ingredients[pid[1]].results = [];
+                    for (let i = 0; i < ninst; i++) {
+                        const x: number = pos[i * 4 + 0];
+                        const y: number = pos[i * 4 + 1];
+                        const z: number = pos[i * 4 + 2];
+                        const ingr_id = pos[i * 4 + 3] as number;
+                        const pid = cell.mapping_ids![ingr_id];
+                        if (!packings[pid[0]].ingredients[pid[1]].results) {
+                            packings[pid[0]].ingredients[pid[1]].results = [];
+                        }
+                        packings[pid[0]].ingredients[pid[1]].results.push([Vec3.create(x, y, z),
+                            Quat.create(quat[i * 4 + 0], quat[i * 4 + 1], quat[i * 4 + 2], quat[i * 4 + 3])]);
                     }
-                    packings[pid[0]].ingredients[pid[1]].results.push([Vec3.create(x, y, z),
-                        Quat.create(quat[i * 4 + 0], quat[i * 4 + 1], quat[i * 4 + 2], quat[i * 4 + 3])]);
                 }
-                let counter = 0;
-                let ctr_points: Vec3[] = [];
-                let prev_ctype = 0;
-                let prev_cid = 0;
 
-                for (let i = 0; i < npoints; i++) {
-                    const x: number = -ctr_pos[i * 4 + 0];
-                    const y: number =  ctr_pos[i * 4 + 1];
-                    const z: number =  ctr_pos[i * 4 + 2];
-                    const cid: number = ctr_info[i * 4 + 0];// curve id
-                    const ctype: number = curve_ids[cid * 4 + 0];// curve type
-                    // cid  148 165 -1 0
-                    // console.log("cid ",cid,ctype,prev_cid,prev_ctype);//165,148
-                    if (prev_ctype !== ctype){
-                        const pid = cell.mapping_ids![-prev_ctype - 1];
-                        const cname = `curve${counter}`;
-                        packings[pid[0]].ingredients[pid[1]].nbCurve = counter + 1;
-                        packings[pid[0]].ingredients[pid[1]][cname] = ctr_points;
-                        ctr_points = [];
-                        counter = 0;
-                    } else if (prev_cid !== cid){
-                        ctr_points = [];
-                        const pid = cell.mapping_ids![-prev_ctype - 1];
-                        const cname = `curve${counter}`;
-                        packings[pid[0]].ingredients[pid[1]][cname] = ctr_points;
-                        counter += 1;
+                if (npoints !== 0) {
+                    const ctr_pos = new Float32Array(buffer, offset, npoints * 4);
+                    offset += npoints * 4 * 4;
+                    offset += npoints * 4 * 4;
+                    const ctr_info = new Float32Array(buffer, offset, npoints * 4);
+                    offset += npoints * 4 * 4;
+                    const curve_ids = new Float32Array(buffer, offset, ncurve * 4);
+                    offset += ncurve * 4 * 4;
+
+                    let counter = 0;
+                    let ctr_points: Vec3[] = [];
+                    let prev_ctype = 0;
+                    let prev_cid = 0;
+
+                    for (let i = 0; i < npoints; i++) {
+                        const x: number = -ctr_pos[i * 4 + 0];
+                        const y: number =  ctr_pos[i * 4 + 1];
+                        const z: number =  ctr_pos[i * 4 + 2];
+                        const cid: number = ctr_info[i * 4 + 0]; // curve id
+                        const ctype: number = curve_ids[cid * 4 + 0]; // curve type
+                        // cid  148 165 -1 0
+                        // console.log("cid ",cid,ctype,prev_cid,prev_ctype);//165,148
+                        if (prev_ctype !== ctype){
+                            const pid = cell.mapping_ids![-prev_ctype - 1];
+                            const cname = `curve${counter}`;
+                            packings[pid[0]].ingredients[pid[1]].nbCurve = counter + 1;
+                            packings[pid[0]].ingredients[pid[1]][cname] = ctr_points;
+                            ctr_points = [];
+                            counter = 0;
+                        } else if (prev_cid !== cid){
+                            ctr_points = [];
+                            const pid = cell.mapping_ids![-prev_ctype - 1];
+                            const cname = `curve${counter}`;
+                            packings[pid[0]].ingredients[pid[1]][cname] = ctr_points;
+                            counter += 1;
+                        }
+                        ctr_points.push(Vec3.create(x, y, z));
+                        prev_ctype = ctype;
+                        prev_cid = cid;
                     }
-                    ctr_points.push(Vec3.create(x, y, z));
-                    prev_ctype = ctype;
-                    prev_cid = cid;
-                }
-                // do the last one
-                if ( npoints !== 0 ) {
+
+                    // do the last one
                     const pid = cell.mapping_ids![-prev_ctype - 1];
                     const cname = `curve${counter}`;
                     packings[pid[0]].ingredients[pid[1]].nbCurve = counter + 1;
@@ -297,7 +295,6 @@ const StructureFromAssemblies = PluginStateTransform.BuiltIn({
     }
 });
 
-
 const CreateTransformer = StateTransformer.builderFactory('cellPACK');
 export const CreateSphere = CreateTransformer({
     name: 'create-sphere',