diff --git a/src/mol-model/structure/model/types.ts b/src/mol-model/structure/model/types.ts
index b4c65a89d297e18bb9a37790b3c39f7bbbf33904..75bec96914943b8ef01d6627bc188d49ad823d37 100644
--- a/src/mol-model/structure/model/types.ts
+++ b/src/mol-model/structure/model/types.ts
@@ -240,6 +240,10 @@ export function isNucleic(moleculeType: MoleculeType) {
     return moleculeType === MoleculeType.DNA || moleculeType === MoleculeType.RNA || moleculeType === MoleculeType.PNA
 }
 
+export function isProtein(moleculeType: MoleculeType) {
+    return moleculeType === MoleculeType.protein
+}
+
 /**
  * TODO write script that read CCD and outputs list of ion names
  *
diff --git a/src/mol-model/structure/structure/unit.ts b/src/mol-model/structure/structure/unit.ts
index 28869515a8ab573b618a463aaaf92f5b3b84927c..221b858d7af89478519e4273690b10879cbf28f6 100644
--- a/src/mol-model/structure/structure/unit.ts
+++ b/src/mol-model/structure/structure/unit.ts
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2017-2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2017-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
@@ -16,8 +16,7 @@ import StructureElement from './element'
 import { ChainIndex, ResidueIndex, ElementIndex } from '../model/indexing';
 import { IntMap, SortedArray } from 'mol-data/int';
 import { hash2, hashFnv32a } from 'mol-data/util';
-import { getAtomicPolymerElements, getCoarsePolymerElements, getAtomicGapElements, getCoarseGapElements } from './util/polymer';
-import { getNucleotideElements } from './util/nucleotide';
+import { getAtomicPolymerElements, getCoarsePolymerElements, getAtomicGapElements, getCoarseGapElements, getNucleotideElements, getProteinElements } from './util/polymer';
 
 /**
  * A building block of a structure that corresponds to an atomic or
@@ -126,7 +125,7 @@ namespace Unit {
      * together with a tranformation (rotation and translation)
      * that is dynamically applied to the underlying atom set.
      *
-     * An atom set can be referenced by multiple diffrent units which
+     * An atom set can be referenced by multiple different units which
      * makes construction of assemblies and spacegroups very efficient.
      */
     export class Atomic implements Base {
@@ -191,6 +190,12 @@ namespace Unit {
             return this.props.nucleotideElements.ref;
         }
 
+        get proteinElements() {
+            if (this.props.proteinElements.ref) return this.props.proteinElements.ref;
+            this.props.proteinElements.ref = getProteinElements(this);
+            return this.props.proteinElements.ref;
+        }
+
         getResidueIndex(elementIndex: StructureElement.UnitIndex) {
             return this.model.atomicHierarchy.residueAtomSegments.index[this.elements[elementIndex]];
         }
@@ -215,6 +220,7 @@ namespace Unit {
         polymerElements: ValueRef<SortedArray<ElementIndex> | undefined>
         gapElements: ValueRef<SortedArray<ElementIndex> | undefined>
         nucleotideElements: ValueRef<SortedArray<ElementIndex> | undefined>
+        proteinElements: ValueRef<SortedArray<ElementIndex> | undefined>
     }
 
     function AtomicProperties(): AtomicProperties {
@@ -224,7 +230,8 @@ namespace Unit {
             rings: ValueRef.create(void 0),
             polymerElements: ValueRef.create(void 0),
             gapElements: ValueRef.create(void 0),
-            nucleotideElements: ValueRef.create(void 0)
+            nucleotideElements: ValueRef.create(void 0),
+            proteinElements: ValueRef.create(void 0),
         };
     }
 
diff --git a/src/mol-model/structure/structure/util/nucleotide.ts b/src/mol-model/structure/structure/util/nucleotide.ts
deleted file mode 100644
index 0b77d8301c3bcdd4821a7720dd556fa0cecf4ecf..0000000000000000000000000000000000000000
--- a/src/mol-model/structure/structure/util/nucleotide.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author Alexander Rose <alexander.rose@weirdbyte.de>
- */
-
-import { Unit, ElementIndex } from 'mol-model/structure';
-import { Segmentation, SortedArray } from 'mol-data/int';
-import { isNucleic } from 'mol-model/structure/model/types';
-
-export function getNucleotideElements(unit: Unit.Atomic) {
-    const indices: ElementIndex[] = []
-    const { elements, model } = unit
-    const { chainAtomSegments, residueAtomSegments } = model.atomicHierarchy
-    const { moleculeType, traceElementIndex } = model.atomicHierarchy.derived.residue
-    const chainIt = Segmentation.transientSegments(chainAtomSegments, elements)
-    const residueIt = Segmentation.transientSegments(residueAtomSegments, elements)
-    while (chainIt.hasNext) {
-        residueIt.setSegment(chainIt.move());
-
-        while (residueIt.hasNext) {
-            const { index } = residueIt.move();
-
-            if (isNucleic(moleculeType[index])) {
-                const elementIndex = traceElementIndex[index]
-                indices.push(elementIndex === -1 ? residueAtomSegments.offsets[index] : elementIndex)
-            }
-        }
-    }
-    return SortedArray.ofSortedArray<ElementIndex>(indices)
-}
\ No newline at end of file
diff --git a/src/mol-model/structure/structure/util/polymer.ts b/src/mol-model/structure/structure/util/polymer.ts
index 951e74807430044b6ef8fd5903cd2dbb22710c0d..ff60719d4811899e5cf2ccbd1f66333fa0e3293d 100644
--- a/src/mol-model/structure/structure/util/polymer.ts
+++ b/src/mol-model/structure/structure/util/polymer.ts
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
@@ -7,6 +7,7 @@
 import { Unit, ElementIndex } from 'mol-model/structure';
 import { Segmentation, OrderedSet, Interval, SortedArray } from 'mol-data/int';
 import SortedRanges from 'mol-data/int/sorted-ranges';
+import { isNucleic, isProtein } from 'mol-model/structure/model/types';
 
 export function getAtomicPolymerElements(unit: Unit.Atomic) {
     const indices: ElementIndex[] = []
@@ -43,6 +44,8 @@ export function getCoarsePolymerElements(unit: Unit.Spheres | Unit.Gaussians) {
     return SortedArray.ofSortedArray<ElementIndex>(indices)
 }
 
+//
+
 export function getAtomicGapElements(unit: Unit.Atomic) {
     const indices: ElementIndex[] = []
     const { elements, model, residueIndex } = unit
@@ -73,4 +76,50 @@ export function getCoarseGapElements(unit: Unit.Spheres | Unit.Gaussians) {
         indices.push(elements[start], elements[end - 1])
     }
     return SortedArray.ofSortedArray<ElementIndex>(indices)
+}
+
+//
+
+export function getNucleotideElements(unit: Unit.Atomic) {
+    const indices: ElementIndex[] = []
+    const { elements, model } = unit
+    const { chainAtomSegments, residueAtomSegments } = model.atomicHierarchy
+    const { moleculeType, traceElementIndex } = model.atomicHierarchy.derived.residue
+    const chainIt = Segmentation.transientSegments(chainAtomSegments, elements)
+    const residueIt = Segmentation.transientSegments(residueAtomSegments, elements)
+    while (chainIt.hasNext) {
+        residueIt.setSegment(chainIt.move());
+
+        while (residueIt.hasNext) {
+            const { index } = residueIt.move();
+
+            if (isNucleic(moleculeType[index])) {
+                const elementIndex = traceElementIndex[index]
+                indices.push(elementIndex === -1 ? residueAtomSegments.offsets[index] : elementIndex)
+            }
+        }
+    }
+    return SortedArray.ofSortedArray<ElementIndex>(indices)
+}
+
+export function getProteinElements(unit: Unit.Atomic) {
+    const indices: ElementIndex[] = []
+    const { elements, model } = unit
+    const { chainAtomSegments, residueAtomSegments } = model.atomicHierarchy
+    const { moleculeType, traceElementIndex } = model.atomicHierarchy.derived.residue
+    const chainIt = Segmentation.transientSegments(chainAtomSegments, elements)
+    const residueIt = Segmentation.transientSegments(residueAtomSegments, elements)
+    while (chainIt.hasNext) {
+        residueIt.setSegment(chainIt.move());
+
+        while (residueIt.hasNext) {
+            const { index } = residueIt.move();
+
+            if (isProtein(moleculeType[index])) {
+                const elementIndex = traceElementIndex[index]
+                indices.push(elementIndex === -1 ? residueAtomSegments.offsets[index] : elementIndex)
+            }
+        }
+    }
+    return SortedArray.ofSortedArray<ElementIndex>(indices)
 }
\ No newline at end of file
diff --git a/src/mol-repr/structure/visual/util/nucleotide.ts b/src/mol-repr/structure/visual/util/nucleotide.ts
index 8e8ed71d1e3ad7de88cede0d4e6d5000bb6e77ef..f97703e71dd3bce59823b0439fbba85e35bcacbe 100644
--- a/src/mol-repr/structure/visual/util/nucleotide.ts
+++ b/src/mol-repr/structure/visual/util/nucleotide.ts
@@ -5,7 +5,6 @@
  */
 
 import { Unit, StructureElement, Structure } from 'mol-model/structure';
-import { getNucleotideElements } from 'mol-model/structure/structure/util/nucleotide';
 import { Loci, EmptyLoci } from 'mol-model/loci';
 import { OrderedSet, Interval } from 'mol-data/int';
 import { LocationIterator } from 'mol-geo/util/location-iterator';
@@ -16,7 +15,7 @@ import { getResidueLoci } from './common';
 export namespace NucleotideLocationIterator {
     export function fromGroup(group: Unit.SymmetryGroup): LocationIterator {
         const u = group.units[0]
-        const nucleotideElementIndices = Unit.isAtomic(u) ? getNucleotideElements(u) : []
+        const nucleotideElementIndices = Unit.isAtomic(u) ? u.nucleotideElements : []
         const groupCount = nucleotideElementIndices.length
         const instanceCount = group.units.length
         const location = StructureElement.create()