Warning, /firebird/firebird-ng/src/app/pages/input-config/input-config.component.ts is written in an unsupported language. File is not indexed.
0001 import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core';
0002 import { FormControl } from '@angular/forms';
0003 import { ConfigService } from '../../services/config.service';
0004 import { ReactiveFormsModule } from '@angular/forms';
0005 import { RouterLink } from '@angular/router';
0006 import { ConfigProperty } from '../../utils/config-property';
0007 import { MatCard, MatCardContent, MatCardTitle } from '@angular/material/card';
0008 import { MatSlideToggle } from '@angular/material/slide-toggle';
0009 import { MatFormField } from '@angular/material/form-field';
0010 import { NgIf } from '@angular/common';
0011 import { MatInput, MatLabel } from '@angular/material/input';
0012 import { ResourceSelectComponent } from '../../components/resource-select/resource-select.component';
0013 import { defaultFirebirdConfig, ServerConfig, ServerConfigService } from '../../services/server-config.service';
0014 import { MatAccordion, MatExpansionPanel, MatExpansionPanelTitle, MatExpansionPanelHeader } from '@angular/material/expansion';
0015 import {ShellComponent} from "../../components/shell/shell.component";
0016 import {MatButton} from "@angular/material/button";
0017 import {MatSelect} from "@angular/material/select";
0018 import {MatOption} from "@angular/material/autocomplete";
0019
0020 @Component({
0021 selector: 'app-input-config',
0022 standalone: true,
0023 imports: [
0024 ReactiveFormsModule,
0025 RouterLink,
0026 MatCard,
0027 MatCardContent,
0028 MatCardTitle,
0029 MatSlideToggle,
0030 MatFormField,
0031 MatInput,
0032 MatLabel,
0033 ResourceSelectComponent,
0034 MatAccordion,
0035 MatExpansionPanel,
0036 MatExpansionPanelTitle,
0037 MatExpansionPanelHeader,
0038 ShellComponent,
0039 MatButton,
0040 MatSelect,
0041 MatOption,
0042 NgIf,
0043 ],
0044 templateUrl: './input-config.component.html',
0045 styleUrls: ['./input-config.component.scss']
0046 })
0047 export class InputConfigComponent implements OnInit, AfterViewInit {
0048
0049 @ViewChild('geometrySelect')
0050 geometrySelect!: ResourceSelectComponent;
0051
0052 @ViewChild('edm4eicSelect')
0053 edm4eicSelect!: ResourceSelectComponent;
0054
0055 @ViewChild('dexJsonSelect')
0056 dexJsonSelect!: ResourceSelectComponent;
0057
0058 @ViewChild('premadeGeometry') premadeGeometry!: ResourceSelectComponent;
0059
0060 selectedEventSource = new FormControl<string>('');
0061 onlyCentralDetector = new FormControl<boolean>(true);
0062 serverUseApi = new FormControl<boolean>(false);
0063 serverApiUrl = new FormControl<string>('http://localhost:5454');
0064 rootEventRange = new FormControl<string>('0');
0065
0066 // Add form controls and options
0067 geometryThemeName = new FormControl<string>('cool2');
0068 geometryCutListName = new FormControl<string>('off');
0069 geometryRootFilterName = new FormControl<string>('default');
0070 geometryFastAndUgly = new FormControl<boolean>(false);
0071 useController = new FormControl<boolean>(false);
0072
0073
0074 firebirdConfig: ServerConfig = defaultFirebirdConfig;
0075
0076 public geometryOptions: string[] = [
0077 "https://seeeic.org/g/epic/artifacts/tgeo/epic_craterlake.root",
0078 "https://seeeic.org/g/epic/artifacts/tgeo/epic_inner_detector.root",
0079 "https://seeeic.org/g/epic/artifacts/tgeo/epic_craterlake_tracking_only.root",
0080 "https://seeeic.org/g/epic/artifacts/tgeo/epic_calorimeters.root",
0081 "https://seeeic.org/g/epic/artifacts/tgeo/epic_pid_only.root",
0082 "https://seeeic.org/g/epic/artifacts/tgeo/epic_forward_detectors.root",
0083 "https://seeeic.org/g/epic/artifacts/tgeo/epic_ip6.root",
0084 "https://seeeic.org/g/epic/artifacts/tgeo/epic_ip6_extended.root",
0085 "https://seeeic.org/g/epic/artifacts/tgeo/epic_craterlake_no_bhcal.root",
0086 "https://seeeic.org/g/epic/artifacts/tgeo/epic_full.root",
0087 "https://seeeic.org/g/epic/artifacts/tgeo/epic_bhcal.root",
0088 "https://seeeic.org/g/epic/artifacts/tgeo/epic_dirc_only.root",
0089 "https://seeeic.org/g/epic/artifacts/tgeo/epic_drich_only.root",
0090 "https://seeeic.org/g/epic/artifacts/tgeo/epic_forward_detectors_with_inserts.root",
0091 "https://seeeic.org/g/epic/artifacts/tgeo/epic_imaging_only.root",
0092 "https://seeeic.org/g/epic/artifacts/tgeo/epic_lfhcal_only.root",
0093 "https://seeeic.org/g/epic/artifacts/tgeo/epic_lfhcal_with_insert.root",
0094 "https://seeeic.org/g/epic/artifacts/tgeo/epic_mrich_only.root",
0095 "https://seeeic.org/g/epic/artifacts/tgeo/epic_pfrich_only.root",
0096 "https://seeeic.org/g/epic/artifacts/tgeo/epic_tof_endcap_only.root",
0097 "https://seeeic.org/g/epic/artifacts/tgeo/epic_tof_only.root",
0098 "https://seeeic.org/g/epic/artifacts/tgeo/epic_vertex_only.root",
0099 "https://seeeic.org/g/epic/artifacts/tgeo/epic_zdc_lyso_sipm.root",
0100 "https://seeeic.org/g/epic/artifacts/tgeo/epic_zdc_sipm_on_tile_only.root"
0101 ];
0102
0103 public trajectoryOptions: string[] = [
0104 "https://seeeic.org/d/py8dis-nc_10x100_minq2-1000_minp-250mev_nevt-5_s.firebird.zip",
0105 "https://seeeic.org/d/py8dis-nc_10x100_minq2-1_minp-250mev_nevt-5_s.firebird.zip",
0106 "https://seeeic.org/d/py8dis-nc_18x275_minq2-1_minp-250mev_nevt-5.firebird_s.zip",
0107 "https://seeeic.org/d/py8dis-nc_18x275_minq2-1000_minp-250mev_nevt-5.firebird_s.zip",
0108 "https://seeeic.org/d/py8dis-nc_5x41_minq2-100_minp-250mev_nevt-5.firebird_s.zip",
0109 "https://seeeic.org/d/reco_py8dis-nc_10x100_minq2-1000_minp-250mev_nevt-5.firebird.zip",
0110 "https://seeeic.org/d/comb_py8dis-nc_10x100_minq2-1000_minp-250mev_nevt-5.firebird.zip",
0111 "https://seeeic.org/d/background_py6_10x100_egas_bgas_smooth.firebird.zip",
0112 "asset://data/dirc_optical.v0.4.firebird.zip",
0113 "asset://data/py8_dis-cc_5x41_minq2-1_minp-150mev_vtxcut-5m_nevt-5.v0.4.firebird.zip",
0114 "asset://data/py8_dis-cc_5x41_minq2-100_minp-150mev_vtxcut-5m_nevt-5.v0.4.firebird.zip",
0115 "asset://data/py8_dis-cc_10x100_minq2-1_minp-150mev_vtxcut-5m_nevt-5.v0.4.firebird.zip",
0116 "asset://data/py8_dis-cc_10x100_minq2-100_minp-150mev_vtxcut-5m_nevt-5.v0.4.firebird.zip",
0117 "asset://data/py8_dis-cc_10x100_minq2-1000_minp-150mev_vtxcut-5m_nevt-5.v0.4.firebird.zip",
0118 "asset://data/py8_dis-cc_18x275_minq2-1_minp-150mev_vtxcut-5m_nevt-5.v0.4.firebird.zip",
0119 "asset://data/py8_dis-cc_18x275_minq2-100_minp-150mev_vtxcut-5m_nevt-5.v0.4.firebird.zip",
0120 "asset://data/py8_dis-cc_18x275_minq2-1000_minp-150mev_vtxcut-5m_nevt-5.v0.4.firebird.zip",
0121 "asset://data/rec_dis_18x275_fdex-v0.4.edm4eic.v0.4.firebird.zip",
0122 ];
0123
0124
0125 public edm4eicOptions: string[] = [
0126 ""
0127 ];
0128
0129
0130 quickLinks: { [title: string]: { geometry: string; dexjson: string; edm4eic: string; eventRange?: string } } = {
0131 'Full ePIC detector geometry (no events)': {
0132 geometry: "https://seeeic.org/g/epic/artifacts/tgeo/epic_craterlake.root",
0133 dexjson: "",
0134 edm4eic: ""
0135 },
0136 'DIS NC in ePIC Beam=10x100 minQ2=1 Trajectories': {
0137 geometry: "https://seeeic.org/g/epic/artifacts/tgeo/epic_craterlake.root",
0138 dexjson: "https://seeeic.org/d/py8dis-nc_10x100_minq2-1000_minp-250mev_nevt-5_s.firebird.zip",
0139 edm4eic: ""
0140 },
0141 'DIS CC in ePIC Beam=18x275 minQ2=1': {
0142 geometry: "https://seeeic.org/g/epic/artifacts/tgeo/epic_craterlake.root",
0143 dexjson: "https://seeeic.org/d/py8dis-nc_18x275_minq2-1_minp-250mev_nevt-5.firebird_s.zip",
0144 edm4eic: ""
0145 },
0146 'DIS CC in ePIC Beam=18x275 minQ2=1000': {
0147 geometry: "https://seeeic.org/g/epic/artifacts/tgeo/epic_craterlake.root",
0148 dexjson: "https://seeeic.org/d/py8dis-nc_18x275_minq2-1000_minp-250mev_nevt-5.firebird_s.zip",
0149 edm4eic: ""
0150 },
0151 'DIS NC in ePIC Beam=5x41 minQ2=100 Trajectories': {
0152 geometry: "https://seeeic.org/g/epic/artifacts/tgeo/epic_craterlake.root",
0153 dexjson: "https://seeeic.org/d/py8dis-nc_5x41_minq2-100_minp-250mev_nevt-5.firebird_s.zip",
0154 edm4eic: ""
0155 },
0156 'Tracking reconstruction ePIC Beam=10x100': {
0157 geometry: "https://eic.github.io/epic/artifacts/tgeo/epic_craterlake_tracking_only.root",
0158 dexjson: "https://seeeic.org/d/reco_py8dis-nc_10x100_minq2-1000_minp-250mev_nevt-5.firebird.zip",
0159 edm4eic: ""
0160 },
0161 'Tracking + Trajectories ePIC Beam=10x100': {
0162 geometry: "https://eic.github.io/epic/artifacts/tgeo/epic_craterlake_tracking_only.root",
0163 dexjson: "https://seeeic.org/d/comb_py8dis-nc_10x100_minq2-1000_minp-250mev_nevt-5.firebird.zip",
0164 edm4eic: ""
0165 },
0166 'Event + Background ePIC Beam=10x100 (Large file)': {
0167 geometry: "https://seeeic.org/g/epic/artifacts/tgeo/epic_craterlake.root",
0168 dexjson: "https://seeeic.org/d/background_py6_10x100_egas_bgas_smooth.firebird.zip",
0169 edm4eic: ""
0170 },
0171 // 'Simulation campaign EDM4EIC': {
0172 // geometry: "https://eic.github.io/epic/artifacts/tgeo/epic_craterlake_tracking_only.root",
0173 // dexjson: "",
0174 // edm4eic: "root://dtn-eic.jlab.org//volatile/eic/EPIC/RECO/25.04.1/epic_craterlake/DIS/NC/18x275/minQ2=10/pythia8NCDIS_18x275_minQ2=10_beamEffects_xAngle=-0.025_hiDiv_1.0000.eicrecon.edm4eic.root"
0175 // },
0176 'DIRC optical photons': {
0177 geometry: "https://eic.github.io/epic/artifacts/tgeo/epic_dirc_only.root",
0178 dexjson: "asset://data/dirc_optical.v0.4.firebird.zip",
0179 edm4eic: ""
0180 }
0181 };
0182
0183 public get quickLinkTitles() {
0184 return Object.keys(this.quickLinks);
0185 }
0186
0187 constructor(
0188 private userConfigService: ConfigService,
0189 private firebirdConfigService: ServerConfigService
0190 ) {}
0191
0192 bindConfigToControl<T>(control: FormControl<T | null>, configName: string, defaultValue?: T): void {
0193 const existing = this.userConfigService.getConfig(configName);
0194
0195 if (!existing) {
0196 // If default provided — create silently and continue
0197 if (defaultValue !== undefined) {
0198 try {
0199 const created = this.userConfigService.createConfig(
0200 configName,
0201 defaultValue
0202 );
0203 if (created) {
0204 this.setupConfigBinding(control, created as any);
0205 }
0206 } catch (error) {
0207 console.error(`Failed to create config '${configName}':`, error);
0208 }
0209 } else {
0210 console.error(
0211 `Config '${configName}' not found and no default value provided`
0212 );
0213 }
0214 return;
0215 }
0216
0217 this.setupConfigBinding(control, existing as any);
0218 }
0219
0220 private setupConfigBinding<T>(control: FormControl<T | null>, config: any): void {
0221 control.setValue(config.value as T, { emitEvent: false });
0222
0223 config.changes$.subscribe((value: T) => {
0224 control.setValue(value, { emitEvent: false });
0225 });
0226
0227 control.valueChanges.subscribe((value: T | null) => {
0228 if (value !== null) {
0229 config.value = value;
0230 }
0231 });
0232 }
0233
0234
0235 ngAfterViewInit(): void {
0236 console.log('[ConfigPage] ngAfterViewInit');
0237
0238 this.bindConfigToControl<string>(this.geometrySelect.value, 'geometry.selectedGeometry', '');
0239 this.bindConfigToControl<string>(this.edm4eicSelect.value, 'events.rootEventSource', '');
0240 this.bindConfigToControl<string>(this.dexJsonSelect.value, 'events.dexEventsSource', '');
0241
0242 this.loadInitialConfig();
0243 }
0244
0245 selectedPreset = 'Full ePIC detector geometry (no events)';
0246
0247 ngOnInit(): void {
0248 this.bindConfigToControl(this.serverUseApi, 'server.useApi', false);
0249 this.bindConfigToControl(this.serverApiUrl, 'server.url', 'http://localhost:5454');
0250 this.bindConfigToControl(this.rootEventRange, 'events.rootEventRange', '0');
0251 this.bindConfigToControl(this.geometryThemeName, 'geometry.themeName', 'cool2');
0252 this.bindConfigToControl(this.geometryCutListName, 'geometry.cutListName', 'off');
0253 this.bindConfigToControl(this.geometryRootFilterName, 'geometry.rootFilterName', 'default');
0254 this.bindConfigToControl(this.geometryFastAndUgly, 'geometry.FastDefaultMaterial', false);
0255 this.bindConfigToControl(this.useController, 'controls.useController', false);
0256
0257 this.firebirdConfig = this.firebirdConfigService.config;
0258
0259 setTimeout(() => {
0260 this.geometrySelect?.value.setValue(this.userConfigService.getConfig('geometry.selectedGeometry')?.value);
0261 this.edm4eicSelect?.value.setValue(this.userConfigService.getConfig('events.rootEventSource')?.value);
0262 this.dexJsonSelect?.value.setValue(this.userConfigService.getConfig('events.dexEventsSource')?.value);
0263 });
0264 }
0265
0266
0267 onPresetChange(newValue: string) {
0268 this.selectedPreset = newValue;
0269 const config = this.quickLinks[newValue];
0270 if (!config) return;
0271
0272 this.userConfigService.getConfig('geometry.selectedGeometry')!.value = config.geometry;
0273 this.userConfigService.getConfig('events.dexEventsSource')!.value = config.dexjson;
0274 this.userConfigService.getConfig('events.rootEventSource')!.value = config.edm4eic;
0275 if (config.eventRange != null) {
0276 this.userConfigService.getConfig('events.rootEventRange')!.value = config.eventRange;
0277 }
0278 }
0279
0280 private loadInitialConfig() {
0281 const savedDex = this.userConfigService.getConfig('events.dexEventsSource')?.value;
0282 const savedGeom = this.userConfigService.getConfig('geometry.selectedGeometry')?.value;
0283 if (savedDex || savedGeom) return;
0284
0285 if (this.quickLinks[this.selectedPreset]) {
0286 this.onPresetChange(this.selectedPreset);
0287 }
0288 }
0289
0290 resetGeometryToDefaults() {
0291 this.userConfigService.getConfig('geometry.themeName')?.setDefault();
0292 this.userConfigService.getConfig('geometry.cutListName')?.setDefault();
0293 this.userConfigService.getConfig('geometry.rootFilterName')?.setDefault();
0294 }
0295 }