UNPKG

pdbe-molstar

Version:
160 lines (159 loc) 7.25 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DomainAnnotationsProvider = exports.DomainAnnotationsParams = exports.DomainAnnotations = void 0; const tslib_1 = require("tslib"); const custom_model_property_1 = require("molstar/lib/mol-model-props/common/custom-model-property"); const wrapper_1 = require("molstar/lib/mol-model-props/common/wrapper"); const custom_property_1 = require("molstar/lib/mol-model/custom-property"); const structure_1 = require("molstar/lib/mol-model/structure"); const array_1 = require("molstar/lib/mol-util/array"); const assets_1 = require("molstar/lib/mol-util/assets"); const param_definition_1 = require("molstar/lib/mol-util/param-definition"); var DomainAnnotations; (function (DomainAnnotations) { DomainAnnotations.DefaultServerUrl = 'https://www.ebi.ac.uk/pdbe/api/mappings'; function getEntryUrl(pdbId, serverUrl) { return `${serverUrl}/${pdbId.toLowerCase()}`; } DomainAnnotations.getEntryUrl = getEntryUrl; function isApplicable(model) { return !!model && structure_1.Model.hasPdbId(model); } DomainAnnotations.isApplicable = isApplicable; function fromJson(model, data) { const info = wrapper_1.PropertyWrapper.createInfo(); const domainMap = createdomainMapFromJson(model, data); return { info, data: domainMap }; } DomainAnnotations.fromJson = fromJson; function fromServer(ctx, model, props) { return tslib_1.__awaiter(this, void 0, void 0, function* () { const url = assets_1.Asset.getUrlAsset(ctx.assetManager, getEntryUrl(model.entryId, props.serverUrl)); const json = yield ctx.assetManager.resolve(url, 'json').runInContext(ctx.runtime); const data = json.data[model.entryId.toLowerCase()]; if (!data) throw new Error('missing data'); return { value: fromJson(model, data), assets: [json] }; }); } DomainAnnotations.fromServer = fromServer; const _emptyArray = []; /** Return a list of domainSource:domainName strings for a particular location (e.g. ['CATH:Globin']) */ function getDomains(e) { if (!structure_1.Unit.isAtomic(e.unit)) return _emptyArray; const prop = exports.DomainAnnotationsProvider.get(e.unit.model).value; if (!prop || !prop.data) return _emptyArray; const rI = e.unit.residueIndex[e.element]; return prop.data.domains.has(rI) ? prop.data.domains.get(rI) : _emptyArray; } DomainAnnotations.getDomains = getDomains; /** Decide whether a structure location belongs to a domain */ function isInDomain(e, domainSource, domainName) { return getDomains(e).includes(domainKey(domainSource, domainName)); } DomainAnnotations.isInDomain = isInDomain; function getDomainTypes(structure) { const model = structure === null || structure === void 0 ? void 0 : structure.models[0]; if (!model) return _emptyArray; const prop = exports.DomainAnnotationsProvider.get(model).value; if (!prop || !prop.data) return _emptyArray; return prop.data.domainTypes; } DomainAnnotations.getDomainTypes = getDomainTypes; function getDomainNames(structure) { const model = structure === null || structure === void 0 ? void 0 : structure.models[0]; if (!model) return []; const prop = exports.DomainAnnotationsProvider.get(model).value; if (!prop || !prop.data) return []; return prop.data.domainNames; } DomainAnnotations.getDomainNames = getDomainNames; })(DomainAnnotations || (exports.DomainAnnotations = DomainAnnotations = {})); exports.DomainAnnotationsParams = { serverUrl: param_definition_1.ParamDefinition.Text(DomainAnnotations.DefaultServerUrl, { description: 'JSON API Server URL' }), }; exports.DomainAnnotationsProvider = custom_model_property_1.CustomModelProperty.createProvider({ label: 'Domain annotations', descriptor: (0, custom_property_1.CustomPropertyDescriptor)({ name: 'domain_annotations', }), type: 'static', defaultParams: exports.DomainAnnotationsParams, getParams: (data) => exports.DomainAnnotationsParams, isApplicable: (data) => DomainAnnotations.isApplicable(data), obtain: (ctx, data, props) => tslib_1.__awaiter(void 0, void 0, void 0, function* () { const p = Object.assign(Object.assign({}, param_definition_1.ParamDefinition.getDefaultValues(exports.DomainAnnotationsParams)), props); try { return yield DomainAnnotations.fromServer(ctx, data, p); } catch (_a) { console.error('Could not obtain domain annotations'); return { value: DomainAnnotations.fromJson(data, {}) }; } }), }); function findChainLabel(map, label_entity_id, label_asym_id) { const entityIndex = map.entities.getEntityIndex; const eI = entityIndex(label_entity_id); if (eI < 0 || !map.entity_index_label_asym_id.has(eI)) return -1; const cm = map.entity_index_label_asym_id.get(eI); if (!cm) return -1; return cm.has(label_asym_id) ? cm.get(label_asym_id) : -1; } function findResidue(modelData, map, label_entity_id, label_asym_id, label_seq_id) { const cI = findChainLabel(map, label_entity_id, label_asym_id); if (cI < 0) return -1; const rm = map.chain_index_auth_seq_id.get(cI); return rm.has(label_seq_id) ? rm.get(label_seq_id) : -1; } function createdomainMapFromJson(modelData, data) { const domainTypes = []; const domainNames = []; const ret = new Map(); const defaultDomains = ['Pfam', 'InterPro', 'CATH', 'SCOP']; for (const db_name in data) { if (!defaultDomains.includes(db_name)) continue; const tempDomains = []; const db = data[db_name]; for (const db_code in db) { const domain = db[db_code]; for (const mapping of domain.mappings) { (0, array_1.arraySetAdd)(tempDomains, domain.identifier); const indexData = modelData.atomicHierarchy.index; const indexMap = indexData.map; for (let seq_id = mapping.start.residue_number; seq_id <= mapping.end.residue_number; seq_id++) { const idx = findResidue(modelData, indexMap, `${mapping.entity_id}`, mapping.chain_id, seq_id); const key = domainKey(db_name, domain.identifier); const prevVal = ret.get(idx); if (prevVal) { prevVal.push(key); } else { ret.set(idx, [key]); } } } } domainTypes.push(db_name); domainNames.push(tempDomains); } return { domains: structure_1.IndexedCustomProperty.fromResidueMap(ret), domainNames, domainTypes, }; } /** Return string used for indexing domains (e.g. `domainKey('CATH', 'Globin') -> 'CATH:Globin'`) */ function domainKey(domainSource, domainName) { return `${domainSource}:${domainName}`; }