Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Modules/TPC/include/TPC/ClusterVisualizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,14 @@ class ClusterVisualizer final : public quality_control::postprocessing::PostProc
/// \param services Interface containing optional interfaces, for example DatabaseInterface
void finalize(quality_control::postprocessing::Trigger, framework::ServiceRegistryRef) override;

template <class T>
void makeRadialProfile(o2::tpc::CalDet<T>& calDet, TCanvas* canv, int nbinsY, float yMin, float yMax);

template <class T>
void fillRadialHisto(TH2D& h2D, const o2::tpc::CalDet<T>& calDet, const o2::tpc::Side side);

private:
int mNHBFPerTF = 32;
o2::ccdb::CcdbApi mCdbApi;
std::string mHost;
std::vector<std::vector<std::unique_ptr<TCanvas>>> mCalDetCanvasVec{}; ///< vector containing a vector of summary canvases for every CalDet object
Expand Down
2 changes: 2 additions & 0 deletions Modules/TPC/include/TPC/Clusters.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class Clusters /*final*/ : public TaskInterface // todo add back the "final" whe

private:
bool mIsMergeable = true;
int mNHBFPerTF = 32;
ClustersData mQCClusters{}; ///< O2 Cluster task to perform actions on cluster objects
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
std::vector<std::unique_ptr<TCanvas>> mNClustersCanvasVec{}; ///< summary canvases of the NClusters object
Expand All @@ -63,6 +64,7 @@ class Clusters /*final*/ : public TaskInterface // todo add back the "final" whe
std::vector<std::unique_ptr<TCanvas>> mSigmaTimeCanvasVec{}; ///< summary canvases of the SigmaTime object
std::vector<std::unique_ptr<TCanvas>> mSigmaPadCanvasVec{}; ///< summary canvases of the SigmaPad object
std::vector<std::unique_ptr<TCanvas>> mTimeBinCanvasVec{}; ///< summary canvases of the TimeBin object
std::vector<std::unique_ptr<TCanvas>> mOccupancyCanvasVec{}; ///< summary canvases of the Occupancy object

void processClusterNative(o2::framework::InputRecord& inputs);
void processKrClusters(o2::framework::InputRecord& inputs);
Expand Down
7 changes: 4 additions & 3 deletions Modules/TPC/run/tpcQCClusterVisualizer.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,18 +60,19 @@
{ "Q_Tot" : [ "600", "0", "600" ] },
{ "Sigma_Time" : [ "200", "0", "2" ] },
{ "Sigma_Pad" : [ "200", "0", "2" ] },
{ "Time_Bin" : [ "1000", "0", "100000" ] }
{ "Time_Bin" : [ "1000", "0", "100000" ] },
{ "Occupancy" : [ "100", "0", "0.001" ] }
],
"path_comment": "This is the path of the ClustersData object that shall be visualized.",
"path": "TPC/MO/Clusters/ClusterData",
"path": "qc/TPC/MO/Clusters/ClusterData",
"dataType_comment": "This is the switch for 'RawDigits' or 'Clusters' task. Choose 'raw' or 'clusters'.",
"dataType": "clusters",
"initTrigger": [
"once"
],
"updateTrigger_comment": "To trigger on a specific file being updated, use e.g. 'newobject:qcdb:TPC/Calib/Noise'",
"updateTrigger": [
"newobject:qcdb:TPC/MO/Clusters/ClusterData"
"newobject:ccdb:qc/TPC/MO/Clusters/ClusterData"
],
"stopTrigger": [
"userorcontrol"
Expand Down
6 changes: 4 additions & 2 deletions Modules/TPC/run/tpcQCClusters_direct.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
"className": "o2::quality_control_modules::tpc::Clusters",
"moduleName": "QcTPC",
"detectorName": "TPC",
"cycleDurationSeconds": "10",
"cycleDurationSeconds": "60",
"maxNumberCycles": "-1",
"resetAfterCycles": "5",
"dataSource": {
"type": "direct",
Expand All @@ -41,7 +42,8 @@
"QtotNBins": "600", "QtotXMin": "0", "QtotXMax": "600",
"SigmaPadNBins": "200", "SigmaPadXMin": "0", "SigmaPadXMax": "2",
"SigmaTimeNBins": "200", "SigmaTimeXMin": "0", "SigmaTimeXMax": "2",
"TimeBinNBins": "1000", "TimeBinXMin": "0", "TimeBinXMax": "100000"
"TimeBinNBins": "1000", "TimeBinXMin": "0", "TimeBinXMax": "100000",
"OccupancyNBins": "1000", "OccupancyXMin": "0", "OccupancyXMax": "0.00001"
},
"location": "local",
"localMachines": [
Expand Down
90 changes: 88 additions & 2 deletions Modules/TPC/src/ClusterVisualizer.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "TPCBase/Painter.h"
#include "TPCBase/CDBInterface.h"
#include "TPCQC/Helpers.h"
#include "DetectorsBase/GRPGeomHelper.h"

// QC includes
#include "QualityControl/QcInfoLogger.h"
Expand Down Expand Up @@ -120,14 +121,16 @@ void ClusterVisualizer::configure(const boost::property_tree::ptree& config)
"Q_Tot",
"Sigma_Pad",
"Sigma_Time",
"Time_Bin"
"Time_Bin",
"Occupancy"
};
} else if (type == "raw") {
mIsClusters = false;
mObservables = {
"N_RawDigits",
"Q_Max",
"Time_Bin"
"Time_Bin",
"Occupancy"
};
} else {
ILOG(Error, Support) << "No valid data type given. 'dataType' has to be either 'clusters' or 'raw'." << ENDM;
Expand All @@ -138,6 +141,8 @@ void ClusterVisualizer::initialize(Trigger, framework::ServiceRegistryRef)
{
mCdbApi.init(mHost);

mNHBFPerTF = o2::base::GRPGeomHelper::instance().getNHBFPerTF();

if (mCalDetCanvasVec.size() > 0) {
mCalDetCanvasVec.clear();
}
Expand All @@ -153,12 +158,25 @@ void ClusterVisualizer::initialize(Trigger, framework::ServiceRegistryRef)
mStoreMaps.size() > 1 ? mStoreMaps.at(calDetIter) : mStoreMaps.at(0));
calDetIter++;
}
if (mIsClusters) {
mCalDetCanvasVec.emplace_back(std::vector<std::unique_ptr<TCanvas>>());
addAndPublish(getObjectsManager(),
mCalDetCanvasVec.back(),
{ "c_radial_profile_Occupancy" },
mStoreMaps.size() > 1 ? mStoreMaps.at(calDetIter) : mStoreMaps.at(0));
}
}

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

for (auto& vec : mCalDetCanvasVec) {
for (auto& canvas : vec) {
canvas.get()->Clear();
}
}

auto calDetIter = 0;

std::unique_ptr<ClustersData> clusterData(mCdbApi.retrieveFromTFileAny<ClustersData>(mPath,
Expand Down Expand Up @@ -199,6 +217,14 @@ void ClusterVisualizer::update(Trigger t, framework::ServiceRegistryRef)
vecPtr = toVector(mCalDetCanvasVec.at(calDetIter));
o2::tpc::painter::makeSummaryCanvases(calDet, int(mRanges[calDet.getName()].at(0)), mRanges[calDet.getName()].at(1), mRanges[calDet.getName()].at(2), false, &vecPtr);
calDetIter++;

auto occupancy = clusters.getOccupancy(mNHBFPerTF);
vecPtr = toVector(mCalDetCanvasVec.at(calDetIter));
o2::tpc::painter::makeSummaryCanvases(occupancy, int(mRanges[occupancy.getName()].at(0)), mRanges[occupancy.getName()].at(1), mRanges[occupancy.getName()].at(2), false, &vecPtr);
calDetIter++;
vecPtr = toVector(mCalDetCanvasVec.at(calDetIter));
makeRadialProfile(occupancy, vecPtr.at(0), int(mRanges[occupancy.getName()].at(0)), mRanges[occupancy.getName()].at(1), mRanges[occupancy.getName()].at(2));
calDetIter++;
}

void ClusterVisualizer::finalize(Trigger t, framework::ServiceRegistryRef)
Expand All @@ -214,4 +240,64 @@ void ClusterVisualizer::finalize(Trigger t, framework::ServiceRegistryRef)
}
}

template <class T>
void ClusterVisualizer::makeRadialProfile(o2::tpc::CalDet<T>& calDet, TCanvas* canv, int nbinsY, float yMin, float yMax)
{
const std::string_view calName = calDet.getName();
const auto radialBinning = o2::tpc::painter::getRowBinningCM();

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);
hAside2D->GetXaxis()->SetTitle("x (cm)");
hAside2D->GetYaxis()->SetTitle(fmt::format("{}", calName).data());
hAside2D->SetTitleOffset(1.05, "XY");
hAside2D->SetTitleSize(0.05, "XY");
hAside2D->SetStats(0);

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);
hCside2D->GetXaxis()->SetTitle("x (cm)");
hCside2D->GetYaxis()->SetTitle(fmt::format("{}", calName).data());
hCside2D->SetTitleOffset(1.05, "XY");
hCside2D->SetTitleSize(0.05, "XY");
hCside2D->SetStats(0);

fillRadialHisto(*hAside2D, calDet, o2::tpc::Side::A);
fillRadialHisto(*hCside2D, calDet, o2::tpc::Side::C);

canv->Divide(1, 2);
canv->cd(1);
hAside2D->Draw("colz");
hAside2D->SetStats(0);
hAside2D->ProfileX("profile_ASide", 1, -1, "d,same");

canv->cd(2);
hCside2D->Draw("colz");
hCside2D->ProfileX("profile_CSide", 1, -1, "d,same");
hAside2D->SetStats(0);

hAside2D->SetBit(TObject::kCanDelete);
hCside2D->SetBit(TObject::kCanDelete);
}

template <class T>
void ClusterVisualizer::fillRadialHisto(TH2D& h2D, const o2::tpc::CalDet<T>& calDet, const o2::tpc::Side side)
{
const o2::tpc::Mapper& mapper = o2::tpc::Mapper::instance();

for (o2::tpc::ROC roc; !roc.looped(); ++roc) {
if (roc.side() != side) {
continue;
}
const int nrows = mapper.getNumberOfRowsROC(roc);
for (int irow = 0; irow < nrows; ++irow) {
const int npads = mapper.getNumberOfPadsInRowROC(roc, irow);
const int globalRow = irow + (roc >= o2::tpc::Mapper::getNumberOfIROCs()) * o2::tpc::Mapper::getNumberOfRowsInIROC();
for (int ipad = 0; ipad < npads; ++ipad) {
const auto val = calDet.getValue(roc, irow, ipad);
const o2::tpc::LocalPosition2D pos = mapper.getPadCentre(o2::tpc::PadPos(globalRow, ipad));
h2D.Fill(pos.X(), val);
}
}
}
}

} // namespace o2::quality_control_modules::tpc
13 changes: 12 additions & 1 deletion Modules/TPC/src/Clusters.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "DataFormatsTPC/ClusterNative.h"
#include "TPCBase/Painter.h"
#include "Framework/InputRecordWalker.h"
#include "DetectorsBase/GRPGeomHelper.h"

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

mQCClusters.setName("ClusterData");

mNHBFPerTF = o2::base::GRPGeomHelper::instance().getNHBFPerTF();

const auto last = mCustomParameters.end();
const auto itMergeable = mCustomParameters.find("mergeableOutput");
std::string mergeable;
Expand Down Expand Up @@ -73,13 +76,16 @@ void Clusters::initialize(InitContext& /*ctx*/)
mWrapperVector.emplace_back(&mQCClusters.getClusters().getSigmaTime());
mWrapperVector.emplace_back(&mQCClusters.getClusters().getSigmaPad());
mWrapperVector.emplace_back(&mQCClusters.getClusters().getTimeBin());
auto occupancy = mQCClusters.getClusters().getOccupancy(mNHBFPerTF);
mWrapperVector.emplace_back(&occupancy);

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

for (auto& wrapper : mWrapperVector) {
getObjectsManager()->startPublishing<true>(&wrapper);
Expand Down Expand Up @@ -123,6 +129,7 @@ void Clusters::processClusterNative(InputRecord& inputs)
}
}
}
mQCClusters.getClusters().endTF();
}

void Clusters::processKrClusters(InputRecord& inputs)
Expand All @@ -138,6 +145,7 @@ void Clusters::processKrClusters(InputRecord& inputs)
mQCClusters.getClusters().processCluster(cl, Sector(cl.sector), int(cl.meanRow));
}
}
mQCClusters.getClusters().endTF();
}

void Clusters::monitorData(ProcessingContext& ctx)
Expand All @@ -156,12 +164,14 @@ void Clusters::monitorData(ProcessingContext& ctx)
fillCanvases(mQCClusters.getClusters().getSigmaTime(), mSigmaTimeCanvasVec, mCustomParameters, "SigmaPad");
fillCanvases(mQCClusters.getClusters().getSigmaPad(), mSigmaPadCanvasVec, mCustomParameters, "SigmaTime");
fillCanvases(mQCClusters.getClusters().getTimeBin(), mTimeBinCanvasVec, mCustomParameters, "TimeBin");
fillCanvases(mQCClusters.getClusters().getTimeBin(), mOccupancyCanvasVec, mCustomParameters, "Occupancy");
}
}

void Clusters::endOfCycle()
{
ILOG(Debug, Devel) << "endOfCycle" << ENDM;
ILOG(Info, Support) << "endOfCycle" << ENDM;
ILOG(Info, Support) << "Processed TFs: " << mQCClusters.getClusters().getProcessedTFs() << ENDM;

if (mIsMergeable) {
mQCClusters.getClusters().normalize();
Expand All @@ -188,6 +198,7 @@ void Clusters::reset()
clearCanvases(mSigmaTimeCanvasVec);
clearCanvases(mSigmaPadCanvasVec);
clearCanvases(mTimeBinCanvasVec);
clearCanvases(mOccupancyCanvasVec);
}
}

Expand Down