diff --git a/src/mol-model-formats/structure/format.ts b/src/mol-model-formats/format.ts
similarity index 100%
rename from src/mol-model-formats/structure/format.ts
rename to src/mol-model-formats/format.ts
diff --git a/src/mol-model-formats/structure/3dg.ts b/src/mol-model-formats/structure/3dg.ts
index ca82890bfe29deaff4c872b43a00130fb961bde7..0e829bdafa8ebaa753e5c7c4212178b5bce02529 100644
--- a/src/mol-model-formats/structure/3dg.ts
+++ b/src/mol-model-formats/structure/3dg.ts
@@ -6,7 +6,7 @@
 
 import { Model } from '../../mol-model/structure/model';
 import { Task } from '../../mol-task';
-import { ModelFormat } from './format';
+import { ModelFormat } from '../format';
 import { Column, Table } from '../../mol-data/db';
 import { EntityBuilder } from './common/entity';
 import { File3DG } from '../../mol-io/reader/3dg/parser';
diff --git a/src/mol-model-formats/structure/basic/atomic.ts b/src/mol-model-formats/structure/basic/atomic.ts
index d6dcc438d792f7b5b458995547f7f38147b3f10f..de9c772db095ee5e15f495b0f3b25763a3fcd7e3 100644
--- a/src/mol-model-formats/structure/basic/atomic.ts
+++ b/src/mol-model-formats/structure/basic/atomic.ts
@@ -16,7 +16,7 @@ import { ElementSymbol } from '../../../mol-model/structure/model/types';
 import { Entities } from '../../../mol-model/structure/model/properties/common';
 import { getAtomicDerivedData } from '../../../mol-model/structure/model/properties/utils/atomic-derived';
 import { AtomSite } from './schema';
-import { ModelFormat } from '../format';
+import { ModelFormat } from '../../format';
 import { SymmetryOperator } from '../../../mol-math/geometry';
 import { MmcifFormat } from '../mmcif';
 import { AtomSiteOperatorMappingSchema } from '../../../mol-model/structure/export/categories/atom_site_operator_mapping';
diff --git a/src/mol-model-formats/structure/basic/parser.ts b/src/mol-model-formats/structure/basic/parser.ts
index 10273c258b9b61a34e49c3de4298cd93af352589..bf7129e2a08e21145a50020e227c1f8e6aac6ee2 100644
--- a/src/mol-model-formats/structure/basic/parser.ts
+++ b/src/mol-model-formats/structure/basic/parser.ts
@@ -15,7 +15,7 @@ import { getAtomicHierarchyAndConformation } from './atomic';
 import { getCoarse, EmptyCoarse, CoarseData } from './coarse';
 import { getSequence } from './sequence';
 import { sortAtomSite } from './sort';
-import { ModelFormat } from '../format';
+import { ModelFormat } from '../../format';
 import { getAtomicRanges } from '../../../mol-model/structure/model/properties/utils/atomic-ranges';
 import { AtomSite, BasicData } from './schema';
 import { getProperties } from './properties';
diff --git a/src/mol-model-formats/structure/cif-core.ts b/src/mol-model-formats/structure/cif-core.ts
index 00d95f6f920f62dec05b27cf5d6953fe34863bc0..542489d1e2428b118a0fe80fc79531280d9d32d5 100644
--- a/src/mol-model-formats/structure/cif-core.ts
+++ b/src/mol-model-formats/structure/cif-core.ts
@@ -12,7 +12,7 @@ import { createModels } from './basic/parser';
 import { BasicSchema, createBasic } from './basic/schema';
 import { ComponentBuilder } from './common/component';
 import { EntityBuilder } from './common/entity';
-import { ModelFormat } from './format';
+import { ModelFormat } from '../format';
 import { CifCore_Database } from '../../mol-io/reader/cif/schema/cif-core';
 import { CifFrame, CIF } from '../../mol-io/reader/cif';
 import { Spacegroup, SpacegroupCell } from '../../mol-math/geometry';
diff --git a/src/mol-model-formats/structure/common/property.ts b/src/mol-model-formats/structure/common/property.ts
index c5f6b277e7bc7865f7a1d546ef45b8e16112c3fb..cbc1718f8a99beb821d9f81e0b947f05f982341a 100644
--- a/src/mol-model-formats/structure/common/property.ts
+++ b/src/mol-model-formats/structure/common/property.ts
@@ -5,7 +5,7 @@
  */
 
 import { CustomPropertyDescriptor, Model } from '../../../mol-model/structure';
-import { ModelFormat } from '../format';
+import { ModelFormat } from '../../format';
 
 class FormatRegistry<T> {
     private map = new Map<ModelFormat['kind'], (model: Model) => T | undefined>()
diff --git a/src/mol-model-formats/structure/cube.ts b/src/mol-model-formats/structure/cube.ts
index 1ab1a282984797d498fef8b1eefad748e500071c..3b72a034b774b8378a99bf0a85c1984f2332fcba 100644
--- a/src/mol-model-formats/structure/cube.ts
+++ b/src/mol-model-formats/structure/cube.ts
@@ -12,7 +12,7 @@ import { createModels } from './basic/parser';
 import { BasicSchema, createBasic } from './basic/schema';
 import { ComponentBuilder } from './common/component';
 import { EntityBuilder } from './common/entity';
-import { ModelFormat } from './format';
+import { ModelFormat } from '../format';
 import { CubeFile } from '../../mol-io/reader/cube/parser';
 
 async function getModels(cube: CubeFile, ctx: RuntimeContext): Promise<Model[]> {
diff --git a/src/mol-model-formats/structure/gro.ts b/src/mol-model-formats/structure/gro.ts
index 88d699041d08f55c0c3a907dfb9f8aeea88912f0..06093e2e16a17a99d29f04541fcb8d6525b73448 100644
--- a/src/mol-model-formats/structure/gro.ts
+++ b/src/mol-model-formats/structure/gro.ts
@@ -6,7 +6,7 @@
 
 import { Model } from '../../mol-model/structure/model';
 import { Task } from '../../mol-task';
-import { ModelFormat } from './format';
+import { ModelFormat } from '../format';
 import { GroFile, GroAtoms } from '../../mol-io/reader/gro/schema';
 import { Column, Table } from '../../mol-data/db';
 import { guessElementSymbolString } from './util';
diff --git a/src/mol-model-formats/structure/mmcif.ts b/src/mol-model-formats/structure/mmcif.ts
index d716565267003abb906d3dcf13567e58e50b76f0..7f3a337c71e30f162b22bcbd021ab11555cf2a85 100644
--- a/src/mol-model-formats/structure/mmcif.ts
+++ b/src/mol-model-formats/structure/mmcif.ts
@@ -7,7 +7,7 @@
 
 import { Model } from '../../mol-model/structure/model/model';
 import { Task } from '../../mol-task';
-import { ModelFormat } from './format';
+import { ModelFormat } from '../format';
 import { CifFrame, CIF } from '../../mol-io/reader/cif';
 import { mmCIF_Database } from '../../mol-io/reader/cif/schema/mmcif';
 import { createModels } from './basic/parser';
diff --git a/src/mol-model-formats/structure/mol.ts b/src/mol-model-formats/structure/mol.ts
index c23612ee9ecd3cfaebdc40fd517e220eaf519c00..dbfc113907915813dc2667ae0e40a9d872c516a3 100644
--- a/src/mol-model-formats/structure/mol.ts
+++ b/src/mol-model-formats/structure/mol.ts
@@ -14,7 +14,7 @@ import { createModels } from './basic/parser';
 import { BasicSchema, createBasic } from './basic/schema';
 import { ComponentBuilder } from './common/component';
 import { EntityBuilder } from './common/entity';
-import { ModelFormat } from './format';
+import { ModelFormat } from '../format';
 import { IndexPairBonds } from './property/bonds/index-pair';
 
 async function getModels(mol: MolFile, ctx: RuntimeContext): Promise<Model[]> {
diff --git a/src/mol-model-formats/structure/psf.ts b/src/mol-model-formats/structure/psf.ts
index 73383d74524128dd1721ff04d2ee4dcb4064dc81..08446d212e067dda575362bf8bf3cc0d2754c64d 100644
--- a/src/mol-model-formats/structure/psf.ts
+++ b/src/mol-model-formats/structure/psf.ts
@@ -12,7 +12,7 @@ import { guessElementSymbolString } from './util';
 import { MoleculeType, getMoleculeType } from '../../mol-model/structure/model/types';
 import { getChainId } from './common/util';
 import { Task } from '../../mol-task';
-import { ModelFormat } from './format';
+import { ModelFormat } from '../format';
 import { Topology } from '../../mol-model/structure/topology/topology';
 import { createBasic, BasicSchema } from './basic/schema';
 
diff --git a/src/mol-model-formats/volume/ccp4.ts b/src/mol-model-formats/volume/ccp4.ts
index a9e5e703f70038b770511f92b41c2750d6342c09..8ccf5ad7aa02d9261492d427211a96a534a8a489 100644
--- a/src/mol-model-formats/volume/ccp4.ts
+++ b/src/mol-model-formats/volume/ccp4.ts
@@ -13,6 +13,7 @@ import { degToRad } from '../../mol-math/misc';
 import { getCcp4ValueType } from '../../mol-io/reader/ccp4/parser';
 import { TypedArrayValueType } from '../../mol-io/common/typed-array';
 import { arrayMin, arrayRms, arrayMean, arrayMax } from '../../mol-util/array';
+import { ModelFormat } from '../format';
 
 /** When available (e.g. in MRC files) use ORIGIN records instead of N[CRS]START */
 export function getCcp4Origin(header: Ccp4Header): Vec3 {
@@ -75,7 +76,24 @@ export function volumeFromCcp4(source: Ccp4File, params?: { voxelSize?: Vec3, of
                 max: isNaN(header.AMAX) ? arrayMax(values) : header.AMAX,
                 mean: isNaN(header.AMEAN) ? arrayMean(values) : header.AMEAN,
                 sigma: (isNaN(header.ARMS) || header.ARMS === 0) ? arrayRms(values) : header.ARMS
-            }
+            },
+            sourceData: Ccp4Format.create(source)
         };
     });
+}
+
+//
+
+export { Ccp4Format };
+
+type Ccp4Format = ModelFormat<Ccp4File>
+
+namespace Ccp4Format {
+    export function is(x: ModelFormat): x is Ccp4Format {
+        return x.kind === 'ccp4';
+    }
+
+    export function create(ccp4: Ccp4File): Ccp4Format {
+        return { kind: 'ccp4', name: ccp4.name, data: ccp4 };
+    }
 }
\ No newline at end of file
diff --git a/src/mol-model-formats/volume/cube.ts b/src/mol-model-formats/volume/cube.ts
index 8ed1613f9f0e875863f9107d35650b56c4f2da8e..416944d77a6e44ff6ef4d399b5f5fd23ef672f58 100644
--- a/src/mol-model-formats/volume/cube.ts
+++ b/src/mol-model-formats/volume/cube.ts
@@ -9,6 +9,7 @@ import { Mat4, Tensor } from '../../mol-math/linear-algebra';
 import { VolumeData } from '../../mol-model/volume/data';
 import { Task } from '../../mol-task';
 import { arrayMax, arrayMean, arrayMin, arrayRms } from '../../mol-util/array';
+import { ModelFormat } from '../format';
 
 export function volumeFromCube(source: CubeFile, params?: { dataIndex?: number, label?: string }): Task<VolumeData> {
     return Task.create<VolumeData>('Create Volume Data', async () => {
@@ -51,7 +52,24 @@ export function volumeFromCube(source: CubeFile, params?: { dataIndex?: number,
                 max: arrayMax(values),
                 mean: arrayMean(values),
                 sigma: arrayRms(values)
-            }
+            },
+            sourceData: CubeFormat.create(source)
         };
     });
+}
+
+//
+
+export { CubeFormat };
+
+type CubeFormat = ModelFormat<CubeFile>
+
+namespace CubeFormat {
+    export function is(x: ModelFormat): x is CubeFormat {
+        return x.kind === 'cube';
+    }
+
+    export function create(cube: CubeFile): CubeFormat {
+        return { kind: 'cube', name: cube.name, data: cube };
+    }
 }
\ No newline at end of file
diff --git a/src/mol-model-formats/volume/density-server.ts b/src/mol-model-formats/volume/density-server.ts
index 57c43fa92acd3ce4d09d875f8b2b7bd42a721a94..bb35f01408b9032a3c4bf3c8cf96fe8bdd809809 100644
--- a/src/mol-model-formats/volume/density-server.ts
+++ b/src/mol-model-formats/volume/density-server.ts
@@ -9,8 +9,9 @@ import { VolumeData } from '../../mol-model/volume/data';
 import { Task } from '../../mol-task';
 import { SpacegroupCell, Box3D } from '../../mol-math/geometry';
 import { Tensor, Vec3 } from '../../mol-math/linear-algebra';
+import { ModelFormat } from '../format';
 
-function volumeFromDensityServerData(source: DensityServer_Data_Database): Task<VolumeData> {
+export function volumeFromDensityServerData(source: DensityServer_Data_Database): Task<VolumeData> {
     return Task.create<VolumeData>('Create Volume Data', async ctx => {
         const { volume_data_3d_info: info, volume_data_3d: values } = source;
         const cell = SpacegroupCell.create(
@@ -41,9 +42,24 @@ function volumeFromDensityServerData(source: DensityServer_Data_Database): Task<
                 max: info.max_sampled.value(0),
                 mean: info.mean_sampled.value(0),
                 sigma: info.sigma_sampled.value(0)
-            }
+            },
+            sourceData: DscifFormat.create(source)
         };
     });
 }
 
-export { volumeFromDensityServerData };
\ No newline at end of file
+//
+
+export { DscifFormat };
+
+type DscifFormat = ModelFormat<DensityServer_Data_Database>
+
+namespace DscifFormat {
+    export function is(x: ModelFormat): x is DscifFormat {
+        return x.kind === 'dscif';
+    }
+
+    export function create(dscif: DensityServer_Data_Database): DscifFormat {
+        return { kind: 'dscif', name: dscif._name, data: dscif };
+    }
+}
\ No newline at end of file
diff --git a/src/mol-model-formats/volume/dsn6.ts b/src/mol-model-formats/volume/dsn6.ts
index 42b3fe63235df190b91b99b50fcf97861fb4ca8b..f6ef76cd6da544664d58060905409f22b83a47f4 100644
--- a/src/mol-model-formats/volume/dsn6.ts
+++ b/src/mol-model-formats/volume/dsn6.ts
@@ -11,8 +11,9 @@ import { Tensor, Vec3 } from '../../mol-math/linear-algebra';
 import { degToRad } from '../../mol-math/misc';
 import { Dsn6File } from '../../mol-io/reader/dsn6/schema';
 import { arrayMin, arrayMax, arrayMean, arrayRms } from '../../mol-util/array';
+import { ModelFormat } from '../format';
 
-function volumeFromDsn6(source: Dsn6File, params?: { voxelSize?: Vec3, label?: string }): Task<VolumeData> {
+export function volumeFromDsn6(source: Dsn6File, params?: { voxelSize?: Vec3, label?: string }): Task<VolumeData> {
     return Task.create<VolumeData>('Create Volume Data', async ctx => {
         const { header, values } = source;
         const size = Vec3.create(header.xlen, header.ylen, header.zlen);
@@ -40,9 +41,24 @@ function volumeFromDsn6(source: Dsn6File, params?: { voxelSize?: Vec3, label?: s
                 max: arrayMax(values),
                 mean: arrayMean(values),
                 sigma: header.sigma !== undefined ? header.sigma : arrayRms(values)
-            }
+            },
+            sourceData: Dsn6Format.create(source)
         };
     });
 }
 
-export { volumeFromDsn6 };
\ No newline at end of file
+//
+
+export { Dsn6Format };
+
+type Dsn6Format = ModelFormat<Dsn6File>
+
+namespace Dsn6Format {
+    export function is(x: ModelFormat): x is Dsn6Format {
+        return x.kind === 'dsn6';
+    }
+
+    export function create(dsn6: Dsn6File): Dsn6Format {
+        return { kind: 'dsn6', name: dsn6.name, data: dsn6 };
+    }
+}
\ No newline at end of file
diff --git a/src/mol-model-formats/volume/dx.ts b/src/mol-model-formats/volume/dx.ts
index 79afcf0712c9dd0ea9a1625a4c27b83b02ed2193..2ec9007ca7b601639f74db0d8486f65816c524ef 100644
--- a/src/mol-model-formats/volume/dx.ts
+++ b/src/mol-model-formats/volume/dx.ts
@@ -9,6 +9,7 @@ import { Mat4, Tensor } from '../../mol-math/linear-algebra';
 import { VolumeData } from '../../mol-model/volume/data';
 import { Task } from '../../mol-task';
 import { arrayMax, arrayMean, arrayMin, arrayRms } from '../../mol-util/array';
+import { ModelFormat } from '../format';
 
 export function volumeFromDx(source: DxFile, params?: { label?: string }): Task<VolumeData> {
     return Task.create<VolumeData>('Create Volume Data', async () => {
@@ -28,7 +29,24 @@ export function volumeFromDx(source: DxFile, params?: { label?: string }): Task<
                 max: arrayMax(values),
                 mean: arrayMean(values),
                 sigma: arrayRms(values)
-            }
+            },
+            sourceData: DxFormat.create(source)
         };
     });
+}
+
+//
+
+export { DxFormat };
+
+type DxFormat = ModelFormat<DxFile>
+
+namespace DxFormat {
+    export function is(x: ModelFormat): x is DxFormat {
+        return x.kind === 'dx';
+    }
+
+    export function create(dx: DxFile): DxFormat {
+        return { kind: 'dx', name: dx.name, data: dx };
+    }
 }
\ No newline at end of file
diff --git a/src/mol-model/structure/model/model.ts b/src/mol-model/structure/model/model.ts
index 2d4a95177e551e1fc1e2dfc9cafc257772287e5c..00e90d1c9c18ee29abea6000147e029a2054d306 100644
--- a/src/mol-model/structure/model/model.ts
+++ b/src/mol-model/structure/model/model.ts
@@ -12,7 +12,7 @@ import { CoarseHierarchy, CoarseConformation } from './properties/coarse';
 import { Entities, ChemicalComponentMap, MissingResidues, StructAsymMap } from './properties/common';
 import { CustomProperties } from '../common/custom-property';
 import { SaccharideComponentMap } from '../structure/carbohydrates/constants';
-import { ModelFormat } from '../../../mol-model-formats/structure/format';
+import { ModelFormat } from '../../../mol-model-formats/format';
 import { calcModelCenter } from './util';
 import { Vec3 } from '../../../mol-math/linear-algebra';
 import { Mutable } from '../../../mol-util/type-helpers';
diff --git a/src/mol-model/structure/topology/topology.ts b/src/mol-model/structure/topology/topology.ts
index f8863254322187503d5d8bd9cd43cbbfcd566388..f65e90ce2f658cd37274b6fde9ae9a599370b162 100644
--- a/src/mol-model/structure/topology/topology.ts
+++ b/src/mol-model/structure/topology/topology.ts
@@ -7,7 +7,7 @@
 import { UUID } from '../../../mol-util';
 import { Column } from '../../../mol-data/db';
 import { BasicData } from '../../../mol-model-formats/structure/basic/schema';
-import { ModelFormat } from '../../../mol-model-formats/structure/format';
+import { ModelFormat } from '../../../mol-model-formats/format';
 
 export { Topology };
 
diff --git a/src/mol-model/volume/data.ts b/src/mol-model/volume/data.ts
index b80149c8541e4363c4dad0b27b098f788cc59afc..2ab5681126a681ba73062b93fed4b485c2695fb1 100644
--- a/src/mol-model/volume/data.ts
+++ b/src/mol-model/volume/data.ts
@@ -8,6 +8,7 @@
 import { SpacegroupCell, Box3D } from '../../mol-math/geometry';
 import { Tensor, Mat4, Vec3 } from '../../mol-math/linear-algebra';
 import { equalEps } from '../../mol-math/linear-algebra/3d/common';
+import { ModelFormat } from '../../mol-model-formats/format';
 
 /** The basic unit cell that contains the data. */
 interface VolumeDataBase {
@@ -20,6 +21,7 @@ interface VolumeDataBase {
         mean: number,
         sigma: number
     }>
+    readonly sourceData: ModelFormat,
 }
 
 interface VolumeData extends VolumeDataBase {
@@ -30,7 +32,8 @@ namespace VolumeData {
     export const One: VolumeData = {
         transform: { kind: 'matrix', matrix: Mat4.identity() },
         data: Tensor.create(Tensor.Space([1, 1, 1], [0, 1, 2]), Tensor.Data1([0])),
-        dataStats: { min: 0, max: 0, mean: 0, sigma: 0 }
+        dataStats: { min: 0, max: 0, mean: 0, sigma: 0 },
+        sourceData: { kind: '', data: '', name: '' }
     };
 
     const _scale = Mat4.zero(), _translate = Mat4.zero();