diff --git a/src/mol-model-formats/structure/mmcif/parser.ts b/src/mol-model-formats/structure/mmcif/parser.ts
index 71063f94d82d6df46bdcafa3bc5bb73da9102ba7..bf6d29319dc724efd3ac0596dbb6bd4e8639f439 100644
--- a/src/mol-model-formats/structure/mmcif/parser.ts
+++ b/src/mol-model-formats/structure/mmcif/parser.ts
@@ -24,11 +24,12 @@ import { getSequence } from './sequence';
 import { sortAtomSite } from './sort';
 import { StructConn } from './bonds/struct_conn';
 import { ChemicalComponent } from 'mol-model/structure/model/properties/chemical-component';
-import { getMoleculeType, MoleculeType } from 'mol-model/structure/model/types';
+import { getMoleculeType, MoleculeType, getEntityType } from 'mol-model/structure/model/types';
 import { ModelFormat } from '../format';
 import { SaccharideComponentMap, SaccharideComponent, SaccharidesSnfgMap, SaccharideCompIdMap, UnknownSaccharideComponent } from 'mol-model/structure/structure/carbohydrates/constants';
 import mmCIF_Format = ModelFormat.mmCIF
 import { memoize1 } from 'mol-util/memoize';
+import { ElementIndex } from 'mol-model/structure/model';
 
 export async function _parse_mmCif(format: mmCIF_Format, ctx: RuntimeContext) {
     const formatData = getFormatData(format)
@@ -247,9 +248,50 @@ function findModelEnd(num: Column<number>, startIndex: number) {
     return endIndex;
 }
 
+function getEntities(format: mmCIF_Format): Entities {
+    let entityData: Table<mmCIF_Schema['entity']>
+
+    if (!format.data.entity.id.isDefined) {
+        const entityIds = new Set<string>()
+        const entityList: Partial<Table.Row<mmCIF_Schema['entity']>>[] = []
+
+        const { label_entity_id, label_comp_id } = format.data.atom_site;
+        for (let i = 0 as ElementIndex, il = format.data.atom_site._rowCount; i < il; i++) {
+            const entityId = label_entity_id.value(i);
+            if (!entityIds.has(entityId)) {
+                entityList.push({ id: entityId, type: getEntityType(label_comp_id.value(i)) })
+                entityIds.add(entityId)
+            }
+        }
+
+        const { entity_id: sphere_entity_id } = format.data.ihm_sphere_obj_site;
+        for (let i = 0 as ElementIndex, il = format.data.ihm_sphere_obj_site._rowCount; i < il; i++) {
+            const entityId = sphere_entity_id.value(i);
+            if (!entityIds.has(entityId)) {
+                entityList.push({ id: entityId, type: 'polymer' })
+                entityIds.add(entityId)
+            }
+        }
+
+        const { entity_id: gaussian_entity_id } = format.data.ihm_gaussian_obj_site;
+        for (let i = 0 as ElementIndex, il = format.data.ihm_gaussian_obj_site._rowCount; i < il; i++) {
+            const entityId = gaussian_entity_id.value(i);
+            if (!entityIds.has(entityId)) {
+                entityList.push({ id: entityId, type: 'polymer' })
+                entityIds.add(entityId)
+            }
+        }
+
+        entityData = Table.ofRows(mmCIF_Schema.entity, entityList)
+    } else {
+        entityData = format.data.entity;
+    }
+    return { data: entityData, getEntityIndex: Column.createIndexer(entityData.id) };
+}
+
 async function readStandard(ctx: RuntimeContext, format: mmCIF_Format, formatData: FormatData) {
     const atomCount = format.data.atom_site._rowCount;
-    const entities: Entities = { data: format.data.entity, getEntityIndex: Column.createIndexer(format.data.entity.id) };
+    const entities = getEntities(format)
 
     const models: Model[] = [];
     let modelStart = 0;
@@ -282,13 +324,13 @@ function splitTable<T extends Table<any>>(table: T, col: Column<number>) {
 }
 
 async function readIHM(ctx: RuntimeContext, format: mmCIF_Format, formatData: FormatData) {
-    const { ihm_model_list } = format.data;
-    const entities: Entities = { data: format.data.entity, getEntityIndex: Column.createIndexer(format.data.entity.id) };
-
     if (format.data.atom_site._rowCount && !format.data.atom_site.ihm_model_id.isDefined) {
         throw new Error('expected _atom_site.ihm_model_id to be defined')
     }
 
+    const { ihm_model_list } = format.data;
+    const entities = getEntities(format)
+
     const atom_sites = splitTable(format.data.atom_site, format.data.atom_site.ihm_model_id);
     // TODO: will coarse IHM records require sorting or will we trust it?
     // ==> Probably implement a sort as as well and store the sourceIndex same as with atomSite
diff --git a/src/mol-model/structure/model/types.ts b/src/mol-model/structure/model/types.ts
index 8b5e1b947e970cc7bf8fcb6533801849423e972e..b4c65a89d297e18bb9a37790b3c39f7bbbf33904 100644
--- a/src/mol-model/structure/model/types.ts
+++ b/src/mol-model/structure/model/types.ts
@@ -219,6 +219,19 @@ export function getComponentType(compId: string): mmCIF_Schema['chem_comp']['typ
     }
 }
 
+export function getEntityType(compId: string): mmCIF_Schema['entity']['type']['T'] {
+    compId = compId.toUpperCase()
+    if (AminoAcidNames.has(compId) || RnaBaseNames.has(compId) || DnaBaseNames.has(compId)) {
+        return 'polymer'
+    } else if (SaccharideCompIdMap.has(compId)) {
+        return 'polymer' // TODO will be 'branched' in the future
+    } else if (WaterNames.has(compId)) {
+        return 'water'
+    } else {
+        return 'non-polymer'
+    }
+}
+
 export function isPolymer(moleculeType: MoleculeType) {
     return moleculeType === MoleculeType.protein || moleculeType === MoleculeType.DNA || moleculeType === MoleculeType.RNA || moleculeType === MoleculeType.PNA
 }
diff --git a/src/mol-model/structure/util.ts b/src/mol-model/structure/util.ts
index 87e34b6e024c77874205055fa2b9448981dce467..92069c44452a9d85c8d0c88c62e3cb033614da49 100644
--- a/src/mol-model/structure/util.ts
+++ b/src/mol-model/structure/util.ts
@@ -56,13 +56,13 @@ export function residueLabel(model: Model, rI: number) {
 export function elementLabel(model: Model, index: ElementIndex) {
     const { atoms, residues, chains, residueAtomSegments, chainAtomSegments } = model.atomicHierarchy
     const { label_atom_id } = atoms
-    const { auth_seq_id, auth_comp_id } = residues
+    const { auth_seq_id, label_comp_id } = residues
     const { auth_asym_id } = chains
 
     const residueIndex = residueAtomSegments.index[index]
     const chainIndex = chainAtomSegments.index[residueIndex]
 
-    return `[${auth_comp_id.value(residueIndex)}]${auth_seq_id.value(residueIndex)}:${auth_asym_id.value(chainIndex)}.${label_atom_id.value(index)}`
+    return `[${label_comp_id.value(residueIndex)}]${auth_seq_id.value(residueIndex)}:${auth_asym_id.value(chainIndex)}.${label_atom_id.value(index)}`
 }
 
 // const centerPos = Vec3.zero()
diff --git a/src/mol-plugin/util/structure-labels.ts b/src/mol-plugin/util/structure-labels.ts
index 932569da9046774aca3952c380c7174f7d9f31ca..1ec7fd2b6cbad2d19e840cd72ce2e500380f176e 100644
--- a/src/mol-plugin/util/structure-labels.ts
+++ b/src/mol-plugin/util/structure-labels.ts
@@ -78,8 +78,8 @@ function getLabelDataComputed(structure: Structure, level: 'elements' | 'residue
     const l = StructureElement.create();
     const { units } = structure;
 
-    const { auth_atom_id } = StructureProperties.atom;
-    const { auth_seq_id, auth_comp_id } = StructureProperties.residue;
+    const { label_atom_id } = StructureProperties.atom;
+    const { auth_seq_id, label_comp_id } = StructureProperties.residue;
     const { auth_asym_id } = StructureProperties.chain;
     const p = Vec3.zero();
 
@@ -97,7 +97,7 @@ function getLabelDataComputed(structure: Structure, level: 'elements' | 'residue
                 l.element = elements[j];
 
                 pos(l.element, p);
-                data.texts.push(auth_atom_id(l));
+                data.texts.push(label_atom_id(l));
                 data.positions.push(Vec3.clone(p));
                 data.sizes.push(1);
                 data.depths.push(2);
@@ -124,7 +124,7 @@ function getLabelDataComputed(structure: Structure, level: 'elements' | 'residue
 
                 l.element = elements[start];
 
-                data.texts.push(`${auth_comp_id(l)} ${auth_seq_id(l)}:${auth_asym_id(l)}`);
+                data.texts.push(`${label_comp_id(l)} ${auth_seq_id(l)}:${auth_asym_id(l)}`);
                 data.positions.push(Vec3.clone(boundaryHelper.center));
                 data.sizes.push(Math.max(1, boundaryHelper.radius / 5));
                 data.depths.push(boundaryHelper.radius);
diff --git a/src/mol-theme/color/residue-name.ts b/src/mol-theme/color/residue-name.ts
index 999bf2a9b274bc9369be3625cf7d7daa895b0a6d..53f601d04baf7dc216fa73ef6b2a34e244051e69 100644
--- a/src/mol-theme/color/residue-name.ts
+++ b/src/mol-theme/color/residue-name.ts
@@ -75,7 +75,7 @@ export function residueNameColor(residueName: string): Color {
 
 function getAtomicCompId(unit: Unit.Atomic, element: ElementIndex) {
     const { modifiedResidues } = unit.model.properties
-    const compId = unit.model.atomicHierarchy.residues.auth_comp_id.value(unit.residueIndex[element])
+    const compId = unit.model.atomicHierarchy.residues.label_comp_id.value(unit.residueIndex[element])
     const parentId = modifiedResidues.parentId.get(compId)
     return parentId === undefined ? compId : parentId
 }
diff --git a/src/mol-theme/label.ts b/src/mol-theme/label.ts
index 69b67a6b9b4559b4e12c9e1bc5bd8c52313d6bb8..baeb5d978cfef83901ca70dc19cd5e52e7accdbe 100644
--- a/src/mol-theme/label.ts
+++ b/src/mol-theme/label.ts
@@ -66,9 +66,9 @@ export function elementLabel(location: StructureElement) {
 
     if (Unit.isAtomic(location.unit)) {
         const asym_id = Props.chain.auth_asym_id(location)
-        const seq_id = Props.residue.auth_seq_id(location)
-        const comp_id = Props.residue.auth_comp_id(location)
-        const atom_id = Props.atom.auth_atom_id(location)
+        const seq_id = location.unit.model.atomicHierarchy.residues.auth_seq_id.isDefined ? Props.residue.auth_seq_id(location) : Props.residue.label_seq_id(location)
+        const comp_id = Props.residue.label_comp_id(location)
+        const atom_id = Props.atom.label_atom_id(location)
         const alt_id = Props.atom.label_alt_id(location)
         label = `[${comp_id}]${seq_id}:${asym_id}.${atom_id}${alt_id ? `%${alt_id}` : ''}`
     } else if (Unit.isCoarse(location.unit)) {