88// In applying this license CERN does not waive the privileges and immunities
99// granted to it by virtue of its status as an Intergovernmental Organization
1010// or submit itself to any jurisdiction.
11- //
12- // Minimal example to run this task:
13- // o2-analysis-centrality-table -b --configuration json://configuration.json | o2-analysis-timestamp -b --configuration json://configuration.json | o2-analysis-event-selection -b --configuration json://configuration.json | o2-analysis-multiplicity-table -b --configuration json://configuration.json | o2-analysis-lf-zdcsp -b --configuration json://configuration.json --aod-file @input_data.txt --aod-writer-json OutputDirector.json
11+
12+ // / \file perRunQc.cxx
13+ // / \brief basic per run check of the ITS dead chips and of the hadronic interaction rate
14+ // / \author victor.gonzalez.sebastian@gmail.com
1415
1516#include < array>
1617#include < cmath>
18+ #include < unordered_map>
19+ #include < memory>
20+ #include < vector>
1721
1822#include " CCDB/BasicCCDBManager.h"
1923#include " Common/CCDB/ctpRateFetcher.h"
2024
25+ #include " DataFormatsParameters/AggregatedRunInfo.h"
26+ #include " DataFormatsITSMFT/NoiseMap.h" // missing include in TimeDeadMap.h
27+ #include " DataFormatsITSMFT/TimeDeadMap.h"
28+ #include " ITSMFTReconstruction/ChipMappingITS.h"
29+
2130#include " Framework/AnalysisDataModel.h"
2231#include " Framework/AnalysisTask.h"
2332#include " Framework/ASoAHelpers.h"
@@ -35,17 +44,22 @@ using BCsWithTimestamps = soa::Join<aod::BCs, aod::Timestamps>;
3544
3645namespace perrunqatask
3746{
47+ static const int32_t nBCsPerOrbit = o2::constants::lhc::LHCMaxBunches;
3848std::unordered_map<int , TH2*> gHadronicRate ;
49+ std::unordered_map<int , std::vector<std::shared_ptr<TH2>>> gDeadChipsVsOrbitInLayer ;
50+ std::unordered_map<int , std::shared_ptr<TH1>> gCollisionOrbitBefore ;
51+ std::unordered_map<int , std::shared_ptr<TH1>> gCollisionOrbitAfter ;
3952
4053TH2* gCurrentHadronicRate ;
54+ std::shared_ptr<TH1> gCurrentCollisionOrbitBefore ;
55+ std::shared_ptr<TH1> gCurrentCollisionOrbitAfter ;
4156} // namespace perrunqatask
4257
4358struct DptDptPerRunQa {
4459
4560 Service<o2::ccdb::BasicCCDBManager> ccdb;
4661
4762 int mRunNumber {-1 };
48- uint64_t mSOR {0 };
4963 double mMinSeconds {-1 .};
5064
5165 ctpRateFetcher mRateFetcher ;
@@ -62,13 +76,63 @@ struct DptDptPerRunQa {
6276 mRunNumber = bc.runNumber ();
6377 if (gHadronicRate .find (mRunNumber ) == gHadronicRate .end ()) {
6478 auto runDuration = ccdb->getRunDuration (mRunNumber );
65- mSOR = runDuration.first ;
79+ uint64_t mSOR = runDuration.first ;
6680 mMinSeconds = std::floor (mSOR * 1 .e -3 ); // / round tsSOR to the highest integer lower than tsSOR
6781 double maxSec = std::ceil (runDuration.second * 1 .e -3 ); // / round tsEOR to the lowest integer higher than tsEOR
6882 const AxisSpec axisSeconds{static_cast <int >(maxSec - mMinSeconds ), 0 , maxSec - mMinSeconds , " Seconds since SOR" };
6983 gHadronicRate [mRunNumber ] = mHistos .add <TH2>(Form (" %i/hadronicRate" , mRunNumber ), " ;Time since SOR (s);Hadronic rate (kHz)" , kTH2D , {{static_cast <int >((maxSec - mMinSeconds ) / 20 .f ), 0 , maxSec - mMinSeconds , " Seconds since SOR" }, {1010 , 0 ., 1010 .}}).get ();
84+
85+ /* initializing the ITS chips dead map*/
86+ /* inspired in DPG/Tasks/AOTEvent/eventSelectionQa.cxx */
87+ auto runInfo = o2::parameters::AggregatedRunInfo::buildAggregatedRunInfo (o2::ccdb::BasicCCDBManager::instance (), mRunNumber );
88+ int64_t tsSOR = runInfo.sor ;
89+ int64_t tsEOR = runInfo.eor ;
90+ o2::itsmft::TimeDeadMap* itsDeadMap = ccdb->getForTimeStamp <o2::itsmft::TimeDeadMap>(" ITS/Calib/TimeDeadMap" , (tsSOR + tsEOR) / 2 );
91+ auto itsDeadMapOrbits = itsDeadMap->getEvolvingMapKeys (); // roughly every second, ~350 TFs = 350x32 orbits
92+ if (itsDeadMapOrbits.size () > 0 ) {
93+ std::vector<double > itsDeadMapOrbitsDouble (itsDeadMapOrbits.begin (), itsDeadMapOrbits.end ());
94+ const AxisSpec axisItsDeadMapOrbits{itsDeadMapOrbitsDouble};
95+ gDeadChipsVsOrbitInLayer [mRunNumber ] = std::vector<std::shared_ptr<TH2>>(o2::itsmft::ChipMappingITS::NLayers, nullptr );
96+ for (int layer = 0 ; layer < o2::itsmft::ChipMappingITS::NLayers; ++layer) {
97+ int nChips = o2::itsmft::ChipMappingITS::getNChipsOnLayer (layer);
98+ double idFirstChip = o2::itsmft::ChipMappingITS::getFirstChipsOnLayer (layer);
99+ gDeadChipsVsOrbitInLayer [mRunNumber ][layer] = mHistos .add <TH2>(TString::Format (" %d/Before/hDeadChipsVsOrbitInLayer%d" , mRunNumber , layer),
100+ TString::Format (" Dead chips in ITS layer %d, before;orbit; chip" , layer),
101+ kTH2C , {axisItsDeadMapOrbits, {nChips, idFirstChip, idFirstChip + nChips}});
102+ }
103+ gCollisionOrbitBefore [mRunNumber ] = mHistos .add <TH1>(TString::Format (" %d/Before/hCollisionOrbitB" , mRunNumber ), " Collision orbit before; orbit" , kTH1I , {axisItsDeadMapOrbits});
104+ gCollisionOrbitAfter [mRunNumber ] = mHistos .add <TH1>(TString::Format (" %d/After/hCollisionOrbitA" , mRunNumber ), " Collision orbit; orbit" , kTH1I , {axisItsDeadMapOrbits});
105+ LOGF (info, " Created the histograms" );
106+
107+ std::vector<uint16_t > vClosest;
108+ for (const auto & orbit : itsDeadMapOrbits) {
109+ itsDeadMap->getMapAtOrbit (orbit, vClosest);
110+ for (size_t iel = 0 ; iel < vClosest.size (); iel++) {
111+ // dead chips are stored as ranges
112+ // vClosest contains first and last chip ids in the range
113+ // last chip id in the range is marked with 0x8000 bit set to 1
114+ uint16_t w1 = vClosest[iel];
115+ bool isLastInSequence = (w1 & 0x8000 ) == 0 ;
116+ uint16_t w2 = isLastInSequence ? w1 + 1 : vClosest[iel + 1 ];
117+ uint16_t chipId1 = w1 & 0x7FFF ;
118+ uint16_t chipId2 = w2 & 0x7FFF ;
119+ for (int chipId = chipId1; chipId < chipId2; chipId++) {
120+ for (int layer = 0 ; layer < o2::itsmft::ChipMappingITS::NLayers; ++layer) {
121+ gDeadChipsVsOrbitInLayer [mRunNumber ][layer]->Fill (orbit, chipId, 1 );
122+ }
123+ }
124+ }
125+ }
126+ LOGF (info, " Initializing the current ones" );
127+ gCurrentCollisionOrbitBefore = gCollisionOrbitBefore [mRunNumber ];
128+ gCurrentCollisionOrbitAfter = gCollisionOrbitAfter [mRunNumber ];
129+ } else {
130+ gCurrentCollisionOrbitBefore = nullptr ;
131+ gCurrentCollisionOrbitAfter = nullptr ;
132+ }
70133 }
71134 gCurrentHadronicRate = gHadronicRate [mRunNumber ];
135+ LOGF (info, " Getting out" );
72136 }
73137
74138 void init (o2::framework::InitContext&)
@@ -78,20 +142,24 @@ struct DptDptPerRunQa {
78142 ccdb->setFatalWhenNull (false );
79143 }
80144
81- void process (soa::Join<aod::Collisions, aod::DptDptCFCollisionsInfo>::iterator const & collision, aod::BCsWithTimestamps const &)
145+ void process (soa::Join<aod::Collisions, aod::EvSels, aod:: DptDptCFCollisionsInfo>::iterator const & collision, aod::BCsWithTimestamps const &)
82146 {
83147 using namespace perrunqatask ;
84148 using namespace analysis ::dptdptfilter;
85149
150+ auto bc = collision.bc_as <aod::BCsWithTimestamps>();
151+ initCCDB (bc);
152+ int64_t orbit = bc.globalBC () / nBCsPerOrbit;
153+ gCurrentCollisionOrbitBefore ->Fill (orbit);
154+
86155 if (!collision.collisionaccepted ()) {
87156 return ;
88157 }
89158
90- auto bc = collision.bc_as <aod::BCsWithTimestamps>();
91- initCCDB (bc);
92159 double hadronicRate = mRateFetcher .fetch (ccdb.service , bc.timestamp (), mRunNumber , " T0VTX" ) * 1 .e -3 ; //
93160 double seconds = bc.timestamp () * 1 .e -3 - mMinSeconds ;
94161 gCurrentHadronicRate ->Fill (seconds, hadronicRate);
162+ gCurrentCollisionOrbitAfter ->Fill (orbit);
95163 }
96164};
97165
0 commit comments