Project
Loading...
Searching...
No Matches
PadPedestalCalibDevice.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 <filesystem>
13#include <string>
14
15#include <TFile.h>
16#include <TF1.h>
17#include <TH1.h>
18
19#include "CCDB/CcdbApi.h"
20#include "CCDB/CcdbObjectInfo.h"
30
31using namespace o2::focal;
32
33PadPedestalCalibDevice::PadPedestalCalibDevice(bool updateCCDB, const std::string& path, bool debugMode) : mUpdateCCDB(updateCCDB), mPath(path), mDebug(debugMode) {}
34
36{
37 std::string histname, histtitle;
38 for (auto layer = 0; layer < 18; layer++) {
39 histname = "PADADC_Layer" + std::to_string(layer);
40 histtitle = "Pad ADC distribution Layer " + std::to_string(layer);
41 mADCDistLayer[layer] = std::make_unique<TH2D>(histname.data(), histtitle.data(), constants::PADLAYER_MODULE_NCHANNELS, -0.5, constants::PADLAYER_MODULE_NCHANNELS - 0.5, 2000, 0., 2000.);
42 mADCDistLayer[layer]->SetDirectory(nullptr);
43 }
44
45 auto calibmethod = ctx.options().get<std::string>("calibmethod");
46 if (calibmethod == "mean") {
47 mExtractionMethod = Method_t::MEAN;
48 } else if (calibmethod == "fit") {
49 mExtractionMethod = Method_t::FIT;
50 } else {
51 LOG(error) << "Unknown calibration method - using default (mean) instead";
52 }
53 LOG(info) << "Writing calibration histograms in path: " << mPath;
54}
55
57{
58 std::vector<char> rawbuffer;
59 for (const auto& rawData : framework::InputRecordWalker(ctx.inputs())) {
60 if (rawData.header != nullptr && rawData.payload != nullptr) {
61 const auto payloadSize = o2::framework::DataRefUtils::getPayloadSize(rawData);
62
63 gsl::span<const char> databuffer(rawData.payload, payloadSize);
64 int currentpos = 0;
65 int currentfee = 0;
66 bool firstHBF = true;
67 while (currentpos < databuffer.size()) {
68 auto rdh = reinterpret_cast<const o2::header::RDHAny*>(databuffer.data() + currentpos);
69 auto trigger = o2::raw::RDHUtils::getTriggerType(rdh);
70 if (trigger & o2::trigger::HB) {
71 // HB trigger received
72 if (o2::raw::RDHUtils::getStop(rdh)) {
73 // Data ready
74 if (rawbuffer.size()) {
75 // Only process if we actually have payload (skip empty HBF)
76 if (currentfee == 0xcafe) { // Use FEE ID 0xcafe for PAD data
77 processRawData(rawbuffer);
78 }
79 } else {
80 LOG(debug) << "Payload size 0 - skip empty HBF";
81 }
82 } else {
83 rawbuffer.clear();
84 currentfee = o2::raw::RDHUtils::getFEEID(rdh);
85 }
86 }
87
88 if (o2::raw::RDHUtils::getMemorySize(rdh) == o2::raw::RDHUtils::getHeaderSize(rdh)) {
89 // Skip page if emtpy
90 currentpos += o2::raw::RDHUtils::getOffsetToNext(rdh);
91 continue;
92 }
93
94 // non-0 payload size:
95 auto payloadsize = o2::raw::RDHUtils::getMemorySize(rdh) - o2::raw::RDHUtils::getHeaderSize(rdh);
96 auto page_payload = databuffer.subspan(currentpos + o2::raw::RDHUtils::getHeaderSize(rdh), payloadsize);
97 std::copy(page_payload.begin(), page_payload.end(), std::back_inserter(rawbuffer));
98 currentpos += o2::raw::RDHUtils::getOffsetToNext(rdh);
99 }
100 }
101 }
102}
103
105{
106 LOG(info) << "Data collected - calculating pedestals and sending them";
107 calculatePedestals();
108 sendData(ec.outputs());
109}
110
111void PadPedestalCalibDevice::sendData(o2::framework::DataAllocator& output)
112{
113
114 if (mUpdateCCDB) {
115 // prepare all info to be sent to CCDB
117 auto image = o2::ccdb::CcdbApi::createObjectImage(mPedestalContainer.get(), &info);
118
119 auto flName = o2::ccdb::CcdbApi::generateFileName("Pedestals");
120 info.setPath("FOC/Calib/PadPedestals");
121 info.setObjectType("Pedestals");
122 info.setFileName(flName);
123
124 const auto now = std::chrono::system_clock::now();
125 long timeStart = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
126 info.setStartValidityTimestamp(timeStart);
128 std::map<std::string, std::string> md;
129 info.setMetaData(md);
130
131 LOG(info) << "Sending object FOC/Calib/PadPedestals";
132
134 output.snapshot(framework::Output{o2::calibration::Utils::gDataOriginCDBPayload, "FOC_PADPEDESTALS", subSpec}, *image.get());
135 output.snapshot(framework::Output{o2::calibration::Utils::gDataOriginCDBWrapper, "FOC_PADPEDESTALS", subSpec}, info);
136 }
137
138 if (mDebug) {
139 TFile pedestalWriter("FOCALPedestalCalib.root", "RECREATE");
140 pedestalWriter.cd();
141 pedestalWriter.WriteObjectAny(mPedestalContainer.get(), o2::focal::PadPedestal::Class(), "ccdb_object");
142 }
143
144 // store ADC distributions in local file
145 std::filesystem::path filepath(mPath);
146 filepath.append("FOCALPadPedestals.root");
147 LOG(info) << "Writing ADC distribution to " << filepath.c_str();
148 TFile distwriter(filepath.c_str(), "RECREATE");
149 distwriter.cd();
150 for (int layer = 0; layer < mADCDistLayer.size(); layer++) {
151 mADCDistLayer[layer]->Write();
152 }
153}
154
155void PadPedestalCalibDevice::processRawData(const gsl::span<const char> padWords)
156{
157 constexpr std::size_t EVENTSIZEPADGBT = 1180,
158 EVENTSIZECHAR = EVENTSIZEPADGBT * sizeof(PadGBTWord) / sizeof(char);
159 auto nevents = padWords.size() / (EVENTSIZECHAR);
160 for (int ievent = 0; ievent < nevents; ievent++) {
161 gsl::span<const PadGBTWord> padWordsGBT(reinterpret_cast<const PadGBTWord*>(padWords.data()), padWords.size() / sizeof(PadGBTWord));
162 mDecoder.reset();
163 mDecoder.decodeEvent(padWordsGBT);
164 // Fill histograms
165 for (auto layer = 0; layer < 18; layer++) {
166 auto layerdata = mDecoder.getData().getDataForASIC(layer).getASIC();
167 for (std::size_t chan = 0; chan < constants::PADLAYER_MODULE_NCHANNELS; chan++) {
168 mADCDistLayer[layer]->Fill(chan, layerdata.getChannel(chan).getADC());
169 }
170 }
171 }
172}
173
174void PadPedestalCalibDevice::calculatePedestals()
175{
176 mPedestalContainer = std::make_unique<PadPedestal>();
177 int nPedestals = 0;
178 for (std::size_t layer = 0; layer < 18; layer++) {
179 for (std::size_t channel = 0; channel < constants::PADLAYER_MODULE_NCHANNELS; channel++) {
180 std::unique_ptr<TH1> channelADC(mADCDistLayer[layer]->ProjectionY("channelADC", channel + 1, channel + 1));
181 try {
182 mPedestalContainer->setPedestal(layer, channel, evaluatePedestal(channelADC.get()));
183 nPedestals++;
185 LOG(error) << "Failure accessing setting pedestal: " << e.what();
186 }
187 }
188 }
189 LOG(info) << "Found pedestals for " << nPedestals << " channels";
190}
191
192double PadPedestalCalibDevice::evaluatePedestal(TH1* channel)
193{
194 double pedestal = 0;
195 switch (mExtractionMethod) {
196 case Method_t::MAX: {
197 // Max model - get center of the maximum bin
198 int maxbin = channel->GetMaximumBin();
199 pedestal = channel->GetBinCenter(maxbin);
200 break;
201 }
202 case Method_t::MEAN: {
203 // Mean model - get the mean of the distribution
204 pedestal = channel->GetMean();
205 break;
206 }
207 case Method_t::FIT: {
208 // Fit model - fit full distribution with Gauss and take mean
209 TF1 pedmodal("pedmodel", "gaus", 0, 2000);
210 channel->Fit(&pedmodal, "Q");
211 pedestal = pedmodal.GetParameter(1);
212 break;
213 }
214 }
215 return pedestal;
216}
217
219{
220 std::vector<o2::framework::OutputSpec> outputs;
221 outputs.emplace_back(framework::ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBPayload, "FOC_PADPEDESTALS"}, o2::framework::Lifetime::Sporadic);
222 outputs.emplace_back(framework::ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBWrapper, "FOC_PADPEDESTALS"}, o2::framework::Lifetime::Sporadic);
223
224 return o2::framework::DataProcessorSpec{"FOCALPadPedestalCalibDevice",
225 o2::framework::select("A:FOC/RAWDATA"),
226 outputs,
227 o2::framework::adaptFromTask<o2::focal::PadPedestalCalibDevice>(updateCCDB, path, debug),
229 {"calibmethod", o2::framework::VariantType::String, "max", {"Method used for pedestal evaluation"}}}};
230}
Definition of the 32 Central Trigger System (CTS) Trigger Types defined in https://twiki....
Utils and constants for calibration and related workflows.
A helper class to iteratate over all parts of all input routes.
void output(const std::map< std::string, ChannelStat > &channels)
Definition rawdump.cxx:197
std::ostringstream debug
static std::string generateFileName(const std::string &inp)
Definition CcdbApi.cxx:798
static std::unique_ptr< std::vector< char > > createObjectImage(const T *obj, CcdbObjectInfo *info=nullptr)
Definition CcdbApi.h:103
void setStartValidityTimestamp(long start)
void setFileName(const std::string &nm)
void setPath(const std::string &path)
void setEndValidityTimestamp(long end)
void setObjectType(const std::string &tp)
void setMetaData(const std::map< std::string, std::string > &md)
static constexpr long INFINITE_TIMESTAMP
const ASICData & getASIC() const
Definition PadData.h:111
const ASICContainer & getDataForASIC(int index) const
Definition PadData.cxx:171
const PadData & getData() const
Definition PadDecoder.h:37
void decodeEvent(gsl::span< const PadGBTWord > padpayload)
void init(framework::InitContext &ctx) final
void endOfStream(o2::framework::EndOfStreamContext &ec) final
This is invoked whenever we have an EndOfStream event.
PadPedestalCalibDevice(bool updateCCDB, const std::string &path, bool debugMode)
void run(framework::ProcessingContext &ctx) final
const char * what() const noexcept final
Definition PadPedestal.h:63
ConfigParamRegistry const & options()
Definition InitContext.h:33
A helper class to iteratate over all parts of all input routes.
InputRecord & inputs()
The inputs associated with this processing context.
GLeglImageOES image
Definition glcorearb.h:4021
GLsizei const GLchar *const * path
Definition glcorearb.h:3591
GLenum GLuint GLint GLint layer
Definition glcorearb.h:1310
constexpr int PADLAYER_MODULE_NCHANNELS
Definition Constants.h:16
o2::framework::DataProcessorSpec getPadPedestalCalibDevice(bool updateCCDB, const std::string &path, bool debug)
std::vector< ConfigParamSpec > Options
std::vector< InputSpec > select(char const *matcher="")
constexpr uint32_t HB
Definition Triggers.h:27
std::string to_string(gsl::span< T, Size > span)
Definition common.h:52
static constexpr o2::header::DataOrigin gDataOriginCDBWrapper
Definition Utils.h:44
static constexpr o2::header::DataOrigin gDataOriginCDBPayload
Definition Utils.h:43
static o2::header::DataHeader::PayloadSizeType getPayloadSize(const DataRef &ref)
uint32_t SubSpecificationType
Definition DataHeader.h:620
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"