Warning, /firebird/firebird-ng/src/app/utils/epic-geometry-arranger.ts is written in an unsupported language. File is not indexed.
0001 import {Object3D, Group} from "three";
0002
0003 // Main detector areas
0004 export const GROUP_FORWARD = "Forward";
0005 export const GROUP_CENTRAL = "Central";
0006 export const GROUP_BACKWARD = "Backward";
0007
0008 // Central detector subgroups
0009 export const GROUP_CALORIMETRY = "Calorimeters";
0010 export const GROUP_TRACKING = "Tracking";
0011 export const GROUP_PID = "PID";
0012 export const GROUP_MAGNETS = "Magnets";
0013 export const GROUP_SUPPORT = "Beam pipe, support";
0014
0015 // All groups for central detector
0016 export const CENTRAL_DETECTOR_GROUPS = [
0017 GROUP_CALORIMETRY,
0018 GROUP_TRACKING,
0019 GROUP_PID,
0020 GROUP_MAGNETS,
0021 GROUP_SUPPORT,
0022 ]
0023
0024
0025 let categoriesByDetName = new Map<string, string>([
0026
0027 // Central
0028 ["SolenoidBarrel_assembly", GROUP_MAGNETS],
0029 ["SolenoidEndcapP", GROUP_MAGNETS],
0030 ["SolenoidEndcapN", GROUP_MAGNETS],
0031
0032 ["VertexBarrelSubAssembly", GROUP_TRACKING],
0033
0034 ["InnerSiTrackerSubAssembly", GROUP_TRACKING],
0035 ["MiddleSiBarrelSubAssembly", GROUP_TRACKING],
0036 ["OuterSiBarrelSubAssembly", GROUP_TRACKING],
0037 ["MiddleSiEndcapSubAssembly", GROUP_TRACKING],
0038 ["OuterSiEndcapSubAssembly", GROUP_TRACKING],
0039 ["EndcapMPGDSubAssembly", GROUP_TRACKING],
0040 ["InnerMPGDBarrelSubAssembly", GROUP_TRACKING],
0041 ["EndcapTOFSubAssembly", GROUP_PID],
0042 ["BarrelTOFSubAssembly", GROUP_PID],
0043 ["OuterBarrelMPGDSubAssembly", GROUP_TRACKING],
0044
0045 // Tracking supports
0046 ["SVT_IB_Support_L2_assembly", GROUP_SUPPORT],
0047 ["SVT_IB_Support_L1_assembly", GROUP_SUPPORT],
0048 ["SVT_IB_Support_L0_L1_assembly", GROUP_SUPPORT],
0049 ["InnerTrackerSupport_assembly", GROUP_SUPPORT],
0050
0051 // PID
0052 ["DIRC", GROUP_PID],
0053 ["RICHEndcapN", GROUP_PID],
0054 ["DRICH", GROUP_PID],
0055
0056 // Fluxes
0057 ["FluxBarrel", GROUP_SUPPORT],
0058 ["FluxEndcapP", GROUP_SUPPORT],
0059 ["FluxEndcapN", GROUP_SUPPORT],
0060
0061
0062 // Calorimeters
0063 ["EcalEndcapP", GROUP_CALORIMETRY],
0064 ["EcalBarrelTrackerSubAssembly", GROUP_TRACKING],
0065 ["EcalBarrelScFi", GROUP_CALORIMETRY],
0066 ["EcalEndcapN", GROUP_CALORIMETRY],
0067 ["LFHCAL", GROUP_CALORIMETRY],
0068 ["HcalEndcapPInsert", GROUP_CALORIMETRY],
0069 ["HcalBarrel", GROUP_CALORIMETRY],
0070 ["HcalEndcapN", GROUP_CALORIMETRY],
0071
0072 // Beam pipe
0073 ["BeamPipe_assembly", GROUP_SUPPORT],
0074
0075
0076 // ========= FORWARD =============
0077 ["Pipe_cen_to_pos_assembly", GROUP_FORWARD], // Electron beampipe
0078
0079
0080 // B0
0081 ["B0Window_vol_ExitWindow", GROUP_FORWARD],
0082 ["Q0EF_BeamlineMagnet_assembly", GROUP_FORWARD], // Magnet around Electron beampipe
0083 ["B0TrackerSubAssembly", GROUP_FORWARD],
0084 ["B0PF_BeamlineMagnet_assembly", GROUP_FORWARD],
0085 ["B0ECal", GROUP_FORWARD],
0086
0087 ["B0APF_BeamlineMagnet_assembly", GROUP_FORWARD], // After B0
0088 ["Q1APF_BeamlineMagnet_assembly", GROUP_FORWARD], // Inner
0089 ["Q1BPF_BeamlineMagnet_assembly", GROUP_FORWARD], // Outer
0090 ["Q1EF_BeamlineMagnet_assembly", GROUP_FORWARD], // Around Electron Beampipe
0091 ["Q2PF_BeamlineMagnet_assembly", GROUP_FORWARD], // Further
0092 ["B1PF_BeamlineMagnet_assembly", GROUP_FORWARD], // After Q2PF
0093 ["B1APF_BeamlineMagnet_assembly", GROUP_FORWARD], // after B1PF
0094
0095 // Off momentum + Roman pods
0096 ["BeamPipeB0_assembly", GROUP_FORWARD], // after B1APF
0097 ["ForwardOffMTracker_station_1", GROUP_FORWARD], // Inside BeamPipeB0_assembly
0098 ["ForwardOffMTracker_station_2", GROUP_FORWARD], // Inside BeamPipeB0_assembly
0099 ["ForwardOffMTracker_station_3", GROUP_FORWARD], // Inside BeamPipeB0_assembly
0100 ["ForwardOffMTracker_station_4", GROUP_FORWARD], // Inside BeamPipeB0_assembly
0101
0102 ["ForwardRomanPot_Station_1", GROUP_FORWARD],
0103 ["ForwardRomanPot_Station_2", GROUP_FORWARD],
0104
0105
0106 // ZDC
0107 ["ZDC_Crystal_envelope", GROUP_FORWARD],
0108 ["HcalFarForwardZDC_SiPMonTile", GROUP_FORWARD],
0109
0110 ["VacuumMagnetElement_assembly", GROUP_FORWARD], // Tube after ZDC
0111
0112 // ========== BACKWARD =============
0113 ["Pipe_Q1eR_to_B2BeR_assembly", GROUP_FORWARD], // Electron pipe
0114 ["Q1ER_BeamlineMagnet_assembly", GROUP_BACKWARD], // Around electron pipeline
0115 ["Q1APR_BeamlineMagnet_assembly", GROUP_BACKWARD], // Around this pipe
0116
0117 ["Q2ER_BeamlineMagnet_assembly", GROUP_BACKWARD], // Next pipe
0118 ["Q1BPR_BeamlineMagnet_assembly", GROUP_BACKWARD], // Around it
0119
0120 ["Q2PR_BeamlineMagnet_assembly", GROUP_BACKWARD], // after Q2ER/Q1BPR
0121
0122 // Tagger
0123 ["BackwardsTaggerVacuum_assembly", GROUP_BACKWARD], // Tagger and pipeline
0124 ["BackwardsTaggerAssembly", GROUP_BACKWARD], // Tagger
0125
0126 ["Magnets_Q3eR_assembly", GROUP_BACKWARD], // Far away magnet
0127
0128 // LUMI
0129 ["LumiWindow_vol_ExitWindow", GROUP_BACKWARD],
0130 ["LumiCollimator_assembly", GROUP_BACKWARD],
0131 ["SweeperMag_assembly", GROUP_BACKWARD],
0132 ["AnalyzerMag_assembly", GROUP_BACKWARD],
0133 ["LumiSpecTracker", GROUP_BACKWARD],
0134 ["LumiPhotonChamber", GROUP_BACKWARD],
0135 ["LumiDirectPCAL", GROUP_BACKWARD]
0136
0137 // ["InnerSiTrackerSubAssembly", GROUP_TRACKING],
0138 // ["MiddleSiTrackerSubAssembly", GROUP_TRACKING],
0139 // ["OuterSiTrackerSubAssembly", GROUP_TRACKING],
0140 // ["EndcapMPGDSubAssembly", GROUP_TRACKING],
0141 // ["InnerMPGDBarrelSubAssembly", GROUP_TRACKING],
0142 // ["EndcapTOFSubAssembly", GROUP_PID],
0143 // ["BarrelTOFSubAssembly", GROUP_PID],
0144 // ["OuterBarrelMPGDSubAssembly", GROUP_TRACKING],
0145 // ["B0TrackerSubAssembly", GROUP_TRACKING],
0146 // ["InnerTrackerSupport_assembly", GROUP_SUPPORT],
0147 // ["DIRC", GROUP_PID],
0148 // ["RICHEndcapN_Vol", GROUP_PID],
0149 // ["DRICH", GROUP_PID],
0150 // ["EcalEndcapP", GROUP_CALORIMETRY],
0151 // ["EcalEndcapPInsert", GROUP_CALORIMETRY],
0152 // ["EcalBarrelImaging", GROUP_CALORIMETRY],
0153 // ["EcalBarrelScFi", GROUP_CALORIMETRY],
0154 // ["EcalEndcapN", GROUP_CALORIMETRY],
0155 // ["LFHCAL_env", GROUP_CALORIMETRY],
0156 // ["HcalEndcapPInsert", GROUP_CALORIMETRY],
0157 // ["HcalBarrel", GROUP_CALORIMETRY],
0158 // ["FluxBarrel_env", GROUP_SUPPORT],
0159 // ["FluxEndcapP", GROUP_SUPPORT],
0160 // ["HcalEndcapN", GROUP_CALORIMETRY],
0161 // ["FluxEndcapN", GROUP_SUPPORT],
0162 // ["BeamPipe_assembly", GROUP_SUPPORT],
0163 // ["B0PF_BeamlineMagnet_assembly", GROUP_MAGNETS],
0164 // ["B0APF_BeamlineMagnet_assembly", GROUP_MAGNETS],
0165 // ["Q1APF_BeamlineMagnet_assembly", GROUP_MAGNETS],
0166 // ["Q1BPF_BeamlineMagnet_assembly", GROUP_MAGNETS],
0167 // ["BeamPipeB0_assembly", GROUP_SUPPORT],
0168 // ["Pipe_cen_to_pos_assembly", GROUP_SUPPORT],
0169 // ["Q0EF_assembly", GROUP_MAGNETS],
0170 // ["Q0EF_vac", GROUP_MAGNETS],
0171 // ["Q1EF_assembly", GROUP_MAGNETS],
0172 // ["Q1EF_vac", GROUP_MAGNETS],
0173 // ["B0ECal", GROUP_CALORIMETRY],
0174 // ["Pipe_Q1eR_to_B2BeR_assembly", GROUP_SUPPORT],
0175 // ["Magnet_Q1eR_assembly", GROUP_MAGNETS],
0176 // ["Magnet_Q2eR_assembly", GROUP_MAGNETS],
0177 // ["Magnet_B2AeR_assembly", GROUP_MAGNETS],
0178 // ["Magnet_B2BeR_assembly", GROUP_MAGNETS],
0179 // ["Magnets_Q3eR_assembly", GROUP_MAGNETS],
0180 ])
0181
0182 function findCategoryNodes(geometry: Object3D): Map<string, Object3D> {
0183
0184 // clear
0185 const nodesByName = new Map<string, Object3D>();
0186
0187 for (const node of geometry.children) {
0188 if (node.name == GROUP_FORWARD) {
0189 nodesByName.set(GROUP_FORWARD, node);
0190 continue;
0191 }
0192
0193 if (node.name == GROUP_BACKWARD) {
0194 nodesByName.set(GROUP_BACKWARD, node);
0195 continue;
0196 }
0197
0198 if (node.name == GROUP_CENTRAL) {
0199 for (const centralDetNode of node.children) {
0200 for (const groupName of CENTRAL_DETECTOR_GROUPS) {
0201 if (centralDetNode.name == groupName) {
0202 nodesByName.set(groupName, centralDetNode);
0203 }
0204 }
0205 }
0206 }
0207 }
0208 return nodesByName;
0209 }
0210
0211 function createCategoryNodes(geometry: Object3D): Map<string, Object3D> {
0212
0213 const nodesByName = new Map<string, Object3D>();
0214
0215 // little helper factory to add groups
0216 function addGroup(name: string): Group {
0217 const group = new Group();
0218 group.name = name;
0219 nodesByName.set(name, group);
0220 return group;
0221 }
0222
0223 // Forward detectors
0224 const forward = addGroup(GROUP_FORWARD);
0225
0226 // Backwards
0227 const backward = addGroup(GROUP_BACKWARD);
0228
0229 // Central detector
0230 const central = addGroup(GROUP_CENTRAL);
0231
0232 // add central detector subgroups
0233 for (const groupName of CENTRAL_DETECTOR_GROUPS) {
0234 let group = addGroup(groupName);
0235 central.add(group);
0236 }
0237
0238 // add groups to detector
0239 geometry.add(backward);
0240 geometry.add(central);
0241 geometry.add(forward);
0242
0243 // We still need categories
0244 return nodesByName;
0245 }
0246
0247 export function arrangeEpicDetectors(geometry: Object3D) {
0248
0249 let categoriesByName = findCategoryNodes(geometry);
0250 if (categoriesByName.size == 0) {
0251 categoriesByName = createCategoryNodes(geometry);
0252 }
0253
0254 // get top detector nodes and iterate over them
0255 const root = geometry.children[0]?.children[0];
0256 if (!root) return;
0257
0258 // Work on a copy so we can safely reparent during iteration
0259 const topDetectorNodes = [...root.children];
0260
0261 for (const detNode of topDetectorNodes) {
0262 for (const [detName, categoryName] of categoriesByDetName) {
0263 if (detNode.name.startsWith(detName)) {
0264 // Found a category name for this detector
0265 const categoryNode = categoriesByName.get(categoryName);
0266 if (categoryNode) {
0267 categoryNode.add(detNode);
0268 }
0269 break;
0270 }
0271 }
0272 }
0273 }