Skip to content

Commit ef01b5f

Browse files
authored
TRD update noisy MCM calibration (#8701)
* TRD fix noisy MCM identifyer * TRD TrackBasedCalib uses DPL CCDB access * Do not crash if noise map missing but raise alarm
1 parent ffe9981 commit ef01b5f

File tree

5 files changed

+116
-29
lines changed

5 files changed

+116
-29
lines changed

DataFormats/Detectors/TRD/include/DataFormatsTRD/NoiseCalibration.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,11 @@ class NoiseStatusMCM
4444
static constexpr int getMcmIdxGlb(int hcid, int rob, int mcm) { return hcid * constants::NMCMHCMAX + (rob / 2) * constants::NMCMROB + mcm; }
4545

4646
// setters
47-
void setIsNoisy(int hcid, int rob, int mcm) { mNoiseFlag.set(hcid * constants::NMCMHCMAX + rob * constants::NMCMROB + mcm); }
47+
void setIsNoisy(int hcid, int rob, int mcm) { mNoiseFlag.set(getMcmIdxGlb(hcid, rob, mcm)); }
4848
void setIsNoisy(int mcmIdxGlb) { mNoiseFlag.set(mcmIdxGlb); }
4949

5050
// getters
51-
bool getIsNoisy(int hcid, int rob, int mcm) const { return mNoiseFlag.test(hcid * constants::NMCMHCMAX + (rob / 2) * constants::NMCMROB + mcm); }
51+
bool getIsNoisy(int hcid, int rob, int mcm) const { return mNoiseFlag.test(getMcmIdxGlb(hcid, rob, mcm)); }
5252
bool getIsNoisy(int mcmIdxGlb) const { return mNoiseFlag.test(mcmIdxGlb); }
5353
auto getNumberOfNoisyMCMs() const { return mNoiseFlag.count(); }
5454
bool isTrackletFromNoisyMCM(const Tracklet64& trklt) const { return getIsNoisy(trklt.getHCID(), trklt.getROB(), trklt.getMCM()); }

Detectors/TRD/calibration/include/TRDCalibration/TrackBasedCalib.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ class TrackBasedCalib
5454
/// Initialize the input arrays
5555
void setInput(const o2::globaltracking::RecoContainer& input);
5656

57+
/// Set the MCM noise map
58+
void setNoiseMapMCM(const NoiseStatusMCM* map) { mNoiseCalib = map; };
59+
5760
/// Reset the output
5861
void reset();
5962

@@ -78,7 +81,7 @@ class TrackBasedCalib
7881
MatCorrType mMatCorr{MatCorrType::USEMatCorrNONE}; ///< if material correction should be done
7982
RecoParam mRecoParam; ///< parameters required for TRD reconstruction
8083
AngularResidHistos mAngResHistos; ///< aggregated data for the track based calibration
81-
NoiseStatusMCM* mNoiseCalib{nullptr}; ///< CCDB object with information of noisy MCMs
84+
const NoiseStatusMCM* mNoiseCalib{nullptr}; ///< CCDB object with information of noisy MCMs
8285
// input arrays which should not be modified since they are provided externally
8386
gsl::span<const TrackTRD> mTracksInITSTPCTRD; ///< TRD tracks reconstructed from TPC or ITS-TPC seeds
8487
gsl::span<const TrackTRD> mTracksInTPCTRD; ///< TRD tracks reconstructed from TPC or TPC seeds

Detectors/TRD/calibration/macros/checkNoisyMCMs.C

Lines changed: 81 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,21 @@
1212
/// \file checkNoisyMCMs.C
1313
/// \brief macro identify noisy MCMs based on the number of found tracklets
1414

15+
/*
16+
Provided an input file with tracklets and trigger records this macro produces a bitset
17+
where noisy MCMs are flagged.
18+
In case useMean is requested the mean number of tracklets sent from each MCM is calculated.
19+
MCMs which don't send any tracklets are not taken into account. The 10% of MCMs which send
20+
the highest number of tracklets are also not considered for the mean calculation. Then, MCMs
21+
which sent more than 100 times as many tracklets as the mean are flagged as noisy. If useMean
22+
is not used simply the MCMs are flagged which sent on average at least one tracklet every 10th
23+
trigger.
24+
25+
Important: Compare the number of tracklets sent from the first and the last masked MCM. In case
26+
there is a large discrepancy between the two numbers the noise threshold might need to be adjusted
27+
or not enough statistics is used.
28+
*/
29+
1530
#if !defined(__CLING__) || defined(__ROOTCLING__)
1631
#include "CCDB/CcdbApi.h"
1732
#include "DataFormatsTRD/NoiseCalibration.h"
@@ -26,10 +41,11 @@
2641
#include <utility>
2742
#include <map>
2843
#include <algorithm>
44+
#include <locale.h>
2945

3046
#endif
3147

32-
void checkNoisyMCMs(std::string inpFile = "trdtracklets.root", bool enableWriteCCDB = false)
48+
void checkNoisyMCMs(std::string inpFile = "trdtracklets.root", bool useMean = true, bool detailedOutput = true, bool enableWriteCCDB = false)
3349
{
3450
using namespace o2::trd;
3551

@@ -51,13 +67,15 @@ void checkNoisyMCMs(std::string inpFile = "trdtracklets.root", bool enableWriteC
5167
tree->SetBranchAddress("TrackTrg", &trigInPtr);
5268
tree->SetBranchAddress("Tracklet", &trackletsInPtr);
5369

54-
std::array<std::pair<unsigned int, unsigned short>, constants::MAXHALFCHAMBER * constants::NMCMHCMAX> trackletCounter{};
70+
std::array<std::pair<unsigned int, unsigned int>, constants::MAXHALFCHAMBER * constants::NMCMHCMAX> trackletCounter{};
5571
std::for_each(trackletCounter.begin(), trackletCounter.end(), [](auto& counter) { static int idx = 0; counter.second = idx++; });
5672

5773
// count number of tracklets per MCM
5874
size_t totalTrackletCounter = 0;
75+
size_t totalTriggerCounter = 0;
5976
for (int iEntry = 0; iEntry < tree->GetEntries(); ++iEntry) {
6077
tree->GetEntry(iEntry);
78+
totalTriggerCounter += trigIn.size();
6179
for (const auto& tracklet : tracklets) {
6280
totalTrackletCounter++;
6381
int mcmGlb = NoiseStatusMCM::getMcmIdxGlb(tracklet.getHCID(), tracklet.getROB(), tracklet.getMCM());
@@ -67,29 +85,53 @@ void checkNoisyMCMs(std::string inpFile = "trdtracklets.root", bool enableWriteC
6785

6886
// estimate noise threshold
6987
std::sort(trackletCounter.begin(), trackletCounter.end(), [](const auto& a, const auto& b) { return a.first < b.first; }); // sort by number of tracklets per MCM
70-
float mean = 0;
71-
int nActiveMcms = 0;
72-
for (int idx = 0; idx < static_cast<int>(0.9 * (constants::MAXHALFCHAMBER * constants::NMCMHCMAX)); ++idx) {
73-
// get average number of tracklets discarding the 10% of MCMs with most entries
88+
float mean90 = 0; // mean excluding 10% of MCMs with most entries
89+
int nActiveMcms90 = 0;
90+
std::vector<int> nTrkltsPerActiveMcm; // for median calculation
91+
for (int idx = 0; idx < constants::MAXHALFCHAMBER * constants::NMCMHCMAX; ++idx) {
7492
if (trackletCounter[idx].first > 0) {
75-
nActiveMcms++;
76-
mean += trackletCounter[idx].first;
93+
nTrkltsPerActiveMcm.push_back(trackletCounter[idx].first);
94+
if (idx < static_cast<int>(0.9 * (constants::MAXHALFCHAMBER * constants::NMCMHCMAX))) {
95+
// for the average number of tracklets we exclude the 10% of MCMs with most entries
96+
nActiveMcms90++;
97+
mean90 += trackletCounter[idx].first;
98+
}
7799
}
78100
}
79-
if (!nActiveMcms) {
101+
if (!nActiveMcms90) {
80102
printf("ERROR: did not find any MCMs which sent tracklets. Aborting\n");
81103
return;
82104
}
83-
mean /= nActiveMcms;
84-
float noiseThreshold = 10 * mean;
85105

86-
for (const auto& counter : trackletCounter) {
87-
if (counter.first > noiseThreshold) {
88-
noiseMap.setIsNoisy(counter.second);
106+
auto n = nTrkltsPerActiveMcm.size() / 2;
107+
auto median = nTrkltsPerActiveMcm[n]; // the distinction between odd/even number of entries in the vector is irrelevant
108+
mean90 /= nActiveMcms90;
109+
auto noiseThreshold = (useMean) ? 100.f * mean90 : (float)totalTriggerCounter / 10.f;
110+
111+
setlocale(LC_NUMERIC, "en_US.utf-8");
112+
printf("Info: Found in total %'lu MCMs which sent tracklets with a median of %i tracklets per MCM\n", nTrkltsPerActiveMcm.size(), median);
113+
printf("Info: Excluding the 10%% of MCMs which sent the highest number of tracklets %'i MCMs remain with on average %.2f tracklets per MCM\n", nActiveMcms90, mean90);
114+
printf("Important: Masking MCMs which sent more than %.2f tracklets for given period\n", noiseThreshold);
115+
116+
std::vector<int> nTrackletsFromNoisyMcm;
117+
bool hasPrintedFirstNoisy = false;
118+
for (int idx = 0; idx < constants::MAXHALFCHAMBER * constants::NMCMHCMAX; ++idx) {
119+
auto mcmIdx = trackletCounter[idx].second;
120+
if (trackletCounter[idx].first > noiseThreshold) {
121+
if (!hasPrintedFirstNoisy) {
122+
printf("Info: The first masked MCM idx(%i) with glb idx %i sent %i trackelts\n", idx, mcmIdx, trackletCounter[idx].first);
123+
hasPrintedFirstNoisy = true;
124+
}
125+
noiseMap.setIsNoisy(mcmIdx);
126+
nTrackletsFromNoisyMcm.push_back(trackletCounter[idx].first);
89127
}
90128
}
129+
if (noiseMap.getNumberOfNoisyMCMs() > 0) {
130+
printf("Info: Last masked MCM sent %i tracklets\n", nTrackletsFromNoisyMcm.back());
131+
}
91132

92133
if (enableWriteCCDB) {
134+
printf("Info: Uploading to CCDB (by default only to ccdb-test)\n");
93135
o2::ccdb::CcdbApi ccdb;
94136
ccdb.init("http://ccdb-test.cern.ch:8080");
95137
std::map<std::string, std::string> metadata;
@@ -98,7 +140,31 @@ void checkNoisyMCMs(std::string inpFile = "trdtracklets.root", bool enableWriteC
98140
auto timeStampEnd = timeStampStart;
99141
timeStampEnd += 1e3 * 60 * 60 * 24 * 60; // 60 days
100142
ccdb.storeAsTFileAny(&noiseMap, "TRD/Calib/NoiseMapMCM", metadata, timeStampStart, timeStampEnd);
143+
} else {
144+
// write to local file
145+
printf("Info: Writing to local file mcmNoiseMap.root\n");
146+
auto fOut = new TFile("mcmNoiseMap.root", "recreate");
147+
fOut->WriteObjectAny(&noiseMap, "o2::trd::NoiseStatusMCM", "map");
148+
fOut->Close();
101149
}
102150

103-
printf("Found in total %lu noisy MCMs for %lu tracklets from %lu trigger records\n", noiseMap.getNumberOfNoisyMCMs(), totalTrackletCounter, trigIn.size());
151+
printf("Info: Found in total %lu noisy MCMs for %'lu tracklets from %'lu triggers\n", noiseMap.getNumberOfNoisyMCMs(), totalTrackletCounter, totalTriggerCounter);
152+
153+
if (detailedOutput) {
154+
size_t countTrackletsFromNoisyMcms = 0;
155+
printf("Info: Number of tracklets sent per masked MCM: \n");
156+
printf("----->\n");
157+
for (int idx = 0; idx < constants::MAXHALFCHAMBER * constants::NMCMHCMAX; ++idx) {
158+
auto mcmIdx = trackletCounter[idx].second;
159+
if (noiseMap.getIsNoisy(mcmIdx)) {
160+
countTrackletsFromNoisyMcms += trackletCounter[idx].first;
161+
int hcid, rob, mcm;
162+
NoiseStatusMCM::convertMcmIdxGlb(mcmIdx, hcid, rob, mcm);
163+
printf("Masked MCM idx (%i), glbIdx(%i). HCID(%i), ROB(%i), MCM(%i). nTracklets: %i\n", idx, mcmIdx, hcid, rob, mcm, trackletCounter[idx].first);
164+
}
165+
}
166+
printf("\n<-----\n");
167+
printf("Info: Number of tracklets sent from masked MCMs: %'lu (%.2f%%)\n", countTrackletsFromNoisyMcms, (float)countTrackletsFromNoisyMcms / totalTrackletCounter * 100);
168+
}
169+
printf("Info: Done\n");
104170
}

Detectors/TRD/calibration/src/TrackBasedCalib.cxx

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
#include "DetectorsBase/GeometryManager.h"
2020
#include "TRDBase/Geometry.h"
2121
#include "TRDBase/PadPlane.h"
22-
#include "CCDB/BasicCCDBManager.h"
2322
#include "CommonUtils/NameConf.h"
2423
#include <fairlogger/Logger.h>
2524

@@ -34,12 +33,6 @@ void TrackBasedCalib::reset()
3433
void TrackBasedCalib::init()
3534
{
3635
mRecoParam.setBfield(o2::base::Propagator::Instance()->getNominalBz());
37-
auto& ccdbmgr = o2::ccdb::BasicCCDBManager::instance();
38-
ccdbmgr.setURL(o2::base::NameConf::getCCDBServer());
39-
mNoiseCalib = ccdbmgr.get<o2::trd::NoiseStatusMCM>("TRD/Calib/NoiseMapMCM");
40-
if (!mNoiseCalib) {
41-
LOG(error) << "Map of noisy MCMs not available";
42-
}
4336
}
4437

4538
void TrackBasedCalib::setInput(const o2::globaltracking::RecoContainer& input)
@@ -69,6 +62,10 @@ void TrackBasedCalib::calculateAngResHistos()
6962
return;
7063
}
7164

65+
if (!mNoiseCalib) {
66+
LOG(alarm) << "No MCM noise map available. Please upload valid object to CCDB.";
67+
}
68+
7269
LOGF(info, "As input tracks are available: %lu ITS-TPC-TRD tracks and %lu TPC-TRD tracks", mTracksInITSTPCTRD.size(), mTracksInTPCTRD.size());
7370

7471
int nTracksSuccessITSTPCTRD = doTrdOnlyTrackFits(mTracksInITSTPCTRD);
@@ -99,7 +96,7 @@ int TrackBasedCalib::doTrdOnlyTrackFits(gsl::span<const TrackTRD>& tracks)
9996
if (trkWork.getTrackletIndex(iLayer) == -1) {
10097
continue;
10198
}
102-
if (mNoiseCalib->isTrackletFromNoisyMCM(mTrackletsRaw[trkWork.getTrackletIndex(iLayer)])) {
99+
if (mNoiseCalib && mNoiseCalib->isTrackletFromNoisyMCM(mTrackletsRaw[trkWork.getTrackletIndex(iLayer)])) {
103100
// ignore tracklets which originate from noisy MCMs
104101
continue;
105102
}
@@ -118,7 +115,7 @@ int TrackBasedCalib::doTrdOnlyTrackFits(gsl::span<const TrackTRD>& tracks)
118115
if (trkWork.getTrackletIndex(iLayer) == -1) {
119116
continue;
120117
}
121-
if (mNoiseCalib->isTrackletFromNoisyMCM(mTrackletsRaw[trkWork.getTrackletIndex(iLayer)])) {
118+
if (mNoiseCalib && mNoiseCalib->isTrackletFromNoisyMCM(mTrackletsRaw[trkWork.getTrackletIndex(iLayer)])) {
122119
// ignore tracklets which originate from noisy MCMs
123120
continue;
124121
}
@@ -137,7 +134,7 @@ int TrackBasedCalib::doTrdOnlyTrackFits(gsl::span<const TrackTRD>& tracks)
137134
if (trkWork.getTrackletIndex(iLayer) == -1) {
138135
continue;
139136
}
140-
if (mNoiseCalib->isTrackletFromNoisyMCM(mTrackletsRaw[trkWork.getTrackletIndex(iLayer)])) {
137+
if (mNoiseCalib && mNoiseCalib->isTrackletFromNoisyMCM(mTrackletsRaw[trkWork.getTrackletIndex(iLayer)])) {
141138
// ignore tracklets which originate from noisy MCMs
142139
continue;
143140
}

Detectors/TRD/workflow/src/TrackBasedCalibSpec.cxx

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "TRDCalibration/TrackBasedCalib.h"
1818
#include "Framework/Task.h"
1919
#include "Framework/ConfigParamRegistry.h"
20+
#include "Framework/CCDBParamSpec.h"
2021
#include "DetectorsBase/GeometryManager.h"
2122
#include "DetectorsBase/Propagator.h"
2223
#include "CommonUtils/NameConf.h"
@@ -40,9 +41,12 @@ class TRDTrackBasedCalibDevice : public Task
4041
~TRDTrackBasedCalibDevice() override = default;
4142
void init(InitContext& ic) final;
4243
void run(ProcessingContext& pc) final;
44+
void finaliseCCDB(framework::ConcreteDataMatcher& matcher, void* obj) final;
4345
void endOfStream(framework::EndOfStreamContext& ec) final;
4446

4547
private:
48+
void updateTimeDependentParams(framework::ProcessingContext& pc);
49+
4650
std::shared_ptr<DataRequest> mDataRequest;
4751
TrackBasedCalib mCalibrator; // gather input data for calibration of vD, ExB and gain
4852
std::unique_ptr<Output> mOutput;
@@ -61,6 +65,7 @@ void TRDTrackBasedCalibDevice::init(InitContext& ic)
6165

6266
void TRDTrackBasedCalibDevice::run(ProcessingContext& pc)
6367
{
68+
updateTimeDependentParams(pc);
6469
if (!mDataHeaderSet) {
6570
mOutput = std::make_unique<Output>(o2::header::gDataOriginTRD, "ANGRESHISTS", 0, Lifetime::Timeframe);
6671
mDataHeaderSet = true;
@@ -78,6 +83,19 @@ void TRDTrackBasedCalibDevice::run(ProcessingContext& pc)
7883
}
7984
}
8085

86+
void TRDTrackBasedCalibDevice::updateTimeDependentParams(ProcessingContext& pc)
87+
{
88+
pc.inputs().get<o2::trd::NoiseStatusMCM*>("mcmnoisemap"); // just to trigger the finaliseCCDB
89+
}
90+
91+
void TRDTrackBasedCalibDevice::finaliseCCDB(ConcreteDataMatcher& matcher, void* obj)
92+
{
93+
if (matcher == ConcreteDataMatcher("TRD", "MCMNOISEMAP", 0)) {
94+
LOG(info) << "NoiseStatusMCM object has been updated";
95+
mCalibrator.setNoiseMapMCM((const o2::trd::NoiseStatusMCM*)obj);
96+
}
97+
}
98+
8199
void TRDTrackBasedCalibDevice::endOfStream(EndOfStreamContext& ec)
82100
{
83101
if (mNumberOfProcessedTFs > 0) {
@@ -105,11 +123,14 @@ DataProcessorSpec getTRDTrackBasedCalibSpec(o2::dataformats::GlobalTrackID::mask
105123
dataRequest->requestTracks(srcTrk, false);
106124
dataRequest->requestClusters(srcClu, false);
107125

126+
auto& inputs = dataRequest->inputs;
127+
inputs.emplace_back("mcmnoisemap", "TRD", "MCMNOISEMAP", 0, Lifetime::Condition, ccdbParamSpec("TRD/Calib/NoiseMapMCM"));
128+
108129
outputs.emplace_back(o2::header::gDataOriginTRD, "ANGRESHISTS", 0, Lifetime::Timeframe);
109130

110131
return DataProcessorSpec{
111132
"trd-trackbased-calib",
112-
dataRequest->inputs,
133+
inputs,
113134
outputs,
114135
AlgorithmSpec{adaptFromTask<TRDTrackBasedCalibDevice>(dataRequest)},
115136
Options{}};

0 commit comments

Comments
 (0)