Skip to content
Snippets Groups Projects
Commit 0b9f31b4 authored by David Sehnal's avatar David Sehnal
Browse files

Mod res support

parent cb0c0518
No related branches found
No related tags found
No related merge requests found
......@@ -126,6 +126,17 @@ export function printSequence(model: Model) {
console.log();
}
export function printModRes(model: Model) {
console.log('\nModified Residues\n=============');
const { residueIndices, keys, data } = model.properties.modifiedResidues;
const { label_comp_id } = model.atomicHierarchy.residues;
for (let i = 0; i < residueIndices.length; i++) {
const rI = residueIndices[i], k = keys[i];
console.log(`Idx: ${rI} ${data.parent_comp_id.value(k)} -> ${label_comp_id.value(rI)}`);
}
console.log();
}
export function printRings(structure: Structure) {
console.log('\nRings\n=============');
for (const unit of structure.units) {
......@@ -186,6 +197,7 @@ async function run(mmcif: mmCIF_Database) {
printUnits(structure);
printRings(structure);
printLinks(structure, false, true);
printModRes(models[0]);
//printSecStructure(models[0]);
}
......
......@@ -11,7 +11,7 @@ import { Vec3 } from 'mol-math/linear-algebra';
import UUID from 'mol-util/uuid';
import Format from '../format';
import Model from '../model';
import { AtomicConformation, AtomicData, AtomicSegments, AtomsSchema, ChainsSchema, ResiduesSchema } from '../properties/atomic';
import { AtomicConformation, AtomicData, AtomicSegments, AtomsSchema, ChainsSchema, ResiduesSchema, AtomicHierarchy } from '../properties/atomic';
import { Entities } from '../properties/common';
import { ModelSymmetry } from '../properties/symmetry';
import { getAtomicKeys } from '../properties/utils/atomic-keys';
......@@ -23,6 +23,7 @@ import { getSequence } from './mmcif/sequence';
import mmCIF_Format = Format.mmCIF
import { Task } from 'mol-task';
import { getSecondaryStructureMmCif } from './mmcif/secondary-structure';
import { ModifiedResidues } from './mmcif/modified-residues';
function findModelBounds({ data }: mmCIF_Format, startIndex: number) {
const num = data.atom_site.pdbx_PDB_model_num;
......@@ -118,6 +119,15 @@ function isHierarchyDataEqual(a: AtomicData, b: AtomicData) {
&& Table.areEqual(a.atoms as Table<AtomsSchema>, b.atoms as Table<AtomsSchema>)
}
function modResProvider(format: mmCIF_Format, hierarchy: AtomicHierarchy, entities: Entities) {
let modres: ModifiedResidues | undefined = void 0;
return () => {
if (modres) return modres;
modres = new ModifiedResidues(format.data.pdbx_struct_mod_residue, hierarchy, entities);
return modres;
}
}
function createModel(format: mmCIF_Format, bounds: Interval, previous?: Model): Model {
const hierarchyOffsets = findHierarchyOffsets(format, bounds);
const hierarchyData = createHierarchyData(format, bounds, hierarchyOffsets);
......@@ -146,6 +156,8 @@ function createModel(format: mmCIF_Format, bounds: Interval, previous?: Model):
? format.data.entry.id.value(0)
: format.data._name;
const modRes = modResProvider(format, atomicHierarchy, entities);
return {
id: UUID.create(),
label,
......@@ -158,7 +170,8 @@ function createModel(format: mmCIF_Format, bounds: Interval, previous?: Model):
coarseHierarchy: coarse.hierarchy,
coarseConformation: coarse.conformation,
properties: {
secondaryStructure: getSecondaryStructureMmCif(format.data, atomicHierarchy)
secondaryStructure: getSecondaryStructureMmCif(format.data, atomicHierarchy),
get modifiedResidues() { return modRes() }
},
symmetry: getSymmetry(format)
};
......
/**
* Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { mmCIF_Database } from 'mol-io/reader/cif/schema/mmcif'
import { AtomicHierarchy } from '../../properties/atomic';
import { Entities } from '../../properties/common';
class ModifiedResidues {
private residueIndexMap = new Map<number, number>();
/** All residue indices within the given model that are modified. */
readonly residueIndices: ReadonlyArray<number>;
/** Indexed same as residueIndex and is key to ModifiedResidues.data table */
readonly keys: ReadonlyArray<number>;
/** Index into the data table. -1 if the residue is not modified. */
getKey(residueIndex: number): number {
return this.residueIndexMap.has(residueIndex) ? this.residueIndexMap.get(residueIndex)! : -1;
}
constructor(public data: mmCIF_Database['pdbx_struct_mod_residue'], hierarchy: AtomicHierarchy, entities: Entities) {
if (data._rowCount === 0) {
this.residueIndices = [];
this.keys = [];
return;
}
const { PDB_ins_code, auth_seq_id, _rowCount } = data;
const asym_id = data.label_asym_id.isDefined ? data.label_asym_id : data.auth_asym_id;
const comp_id = data.label_comp_id.isDefined ? data.label_comp_id : data.auth_comp_id;
const entityIds = entities.data.id.toArray();
const residueIndices: number[] = [];
const keys: number[] = [];
for (let i = 0; i < _rowCount; i++) {
const aId = asym_id.value(i);
const eIdx = getEntityId(hierarchy, entityIds, aId);
if (eIdx < 0) continue;
const key = hierarchy.findResidueKey(entityIds[eIdx], aId, comp_id.value(i), auth_seq_id.value(i), PDB_ins_code.value(i));
if (key >= 0) {
this.residueIndexMap.set(key, i);
residueIndices[residueIndices.length] = key;
keys[keys.length] = i;
}
}
this.residueIndices = residueIndices;
this.keys = keys;
}
}
function getEntityId(hierarchy: AtomicHierarchy, ids: ArrayLike<string>, asym_id: string) {
for (let i = 0, _i = ids.length; i < _i; i++) {
if (hierarchy.findChainKey(ids[i], asym_id) >= 0) return i;
}
return -1;
}
export { ModifiedResidues }
\ No newline at end of file
......@@ -15,6 +15,7 @@ import { SecondaryStructure } from './properties/seconday-structure';
//import from_gro from './formats/gro'
import from_mmCIF from './formats/mmcif'
import { ModifiedResidues } from './formats/mmcif/modified-residues';
/**
* Interface to the "source data" of the molecule.
......@@ -37,7 +38,11 @@ interface Model extends Readonly<{
atomicConformation: AtomicConformation,
/** Various parts of the code can "cache" custom properties here */
properties: { readonly secondaryStructure: SecondaryStructure } & { [customName: string]: any },
properties: {
readonly secondaryStructure: SecondaryStructure,
readonly modifiedResidues: ModifiedResidues,
[customName: string]: any
},
coarseHierarchy: CoarseHierarchy,
coarseConformation: CoarseConformation
......
......@@ -65,7 +65,9 @@ export interface AtomicKeys {
// also index to the Entities table.
entityKey: ArrayLike<number>,
findChainKey(entityId: string, label_asym_id: string): number
findChainKey(entityId: string, label_asym_id: string): number,
/** Unique number for each of the residue. Also the index of the 1st occurence of this residue. */
findResidueKey(entityId: string, label_asym_id: string, label_comp_id: string, auth_seq_id: number, pdbx_PDB_ins_code: string): number
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment