molstar
Version:
A comprehensive macromolecular library.
833 lines (832 loc) • 43.6 kB
JavaScript
/**
* Copyright (c) 2019-2022 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, __generator } from "tslib";
import { StateAction } from '../../mol-state';
import { PluginStateObject as PSO } from '../../mol-plugin-state/objects';
import { ParamDefinition as PD } from '../../mol-util/param-definition';
import { getFromPdb, getFromCellPackDB, parseCif, parsePDBfile, getStructureMean, getFromOPM } from './util';
import { Model, Structure, StructureSymmetry, StructureSelection, QueryContext, Unit } from '../../mol-model/structure';
import { trajectoryFromMmCIF } from '../../mol-model-formats/structure/mmcif';
import { trajectoryFromPDB } from '../../mol-model-formats/structure/pdb';
import { Mat4, Vec3, Quat } from '../../mol-math/linear-algebra';
import { SymmetryOperator } from '../../mol-math/geometry';
import { Task } from '../../mol-task';
import { StateTransforms } from '../../mol-plugin-state/transforms';
import { ParseCellPack, StructureFromCellpack, DefaultCellPackBaseUrl, StructureFromAssemblies, CreateCompartmentSphere } from './state';
import { MolScriptBuilder as MS } from '../../mol-script/language/builder';
import { getMatFromResamplePoints } from './curve';
import { compile } from '../../mol-script/runtime/query/compiler';
import { CellpackPackingPreset, CellpackMembranePreset } from './preset';
import { Asset } from '../../mol-util/assets';
import { Color } from '../../mol-util/color';
import { objectForEach } from '../../mol-util/object';
import { readFromFile } from '../../mol-util/data-source';
import { ColorNames } from '../../mol-util/color/names';
function getCellPackModelUrl(fileName, baseUrl) {
return "".concat(baseUrl, "/results/").concat(fileName);
}
var TrajectoryCache = /** @class */ (function () {
function TrajectoryCache() {
this.map = new Map();
}
TrajectoryCache.prototype.set = function (id, trajectory) { this.map.set(id, trajectory); };
TrajectoryCache.prototype.get = function (id) { return this.map.get(id); };
return TrajectoryCache;
}());
function getModel(plugin, id, ingredient, baseUrl, trajCache, location, file) {
return __awaiter(this, void 0, void 0, function () {
var assetManager, modelIndex, surface, trajectory, assets, text, cif, binary, cif, text, pdb, data, e_1, _a, mmcif, asset, _b, mmcif, asset, data, model;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
assetManager = plugin.managers.asset;
modelIndex = (ingredient.source.model) ? parseInt(ingredient.source.model) : 0;
surface = (ingredient.ingtype) ? (ingredient.ingtype === 'transmembrane') : false;
if (location === 'surface')
surface = true;
trajectory = trajCache.get(id);
assets = [];
if (!!trajectory) return [3 /*break*/, 32];
if (!file) return [3 /*break*/, 14];
if (!file.name.endsWith('.cif')) return [3 /*break*/, 4];
return [4 /*yield*/, plugin.runTask(assetManager.resolve(file, 'string'))];
case 1:
text = _c.sent();
assets.push(text);
return [4 /*yield*/, parseCif(plugin, text.data)];
case 2:
cif = (_c.sent()).blocks[0];
return [4 /*yield*/, plugin.runTask(trajectoryFromMmCIF(cif))];
case 3:
trajectory = _c.sent();
return [3 /*break*/, 13];
case 4:
if (!file.name.endsWith('.bcif')) return [3 /*break*/, 8];
return [4 /*yield*/, plugin.runTask(assetManager.resolve(file, 'binary'))];
case 5:
binary = _c.sent();
assets.push(binary);
return [4 /*yield*/, parseCif(plugin, binary.data)];
case 6:
cif = (_c.sent()).blocks[0];
return [4 /*yield*/, plugin.runTask(trajectoryFromMmCIF(cif))];
case 7:
trajectory = _c.sent();
return [3 /*break*/, 13];
case 8:
if (!file.name.endsWith('.pdb')) return [3 /*break*/, 12];
return [4 /*yield*/, plugin.runTask(assetManager.resolve(file, 'string'))];
case 9:
text = _c.sent();
assets.push(text);
return [4 /*yield*/, parsePDBfile(plugin, text.data, id)];
case 10:
pdb = _c.sent();
return [4 /*yield*/, plugin.runTask(trajectoryFromPDB(pdb))];
case 11:
trajectory = _c.sent();
return [3 /*break*/, 13];
case 12: throw new Error("unsupported file type '".concat(file.name, "'"));
case 13: return [3 /*break*/, 31];
case 14:
if (!id.match(/^[1-9][a-zA-Z0-9]{3,3}$/i)) return [3 /*break*/, 26];
if (!surface) return [3 /*break*/, 22];
_c.label = 15;
case 15:
_c.trys.push([15, 18, , 21]);
return [4 /*yield*/, getFromOPM(plugin, id, assetManager)];
case 16:
data = _c.sent();
assets.push(data.asset);
data.pdb.id = id.toUpperCase();
return [4 /*yield*/, plugin.runTask(trajectoryFromPDB(data.pdb))];
case 17:
trajectory = _c.sent();
return [3 /*break*/, 21];
case 18:
e_1 = _c.sent();
return [4 /*yield*/, getFromPdb(plugin, id, assetManager)];
case 19:
_a = _c.sent(), mmcif = _a.mmcif, asset = _a.asset;
assets.push(asset);
return [4 /*yield*/, plugin.runTask(trajectoryFromMmCIF(mmcif))];
case 20:
trajectory = _c.sent();
return [3 /*break*/, 21];
case 21: return [3 /*break*/, 25];
case 22: return [4 /*yield*/, getFromPdb(plugin, id, assetManager)];
case 23:
_b = _c.sent(), mmcif = _b.mmcif, asset = _b.asset;
assets.push(asset);
return [4 /*yield*/, plugin.runTask(trajectoryFromMmCIF(mmcif))];
case 24:
trajectory = _c.sent();
_c.label = 25;
case 25: return [3 /*break*/, 31];
case 26: return [4 /*yield*/, getFromCellPackDB(plugin, id, baseUrl, assetManager)];
case 27:
data = _c.sent();
assets.push(data.asset);
if (!('pdb' in data)) return [3 /*break*/, 29];
return [4 /*yield*/, plugin.runTask(trajectoryFromPDB(data.pdb))];
case 28:
trajectory = _c.sent();
return [3 /*break*/, 31];
case 29: return [4 /*yield*/, plugin.runTask(trajectoryFromMmCIF(data.mmcif))];
case 30:
trajectory = _c.sent();
_c.label = 31;
case 31:
trajCache.set(id, trajectory);
_c.label = 32;
case 32: return [4 /*yield*/, plugin.resolveTask(trajectory === null || trajectory === void 0 ? void 0 : trajectory.getFrameAtIndex(modelIndex))];
case 33:
model = _c.sent();
return [2 /*return*/, { model: model, assets: assets }];
}
});
});
}
function getStructure(plugin, model, source, props) {
if (props === void 0) { props = {}; }
return __awaiter(this, void 0, void 0, function () {
var structure, assembly, query, sel, asymIds, compiled, result;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
structure = Structure.ofModel(model);
assembly = props.assembly;
if (!assembly) return [3 /*break*/, 2];
return [4 /*yield*/, plugin.runTask(StructureSymmetry.buildAssembly(structure, assembly))];
case 1:
structure = _a.sent();
_a.label = 2;
case 2:
if (source.source.selection) {
sel = source.source.selection;
asymIds = sel.replace(/ /g, '').replace(/:/g, '').split('or').slice(1);
query = MS.struct.modifier.union([
MS.struct.generator.atomGroups({
'chain-test': MS.core.set.has([MS.set.apply(MS, asymIds), MS.ammp('auth_asym_id')])
})
]);
}
else {
query = MS.struct.modifier.union([
MS.struct.generator.atomGroups({
'entity-test': MS.core.rel.eq([MS.ammp('entityType'), 'polymer'])
})
]);
}
compiled = compile(query);
result = compiled(new QueryContext(structure));
structure = StructureSelection.unionStructure(result);
// change here if possible the label ?
// structure.label = source.name;
return [2 /*return*/, structure];
}
});
});
}
function getTransformLegacy(trans, rot) {
var q = Quat.create(-rot[3], rot[0], rot[1], rot[2]);
var m = Mat4.fromQuat(Mat4(), q);
Mat4.transpose(m, m);
Mat4.scale(m, m, Vec3.create(-1.0, 1.0, -1.0));
Mat4.setTranslation(m, trans);
return m;
}
function getTransform(trans, rot) {
var q = Quat.create(-rot[0], rot[1], rot[2], -rot[3]);
var m = Mat4.fromQuat(Mat4(), q);
var p = Vec3.create(-trans[0], trans[1], trans[2]);
Mat4.setTranslation(m, p);
return m;
}
function getResultTransforms(results, legacy) {
if (legacy)
return results.map(function (r) { return getTransformLegacy(r[0], r[1]); });
else
return results.map(function (r) { return getTransform(r[0], r[1]); });
}
function getCurveTransforms(ingredient) {
var n = ingredient.nbCurve || 0;
var instances = [];
var segmentLength = 3.4;
if (ingredient.uLength) {
segmentLength = ingredient.uLength;
}
else if (ingredient.radii) {
segmentLength = ingredient.radii[0].radii
? ingredient.radii[0].radii[0] * 2.0
: 3.4;
}
var resampling = false;
for (var i = 0; i < n; ++i) {
var cname = "curve".concat(i);
if (!(cname in ingredient)) {
console.warn("Expected '".concat(cname, "' in ingredient"));
continue;
}
var _points = ingredient[cname];
if (_points.length <= 2) {
// TODO handle curve with 2 or less points
continue;
}
// test for resampling
var distance = Vec3.distance(_points[0], _points[1]);
if (distance >= segmentLength + 2.0) {
// console.info(distance);
resampling = true;
}
var points = new Float32Array(_points.length * 3);
for (var i_1 = 0, il = _points.length; i_1 < il; ++i_1)
Vec3.toArray(_points[i_1], points, i_1 * 3);
var newInstances = getMatFromResamplePoints(points, segmentLength, resampling);
instances.push.apply(instances, newInstances);
}
return instances;
}
function getAssembly(name, transforms, structure) {
var builder = Structure.Builder({ label: name });
var units = structure.units;
for (var i = 0, il = transforms.length; i < il; ++i) {
var id = "".concat(i + 1);
var op = SymmetryOperator.create(id, transforms[i], { assembly: { id: id, operId: i, operList: [id] } });
for (var _i = 0, units_1 = units; _i < units_1.length; _i++) {
var unit = units_1[_i];
builder.addWithOperator(unit, op);
}
}
return builder.getStructure();
}
function getCurve(name, transforms, model) {
return __awaiter(this, void 0, void 0, function () {
var structure, assembly;
return __generator(this, function (_a) {
structure = Structure.ofModel(model);
assembly = getAssembly(name, transforms, structure);
return [2 /*return*/, assembly];
});
});
}
function getIngredientStructure(plugin, ingredient, baseUrl, ingredientFiles, trajCache, location) {
return __awaiter(this, void 0, void 0, function () {
var name, source, results, nbCurve, file, _a, model, assets, structure, bu, legacy, pcp, structureMean, m1, o, m, p, q, m;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
name = ingredient.name, source = ingredient.source, results = ingredient.results, nbCurve = ingredient.nbCurve;
if (source.pdb === 'None')
return [2 /*return*/];
file = ingredientFiles[source.pdb];
if (!file) {
// TODO can these be added to the library?
if (name === 'HIV1_CAhex_0_1_0')
return [2 /*return*/]; // 1VU4CtoH_hex.pdb
if (name === 'HIV1_CAhexCyclophilA_0_1_0')
return [2 /*return*/]; // 1AK4fitTo1VU4hex.pdb
if (name === 'iLDL')
return [2 /*return*/]; // EMD-5239
if (name === 'peptides')
return [2 /*return*/]; // peptide.pdb
if (name === 'lypoglycane')
return [2 /*return*/];
}
return [4 /*yield*/, getModel(plugin, source.pdb || name, ingredient, baseUrl, trajCache, location, file)];
case 1:
_a = _b.sent(), model = _a.model, assets = _a.assets;
if (!model)
return [2 /*return*/];
if (!nbCurve) return [3 /*break*/, 3];
return [4 /*yield*/, getCurve(name, getCurveTransforms(ingredient), model)];
case 2:
structure = _b.sent();
return [3 /*break*/, 5];
case 3:
if ((!results || results.length === 0))
return [2 /*return*/];
bu = source.bu ? source.bu : undefined;
if (bu) {
if (bu === 'AU') {
bu = undefined;
}
else {
bu = bu.slice(2);
}
}
return [4 /*yield*/, getStructure(plugin, model, ingredient, { assembly: bu })];
case 4:
structure = _b.sent();
legacy = true;
pcp = ingredient.principalVector ? ingredient.principalVector : ingredient.principalAxis;
if (pcp) {
legacy = false;
structureMean = getStructureMean(structure);
Vec3.negate(structureMean, structureMean);
m1 = Mat4.identity();
Mat4.setTranslation(m1, structureMean);
structure = Structure.transform(structure, m1);
if (ingredient.offset) {
o = Vec3.create(ingredient.offset[0], ingredient.offset[1], ingredient.offset[2]);
if (!Vec3.exactEquals(o, Vec3())) { // -1, 1, 4e-16 ??
if (location !== 'surface') {
Vec3.negate(o, o);
}
m = Mat4.identity();
Mat4.setTranslation(m, o);
structure = Structure.transform(structure, m);
}
}
if (pcp) {
p = Vec3.create(pcp[0], pcp[1], pcp[2]);
if (!Vec3.exactEquals(p, Vec3.unitZ)) {
q = Quat.identity();
Quat.rotationTo(q, p, Vec3.unitZ);
m = Mat4.fromQuat(Mat4(), q);
structure = Structure.transform(structure, m);
}
}
}
structure = getAssembly(name, getResultTransforms(results, legacy), structure);
_b.label = 5;
case 5: return [2 /*return*/, { structure: structure, assets: assets }];
}
});
});
}
export function createStructureFromCellPack(plugin, packing, baseUrl, ingredientFiles) {
var _this = this;
return Task.create('Create Packing Structure', function (ctx) { return __awaiter(_this, void 0, void 0, function () {
var ingredients, location, name, assets, trajCache, structures, colors, _a, _b, _i, iName, ingredientStructure, c, units, offsetInvariantId, offsetChainGroupId, _c, structures_1, s, maxInvariantId, maxChainGroupId, _d, _e, u, invariantId, chainGroupId, structure, i, il;
return __generator(this, function (_f) {
switch (_f.label) {
case 0:
ingredients = packing.ingredients, location = packing.location, name = packing.name;
assets = [];
trajCache = new TrajectoryCache();
structures = [];
colors = [];
_a = [];
for (_b in ingredients)
_a.push(_b);
_i = 0;
_f.label = 1;
case 1:
if (!(_i < _a.length)) return [3 /*break*/, 6];
iName = _a[_i];
if (!ctx.shouldUpdate) return [3 /*break*/, 3];
return [4 /*yield*/, ctx.update(iName)];
case 2:
_f.sent();
_f.label = 3;
case 3: return [4 /*yield*/, getIngredientStructure(plugin, ingredients[iName], baseUrl, ingredientFiles, trajCache, location)];
case 4:
ingredientStructure = _f.sent();
if (ingredientStructure) {
structures.push(ingredientStructure.structure);
assets.push.apply(assets, ingredientStructure.assets);
c = ingredients[iName].color;
if (c) {
colors.push(Color.fromNormalizedRgb(c[0], c[1], c[2]));
}
else {
colors.push(Color.fromNormalizedRgb(1, 0, 0));
}
}
_f.label = 5;
case 5:
_i++;
return [3 /*break*/, 1];
case 6:
if (!ctx.shouldUpdate) return [3 /*break*/, 8];
return [4 /*yield*/, ctx.update("".concat(name, " - units"))];
case 7:
_f.sent();
_f.label = 8;
case 8:
units = [];
offsetInvariantId = 0;
offsetChainGroupId = 0;
_c = 0, structures_1 = structures;
_f.label = 9;
case 9:
if (!(_c < structures_1.length)) return [3 /*break*/, 13];
s = structures_1[_c];
if (!ctx.shouldUpdate) return [3 /*break*/, 11];
return [4 /*yield*/, ctx.update("".concat(s.label))];
case 10:
_f.sent();
_f.label = 11;
case 11:
maxInvariantId = 0;
maxChainGroupId = 0;
for (_d = 0, _e = s.units; _d < _e.length; _d++) {
u = _e[_d];
invariantId = u.invariantId + offsetInvariantId;
chainGroupId = u.chainGroupId + offsetChainGroupId;
if (u.invariantId > maxInvariantId)
maxInvariantId = u.invariantId;
units.push(Unit.create(units.length, invariantId, chainGroupId, u.traits, u.kind, u.model, u.conformation.operator, u.elements, u.props));
}
offsetInvariantId += maxInvariantId + 1;
offsetChainGroupId += maxChainGroupId + 1;
_f.label = 12;
case 12:
_c++;
return [3 /*break*/, 9];
case 13:
if (!ctx.shouldUpdate) return [3 /*break*/, 15];
return [4 /*yield*/, ctx.update("".concat(name, " - structure"))];
case 14:
_f.sent();
_f.label = 15;
case 15:
structure = Structure.create(units, { label: name + '.' + location });
for (i = 0, il = structure.models.length; i < il; ++i) {
Model.TrajectoryInfo.set(structure.models[i], { size: il, index: i });
}
return [2 /*return*/, { structure: structure, assets: assets, colors: colors }];
}
});
}); });
}
function handleHivRna(plugin, packings, baseUrl) {
return __awaiter(this, void 0, void 0, function () {
var i, il, url, json, points, curve0, j, jl;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
i = 0, il = packings.length;
_a.label = 1;
case 1:
if (!(i < il)) return [3 /*break*/, 4];
if (!(packings[i].name === 'HIV1_capsid_3j3q_PackInner_0_1_0' || packings[i].name === 'HIV_capsid')) return [3 /*break*/, 3];
url = Asset.getUrlAsset(plugin.managers.asset, "".concat(baseUrl, "/extras/rna_allpoints.json"));
return [4 /*yield*/, plugin.runTask(plugin.managers.asset.resolve(url, 'json', false))];
case 2:
json = _a.sent();
points = json.data.points;
curve0 = [];
for (j = 0, jl = points.length; j < jl; j += 3) {
curve0.push(Vec3.fromArray(Vec3(), points, j));
}
packings[i].ingredients['RNA'] = {
source: { pdb: 'RNA_U_Base.pdb', transform: { center: false } },
results: [],
name: 'RNA',
nbCurve: 1,
curve0: curve0
};
_a.label = 3;
case 3:
++i;
return [3 /*break*/, 1];
case 4: return [2 /*return*/];
}
});
});
}
function loadMembrane(plugin, name, state, params) {
return __awaiter(this, void 0, void 0, function () {
var file, fileName, _i, _a, f, cifileName, _b, _c, f, legacy_membrane, geometry_membrane, b, url, url, url, url, props, membrane, membraneParams, membrane, membraneParams;
return __generator(this, function (_d) {
switch (_d.label) {
case 0:
file = undefined;
if (params.ingredients !== null) {
fileName = "".concat(name, ".bcif");
for (_i = 0, _a = params.ingredients; _i < _a.length; _i++) {
f = _a[_i];
if (fileName === f.name) {
file = f;
break;
}
}
if (!file) {
cifileName = "".concat(name, ".cif");
for (_b = 0, _c = params.ingredients; _b < _c.length; _b++) {
f = _c[_b];
if (cifileName === f.name) {
file = f;
break;
}
}
}
}
legacy_membrane = false;
geometry_membrane = false;
b = state.build().toRoot();
if (file) {
if (file.name.endsWith('.cif')) {
b = b.apply(StateTransforms.Data.ReadFile, { file: file, isBinary: false, label: file.name }, { state: { isGhost: true } });
}
else if (file.name.endsWith('.bcif')) {
b = b.apply(StateTransforms.Data.ReadFile, { file: file, isBinary: true, label: file.name }, { state: { isGhost: true } });
}
}
else {
if (name.toLowerCase().endsWith('.bcif')) {
url = Asset.getUrlAsset(plugin.managers.asset, "".concat(params.baseUrl, "/membranes/").concat(name));
b = b.apply(StateTransforms.Data.Download, { url: url, isBinary: true, label: name }, { state: { isGhost: true } });
}
else if (name.toLowerCase().endsWith('.cif')) {
url = Asset.getUrlAsset(plugin.managers.asset, "".concat(params.baseUrl, "/membranes/").concat(name));
b = b.apply(StateTransforms.Data.Download, { url: url, isBinary: false, label: name }, { state: { isGhost: true } });
}
else if (name.toLowerCase().endsWith('.ply')) {
url = Asset.getUrlAsset(plugin.managers.asset, "".concat(params.baseUrl, "/geometries/").concat(name));
b = b.apply(StateTransforms.Data.Download, { url: url, isBinary: false, label: name }, { state: { isGhost: true } });
geometry_membrane = true;
}
else {
url = Asset.getUrlAsset(plugin.managers.asset, "".concat(params.baseUrl, "/membranes/").concat(name, ".bcif"));
b = b.apply(StateTransforms.Data.Download, { url: url, isBinary: true, label: name }, { state: { isGhost: true } });
legacy_membrane = true;
}
}
props = {
type: {
name: 'assembly',
params: { id: '1' }
}
};
if (!legacy_membrane) return [3 /*break*/, 3];
return [4 /*yield*/, b.apply(StateTransforms.Data.ParseCif, undefined, { state: { isGhost: true } })
.apply(StateTransforms.Model.TrajectoryFromMmCif, undefined, { state: { isGhost: true } })
.apply(StateTransforms.Model.ModelFromTrajectory, undefined, { state: { isGhost: true } })
.apply(StructureFromAssemblies, undefined, { state: { isGhost: true } })
.commit({ revertOnError: true })];
case 1:
membrane = _d.sent();
membraneParams = {
ignoreLight: params.preset.adjustStyle,
representation: params.preset.representation,
};
return [4 /*yield*/, CellpackMembranePreset.apply(membrane, membraneParams, plugin)];
case 2:
_d.sent();
return [3 /*break*/, 8];
case 3:
if (!geometry_membrane) return [3 /*break*/, 5];
return [4 /*yield*/, b.apply(StateTransforms.Data.ParsePly, undefined, { state: { isGhost: true } })
.apply(StateTransforms.Model.ShapeFromPly)
.apply(StateTransforms.Representation.ShapeRepresentation3D, { xrayShaded: true,
doubleSided: true, coloring: { name: 'uniform', params: { color: ColorNames.orange } } })
.commit({ revertOnError: true })];
case 4:
_d.sent();
return [3 /*break*/, 8];
case 5: return [4 /*yield*/, b.apply(StateTransforms.Data.ParseCif, undefined, { state: { isGhost: true } })
.apply(StateTransforms.Model.TrajectoryFromMmCif, undefined, { state: { isGhost: true } })
.apply(StateTransforms.Model.ModelFromTrajectory, undefined, { state: { isGhost: true } })
.apply(StateTransforms.Model.StructureFromModel, props, { state: { isGhost: true } })
.commit({ revertOnError: true })];
case 6:
membrane = _d.sent();
membraneParams = {
ignoreLight: params.preset.adjustStyle,
representation: params.preset.representation,
};
return [4 /*yield*/, CellpackMembranePreset.apply(membrane, membraneParams, plugin)];
case 7:
_d.sent();
_d.label = 8;
case 8: return [2 /*return*/];
}
});
});
}
function handleMembraneSpheres(state, primitives) {
return __awaiter(this, void 0, void 0, function () {
var nSpheres, j;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
nSpheres = primitives.positions.length / 3;
j = 0;
_a.label = 1;
case 1:
if (!(j < nSpheres)) return [3 /*break*/, 4];
return [4 /*yield*/, state.build()
.toRoot()
.apply(CreateCompartmentSphere, {
center: Vec3.create(primitives.positions[j * 3 + 0], primitives.positions[j * 3 + 1], primitives.positions[j * 3 + 2]),
radius: primitives.radii[j]
})
.commit()];
case 2:
_a.sent();
_a.label = 3;
case 3:
j++;
return [3 /*break*/, 1];
case 4: return [2 /*return*/];
}
});
});
}
function loadPackings(plugin, runtime, state, params) {
return __awaiter(this, void 0, void 0, function () {
var ingredientFiles, cellPackJson, resultsFile, url, file, modelFile, data, cellPackBuilder, cellPackObject, packings, i, il, p, packing, packingParams;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
ingredientFiles = params.ingredients || [];
resultsFile = params.results;
if (!(params.source.name === 'id')) return [3 /*break*/, 1];
url = Asset.getUrlAsset(plugin.managers.asset, getCellPackModelUrl(params.source.params, params.baseUrl));
cellPackJson = state.build().toRoot()
.apply(StateTransforms.Data.Download, { url: url, isBinary: false, label: params.source.params }, { state: { isGhost: true } });
return [3 /*break*/, 5];
case 1:
file = params.source.params;
if (!(file === null || file === void 0 ? void 0 : file.file)) {
plugin.log.error('No file selected');
return [2 /*return*/];
}
modelFile = void 0;
if (!file.name.toLowerCase().endsWith('.zip')) return [3 /*break*/, 3];
return [4 /*yield*/, readFromFile(file.file, 'zip').runInContext(runtime)];
case 2:
data = _a.sent();
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, function (v, k) {
if (k === 'model.json')
return;
if (k === 'results.bin')
return;
ingredientFiles.push(Asset.File(new File([v], k)));
});
return [3 /*break*/, 4];
case 3:
modelFile = file;
_a.label = 4;
case 4:
cellPackJson = state.build().toRoot()
.apply(StateTransforms.Data.ReadFile, { file: modelFile, isBinary: false, label: modelFile.name }, { state: { isGhost: true } });
_a.label = 5;
case 5:
cellPackBuilder = cellPackJson
.apply(StateTransforms.Data.ParseJson, undefined, { state: { isGhost: true } })
.apply(ParseCellPack, { resultsFile: resultsFile, baseUrl: params.baseUrl });
return [4 /*yield*/, state.updateTree(cellPackBuilder).runInContext(runtime)];
case 6:
cellPackObject = _a.sent();
packings = cellPackObject.obj.data.packings;
return [4 /*yield*/, handleHivRna(plugin, packings, params.baseUrl)];
case 7:
_a.sent();
i = 0, il = packings.length;
_a.label = 8;
case 8:
if (!(i < il)) return [3 /*break*/, 23];
p = { packing: i, baseUrl: params.baseUrl, ingredientFiles: ingredientFiles };
return [4 /*yield*/, state.build()
.to(cellPackBuilder.ref)
.apply(StructureFromCellpack, p)
.commit({ revertOnError: true })];
case 9:
packing = _a.sent();
packingParams = {
traceOnly: params.preset.traceOnly,
ignoreLight: params.preset.adjustStyle,
representation: params.preset.representation,
};
return [4 /*yield*/, CellpackPackingPreset.apply(packing, packingParams, plugin)];
case 10:
_a.sent();
if (!packings[i].compartment) return [3 /*break*/, 22];
if (!(params.membrane === 'lipids')) return [3 /*break*/, 18];
if (!packings[i].compartment.geom_type) return [3 /*break*/, 15];
if (!(packings[i].compartment.geom_type === 'file')) return [3 /*break*/, 12];
// TODO: load mesh files or vertex,faces data
return [4 /*yield*/, loadMembrane(plugin, packings[i].compartment.filename, state, params)];
case 11:
// TODO: load mesh files or vertex,faces data
_a.sent();
return [3 /*break*/, 14];
case 12:
if (!packings[i].compartment.compartment_primitives) return [3 /*break*/, 14];
return [4 /*yield*/, handleMembraneSpheres(state, packings[i].compartment.compartment_primitives)];
case 13:
_a.sent();
_a.label = 14;
case 14: return [3 /*break*/, 17];
case 15:
if (!(params.membrane === 'lipids')) return [3 /*break*/, 17];
return [4 /*yield*/, loadMembrane(plugin, packings[i].name, state, params)];
case 16:
_a.sent();
_a.label = 17;
case 17: return [3 /*break*/, 22];
case 18:
if (!(params.membrane === 'geometry')) return [3 /*break*/, 22];
if (!packings[i].compartment.compartment_primitives) return [3 /*break*/, 20];
return [4 /*yield*/, handleMembraneSpheres(state, packings[i].compartment.compartment_primitives)];
case 19:
_a.sent();
return [3 /*break*/, 22];
case 20:
if (!(packings[i].compartment.geom_type === 'file')) return [3 /*break*/, 22];
if (!packings[i].compartment.filename.toLowerCase().endsWith('.ply')) return [3 /*break*/, 22];
return [4 /*yield*/, loadMembrane(plugin, packings[i].compartment.filename, state, params)];
case 21:
_a.sent();
_a.label = 22;
case 22:
++i;
return [3 /*break*/, 8];
case 23: return [2 /*return*/];
}
});
});
}
var LoadCellPackModelParams = {
source: PD.MappedStatic('id', {
'id': PD.Select('InfluenzaModel2.json', [
['blood_hiv_immature_inside.json', 'Blood HIV immature'],
['HIV_immature_model.json', 'HIV immature'],
['Blood_HIV.json', 'Blood HIV'],
['HIV-1_0.1.6-8_mixed_radii_pdb.json', 'HIV'],
['influenza_model1.json', 'Influenza envelope'],
['InfluenzaModel2.json', 'Influenza complete'],
['ExosomeModel.json', 'Exosome Model'],
['MycoplasmaGenitalium.json', 'Mycoplasma Genitalium curated model'],
], { description: 'Download the model definition with `id` from the server at `baseUrl.`' }),
'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', description: 'open results file in binary format from cellpackgpu for the specified recipe', label: 'Results file' }),
membrane: PD.Select('lipids', PD.arrayToOptions(['lipids', 'geometry', 'none'])),
ingredients: PD.FileList({ accept: '.cif,.bcif,.pdb', label: 'Ingredient files' }),
preset: PD.Group({
traceOnly: PD.Boolean(false),
adjustStyle: PD.Boolean(true),
representation: PD.Select('gaussian-surface', PD.arrayToOptions(['spacefill', 'gaussian-surface', 'point', 'orientation']))
}, { isExpanded: true })
};
export var LoadCellPackModel = StateAction.build({
display: { name: 'Load CellPack', description: 'Open or download a model' },
params: LoadCellPackModelParams,
from: PSO.Root
})(function (_a, ctx) {
var state = _a.state, params = _a.params;
return Task.create('CellPack Loader', function (taskCtx) { return __awaiter(void 0, void 0, void 0, function () {
var _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
if (params.preset.adjustStyle) {
ctx.managers.interactivity.setProps({ granularity: 'chain' });
ctx.managers.structure.component.setOptions(__assign(__assign({}, ctx.managers.structure.component.state.options), { visualQuality: 'custom', ignoreLight: true, showHydrogens: false }));
(_a = ctx.canvas3d) === null || _a === void 0 ? void 0 : _a.setProps({
multiSample: { mode: 'off' },
cameraClipping: { far: false },
renderer: { colorMarker: false },
marking: {
enabled: true,
ghostEdgeStrength: 1,
},
postprocessing: {
occlusion: {
name: 'on',
params: {
samples: 32,
radius: 8,
bias: 1,
blurKernelSize: 15,
resolutionScale: 1,
}
},
outline: {
name: 'on',
params: {
scale: 1,
threshold: 0.33,
color: ColorNames.black,
}
}
}
});
}
return [4 /*yield*/, loadPackings(ctx, taskCtx, state, params)];
case 1:
_b.sent();
return [2 /*return*/];
}
});
}); });
});