Skip to content

Commit 5a30ddc

Browse files
authored
TPC QC: adds occupancy histogram in Cluster task (#2551)
* TPC: add occupancy plot to Cluster task * Feat: add occupancy histograms to Cluster tasks
1 parent 1d7993a commit 5a30ddc

6 files changed

Lines changed: 117 additions & 8 deletions

File tree

Modules/TPC/include/TPC/ClusterVisualizer.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,14 @@ class ClusterVisualizer final : public quality_control::postprocessing::PostProc
6565
/// \param services Interface containing optional interfaces, for example DatabaseInterface
6666
void finalize(quality_control::postprocessing::Trigger, framework::ServiceRegistryRef) override;
6767

68+
template <class T>
69+
void makeRadialProfile(o2::tpc::CalDet<T>& calDet, TCanvas* canv, int nbinsY, float yMin, float yMax);
70+
71+
template <class T>
72+
void fillRadialHisto(TH2D& h2D, const o2::tpc::CalDet<T>& calDet, const o2::tpc::Side side);
73+
6874
private:
75+
int mNHBFPerTF = 32;
6976
o2::ccdb::CcdbApi mCdbApi;
7077
std::string mHost;
7178
std::vector<std::vector<std::unique_ptr<TCanvas>>> mCalDetCanvasVec{}; ///< vector containing a vector of summary canvases for every CalDet object

Modules/TPC/include/TPC/Clusters.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class Clusters /*final*/ : public TaskInterface // todo add back the "final" whe
5555

5656
private:
5757
bool mIsMergeable = true;
58+
int mNHBFPerTF = 32;
5859
ClustersData mQCClusters{}; ///< O2 Cluster task to perform actions on cluster objects
5960
std::vector<o2::tpc::qc::CalPadWrapper> mWrapperVector{}; ///< vector holding CalPad objects wrapped as TObjects; published on QCG; will be non-wrapped CalPad objects in the future
6061
std::vector<std::unique_ptr<TCanvas>> mNClustersCanvasVec{}; ///< summary canvases of the NClusters object
@@ -63,6 +64,7 @@ class Clusters /*final*/ : public TaskInterface // todo add back the "final" whe
6364
std::vector<std::unique_ptr<TCanvas>> mSigmaTimeCanvasVec{}; ///< summary canvases of the SigmaTime object
6465
std::vector<std::unique_ptr<TCanvas>> mSigmaPadCanvasVec{}; ///< summary canvases of the SigmaPad object
6566
std::vector<std::unique_ptr<TCanvas>> mTimeBinCanvasVec{}; ///< summary canvases of the TimeBin object
67+
std::vector<std::unique_ptr<TCanvas>> mOccupancyCanvasVec{}; ///< summary canvases of the Occupancy object
6668

6769
void processClusterNative(o2::framework::InputRecord& inputs);
6870
void processKrClusters(o2::framework::InputRecord& inputs);

Modules/TPC/run/tpcQCClusterVisualizer.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,18 +60,19 @@
6060
{ "Q_Tot" : [ "600", "0", "600" ] },
6161
{ "Sigma_Time" : [ "200", "0", "2" ] },
6262
{ "Sigma_Pad" : [ "200", "0", "2" ] },
63-
{ "Time_Bin" : [ "1000", "0", "100000" ] }
63+
{ "Time_Bin" : [ "1000", "0", "100000" ] },
64+
{ "Occupancy" : [ "100", "0", "0.001" ] }
6465
],
6566
"path_comment": "This is the path of the ClustersData object that shall be visualized.",
66-
"path": "TPC/MO/Clusters/ClusterData",
67+
"path": "qc/TPC/MO/Clusters/ClusterData",
6768
"dataType_comment": "This is the switch for 'RawDigits' or 'Clusters' task. Choose 'raw' or 'clusters'.",
6869
"dataType": "clusters",
6970
"initTrigger": [
7071
"once"
7172
],
7273
"updateTrigger_comment": "To trigger on a specific file being updated, use e.g. 'newobject:qcdb:TPC/Calib/Noise'",
7374
"updateTrigger": [
74-
"newobject:qcdb:TPC/MO/Clusters/ClusterData"
75+
"newobject:ccdb:qc/TPC/MO/Clusters/ClusterData"
7576
],
7677
"stopTrigger": [
7778
"userorcontrol"

Modules/TPC/run/tpcQCClusters_direct.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@
2828
"className": "o2::quality_control_modules::tpc::Clusters",
2929
"moduleName": "QcTPC",
3030
"detectorName": "TPC",
31-
"cycleDurationSeconds": "10",
31+
"cycleDurationSeconds": "60",
32+
"maxNumberCycles": "-1",
3233
"resetAfterCycles": "5",
3334
"dataSource": {
3435
"type": "direct",
@@ -41,7 +42,8 @@
4142
"QtotNBins": "600", "QtotXMin": "0", "QtotXMax": "600",
4243
"SigmaPadNBins": "200", "SigmaPadXMin": "0", "SigmaPadXMax": "2",
4344
"SigmaTimeNBins": "200", "SigmaTimeXMin": "0", "SigmaTimeXMax": "2",
44-
"TimeBinNBins": "1000", "TimeBinXMin": "0", "TimeBinXMax": "100000"
45+
"TimeBinNBins": "1000", "TimeBinXMin": "0", "TimeBinXMax": "100000",
46+
"OccupancyNBins": "1000", "OccupancyXMin": "0", "OccupancyXMax": "0.00001"
4547
},
4648
"location": "local",
4749
"localMachines": [

Modules/TPC/src/ClusterVisualizer.cxx

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "TPCBase/Painter.h"
1919
#include "TPCBase/CDBInterface.h"
2020
#include "TPCQC/Helpers.h"
21+
#include "DetectorsBase/GRPGeomHelper.h"
2122

2223
// QC includes
2324
#include "QualityControl/QcInfoLogger.h"
@@ -120,14 +121,16 @@ void ClusterVisualizer::configure(const boost::property_tree::ptree& config)
120121
"Q_Tot",
121122
"Sigma_Pad",
122123
"Sigma_Time",
123-
"Time_Bin"
124+
"Time_Bin",
125+
"Occupancy"
124126
};
125127
} else if (type == "raw") {
126128
mIsClusters = false;
127129
mObservables = {
128130
"N_RawDigits",
129131
"Q_Max",
130-
"Time_Bin"
132+
"Time_Bin",
133+
"Occupancy"
131134
};
132135
} else {
133136
ILOG(Error, Support) << "No valid data type given. 'dataType' has to be either 'clusters' or 'raw'." << ENDM;
@@ -138,6 +141,8 @@ void ClusterVisualizer::initialize(Trigger, framework::ServiceRegistryRef)
138141
{
139142
mCdbApi.init(mHost);
140143

144+
mNHBFPerTF = o2::base::GRPGeomHelper::instance().getNHBFPerTF();
145+
141146
if (mCalDetCanvasVec.size() > 0) {
142147
mCalDetCanvasVec.clear();
143148
}
@@ -153,12 +158,25 @@ void ClusterVisualizer::initialize(Trigger, framework::ServiceRegistryRef)
153158
mStoreMaps.size() > 1 ? mStoreMaps.at(calDetIter) : mStoreMaps.at(0));
154159
calDetIter++;
155160
}
161+
if (mIsClusters) {
162+
mCalDetCanvasVec.emplace_back(std::vector<std::unique_ptr<TCanvas>>());
163+
addAndPublish(getObjectsManager(),
164+
mCalDetCanvasVec.back(),
165+
{ "c_radial_profile_Occupancy" },
166+
mStoreMaps.size() > 1 ? mStoreMaps.at(calDetIter) : mStoreMaps.at(0));
167+
}
156168
}
157169

158170
void ClusterVisualizer::update(Trigger t, framework::ServiceRegistryRef)
159171
{
160172
ILOG(Info, Support) << "Trigger type is: " << t.triggerType << ", the timestamp is " << t.timestamp << ENDM;
161173

174+
for (auto& vec : mCalDetCanvasVec) {
175+
for (auto& canvas : vec) {
176+
canvas.get()->Clear();
177+
}
178+
}
179+
162180
auto calDetIter = 0;
163181

164182
std::unique_ptr<ClustersData> clusterData(mCdbApi.retrieveFromTFileAny<ClustersData>(mPath,
@@ -199,6 +217,14 @@ void ClusterVisualizer::update(Trigger t, framework::ServiceRegistryRef)
199217
vecPtr = toVector(mCalDetCanvasVec.at(calDetIter));
200218
o2::tpc::painter::makeSummaryCanvases(calDet, int(mRanges[calDet.getName()].at(0)), mRanges[calDet.getName()].at(1), mRanges[calDet.getName()].at(2), false, &vecPtr);
201219
calDetIter++;
220+
221+
auto occupancy = clusters.getOccupancy(mNHBFPerTF);
222+
vecPtr = toVector(mCalDetCanvasVec.at(calDetIter));
223+
o2::tpc::painter::makeSummaryCanvases(occupancy, int(mRanges[occupancy.getName()].at(0)), mRanges[occupancy.getName()].at(1), mRanges[occupancy.getName()].at(2), false, &vecPtr);
224+
calDetIter++;
225+
vecPtr = toVector(mCalDetCanvasVec.at(calDetIter));
226+
makeRadialProfile(occupancy, vecPtr.at(0), int(mRanges[occupancy.getName()].at(0)), mRanges[occupancy.getName()].at(1), mRanges[occupancy.getName()].at(2));
227+
calDetIter++;
202228
}
203229

204230
void ClusterVisualizer::finalize(Trigger t, framework::ServiceRegistryRef)
@@ -214,4 +240,64 @@ void ClusterVisualizer::finalize(Trigger t, framework::ServiceRegistryRef)
214240
}
215241
}
216242

243+
template <class T>
244+
void ClusterVisualizer::makeRadialProfile(o2::tpc::CalDet<T>& calDet, TCanvas* canv, int nbinsY, float yMin, float yMax)
245+
{
246+
const std::string_view calName = calDet.getName();
247+
const auto radialBinning = o2::tpc::painter::getRowBinningCM();
248+
249+
auto hAside2D = new TH2D(fmt::format("h_{}_radialProfile_Aside", calName).data(), fmt::format("{}: Radial profile (A-Side)", calName).data(), radialBinning.size() - 1, radialBinning.data(), nbinsY, yMin, yMax);
250+
hAside2D->GetXaxis()->SetTitle("x (cm)");
251+
hAside2D->GetYaxis()->SetTitle(fmt::format("{}", calName).data());
252+
hAside2D->SetTitleOffset(1.05, "XY");
253+
hAside2D->SetTitleSize(0.05, "XY");
254+
hAside2D->SetStats(0);
255+
256+
auto hCside2D = new TH2D(fmt::format("h_{}_radialProfile_Cside", calName).data(), fmt::format("{}: Radial profile (C-Side)", calName).data(), radialBinning.size() - 1, radialBinning.data(), nbinsY, yMin, yMax);
257+
hCside2D->GetXaxis()->SetTitle("x (cm)");
258+
hCside2D->GetYaxis()->SetTitle(fmt::format("{}", calName).data());
259+
hCside2D->SetTitleOffset(1.05, "XY");
260+
hCside2D->SetTitleSize(0.05, "XY");
261+
hCside2D->SetStats(0);
262+
263+
fillRadialHisto(*hAside2D, calDet, o2::tpc::Side::A);
264+
fillRadialHisto(*hCside2D, calDet, o2::tpc::Side::C);
265+
266+
canv->Divide(1, 2);
267+
canv->cd(1);
268+
hAside2D->Draw("colz");
269+
hAside2D->SetStats(0);
270+
hAside2D->ProfileX("profile_ASide", 1, -1, "d,same");
271+
272+
canv->cd(2);
273+
hCside2D->Draw("colz");
274+
hCside2D->ProfileX("profile_CSide", 1, -1, "d,same");
275+
hAside2D->SetStats(0);
276+
277+
hAside2D->SetBit(TObject::kCanDelete);
278+
hCside2D->SetBit(TObject::kCanDelete);
279+
}
280+
281+
template <class T>
282+
void ClusterVisualizer::fillRadialHisto(TH2D& h2D, const o2::tpc::CalDet<T>& calDet, const o2::tpc::Side side)
283+
{
284+
const o2::tpc::Mapper& mapper = o2::tpc::Mapper::instance();
285+
286+
for (o2::tpc::ROC roc; !roc.looped(); ++roc) {
287+
if (roc.side() != side) {
288+
continue;
289+
}
290+
const int nrows = mapper.getNumberOfRowsROC(roc);
291+
for (int irow = 0; irow < nrows; ++irow) {
292+
const int npads = mapper.getNumberOfPadsInRowROC(roc, irow);
293+
const int globalRow = irow + (roc >= o2::tpc::Mapper::getNumberOfIROCs()) * o2::tpc::Mapper::getNumberOfRowsInIROC();
294+
for (int ipad = 0; ipad < npads; ++ipad) {
295+
const auto val = calDet.getValue(roc, irow, ipad);
296+
const o2::tpc::LocalPosition2D pos = mapper.getPadCentre(o2::tpc::PadPos(globalRow, ipad));
297+
h2D.Fill(pos.X(), val);
298+
}
299+
}
300+
}
301+
}
302+
217303
} // namespace o2::quality_control_modules::tpc

Modules/TPC/src/Clusters.cxx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "DataFormatsTPC/ClusterNative.h"
2121
#include "TPCBase/Painter.h"
2222
#include "Framework/InputRecordWalker.h"
23+
#include "DetectorsBase/GRPGeomHelper.h"
2324

2425
// QC includes
2526
#include "QualityControl/QcInfoLogger.h"
@@ -42,6 +43,8 @@ void Clusters::initialize(InitContext& /*ctx*/)
4243

4344
mQCClusters.setName("ClusterData");
4445

46+
mNHBFPerTF = o2::base::GRPGeomHelper::instance().getNHBFPerTF();
47+
4548
const auto last = mCustomParameters.end();
4649
const auto itMergeable = mCustomParameters.find("mergeableOutput");
4750
std::string mergeable;
@@ -73,13 +76,16 @@ void Clusters::initialize(InitContext& /*ctx*/)
7376
mWrapperVector.emplace_back(&mQCClusters.getClusters().getSigmaTime());
7477
mWrapperVector.emplace_back(&mQCClusters.getClusters().getSigmaPad());
7578
mWrapperVector.emplace_back(&mQCClusters.getClusters().getTimeBin());
79+
auto occupancy = mQCClusters.getClusters().getOccupancy(mNHBFPerTF);
80+
mWrapperVector.emplace_back(&occupancy);
7681

7782
addAndPublish(getObjectsManager(), mNClustersCanvasVec, { "c_Sides_N_Clusters", "c_ROCs_N_Clusters_1D", "c_ROCs_N_Clusters_2D" });
7883
addAndPublish(getObjectsManager(), mQMaxCanvasVec, { "c_Sides_Q_Max", "c_ROCs_Q_Max_1D", "c_ROCs_Q_Max_2D" });
7984
addAndPublish(getObjectsManager(), mQTotCanvasVec, { "c_Sides_Q_Tot", "c_ROCs_Q_Tot_1D", "c_ROCs_Q_Tot_2D" });
8085
addAndPublish(getObjectsManager(), mSigmaTimeCanvasVec, { "c_Sides_Sigma_Time", "c_ROCs_Sigma_Time_1D", "c_ROCs_Sigma_Time_2D" });
8186
addAndPublish(getObjectsManager(), mSigmaPadCanvasVec, { "c_Sides_Sigma_Pad", "c_ROCs_Sigma_Pad_1D", "c_ROCs_Sigma_Pad_2D" });
8287
addAndPublish(getObjectsManager(), mTimeBinCanvasVec, { "c_Sides_Time_Bin", "c_ROCs_Time_Bin_1D", "c_ROCs_Time_Bin_2D" });
88+
addAndPublish(getObjectsManager(), mOccupancyCanvasVec, { "c_Sides_Occupancy", "c_ROCs_Occupancy_1D", "c_ROCs_Occupancy_2D" });
8389

8490
for (auto& wrapper : mWrapperVector) {
8591
getObjectsManager()->startPublishing<true>(&wrapper);
@@ -123,6 +129,7 @@ void Clusters::processClusterNative(InputRecord& inputs)
123129
}
124130
}
125131
}
132+
mQCClusters.getClusters().endTF();
126133
}
127134

128135
void Clusters::processKrClusters(InputRecord& inputs)
@@ -138,6 +145,7 @@ void Clusters::processKrClusters(InputRecord& inputs)
138145
mQCClusters.getClusters().processCluster(cl, Sector(cl.sector), int(cl.meanRow));
139146
}
140147
}
148+
mQCClusters.getClusters().endTF();
141149
}
142150

143151
void Clusters::monitorData(ProcessingContext& ctx)
@@ -156,12 +164,14 @@ void Clusters::monitorData(ProcessingContext& ctx)
156164
fillCanvases(mQCClusters.getClusters().getSigmaTime(), mSigmaTimeCanvasVec, mCustomParameters, "SigmaPad");
157165
fillCanvases(mQCClusters.getClusters().getSigmaPad(), mSigmaPadCanvasVec, mCustomParameters, "SigmaTime");
158166
fillCanvases(mQCClusters.getClusters().getTimeBin(), mTimeBinCanvasVec, mCustomParameters, "TimeBin");
167+
fillCanvases(mQCClusters.getClusters().getTimeBin(), mOccupancyCanvasVec, mCustomParameters, "Occupancy");
159168
}
160169
}
161170

162171
void Clusters::endOfCycle()
163172
{
164-
ILOG(Debug, Devel) << "endOfCycle" << ENDM;
173+
ILOG(Info, Support) << "endOfCycle" << ENDM;
174+
ILOG(Info, Support) << "Processed TFs: " << mQCClusters.getClusters().getProcessedTFs() << ENDM;
165175

166176
if (mIsMergeable) {
167177
mQCClusters.getClusters().normalize();
@@ -188,6 +198,7 @@ void Clusters::reset()
188198
clearCanvases(mSigmaTimeCanvasVec);
189199
clearCanvases(mSigmaPadCanvasVec);
190200
clearCanvases(mTimeBinCanvasVec);
201+
clearCanvases(mOccupancyCanvasVec);
191202
}
192203
}
193204

0 commit comments

Comments
 (0)