Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
M
Molstar
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Michal Malý
Molstar
Commits
3b00d25c
Commit
3b00d25c
authored
Mar 27, 2019
by
Sebastian Bittrich
Browse files
Options
Downloads
Patches
Plain Diff
more memory-efficient way to store atom radii
parent
81732b1e
No related branches found
No related tags found
No related merge requests found
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/mol-model/structure/structure/accessible-surface-area.ts
+55
-42
55 additions, 42 deletions
src/mol-model/structure/structure/accessible-surface-area.ts
src/tests/browser/render-structure.ts
+4
-3
4 additions, 3 deletions
src/tests/browser/render-structure.ts
with
59 additions
and
45 deletions
src/mol-model/structure/structure/accessible-surface-area.ts
+
55
−
42
View file @
3b00d25c
...
@@ -14,19 +14,19 @@ import { VdwRadius } from '../model/properties/atomic';
...
@@ -14,19 +14,19 @@ import { VdwRadius } from '../model/properties/atomic';
import
{
isHydrogen
,
getElementIdx
}
from
'
./unit/links/common
'
;
import
{
isHydrogen
,
getElementIdx
}
from
'
./unit/links/common
'
;
namespace
AccessibleSurfaceArea
{
namespace
AccessibleSurfaceArea
{
// Chothia's amino acid atom
s
vdw radii
// Chothia's amino acid
and nucleotide
atom vdw radii
const
trigonalCarbonVdw
=
1.76
;
export
const
VdWLookup
=
[
const
tetrahedralCarbonVdw
=
1.87
;
-
1.0
,
// 0: missing
const
trigonalNitrogenVdw
=
1.65
;
1.76
,
// 1: trigonal C
const
tetrahedralNitrogenVdw
=
1.50
;
1.87
,
// 2: tetrahedral C
// deviating radii from definition in types.ts
1.65
,
// 3: trigonal N
const
oxygenVdw
=
1.40
;
1.50
,
// 4: tetrahedral N
const
sulfurVdw
=
1.85
;
1.40
,
// 5: O
// Chothia's nucleotide atom vdw radii
1.85
,
// 6: S
const
nucCarbonVdw
=
1.80
;
1.80
,
// 7: C (nucleic)
const
nucNitrogenVdw
=
1.60
;
1.60
,
// 8: N (nucleic)
const
nucPhosphorusVdw
=
1.40
;
1.40
// 9: P (nucleic)
export
const
missingValue
=
-
1.0
;
]
// can still be appended on-the-fly for rare elements like selenium
/**
/**
* Adapts the BioJava implementation by Jose Duarte. That implementation is based on the publication by Shrake, A., and
* Adapts the BioJava implementation by Jose Duarte. That implementation is based on the publication by Shrake, A., and
...
@@ -48,7 +48,6 @@ namespace AccessibleSurfaceArea {
...
@@ -48,7 +48,6 @@ namespace AccessibleSurfaceArea {
normalizeAccessibleSurfaceArea
(
ctx
);
normalizeAccessibleSurfaceArea
(
ctx
);
return
{
return
{
atomRadius
:
ctx
.
atomRadius
!
,
accessibleSurfaceArea
:
ctx
.
accessibleSurfaceArea
!
,
accessibleSurfaceArea
:
ctx
.
accessibleSurfaceArea
!
,
relativeAccessibleSurfaceArea
:
ctx
.
relativeAccessibleSurfaceArea
!
,
relativeAccessibleSurfaceArea
:
ctx
.
relativeAccessibleSurfaceArea
!
,
buried
:
(
index
:
number
)
=>
ctx
.
relativeAccessibleSurfaceArea
!
[
index
]
<
0.16
// TODO this doesnt seem super elegant
buried
:
(
index
:
number
)
=>
ctx
.
relativeAccessibleSurfaceArea
!
[
index
]
<
0.16
// TODO this doesnt seem super elegant
...
@@ -62,7 +61,7 @@ namespace AccessibleSurfaceArea {
...
@@ -62,7 +61,7 @@ namespace AccessibleSurfaceArea {
spherePoints
:
Vec3
[],
spherePoints
:
Vec3
[],
cons
:
number
,
cons
:
number
,
maxLookupRadius
:
number
,
maxLookupRadius
:
number
,
atomRadius
?:
Float32Array
,
// TODO there are only 5-10 unique values in this array - rather than storing values, a int pointing to a dictionary will be far more memory efficient
atomRadius
?:
Int8Array
,
accessibleSurfaceArea
?:
Float32Array
,
accessibleSurfaceArea
?:
Float32Array
,
relativeAccessibleSurfaceArea
?:
Float32Array
relativeAccessibleSurfaceArea
?:
Float32Array
}
}
...
@@ -98,14 +97,13 @@ namespace AccessibleSurfaceArea {
...
@@ -98,14 +97,13 @@ namespace AccessibleSurfaceArea {
for
(
let
aI
=
0
;
aI
<
atomCount
;
++
aI
)
{
for
(
let
aI
=
0
;
aI
<
atomCount
;
++
aI
)
{
if
(
aI
%
10000
===
0
)
{
if
(
aI
%
10000
===
0
)
{
console
.
log
(
`calculating accessible surface area, current:
${
aI
}
, max:
${
atomCount
}
`
);
if
(
ctx
.
rtctx
.
shouldUpdate
)
{
if
(
ctx
.
rtctx
.
shouldUpdate
)
{
await
ctx
.
rtctx
.
update
({
message
:
'
calculating accessible surface area
'
,
current
:
aI
,
max
:
atomCount
});
await
ctx
.
rtctx
.
update
({
message
:
'
calculating accessible surface area
'
,
current
:
aI
,
max
:
atomCount
});
}
}
}
}
const
radius1
=
atomRadius
!
[
aI
];
const
radius1
=
VdWLookup
[
atomRadius
!
[
aI
]
]
;
if
(
radius1
===
missingValue
)
continue
;
if
(
radius1
===
VdWLookup
[
0
]
)
continue
;
// pre-filter by lookup3d
// pre-filter by lookup3d
// 36275 ms - lookup ~3000 ms
// 36275 ms - lookup ~3000 ms
...
@@ -116,8 +114,8 @@ namespace AccessibleSurfaceArea {
...
@@ -116,8 +114,8 @@ namespace AccessibleSurfaceArea {
const
neighbors
=
[];
const
neighbors
=
[];
for
(
let
iI
=
0
;
iI
<
count
;
++
iI
)
{
for
(
let
iI
=
0
;
iI
<
count
;
++
iI
)
{
const
bI
=
units
[
iI
].
elements
[
indices
[
iI
]];
const
bI
=
units
[
iI
].
elements
[
indices
[
iI
]];
const
radius2
=
atomRadius
!
[
bI
];
const
radius2
=
VdWLookup
[
atomRadius
!
[
bI
]
]
;
if
(
aI
===
bI
||
radius2
===
missingValue
)
continue
;
if
(
aI
===
bI
||
radius2
===
VdWLookup
[
0
]
)
continue
;
const
cutoff2
=
(
cutoff1
+
radius2
)
*
(
cutoff1
+
radius2
);
const
cutoff2
=
(
cutoff1
+
radius2
)
*
(
cutoff1
+
radius2
);
if
(
squaredDistances
[
iI
]
<
cutoff2
)
{
if
(
squaredDistances
[
iI
]
<
cutoff2
)
{
...
@@ -137,7 +135,8 @@ namespace AccessibleSurfaceArea {
...
@@ -137,7 +135,8 @@ namespace AccessibleSurfaceArea {
for
(
let
_nI
=
0
;
_nI
<
neighbors
.
length
;
++
_nI
)
{
for
(
let
_nI
=
0
;
_nI
<
neighbors
.
length
;
++
_nI
)
{
const
nI
=
neighbors
[
_nI
];
const
nI
=
neighbors
[
_nI
];
position
(
nI
,
bPos
);
position
(
nI
,
bPos
);
const
cutoff3
=
(
atomRadius
!
[
nI
]
+
probeSize
!
)
*
(
atomRadius
!
[
nI
]
+
probeSize
!
);
const
radius3
=
VdWLookup
[
atomRadius
!
[
nI
]];
const
cutoff3
=
(
radius3
+
probeSize
!
)
*
(
radius3
+
probeSize
!
);
if
(
Vec3
.
squaredDistance
(
testPoint
,
bPos
)
<
cutoff3
)
{
if
(
Vec3
.
squaredDistance
(
testPoint
,
bPos
)
<
cutoff3
)
{
accessible
=
false
;
accessible
=
false
;
break
;
break
;
...
@@ -161,7 +160,7 @@ namespace AccessibleSurfaceArea {
...
@@ -161,7 +160,7 @@ namespace AccessibleSurfaceArea {
const
residueCount
=
moleculeType
.
length
;
const
residueCount
=
moleculeType
.
length
;
// with atom and residue count at hand: initialize arrays
// with atom and residue count at hand: initialize arrays
ctx
.
atomRadius
=
new
Float32
Array
(
atomCount
-
1
);
ctx
.
atomRadius
=
new
Int8
Array
(
atomCount
-
1
);
ctx
.
accessibleSurfaceArea
=
new
Float32Array
(
residueCount
-
1
);
ctx
.
accessibleSurfaceArea
=
new
Float32Array
(
residueCount
-
1
);
ctx
.
relativeAccessibleSurfaceArea
=
new
Float32Array
(
residueCount
-
1
);
ctx
.
relativeAccessibleSurfaceArea
=
new
Float32Array
(
residueCount
-
1
);
...
@@ -171,7 +170,7 @@ namespace AccessibleSurfaceArea {
...
@@ -171,7 +170,7 @@ namespace AccessibleSurfaceArea {
const
elementIdx
=
getElementIdx
(
element
);
const
elementIdx
=
getElementIdx
(
element
);
// skip hydrogen atoms
// skip hydrogen atoms
if
(
isHydrogen
(
elementIdx
))
{
if
(
isHydrogen
(
elementIdx
))
{
ctx
.
atomRadius
[
aI
]
=
missingValue
;
ctx
.
atomRadius
[
aI
]
=
VdWLookup
[
0
]
;
continue
;
continue
;
}
}
...
@@ -179,7 +178,7 @@ namespace AccessibleSurfaceArea {
...
@@ -179,7 +178,7 @@ namespace AccessibleSurfaceArea {
// skip non-polymer groups
// skip non-polymer groups
if
(
!
ctx
.
params
.
nonPolymer
)
{
if
(
!
ctx
.
params
.
nonPolymer
)
{
if
(
!
isPolymer
(
residueType
))
{
if
(
!
isPolymer
(
residueType
))
{
ctx
.
atomRadius
[
aI
]
=
missingValue
;
ctx
.
atomRadius
[
aI
]
=
VdWLookup
[
0
]
;
continue
;
continue
;
}
}
}
}
...
@@ -196,7 +195,7 @@ namespace AccessibleSurfaceArea {
...
@@ -196,7 +195,7 @@ namespace AccessibleSurfaceArea {
}
else
if
(
residueType
===
MoleculeType
.
protein
)
{
}
else
if
(
residueType
===
MoleculeType
.
protein
)
{
ctx
.
atomRadius
[
aI
]
=
determineRadiusAmino
(
atomId
,
element
,
compId
);
ctx
.
atomRadius
[
aI
]
=
determineRadiusAmino
(
atomId
,
element
,
compId
);
}
else
{
}
else
{
ctx
.
atomRadius
[
aI
]
=
VdwRadius
(
element
);
ctx
.
atomRadius
[
aI
]
=
handleNonStandardCase
(
element
);
}
}
}
}
}
}
...
@@ -209,43 +208,58 @@ namespace AccessibleSurfaceArea {
...
@@ -209,43 +208,58 @@ namespace AccessibleSurfaceArea {
function
determineRadiusAmino
(
atomId
:
string
,
element
:
ElementSymbol
,
compId
:
string
):
number
{
function
determineRadiusAmino
(
atomId
:
string
,
element
:
ElementSymbol
,
compId
:
string
):
number
{
switch
(
element
)
{
switch
(
element
)
{
case
'
O
'
:
case
'
O
'
:
return
oxygenVdw
;
return
5
;
case
'
S
'
:
case
'
S
'
:
return
sulfurVdw
;
return
6
;
case
'
N
'
:
case
'
N
'
:
return
atomId
===
'
NZ
'
?
tetrahedralNitrogenVdw
:
trigonalNitrogenVdw
;
return
atomId
===
'
NZ
'
?
4
:
3
;
case
'
C
'
:
case
'
C
'
:
switch
(
atomId
)
{
switch
(
atomId
)
{
case
'
C
'
:
case
'
CE1
'
:
case
'
CE2
'
:
case
'
CE3
'
:
case
'
CH2
'
:
case
'
CZ
'
:
case
'
CZ2
'
:
case
'
CZ3
'
:
case
'
C
'
:
case
'
CE1
'
:
case
'
CE2
'
:
case
'
CE3
'
:
case
'
CH2
'
:
case
'
CZ
'
:
case
'
CZ2
'
:
case
'
CZ3
'
:
return
trigonalCarbonVdw
;
return
1
;
case
'
CA
'
:
case
'
CB
'
:
case
'
CE
'
:
case
'
CG1
'
:
case
'
CG2
'
:
case
'
CA
'
:
case
'
CB
'
:
case
'
CE
'
:
case
'
CG1
'
:
case
'
CG2
'
:
return
tetrahedralCarbonVdw
;
return
2
;
default
:
default
:
switch
(
compId
)
{
switch
(
compId
)
{
case
'
PHE
'
:
case
'
TRP
'
:
case
'
TYR
'
:
case
'
HIS
'
:
case
'
ASP
'
:
case
'
ASN
'
:
case
'
PHE
'
:
case
'
TRP
'
:
case
'
TYR
'
:
case
'
HIS
'
:
case
'
ASP
'
:
case
'
ASN
'
:
return
trigonalCarbonVdw
;
return
1
;
case
'
PRO
'
:
case
'
LYS
'
:
case
'
ARG
'
:
case
'
MET
'
:
case
'
ILE
'
:
case
'
LEU
'
:
case
'
PRO
'
:
case
'
LYS
'
:
case
'
ARG
'
:
case
'
MET
'
:
case
'
ILE
'
:
case
'
LEU
'
:
return
tetrahedralCarbonVdw
;
return
2
;
case
'
GLU
'
:
case
'
GLN
'
:
case
'
GLU
'
:
case
'
GLN
'
:
return
atomId
===
'
CD
'
?
trigonalCarbonVdw
:
tetrahedralCarbonVdw
;
return
atomId
===
'
CD
'
?
1
:
2
;
}
}
}
}
}
}
return
VdwRadius
(
element
);
return
handleNonStandardCase
(
element
);
}
}
function
determineRadiusNucl
(
atomId
:
string
,
element
:
ElementSymbol
,
compId
:
string
):
number
{
function
determineRadiusNucl
(
atomId
:
string
,
element
:
ElementSymbol
,
compId
:
string
):
number
{
switch
(
element
)
{
switch
(
element
)
{
case
'
C
'
:
case
'
C
'
:
return
nucCarbonVdw
;
return
7
;
case
'
N
'
:
case
'
N
'
:
return
nucNitrogenVdw
;
return
8
;
case
'
P
'
:
case
'
P
'
:
return
nucPhosphorusVdw
;
return
9
;
case
'
O
'
:
case
'
O
'
:
return
oxygenVdw
;
return
5
;
}
}
return
VdwRadius
(
element
);
return
handleNonStandardCase
(
element
);
}
function
handleNonStandardCase
(
element
:
ElementSymbol
):
number
{
const
radius
=
VdwRadius
(
element
);
let
index
=
VdWLookup
.
indexOf
(
radius
);
console
.
log
(
radius
);
console
.
log
(
index
);
console
.
log
(
VdWLookup
);
if
(
index
===
-
1
)
{
// add novel value to lookup array
console
.
log
(
`novel value
${
radius
}
for
${
element
}
`
)
index
=
VdWLookup
.
length
;
VdWLookup
[
index
]
=
radius
;
}
return
index
;
}
}
function
initialize
(
rtctx
:
RuntimeContext
,
structure
:
Structure
,
params
:
Partial
<
PD
.
Values
<
AccessibleSurfaceAreaComputationParams
>>
):
AccessibleSurfaceAreaContext
{
function
initialize
(
rtctx
:
RuntimeContext
,
structure
:
Structure
,
params
:
Partial
<
PD
.
Values
<
AccessibleSurfaceAreaComputationParams
>>
):
AccessibleSurfaceAreaContext
{
...
@@ -255,7 +269,7 @@ namespace AccessibleSurfaceArea {
...
@@ -255,7 +269,7 @@ namespace AccessibleSurfaceArea {
params
:
params
,
params
:
params
,
spherePoints
:
generateSpherePoints
(
params
.
numberOfSpherePoints
!
),
spherePoints
:
generateSpherePoints
(
params
.
numberOfSpherePoints
!
),
cons
:
4.0
*
Math
.
PI
/
params
.
numberOfSpherePoints
!
,
cons
:
4.0
*
Math
.
PI
/
params
.
numberOfSpherePoints
!
,
maxLookupRadius
:
2
*
params
.
probeSize
!
+
2
*
tetrahedralCarbonVdw
// 2x probe size + 2x largest VdW
maxLookupRadius
:
2
*
params
.
probeSize
!
+
2
*
VdWLookup
[
2
]
// 2x probe size + 2x largest VdW
}
}
}
}
...
@@ -318,7 +332,6 @@ namespace AccessibleSurfaceArea {
...
@@ -318,7 +332,6 @@ namespace AccessibleSurfaceArea {
}
}
interface
AccessibleSurfaceArea
{
interface
AccessibleSurfaceArea
{
readonly
atomRadius
?:
ArrayLike
<
number
>
readonly
accessibleSurfaceArea
?:
ArrayLike
<
number
>
readonly
accessibleSurfaceArea
?:
ArrayLike
<
number
>
readonly
relativeAccessibleSurfaceArea
?:
ArrayLike
<
number
>
readonly
relativeAccessibleSurfaceArea
?:
ArrayLike
<
number
>
buried
(
index
:
number
):
boolean
buried
(
index
:
number
):
boolean
...
...
This diff is collapsed.
Click to expand it.
src/tests/browser/render-structure.ts
+
4
−
3
View file @
3b00d25c
...
@@ -69,9 +69,10 @@ function getCartoonRepr() {
...
@@ -69,9 +69,10 @@ function getCartoonRepr() {
let
accessibleSurfaceArea
:
AccessibleSurfaceArea
;
let
accessibleSurfaceArea
:
AccessibleSurfaceArea
;
async
function
init
(
props
=
{})
{
async
function
init
(
props
=
{})
{
const
cif
=
await
downloadFromPdb
(
const
cif
=
await
downloadFromPdb
(
'
3j3q
'
//
'3j3q'
//
'1aon'
'
1aon
'
// '1acj'
// '1acj'
// '1pga'
)
)
const
models
=
await
getModels
(
cif
)
const
models
=
await
getModels
(
cif
)
const
structure
=
await
getStructure
(
models
[
0
])
const
structure
=
await
getStructure
(
models
[
0
])
...
@@ -117,7 +118,7 @@ export function AccessibleSurfaceAreaColorTheme(ctx: ThemeDataContext, props: PD
...
@@ -117,7 +118,7 @@ export function AccessibleSurfaceAreaColorTheme(ctx: ThemeDataContext, props: PD
if
(
StructureElement
.
isLocation
(
location
))
{
if
(
StructureElement
.
isLocation
(
location
))
{
if
(
Unit
.
isAtomic
(
location
.
unit
))
{
if
(
Unit
.
isAtomic
(
location
.
unit
))
{
const
value
=
accessibleSurfaceArea
.
relativeAccessibleSurfaceArea
!
[
location
.
unit
.
residueIndex
[
location
.
element
]];
const
value
=
accessibleSurfaceArea
.
relativeAccessibleSurfaceArea
!
[
location
.
unit
.
residueIndex
[
location
.
element
]];
return
value
!==
AccessibleSurfaceArea
.
missing
V
alue
?
scale
.
color
(
value
)
:
DefaultColor
;
return
value
!==
AccessibleSurfaceArea
.
VdWLookup
[
0
]
/* signals
missing
v
alue
*/
?
scale
.
color
(
value
)
:
DefaultColor
;
}
}
}
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment