Project
Loading...
Searching...
No Matches
PedestalsCalculationSpec.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
18
19#include <random>
20#include <iostream>
21#include <fstream>
22#include <stdexcept>
23#include <array>
24#include <functional>
25#include <vector>
26
27#include "TTree.h"
28#include "TString.h"
29#include "TFile.h"
30#include "TMath.h"
31#include "TMatrixF.h"
32
33#include <gsl/span>
34
39#include "Framework/Lifetime.h"
40#include "Framework/Output.h"
41#include "Framework/Task.h"
43#include "Framework/Logger.h"
45#include <fairmq/Device.h>
46
47#include "CCDB/CcdbApi.h"
49
54
57#include "HMPIDBase/Geo.h"
60
62namespace o2
63{
64namespace hmpid
65{
66
67using namespace o2;
68using namespace o2::framework;
70
71//=======================
72// Init
74{
75
76 LOG(info) << "[HMPID Pedestal Calculation - v.1 - Init] ( create Decoder for " << Geo::MAXEQUIPMENTS << " equipments !";
77
79 mDeco->init();
80 mTotalDigits = 0;
81 mTotalFrames = 0;
82
83 mSigmaCut = ic.options().get<float>("sigmacut");
84 mWriteToFiles = ic.options().get<bool>("use-files");
85 mPedestalsBasePath = ic.options().get<std::string>("files-basepath");
86 mPedestalsCCDBBasePath = mPedestalsBasePath;
87
88 mWriteToDB = ic.options().get<bool>("use-ccdb");
89 if (mWriteToDB) {
90 mDBapi.init(ic.options().get<std::string>("ccdb-uri")); // or http://localhost:8080 for a local installation
91 mWriteToDB = mDBapi.isHostReachable() ? true : false;
92 }
93
94 mPedestalTag = ic.options().get<std::string>("pedestals-tag");
95 mFastAlgorithm = ic.options().get<bool>("fast-decode");
96
97 mWriteToDCSDB = ic.options().get<bool>("use-dcsccdb");
98 if (mWriteToDCSDB) {
99 mDCSDBapi.init(ic.options().get<std::string>("dcsccdb-uri")); // or http://localhost:8080 for a local installation
100 mWriteToDCSDB = mDCSDBapi.isHostReachable() ? true : false;
101 }
102 mDcsCcdbAliveHours = ic.options().get<int>("dcsccdb-alivehours");
103
104 mExTimer.start();
105 LOG(info) << "Calculate Ped/Thresh." + (mWriteToDB ? " Store in DCSCCDB at " + mPedestalsBasePath + " with Tag:" + mPedestalTag : " CCDB not used !");
106 return;
107}
108
110{
111 if (mPedestalTag == "run_number") { // if the Tag is run_number, then substitute the Tag with RN
112 const std::string NAStr = "NA";
113 mPedestalTag = pc.services().get<RawDeviceService>().device()->fConfig->GetProperty<std::string>("runNumber", NAStr);
114 }
115 decodeTF(pc);
116 mExTimer.elapseMes("Decoding... Digits decoded = " + std::to_string(mTotalDigits) + " Frames received = " + std::to_string(mTotalFrames));
117 return;
118}
119
121{
122 if (mWriteToDB) {
123 recordPedInCcdb();
124 }
125 if (mWriteToDCSDB) {
126 recordPedInDcsCcdb();
127 }
128 if (mWriteToFiles) {
129 recordPedInFiles();
130 }
131 mExTimer.stop();
132 return;
133}
134
135void PedestalsCalculationTask::recordPedInFiles()
136{
137 double Average;
138 double Variance;
139 double Samples;
140 double SumOfCharge;
141 double SumOfSquares;
142
143 uint32_t Buffer;
144 uint32_t Pedestal;
145 uint32_t Threshold;
146
147 for (int e = 0; e < Geo::MAXEQUIPMENTS; e++) {
148 if (mDeco->getAverageEventSize(e) == 0) {
149 continue;
150 }
151 auto padsFileName = fmt::format("{}_{}.dat", mPedestalsBasePath, std::to_string(e));
152 FILE* fpads = fopen(padsFileName.c_str(), "w");
153 if (fpads == nullptr) {
154 mExTimer.logMes("error creating the file = " + std::string(padsFileName));
155 LOG(error) << "error creating the file = " << padsFileName;
156 return;
157 }
158 for (int c = 0; c < Geo::N_COLUMNS; c++) {
159 for (int d = 0; d < Geo::N_DILOGICS; d++) {
160 for (int h = 0; h < Geo::N_CHANNELS; h++) {
161 Samples = (double)mDeco->getChannelSamples(e, c, d, h);
162 SumOfCharge = mDeco->getChannelSum(e, c, d, h);
163 SumOfSquares = mDeco->getChannelSquare(e, c, d, h);
164
165 if (Samples > 0) {
166 Average = SumOfCharge / Samples;
167 Variance = sqrt(abs((Samples * SumOfSquares) - (SumOfCharge * SumOfCharge))) / Samples;
168 } else {
169 Average = 0;
170 Variance = 0;
171 }
172 Pedestal = (uint32_t)Average;
173 Threshold = (uint32_t)(Variance * mSigmaCut + Average);
174 Buffer = ((Threshold & 0x001FF) << 9) | (Pedestal & 0x001FF);
175 fprintf(fpads, "%05X\n", Buffer);
176 }
177 for (int h = 48; h < 64; h++) {
178 fprintf(fpads, "%05X\n", 0);
179 }
180 }
181 }
182 mExTimer.logMes("End write the equipment = " + std::to_string(e));
183 fprintf(fpads, "%05X\n", 0xA0A0A);
184 fclose(fpads);
185 }
186 mExTimer.logMes("End Writing the pedestals ! Digits decoded = " + std::to_string(mTotalDigits) + " Frames received = " + std::to_string(mTotalFrames));
187 return;
188}
189
190void PedestalsCalculationTask::recordPedInDcsCcdb()
191{
192 // create the root structure
193 LOG(info) << "Store Pedestals in DCS CCDB ";
194
195 float xb, yb, ch, Samples;
196 double SumOfCharge, SumOfSquares, Average, Variance;
197 uint32_t Pedestal, Threshold, PedThr;
198 std::string PedestalFixedTag = "Latest";
199
200 o2::dcs::DCSconfigObject_t pedestalsConfig;
201
202// Setup dimensions for Equipment granularity with 48 channels/dilogic
203#define PEDTHFORMAT "%05X,"
204#define COLUMNTAIL false
205#define PEDTHBYTES 6
206 int bufferDim = PEDTHBYTES * Geo::N_CHANNELS * Geo::N_DILOGICS * Geo::N_COLUMNS + 10;
207 char* outBuffer = new char[bufferDim];
208 char* inserPtr;
209 char* endPtr = outBuffer + bufferDim;
210
211 for (int e = 0; e < Geo::MAXEQUIPMENTS; e++) {
212 if (mDeco->getAverageEventSize(e) == 0) { // skip the empty equipment
213 continue;
214 }
215 inserPtr = outBuffer;
216 // algoritm based on equipment granularity
217 for (int c = 0; c < Geo::N_COLUMNS; c++) {
218 for (int d = 0; d < Geo::N_DILOGICS; d++) {
219 for (int h = 0; h < Geo::N_CHANNELS; h++) {
220 Samples = (double)mDeco->getChannelSamples(e, c, d, h);
221 SumOfCharge = mDeco->getChannelSum(e, c, d, h);
222 SumOfSquares = mDeco->getChannelSquare(e, c, d, h);
223 if (Samples > 0) {
224 Average = SumOfCharge / Samples;
225 Variance = sqrt(abs((Samples * SumOfSquares) - (SumOfCharge * SumOfCharge))) / Samples;
226 } else {
227 Average = 0;
228 Variance = 0;
229 }
230 Pedestal = (uint32_t)Average;
231 Threshold = (uint32_t)(Variance * mSigmaCut + Average);
232 PedThr = ((Threshold & 0x001FF) << 9) | (Pedestal & 0x001FF);
233 assert(inserPtr < endPtr);
234 snprintf(inserPtr, endPtr - inserPtr, PEDTHFORMAT, PedThr);
235 inserPtr += PEDTHBYTES;
236 }
237 if (COLUMNTAIL) {
238 for (int h = 48; h < 64; h++) {
239 assert(inserPtr < endPtr);
240 snprintf(inserPtr, endPtr - inserPtr, PEDTHFORMAT, 0);
241 inserPtr += PEDTHBYTES;
242 }
243 }
244 }
245 }
246 mExTimer.logMes("End write the equipment = " + std::to_string(e));
247 assert(inserPtr < endPtr);
248 snprintf(inserPtr, endPtr - inserPtr, "%05X\n", 0xA0A0A); // The closure value
249 inserPtr += 6;
250 *inserPtr = '\0'; // close the string rap.
251 o2::dcs::addConfigItem(pedestalsConfig, "Equipment" + std::to_string(e), (const char*)outBuffer);
252 }
253
254 long minTimeStamp = o2::ccdb::getCurrentTimestamp();
255 long maxTimeStamp = minTimeStamp + (3600L * mDcsCcdbAliveHours * 1000);
256
257 auto filename = fmt::format("{}_{}.dat", mPedestalsBasePath, PedestalFixedTag);
258 mExTimer.logMes("File name = >" + filename + "< (" + mPedestalsCCDBBasePath + "," + PedestalFixedTag);
259
260 mDbMetadata.emplace("Tag", PedestalFixedTag.c_str());
261 mDCSDBapi.storeAsTFileAny(&pedestalsConfig, filename.c_str(), mDbMetadata, minTimeStamp, maxTimeStamp);
262
263 mExTimer.logMes("End Writing the pedestals ! Digits decoded = " + std::to_string(mTotalDigits) + " Frames received = " + std::to_string(mTotalFrames));
264
265 return;
266}
267
268void PedestalsCalculationTask::recordPedInCcdb()
269{
270 // create the root structure
271 LOG(info) << "Store Pedestals in ccdb ";
272
273 float xb, yb, ch;
274 double Samples, SumOfCharge, SumOfSquares, Average, Variance;
275
276 TObjArray aSigmas(Geo::N_MODULES);
277 TObjArray aPedestals(Geo::N_MODULES);
278
279 for (int i = 0; i < Geo::N_MODULES; i++) {
280 aSigmas.AddAt(new TMatrixF(Geo::N_XROWS, Geo::N_YCOLS), i);
281 aPedestals.AddAt(new TMatrixF(Geo::N_XROWS, Geo::N_YCOLS), i);
282 }
283
284 for (int m = 0; m < o2::hmpid::Geo::N_MODULES; m++) {
285 if (mDeco->getAverageEventSize(m * 2) == 0 && mDeco->getAverageEventSize(m * 2 + 1) == 0) {
286 continue; // If no events skip the chamber
287 }
288 TMatrixF* pS = (TMatrixF*)aSigmas.At(m);
289 TMatrixF* pP = (TMatrixF*)aPedestals.At(m);
290
291 for (int x = 0; x < o2::hmpid::Geo::N_XROWS; x++) {
292 for (int y = 0; y < o2::hmpid::Geo::N_YCOLS; y++) {
293
294 Samples = (double)mDeco->getPadSamples(m, x, y);
295 SumOfCharge = mDeco->getPadSum(m, x, y);
296 SumOfSquares = mDeco->getPadSquares(m, x, y);
297 if (Samples > 0) {
298 (*pP)(x, y) = SumOfCharge / Samples;
299 (*pS)(x, y) = sqrt(abs((Samples * SumOfSquares) - (SumOfCharge * SumOfCharge))) / Samples;
300 } else {
301 (*pP)(x, y) = 0;
302 (*pS)(x, y) = 0;
303 }
304 }
305 }
306 }
307
308 long minTimeStamp = o2::ccdb::getCurrentTimestamp();
309 long maxTimeStamp = minTimeStamp + (3600L * 24 * (5 * 365) * 1000); // 5 years
310
311 for (int i = 0; i < Geo::N_MODULES; i++) {
312 if (mDeco->getAverageEventSize(i * 2) == 0 && mDeco->getAverageEventSize(i * 2 + 1) == 0) {
313 continue; // If no events skip the chamber
314 }
315 TString filename = TString::Format("%s/%s/Mean_%d", mPedestalsCCDBBasePath.c_str(), mPedestalTag.c_str(), i);
316 mDbMetadata.emplace("Tag", mPedestalTag.c_str());
317 mDBapi.storeAsTFileAny(aPedestals.At(i), filename.Data(), mDbMetadata, minTimeStamp, maxTimeStamp);
318 }
319 for (int i = 0; i < Geo::N_MODULES; i++) {
320 if (mDeco->getAverageEventSize(i * 2) == 0 && mDeco->getAverageEventSize(i * 2 + 1) == 0) {
321 continue; // If no events skip the chamber
322 }
323 TString filename = TString::Format("%s/%s/Sigma_%d", mPedestalsCCDBBasePath.c_str(), mPedestalTag.c_str(), i);
324 mDbMetadata.emplace("Tag", mPedestalTag.c_str());
325 mDBapi.storeAsTFileAny(aSigmas.At(i), filename.Data(), mDbMetadata, minTimeStamp, maxTimeStamp);
326 }
327 return;
328}
329
330//_________________________________________________________________________________________________
331// the decodeTF() function processes the the messages generated by the (sub)TimeFrame builder
333{
334 LOG(debug) << "*********** In decodeTF **************";
335 // get the input buffer
336 auto& inputs = pc.inputs();
337 DPLRawParser parser(inputs, o2::framework::select("TF:HMP/RAWDATA"));
338 for (auto it = parser.begin(), end = parser.end(); it != end; ++it) {
339 uint32_t* theBuffer = (uint32_t*)it.raw();
340 mDeco->setUpStream(theBuffer, it.size() + it.offset());
341 try {
342 if (mFastAlgorithm) {
343 mDeco->decodePageFast(&theBuffer);
344 } else {
345 mDeco->decodePage(&theBuffer);
346 }
347 } catch (int e) {
348 // The stream end !
349 LOG(debug) << "End Page decoding !";
350 }
351 mTotalFrames++;
352 mTotalDigits += mDeco->mDigits.size();
353 }
354 return;
355}
356
357//_________________________________________________________________________________________________
359{
360
361 std::vector<o2::framework::InputSpec> inputs;
362 inputs.emplace_back("TF", o2::framework::ConcreteDataTypeMatcher{"HMP", "RAWDATA"}, o2::framework::Lifetime::Timeframe);
363
364 std::vector<o2::framework::OutputSpec> outputs;
365
366 return DataProcessorSpec{
367 "HMP-PestalsCalculation",
368 o2::framework::select(inputSpec.c_str()),
369 outputs,
370 AlgorithmSpec{adaptFromTask<PedestalsCalculationTask>()},
371 Options{{"files-basepath", VariantType::String, "HMP/Config", {"Name of the Base Path of Pedestals/Thresholds files."}},
372 {"use-files", VariantType::Bool, false, {"Register the Pedestals/Threshold values into ASCII files"}},
373 {"use-ccdb", VariantType::Bool, false, {"Register the Pedestals/Threshold values into the CCDB"}},
374 {"ccdb-uri", VariantType::String, "http://ccdb-test.cern.ch:8080", {"URI for the CCDB access."}},
375 {"use-dcsccdb", VariantType::Bool, false, {"Register the Pedestals/Threshold values into the DCS-CCDB"}},
376 {"dcsccdb-uri", VariantType::String, "http://ccdb-test.cern.ch:8080", {"URI for the DCS-CCDB access."}},
377 {"dcsccdb-alivehours", VariantType::Int, 3, {"Alive hours in DCS-CCDB."}},
378 {"fast-decode", VariantType::Bool, true, {"Use the fast algorithm. (error 0.8%)"}},
379 {"pedestals-tag", VariantType::String, "Latest", {"The tag applied to this set of pedestals/threshold values"}},
380 {"sigmacut", VariantType::Float, 4.0f, {"Sigma values for the Thresholds calculation."}}}};
381}
382
383} // namespace hmpid
384} // end namespace o2
A raw page parser for DPL input.
int32_t i
Definition of the Names Generator class.
#define COLUMNTAIL
#define PEDTHBYTES
#define PEDTHFORMAT
Definition of the RAW Data Header.
uint32_t c
Definition RawData.h:2
std::ostringstream debug
Class for time synchronization of RawReader instances.
int storeAsTFileAny(const T *obj, std::string const &path, std::map< std::string, std::string > const &metadata, long startValidityTimestamp=-1, long endValidityTimestamp=-1, std::vector< char >::size_type maxSize=0) const
Definition CcdbApi.h:157
void init(std::string const &hosts)
Definition CcdbApi.cxx:165
bool isHostReachable() const
Definition CcdbApi.cxx:1301
The parser handles transparently input in the format of raw pages.
const_iterator end() const
const_iterator begin() const
ConfigParamRegistry const & options()
Definition InitContext.h:33
InputRecord & inputs()
The inputs associated with this processing context.
ServiceRegistryRef services()
The services registry associated with this processing context.
void stop()
stop : stops the timer
Definition Common.h:73
void elapseMes(std::string const message)
Definition Common.h:91
void start()
start : starts the timer
Definition Common.h:64
void logMes(std::string const message)
Definition Common.h:81
static constexpr int N_COLUMNS
Definition Geo.h:82
static constexpr int N_XROWS
Definition Geo.h:88
static constexpr int N_MODULES
Definition Geo.h:87
static constexpr int N_DILOGICS
Definition Geo.h:83
static constexpr int N_CHANNELS
Definition Geo.h:84
static constexpr int N_YCOLS
Definition Geo.h:89
static constexpr int MAXEQUIPMENTS
Definition Geo.h:79
float getAverageEventSize(int Equipment)
void decodePageFast(uint32_t **streamBuf)
void init()
Init all the members variables.
std::vector< o2::hmpid::Digit > mDigits
double getChannelSquare(int Equipment, int Column, int Dilogic, int Channel)
void decodePage(uint32_t **streamBuffer)
uint16_t getChannelSamples(int Equipment, int Column, int Dilogic, int Channel)
bool setUpStream(void *Buffer, long BufferLen)
double getPadSum(int Module, int Row, int Column)
uint16_t getPadSamples(int Module, int Row, int Column)
double getPadSquares(int Module, int Row, int Column)
double getChannelSum(int Equipment, int Column, int Dilogic, int Channel)
void decodeTF(framework::ProcessingContext &pc)
void init(framework::InitContext &ic) final
void run(framework::ProcessingContext &pc) final
void endOfStream(framework::EndOfStreamContext &ec) override
This is invoked whenever we have an EndOfStream event.
GLint GLenum GLint x
Definition glcorearb.h:403
const GLfloat * m
Definition glcorearb.h:4066
GLuint GLuint end
Definition glcorearb.h:469
GLint y
Definition glcorearb.h:270
long getCurrentTimestamp()
returns the timestamp in long corresponding to "now"
std::vector< char > DCSconfigObject_t
void addConfigItem(DCSconfigObject_t &configVector, std::string key, const T value)
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
std::vector< ConfigParamSpec > Options
std::vector< InputSpec > select(char const *matcher="")
o2::framework::DataProcessorSpec getPedestalsCalculationSpec(std::string inputSpec="TF:HMP/RAWDATA")
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
std::string to_string(gsl::span< T, Size > span)
Definition common.h:52
std::string filename()
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"