Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /snippets/Tracking/TrackMetrics/TrackMetrics.C was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 // ============================================================

0002 // Build particle -> reco hit associations

0003 //

0004 // Goal:

0005 //   For each MC particle (status==1), save the list of

0006 //   reconstructed tracking hits associated with it.

0007 //

0008 // This will later allow:

0009 //

0010 //   particle -> hits

0011 //   track    -> hits

0012 //

0013 // and therefore:

0014 //   track <-> particle matching via shared hits

0015 // ============================================================

0016 
0017 #include <unordered_map>
0018 #include <unordered_set>
0019 #include <vector>
0020 #include <cstdint>
0021 #include <iostream>
0022 
0023 // ============================================================

0024 // Unique hit key type

0025 // ============================================================

0026 using HitKey = uint64_t;
0027 
0028 // ============================================================

0029 // Create globally unique hit key

0030 // ============================================================

0031 inline HitKey makeHitKey(const podio::ObjectID& id) {
0032     return (uint64_t(id.collectionID) << 32) 
0033         | uint32_t(id.index);
0034     }
0035 
0036 // ==============================================================

0037 // Create structure for globally unique hit key and quality flag

0038 // ==============================================================

0039 struct TruthHitInfo {
0040     
0041     uint64_t recoHitKey;
0042     int quality;
0043 
0044 };
0045 
0046 // ==============================================================

0047 // Create structure for Rawhit to Particle with hit quality flag

0048 // ==============================================================

0049 struct RawHitTruthInfo {
0050 
0051     int particleID;
0052     int quality;
0053 
0054 };
0055 
0056 // ============================================================

0057 // Function to set plotting style

0058 // ============================================================

0059 void set_style(){
0060     gStyle->SetOptStat(0);
0061     gStyle->SetPadBorderMode(0);
0062     gStyle->SetFrameBorderMode(0);
0063     gStyle->SetFrameLineWidth(2);
0064     gStyle->SetLabelSize(0.035,"X");
0065     gStyle->SetLabelSize(0.035,"Y");
0066     //gStyle->SetLabelOffset(0.01,"X");

0067     //gStyle->SetLabelOffset(0.01,"Y");

0068     gStyle->SetTitleXSize(0.04);
0069     gStyle->SetTitleXOffset(0.9);
0070     gStyle->SetTitleYSize(0.04);
0071     gStyle->SetTitleYOffset(0.9);
0072 }
0073 
0074 // ============================================================

0075 // Main function

0076 // ============================================================

0077 void TrackMetrics(int input_setting = 1){
0078 
0079     // ============================================================

0080     // Set style

0081     // ============================================================

0082     set_style();
0083 
0084     // ============================================================

0085     // Set maximum number of events allowed to run

0086     // ============================================================

0087     int max_events = 1E2;
0088 
0089     // ============================================================

0090     // Detector config

0091     // ============================================================

0092     enum class DetectorType {
0093         Endcap,
0094         Barrel
0095     };
0096 
0097     struct DetectorConfig {
0098         std::string collection;
0099         DetectorType type;
0100     };
0101 
0102     // ============================================================

0103     // Active detector collections

0104     // ============================================================

0105     std::vector<DetectorConfig> detectors = {
0106         {"SiEndcapTrackerRecHits", DetectorType::Endcap},
0107         {"SiBarrelVertexRecHits", DetectorType::Barrel},
0108         {"SiBarrelTrackerRecHits", DetectorType::Barrel},
0109         {"MPGDBarrelRecHits", DetectorType::Barrel},
0110         {"OuterMPGDBarrelRecHits", DetectorType::Barrel},
0111         {"BackwardMPGDEndcapRecHits", DetectorType::Endcap},
0112         {"ForwardMPGDEndcapRecHits", DetectorType::Endcap},
0113         {"TOFBarrelRecHits",DetectorType::Barrel},
0114         {"TOFEndcapRecHits",DetectorType::Endcap}
0115     };
0116 
0117     // ============================================================

0118     // Create histograms

0119     // ============================================================

0120 
0121     // ============================================================

0122     // Open files and load Reader

0123     // ============================================================

0124     std::vector<string> inputfiles;
0125     podio::ROOTReader r;
0126 
0127     std::string input;
0128     if (input_setting==0) 
0129         input = "./input_lists/local_files.txt";
0130     else if (input_setting==1)
0131         input = "./input_lists/local_merged_files.txt";
0132     else if (input_setting==2) 
0133         input = "./input_lists/list_ForcedBG_10um.txt";
0134     
0135     std::ifstream in(input);
0136     std::string file("");
0137     while (in >> file){
0138         inputfiles.push_back(file);
0139     }
0140     r.openFiles(inputfiles);
0141     in.close();
0142 
0143     // Print run information

0144     auto nevents = r.getEntries(podio::Category::Event);
0145     if (nevents > max_events) 
0146         nevents = max_events;
0147 
0148     cout<<"Running analysis on "<<input<<"!"<<endl;
0149     cout<<"Analyzing "<< nevents <<" events!"<<endl;
0150 
0151     // ============================================================

0152     // Event loop

0153     // ============================================================

0154     for (unsigned int ievent = 0; ievent < nevents; ievent++) {
0155         
0156         if ((ievent % 100) == 0) 
0157             std::cout << "Processed event "
0158                       << ievent
0159                       << std::endl;
0160 
0161         // ========================================================

0162         // Read event

0163         // ========================================================

0164         auto f = 
0165             podio::Frame( 
0166                 r.readNextEntry(podio::Category::Event) 
0167             );
0168 
0169         // ========================================================

0170         // RawHit <-> SimHit associations

0171         // ========================================================

0172         auto& raw_hit_assocs =
0173             f.get<edm4eic::MCRecoTrackerHitAssociationCollection>(
0174                 "CentralTrackingRawHitAssociations"
0175             );
0176 
0177         // ========================================================

0178         // Map:

0179         //

0180         //   rawHitKey -> RawHitTruthInfo

0181         //

0182         // This is built ONCE per event.

0183         // ========================================================

0184         std::unordered_map<HitKey, RawHitTruthInfo>
0185             rawHitTruthMap;
0186 
0187         for (const auto& assoc : raw_hit_assocs) {
0188             
0189             auto sim_hit = assoc.getSimHit();
0190             
0191             auto mc_particle =
0192                 sim_hit.getParticle();
0193 
0194             int mc_status =
0195                 mc_particle.getGeneratorStatus();
0196 
0197             // ----------------------------------------------------

0198             // Keep only generator particles

0199             // ----------------------------------------------------

0200             if (mc_status != 1)
0201                 continue;
0202 
0203             int particleID =
0204                 mc_particle.getObjectID().index;
0205 
0206             auto raw_hit =
0207                 assoc.getRawHit();
0208 
0209             HitKey rawKey =
0210                 makeHitKey(raw_hit.getObjectID());
0211 
0212             RawHitTruthInfo info;
0213             
0214             info.particleID = particleID;
0215             info.quality   = sim_hit.getQuality();
0216             
0217             rawHitTruthMap[rawKey] = info;
0218         }
0219 
0220         // ========================================================

0221         // Final structure:

0222         //

0223         //   particleID -> set of TruthHitInfo

0224         //

0225         // ========================================================

0226         std::unordered_map<
0227             int,
0228             std::vector<TruthHitInfo>
0229         > particleHits;
0230 
0231         // ========================================================

0232         // Loop over detector collections

0233         // ========================================================

0234         for (const auto& det : detectors) {
0235 
0236             auto& rechit_coll =
0237                 f.get<edm4eic::TrackerHitCollection>(
0238                     det.collection
0239                 );
0240 
0241             std::cout
0242                 << "Event " << ievent
0243                 << " | Collection: " << det.collection
0244                 << " | rechits: " << rechit_coll.size()
0245                 << std::endl;
0246 
0247             // ====================================================

0248             // Loop over reconstructed hits

0249             // ====================================================

0250             for (const auto& hit : rechit_coll) {
0251 
0252                 // ------------------------------------------------

0253                 // Get raw hit associated with reco hit

0254                 // ------------------------------------------------

0255                 auto raw_hit =
0256                     hit.getRawHit();
0257 
0258                 HitKey rawKey =
0259                     makeHitKey(raw_hit.getObjectID());
0260                     
0261                 // ------------------------------------------------

0262                 // Find corresponding MC particle

0263                 // ------------------------------------------------

0264                 auto it =
0265                     rawHitTruthMap.find(rawKey);
0266 
0267                 if (it == rawHitTruthMap.end())
0268                     continue;
0269 
0270                 const auto& truth = it->second;
0271                 
0272                 int particleID = truth.particleID;
0273                 int quality = truth.quality;
0274 
0275                 // ------------------------------------------------

0276                 // Create reco hit key

0277                 // ------------------------------------------------

0278                 HitKey recoKey =
0279                     makeHitKey(hit.getObjectID());
0280 
0281                 // ------------------------------------------------

0282                 // Save reco hit key and quality

0283                 // ------------------------------------------------

0284                 TruthHitInfo hitInfo;
0285                 
0286                 hitInfo.recoHitKey = recoKey;
0287                 hitInfo.quality    = quality;
0288                 
0289                 particleHits[particleID].push_back(hitInfo);
0290             }
0291         }
0292 
0293         // ========================================================

0294         // Debug printout

0295         // ========================================================

0296         std::cout
0297             << "Event "
0298             << ievent
0299             << " has "
0300             << particleHits.size()
0301             << " \033[1;34mstatus==1\033[0m"
0302             << " particles with tracker hits"
0303             << std::endl;
0304 
0305         // --------------------------------------------------------

0306         // Print first few particles

0307         // --------------------------------------------------------

0308         int nprint = 0;
0309 
0310         for (const auto& [pid, hits] : particleHits) {
0311 
0312             int nQuality0 = 0;
0313 
0314             for (const auto& hit : hits) {
0315 
0316                 if (hit.quality == 0)
0317                 nQuality0++;
0318             }
0319 
0320             std::cout
0321                 << "  Particle "
0322                 << pid
0323                 << " --> "
0324                 << hits.size()
0325                 << " reco hits"
0326                 << " (and "
0327                 << nQuality0
0328                 << " \033[1;32mquality==0\033[0m" 
0329                 << " hits)"
0330                 << std::endl;
0331 
0332             nprint++;
0333 
0334             if (nprint > 10)
0335                 break;
0336         }
0337 
0338     } // end event loop

0339 
0340     // --------------------------------------------------------

0341     // Make plots

0342     // --------------------------------------------------------

0343 
0344 } // end main function