pdbe-molstar
Version:
Molstar implementation for PDBe
160 lines (159 loc) • 7.25 kB
JavaScript
;
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}`;
}