diff --git a/src/mol-model/structure/structure/accessible-surface-area.ts b/src/mol-model/structure/structure/accessible-surface-area.ts
index c11da06d205fdd96e54578e7c7cc24c3163ebce0..9230353d56d458773627a54ad83e7420f80afe02 100644
--- a/src/mol-model/structure/structure/accessible-surface-area.ts
+++ b/src/mol-model/structure/structure/accessible-surface-area.ts
@@ -14,19 +14,19 @@ import { VdwRadius } from '../model/properties/atomic';
 import { isHydrogen, getElementIdx } from './unit/links/common';
 
 namespace AccessibleSurfaceArea {
-    // Chothia's amino acid atoms vdw radii
-    const trigonalCarbonVdw = 1.76;
-    const tetrahedralCarbonVdw = 1.87;
-    const trigonalNitrogenVdw = 1.65;
-    const tetrahedralNitrogenVdw = 1.50;
-    // deviating radii from definition in types.ts
-    const oxygenVdw = 1.40;
-    const sulfurVdw = 1.85;
-    // Chothia's nucleotide atom vdw radii
-    const nucCarbonVdw = 1.80;
-    const nucNitrogenVdw = 1.60;
-    const nucPhosphorusVdw = 1.40;
-    export const missingValue = -1.0;
+    // Chothia's amino acid and nucleotide atom vdw radii
+    export const VdWLookup = [
+        -1.0, // 0: missing
+        1.76, // 1: trigonal C
+        1.87, // 2: tetrahedral C
+        1.65, // 3: trigonal N
+        1.50, // 4: tetrahedral N
+        1.40, // 5: O
+        1.85, // 6: S
+        1.80, // 7: C (nucleic)
+        1.60, // 8: N (nucleic)
+        1.40  // 9: P (nucleic)
+    ] // 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
@@ -48,7 +48,6 @@ namespace AccessibleSurfaceArea {
         normalizeAccessibleSurfaceArea(ctx);
 
         return {
-            atomRadius: ctx.atomRadius!,
             accessibleSurfaceArea: ctx.accessibleSurfaceArea!,
             relativeAccessibleSurfaceArea: ctx.relativeAccessibleSurfaceArea!,
             buried: (index: number) => ctx.relativeAccessibleSurfaceArea![index] < 0.16 // TODO this doesnt seem super elegant
@@ -62,7 +61,7 @@ namespace AccessibleSurfaceArea {
         spherePoints: Vec3[],
         cons: 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,
         relativeAccessibleSurfaceArea?: Float32Array
     }
@@ -98,14 +97,13 @@ namespace AccessibleSurfaceArea {
 
         for (let aI = 0; aI < atomCount; ++aI) {
             if (aI % 10000 === 0) {
-                console.log(`calculating accessible surface area, current: ${ aI }, max: ${ atomCount }`);
                 if (ctx.rtctx.shouldUpdate) {
                     await ctx.rtctx.update({ message: 'calculating accessible surface area', current: aI, max: atomCount });
                 }
             }
 
-            const radius1 = atomRadius![aI];
-            if (radius1 === missingValue) continue;
+            const radius1 = VdWLookup[atomRadius![aI]];
+            if (radius1 === VdWLookup[0]) continue;
 
             // pre-filter by lookup3d
             // 36275 ms - lookup ~3000 ms
@@ -116,8 +114,8 @@ namespace AccessibleSurfaceArea {
             const neighbors = [];
             for (let iI = 0; iI < count; ++iI) {
                 const bI = units[iI].elements[indices[iI]];
-                const radius2 = atomRadius![bI];
-                if (aI === bI || radius2 === missingValue) continue;
+                const radius2 = VdWLookup[atomRadius![bI]];
+                if (aI === bI || radius2 === VdWLookup[0]) continue;
 
                 const cutoff2 = (cutoff1 + radius2) * (cutoff1 + radius2);
                 if (squaredDistances[iI] < cutoff2) {
@@ -137,7 +135,8 @@ namespace AccessibleSurfaceArea {
                 for (let _nI = 0; _nI < neighbors.length; ++_nI) {
                     const nI = neighbors[_nI];
                     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) {
                         accessible = false;
                         break;
@@ -161,7 +160,7 @@ namespace AccessibleSurfaceArea {
         const residueCount = moleculeType.length;
 
         // with atom and residue count at hand: initialize arrays
-        ctx.atomRadius = new Float32Array(atomCount - 1);
+        ctx.atomRadius = new Int8Array(atomCount - 1);
         ctx.accessibleSurfaceArea = new Float32Array(residueCount - 1);
         ctx.relativeAccessibleSurfaceArea = new Float32Array(residueCount - 1);
 
@@ -171,7 +170,7 @@ namespace AccessibleSurfaceArea {
             const elementIdx = getElementIdx(element);
             // skip hydrogen atoms
             if (isHydrogen(elementIdx)) {
-                ctx.atomRadius[aI] = missingValue;
+                ctx.atomRadius[aI] = VdWLookup[0];
                 continue;
             }
 
@@ -179,7 +178,7 @@ namespace AccessibleSurfaceArea {
             // skip non-polymer groups
             if (!ctx.params.nonPolymer) {
                 if (!isPolymer(residueType)) {
-                    ctx.atomRadius[aI] = missingValue;
+                    ctx.atomRadius[aI] = VdWLookup[0];
                     continue;
                 }
             }
@@ -192,11 +191,11 @@ namespace AccessibleSurfaceArea {
             if (parentId !== void 0) compId = parentId;
 
             if (isNucleic(residueType)) {
-                ctx.atomRadius[aI] = determineRadiusNucl(atomId, element, compId);
+                 ctx.atomRadius[aI] = determineRadiusNucl(atomId, element, compId);
             } else if (residueType === MoleculeType.protein) {
                 ctx.atomRadius[aI] = determineRadiusAmino(atomId, element, compId);
             } else {
-                ctx.atomRadius[aI] = VdwRadius(element);
+                ctx.atomRadius[aI] = handleNonStandardCase(element);
             }
         }
     }
@@ -209,43 +208,58 @@ namespace AccessibleSurfaceArea {
     function determineRadiusAmino(atomId: string, element: ElementSymbol, compId: string): number {
         switch (element) {
             case 'O':
-            return oxygenVdw;
+            return 5;
             case 'S':
-            return sulfurVdw;
+            return 6;
             case 'N':
-            return atomId === 'NZ' ? tetrahedralNitrogenVdw : trigonalNitrogenVdw;
+            return atomId === 'NZ' ? 4 : 3;
             case 'C':
             switch (atomId) {
                 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':
-                return tetrahedralCarbonVdw;
+                return 2;
                 default:
                 switch (compId) {
                     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':
-                    return tetrahedralCarbonVdw;
+                    return 2;
                     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 {
         switch (element) {
             case 'C':
-            return nucCarbonVdw;
+            return 7;
             case 'N':
-            return nucNitrogenVdw;
+            return 8;
             case 'P':
-            return nucPhosphorusVdw;
+            return 9;
             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 {
@@ -255,7 +269,7 @@ namespace AccessibleSurfaceArea {
             params: params,
             spherePoints: generateSpherePoints(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 {
 }
 
 interface AccessibleSurfaceArea {
-    readonly atomRadius?: ArrayLike<number>
     readonly accessibleSurfaceArea?: ArrayLike<number>
     readonly relativeAccessibleSurfaceArea?: ArrayLike<number>
     buried(index: number): boolean
diff --git a/src/tests/browser/render-structure.ts b/src/tests/browser/render-structure.ts
index b7d9dfb2a50819ae760c46c496f3b9ade80f09be..3e951187cd711c52c7876db088a9bda17db208d3 100644
--- a/src/tests/browser/render-structure.ts
+++ b/src/tests/browser/render-structure.ts
@@ -69,9 +69,10 @@ function getCartoonRepr() {
 let accessibleSurfaceArea: AccessibleSurfaceArea;
 async function init(props = {}) {
     const cif = await downloadFromPdb(
-        '3j3q'
-        // '1aon'
+        // '3j3q'
+        '1aon'
         // '1acj'
+        // '1pga'
         )
     const models = await getModels(cif)
     const structure = await getStructure(models[0])
@@ -117,7 +118,7 @@ export function AccessibleSurfaceAreaColorTheme(ctx: ThemeDataContext, props: PD
         if (StructureElement.isLocation(location)) {
             if (Unit.isAtomic(location.unit)) {
                 const value = accessibleSurfaceArea.relativeAccessibleSurfaceArea![location.unit.residueIndex[location.element]];
-                return value !== AccessibleSurfaceArea.missingValue ? scale.color(value) : DefaultColor;
+                return value !== AccessibleSurfaceArea.VdWLookup[0] /* signals missing value */ ? scale.color(value) : DefaultColor;
             }
         }