Project
Loading...
Searching...
No Matches
DCS.h
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
15
16#ifndef TPC_DCSCalibData_H_
17#define TPC_DCSCalibData_H_
18
19#include <algorithm>
20#include <iterator>
21#include <string>
22#include <string_view>
23#include <vector>
24#include <numeric>
25#include <array>
26#include <unordered_map>
27#include <cstdlib>
28
29#include "Rtypes.h"
30
31#include "Framework/Logger.h"
32#include "DataFormatsTPC/Defs.h"
33#include "MathUtils/fit.h"
34
35using namespace o2::tpc;
36
37class TLinearFitter;
38class TTree;
39
40namespace o2::tpc::dcs
41{
42
43using DataType = float;
44
45using TimeStampType = uint64_t;
46
50template <typename T>
51struct DataPoint {
54
55 bool equalTime(const DataPoint& other) const { return time == other.time; }
56 bool operator<(const DataPoint& other) const { return time < other.time; }
57 bool operator<(const TimeStampType timeStamp) const { return time < timeStamp; }
58 DataPoint operator+(const DataPoint& other) const { return DataPoint{(time + other.time) / TimeStampType{2}, value + other.value}; }
59 DataPoint operator/(const DataType denom) const { return DataPoint{time, value / denom}; }
60
62};
63
67template <typename T>
70 uint32_t sensorNumber{};
71 std::vector<DPType> data;
72
74 auto getPairOfVector() const
75 {
76 std::pair<std::vector<T>, std::vector<TimeStampType>> pairs;
77 pairs.first.reserve(data.size());
78 pairs.second.reserve(data.size());
79 for (const auto& dp : data) {
80 pairs.first.emplace_back(dp.value);
81 pairs.second.emplace_back(dp.time);
82 }
83 return pairs;
84 }
85
86 void fill(const TimeStampType time, const T& value) { data.emplace_back(DPType{time, value}); }
87
88 void fill(const DPType& dataPoint) { data.emplace_back(dataPoint); }
89
90 void sort() { std::sort(data.begin(), data.end()); }
91
93 {
94 sort();
95 data.erase(
96 std::unique(data.begin(), data.end(),
97 [](const auto& dp1, const auto& dp2) {
98 return dp1.time == dp2.time;
99 }),
100 data.end());
101 data.shrink_to_fit();
102 }
103
104 void clear() { data.clear(); }
105
107 {
108 data.insert(data.end(), other.data.begin(), other.data.end());
109 }
110
114 const T& getValueForTime(const TimeStampType timeStamp) const
115 {
116 const auto i = std::upper_bound(data.begin(), data.end(), DPType{timeStamp, {}});
117 return (i == data.begin()) ? (*i).value : (*(i - 1)).value;
118 }
119
121 const T getAverageValueForTime(const TimeStampType timeStamp, const long range) const
122 {
123 return getAverageValueForTime(timeStamp, timeStamp, range);
124 }
125
127 const std::pair<T, long> getSumAndPoints(const TimeStampType from, const TimeStampType until, const long range) const
128 {
129 const auto iFrom = std::upper_bound(data.begin(), data.end(), DPType{from, {}});
130 const auto iUntil = (from == until) ? iFrom : std::upper_bound(data.begin(), data.end(), DPType{until, {}});
131 const auto distFrom = std::distance(data.begin(), iFrom);
132 const auto distUntil = std::distance(iUntil, data.end());
133 const auto nFrom = std::min(distFrom, range + 1);
134 const auto nUntil = std::min(distUntil, range);
135 const auto nPoints = std::distance(iFrom - nFrom, iUntil + nUntil);
136 return {std::accumulate(iFrom - nFrom, iUntil + nUntil, DPType{(*(iFrom - nFrom)).time, T{}}).value, nPoints};
137 }
138
139 const T getAverageValueForTime(const TimeStampType from, const TimeStampType until, const long range) const
140 {
141 const auto sumAndPoints = getSumAndPoints(from, until, range);
142 return sumAndPoints.first / static_cast<float>(sumAndPoints.second);
143 }
144
146};
147
148template <typename T>
149void doSortAndClean(std::vector<dcs::DataPointVector<T>>& dataVector)
150{
151 for (auto& data : dataVector) {
152 data.sortAndClean();
153 }
154}
155
156template <typename T>
157void doClear(std::vector<dcs::DataPointVector<T>>& dataVector)
158{
159 for (auto& data : dataVector) {
160 data.clear();
161 }
162}
163
164template <typename T>
165void doAppend(std::vector<dcs::DataPointVector<T>>& a, const std::vector<dcs::DataPointVector<T>>& b)
166{
167 if (a.size() != b.size()) {
168 LOGP(warning, "Trying to append std::vector<dcs::DataPointVector<T>>s of different size: {} != {}", a.size(), b.size());
169 }
170 for (size_t i = 0; i < a.size(); ++i) {
171 a[i].append(b[i]);
172 }
173}
174
175template <typename T>
176const T getAverageValueForTime(const std::vector<dcs::DataPointVector<T>>& dpVec, const TimeStampType from, const TimeStampType until, const long range)
177{
178 T ret{};
179 long nPoints{};
180
181 for (const auto& dps : dpVec) {
182 const auto sumAndPoints = dps.getSumAndPoints(from, until, range);
183 ret += sumAndPoints.first;
184 nPoints += sumAndPoints.second;
185 }
186 return (nPoints > 0) ? ret / static_cast<float>(nPoints) : T{};
187}
188
189template <typename T>
190dcs::TimeStampType getMinTime(const std::vector<dcs::DataPointVector<T>>& data, const bool roundToInterval, dcs::TimeStampType fitInterval)
191{
192 constexpr auto max = std::numeric_limits<dcs::TimeStampType>::max();
193 dcs::TimeStampType firstTime = std::numeric_limits<dcs::TimeStampType>::max();
194 for (const auto& sensor : data) {
195 const auto time = sensor.data.size() ? sensor.data.front().time : max;
196 firstTime = std::min(firstTime, time);
197 }
198
199 // mFitInterval is is seconds. Round to full amount.
200 // if e.g. mFitInterval = 5min, then round 10:07:20.510 to 10:05:00.000
201 if (roundToInterval) {
202 firstTime -= (firstTime % fitInterval);
203 }
204
205 return firstTime;
206}
207
208template <typename T>
210{
211 constexpr auto min = 0;
212 dcs::TimeStampType lastTime = 0;
213 for (const auto& sensor : data) {
214 const auto time = sensor.data.size() ? sensor.data.back().time : 0;
215 lastTime = std::max(lastTime, time);
216 }
217
218 // mFitInterval is is seconds. Round to full amount.
219 // if e.g. mFitInterval = 5min, then round 10:07:20.510 to 10:05:00.000
220 // TODO: fix this
221 // if (mRoundToInterval) {
222 // lastTime -= (lastTime % mFitInterval);
223 //}
224
225 return lastTime;
226}
227
229// using RawDPsI = DataPointVector<int>;
230
235 struct Position {
236 float x;
237 float y;
238 };
239
240 Temperature() noexcept;
241
242 static constexpr int SensorsPerSide = 9;
243
244 static const std::unordered_map<std::string, int> SensorNameMap;
245
246 static constexpr std::array<Position, SensorsPerSide * SIDES> SensorPosition{{
247 {211.40f, 141.25f},
248 {82.70f, 227.22f},
249 {-102.40f, 232.72f},
250 {-228.03f, 112.45f},
251 {-246.96f, -60.43f},
252 {-150.34f, -205.04f},
253 {-16.63f, -253.71f},
254 {175.82f, -183.66f},
255 {252.74f, -27.68f},
256 {228.03f, 112.45f},
257 {102.40f, 232.72f},
258 {-71.15f, 244.09f},
259 {-211.40f, 141.25f},
260 {-252.74f, -27.68f},
261 {-175.82f, -183.66f},
262 {-16.63f, -253.71f},
263 {150.34f, -205.04f},
264 {252.74f, -27.68f},
265 }};
266
267 static constexpr auto& getSensorPosition(const size_t sensor) { return SensorPosition[sensor]; }
268
273 void fitTemperature(Side side, dcs::TimeStampType fitInterval = 5 * 60 * 1000, const bool roundToInterval = false);
274
275 struct Stats {
276 DataType mean{};
277 DataType gradX{};
278 DataType gradY{};
279
280 Stats operator+(const Stats& other) const { return Stats{mean + other.mean, gradX + other.gradX, gradY + other.gradY}; }
281 Stats operator/(const DataType val) const { return Stats{mean / val, gradX / val, gradY / val}; }
282
284 };
286
289 std::vector<RawDPsF> raw;
290
291 const Stats& getStats(const Side s, const TimeStampType timeStamp) const
292 {
293 return (s == Side::A) ? statsA.getValueForTime(timeStamp) : statsC.getValueForTime(timeStamp);
294 }
295
297 {
298 return getAverageValueForTime(raw, 0, 9999999999999, 0);
299 }
300
301 void fill(std::string_view sensor, const TimeStampType time, const DataType temperature)
302 {
303 raw[SensorNameMap.at(sensor.data())].fill(time, temperature);
304 };
305
307 {
308 statsA.sortAndClean();
309 statsC.sortAndClean();
310 doSortAndClean(raw);
311 }
312
313 void clear()
314 {
315 doClear(raw);
316 statsA.clear();
317 statsC.clear();
318 }
319
321 {
322 statsA.append(other.statsA);
323 statsC.append(other.statsC);
324 doAppend(raw, other.raw);
325 }
326
327 private:
328 bool makeFit(TLinearFitter& fitter, const int nDim, std::vector<double>& xVals, std::vector<double>& temperatures);
329
330 ClassDefNV(Temperature, 1);
331};
332
336struct HV {
337
338 HV() noexcept;
339
340 // Exmple strings
341 // TPC_HV_A03_I_G1B_I
342 // TPC_HV_A03_O1_G1B_I
343 static constexpr size_t SidePos = 7;
344 static constexpr size_t SectorPos = 8;
345 static constexpr size_t ROCPos = 11;
346 static constexpr size_t GEMPos = 14;
347 static constexpr size_t ElectrodePos = 15;
348
349 enum class StackState : char {
350 NO_CONTROL = 2,
351 STBY_CONFIGURED = 3,
352 OFF = 4,
353 RAMPIG_DOWN = 7,
354 RAMPIG_UP = 8,
355 RAMPIG_DOWN_LOW = 9,
356 RAMPIG_UP_LOW = 10,
357 ON = 11,
358 ERROR = 13,
359 INTERMEDIATE = 14,
360 MIXED = 19,
361 INTERLOCK = 24,
362 ERROR_LOCAL = 25,
363 SOFT_INTERLOCK = 29,
364 };
365
366 static const std::unordered_map<StackState, std::string> StackStateNameMap;
367
369
370 std::vector<RawDPsF> voltages;
371 std::vector<RawDPsF> currents;
372 std::vector<RawDPsState> states;
373
374 static int getSector(std::string_view sensor)
375 {
376 const auto sideOffset = (sensor[SidePos] == 'A') ? 0 : SECTORSPERSIDE;
377 const auto sector = std::atoi(sensor.substr(SectorPos, 2).data());
378 return sector + sideOffset;
379 }
380
381 static GEMstack getStack(std::string_view sensor)
382 {
383 if (sensor[ROCPos] == 'I') {
384 return GEMstack::IROCgem;
385 }
386 const auto orocType = int(sensor[ROCPos + 1] - '0');
387 return static_cast<GEMstack>(orocType);
388 }
389
391 void fillUI(std::string_view sensor, const TimeStampType time, const DataType value)
392 {
393 const int sector = getSector(sensor);
394 const auto stack = getStack(sensor);
395 const auto rocOffset = int(stack != GEMstack::IROCgem);
396 const auto gem = int(sensor[GEMPos + rocOffset] - '0');
397 const bool isTop = sensor[ElectrodePos + rocOffset] == 'T';
398 // the counting is GEM1 top, bottom, GEM2 top, bottom, ...
399 const int electrode = 2 * (gem - 1) + !isTop;
400 const StackID stackID{sector, stack};
401 const int index = stackID.getIndex() * 2 * GEMSPERSTACK + electrode;
402
403 const auto type = sensor.back();
404 // LOGP(info, "Fill type: {}, index: {} (sec: {}, stack: {}, gem: {}, elec: {}), time: {}, value: {}", type, index, sector, stack, gem, electrode, time, value);
405 if (type == 'I') {
406 currents[index].fill(time, value);
407 } else if (type == 'U') {
408 voltages[index].fill(time, value);
409 }
410 }
411
413 void fillStatus(std::string_view sensor, const TimeStampType time, const uint32_t value)
414 {
415 const int sector = getSector(sensor);
416 const auto stack = getStack(sensor);
417 const StackID stackID{sector, stack};
418
419 // TODO: check value for validity
420 states[stackID.getIndex()].fill(time, static_cast<StackState>(value));
421 }
422
424 {
425 doSortAndClean(voltages);
426 doSortAndClean(currents);
428 }
429
430 void clear()
431 {
432 doClear(voltages);
433 doClear(currents);
435 }
436
437 void append(const HV& other)
438 {
439 doAppend(voltages, other.voltages);
440 doAppend(currents, other.currents);
441 doAppend(states, other.states);
442 }
443
445};
446
450struct Gas {
451 static constexpr size_t SensorPos = 4;
452 static constexpr size_t TypePosGC = 7;
453 static constexpr size_t TypePosAn = 15;
454
455 RawDPsF neon{};
456 RawDPsF co2{};
457 RawDPsF n2{};
458 RawDPsF argon{};
459 RawDPsF h2o{};
461 RawDPsF h2oSensor{};
462 RawDPsF o2Sensor{};
463
464 void fill(std::string_view sensor, const TimeStampType time, const DataType value)
465 {
466 if (sensor[SensorPos] == 'G') { // check if from GC
467 switch (sensor[TypePosGC]) {
468 case 'N': {
469 if (sensor[TypePosGC + 1] == 'E') {
470 neon.fill(time, value);
471 } else {
472 n2.fill(time, value);
473 }
474 break;
475 }
476 case 'A':
477 argon.fill(time, value);
478 break;
479 case 'C':
480 co2.fill(time, value);
481 break;
482 case 'O':
483 o2.fill(time, value);
484 break;
485 case 'W':
486 h2o.fill(time, value);
487 break;
488 default:
489 LOGP(warning, "Unknown gas sensor {}", sensor);
490 break;
491 }
492 } else { // otherwise dedicated sensor
493 switch (sensor[TypePosAn]) {
494 case 'H':
495 h2oSensor.fill(time, value);
496 break;
497 case 'O':
498 o2Sensor.fill(time, value);
499 break;
500 default:
501 LOGP(warning, "Unknown gas sensor {}", sensor);
502 break;
503 }
504 }
505 };
506
508 {
509 neon.sortAndClean();
510 co2.sortAndClean();
511 n2.sortAndClean();
512 argon.sortAndClean();
513 h2o.sortAndClean();
514 o2.sortAndClean();
515 h2oSensor.sortAndClean();
516 o2Sensor.sortAndClean();
517 }
518
519 void clear()
520 {
521 neon.clear();
522 co2.clear();
523 n2.clear();
524 argon.clear();
525 h2o.clear();
526 o2.clear();
527 h2oSensor.clear();
528 o2Sensor.clear();
529 }
530
531 void append(const Gas& other)
532 {
533 neon.append(other.neon);
534 co2.append(other.co2);
535 n2.append(other.n2);
536 argon.append(other.argon);
537 h2o.append(other.h2o);
538 o2.append(other.o2);
539 h2oSensor.append(other.h2oSensor);
540 o2Sensor.append(other.o2Sensor);
541 }
542
544
546
548};
549
568
569struct Pressure {
570
575 void fill(std::string_view sensor, const TimeStampType time, const DataType value);
576
580 void sortAndClean(float pMin = 800, float pMax = 1100);
581
583 void clear();
584
586 void append(const Pressure& other);
587
590
593
600 void makeRobustPressure(TimeStampType timeInterval = 100 * 1000, TimeStampType timeIntervalRef = 24 * 60 * 1000, TimeStampType tStart = 1, TimeStampType tEnd = 0, const int nthreads = 1);
601
603 static void setAliases(TTree* tree);
604
605 RawDPsF cavernAtmosPressure{};
606 RawDPsF cavernAtmosPressure2{};
607 RawDPsF surfaceAtmosPressure{};
608 RobustPressure robustPressure{};
609
610 std::pair<std::vector<float>, std::vector<TimeStampType>> mCavernAtmosPressure1Buff{};
611 std::pair<std::vector<float>, std::vector<TimeStampType>> mCavernAtmosPressure2Buff{};
612 std::pair<std::vector<float>, std::vector<TimeStampType>> mSurfaceAtmosPressureBuff{};
613
614 std::pair<std::vector<float>, std::vector<TimeStampType>> mPressure12Buff{};
615 std::pair<std::vector<float>, std::vector<TimeStampType>> mPressure1SBuff{};
616 std::pair<std::vector<float>, std::vector<TimeStampType>> mPressure2SBuff{};
617
618 std::pair<std::vector<float>, std::vector<TimeStampType>> mRobPressureBuff{};
620};
621
622} // namespace o2::tpc::dcs
623#endif
int16_t time
Definition RawEventData.h:4
int32_t i
uint32_t side
Definition RawData.h:0
uint32_t stack
Definition RawData.h:1
GLuint GLuint end
Definition glcorearb.h:469
GLenum array
Definition glcorearb.h:4274
GLuint index
Definition glcorearb.h:781
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLenum GLint * range
Definition glcorearb.h:1899
GLsizei const GLfloat * value
Definition glcorearb.h:819
GLint GLint GLsizei GLint GLenum GLenum type
Definition glcorearb.h:275
GLboolean * data
Definition glcorearb.h:298
GLuint GLfloat * val
Definition glcorearb.h:1582
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
GLuint * states
Definition glcorearb.h:4932
void doAppend(std::vector< dcs::DataPointVector< T > > &a, const std::vector< dcs::DataPointVector< T > > &b)
Definition DCS.h:165
float DataType
Definition DCS.h:43
dcs::TimeStampType getMinTime(const std::vector< dcs::DataPointVector< T > > &data, const bool roundToInterval, dcs::TimeStampType fitInterval)
Definition DCS.h:190
void doClear(std::vector< dcs::DataPointVector< T > > &dataVector)
Definition DCS.h:157
uint64_t TimeStampType
Definition DCS.h:45
const T getAverageValueForTime(const std::vector< dcs::DataPointVector< T > > &dpVec, const TimeStampType from, const TimeStampType until, const long range)
Definition DCS.h:176
void doSortAndClean(std::vector< dcs::DataPointVector< T > > &dataVector)
Definition DCS.h:149
dcs::TimeStampType getMaxTime(const std::vector< dcs::DataPointVector< T > > &data)
Definition DCS.h:209
Global TPC definitions and constants.
Definition SimTraits.h:167
GEMstack
TPC GEM stack types.
Definition Defs.h:53
constexpr unsigned char SECTORSPERSIDE
Definition Defs.h:40
Enum< T >::Iterator begin(Enum< T >)
Definition Defs.h:173
constexpr unsigned short GEMSPERSTACK
Definition Defs.h:58
constexpr unsigned char SIDES
Definition Defs.h:41
Side
TPC readout sidE.
Definition Defs.h:35
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
Defining DataPointCompositeObject explicitly as copiable.
GEM stack identification.
Definition Defs.h:77
std::vector< DPType > data
Definition DCS.h:71
void fill(const TimeStampType time, const T &value)
Definition DCS.h:86
auto getPairOfVector() const
convert data points to a vector of pairs: pair.first -> data and pair.second -> time
Definition DCS.h:74
void fill(const DPType &dataPoint)
Definition DCS.h:88
const T getAverageValueForTime(const TimeStampType from, const TimeStampType until, const long range) const
Definition DCS.h:139
void append(const DataPointVector< T > &other)
Definition DCS.h:106
ClassDefNV(DataPointVector, 1)
const std::pair< T, long > getSumAndPoints(const TimeStampType from, const TimeStampType until, const long range) const
calculate average value between from and unil, extending the range by +- range elements
Definition DCS.h:127
const T & getValueForTime(const TimeStampType timeStamp) const
Definition DCS.h:114
const T getAverageValueForTime(const TimeStampType timeStamp, const long range) const
calculate average value for timeStamp, extending the range by +- range elements
Definition DCS.h:121
bool equalTime(const DataPoint &other) const
Definition DCS.h:55
bool operator<(const TimeStampType timeStamp) const
Definition DCS.h:57
TimeStampType time
Definition DCS.h:52
DataPoint operator/(const DataType denom) const
Definition DCS.h:59
DataPoint operator+(const DataPoint &other) const
Definition DCS.h:58
bool operator<(const DataPoint &other) const
Definition DCS.h:56
ClassDefNV(DataPoint, 1)
void clear()
Definition DCS.h:519
void fill(std::string_view sensor, const TimeStampType time, const DataType value)
Definition DCS.h:464
void append(const Gas &other)
Definition DCS.h:531
void sortAndClean()
Definition DCS.h:507
void clear()
Definition DCS.h:430
void sortAndClean()
Definition DCS.h:423
std::vector< RawDPsF > voltages
voltages per GEM stack, counting is IROCs GEM1 top, bottom, GEM2 top, bottom, .. O1 ....
Definition DCS.h:370
static const std::unordered_map< StackState, std::string > StackStateNameMap
map state to string
Definition DCS.h:366
std::vector< RawDPsState > states
HV state per sector.
Definition DCS.h:372
std::vector< RawDPsF > currents
currents per GEM stack, counting is IROCs GEM1 top, bottom, GEM2 top, bottom, .. O1 ....
Definition DCS.h:371
static GEMstack getStack(std::string_view sensor)
Definition DCS.h:381
static int getSector(std::string_view sensor)
Definition DCS.h:374
void fillStatus(std::string_view sensor, const TimeStampType time, const uint32_t value)
Fill stack status information.
Definition DCS.h:413
void append(const HV &other)
Definition DCS.h:437
void fillUI(std::string_view sensor, const TimeStampType time, const DataType value)
Fill voltage and current information.
Definition DCS.h:391
ClassDefNV(Pressure, 1)
Stats cavernAtmosPressure2S
rolling statistics of cavernAtmosPressure2/surfaceAtmosPressure
Definition DCS.h:557
Stats cavernAtmosPressure1S
rolling statistics of cavernAtmosPressure/surfaceAtmosPressure
Definition DCS.h:556
std::vector< uint8_t > isOk
bit mask of valid sensors: cavernBit 0, cavern2Bit = 1, surfaceBit = 2
Definition DCS.h:558
Stats cavernAtmosPressure2
rolling statistics of cavern sensor 2
Definition DCS.h:554
std::vector< float > robustPressure
combined robust pressure value that should be used
Definition DCS.h:559
Stats cavernAtmosPressure12
rolling statistics of cavernAtmosPressure/cavernAtmosPressure2
Definition DCS.h:555
ClassDefNV(RobustPressure, 1)
std::vector< TimeStampType > time
time stamps of all pressure values
Definition DCS.h:560
Stats cavernAtmosPressure
rolling statistics of cavern sensor 1
Definition DCS.h:553
TimeStampType timeIntervalRef
reference time interval used for normalization of pressure sensors
Definition DCS.h:562
Stats surfaceAtmosPressure
rolling statistics of surface sensor
Definition DCS.h:552
TimeStampType timeInterval
time interval used for rolling statistics
Definition DCS.h:561
Stats operator+(const Stats &other) const
Definition DCS.h:280
Stats operator/(const DataType val) const
Definition DCS.h:281
DataType getMeanTempRaw()
Definition DCS.h:296
StatsDPs statsA
statistics fit values per integration time A-Side
Definition DCS.h:287
void append(const Temperature &other)
Definition DCS.h:320
StatsDPs statsC
statistics fit values per integration time C-Side
Definition DCS.h:288
static constexpr auto & getSensorPosition(const size_t sensor)
Definition DCS.h:267
std::vector< RawDPsF > raw
raw temperature values from DCS for
Definition DCS.h:289
void fill(std::string_view sensor, const TimeStampType time, const DataType temperature)
Definition DCS.h:301
const Stats & getStats(const Side s, const TimeStampType timeStamp) const
Definition DCS.h:291
constexpr size_t min
constexpr size_t max
VectorOfTObjectPtrs other
vec clear()
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))