Project
Loading...
Searching...
No Matches
OfflineCalibSpec.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
12#include <iostream>
13#include <vector>
14#include <type_traits>
15#include <gsl/span>
16
17#include <fairlogger/Logger.h>
18
26
27using namespace o2::emcal;
28
30{
31 // energy vs. cell ID
32 mCellAmplitude = std::unique_ptr<TH2>(new TH2F("mCellAmplitude", "Cell amplitude", 800, 0., 40., 17664, -0.5, 17663.5));
33 // time vs. cell ID
34 mCellTime = std::unique_ptr<TH2>(new TH2F("mCellTime", "Cell time", 800, -200, 600, 17664, -0.5, 17663.5));
35 // time vs. cell ID
36 mCellTimeLG = std::unique_ptr<TH2>(new TH2F("mCellTimeLG", "Cell time (low gain)", 800, -200, 600, 17664, -0.5, 17663.5));
37 // time vs. cell ID
38 mCellTimeHG = std::unique_ptr<TH2>(new TH2F("mCellTimeHG", "Cell time (high gain)", 800, -200, 600, 17664, -0.5, 17663.5));
39 // number of events
40 mNevents = std::unique_ptr<TH1>(new TH1F("mNevents", "Number of events", 1, 0.5, 1.5));
41 if (mMakeCellIDTimeEnergy) {
42 // cell time, cell energy, cell ID
43 std::array<int, 3> arrNBins = {17664, 100, 100}; // NCells, time, energy
44 std::array<double, 3> arrMin = {-0.5, -50, 0};
45 std::array<double, 3> arrMax = {17663.5, 50., 50};
46 mCellTimeEnergy = std::unique_ptr<THnSparseF>(new THnSparseF("CellIDvsTimevsEnergy", "CellIDvsTimevsEnergy", arrNBins.size(), arrNBins.data(), arrMin.data(), arrMax.data()));
47 }
48}
49
51{
52 LOG(info) << "Handling new Calibration objects";
53 mCalibrationHandler->finalizeCCDB(matcher, obj);
54
55 if (matcher == o2::framework::ConcreteDataMatcher("EMC", "EMCALCALIBPARAM", 0)) {
56 LOG(info) << "EMCal CalibParams updated";
58 }
59
60 if (mRejectL0Triggers && matcher == o2::framework::ConcreteDataMatcher("CTP", "CTPCONFIG", 0)) {
61 // clear current class mask and prepare to fill in the updated values
62 // The trigger names are seperated by a ":" in one string in the calib params
63 mSelectedClassMasks.clear();
64 std::string strSelClassMasks = EMCALCalibParams::Instance().selectedClassMasks;
65 std::string delimiter = ":";
66 size_t pos = 0;
67 std::vector<std::string> vSelMasks;
68 while ((pos = strSelClassMasks.find(delimiter)) != std::string::npos) {
69 vSelMasks.push_back(strSelClassMasks.substr(0, pos));
70 strSelClassMasks.erase(0, pos + delimiter.length());
71 }
72 vSelMasks.push_back(strSelClassMasks);
73
74 auto ctpconf = reinterpret_cast<o2::ctp::CTPConfiguration*>(obj);
75
76 for (auto& cls : ctpconf->getCTPClasses()) {
77 LOG(debug) << "CTP class: " << cls.name << "\t " << cls.classMask;
78
79 if (std::find(vSelMasks.begin(), vSelMasks.end(), cls.name) != vSelMasks.end()) {
80 mSelectedClassMasks.push_back(cls.classMask);
81 LOG(info) << "Setting selected class mask " << cls.name << " to bit " << cls.classMask;
82 }
83 }
84 }
85}
86
87void OfflineCalibSpec::updateCalibObjects()
88{
89 if (mCalibrationHandler->hasUpdateGainCalib()) {
90 LOG(info) << "updateCalibObjects: Gain calib params changed";
91 mGainCalibFactors = mCalibrationHandler->getGainCalibration();
92 }
93}
94
96{
97 auto cells = pc.inputs().get<gsl::span<o2::emcal::Cell>>("cells");
98 auto triggerrecords = pc.inputs().get<gsl::span<o2::emcal::TriggerRecord>>("triggerrecord");
99
100 // prepare CTPConfiguration such that it can be loaded in finalise ccdb
101 if (mRejectL0Triggers) {
103 }
104
105 using ctpDigitsType = std::decay_t<decltype(pc.inputs().get<gsl::span<o2::ctp::CTPDigit>>(getCTPDigitsBinding()))>;
106 std::optional<ctpDigitsType> ctpDigits;
107 if (mRejectL0Triggers) {
108 ctpDigits = pc.inputs().get<gsl::span<o2::ctp::CTPDigit>>(getCTPDigitsBinding());
109 }
110
111 mCalibrationHandler->checkUpdates(pc);
112 updateCalibObjects();
113
114 LOG(debug) << "[EMCALOfflineCalib - run] received " << cells.size() << " cells from " << triggerrecords.size() << " triggers ...";
115 if (triggerrecords.size()) {
116 for (const auto& trg : triggerrecords) {
117 if (!trg.getNumberOfObjects()) {
118 LOG(debug) << "[EMCALOfflineCalib - run] Trigger does not contain cells, skipping ...";
119 continue;
120 }
121
122 // reject calibration triggers (EMCAL LED events etc.)
123 if (mRejectCalibTriggers) {
124 LOG(debug) << "Trigger: " << trg.getTriggerBits() << " o2::trigger::Cal " << o2::trigger::Cal;
125 if (trg.getTriggerBits() & o2::trigger::Cal) {
126 LOG(debug) << "skipping triggered events due to wrong trigger (no Physics trigger)";
127 continue;
128 }
129 }
130
131 // reject all triggers that are not included in the classMask (typically only EMC min. bias should be accepted)
132 uint64_t classMaskCTP = 0;
133 if (mRejectL0Triggers) {
134 bool acceptEvent = false;
135 // Match the EMCal bc to the CTP bc
136 int64_t bcEMC = trg.getBCData().toLong();
137 for (auto& ctpDigit : *ctpDigits) {
138 int64_t bcCTP = ctpDigit.intRecord.toLong();
139 LOG(debug) << "bcEMC " << bcEMC << " bcCTP " << bcCTP;
140 if (bcCTP == bcEMC) {
141 // obtain trigger mask that belongs to the selected bc
142 classMaskCTP = ctpDigit.CTPClassMask.to_ulong();
143 // now check if min bias trigger is not in mask
144 for (const uint64_t& selectedClassMask : mSelectedClassMasks) {
145 if ((classMaskCTP & selectedClassMask) != 0) {
146 LOG(debug) << "trigger " << selectedClassMask << " found! accepting event";
147 acceptEvent = true;
148 break;
149 }
150 }
151 break; // break as bc was matched
152 }
153 }
154 // if current event is not accepted (selected triggers not present), move on to next event
155 if (!acceptEvent) {
156 continue;
157 }
158 }
159
160 LOG(debug) << "[EMCALOfflineCalib - run] Trigger has " << trg.getNumberOfObjects() << " cells ..." << std::endl;
161 gsl::span<const o2::emcal::Cell> objectsTrigger(cells.data() + trg.getFirstEntry(), trg.getNumberOfObjects());
162 for (const auto& c : objectsTrigger) {
163 LOG(debug) << "[EMCALOfflineSpec - run] Channel: " << c.getTower();
164 LOG(debug) << "[EMCALOfflineSpec - run] Energy: " << c.getEnergy();
165 LOG(debug) << "[EMCALOfflineSpec - run] Time: " << c.getTimeStamp();
166 LOG(debug) << "[EMCALOfflineSpec - run] IsLowGain: " << c.getLowGain();
167 float cellE = c.getEnergy();
168 if (mGainCalibFactors && mCalibrationHandler->hasGainCalib()) {
169 LOG(debug) << "gain calib factor " << mGainCalibFactors->getGainCalibFactors(c.getTower());
170 cellE *= mGainCalibFactors->getGainCalibFactors(c.getTower());
171 LOG(debug) << "[EMCALOfflineSpec - run] corrected Energy: " << cellE;
172 }
173 mCellAmplitude->Fill(cellE, c.getTower());
174 if (cellE > 0.5) {
175 mCellTime->Fill(c.getTimeStamp(), c.getTower());
176 if (c.getLowGain()) {
177 mCellTimeLG->Fill(c.getTimeStamp(), c.getTower());
178 } else { // high gain cells
179 mCellTimeHG->Fill(c.getTimeStamp(), c.getTower());
180 }
181 if (mMakeCellIDTimeEnergy) {
182 mCellTimeEnergy->Fill(c.getTower(), c.getTimeStamp(), cellE);
183 }
184 }
185 }
186 mNevents->Fill(1);
187 }
188 }
189}
190
192{
193 // write histograms to root file here
194 std::unique_ptr<TFile> outputFile(new TFile("emcal-offline-calib.root", "RECREATE"));
195 outputFile->cd();
196 mCellAmplitude->Write();
197 mCellTime->Write();
198 mCellTimeLG->Write();
199 mCellTimeHG->Write();
200 mNevents->Write();
201 if (mMakeCellIDTimeEnergy) {
202 mCellTimeEnergy->Write();
203 }
204 outputFile->Close();
205}
206
207o2::framework::DataProcessorSpec o2::emcal::getEmcalOfflineCalibSpec(bool makeCellIDTimeEnergy, bool rejectCalibTriggers, bool rejectL0Trigger, uint32_t inputsubspec, bool enableGainCalib, bool ctpcfgperrun)
208{
209
210 std::vector<o2::framework::InputSpec>
211 inputs = {{"cells", o2::header::gDataOriginEMC, "CELLS", inputsubspec, o2::framework::Lifetime::Timeframe},
212 {"triggerrecord", o2::header::gDataOriginEMC, "CELLSTRGR", inputsubspec, o2::framework::Lifetime::Timeframe}};
213
214 if (rejectL0Trigger) {
215 inputs.emplace_back(OfflineCalibSpec::getCTPConfigBinding(), "CTP", "CTPCONFIG", 0, o2::framework::Lifetime::Condition, o2::framework::ccdbParamSpec("CTP/Config/Config", ctpcfgperrun));
216 inputs.emplace_back(OfflineCalibSpec::getCTPDigitsBinding(), "CTP", "DIGITS", 0, o2::framework::Lifetime::Timeframe);
217 }
218 auto calibhandler = std::make_shared<o2::emcal::CalibLoader>();
219 calibhandler->enableGainCalib(enableGainCalib);
220 calibhandler->defineInputSpecs(inputs);
221
222 return o2::framework::DataProcessorSpec{"EMCALOfflineCalib",
223 inputs,
224 {},
225 o2::framework::adaptFromTask<o2::emcal::OfflineCalibSpec>(makeCellIDTimeEnergy, rejectCalibTriggers, rejectL0Trigger, calibhandler)};
226}
Definition of the 32 Central Trigger System (CTS) Trigger Types defined in https://twiki....
uint16_t pos
Definition RawData.h:3
uint32_t c
Definition RawData.h:2
std::ostringstream debug
void printKeyValues(bool showProv=true, bool useLogger=false) const final
float getGainCalibFactors(unsigned short iCell) const
Get the gain calibration factor for a certain cell.
static const char * getCTPConfigBinding()
void finaliseCCDB(framework::ConcreteDataMatcher &matcher, void *obj) final
void endOfStream(o2::framework::EndOfStreamContext &ec) final
Write histograms to an output root file.
static const char * getCTPDigitsBinding()
void init(framework::InitContext &ctx) final
Initializing the offline calib task.
void run(framework::ProcessingContext &ctx) final
Fill histograms needed for the offline calibration.
decltype(auto) get(R binding, int part=0) const
InputRecord & inputs()
The inputs associated with this processing context.
o2::framework::DataProcessorSpec getEmcalOfflineCalibSpec(bool makeCellIDTimeEnergy, bool rejectCalibTriggers, bool rejectL0Trigger, uint32_t inputsubspec, bool enableGainCalib, bool ctpcfgperrun)
Creating offline calib spec.
constexpr o2::header::DataOrigin gDataOriginEMC
Definition DataHeader.h:565
std::vector< ConfigParamSpec > ccdbParamSpec(std::string const &path, int runDependent, std::vector< CCDBMetadata > metadata={}, int qrate=0)
constexpr uint32_t Cal
Definition Triggers.h:32
std::string selectedClassMasks
name of EMCal min. bias trigger that is used for calibration
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< Cell > cells