molstar
Version:
A comprehensive macromolecular library.
394 lines (393 loc) • 22.3 kB
JavaScript
/**
* 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 })];
}
});
}); });
}
});