From a7489e6c603af7bc84feb88c8c7952ed31cdd3a5 Mon Sep 17 00:00:00 2001 From: Dmitry Romanov Date: Wed, 15 May 2024 20:39:47 -0400 Subject: [PATCH] Update --- firebird-ng/src/app/geometry.service.ts | 177 ++++-------------- .../input-config/input-config.component.ts | 12 +- .../src/app/root-geometry.processor.ts | 146 +++++++++++++++ 3 files changed, 193 insertions(+), 142 deletions(-) create mode 100644 firebird-ng/src/app/root-geometry.processor.ts diff --git a/firebird-ng/src/app/geometry.service.ts b/firebird-ng/src/app/geometry.service.ts index 0c21944..0528cb8 100644 --- a/firebird-ng/src/app/geometry.service.ts +++ b/firebird-ng/src/app/geometry.service.ts @@ -1,3 +1,4 @@ + import {Injectable} from '@angular/core'; //import { openFile } from '../../../jsroot/core.mjs'; //import * as ROOT from '../../../jsroot/build; @@ -10,40 +11,10 @@ import { PruneRuleActions, removeGeoNode, testGeoBit } from './utils/cern-root.utils'; import {build} from 'jsrootdi/geom'; +import {BehaviorSubject} from "rxjs"; +import {RootGeometryProcessor} from "./root-geometry.processor"; -export class DetectorGeometryFineTuning { - namePattern: string = ""; - editRules: GeoNodeEditRule[] = []; -} - - -function pruneTopLevelDetectors(geoManager: any, removeNames: string[]): any { - const volume = geoManager.fMasterVolume === undefined ? geoManager.fVolume : geoManager.fMasterVolume; - const nodes: any[] = volume?.fNodes?.arr ?? []; - let removedNodes: any[] = []; - - // Don't have nodes? Have problems? - if(!nodes.length) { - return {nodes, removedNodes}; - } - - // Collect nodes to remove - for(let node of nodes) { - let isRemoving = removeNames.some(substr => node.fName.startsWith(substr)) - if(isRemoving) { - removedNodes.push(node); - } - } - - // Now remove nodes - for(let node of removedNodes) { - removeGeoNode(node); - } - - return {nodes, removedNodes} -} - @Injectable({ @@ -51,81 +22,32 @@ function pruneTopLevelDetectors(geoManager: any, removeNames: string[]): any { }) export class GeometryService { - /** - * Detectors (top level TGeo nodes) to be removed. - * (!) startsWith function is used for filtering (aka: detector.fName.startsWith(removeDetectorNames[i]) ... ) - */ - removeDetectorNames: string[] = [ - "Lumi", - "Magnet", - "B0", - "B1", - "B2", - "Q0", - "Q1", - "Q2", - "BeamPipe", - "Pipe", - "ForwardOffM", - "Forward", - "Backward", - "Vacuum", - "SweeperMag", - "AnalyzerMag", - "ZDC", - "LFHCAL", - "HcalFarForward" - ]; - - subDetectorsRules: DetectorGeometryFineTuning[] = [ - { - namePattern: "*/EcalBarrelScFi*", - editRules: [ - {pattern: "*/fiber_grid*", prune:PruneRuleActions.Remove}, - ] - }, - { - namePattern: "*/EcalBarrelImaging*", - editRules: [ - {pattern: "*/stav*", prune:PruneRuleActions.RemoveChildren}, - ] - }, - { - namePattern: "*/DRICH*", - editRules: [ - {pattern: "*/DRICH_cooling*", prune:PruneRuleActions.RemoveSiblings}, - ] - }, - { - namePattern: "*/EcalEndcapN*", - editRules: [ - {pattern: "*/crystal*", prune:PruneRuleActions.RemoveSiblings}, - ] - }, - { - namePattern: "*/HcalEndcapPInsert_23*", - editRules: [ - {pattern: "*/*layer*slice1_*", prune:PruneRuleActions.RemoveSiblings}, - ] - }, - { - namePattern: "*/HcalBarrel*", - editRules: [ - {pattern: "*/Tile*", prune:PruneRuleActions.Remove}, - {pattern: "*/ChimneyTile*", prune:PruneRuleActions.Remove}, - ] - }, - { - namePattern: "*/EndcapTOF*", - editRules: [ - {pattern: "*/suppbar*", prune:PruneRuleActions.Remove}, - {pattern: "*/component*3", prune:PruneRuleActions.RemoveSiblings}, - ] - } - - ] + rootGeometryProcessor = new RootGeometryProcessor(); constructor() { + this.load(); + } + + private stateSubject = new BehaviorSubject(this.load()); + state$ = this.stateSubject.asObservable(); + + save(state: any) { + localStorage.setItem('geometrySettings', JSON.stringify(state)); + this.stateSubject.next(state); + } + + load(): any { + const settings = localStorage.getItem('geometrySettings'); + return settings ? JSON.parse(settings) : { + selectedGeometry: 'epic-central-optimized', + geoOptEnabled: true, + selectedGeoCutoff: 'Central detector', + geoPostEnabled: true + }; + } + + getState() { + return this.stateSubject.value; } @@ -135,55 +57,34 @@ export class GeometryService { let url: string = 'https://eic.github.io/epic/artifacts/tgeo/epic_full.root'; // >oO let objectName = 'default'; - console.log(`Loading file ${url}`) + console.time('[GeoSrv]: Total load geometry time'); + console.log(`[GeoSrv]: Loading file ${url}`) - console.time('Open root file'); + console.time('[GeoSrv]: Open root file'); const file = await openFile(url); // >oO debug console.log(file); - console.timeEnd('Open root file'); + console.timeEnd('[GeoSrv]: Open root file'); - console.time('Reading geometry from file'); + console.time('[GeoSrv]: Reading geometry from file'); const rootGeoManager = await findGeoManager(file) // await file.readObject(objectName); // >oO console.log(geoManager); - console.timeEnd('Reading geometry from file'); - - // Getting main detector nodes - let result = pruneTopLevelDetectors(rootGeoManager, this.removeDetectorNames); - console.log("Filtered top level detectors: ", result); + console.timeEnd('[GeoSrv]: Reading geometry from file'); - // >oO analyzeGeoNodes(rootGeoManager, 1); - // Now we go with the fine tuning each detector - for(let detector of this.subDetectorsRules) { - let topDetNode = findSingleGeoNode(rootGeoManager, detector.namePattern, 1); - console.log(`Processing ${topDetNode}`); - if(!topDetNode) { - continue; - } - console.time(`Process sub-detector: ${detector.namePattern}`); - for(let rule of detector.editRules) { + console.time('[GeoSrv]: Root geometry pre-processing'); + this.rootGeometryProcessor.process(rootGeoManager); + console.time('[GeoSrv]: Root geometry pre-processing'); - editGeoNodes(topDetNode, [rule]) - } - console.timeEnd(`Process sub-detector: ${detector.namePattern}`); - } - - console.log(`Done processing ${this.subDetectorsRules.length} detectors`); - - console.log(`---- DETECTOR ANALYSIS ----`); analyzeGeoNodes(rootGeoManager, 1); - console.log(`---- END DETECTOR ANALYSIS ----`); - - //analyzeGeoNodes(geoManager, 1); - // return {rootGeoManager: null, rootObject3d: null}; // - console.time('Build geometry'); + console.time('[GeoSrv]: Build geometry'); let rootObject3d = build(rootGeoManager, { numfaces: 500000000, numnodes: 50000000, instancing:1, dflt_colors: false, vislevel: 100, doubleside:true, transparency:true}); - console.timeEnd('Build geometry'); + console.timeEnd('[GeoSrv]: Build geometry'); // >oO console.log(geo); + console.timeEnd('[GeoSrv]: Total load geometry time'); return {rootGeoManager, rootObject3d}; } } diff --git a/firebird-ng/src/app/input-config/input-config.component.ts b/firebird-ng/src/app/input-config/input-config.component.ts index 16e3f1f..346d8cd 100644 --- a/firebird-ng/src/app/input-config/input-config.component.ts +++ b/firebird-ng/src/app/input-config/input-config.component.ts @@ -31,10 +31,14 @@ export class InputConfigComponent implements OnInit { } ngOnInit(): void { - // const savedSettings = this.geometryService.load(); - // if (savedSettings) { - // this.geoForm.setValue(savedSettings); - // } + const savedSettings = this.geometryService.getState(); + if (savedSettings) { + this.geoForm.setValue(savedSettings); + } + + this.geometryService.state$.subscribe(state => { + this.geoForm.setValue(state, { emitEvent: false }); + }); } } diff --git a/firebird-ng/src/app/root-geometry.processor.ts b/firebird-ng/src/app/root-geometry.processor.ts new file mode 100644 index 0000000..f91edb6 --- /dev/null +++ b/firebird-ng/src/app/root-geometry.processor.ts @@ -0,0 +1,146 @@ +import {Injectable} from '@angular/core'; +//import { openFile } from '../../../jsroot/core.mjs'; +//import * as ROOT from '../../../jsroot/build; +import {openFile} from 'jsrootdi'; +import { + analyzeGeoNodes, + editGeoNodes, + findGeoManager, findGeoNodes, findSingleGeoNode, geoBITS, + GeoNodeEditRule, printAllGeoBitsStatus, + PruneRuleActions, removeGeoNode, testGeoBit +} from './utils/cern-root.utils'; +import {build} from 'jsrootdi/geom'; +import {BehaviorSubject} from "rxjs"; + + +export class DetectorGeometryFineTuning { + namePattern: string = ""; + editRules: GeoNodeEditRule[] = []; +} + + +function pruneTopLevelDetectors(geoManager: any, removeNames: string[]): any { + const volume = geoManager.fMasterVolume === undefined ? geoManager.fVolume : geoManager.fMasterVolume; + const nodes: any[] = volume?.fNodes?.arr ?? []; + let removedNodes: any[] = []; + + // Don't have nodes? Have problems? + if(!nodes.length) { + return {nodes, removedNodes}; + } + + // Collect nodes to remove + for(let node of nodes) { + let isRemoving = removeNames.some(substr => node.fName.startsWith(substr)) + if(isRemoving) { + removedNodes.push(node); + } + } + + // Now remove nodes + for(let node of removedNodes) { + removeGeoNode(node); + } + + return {nodes, removedNodes} +} + +export class RootGeometryProcessor { + /** + * Detectors (top level TGeo nodes) to be removed. + * (!) startsWith function is used for filtering (aka: detector.fName.startsWith(removeDetectorNames[i]) ... ) + */ + removeDetectorNames: string[] = [ + "Lumi", + "Magnet", + "B0", + "B1", + "B2", + "Q0", + "Q1", + "Q2", + "BeamPipe", + "Pipe", + "ForwardOffM", + "Forward", + "Backward", + "Vacuum", + "SweeperMag", + "AnalyzerMag", + "ZDC", + "LFHCAL", + "HcalFarForward" + ]; + + subDetectorsRules: DetectorGeometryFineTuning[] = [ + { + namePattern: "*/EcalBarrelScFi*", + editRules: [ + {pattern: "*/fiber_grid*", prune: PruneRuleActions.Remove}, + ] + }, + { + namePattern: "*/EcalBarrelImaging*", + editRules: [ + {pattern: "*/stav*", prune: PruneRuleActions.RemoveChildren}, + ] + }, + { + namePattern: "*/DRICH*", + editRules: [ + {pattern: "*/DRICH_cooling*", prune: PruneRuleActions.RemoveSiblings}, + ] + }, + { + namePattern: "*/EcalEndcapN*", + editRules: [ + {pattern: "*/crystal*", prune: PruneRuleActions.RemoveSiblings}, + ] + }, + { + namePattern: "*/HcalEndcapPInsert_23*", + editRules: [ + {pattern: "*/*layer*slice1_*", prune: PruneRuleActions.RemoveSiblings}, + ] + }, + { + namePattern: "*/HcalBarrel*", + editRules: [ + {pattern: "*/Tile*", prune: PruneRuleActions.Remove}, + {pattern: "*/ChimneyTile*", prune: PruneRuleActions.Remove}, + ] + }, + { + namePattern: "*/EndcapTOF*", + editRules: [ + {pattern: "*/suppbar*", prune: PruneRuleActions.Remove}, + {pattern: "*/component*3", prune: PruneRuleActions.RemoveSiblings}, + ] + } + ] + + public process(rootGeoManager:any):any { + // Getting main detector nodes + let result = pruneTopLevelDetectors(rootGeoManager, this.removeDetectorNames); + console.log("Filtered top level detectors: ", result); + + + // >oO analyzeGeoNodes(rootGeoManager, 1); + // Now we go with the fine-tuning of each detector + for(let detector of this.subDetectorsRules) { + let topDetNode = findSingleGeoNode(rootGeoManager, detector.namePattern, 1); + console.log(`Processing ${topDetNode}`); + if(!topDetNode) { + continue; + } + console.time(`Process sub-detector: ${detector.namePattern}`); + for(let rule of detector.editRules) { + + editGeoNodes(topDetNode, [rule]) + } + console.timeEnd(`Process sub-detector: ${detector.namePattern}`); + } + + console.log(`Done processing ${this.subDetectorsRules.length} detectors`); + } +}