Skip to content
Snippets Groups Projects
Commit d0a861d3 authored by Alexander Rose's avatar Alexander Rose
Browse files

take aromatic rings into account for hydrogen bond calculation

parent 9f7b96c7
Branches
No related tags found
No related merge requests found
...@@ -68,8 +68,11 @@ function addUnitHydrogenDonors(structure: Structure, unit: Unit.Atomic, builder: ...@@ -68,8 +68,11 @@ function addUnitHydrogenDonors(structure: Structure, unit: Unit.Atomic, builder:
const { totalH } = getUnitValenceModel(structure, unit) const { totalH } = getUnitValenceModel(structure, unit)
const { elements } = unit const { elements } = unit
const { x, y, z } = unit.model.atomicConformation const { x, y, z } = unit.model.atomicConformation
const { elementAromaticRingIndices } = unit.rings
for (let i = 0 as StructureElement.UnitIndex, il = elements.length; i < il; ++i) { for (let i = 0 as StructureElement.UnitIndex, il = elements.length; i < il; ++i) {
if (elementAromaticRingIndices.has(i)) continue;
const element = typeSymbol(unit, i) const element = typeSymbol(unit, i)
if (( if ((
// include both nitrogen atoms in histidine due to // include both nitrogen atoms in histidine due to
...@@ -99,7 +102,7 @@ function addUnitWeakHydrogenDonors(structure: Structure, unit: Unit.Atomic, buil ...@@ -99,7 +102,7 @@ function addUnitWeakHydrogenDonors(structure: Structure, unit: Unit.Atomic, buil
( (
bondToElementCount(structure, unit, i, Elements.N) > 0 || bondToElementCount(structure, unit, i, Elements.N) > 0 ||
bondToElementCount(structure, unit, i, Elements.O) > 0 || bondToElementCount(structure, unit, i, Elements.O) > 0 ||
inAromaticRingWithElectronNegativeElement(structure, unit, i) inAromaticRingWithElectronNegativeElement(unit, i)
) )
) { ) {
builder.add(FeatureType.WeakHydrogenDonor, FeatureGroup.None, x[elements[i]], y[elements[i]], z[elements[i]], i) builder.add(FeatureType.WeakHydrogenDonor, FeatureGroup.None, x[elements[i]], y[elements[i]], z[elements[i]], i)
...@@ -107,27 +110,21 @@ function addUnitWeakHydrogenDonors(structure: Structure, unit: Unit.Atomic, buil ...@@ -107,27 +110,21 @@ function addUnitWeakHydrogenDonors(structure: Structure, unit: Unit.Atomic, buil
} }
} }
function inAromaticRingWithElectronNegativeElement(structure: Structure, unit: Unit.Atomic, index: StructureElement.UnitIndex) { function inAromaticRingWithElectronNegativeElement(unit: Unit.Atomic, index: StructureElement.UnitIndex) {
return false // TODO const { elementAromaticRingIndices, all } = unit.rings
// if (!a.isAromatic()) return false const ringIndices = elementAromaticRingIndices.get(index)
if (ringIndices === undefined) return false
// const ringData = a.residueType.getRings()
// if (!ringData) return false
// let hasElement = false for (let i = 0, il = ringIndices.length; i < il; ++i) {
// const rings = ringData.rings const ring = all[ringIndices[i]]
// rings.forEach(ring => { for (let j = 0, jl = ring.length; j < jl; ++j) {
// if (hasElement) return // already found one const element = typeSymbol(unit, ring[j])
// if (ring.some(idx => (a.index - a.residueAtomOffset) === idx)) { // in ring if (element === Elements.N || element === Elements.O) {
// hasElement = ring.some(idx => { return true
// const atomTypeId = a.residueType.atomTypeIdList[ idx ] }
// const number = a.atomMap.get(atomTypeId).number }
// return number === Elements.N || number === Elements.O }
// }) return false
// }
// })
// return hasElement
} }
/** /**
...@@ -137,12 +134,15 @@ function addUnitHydrogenAcceptors(structure: Structure, unit: Unit.Atomic, build ...@@ -137,12 +134,15 @@ function addUnitHydrogenAcceptors(structure: Structure, unit: Unit.Atomic, build
const { charge, implicitH, idealGeometry } = getUnitValenceModel(structure, unit) const { charge, implicitH, idealGeometry } = getUnitValenceModel(structure, unit)
const { elements } = unit const { elements } = unit
const { x, y, z } = unit.model.atomicConformation const { x, y, z } = unit.model.atomicConformation
const { elementAromaticRingIndices } = unit.rings
const add = (i: StructureElement.UnitIndex) => { const add = (i: StructureElement.UnitIndex) => {
builder.add(FeatureType.HydrogenAcceptor, FeatureGroup.None, x[elements[i]], y[elements[i]], z[elements[i]], i) builder.add(FeatureType.HydrogenAcceptor, FeatureGroup.None, x[elements[i]], y[elements[i]], z[elements[i]], i)
} }
for (let i = 0 as StructureElement.UnitIndex, il = elements.length; i < il; ++i) { for (let i = 0 as StructureElement.UnitIndex, il = elements.length; i < il; ++i) {
if (elementAromaticRingIndices.has(i)) continue;
const element = typeSymbol(unit, i) const element = typeSymbol(unit, i)
if (element === Elements.O) { if (element === Elements.O) {
// Basically assume all oxygen atoms are acceptors! // Basically assume all oxygen atoms are acceptors!
......
...@@ -25,6 +25,7 @@ class UnitRings { ...@@ -25,6 +25,7 @@ class UnitRings {
private _byFingerprint?: ReadonlyMap<UnitRing.Fingerprint, ReadonlyArray<UnitRings.Index>>; private _byFingerprint?: ReadonlyMap<UnitRing.Fingerprint, ReadonlyArray<UnitRings.Index>>;
private _index?: { private _index?: {
readonly elementRingIndices: ReadonlyMap<StructureElement.UnitIndex, UnitRings.Index[]>, readonly elementRingIndices: ReadonlyMap<StructureElement.UnitIndex, UnitRings.Index[]>,
readonly elementAromaticRingIndices: ReadonlyMap<StructureElement.UnitIndex, UnitRings.Index[]>,
readonly ringComponentIndex: ReadonlyArray<UnitRings.ComponentIndex>, readonly ringComponentIndex: ReadonlyArray<UnitRings.ComponentIndex>,
readonly ringComponents: ReadonlyArray<ReadonlyArray<UnitRings.Index>> readonly ringComponents: ReadonlyArray<ReadonlyArray<UnitRings.Index>>
}; };
...@@ -32,7 +33,7 @@ class UnitRings { ...@@ -32,7 +33,7 @@ class UnitRings {
private get index() { private get index() {
if (this._index) return this._index; if (this._index) return this._index;
this._index = createIndex(this.all); this._index = createIndex(this.all, this.aromaticRings);
return this._index; return this._index;
} }
...@@ -42,11 +43,15 @@ class UnitRings { ...@@ -42,11 +43,15 @@ class UnitRings {
return this._byFingerprint; return this._byFingerprint;
} }
/** Maps atom index inside a Unit to the smallest ring index (an atom can be part of more than one ring) */ /** Maps atom index inside a Unit to ring indices (an atom can be part of more than one ring) */
get elementRingIndices() { get elementRingIndices() {
return this.index.elementRingIndices; return this.index.elementRingIndices;
} }
get elementAromaticRingIndices() {
return this.index.elementAromaticRingIndices;
}
/** Maps UnitRings.Index to index to ringComponents */ /** Maps UnitRings.Index to index to ringComponents */
get ringComponentIndex() { get ringComponentIndex() {
return this.index.ringComponentIndex; return this.index.ringComponentIndex;
......
...@@ -253,8 +253,9 @@ function buildFinderprint(elements: string[], offset: number) { ...@@ -253,8 +253,9 @@ function buildFinderprint(elements: string[], offset: number) {
type RingIndex = import('../rings').UnitRings.Index type RingIndex = import('../rings').UnitRings.Index
type RingComponentIndex = import('../rings').UnitRings.ComponentIndex type RingComponentIndex = import('../rings').UnitRings.ComponentIndex
export function createIndex(rings: ArrayLike<SortedArray<StructureElement.UnitIndex>>) { export function createIndex(rings: ArrayLike<SortedArray<StructureElement.UnitIndex>>, aromaticRings: ReadonlyArray<RingIndex>) {
const elementRingIndices: Map<StructureElement.UnitIndex, RingIndex[]> = new Map(); const elementRingIndices: Map<StructureElement.UnitIndex, RingIndex[]> = new Map();
const elementAromaticRingIndices: Map<StructureElement.UnitIndex, RingIndex[]> = new Map();
// for each ring atom, assign all rings that it is present in // for each ring atom, assign all rings that it is present in
for (let rI = 0 as RingIndex, _rI = rings.length; rI < _rI; rI++) { for (let rI = 0 as RingIndex, _rI = rings.length; rI < _rI; rI++) {
...@@ -266,6 +267,17 @@ export function createIndex(rings: ArrayLike<SortedArray<StructureElement.UnitIn ...@@ -266,6 +267,17 @@ export function createIndex(rings: ArrayLike<SortedArray<StructureElement.UnitIn
} }
} }
// for each ring atom, assign all aromatic rings that it is present in
for (let aI = 0, _aI = aromaticRings.length; aI < _aI; aI++) {
const rI = aromaticRings[aI]
const r = rings[rI];
for (let i = 0, _i = r.length; i < _i; i++) {
const e = r[i];
if (elementAromaticRingIndices.has(e)) elementAromaticRingIndices.get(e)!.push(rI);
else elementAromaticRingIndices.set(e, [rI]);
}
}
// create a graph where vertices are rings, edge if two rings share at least one atom // create a graph where vertices are rings, edge if two rings share at least one atom
const graph = new IntAdjacencyGraph.UniqueEdgeBuilder(rings.length); const graph = new IntAdjacencyGraph.UniqueEdgeBuilder(rings.length);
for (let rI = 0 as RingIndex, _rI = rings.length; rI < _rI; rI++) { for (let rI = 0 as RingIndex, _rI = rings.length; rI < _rI; rI++) {
...@@ -296,5 +308,5 @@ export function createIndex(rings: ArrayLike<SortedArray<StructureElement.UnitIn ...@@ -296,5 +308,5 @@ export function createIndex(rings: ArrayLike<SortedArray<StructureElement.UnitIn
ringComponents[ringComponentIndex[rI]].push(rI); ringComponents[ringComponentIndex[rI]].push(rI);
} }
return { elementRingIndices, ringComponentIndex, ringComponents }; return { elementRingIndices, elementAromaticRingIndices, ringComponentIndex, ringComponents };
} }
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment