From 8e0e958e9a4cef6e16801a4f2c9d6258d8d7afd9 Mon Sep 17 00:00:00 2001 From: Damiano Clementel Date: Tue, 9 Apr 2024 16:16:46 +0100 Subject: [PATCH] Detaches settings service from structure service --- .../representation/representation.service.ts | 27 ++++++++++--- .../src/lib/services/structure.service.ts | 40 +++++++++---------- 2 files changed, 40 insertions(+), 27 deletions(-) diff --git a/projects/ngx-structure-viewer/src/lib/services/representation/representation.service.ts b/projects/ngx-structure-viewer/src/lib/services/representation/representation.service.ts index 7adda84..3df2992 100644 --- a/projects/ngx-structure-viewer/src/lib/services/representation/representation.service.ts +++ b/projects/ngx-structure-viewer/src/lib/services/representation/representation.service.ts @@ -1,4 +1,4 @@ -import { Observable, ReplaySubject, Subscription, combineLatestWith, from, map, shareReplay, switchMap } from 'rxjs'; +import { Observable, ReplaySubject, Subscription, combineLatestWith, from, map, shareReplay, switchMap, withLatestFrom } from 'rxjs'; import { Injectable, OnDestroy } from '@angular/core'; // Molstar dependencies import { Structure, StructureElement, StructureProperties as SP, StructureSelection } from 'molstar/lib/mol-model/structure'; @@ -82,6 +82,23 @@ export class RepresentationService implements OnDestroy { const interactions$ = this.getInteractionsRepresentation(); // Combine structure emission this.representation$ = this.structureService.structure$.pipe( + // Get latest source + withLatestFrom(this.structureService.source$), + // TODO Generate loci representation + switchMap(([structure, source]) => from((async () => { + // Define reference for current plugin + const plugin = this.pluginService.plugin; + // Create component for the whole structure + const component = await plugin.builders.structure.tryCreateComponentStatic(structure, 'polymer', { label: source.label }); + // Define color + const [ value ] = fromHexString(this.settingsService.settings['backbone-color']); + // Initialize white representation + await plugin.builders.structure.representation.addRepresentation(component!, { + type: 'cartoon', + color: 'uniform', + colorParams: { value }, + }); + })())), // Combine with structure initialization combineLatestWith(this.canvasService.initialized$), // With loci representation pipeline @@ -142,7 +159,7 @@ export class RepresentationService implements OnDestroy { for (const { ids, color: hex } of loci) { // Define current Mol* loci // const locus = getLociFromRange(start, end, structure); - const locus = getLocusFromSet(ids, structure); + const locus = getLocusFromSet(ids, structure.cell?.obj?.data); // Define current Mol* bundle const bundle = StructureElement.Bundle.fromLoci(locus); // Compute color @@ -155,7 +172,7 @@ export class RepresentationService implements OnDestroy { // Initialize plugin update const update = plugin.state.data.build(); // Filter bundle of layers - const bundle = getFilteredBundle(layers, structure); + const bundle = getFilteredBundle(layers, structure.cell?.obj?.data); // Loop through structures in plugin for (const structureRef of plugin.managers.structure.hierarchy.current.structures) { // Loop through components in current structure @@ -170,7 +187,7 @@ export class RepresentationService implements OnDestroy { Overpaint.toBundle(bundle as never) ); // TODO Define locus for all residues - const _locus = getLocusFromSet([...this.structureService.i2r.values()], structure); + const _locus = getLocusFromSet([...this.structureService.i2r.values()], structure.cell?.obj?.data as Structure); const _bundle = StructureElement.Bundle.fromLoci(_locus); // eslint-disable-next-line @typescript-eslint/no-unused-vars const [_color, alpha] = fromHexString(this.settingsService.settings['backbone-color']); @@ -204,7 +221,7 @@ export class RepresentationService implements OnDestroy { // Define interactors const interactors = interactions.reduce((acc, { from, to }) => [...acc, from, to], [] as Interactor[]); // Loop through each atom in the structure - Structure.eachAtomicHierarchyElement(structure, ({ + Structure.eachAtomicHierarchyElement(structure.cell?.obj?.data as Structure, ({ // Define function for each atom atom: (a) => { // Define coordinates vector diff --git a/projects/ngx-structure-viewer/src/lib/services/structure.service.ts b/projects/ngx-structure-viewer/src/lib/services/structure.service.ts index f712a1a..a3d5fed 100644 --- a/projects/ngx-structure-viewer/src/lib/services/structure.service.ts +++ b/projects/ngx-structure-viewer/src/lib/services/structure.service.ts @@ -1,18 +1,18 @@ import { Observable, ReplaySubject, combineLatest, from, map, shareReplay, switchMap, tap } from 'rxjs'; import { Structure, StructureProperties } from 'molstar/lib/mol-model/structure'; +// import { StateObjectRef } from 'molstar/lib/mol-state'; import { Asset } from 'molstar/lib/mol-util/assets'; import { Injectable } from '@angular/core'; // Custom services -import { SettingsService } from './settings.service'; +// import { SettingsService } from './settings.service'; import { PluginService } from './plugin.service'; import { Source } from '../interfaces/source'; -import { fromHexString } from '../colors'; - @Injectable({ providedIn: 'platform' }) export class StructureService { - readonly structure$: Observable; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + readonly structure$: Observable; // TODO readonly source$ = new ReplaySubject; @@ -25,7 +25,7 @@ export class StructureService { public i2r!: Map; constructor( - public settingsService: SettingsService, + // public settingsService: SettingsService, public pluginService: PluginService, ) { const plugin$ = this.pluginService.plugin$; @@ -56,22 +56,18 @@ export class StructureService { const trajectory = await plugin.builders.structure.parseTrajectory(data, source.format); // Create model const model = await plugin.builders.structure.createModel(trajectory, { modelIndex: 0 }); - // Create structure - const name = 'model'; - const params = {}; - const structure = await plugin.builders.structure.createStructure(model, { name, params }); - // Create component for the whole structure - const component = await plugin.builders.structure.tryCreateComponentStatic(structure, 'polymer', { label: source.label }); - // Define color - const [ value ] = fromHexString(this.settingsService.settings['backbone-color']); - // Initialize white representation - await plugin.builders.structure.representation.addRepresentation(component!, { - type: 'cartoon', - color: 'uniform', - colorParams: { value }, - }); - // Return structure data - return structure.cell?.obj?.data as Structure; + // TODO Create structure + return plugin.builders.structure.createStructure(model, { name: 'model', params: {} }); + // // Create component for the whole structure + // const component = await plugin.builders.structure.tryCreateComponentStatic(structure, 'polymer', { label: source.label }); + // // Define color + // const [ value ] = fromHexString(this.settingsService.settings['backbone-color']); + // // Initialize white representation + // await plugin.builders.structure.representation.addRepresentation(component!, { + // type: 'cartoon', + // color: 'uniform', + // colorParams: { value }, + // }); })())), // Get residues data out of structure tap((structure) => { @@ -81,7 +77,7 @@ export class StructureService { const r2i = this.r2i = new Map(); const i2r = this.i2r = new Map(); // Loop through each residue - Structure.eachAtomicHierarchyElement(structure, ({ + Structure.eachAtomicHierarchyElement(structure.cell?.obj?.data as Structure, ({ // Do nothing on residue loop residue: (r) => { // Define residue index