UNPKG

molstar

Version:

A comprehensive macromolecular library.

394 lines (393 loc) 22.3 kB
/** * Copyright (c) 2019-2021 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> * @author Ludovic Autin <ludovic.autin@gmail.com> */ import { __assign, __awaiter, __extends, __generator } from "tslib"; import { PluginStateObject as PSO, PluginStateTransform } from '../../mol-plugin-state/objects'; import { ParamDefinition as PD } from '../../mol-util/param-definition'; import { Task } from '../../mol-task'; import { createStructureFromCellPack } from './model'; import { Asset } from '../../mol-util/assets'; import { CellPackInfoProvider } from './property'; import { Structure, StructureSymmetry, Model } from '../../mol-model/structure'; import { ModelSymmetry } from '../../mol-model-formats/structure/property/symmetry'; import { Vec3, Quat } from '../../mol-math/linear-algebra'; import { StateTransformer } from '../../mol-state'; import { MBRepresentation, MBParams } from './representation'; import { IsNativeEndianLittle, flipByteOrder } from '../../mol-io/common/binary'; import { getFloatValue } from './util'; export var DefaultCellPackBaseUrl = 'https://raw.githubusercontent.com/mesoscope/cellPACK_data/master/cellPACK_database_1.1.0'; var CellPack = /** @class */ (function (_super) { __extends(CellPack, _super); function CellPack() { return _super !== null && _super.apply(this, arguments) || this; } return CellPack; }(PSO.Create({ name: 'CellPack', typeClass: 'Object' }))); export { CellPack }; export { ParseCellPack }; var ParseCellPack = PluginStateTransform.BuiltIn({ name: 'parse-cellpack', display: { name: 'Parse CellPack', description: 'Parse CellPack from JSON data' }, from: PSO.Format.Json, to: CellPack, params: function (a) { return { resultsFile: PD.File({ accept: '.bin' }), baseUrl: PD.Text(DefaultCellPackBaseUrl) }; } })({ apply: function (_a, plugin) { var _this = this; var a = _a.a, params = _a.params, cache = _a.cache; return Task.create('Parse CellPack', function (ctx) { return __awaiter(_this, void 0, void 0, function () { var cell, counter_id, fiber_counter_id, comp_counter, packings, compartments, cytoplasme, iName, name_1, _a, surface, interior, filename, compartment, iName, iName, options, resultsAsset, url, results, buffer, numbers, ninst, npoints, ncurve, offset, pos, quat, i, x, y, z, ingr_id, pid, ctr_pos, ctr_info, curve_ids, counter, ctr_points, prev_ctype, prev_cid, i, x, y, z, cid, ctype, pid_1, cname_1, pid_2, cname_2, pid, cname; return __generator(this, function (_b) { switch (_b.label) { case 0: cell = a.data; counter_id = 0; fiber_counter_id = 0; comp_counter = 0; packings = []; compartments = cell.compartments, cytoplasme = cell.cytoplasme; if (!cell.mapping_ids) cell.mapping_ids = {}; if (cytoplasme) { packings.push({ name: 'Cytoplasme', location: 'cytoplasme', ingredients: cytoplasme.ingredients }); for (iName in cytoplasme.ingredients) { if (cytoplasme.ingredients[iName].ingtype === 'fiber') { cell.mapping_ids[-(fiber_counter_id + 1)] = [comp_counter, iName]; if (!cytoplasme.ingredients[iName].nbCurve) cytoplasme.ingredients[iName].nbCurve = 0; fiber_counter_id++; } else { cell.mapping_ids[counter_id] = [comp_counter, iName]; if (!cytoplasme.ingredients[iName].results) { cytoplasme.ingredients[iName].results = []; } counter_id++; } } comp_counter++; } if (compartments) { for (name_1 in compartments) { _a = compartments[name_1], surface = _a.surface, interior = _a.interior; filename = ''; if (compartments[name_1].geom_type === 'file') { filename = (compartments[name_1].geom) ? compartments[name_1].geom : ''; } compartment = { filename: filename, geom_type: compartments[name_1].geom_type, compartment_primitives: compartments[name_1].mb }; if (surface) { packings.push({ name: name_1, location: 'surface', ingredients: surface.ingredients, compartment: compartment }); for (iName in surface.ingredients) { if (surface.ingredients[iName].ingtype === 'fiber') { cell.mapping_ids[-(fiber_counter_id + 1)] = [comp_counter, iName]; if (!surface.ingredients[iName].nbCurve) surface.ingredients[iName].nbCurve = 0; fiber_counter_id++; } else { cell.mapping_ids[counter_id] = [comp_counter, iName]; if (!surface.ingredients[iName].results) { surface.ingredients[iName].results = []; } counter_id++; } } comp_counter++; } if (interior) { if (!surface) packings.push({ name: name_1, location: 'interior', ingredients: interior.ingredients, compartment: compartment }); else packings.push({ name: name_1, location: 'interior', ingredients: interior.ingredients }); for (iName in interior.ingredients) { if (interior.ingredients[iName].ingtype === 'fiber') { cell.mapping_ids[-(fiber_counter_id + 1)] = [comp_counter, iName]; if (!interior.ingredients[iName].nbCurve) interior.ingredients[iName].nbCurve = 0; fiber_counter_id++; } else { cell.mapping_ids[counter_id] = [comp_counter, iName]; if (!interior.ingredients[iName].results) { interior.ingredients[iName].results = []; } counter_id++; } } comp_counter++; } } } options = cell.options; if (!params.resultsFile) return [3 /*break*/, 2]; return [4 /*yield*/, plugin.runTask(plugin.managers.asset.resolve(params.resultsFile, 'binary', true))]; case 1: resultsAsset = _b.sent(); return [3 /*break*/, 4]; case 2: if (!(options === null || options === void 0 ? void 0 : options.resultfile)) return [3 /*break*/, 4]; url = "".concat(params.baseUrl, "/results/").concat(options.resultfile); return [4 /*yield*/, plugin.runTask(plugin.managers.asset.resolve(Asset.getUrlAsset(plugin.managers.asset, url), 'binary', true))]; case 3: resultsAsset = _b.sent(); _b.label = 4; case 4: if (resultsAsset) { cache.asset = resultsAsset; results = resultsAsset.data; buffer = IsNativeEndianLittle ? results.buffer : flipByteOrder(results, 4); numbers = new DataView(buffer); ninst = getFloatValue(numbers, 0); npoints = getFloatValue(numbers, 4); ncurve = getFloatValue(numbers, 8); 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; for (i = 0; i < ninst; i++) { x = pos[i * 4 + 0]; y = pos[i * 4 + 1]; z = pos[i * 4 + 2]; ingr_id = pos[i * 4 + 3]; 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])]); } } 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; counter = 0; ctr_points = []; prev_ctype = 0; prev_cid = 0; for (i = 0; i < npoints; i++) { x = -ctr_pos[i * 4 + 0]; y = ctr_pos[i * 4 + 1]; z = ctr_pos[i * 4 + 2]; cid = ctr_info[i * 4 + 0]; ctype = curve_ids[cid * 4 + 0]; // cid 148 165 -1 0 // console.log("cid ",cid,ctype,prev_cid,prev_ctype);//165,148 if (prev_ctype !== ctype) { pid_1 = cell.mapping_ids[-prev_ctype - 1]; cname_1 = "curve".concat(counter); packings[pid_1[0]].ingredients[pid_1[1]].nbCurve = counter + 1; packings[pid_1[0]].ingredients[pid_1[1]][cname_1] = ctr_points; ctr_points = []; counter = 0; } else if (prev_cid !== cid) { ctr_points = []; pid_2 = cell.mapping_ids[-prev_ctype - 1]; cname_2 = "curve".concat(counter); packings[pid_2[0]].ingredients[pid_2[1]][cname_2] = ctr_points; counter += 1; } ctr_points.push(Vec3.create(x, y, z)); prev_ctype = ctype; prev_cid = cid; } pid = cell.mapping_ids[-prev_ctype - 1]; cname = "curve".concat(counter); packings[pid[0]].ingredients[pid[1]].nbCurve = counter + 1; packings[pid[0]].ingredients[pid[1]][cname] = ctr_points; } } return [2 /*return*/, new CellPack({ cell: cell, packings: packings })]; } }); }); }); }, dispose: function (_a) { var _b; var cache = _a.cache; (_b = cache === null || cache === void 0 ? void 0 : cache.asset) === null || _b === void 0 ? void 0 : _b.dispose(); }, }); export { StructureFromCellpack }; var StructureFromCellpack = PluginStateTransform.BuiltIn({ name: 'structure-from-cellpack', display: { name: 'Structure from CellPack', description: 'Create Structure from CellPack Packing' }, from: CellPack, to: PSO.Molecule.Structure, params: function (a) { var options = a ? a.data.packings.map(function (d, i) { return [i, d.name]; }) : []; return { packing: PD.Select(0, options), baseUrl: PD.Text(DefaultCellPackBaseUrl), ingredientFiles: PD.FileList({ accept: '.cif,.bcif,.pdb' }) }; } })({ apply: function (_a, plugin) { var _this = this; var a = _a.a, params = _a.params, cache = _a.cache; return Task.create('Structure from CellPack', function (ctx) { return __awaiter(_this, void 0, void 0, function () { var packing, ingredientFiles, _i, _a, file, _b, structure, assets, colors; return __generator(this, function (_c) { switch (_c.label) { case 0: packing = a.data.packings[params.packing]; ingredientFiles = {}; if (params.ingredientFiles !== null) { for (_i = 0, _a = params.ingredientFiles; _i < _a.length; _i++) { file = _a[_i]; ingredientFiles[file.name] = file; } } return [4 /*yield*/, createStructureFromCellPack(plugin, packing, params.baseUrl, ingredientFiles).runInContext(ctx)]; case 1: _b = _c.sent(), structure = _b.structure, assets = _b.assets, colors = _b.colors; return [4 /*yield*/, CellPackInfoProvider.attach({ runtime: ctx, assetManager: plugin.managers.asset }, structure, { info: { packingsCount: a.data.packings.length, packingIndex: params.packing, colors: colors } })]; case 2: _c.sent(); cache.assets = assets; return [2 /*return*/, new PSO.Molecule.Structure(structure, { label: packing.name + '.' + packing.location })]; } }); }); }); }, dispose: function (_a) { var b = _a.b, cache = _a.cache; var assets = cache.assets; if (assets) { for (var _i = 0, assets_1 = assets; _i < assets_1.length; _i++) { var a = assets_1[_i]; a.dispose(); } } if (b) { b.data.customPropertyDescriptors.dispose(); for (var _b = 0, _c = b.data.models; _b < _c.length; _b++) { var m = _c[_b]; m.customProperties.dispose(); } } } }); export { StructureFromAssemblies }; var StructureFromAssemblies = PluginStateTransform.BuiltIn({ name: 'Structure from all assemblies', display: { name: 'Structure from all assemblies' }, from: PSO.Molecule.Model, to: PSO.Molecule.Structure, params: {} })({ canAutoUpdate: function (_a) { var newParams = _a.newParams; return true; }, apply: function (_a) { var _this = this; var a = _a.a, params = _a.params; return Task.create('Build Structure', function (ctx) { return __awaiter(_this, void 0, void 0, function () { var model, initial_structure, structures, structure, symmetry, _i, _a, a_1, s, builder, offsetInvariantId, _b, structures_1, s, maxInvariantId, _c, _d, u, invariantId, i, il; return __generator(this, function (_e) { switch (_e.label) { case 0: model = a.data; initial_structure = Structure.ofModel(model); structures = []; structure = initial_structure; symmetry = ModelSymmetry.Provider.get(model); if (!(symmetry && symmetry.assemblies.length !== 0)) return [3 /*break*/, 5]; _i = 0, _a = symmetry.assemblies; _e.label = 1; case 1: if (!(_i < _a.length)) return [3 /*break*/, 4]; a_1 = _a[_i]; return [4 /*yield*/, StructureSymmetry.buildAssembly(initial_structure, a_1.id).runInContext(ctx)]; case 2: s = _e.sent(); structures.push(s); _e.label = 3; case 3: _i++; return [3 /*break*/, 1]; case 4: builder = Structure.Builder({ label: 'Membrane' }); offsetInvariantId = 0; for (_b = 0, structures_1 = structures; _b < structures_1.length; _b++) { s = structures_1[_b]; maxInvariantId = 0; for (_c = 0, _d = s.units; _c < _d.length; _c++) { u = _d[_c]; invariantId = u.invariantId + offsetInvariantId; if (u.invariantId > maxInvariantId) maxInvariantId = u.invariantId; builder.addUnit(u.kind, u.model, u.conformation.operator, u.elements, 0 /* Unit.Trait.None */, invariantId); } offsetInvariantId += maxInvariantId + 1; } structure = builder.getStructure(); for (i = 0, il = structure.models.length; i < il; ++i) { Model.TrajectoryInfo.set(structure.models[i], { size: il, index: i }); } _e.label = 5; case 5: return [2 /*return*/, new PSO.Molecule.Structure(structure, { label: a.label, description: "".concat(a.description) })]; } }); }); }); }, dispose: function (_a) { var b = _a.b; b === null || b === void 0 ? void 0 : b.data.customPropertyDescriptors.dispose(); } }); var CreateTransformer = StateTransformer.builderFactory('cellPACK'); export var CreateCompartmentSphere = CreateTransformer({ name: 'create-compartment-sphere', display: 'CompartmentSphere', from: PSO.Root, to: PSO.Shape.Representation3D, params: { center: PD.Vec3(Vec3()), radius: PD.Numeric(1), label: PD.Text("Compartment Sphere") } })({ canAutoUpdate: function (_a) { var oldParams = _a.oldParams, newParams = _a.newParams; return true; }, apply: function (_a, plugin) { var _this = this; var a = _a.a, params = _a.params; return Task.create('Compartment Sphere', function (ctx) { return __awaiter(_this, void 0, void 0, function () { var data, repr; var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: data = params; repr = MBRepresentation(__assign({ webgl: (_a = plugin.canvas3d) === null || _a === void 0 ? void 0 : _a.webgl }, plugin.representation.structure.themes), function () { return (MBParams); }); return [4 /*yield*/, repr.createOrUpdate(__assign(__assign({}, params), { quality: 'custom', xrayShaded: true, doubleSided: true }), data).runInContext(ctx)]; case 1: _b.sent(); return [2 /*return*/, new PSO.Shape.Representation3D({ repr: repr, sourceData: a }, { label: data.label })]; } }); }); }); } });