diff --git a/src/apps/rednatco/api-impl.ts b/src/apps/rednatco/api-impl.ts
index fa36829f0dd9f3091b37389f0013c2d141db6b54..d9940fa8a9aa682c23732779d988afc26e2e226a 100644
--- a/src/apps/rednatco/api-impl.ts
+++ b/src/apps/rednatco/api-impl.ts
@@ -34,9 +34,9 @@ export class ReDNATCOMspApiImpl implements ReDNATCOMspApi.Object {
         return !!this.target;
     }
 
-    loadStructure(coords: { data: string, type: 'cif'|'pdb' }, densityMap: { data: Uint8Array, type: 'ccp4'|'dsn6'|'ds' }|null) {
+    loadStructure(coords: { data: string, type: 'cif'|'pdb' }, densityMaps: { data: Uint8Array, type: 'ccp4'|'dsn6', kind: '2fo-fc'|'fo-fc'|'em' }[]|null) {
         this.check();
-        this.target!.loadStructure(coords, densityMap);
+        this.target!.loadStructure(coords, densityMaps);
     }
 
     query<T extends ReDNATCOMspApi.Queries.Type>(type: T): ReDNATCOMspApi.ResponseTypes[T] {
diff --git a/src/apps/rednatco/api.ts b/src/apps/rednatco/api.ts
index 07d281d5a2d2a82b5a18bf1e5b5915b9fa862fd8..09a30b75b6e6a3223376caf251c4952643874e06 100644
--- a/src/apps/rednatco/api.ts
+++ b/src/apps/rednatco/api.ts
@@ -126,7 +126,7 @@ export namespace ReDNATCOMspApi {
         event: (evt: Event) => void;
         init: (elemId: string, onEvent?: (evt: Event) => void) => void;
         isReady: () => boolean;
-        loadStructure: (coords: { data: string, type: 'cif'|'pdb'}, densityMap: { data: Uint8Array, type: 'ccp4'|'dsn6'|'ds' }|null) => void;
+        loadStructure: (coords: { data: string, type: 'cif'|'pdb'}, densityMaps: { data: Uint8Array, type: 'ccp4'|'dsn6', kind: '2fo-fc'|'fo-fc'|'em' }[]|null) => void;
         query: <T extends Queries.Type>(type: T) => ResponseTypes[T];
     }
 }
diff --git a/src/apps/rednatco/controls.tsx b/src/apps/rednatco/controls.tsx
index 5c720989e87a9eb47959b79fdc2775e699001344..572d184203435c52797a7ab78c7fda5eda641234 100644
--- a/src/apps/rednatco/controls.tsx
+++ b/src/apps/rednatco/controls.tsx
@@ -1,5 +1,6 @@
 import React from 'react';
-import { fuzzyCmp, numDecimals, reduceDecimals, stof } from './util';
+import { fuzzyCmp, luminance, numDecimals, reduceDecimals, stof } from './util';
+import { Color } from '../../mol-util/color';
 
 const Zero = '0'.charCodeAt(0);
 const Nine = '9'.charCodeAt(0);
@@ -57,6 +58,20 @@ export namespace CollapsibleVertical {
     }
 }
 
+export class ColorBox extends React.Component<{ caption: string, color: Color }> {
+    render() {
+        const lum = luminance(this.props.color);
+        return (
+            <div
+                className='rmsp-color-box'
+                style={{ backgroundColor: Color.toStyle(this.props.color) }}
+            >
+                <span style={{ color: lum > 0.6 ? 'black' : 'white', margin: '0.15em' }}>{this.props.caption}</span>
+            </div>
+        );
+    }
+}
+
 export class PushButton extends React.Component<{ text: string, enabled: boolean, onClick: () => void }> {
     render() {
         return (
diff --git a/src/apps/rednatco/density-map-controls.tsx b/src/apps/rednatco/density-map-controls.tsx
index 750a3066e1ec638b1d54ddd9e1262325f734a8d7..e454a042511b16b17a4e2eb77d108f915e6a63e1 100644
--- a/src/apps/rednatco/density-map-controls.tsx
+++ b/src/apps/rednatco/density-map-controls.tsx
@@ -1,32 +1,74 @@
 import React from 'react';
-import { CollapsibleVertical, RangeSlider, SpinBox, ToggleButton } from './controls';
-import { isoToFixed } from './util';
+import { ColorPicker } from './color-picker';
+import { CollapsibleVertical, ColorBox, RangeSlider, SpinBox, ToggleButton } from './controls';
+import { DensityMapDisplay, DensityMapKind } from './index';
+import { isoBounds, isoToFixed } from './util';
+import { ReDNATCOMspViewer as Viewer } from './viewer';
+import { Color } from '../../mol-util/color';
 
 export class DensityMapControls extends React.Component<DensityMapControls.Props> {
-    render() {
-        return (
-            <CollapsibleVertical caption='Density map'>
-                <div className='rmsp-controls'>
+    private colors(index: number, colors: DensityMapDisplay['colors']) {
+        const elems = new Array<JSX.Element>();
+
+        for (let idx = 0; idx < colors.length; idx++) {
+            const c = colors[idx];
+            const e =
+                <div className='rmsp-control-item'
+                    key={idx}
+                    style={{ backgroundColor: Color.toHexString(c.color) }}
+                    onClick={(evt) => {
+                        ColorPicker.create(
+                            evt,
+                            c.color,
+                            (color) => {
+                                colors[idx] = { ...colors[idx], color: Color(color) },
+                                this.props.changeColors(index, colors);
+                            }
+                        );
+                    }}
+                >
+                    <ColorBox
+                        caption={c.name}
+                        color={c.color}
+                    />
+                </div>;
+            elems.push(e);
+        }
+
+        return elems;
+    }
+
+    private controls(display: DensityMapDisplay[]) {
+        const ctrls = new Array<JSX.Element>();
+
+        for (let idx = 0; idx < display.length; idx++) {
+            const isoRange = this.props.viewer.densityMapIsoRange(idx);
+            const _isoBounds = isoRange ? isoBounds(isoRange.min, isoRange.max) : { min: 0, max: 0, step: 0 };
+
+            const d = display[idx];
+            const elem = (
+                <React.Fragment key={idx}>
                     <div className='rmsp-controls-section-caption'>
-                        Representations:
+                        {this.mapName(d.kind)}
                     </div>
                     <div className='rmsp-controls-line'>
                         <div className='rmsp-control-item'>
                             <ToggleButton
                                 text='Wireframe'
-                                switchedOn={this.props.wireframe}
-                                onClick={() => this.props.toggleWireframe()}
+                                switchedOn={d.representations.includes('wireframe')}
+                                onClick={() => this.props.toggleWireframe(idx)}
                                 enabled={true}
                             />
                         </div>
                         <div className='rmsp-control-item'>
                             <ToggleButton
                                 text='Solid'
-                                switchedOn={this.props.solid}
-                                onClick={() => this.props.toggleSolid()}
+                                switchedOn={d.representations.includes('solid')}
+                                onClick={() => this.props.toggleSolid(idx)}
                                 enabled={true}
                             />
                         </div>
+                        { this.colors(idx, d.colors) }
                     </div>
 
                     <div className='rmsp-controls-section-caption'>
@@ -35,22 +77,22 @@ export class DensityMapControls extends React.Component<DensityMapControls.Props
                     <div className='rmsp-controls-line'>
                         <div className='rmsp-control-item'>
                             <RangeSlider
-                                min={this.props.isoMin}
-                                max={this.props.isoMax}
-                                step={this.props.isoStep}
-                                value={isoToFixed(this.props.iso, this.props.isoStep)}
-                                onChange={(v) => this.props.changeIso(v!)}
+                                min={_isoBounds.min}
+                                max={_isoBounds.max}
+                                step={_isoBounds.step}
+                                value={isoToFixed(d.isoValue, _isoBounds.step)}
+                                onChange={(v) => this.props.changeIso(idx, v!)}
                             />
                         </div>
-                        <div className='rmsp-control-item'>
+                        <div className='rmsp-control-item-squished'>
                             <div style={{ display: 'grid', gridTemplateColumns: '4em 1fr' }}>
                                 <SpinBox
-                                    min={this.props.isoMin}
-                                    max={this.props.isoMax}
-                                    step={this.props.isoStep}
-                                    maxNumDecimals={Math.log10(this.props.isoStep) >= 0 ? 0 : -Math.log10(this.props.isoStep)}
-                                    value={isoToFixed(this.props.iso, this.props.isoStep)}
-                                    onChange={(n) => this.props.changeIso(n)}
+                                    min={_isoBounds.min}
+                                    max={_isoBounds.max}
+                                    step={_isoBounds.step}
+                                    maxNumDecimals={Math.log10(_isoBounds.step) >= 0 ? 0 : -Math.log10(_isoBounds.step)}
+                                    value={isoToFixed(d.isoValue, _isoBounds.step)}
+                                    onChange={(n) => this.props.changeIso(idx, n)}
                                     pathPrefix=''
                                 />
                                 <div />
@@ -67,24 +109,48 @@ export class DensityMapControls extends React.Component<DensityMapControls.Props
                                 min={0}
                                 max={100}
                                 step={1}
-                                value={(1.0 - this.props.alpha) * 100}
-                                onChange={(n) => this.props.changeAlpha(1.0 - (n! / 100))}
+                                value={(1.0 - d.alpha) * 100}
+                                onChange={(n) => this.props.changeAlpha(idx, 1.0 - (n! / 100))}
                             />
                         </div>
-                        <div className='rmsp-control-item'>
+                        <div className='rmsp-control-item-squished'>
                             <div style={{ display: 'grid', gridTemplateColumns: '4em 1fr' }}>
                                 <SpinBox
                                     min={0}
                                     max={100}
                                     step={1}
                                     maxNumDecimals={0}
-                                    value={(1.0 - this.props.alpha) * 100}
-                                    onChange={(n) => this.props.changeAlpha(1.0 - (n / 100))}
+                                    value={(1.0 - d.alpha) * 100}
+                                    onChange={(n) => this.props.changeAlpha(idx, 1.0 - (n / 100))}
                                     pathPrefix=''
                                 />
                             </div>
                         </div>
                     </div>
+                </React.Fragment>
+            );
+            ctrls.push(elem);
+        }
+
+        return ctrls;
+    }
+
+    private mapName(kind: DensityMapKind) {
+        switch (kind) {
+            case '2fo-fc':
+                return <span>2Fo-Fc</span>;
+            case 'fo-fc':
+                return <span>Fo-Fc</span>;
+            case 'em':
+                return <span>EM map</span>;
+        }
+    }
+
+    render() {
+        return (
+            <CollapsibleVertical caption='Density map'>
+                <div className='rmsp-controls'>
+                    {this.controls(this.props.display)}
                 </div>
             </CollapsibleVertical>
         );
@@ -93,18 +159,13 @@ export class DensityMapControls extends React.Component<DensityMapControls.Props
 
 export namespace DensityMapControls {
     export interface Props {
-        wireframe: boolean;
-        solid: boolean;
-        toggleWireframe: () => void;
-        toggleSolid: () => void;
-
-        isoMin: number;
-        isoMax: number;
-        isoStep: number;
-        iso: number;
-        changeIso: (iso: number) => void;
+        viewer: Viewer;
+        display: DensityMapDisplay[];
 
-        alpha: number;
-        changeAlpha: (alpha: number) => void;
+        toggleWireframe: (index: number) => void;
+        toggleSolid: (index: number) => void;
+        changeIso: (index: number, iso: number) => void;
+        changeAlpha: (index: number, alpha: number) => void;
+        changeColors: (index: number, colors: DensityMapDisplay['colors']) => void;
     }
 }
diff --git a/src/apps/rednatco/idents.ts b/src/apps/rednatco/idents.ts
index 91b5b4c91d599df50d24dd472a644c1cd9770b2d..4a0df1b229b2c4961595bc2f72c50b4f4b8dc440 100644
--- a/src/apps/rednatco/idents.ts
+++ b/src/apps/rednatco/idents.ts
@@ -18,9 +18,10 @@ export function ID(id: ID, sub: Substructure|'', ref: string) {
 }
 
 export type DensityID = 'data'|'volume'|'visual';
+// export type DensityKind = 'absolute'|'difference-positive'|'difference-negative';
 
-export function DensityID(id: DensityID, ref: string) {
-    return `${ref}_density-map_${id}`;
+export function DensityID(index: number, id: DensityID, ref: string) {
+    return `${ref}_density-map_${index}_${id}`;
 }
 
 export function isVisual(ident: string) {
diff --git a/src/apps/rednatco/index.tsx b/src/apps/rednatco/index.tsx
index f341c19528a695b085896acc37a901899189cde4..010f6db2b581f98e1e82a9b0eb16d3076734416a 100644
--- a/src/apps/rednatco/index.tsx
+++ b/src/apps/rednatco/index.tsx
@@ -7,8 +7,8 @@ import { Filters } from './filters';
 import { ReDNATCOMspViewer } from './viewer';
 import { NtCColors } from './colors';
 import { ColorPicker } from './color-picker';
-import { CollapsibleVertical, PushButton, ToggleButton } from './controls';
-import { isoBounds, luminance, toggleArray } from './util';
+import { CollapsibleVertical, ColorBox, PushButton, ToggleButton } from './controls';
+import { toggleArray } from './util';
 import { Color } from '../../mol-util/color';
 import { assertUnreachable } from '../../mol-util/type-helpers';
 import './index.html';
@@ -27,10 +27,24 @@ const ConformersByClass = {
 type ConformersByClass = typeof ConformersByClass;
 
 const DefaultChainColor = Color(0xD9D9D9);
-const DefaultDensityMapAlpha = 0.5;
+const DefaultDensityMapAlpha = 0.25;
 const DefaultWaterColor = Color(0x0BB2FF);
 export type VisualRepresentations = 'ball-and-stick'|'cartoon';
 export type DensityMapRepresentation = 'wireframe'|'solid';
+export type DensityMapKind = '2fo-fc'|'fo-fc'|'em';
+
+export const DefaultDensityDifferencePositiveColor = Color(0x00C300);
+export const DefaultDensityDifferenceNegativeColor = Color(0xC30000);
+export const DefaultDensityMapColor = Color(0x009DFF);
+const DefaultDensityMapDisplay = {
+    kind: '2fo-fc' as DensityMapKind,
+    representations: ['solid'] as DensityMapRepresentation[],
+    isoValue: 0,
+
+    alpha: DefaultDensityMapAlpha,
+    colors: [{ color: DefaultDensityMapColor, name: 'Color' }],
+};
+export type DensityMapDisplay = typeof DefaultDensityMapDisplay;
 
 const Display = {
     structures: {
@@ -53,13 +67,7 @@ const Display = {
         chainColor: DefaultChainColor,
         waterColor: DefaultWaterColor,
     },
-    densityMap: {
-        representations: ['wireframe'] as DensityMapRepresentation[],
-        isoValue: 0,
-
-        alpha: DefaultDensityMapAlpha,
-        color: 0x000000
-    },
+    densityMaps: [] as DensityMapDisplay[],
 };
 export type Display = typeof Display;
 
@@ -69,20 +77,6 @@ function capitalize(s: string) {
     return s[0].toLocaleUpperCase() + s.slice(1);
 }
 
-class ColorBox extends React.Component<{ caption: string, color: Color }> {
-    render() {
-        const lum = luminance(this.props.color);
-        return (
-            <div
-                className='rmsp-color-box'
-                style={{ backgroundColor: Color.toStyle(this.props.color) }}
-            >
-                <span style={{ color: lum > 0.6 ? 'black' : 'white' }}>{this.props.caption}</span>
-            </div>
-        );
-    }
-}
-
 interface State {
     display: Display;
     showControls: boolean;
@@ -231,11 +225,32 @@ export class ReDNATCOMsp extends React.Component<ReDNATCOMsp.Props, State> {
         }
     }
 
-    loadStructure(coords: { data: string, type: 'pdb'|'cif' }, densityMap: { data: Uint8Array, type: 'ccp4'|'dsn6'|'ds' }|null) {
+    loadStructure(coords: { data: string, type: 'pdb'|'cif' }, densityMaps: { data: Uint8Array, type: 'ccp4'|'dsn6', kind: '2fo-fc'|'fo-fc'|'em' }[]|null) {
         if (this.viewer) {
-            this.viewer.loadStructure(coords, densityMap, this.state.display).then(() => {
+            const display = { ...this.state.display };
+            if (densityMaps) {
+                display.densityMaps.length = densityMaps.length;
+                for (let idx = 0; idx < densityMaps.length; idx++) {
+                    const dm = densityMaps[idx];
+
+                    if (dm.kind === 'fo-fc') {
+                        display.densityMaps[idx] = {
+                            ...DefaultDensityMapDisplay,
+                            kind: dm.kind,
+                            colors: [
+                                { color: DefaultDensityDifferencePositiveColor, name: '+ color' },
+                                { color: DefaultDensityDifferenceNegativeColor, name: '- color' },
+                            ],
+                        };
+                    } else
+                        display.densityMaps[idx] = { ...DefaultDensityMapDisplay, kind: dm.kind };
+                }
+            } else
+                display.densityMaps.length = 0;
+
+            this.viewer.loadStructure(coords, densityMaps, display).then(() => {
                 this.presentConformers = this.viewer!.getPresentConformers();
-                this.forceUpdate();
+                this.setState({ ...this.state, display });
                 ReDNATCOMspApi.event(Api.Events.StructureLoaded());
             });
         }
@@ -271,9 +286,6 @@ export class ReDNATCOMsp extends React.Component<ReDNATCOMsp.Props, State> {
         const hasProtein = this.viewer?.has('structure', 'protein') ?? false;
         const hasWater = this.viewer?.has('structure', 'water') ?? false;
 
-        const isoRange = this.viewer?.densityMapIsoRange();
-        const _isoBounds = isoRange ? isoBounds(isoRange.min, isoRange.max) : { min: 0, max: 0, step: 0 };
-
         return (
             <div className='rmsp-app'>
                 <div id={this.props.elemId + '-viewer'} className='rmsp-viewer'></div>
@@ -500,44 +512,44 @@ export class ReDNATCOMsp extends React.Component<ReDNATCOMsp.Props, State> {
                         </div>
                     </div>
                 </CollapsibleVertical>
-                {this.viewer?.hasDensityMap()
+                {this.viewer?.hasDensityMaps()
                     ? <DensityMapControls
-                        wireframe={this.state.display.densityMap.representations.includes('wireframe')}
-                        toggleWireframe={() => {
+                        viewer={this.viewer}
+                        display={this.state.display.densityMaps}
+                        toggleWireframe={(index) => {
                             const display = { ...this.state.display };
-                            display.densityMap.representations = toggleArray(display.densityMap.representations, 'wireframe');
+                            display.densityMaps[index].representations = toggleArray(display.densityMaps[index].representations, 'wireframe');
 
-                            this.viewer!.changeDensityMap(display);
+                            this.viewer!.changeDensityMap(index, display);
                             this.setState({ ...this.state, display });
                         }}
 
-                        solid={this.state.display.densityMap.representations.includes('solid')}
-                        toggleSolid={() => {
+                        toggleSolid={(index) => {
                             const display = { ...this.state.display };
-                            display.densityMap.representations = toggleArray(display.densityMap.representations, 'solid');
+                            display.densityMaps[index].representations = toggleArray(display.densityMaps[index].representations, 'solid');
 
-                            this.viewer!.changeDensityMap(display);
+                            this.viewer!.changeDensityMap(index, display);
                             this.setState({ ...this.state, display });
                         }}
-
-                        isoMin={_isoBounds.min}
-                        isoMax={_isoBounds.max}
-                        isoStep={_isoBounds.step}
-                        iso={this.state.display.densityMap.isoValue}
-                        changeIso={(v) => {
+                        changeIso={(index, v) => {
                             const display = { ...this.state.display };
-                            display.densityMap.isoValue = v;
+                            display.densityMaps[index].isoValue = v;
 
-                            this.viewer!.changeDensityMap(display);
+                            this.viewer!.changeDensityMap(index, display);
                             this.setState({ ...this.state, display });
                         }}
+                        changeAlpha={(index, alpha) => {
+                            const display = { ...this.state.display };
+                            display.densityMaps[index].alpha = alpha;
 
-                        alpha={this.state.display.densityMap.alpha}
-                        changeAlpha={(alpha) => {
+                            this.viewer!.changeDensityMap(index, display);
+                            this.setState({ ...this.state, display });
+                        }}
+                        changeColors={(index, colors) => {
                             const display = { ...this.state.display };
-                            display.densityMap.alpha = alpha;
+                            display.densityMaps[index].colors = colors;
 
-                            this.viewer!.changeDensityMap(display);
+                            this.viewer!.changeDensityMap(index, display);
                             this.setState({ ...this.state, display });
                         }}
                     />
diff --git a/src/apps/rednatco/rednatco-molstar.css b/src/apps/rednatco/rednatco-molstar.css
index fddb76fdec5905731c5c7e0360845e52e3139919..5f33a4a53ebbb98fa22f0b20617dbd0a52db377a 100644
--- a/src/apps/rednatco/rednatco-molstar.css
+++ b/src/apps/rednatco/rednatco-molstar.css
@@ -79,6 +79,9 @@
     flex: 1;
 }
 
+.rmsp-control-item-squished {
+}
+
 .rmsp-controls-line {
     align-items: center;
     display: flex;
diff --git a/src/apps/rednatco/viewer.ts b/src/apps/rednatco/viewer.ts
index aacf7a673e73650f3714bce1dc6b8f57325c09e2..a6c978d72a9b6ddd114f4e0b338ecce9b6976157 100644
--- a/src/apps/rednatco/viewer.ts
+++ b/src/apps/rednatco/viewer.ts
@@ -244,20 +244,28 @@ export class ReDNATCOMspViewer {
         this.app = app;
     }
 
-    private densityMapVisuals(vis: Display['densityMap']) {
+    private densityMapVisuals(vis: Display['densityMaps'][0], visKind: 'absolute'|'positive'|'negative') {
+        const isoValue = visKind === 'absolute'
+            ? Volume.IsoValue.absolute(vis.isoValue)
+            : visKind === 'positive'
+                ? Volume.IsoValue.relative(vis.isoValue) : Volume.IsoValue.relative(-vis.isoValue);
+
+        const color = visKind === 'absolute' || visKind === 'positive'
+            ? vis.colors[0] : vis.colors[1]
+
         return {
             type: {
                 name: 'isosurface',
                 params: {
                     alpha: vis.alpha,
-                    isoValue: Volume.IsoValue.absolute(vis.isoValue),
+                    isoValue,
                     visuals: vis.representations,
                     sizeFactor: 0.75,
                 }
             },
             colorTheme: {
                 name: 'uniform',
-                params: { value: Color(vis.color) },
+                params: { value: Color(color.color) },
             },
         };
     }
@@ -649,22 +657,41 @@ export class ReDNATCOMspViewer {
         await b.commit();
     }
 
-    async changeDensityMap(display: Display) {
-        if (!this.hasDensityMap())
+    async changeDensityMap(index: number, display: Display) {
+        if (!this.hasDensityMaps())
             return;
 
-        const b = this.plugin.state.data.build().to(IDs.DensityID('visual', BaseRef));
-        const vis = display.densityMap;
+        const dm = display.densityMaps[index];
 
-        b.update(
-            StateTransforms.Representation.VolumeRepresentation3D,
-            old => ({
-                ...old,
-                ...this.densityMapVisuals(vis),
-            })
-        );
-
-        await b.commit();
+        if (dm.kind === 'fo-fc') {
+            await this.plugin.state.data.build().to(IDs.DensityID(index, 'visual', BaseRef + '_pos'))
+                .update(
+                    StateTransforms.Representation.VolumeRepresentation3D,
+                    old => ({
+                        ...old,
+                        ...this.densityMapVisuals(dm, 'positive'),
+                    })
+                )
+                .to(IDs.DensityID(index, 'visual', BaseRef + '_neg'))
+                .update(
+                    StateTransforms.Representation.VolumeRepresentation3D,
+                    old => ({
+                        ...old,
+                        ...this.densityMapVisuals(dm, 'negative'),
+                    })
+                )
+                .commit();
+        } else {
+            await this.plugin.state.data.build().to(IDs.DensityID(index, 'visual', BaseRef))
+                .update(
+                    StateTransforms.Representation.VolumeRepresentation3D,
+                    old => ({
+                        ...old,
+                        ...this.densityMapVisuals(dm, 'absolute'),
+                    })
+                )
+                .commit();
+        }
     }
 
     currentModelNumber() {
@@ -674,8 +701,8 @@ export class ReDNATCOMspViewer {
         return (model as StateObject<Model>).data.modelNum;
     }
 
-    densityMapIsoRange(ref = BaseRef): { min: number, max: number }|undefined {
-        const cell = this.plugin.state.data.cells.get(IDs.DensityID('volume', ref));
+    densityMapIsoRange(index: number, ref = BaseRef): { min: number, max: number }|undefined {
+        const cell = this.plugin.state.data.cells.get(IDs.DensityID(index, 'volume', ref));
         if (!cell || !cell.obj)
             return void 0;
 
@@ -842,8 +869,8 @@ export class ReDNATCOMspViewer {
         return !!this.plugin.state.data.cells.get(IDs.ID(id, sub, ref))?.obj?.data;
     }
 
-    hasDensityMap(ref = BaseRef) {
-        return !!this.plugin.state.data.cells.get(IDs.DensityID('volume', ref))?.obj?.data;
+    hasDensityMaps(ref = BaseRef) {
+        return !!this.plugin.state.data.cells.get(IDs.DensityID(0, 'volume', ref))?.obj?.data;
     }
 
     isReady() {
@@ -852,7 +879,7 @@ export class ReDNATCOMspViewer {
 
     async loadStructure(
         coords: { data: string, type: 'pdb'|'cif' },
-        densityMap: { data: Uint8Array, type: 'ccp4'|'dsn6'|'ds' }|null,
+        densityMaps: { data: Uint8Array, type: 'ccp4'|'dsn6', kind: '2fo-fc'|'fo-fc'|'em' }[]|null,
         display: Display
     ) {
         // TODO: Remove the currently loaded structure
@@ -941,42 +968,54 @@ export class ReDNATCOMspViewer {
         await b3.commit();
 
         // Load density map, if any
-        if (densityMap) {
-            // This is ridiculous but anything saner breaks type checker
-            if (densityMap.type === 'ccp4') {
-                await this.plugin.state.data.build().toRoot()
-                    .apply(RawData, { data: densityMap.data }, { ref: IDs.DensityID('data', BaseRef) })
-                    .apply(StateTransforms.Data.ParseCcp4)
-                    .apply(StateTransforms.Volume.VolumeFromCcp4, {}, { ref: IDs.DensityID('volume', BaseRef) })
-                    .commit();
-            } else if (densityMap.type === 'dsn6') {
-                await this.plugin.state.data.build().toRoot()
-                    .apply(RawData, { data: densityMap.data }, { ref: IDs.DensityID('data', BaseRef) })
-                    .apply(StateTransforms.Data.ParseDsn6)
-                    .apply(StateTransforms.Volume.VolumeFromDsn6, {}, { ref: IDs.DensityID('volume', BaseRef) })
-                    .commit();
-            } else if (densityMap.type === 'ds') {
-                await this.plugin.state.data.build().toRoot()
-                    .apply(RawData, { data: densityMap.data }, { ref: IDs.DensityID('data', BaseRef) })
-                    .apply(StateTransforms.Data.ParseCif)
-                    .apply(StateTransforms.Volume.VolumeFromDensityServerCif, {}, { ref: IDs.DensityID('volume', BaseRef) })
-                    .commit();
-            }
-
-            const isoRange = this.densityMapIsoRange()!;
-            const bounds = isoBounds(isoRange.min, isoRange.max);
-            const iso = prettyIso(((isoRange.max - isoRange.min) / 2) + isoRange.min, bounds.step);
-
-            display.densityMap.representations = ['wireframe'];
-            display.densityMap.isoValue = iso;
+        if (densityMaps) {
+            for (let idx = 0; idx < densityMaps.length; idx++) {
+                const dm = densityMaps[idx];
+                if (dm.type === 'ccp4') {
+                    await this.plugin.state.data.build().toRoot()
+                        .apply(RawData, { data: dm.data }, { ref: IDs.DensityID(idx, 'data', BaseRef) })
+                        .apply(StateTransforms.Data.ParseCcp4)
+                        .apply(StateTransforms.Volume.VolumeFromCcp4, {}, { ref: IDs.DensityID(idx, 'volume', BaseRef) })
+                        .commit();
+                } else if (dm.type === 'dsn6') {
+                    await this.plugin.state.data.build().toRoot()
+                        .apply(RawData, { data: dm.data }, { ref: IDs.DensityID(idx, 'data', BaseRef) })
+                        .apply(StateTransforms.Data.ParseDsn6)
+                        .apply(StateTransforms.Volume.VolumeFromDsn6, {}, { ref: IDs.DensityID(idx, 'volume', BaseRef) })
+                        .commit();
+                }
 
-            await this.plugin.state.data.build().to(IDs.DensityID('volume', BaseRef))
-                .apply(
-                    StateTransforms.Representation.VolumeRepresentation3D,
-                    this.densityMapVisuals(display.densityMap),
-                    { ref: IDs.DensityID('visual', BaseRef) }
-                )
-                .commit();
+                const isoRange = this.densityMapIsoRange(idx)!;
+                const bounds = isoBounds(isoRange.min, isoRange.max);
+
+                if (dm.kind === 'fo-fc') {
+                    display.densityMaps[idx].isoValue = prettyIso(isoRange.max * 0.67, bounds.step);
+
+                    this.plugin.state.data.build().to(IDs.DensityID(idx, 'volume', BaseRef))
+                        .apply(
+                            StateTransforms.Representation.VolumeRepresentation3D,
+                            this.densityMapVisuals(display.densityMaps[idx], 'positive'),
+                            { ref: IDs.DensityID(idx, 'visual', BaseRef + '_pos') }
+                        )
+                        .to(IDs.DensityID(idx, 'volume', BaseRef))
+                        .apply(
+                            StateTransforms.Representation.VolumeRepresentation3D,
+                            this.densityMapVisuals(display.densityMaps[idx], 'negative'),
+                            { ref: IDs.DensityID(idx, 'visual', BaseRef + '_neg') }
+                        )
+                        .commit();
+                } else {
+                    display.densityMaps[idx].isoValue = prettyIso(((isoRange.max - isoRange.min) / 2) + isoRange.min, bounds.step);
+
+                    await this.plugin.state.data.build().to(IDs.DensityID(idx, 'volume', BaseRef))
+                        .apply(
+                            StateTransforms.Representation.VolumeRepresentation3D,
+                            this.densityMapVisuals(display.densityMaps[idx], 'absolute'),
+                            { ref: IDs.DensityID(idx, 'visual', BaseRef) }
+                        )
+                        .commit();
+                }
+            }
         }
 
         this.haveMultipleModels = this.getModelCount() > 1;