Просмотр исходного кода

nucleotide cartoon, detect Purin/Pyrimidin from geometry

Alexander Rose 5 лет назад
Родитель
Сommit
0810ed411d

+ 2 - 2
src/mol-model/structure/model/types.ts

@@ -178,11 +178,11 @@ export const AminoAcidNames = new Set([
 export const RnaBaseNames = new Set([ 'A', 'C', 'T', 'G', 'I', 'U' ])
 export const DnaBaseNames = new Set([ 'DA', 'DC', 'DT', 'DG', 'DI', 'DU' ])
 export const PeptideBaseNames = new Set([ 'APN', 'CPN', 'TPN', 'GPN' ])
-export const PurinBaseNames = new Set([ 'A', 'G', 'DA', 'DG', 'DI', 'APN', 'GPN' ])
+export const PurineBaseNames = new Set([ 'A', 'G', 'DA', 'DG', 'DI', 'APN', 'GPN' ])
 export const PyrimidineBaseNames = new Set([ 'C', 'T', 'U', 'DC', 'DT', 'DU', 'CPN', 'TPN' ])
 export const BaseNames = SetUtils.unionMany(RnaBaseNames, DnaBaseNames, PeptideBaseNames)
 
-export const isPurinBase = (compId: string) => PurinBaseNames.has(compId.toUpperCase())
+export const isPurineBase = (compId: string) => PurineBaseNames.has(compId.toUpperCase())
 export const isPyrimidineBase = (compId: string) => PyrimidineBaseNames.has(compId.toUpperCase())
 
 /** get the molecule type from component type and id */

+ 17 - 3
src/mol-repr/structure/visual/nucleotide-block-mesh.ts

@@ -14,7 +14,7 @@ import { Mesh } from '../../../mol-geo/geometry/mesh/mesh';
 import { MeshBuilder } from '../../../mol-geo/geometry/mesh/mesh-builder';
 import { Segmentation } from '../../../mol-data/int';
 import { CylinderProps } from '../../../mol-geo/primitive/cylinder';
-import { isNucleic, isPurinBase, isPyrimidineBase } from '../../../mol-model/structure/model/types';
+import { isNucleic, isPurineBase, isPyrimidineBase } from '../../../mol-model/structure/model/types';
 import { addCylinder } from '../../../mol-geo/geometry/mesh/builder/cylinder';
 import { UnitsMeshParams, UnitsVisual, UnitsMeshVisual } from '../units-visual';
 import { NucleotideLocationIterator, getNucleotideElementLoci, eachNucleotideElement } from './util/nucleotide';
@@ -78,7 +78,21 @@ function createNucleotideBlockMesh(ctx: VisualContext, unit: Unit, structure: St
                 let idx1: ElementIndex | -1 = -1, idx2: ElementIndex | -1 = -1, idx3: ElementIndex | -1 = -1, idx4: ElementIndex | -1 = -1, idx5: ElementIndex | -1 = -1, idx6: ElementIndex | -1 = -1
                 let width = 4.5, height = 4.5, depth = 2.5 * sizeFactor
 
-                if (isPurinBase(compId)) {
+                let isPurine = isPurineBase(compId)
+                let isPyrimidine = isPyrimidineBase(compId)
+
+                if (!isPurine && !isPyrimidine) {
+                    // detect Purine or Pyrimidin based on geometry
+                    const idxC4 = atomicIndex.findAtomOnResidue(residueIndex, 'C4')
+                    const idxN9 = atomicIndex.findAtomOnResidue(residueIndex, 'N9')
+                    if (idxC4 !== -1 && idxN9 !== -1 && Vec3.distance(pos(idxC4, p1), pos(idxN9, p2)) < 1.6) {
+                        isPurine = true
+                    } else {
+                        isPyrimidine = true
+                    }
+                }
+
+                if (isPurine) {
                     height = 4.5
                     idx1 = atomicIndex.findAtomOnResidue(residueIndex, 'N1')
                     idx2 = atomicIndex.findAtomOnResidue(residueIndex, 'C4')
@@ -86,7 +100,7 @@ function createNucleotideBlockMesh(ctx: VisualContext, unit: Unit, structure: St
                     idx4 = atomicIndex.findAtomOnResidue(residueIndex, 'C2')
                     idx5 = atomicIndex.findAtomOnResidue(residueIndex, 'N9')
                     idx6 = traceElementIndex[residueIndex]
-                } else if (isPyrimidineBase(compId)) {
+                } else if (isPyrimidine) {
                     height = 3.0
                     idx1 = atomicIndex.findAtomOnResidue(residueIndex, 'N3')
                     idx2 = atomicIndex.findAtomOnResidue(residueIndex, 'C6')

+ 17 - 3
src/mol-repr/structure/visual/nucleotide-ring-mesh.ts

@@ -14,7 +14,7 @@ import { Mesh } from '../../../mol-geo/geometry/mesh/mesh';
 import { MeshBuilder } from '../../../mol-geo/geometry/mesh/mesh-builder';
 import { Segmentation } from '../../../mol-data/int';
 import { CylinderProps } from '../../../mol-geo/primitive/cylinder';
-import { isNucleic, isPurinBase, isPyrimidineBase } from '../../../mol-model/structure/model/types';
+import { isNucleic, isPurineBase, isPyrimidineBase } from '../../../mol-model/structure/model/types';
 import { addCylinder } from '../../../mol-geo/geometry/mesh/builder/cylinder';
 import { addSphere } from '../../../mol-geo/geometry/mesh/builder/sphere';
 import { UnitsMeshParams, UnitsVisual, UnitsMeshVisual } from '../units-visual';
@@ -101,7 +101,21 @@ function createNucleotideRingMesh(ctx: VisualContext, unit: Unit, structure: Str
 
                 builderState.currentGroup = i
 
-                if (isPurinBase(compId)) {
+                let isPurine = isPurineBase(compId)
+                let isPyrimidine = isPyrimidineBase(compId)
+
+                if (!isPurine && !isPyrimidine) {
+                    // detect Purine or Pyrimidin based on geometry
+                    const idxC4 = atomicIndex.findAtomOnResidue(residueIndex, 'C4')
+                    const idxN9 = atomicIndex.findAtomOnResidue(residueIndex, 'N9')
+                    if (idxC4 !== -1 && idxN9 !== -1 && Vec3.distance(pos(idxC4, pC4), pos(idxN9, pN9)) < 1.6) {
+                        isPurine = true
+                    } else {
+                        isPyrimidine = true
+                    }
+                }
+
+                if (isPurine) {
                     idxTrace = traceElementIndex[residueIndex]
                     idxN1 = atomicIndex.findAtomOnResidue(residueIndex, 'N1')
                     idxC2 = atomicIndex.findAtomOnResidue(residueIndex, 'C2')
@@ -131,7 +145,7 @@ function createNucleotideRingMesh(ctx: VisualContext, unit: Unit, structure: Str
                         MeshBuilder.addTriangleFan(builderState, positionsRing5_6, fanIndicesTopRing5_6)
                         MeshBuilder.addTriangleFan(builderState, positionsRing5_6, fanIndicesBottomRing5_6)
                     }
-                } else if (isPyrimidineBase(compId)) {
+                } else if (isPyrimidine) {
                     idxTrace = traceElementIndex[residueIndex]
                     idxN1 = atomicIndex.findAtomOnResidue(residueIndex, 'N1')
                     idxC2 = atomicIndex.findAtomOnResidue(residueIndex, 'C2')