Back to home page

EIC code displayed by LXR

 
 

    


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 }