|
| 1 | +/// \file CheckITSTracksVsROF.C |
| 2 | +/// \brief Simple macro to check ITS tracks in AO2D files as a function of bunch crossing within a ROF |
| 3 | + |
| 4 | +#if !defined(__CLING__) || defined(__ROOTCLING__) |
| 5 | +#include <TSystem.h> |
| 6 | +#include <TFile.h> |
| 7 | +#include <TTree.h> |
| 8 | +#include <TKey.h> |
| 9 | +#include <TH1F.h> |
| 10 | +#include <TH2F.h> |
| 11 | +#include <TProfile.h> |
| 12 | +#include <TCanvas.h> |
| 13 | +#include <CCDB/BasicCCDBManager.h> |
| 14 | +#include <CommonConstants/LHCConstants.h> |
| 15 | +#include "DataFormatsParameters/GRPLHCIFData.h" |
| 16 | +#include "DataFormatsFIT/Triggers.h" |
| 17 | +#include <DataFormatsFT0/Digit.h> |
| 18 | +#include <Framework/DataTypes.h> |
| 19 | +#include <DataFormatsParameters/AggregatedRunInfo.h> |
| 20 | +#endif |
| 21 | + |
| 22 | +int32_t nBCsPerOrbit = o2::constants::lhc::LHCMaxBunches; |
| 23 | +int32_t nBCsPerITSROF = 198; |
| 24 | +int32_t offsetITSROF = 64; // from current analysis of delay of ITS ROF with respect to other detectors |
| 25 | +constexpr float minCollTimeFT0A = -5.f; |
| 26 | +constexpr float maxCollTimeFT0A = 5.f; |
| 27 | +constexpr float minCollTimeFT0C = -5.f; |
| 28 | +constexpr float maxCollTimeFT0C = 5.f; |
| 29 | +constexpr float minCollTimeFV0A = -5.f; |
| 30 | +constexpr float maxCollTimeFV0A = 5.f; |
| 31 | +constexpr float maxZv = 10.f; |
| 32 | +constexpr float maxTrackEta = 0.8f; |
| 33 | + |
| 34 | +void CheckITSTracksVsROF(int maxFiles = 6, int maxDF = 99999) |
| 35 | +{ |
| 36 | + |
| 37 | + printf("nBCsPerOrbit = %d\n", nBCsPerOrbit); |
| 38 | + // define histograms |
| 39 | + TH1F* hTrNoColl = new TH1F("hTrNoColl", "", 2, -0.5, 1.5); |
| 40 | + hTrNoColl->GetXaxis()->SetBinLabel(1, "No collision assoc."); |
| 41 | + hTrNoColl->GetXaxis()->SetBinLabel(2, "With collision assoc."); |
| 42 | + TH1F* hTrTime = new TH1F("hTrTime", ";time;entries", 100, -10000., 10000.); |
| 43 | + TH1F* hCollTime = new TH1F("hCollTime", ";time;entries", 100, -20., 20.); |
| 44 | + TH1F* hVz = new TH1F("hVz", ";z_{v} (cm);entries", 100, -20., 20.); |
| 45 | + TH2F* hTrVsCollTime = new TH2F("hTrVsCollTime", ";coll time;track time", 100, -20., 20., 100, -10000., 10000.); |
| 46 | + int nBinsROF = 395; |
| 47 | + float minROF = -197.5; |
| 48 | + float maxROF = 197.5; |
| 49 | + TH2F* hCluTrackVsBCinROF = new TH2F("hCluTrackVsBC", ";bcInROF;N_{ITSclusters}", nBinsROF, minROF, maxROF, 8, -0.5, 7.5); |
| 50 | + TH1F* hNEventsVsBC = new TH1F("hNEventsVsBC", ";bc;N_{Collisions}", 3601, -0.5, 3600.5); |
| 51 | + TH1F* hNTracksVsBC = new TH1F("hNTracksVsBC", ";bc;N_{Tracks}", 3601, -0.5, 3600.5); |
| 52 | + TH1F* hNTracksPerEventVsBC = new TH1F("hNTracksPerEventVsBC", ";bc;N_{Tracks} per event", 3601, -0.5, 3600.5); |
| 53 | + TH1F* hNEventsVsBCinROF = new TH1F("hNEventsVsBCinROF", ";bcInROF;N_{Collisions}", nBinsROF, minROF, maxROF); |
| 54 | + TH1F* hNTracksVsBCinROF = new TH1F("hNTracksVsBCinROF", ";bcInROF;N_{Tracks}", nBinsROF, minROF, maxROF); |
| 55 | + TH1F* hNTracksPerEventVsBCinROF = new TH1F("hNTracksPerEventVsBCinROF", ";bcInROF;N_{Tracks} per event", nBinsROF, minROF, maxROF); |
| 56 | + TH2F* hNPVContribVsBCinROF = new TH2F("hNPVContribVsBC", ";bcInROF;N_{PVcontrib}", nBinsROF, minROF, maxROF, 151, -0.5, 150.5); |
| 57 | + |
| 58 | + // process all AO2D files in subdirectories of the current directory |
| 59 | + gSystem->Exec("find ./ -name AO2D.root | sort > filelist.txt"); |
| 60 | + int nFiles = 0; |
| 61 | + std::ifstream aodList("filelist.txt"); |
| 62 | + std::string line; |
| 63 | + std::vector<std::string> filNames; |
| 64 | + while (std::getline(aodList, line)) { |
| 65 | + if (!line.empty()) { |
| 66 | + filNames.push_back(line); |
| 67 | + ++nFiles; |
| 68 | + } |
| 69 | + } |
| 70 | + if (nFiles > maxFiles) |
| 71 | + nFiles = maxFiles; |
| 72 | + |
| 73 | + for (int jf = 0; jf < nFiles; ++jf) { |
| 74 | + TFile* fil = TFile::Open(filNames[jf].c_str()); |
| 75 | + if (!fil || fil->IsZombie()) { |
| 76 | + printf("Cannot open %s\n", filNames[jf].c_str()); |
| 77 | + continue; |
| 78 | + } |
| 79 | + TList* l = (TList*)fil->GetListOfKeys(); |
| 80 | + int nKeys = l->GetEntries(); |
| 81 | + for (int j = 0; j < nKeys; ++j) { |
| 82 | + if (j >= maxDF) |
| 83 | + break; |
| 84 | + TKey* k = (TKey*)l->At(j); |
| 85 | + TString cname = k->GetClassName(); |
| 86 | + if (cname == "TDirectoryFile") { |
| 87 | + TDirectoryFile* d = (TDirectoryFile*)fil->Get(k->GetName()); |
| 88 | + printf("%s %s\n", fil->GetName(), d->GetName()); |
| 89 | + |
| 90 | + // Access TTree with BC info |
| 91 | + TTree* tb = (TTree*)d->Get("O2bc_001"); |
| 92 | + if (!tb) { |
| 93 | + printf("TTree O2bc_001 missing\n"); |
| 94 | + continue; |
| 95 | + } |
| 96 | + printf(" BC Tree entries = %lld\n", tb->GetEntries()); |
| 97 | + ULong64_t gloBC; |
| 98 | + int nRun; |
| 99 | + tb->SetBranchAddress("fRunNumber", &nRun); |
| 100 | + tb->SetBranchAddress("fGlobalBC", &gloBC); |
| 101 | + |
| 102 | + // Access TTree with collision info |
| 103 | + TTree* tc = (TTree*)d->Get("O2collision_001"); |
| 104 | + if (!tc) { |
| 105 | + printf("TTree O2collision_001 missing\n"); |
| 106 | + continue; |
| 107 | + } |
| 108 | + printf(" Collision Tree entries = %lld\n", tc->GetEntries()); |
| 109 | + float xv, yv, zv, ctime; |
| 110 | + int iBC; |
| 111 | + ushort nPVcontrib; |
| 112 | + tc->SetBranchAddress("fPosX", &xv); |
| 113 | + tc->SetBranchAddress("fPosY", &yv); |
| 114 | + tc->SetBranchAddress("fPosZ", &zv); |
| 115 | + tc->SetBranchAddress("fCollisionTime", &ctime); |
| 116 | + tc->SetBranchAddress("fNumContrib", &nPVcontrib); |
| 117 | + tc->SetBranchAddress("fIndexBCs", &iBC); |
| 118 | + |
| 119 | + // Access TTree with FT0 info |
| 120 | + TTree* tft = (TTree*)d->Get("O2ft0"); |
| 121 | + if (!tft) { |
| 122 | + printf("TTree O2ft0 missing\n"); |
| 123 | + continue; |
| 124 | + } |
| 125 | + printf(" FT0 Tree entries = %lld\n", tft->GetEntries()); |
| 126 | + float timeft0a, timeft0c; |
| 127 | + int iBCft0; |
| 128 | + UChar_t trigMask; |
| 129 | + tft->SetBranchAddress("fIndexBCs", &iBCft0); |
| 130 | + tft->SetBranchAddress("fTimeA", &timeft0a); |
| 131 | + tft->SetBranchAddress("fTimeC", &timeft0c); |
| 132 | + tft->SetBranchAddress("fTriggerMask", &trigMask); |
| 133 | + |
| 134 | + // Access TTree with FV0 info |
| 135 | + TTree* tfv = (TTree*)d->Get("O2fv0a"); |
| 136 | + if (!tfv) { |
| 137 | + printf("TTree O2fv0a missing\n"); |
| 138 | + continue; |
| 139 | + } |
| 140 | + printf(" FV0A Tree entries = %lld\n", tfv->GetEntries()); |
| 141 | + float timefv0a; |
| 142 | + int iBCfv0; |
| 143 | + tfv->SetBranchAddress("fIndexBCs", &iBCfv0); |
| 144 | + tfv->SetBranchAddress("fTime", &timefv0a); |
| 145 | + |
| 146 | + // Access TTree with track parameters at their innermost update |
| 147 | + TTree* tt = (TTree*)d->Get("O2track_iu"); |
| 148 | + if (!tt) { |
| 149 | + printf("TTree O2track_iu missing\n"); |
| 150 | + continue; |
| 151 | + } |
| 152 | + printf(" Track Tree entries = %lld\n", tt->GetEntries()); |
| 153 | + // 5 parameters defining the track helix: y, z, sin(phi), tan(lambda), q/pt |
| 154 | + // x is a coordinate along the track |
| 155 | + // alpha: angle between track reference system and global reference system |
| 156 | + float x, alp, y, z, snp, tgl, qpt; |
| 157 | + int iColl; |
| 158 | + tt->SetBranchAddress("fIndexCollisions", &iColl); |
| 159 | + tt->SetBranchAddress("fX", &x); |
| 160 | + tt->SetBranchAddress("fAlpha", &alp); |
| 161 | + tt->SetBranchAddress("fY", &y); |
| 162 | + tt->SetBranchAddress("fZ", &z); |
| 163 | + tt->SetBranchAddress("fSnp", &snp); |
| 164 | + tt->SetBranchAddress("fTgl", &tgl); |
| 165 | + tt->SetBranchAddress("fSigned1Pt", &qpt); |
| 166 | + |
| 167 | + // Access TTree with track extra information |
| 168 | + TTree* te = (TTree*)d->Get("O2trackextra_002"); |
| 169 | + if (!te) |
| 170 | + te = (TTree*)d->Get("O2trackextra_001"); |
| 171 | + if (!te) { |
| 172 | + printf("TTree O2trackextra_002 and O2trackextra_001 both missing\n"); |
| 173 | + continue; |
| 174 | + } |
| 175 | + uint itsclusiz; |
| 176 | + uint8_t nTPCclu; |
| 177 | + uint trflag; |
| 178 | + float itschi2, tpcchi2, trtime; |
| 179 | + te->SetBranchAddress("fITSClusterSizes", &itsclusiz); |
| 180 | + te->SetBranchAddress("fITSChi2NCl", &itschi2); |
| 181 | + te->SetBranchAddress("fTPCNClsFindable", &nTPCclu); |
| 182 | + te->SetBranchAddress("fTPCChi2NCl", &tpcchi2); |
| 183 | + te->SetBranchAddress("fTrackTime", &trtime); |
| 184 | + te->SetBranchAddress("fFlags", &trflag); |
| 185 | + |
| 186 | + // get run information |
| 187 | + if (tb->GetEntries() == 0) { |
| 188 | + printf("Empty BC tree\n"); |
| 189 | + continue; |
| 190 | + } |
| 191 | + tb->GetEntry(0); |
| 192 | + auto runInfo = o2::parameters::AggregatedRunInfo::buildAggregatedRunInfo(o2::ccdb::BasicCCDBManager::instance(), nRun); |
| 193 | + // uint64_t sorTimestamp = runInfo.sor; |
| 194 | + // uint64_t eorTimestamp = runInfo.eor; |
| 195 | + int64_t bcSOR = runInfo.orbitSOR * nBCsPerOrbit; |
| 196 | + int64_t nBCsPerTF = runInfo.orbitsPerTF * nBCsPerOrbit; |
| 197 | + auto calcBcInROF = [&](ULong64_t bcGlobal) { |
| 198 | + int bc = (bcGlobal + nBCsPerOrbit) % nBCsPerITSROF; |
| 199 | + bc -= offsetITSROF; |
| 200 | + return bc; |
| 201 | + }; |
| 202 | + |
| 203 | + // fill maps for BC and FT0 |
| 204 | + int nFT0 = tft->GetEntries(); |
| 205 | + std::unordered_map<int, int> bcToFT0; |
| 206 | + bcToFT0.reserve(nFT0); |
| 207 | + for (int jft = 0; jft < nFT0; ++jft) { |
| 208 | + tft->GetEntry(jft); |
| 209 | + bcToFT0[iBCft0] = jft; |
| 210 | + } |
| 211 | + // fill maps for BC and FV0 |
| 212 | + int nFV0 = tfv->GetEntries(); |
| 213 | + std::unordered_map<int, int> bcToFV0; |
| 214 | + bcToFV0.reserve(nFV0); |
| 215 | + for (int jfv = 0; jfv < nFV0; ++jfv) { |
| 216 | + tfv->GetEntry(jfv); |
| 217 | + bcToFV0[iBCfv0] = jfv; |
| 218 | + } |
| 219 | + // tag good collisions |
| 220 | + int nColl = tc->GetEntries(); |
| 221 | + std::vector<int> ft0indices(nColl, -1); |
| 222 | + std::vector<int> fv0indices(nColl, -1); |
| 223 | + std::vector<bool> isGoodColl(nColl, false); |
| 224 | + for (int i = 0; i < nColl; ++i) { |
| 225 | + ft0indices[i] = -1; |
| 226 | + tc->GetEntry(i); |
| 227 | + if (iBC < 0 || iBC >= tb->GetEntries()) { |
| 228 | + printf("ERROR: iBC out of range\n"); |
| 229 | + continue; |
| 230 | + } |
| 231 | + tb->GetEntry(iBC); |
| 232 | + auto it = bcToFT0.find(iBC); |
| 233 | + if (it != bcToFT0.end()) |
| 234 | + ft0indices[i] = it->second; |
| 235 | + auto iv = bcToFV0.find(iBC); |
| 236 | + if (iv != bcToFV0.end()) |
| 237 | + fv0indices[i] = iv->second; |
| 238 | + if (std::abs(zv) > maxZv) |
| 239 | + continue; |
| 240 | + int jft0 = ft0indices[i]; |
| 241 | + int jfv0 = fv0indices[i]; |
| 242 | + if (jft0 >= 0 && jfv0 >= 0) { |
| 243 | + tft->GetEntry(jft0); |
| 244 | + tfv->GetEntry(jfv0); |
| 245 | + bool isTVX = TESTBIT(trigMask, o2::ft0::Triggers::bitVertex); |
| 246 | + int64_t bcInTF = (static_cast<int64_t>(gloBC) - bcSOR) % nBCsPerTF; |
| 247 | + bool isTFBorderOK = (bcInTF > 300 && bcInTF < nBCsPerTF - 4000); |
| 248 | + if (isTFBorderOK && isTVX && |
| 249 | + timeft0a > minCollTimeFT0A && timeft0a < maxCollTimeFT0A && |
| 250 | + timeft0c > minCollTimeFT0C && timeft0c < maxCollTimeFT0C && |
| 251 | + timefv0a > minCollTimeFV0A && timefv0a < maxCollTimeFV0A) { |
| 252 | + isGoodColl[i] = true; |
| 253 | + int bcInITSROF = calcBcInROF(gloBC); |
| 254 | + hNEventsVsBC->Fill(gloBC % nBCsPerOrbit); |
| 255 | + hNEventsVsBCinROF->Fill(bcInITSROF); |
| 256 | + hCollTime->Fill(ctime); |
| 257 | + hVz->Fill(zv); |
| 258 | + } |
| 259 | + } |
| 260 | + } |
| 261 | + |
| 262 | + // loop over tracks |
| 263 | + int nTracks = tt->GetEntries(); |
| 264 | + for (int i = 0; i < nTracks; ++i) { |
| 265 | + // O2track_iu and O2trackextra_xxx entries are aligned 1-to-1 |
| 266 | + tt->GetEntry(i); |
| 267 | + te->GetEntry(i); |
| 268 | + // compute the ITS cluster map, which can be used in track selecion |
| 269 | + int nITSclu = 0; |
| 270 | + uint itsCluMap = 0; |
| 271 | + for (int jLay = 0; jLay < 7; ++jLay) { |
| 272 | + if ((itsclusiz >> (jLay * 4)) & 0xf) { |
| 273 | + nITSclu++; |
| 274 | + itsCluMap |= (1 << jLay); |
| 275 | + } |
| 276 | + } |
| 277 | + // track selections |
| 278 | + if (!(trflag & o2::aod::track::PVContributor)) |
| 279 | + continue; |
| 280 | + if (nITSclu == 0 || itschi2 < 0. || tpcchi2 < 0.) |
| 281 | + continue; |
| 282 | + // compute eta from track dip angle lambda via tgl = tan(lambda) |
| 283 | + float cl = 1. / std::sqrt(1. + tgl * tgl); |
| 284 | + float sl = cl * tgl; |
| 285 | + float eta = 0.5 * std::log((1 + sl) / (1 - sl)); |
| 286 | + if (std::abs(eta) > maxTrackEta) |
| 287 | + continue; |
| 288 | + // collision selections |
| 289 | + if (iColl >= 0 && iColl < nColl && isGoodColl[iColl]) { |
| 290 | + tc->GetEntry(iColl); |
| 291 | + hTrTime->Fill(trtime); |
| 292 | + hTrVsCollTime->Fill(ctime, trtime); |
| 293 | + tb->GetEntry(iBC); |
| 294 | + int bcInITSROF = calcBcInROF(gloBC); |
| 295 | + hNTracksVsBC->Fill(gloBC % nBCsPerOrbit); |
| 296 | + hCluTrackVsBCinROF->Fill(bcInITSROF, nITSclu); |
| 297 | + hNTracksVsBCinROF->Fill(bcInITSROF); |
| 298 | + hNPVContribVsBCinROF->Fill(bcInITSROF, nPVcontrib); |
| 299 | + hTrNoColl->Fill(1); |
| 300 | + } else { |
| 301 | + hTrNoColl->Fill(0); |
| 302 | + } |
| 303 | + } |
| 304 | + } |
| 305 | + } |
| 306 | + } |
| 307 | + |
| 308 | + // plotting |
| 309 | + TProfile* pctr = hNPVContribVsBCinROF->ProfileX(); |
| 310 | + TProfile* pclu = hCluTrackVsBCinROF->ProfileX(); |
| 311 | + TH1F* hFrac7 = new TH1F("hFrac7", ";bcInROF;Fraction of tracks with 7 clusters", hCluTrackVsBCinROF->GetXaxis()->GetNbins(), hCluTrackVsBCinROF->GetXaxis()->GetXmin(), hCluTrackVsBCinROF->GetXaxis()->GetXmax()); |
| 312 | + for (int jx = 1; jx <= hCluTrackVsBCinROF->GetXaxis()->GetNbins(); jx++) { |
| 313 | + double tot = 0.; |
| 314 | + for (int jy = 1; jy <= hCluTrackVsBCinROF->GetYaxis()->GetNbins(); jy++) { |
| 315 | + double c = hCluTrackVsBCinROF->GetBinContent(jx, jy); |
| 316 | + tot += c; |
| 317 | + } |
| 318 | + double seven = hCluTrackVsBCinROF->GetBinContent(jx, 8); |
| 319 | + double f = 0.; |
| 320 | + double ef = 0.; |
| 321 | + if (tot > 0) { |
| 322 | + f = seven / tot; |
| 323 | + ef = std::sqrt(f * (1 - f) / tot); |
| 324 | + } |
| 325 | + hFrac7->SetBinContent(jx, f); |
| 326 | + hFrac7->SetBinError(jx, ef); |
| 327 | + } |
| 328 | + for (int jx = 1; jx <= hNTracksVsBC->GetXaxis()->GetNbins(); jx++) { |
| 329 | + double nt = hNTracksVsBC->GetBinContent(jx); |
| 330 | + double ne = hNEventsVsBC->GetBinContent(jx); |
| 331 | + if (ne > 0) |
| 332 | + hNTracksPerEventVsBC->SetBinContent(jx, nt / ne); |
| 333 | + } |
| 334 | + for (int jx = 1; jx <= hNTracksVsBCinROF->GetXaxis()->GetNbins(); jx++) { |
| 335 | + double nt = hNTracksVsBCinROF->GetBinContent(jx); |
| 336 | + double ne = hNEventsVsBCinROF->GetBinContent(jx); |
| 337 | + if (ne > 0) |
| 338 | + hNTracksPerEventVsBCinROF->SetBinContent(jx, nt / ne); |
| 339 | + } |
| 340 | + |
| 341 | + hCluTrackVsBCinROF->SetStats(0); |
| 342 | + hFrac7->SetStats(0); |
| 343 | + hNPVContribVsBCinROF->SetStats(0); |
| 344 | + |
| 345 | + TCanvas* ctr = new TCanvas("ctr", "", 1400, 500); |
| 346 | + ctr->Divide(3, 1); |
| 347 | + ctr->cd(1); |
| 348 | + hTrNoColl->Draw(); |
| 349 | + ctr->cd(2); |
| 350 | + hCollTime->Draw(); |
| 351 | + ctr->cd(3); |
| 352 | + hVz->Draw(); |
| 353 | + |
| 354 | + TCanvas* cbc = new TCanvas("cbc", "", 1400, 800); |
| 355 | + cbc->Divide(1, 3); |
| 356 | + cbc->cd(1); |
| 357 | + hNEventsVsBC->Draw(); |
| 358 | + cbc->cd(2); |
| 359 | + hNTracksVsBC->Draw(); |
| 360 | + cbc->cd(3); |
| 361 | + hNTracksPerEventVsBC->Draw(); |
| 362 | + |
| 363 | + TCanvas* crof = new TCanvas("crof", "", 1400, 800); |
| 364 | + crof->Divide(3, 2); |
| 365 | + crof->cd(1); |
| 366 | + hNEventsVsBCinROF->Draw(); |
| 367 | + crof->cd(2); |
| 368 | + hNTracksVsBCinROF->Draw(); |
| 369 | + crof->cd(3); |
| 370 | + hNTracksPerEventVsBCinROF->Draw(); |
| 371 | + crof->cd(4); |
| 372 | + gPad->SetLogz(); |
| 373 | + hCluTrackVsBCinROF->Draw("colz"); |
| 374 | + pclu->SetLineWidth(2); |
| 375 | + pclu->Draw("same"); |
| 376 | + crof->cd(5); |
| 377 | + hFrac7->SetMinimum(0.); |
| 378 | + hFrac7->SetMaximum(1.); |
| 379 | + hFrac7->SetLineWidth(2); |
| 380 | + hFrac7->Draw(); |
| 381 | + crof->cd(6); |
| 382 | + gPad->SetLogz(); |
| 383 | + hNPVContribVsBCinROF->Draw("colz"); |
| 384 | + pctr->SetLineWidth(2); |
| 385 | + pctr->Draw("same"); |
| 386 | + crof->SaveAs("ITSTracksVsBCinROF.png"); |
| 387 | +} |
0 commit comments