From df9540b89be29684bf99929c3a0f600c7d8f2fef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Mal=C3=BD?= <michal.maly@ibt.cas.cz> Date: Wed, 9 Nov 2022 18:48:52 +0100 Subject: [PATCH] ReDNATCO plugin stage 32 --- src/apps/rednatco/api-impl.ts | 4 ++-- src/apps/rednatco/api.ts | 2 +- src/apps/rednatco/idents.ts | 7 ++++++ src/apps/rednatco/index.tsx | 4 ++-- src/apps/rednatco/viewer.ts | 43 ++++++++++++++++++++++++++++++++--- 5 files changed, 52 insertions(+), 8 deletions(-) diff --git a/src/apps/rednatco/api-impl.ts b/src/apps/rednatco/api-impl.ts index a24cca51f..4121bb9e9 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(data: string, type: 'cif'|'pdb') { + loadStructure(coords: { data: string, type: 'cif'|'pdb' }, densityMap: { data: Uint8Array, type: 'ccp4'|'dsn6' }|null) { this.check(); - this.target!.loadStructure(data, type); + this.target!.loadStructure(coords, densityMap); } 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 dcf9854ac..549b8a448 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: (data: string, type: 'cif'|'pdb') => void; + loadStructure: (coords: { data: string, type: 'cif'|'pdb'}, densityMap: { data: Uint8Array, type: 'ccp4'|'dsn6' }|null) => void; query: <T extends Queries.Type>(type: T) => ResponseTypes[T]; } } diff --git a/src/apps/rednatco/idents.ts b/src/apps/rednatco/idents.ts index 96a74d6be..91b5b4c91 100644 --- a/src/apps/rednatco/idents.ts +++ b/src/apps/rednatco/idents.ts @@ -8,6 +8,7 @@ export type ID = 'structure' | /* Possibly filtered structure as PSO - this is what shall be used to create visuals from */ 'visual' | /* Visual PSO - the thing that is actually drawn on the screen */ 'pyramids'|'superposition'; /* Additional identifiers for DNATCO-specific objects */ + export type Substructure = 'nucleic'|'protein'|'water'|'selected-slice'|'remainder-slice'; export function ID(id: ID, sub: Substructure|'', ref: string) { @@ -16,6 +17,12 @@ export function ID(id: ID, sub: Substructure|'', ref: string) { return `${ref}_${sub}_${id}`; } +export type DensityID = 'data'|'volume'|'visual'; + +export function DensityID(id: DensityID, ref: string) { + return `${ref}_density-map_${id}`; +} + export function isVisual(ident: string) { return ident.endsWith('_visual'); } diff --git a/src/apps/rednatco/index.tsx b/src/apps/rednatco/index.tsx index ae047f25b..e5a86b0ae 100644 --- a/src/apps/rednatco/index.tsx +++ b/src/apps/rednatco/index.tsx @@ -204,9 +204,9 @@ export class ReDNATCOMsp extends React.Component<ReDNATCOMsp.Props, State> { } } - loadStructure(data: string, type: 'pdb'|'cif') { + loadStructure(coords: { data: string, type: 'pdb'|'cif' }, densityMap: { data: Uint8Array, type: 'ccp4'|'dsn6' }|null) { if (this.viewer) { - this.viewer.loadStructure(data, type, this.state.display).then(() => { + this.viewer.loadStructure(coords, densityMap, this.state.display).then(() => { this.presentConformers = this.viewer!.getPresentConformers(); this.forceUpdate(); ReDNATCOMspApi.event(Api.Events.StructureLoaded()); diff --git a/src/apps/rednatco/viewer.ts b/src/apps/rednatco/viewer.ts index 06195b5df..8c609374f 100644 --- a/src/apps/rednatco/viewer.ts +++ b/src/apps/rednatco/viewer.ts @@ -16,6 +16,7 @@ import { BoundaryHelper } from '../../mol-math/geometry/boundary-helper'; import { Vec3 } from '../../mol-math/linear-algebra/3d'; import { EmptyLoci, Loci } from '../../mol-model/loci'; import { ElementIndex, Model, StructureElement, StructureProperties, StructureSelection, Trajectory } from '../../mol-model/structure'; +// import { Volume } from '../../mol-model/volume'; import { structureUnion, structureSubtract } from '../../mol-model/structure/query/utils/structure-set'; import { Location } from '../../mol-model/structure/structure/element/location'; import { MmcifFormat } from '../../mol-model-formats/structure/mmcif'; @@ -799,16 +800,20 @@ export class ReDNATCOMspViewer { return this.has('structure', '', BaseRef); } - async loadStructure(data: string, type: 'pdb'|'cif', display: Display) { + async loadStructure( + coords: { data: string, type: 'pdb'|'cif' }, + densityMap: { data: Uint8Array, type: 'ccp4'|'dsn6' }|null, + display: Display + ) { // TODO: Remove the currently loaded structure const chainColor = Color(display.chainColor); const waterColor = Color(display.waterColor); - const b = (t => type === 'pdb' + const b = (t => coords.type === 'pdb' ? t.apply(StateTransforms.Model.TrajectoryFromPDB, {}, { ref: IDs.ID('trajectory', '', BaseRef) }) : t.apply(StateTransforms.Data.ParseCif).apply(StateTransforms.Model.TrajectoryFromMmCif, {}, { ref: IDs.ID('trajectory', '', BaseRef) }) - )(this.plugin.state.data.build().toRoot().apply(RawData, { data }, { ref: IDs.ID('data', '', BaseRef) })) + )(this.plugin.state.data.build().toRoot().apply(RawData, { data: coords.data }, { ref: IDs.ID('data', '', BaseRef) })) .apply(StateTransforms.Model.ModelFromTrajectory, { modelIndex: display.modelNumber ? display.modelNumber - 1 : 0 }, { ref: IDs.ID('model', '', BaseRef) }) .apply(StateTransforms.Model.StructureFromModel, {}, { ref: IDs.ID('entire-structure', '', BaseRef) }) // Extract substructures @@ -885,6 +890,38 @@ export class ReDNATCOMspViewer { await b3.commit(); + // Load density map, if any + if (densityMap) { + const [ParseTransform, VolumeTransform] = densityMap.type === 'ccp4' + ? [StateTransforms.Data.ParseCcp4, StateTransforms.Volume.VolumeFromCcp4] + : [StateTransforms.Data.ParseDsn6, StateTransforms.Volume.VolumeFromDsn6]; + const b4 = this.plugin.state.data.build(); + b4.toRoot() + .apply(RawData, { data: densityMap.data }, { ref: IDs.DensityID('data', BaseRef) }) + .apply(ParseTransform) + .apply(VolumeTransform, {}, { ref: IDs.DensityID('volume', BaseRef) }) + .apply( + StateTransforms.Representation.VolumeRepresentation3D, + { + type: { + name: 'isosurface', + params: { + alpha: 0.5, + visuals: ['wireframe'], + sizeFactor: 0.75, + } + }, + colorTheme: { + name: 'uniform', + params: { value: Color(0x000000) }, + }, + }, + { ref: IDs.DensityID('visual', BaseRef) } + ); + + await b4.commit(); + } + this.haveMultipleModels = this.getModelCount() > 1; const ntcInfo = this.gatherStepInfo(); -- GitLab