Project
Loading...
Searching...
No Matches
DCS.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
15
16#include <limits>
17
18#include "DataFormatsTPC/DCS.h"
19#include "TLinearFitter.h"
20#include "TTree.h"
21
22using namespace o2::tpc::dcs;
23
24//==============================================================================
25//
26//
27const std::unordered_map<std::string, int> Temperature::SensorNameMap = {
28 {"TPC_PT_351_TEMPERATURE", 0},
29 {"TPC_PT_376_TEMPERATURE", 1},
30 {"TPC_PT_415_TEMPERATURE", 2},
31 {"TPC_PT_447_TEMPERATURE", 3},
32 {"TPC_PT_477_TEMPERATURE", 4},
33 {"TPC_PT_488_TEMPERATURE", 5},
34 {"TPC_PT_537_TEMPERATURE", 6},
35 {"TPC_PT_575_TEMPERATURE", 7},
36 {"TPC_PT_589_TEMPERATURE", 8},
37 {"TPC_PT_629_TEMPERATURE", 9},
38 {"TPC_PT_664_TEMPERATURE", 10},
39 {"TPC_PT_695_TEMPERATURE", 11},
40 {"TPC_PT_735_TEMPERATURE", 12},
41 {"TPC_PT_757_TEMPERATURE", 13},
42 {"TPC_PT_797_TEMPERATURE", 14},
43 {"TPC_PT_831_TEMPERATURE", 15},
44 {"TPC_PT_851_TEMPERATURE", 16},
45 {"TPC_PT_895_TEMPERATURE", 17},
46};
47
48Temperature::Temperature() noexcept : raw(SensorsPerSide * SIDES)
49{
50 for (size_t i = 0; i < raw.size(); ++i) {
51 raw[i].sensorNumber = i;
52 }
53}
54
55//==============================================================================
56//
57//
61{
62 for (size_t i = 0; i < voltages.size(); ++i) {
63 voltages[i].sensorNumber = i;
64 currents[i].sensorNumber = i;
65 }
66 for (size_t i = 0; i < states.size(); ++i) {
67 states[i].sensorNumber = i;
68 }
69}
70
71const std::unordered_map<HV::StackState, std::string> HV::StackStateNameMap =
72 {
73 {StackState::OFF, "OFF"},
74 {StackState::STBY_CONFIGURED, "STBY_CONFIGURED"},
75 {StackState::INTERMEDIATE, "INTERMEDIATE"},
76 {StackState::ON, "ON"},
77 {StackState::ERROR, "ERROR"},
78 {StackState::ERROR_LOCAL, "ERROR_LOCAL"},
79 {StackState::SOFT_INTERLOCK, "SOFT_INTERLOCK"},
80 {StackState::INTERLOCK, "INTERLOCK"},
81 {StackState::RAMPIG_UP_LOW, "RAMPIG_UP_LOW"},
82 {StackState::RAMPIG_DOWN_LOW, "RAMPIG_DOWN_LOW"},
83 {StackState::RAMPIG_UP, "RAMPIG_UP"},
84 {StackState::RAMPIG_DOWN, "RAMPIG_DOWN"},
85 {StackState::MIXED, "MIXED"},
86 {StackState::NO_CONTROL, "NO_CONTROL"},
87};
88
90{
91 constexpr auto max = std::numeric_limits<dcs::TimeStampType>::max();
92 const std::vector<TimeStampType> times{
93 neon.data.size() ? neon.data.front().time : max,
94 co2.data.size() ? co2.data.front().time : max,
95 n2.data.size() ? n2.data.front().time : max,
96 argon.data.size() ? argon.data.front().time : max,
97 h2o.data.size() ? h2o.data.front().time : max,
98 o2.data.size() ? o2.data.front().time : max,
99 h2oSensor.data.size() ? h2oSensor.data.front().time : max,
100 o2Sensor.data.size() ? o2Sensor.data.front().time : max,
101 };
102
103 return *std::min_element(times.begin(), times.end());
104}
105
107{
108 constexpr auto min = 0;
109 const std::vector<TimeStampType> times{
110 neon.data.size() ? neon.data.back().time : min,
111 co2.data.size() ? co2.data.back().time : min,
112 n2.data.size() ? n2.data.back().time : min,
113 argon.data.size() ? argon.data.back().time : min,
114 h2o.data.size() ? h2o.data.back().time : min,
115 o2.data.size() ? o2.data.back().time : min,
116 h2oSensor.data.size() ? h2oSensor.data.back().time : min,
117 o2Sensor.data.size() ? o2Sensor.data.back().time : min,
118 };
119
120 return *std::max_element(times.begin(), times.end());
121}
122
124{
125 constexpr auto max = std::numeric_limits<dcs::TimeStampType>::max();
126 const std::vector<TimeStampType> times{
127 cavernAtmosPressure.data.size() ? cavernAtmosPressure.data.front().time : max,
128 cavernAtmosPressure2.data.size() ? cavernAtmosPressure2.data.front().time : max,
129 surfaceAtmosPressure.data.size() ? surfaceAtmosPressure.data.front().time : max,
130 };
131
132 return *std::min_element(times.begin(), times.end());
133}
134
136{
137 constexpr auto min = 0;
138 const std::vector<TimeStampType> times{
139 cavernAtmosPressure.data.size() ? cavernAtmosPressure.data.back().time : min,
142 };
143
144 return *std::max_element(times.begin(), times.end());
145}
146
147bool Temperature::makeFit(TLinearFitter& fitter, const int nDim, std::vector<double>& xVals, std::vector<double>& temperatures)
148{
149 const int minPointsForFit = 5;
150 if (temperatures.empty() || (temperatures.size() < minPointsForFit)) {
151 LOGP(warning, "Number of points {} for fit smaller than minimum of {}!", temperatures.size(), minPointsForFit);
152 return false;
153 }
154
155 fitter.ClearPoints();
156 fitter.AssignData(temperatures.size(), nDim, xVals.data(), temperatures.data());
157 int status = fitter.Eval();
158 if (status == 1) {
159 LOGP(warning, "Fit failed!");
160 return false;
161 }
162 return true;
163}
164
165void Temperature::fitTemperature(Side side, dcs::TimeStampType fitInterval, const bool roundToInterval)
166{
167 // clear old data
168 auto& stats = (side == Side::A) ? statsA : statsC;
169 stats.clear();
170
171 // temperature fits in x-y
172 const int nDim = 2;
173 TLinearFitter fitter(nDim, "1 ++ x0 ++ x1", "");
174 std::array<size_t, dcs::Temperature::SensorsPerSide> startPos{};
175 const size_t sensorOffset = (side == Side::C) ? dcs::Temperature::SensorsPerSide : 0;
176
177 const dcs::TimeStampType refTime = getMinTime(raw, fitInterval, roundToInterval);
178 const dcs::TimeStampType refTimeMax = getMaxTime(raw);
179
180 // calculate number of intervals and see if the last interval should be merged into the previous one
181 const int lastIntervalDuration = (refTimeMax - refTime) % fitInterval;
182
183 // process the last interval only if it contains more than 50% of the interval duration
184 const bool procLastInt = (lastIntervalDuration / fitInterval > 0.5);
185 int numIntervals = (refTimeMax - refTime) / fitInterval + procLastInt;
186 if (numIntervals == 0) {
187 numIntervals = 1;
188 }
189
190 // buffer for fit values
191 std::vector<double> xVals;
192 std::vector<double> temperatures;
193 xVals.reserve(2 * 1000);
194 temperatures.reserve(1000);
195
196 for (int interval = 0; interval < numIntervals; ++interval) {
197 const dcs::TimeStampType timeStart = refTime + interval * fitInterval;
198
199 // clear buffer
200 xVals.clear();
201 temperatures.clear();
202
203 // TODO: check if we should use refTime
204 dcs::TimeStampType firstTime = std::numeric_limits<dcs::TimeStampType>::max();
205 dcs::TimeStampType LastTime = 0;
206
207 for (size_t iSensor = 0; iSensor < dcs::Temperature::SensorsPerSide; ++iSensor) {
208 const auto& sensor = raw[iSensor + sensorOffset];
209
210 LOGP(debug, "sensor {}, start {}, size {}", sensor.sensorNumber, startPos[iSensor], sensor.data.size());
211 while (startPos[iSensor] < sensor.data.size()) {
212 const auto& dataPoint = sensor.data[startPos[iSensor]];
213 if (((dataPoint.time - timeStart) >= fitInterval) && (interval != numIntervals - 1)) {
214 LOGP(debug, "sensor {}, {} - {} >= {}", sensor.sensorNumber, dataPoint.time, timeStart, fitInterval);
215 break;
216 }
217 firstTime = std::min(firstTime, dataPoint.time);
218 LastTime = std::max(LastTime, dataPoint.time);
219 const auto temperature = dataPoint.value;
220 // sanity check
221 ++startPos[iSensor];
222 if (temperature < 15 || temperature > 25) {
223 continue;
224 }
225 const auto& pos = dcs::Temperature::SensorPosition[iSensor + sensorOffset];
226 xVals.emplace_back(pos.x);
227 xVals.emplace_back(pos.y);
228 temperatures.emplace_back(temperature);
229 }
230 }
231 if (firstTime < std::numeric_limits<dcs::TimeStampType>::max() && !temperatures.empty()) {
232 const bool fitOk = makeFit(fitter, nDim, xVals, temperatures);
233 if (!fitOk) {
234 continue;
235 }
236 auto& stat = stats.data.emplace_back();
237 stat.time = (firstTime + LastTime) / 2;
238 stat.value.mean = fitter.GetParameter(0);
239 stat.value.gradX = fitter.GetParameter(1);
240 stat.value.gradY = fitter.GetParameter(2);
241
242 // check if data contains outliers
243 const float maxDeltaT = 1;
244 const float meanTemp = fitter.GetParameter(0);
245 const bool isDataGood = std::all_of(temperatures.begin(), temperatures.end(), [meanTemp, maxDeltaT](double t) { return std::abs(t - meanTemp) < maxDeltaT; });
246
247 // do second iteration only in case of outliers
248 if (!isDataGood) {
249 std::vector<double> xVals2;
250 std::vector<double> temperatures2;
251 xVals2.reserve(xVals.size());
252 temperatures2.reserve(temperatures.size());
253 for (int i = 0; i < temperatures.size(); ++i) {
254 if (std::abs(temperatures[i] - meanTemp) < maxDeltaT) {
255 const int idx = 2 * i;
256 xVals2.emplace_back(xVals[idx]);
257 xVals2.emplace_back(xVals[idx + 1]);
258 temperatures2.emplace_back(temperatures[i]);
259 }
260 }
261 const bool fitOk2 = makeFit(fitter, nDim, xVals2, temperatures2);
262 if (fitOk2) {
263 stat.value.mean = fitter.GetParameter(0);
264 stat.value.gradX = fitter.GetParameter(1);
265 stat.value.gradY = fitter.GetParameter(2);
266 }
267 }
268 }
269 }
270}
271
272void Pressure::fill(std::string_view sensor, const TimeStampType time, const DataType value)
273{
274 if (sensor == "CavernAtmosPressure") {
276 } else if (sensor == "CavernAtmosPressure2") {
278 } else if (sensor == "SurfaceAtmosPressure") {
280 } else {
281 LOGP(warning, "Unknown pressure sensor {}", sensor);
282 }
283}
284
285void Pressure::sortAndClean(float pMin, float pMax)
286{
290
291 auto removeOutliers = [](auto& dataVec, auto minVal, auto maxVal) {
292 dataVec.erase(
293 std::remove_if(dataVec.begin(), dataVec.end(),
294 [minVal, maxVal](const auto& dp) {
295 return (dp.value < minVal || dp.value > maxVal);
296 }),
297 dataVec.end());
298 };
299
300 removeOutliers(cavernAtmosPressure.data, pMin, pMax);
301 removeOutliers(cavernAtmosPressure2.data, pMin, pMax);
302 removeOutliers(surfaceAtmosPressure.data, pMin, pMax);
303}
304
312
314{
315 cavernAtmosPressure.append(other.cavernAtmosPressure);
316 cavernAtmosPressure2.append(other.cavernAtmosPressure2);
317 surfaceAtmosPressure.append(other.surfaceAtmosPressure);
318}
319
320void fillBuffer(std::pair<std::vector<float>, std::vector<TimeStampType>>& buffer, const std::pair<std::vector<float>, std::vector<TimeStampType>>& values, TimeStampType tStart, const int minPoints)
321{
322 const auto itStartBuff = std::lower_bound(buffer.second.begin(), buffer.second.end(), tStart);
323 size_t idxStartBuffer = std::distance(buffer.second.begin(), itStartBuff);
324 if (buffer.first.size() - idxStartBuffer < minPoints) {
325 if (buffer.first.size() < minPoints) {
326 idxStartBuffer = 0;
327 } else {
328 idxStartBuffer = buffer.first.size() - minPoints;
329 }
330 }
331
332 std::pair<std::vector<float>, std::vector<TimeStampType>> buffTmp{
333 std::vector<float>(buffer.first.begin() + idxStartBuffer, buffer.first.end()),
334 std::vector<TimeStampType>(buffer.second.begin() + idxStartBuffer, buffer.second.end())};
335
336 buffTmp.first.insert(buffTmp.first.end(), values.first.begin(), values.first.end());
337 buffTmp.second.insert(buffTmp.second.end(), values.second.begin(), values.second.end());
338
339 buffer = std::move(buffTmp);
340}
341
342void Pressure::makeRobustPressure(TimeStampType timeInterval, TimeStampType timeIntervalRef, TimeStampType tStart, TimeStampType tEnd, const int nthreads)
343{
344 const auto surfaceAtmosPressurePair = surfaceAtmosPressure.getPairOfVector();
345 const auto cavernAtmosPressurePair = cavernAtmosPressure.getPairOfVector();
346 const auto cavernAtmosPressure2Pair = cavernAtmosPressure2.getPairOfVector();
347
348 // round to second
349 tStart = tStart / 1000 * 1000;
350 const TimeStampType tStartRef = (tStart - timeIntervalRef);
351 const int minPointsRef = 50;
352 fillBuffer(mCavernAtmosPressure1Buff, cavernAtmosPressurePair, tStartRef, minPointsRef);
353 fillBuffer(mCavernAtmosPressure2Buff, cavernAtmosPressure2Pair, tStartRef, minPointsRef);
354 fillBuffer(mSurfaceAtmosPressureBuff, surfaceAtmosPressurePair, tStartRef, minPointsRef);
355
356 int nIntervals = std::round((tEnd - tStart) / timeInterval);
357 if (nIntervals == 0) {
358 nIntervals = 1; // at least one interval
359 }
360 std::vector<TimeStampType> times;
361 times.reserve(nIntervals);
362 for (int i = 0; i < nIntervals; ++i) {
363 times.emplace_back(tStart + (i + 0.5) * timeInterval);
364 }
365
367 const int minPoints = 4;
368 const auto cavernAtmosPressureStats = o2::math_utils::getRollingStatistics(mCavernAtmosPressure1Buff.second, mCavernAtmosPressure1Buff.first, times, timeInterval, nthreads, minPoints, minPoints);
369 const auto cavernAtmosPressure2Stats = o2::math_utils::getRollingStatistics(mCavernAtmosPressure2Buff.second, mCavernAtmosPressure2Buff.first, times, timeInterval, nthreads, minPoints, minPoints);
370 const auto surfaceAtmosPressureStats = o2::math_utils::getRollingStatistics(mSurfaceAtmosPressureBuff.second, mSurfaceAtmosPressureBuff.first, times, timeInterval, nthreads, minPoints, minPoints);
371
372 // subtract the moving median values from the different sensors if they are ok
373 std::pair<std::vector<float>, std::vector<TimeStampType>> cavernAtmosPressure12;
374 std::pair<std::vector<float>, std::vector<TimeStampType>> cavernAtmosPressure1S;
375 std::pair<std::vector<float>, std::vector<TimeStampType>> cavernAtmosPressure2S;
376 cavernAtmosPressure12.first.reserve(nIntervals);
377 cavernAtmosPressure1S.first.reserve(nIntervals);
378 cavernAtmosPressure2S.first.reserve(nIntervals);
379 cavernAtmosPressure12.second.reserve(nIntervals);
380 cavernAtmosPressure1S.second.reserve(nIntervals);
381 cavernAtmosPressure2S.second.reserve(nIntervals);
382
383 for (int i = 0; i < nIntervals; i++) {
384 // coarse check if data is close by
385 const int maxDist = 600 * 1000;
386 const bool cavernOk = (cavernAtmosPressureStats.median[i] > 0) && (cavernAtmosPressureStats.closestDistanceL[i] < maxDist) && (cavernAtmosPressureStats.closestDistanceR[i] < maxDist);
387 const bool cavern2Ok = (cavernAtmosPressure2Stats.median[i] > 0) && (cavernAtmosPressure2Stats.closestDistanceL[i] < maxDist) && (cavernAtmosPressure2Stats.closestDistanceR[i] < maxDist);
388 const bool surfaceOk = (surfaceAtmosPressureStats.median[i] > 0) && (surfaceAtmosPressureStats.closestDistanceL[i] < maxDist) && (surfaceAtmosPressureStats.closestDistanceR[i] < maxDist);
389
390 if (cavernOk && cavern2Ok) {
391 cavernAtmosPressure12.first.emplace_back(cavernAtmosPressureStats.median[i] - cavernAtmosPressure2Stats.median[i]);
392 cavernAtmosPressure12.second.emplace_back(times[i]);
393 }
394 if (cavernOk && surfaceOk) {
395 cavernAtmosPressure1S.first.emplace_back(cavernAtmosPressureStats.median[i] - surfaceAtmosPressureStats.median[i]);
396 cavernAtmosPressure1S.second.emplace_back(times[i]);
397 }
398 if (cavern2Ok && surfaceOk) {
399 cavernAtmosPressure2S.first.emplace_back(cavernAtmosPressure2Stats.median[i] - surfaceAtmosPressureStats.median[i]);
400 cavernAtmosPressure2S.second.emplace_back(times[i]);
401 }
402 }
403
404 fillBuffer(mPressure12Buff, cavernAtmosPressure12, tStartRef, minPointsRef);
405 fillBuffer(mPressure1SBuff, cavernAtmosPressure1S, tStartRef, minPointsRef);
406 fillBuffer(mPressure2SBuff, cavernAtmosPressure2S, tStartRef, minPointsRef);
407
408 // get long term median of diffs - this is used for normalization of the pressure values -
409 const auto cavernAtmosPressure12Stats = o2::math_utils::getRollingStatistics(mPressure12Buff.second, mPressure12Buff.first, times, timeIntervalRef, nthreads, 3, minPointsRef);
410 const auto cavernAtmosPressure1SStats = o2::math_utils::getRollingStatistics(mPressure1SBuff.second, mPressure1SBuff.first, times, timeIntervalRef, nthreads, 3, minPointsRef);
411 const auto cavernAtmosPressure2SStats = o2::math_utils::getRollingStatistics(mPressure2SBuff.second, mPressure2SBuff.first, times, timeIntervalRef, nthreads, 3, minPointsRef);
412
413 // calculate diffs of median values
414 const float maxDist = 20 * timeInterval;
415 const float maxDiff = 0.2;
416 std::pair<std::vector<float>, std::vector<TimeStampType>> robustPressureTmp;
417 robustPressureTmp.first.reserve(nIntervals);
418 robustPressureTmp.second.reserve(nIntervals);
419 std::vector<uint8_t> isOk(nIntervals);
420
421 for (int i = 0; i < nIntervals; ++i) {
422 // difference beween pressure values corrected for the long term median
423 const float delta12 = cavernAtmosPressureStats.median[i] - cavernAtmosPressure2Stats.median[i] - cavernAtmosPressure12Stats.median[i];
424 const float delta1S = cavernAtmosPressureStats.median[i] - surfaceAtmosPressureStats.median[i] - cavernAtmosPressure1SStats.median[i];
425 const float delta2S = cavernAtmosPressure2Stats.median[i] - surfaceAtmosPressureStats.median[i] - cavernAtmosPressure2SStats.median[i];
426
427 const auto distCavernAtmosPressureL = cavernAtmosPressureStats.closestDistanceL[i];
428 const auto distCavernAtmosPressure2L = cavernAtmosPressure2Stats.closestDistanceL[i];
429 const auto distSurfaceAtmosPressureL = surfaceAtmosPressureStats.closestDistanceL[i];
430 const auto distCavernAtmosPressureR = cavernAtmosPressureStats.closestDistanceR[i];
431 const auto distCavernAtmosPressure2R = cavernAtmosPressure2Stats.closestDistanceR[i];
432 const auto distSurfaceAtmosPressureR = surfaceAtmosPressureStats.closestDistanceR[i];
433
434 // check if data is ok
435 const bool cavernDistOk = (cavernAtmosPressureStats.median[i] > 0) && ((distCavernAtmosPressureL < maxDist) || (distCavernAtmosPressureR < maxDist));
436 const bool cavern2DistOk = (cavernAtmosPressure2Stats.median[i] > 0) && ((distCavernAtmosPressure2L < maxDist) || (distCavernAtmosPressure2R < maxDist));
437 const bool surfaceDistOk = (surfaceAtmosPressureStats.median[i] > 0) && ((distSurfaceAtmosPressureL < maxDist) || (distSurfaceAtmosPressureR < maxDist));
438 const bool onlyOneSensor = (cavernDistOk + cavern2DistOk + surfaceDistOk) == 1; // check if only 1 sensor exists, if so use that sensor
439
440 uint8_t maskIsOkTmp = 0;
441 const int cavernBit = 0; // val 1
442 const int cavern2Bit = 1; // val 2
443 const int surfaceBit = 2; // val 4
444
445 // check if ratio sensor 1 and 2 are good
446 // maskIsOkTmp = 3
447 if (((std::abs(delta12) < maxDiff) && (cavernDistOk && cavern2DistOk)) || onlyOneSensor) {
448 if (cavernDistOk) {
449 maskIsOkTmp |= (1 << cavernBit);
450 }
451 if (cavern2DistOk) {
452 maskIsOkTmp |= (1 << cavern2Bit);
453 }
454 }
455
456 // check if ratio sensor 1 and surface are good
457 // maskIsOkTmp = 5
458 if ((std::abs(delta1S) < maxDiff) && ((cavernDistOk && surfaceDistOk)) || onlyOneSensor) {
459 if (cavernDistOk) {
460 maskIsOkTmp |= (1 << cavernBit);
461 }
462 if (surfaceDistOk) {
463 maskIsOkTmp |= (1 << surfaceBit);
464 }
465 }
466
467 // check if ratio sensor 2 and surface are good
468 // maskIsOkTmp = 6
469 if ((std::abs(delta2S) < maxDiff) && ((cavern2DistOk && surfaceDistOk)) || onlyOneSensor) {
470 if (cavern2DistOk) {
471 maskIsOkTmp |= (1 << cavern2Bit);
472 }
473 if (surfaceDistOk) {
474 maskIsOkTmp |= (1 << surfaceBit);
475 }
476 }
477
478 // calculate robust pressure
479 float pressure = 0;
480 int pressureCount = 0;
481 if ((maskIsOkTmp >> cavernBit) & 1) {
482 pressure += cavernAtmosPressureStats.median[i];
483 pressureCount++;
484 }
485
486 if ((maskIsOkTmp >> cavern2Bit) & 1) {
487 pressure += cavernAtmosPressure2Stats.median[i] + cavernAtmosPressure12Stats.median[i];
488 pressureCount++;
489 }
490
491 if ((maskIsOkTmp >> surfaceBit) & 1) {
492 pressure += surfaceAtmosPressureStats.median[i] + cavernAtmosPressure1SStats.median[i];
493 pressureCount++;
494 }
495
496 isOk[i] = maskIsOkTmp;
497 if (pressureCount > 0) {
498 pressure /= pressureCount;
499 robustPressureTmp.first.emplace_back(pressure);
500 robustPressureTmp.second.emplace_back(times[i]);
501 }
502 }
503
504 fillBuffer(mRobPressureBuff, robustPressureTmp, tStartRef, minPointsRef);
505
507 pOut.surfaceAtmosPressure = std::move(surfaceAtmosPressureStats);
508 pOut.cavernAtmosPressure2 = std::move(cavernAtmosPressure2Stats);
509 pOut.cavernAtmosPressure = std::move(cavernAtmosPressureStats);
510 pOut.cavernAtmosPressure12 = std::move(cavernAtmosPressure12Stats);
511 pOut.cavernAtmosPressure1S = std::move(cavernAtmosPressure1SStats);
512 pOut.cavernAtmosPressure2S = std::move(cavernAtmosPressure2SStats);
513 pOut.isOk = std::move(isOk);
514 pOut.robustPressure = o2::math_utils::getRollingStatistics(mRobPressureBuff.second, mRobPressureBuff.first, times, timeInterval, nthreads, 1, 5).median;
515 pOut.time = std::move(times);
516 pOut.timeInterval = timeInterval;
517 pOut.timeIntervalRef = timeIntervalRef;
518 pOut.maxDist = maxDist;
519 pOut.maxDiff = maxDiff;
520}
521
523{
524 tree->SetAlias("cavernDistOk", "robustPressure.cavernAtmosPressure.median>0 && (robustPressure.cavernAtmosPressure.closestDistanceR<robustPressure.maxDist || robustPressure.cavernAtmosPressure.closestDistanceL<robustPressure.maxDist)");
525 tree->SetAlias("cavern2DistOk", "robustPressure.cavernAtmosPressure2.median>0 && (robustPressure.cavernAtmosPressure2.closestDistanceR<robustPressure.maxDist || robustPressure.cavernAtmosPressure2.closestDistanceL<robustPressure.maxDist)");
526 tree->SetAlias("surfaceDistOk", "robustPressure.surfaceAtmosPressure.median>0 && (robustPressure.surfaceAtmosPressure.closestDistanceR<robustPressure.maxDist || robustPressure.surfaceAtmosPressure.closestDistanceL<robustPressure.maxDist)");
527 tree->SetAlias("onlyOneSensor", "(cavernDistOk + cavern2DistOk + surfaceDistOk) == 1");
528 tree->SetAlias("delta12", "robustPressure.cavernAtmosPressure.median - robustPressure.cavernAtmosPressure2.median - robustPressure.cavernAtmosPressure12.median");
529 tree->SetAlias("delta1S", "robustPressure.cavernAtmosPressure.median - robustPressure.surfaceAtmosPressure.median - robustPressure.cavernAtmosPressure1S.median");
530 tree->SetAlias("delta2S", "robustPressure.surfaceAtmosPressure.median - robustPressure.cavernAtmosPressure2.median - robustPressure.cavernAtmosPressure2S.median");
531 tree->SetAlias("delta12_Ok", "abs(delta12)<robustPressure.maxDiff");
532 tree->SetAlias("delta1S_Ok", "abs(delta1S)<robustPressure.maxDiff");
533 tree->SetAlias("delta2S_Ok", "abs(delta2S)<robustPressure.maxDiff");
534}
std::vector< unsigned long > times
void fillBuffer(std::pair< std::vector< float >, std::vector< TimeStampType > > &buffer, const std::pair< std::vector< float >, std::vector< TimeStampType > > &values, TimeStampType tStart, const int minPoints)
Definition DCS.cxx:320
DCS data point data formats.
int16_t time
Definition RawEventData.h:4
int32_t i
uint16_t pos
Definition RawData.h:3
uint32_t side
Definition RawData.h:0
std::ostringstream debug
GLuint buffer
Definition glcorearb.h:655
GLsizei const GLfloat * value
Definition glcorearb.h:819
GLenum GLsizei GLsizei GLint * values
Definition glcorearb.h:1576
GLuint * states
Definition glcorearb.h:4932
RollingStats getRollingStatistics(const DataTimeType &timeData, const DataType &data, const DataTime &times, const double deltaMax, const int mNthreads, const size_t minPoints=4, const size_t nClosestPoints=4)
calculates the rolling statistics of the input data
Definition fit.h:846
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
uint64_t TimeStampType
Definition DCS.h:45
dcs::TimeStampType getMaxTime(const std::vector< dcs::DataPointVector< T > > &data)
Definition DCS.h:209
constexpr unsigned char SECTORSPERSIDE
Definition Defs.h:40
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
Definition Defs.h:35
@ C
Definition Defs.h:36
constexpr unsigned short GEMSTACKSPERSECTOR
Definition Defs.h:57
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
std::vector< float > median
median of rolling data
Definition fit.h:827
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 append(const DataPointVector< T > &other)
Definition DCS.h:106
RawDPsF h2o
H2O measurement from gas chromatograph.
Definition DCS.h:459
RawDPsF neon
neon measurement from gas chromatograph
Definition DCS.h:455
TimeStampType getMaxTime() const
Definition DCS.cxx:106
TimeStampType getMinTime() const
Definition DCS.cxx:89
RawDPsF co2
CO2 measurement from gas chromatograph.
Definition DCS.h:456
RawDPsF h2oSensor
O2 measurement from dedicated gas sensor.
Definition DCS.h:461
RawDPsF argon
argon measurement from gas chromatograph
Definition DCS.h:458
RawDPsF o2Sensor
O2 measurement from dedicated gas sensor.
Definition DCS.h:462
RawDPsF n2
neon measurement from gas chromatograph
Definition DCS.h:457
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
HV() noexcept
Definition DCS.cxx:58
std::vector< RawDPsF > currents
currents per GEM stack, counting is IROCs GEM1 top, bottom, GEM2 top, bottom, .. O1 ....
Definition DCS.h:371
std::pair< std::vector< float >, std::vector< TimeStampType > > mPressure12Buff
! buffer for normalizing the pressure cavern 1 / cavern 2
Definition DCS.h:614
void append(const Pressure &other)
append other pressure values
Definition DCS.cxx:313
void sortAndClean(float pMin=800, float pMax=1100)
Definition DCS.cxx:285
RawDPsF cavernAtmosPressure2
raw pressure in the cavern from sensor 2
Definition DCS.h:606
RobustPressure robustPressure
combined robust pressure estimator from all three sensors
Definition DCS.h:608
std::pair< std::vector< float >, std::vector< TimeStampType > > mPressure2SBuff
! buffer for normalizing the pressure cavern 2 / surface
Definition DCS.h:616
RawDPsF surfaceAtmosPressure
raw pressure at the surface
Definition DCS.h:607
void fill(std::string_view sensor, const TimeStampType time, const DataType value)
fill pressure data
Definition DCS.cxx:272
static void setAliases(TTree *tree)
set aliases for the cuts used in the calculation of the robust pressure
Definition DCS.cxx:522
void makeRobustPressure(TimeStampType timeInterval=100 *1000, TimeStampType timeIntervalRef=24 *60 *1000, TimeStampType tStart=1, TimeStampType tEnd=0, const int nthreads=1)
average pressure values for given time interval
Definition DCS.cxx:342
TimeStampType getMinTime() const
Definition DCS.cxx:123
std::pair< std::vector< float >, std::vector< TimeStampType > > mCavernAtmosPressure2Buff
! buffer for the pressure cavern 2 sensor
Definition DCS.h:611
std::pair< std::vector< float >, std::vector< TimeStampType > > mSurfaceAtmosPressureBuff
! buffer for the pressure surface sensort
Definition DCS.h:612
std::pair< std::vector< float >, std::vector< TimeStampType > > mPressure1SBuff
! buffer for normalizing the pressure cavern 1 / surface
Definition DCS.h:615
RawDPsF cavernAtmosPressure
raw pressure in the cavern from sensor 1
Definition DCS.h:605
std::pair< std::vector< float >, std::vector< TimeStampType > > mRobPressureBuff
! buffer for the robust pressure
Definition DCS.h:618
std::pair< std::vector< float >, std::vector< TimeStampType > > mCavernAtmosPressure1Buff
! buffer for the pressure cavern 1 sensor
Definition DCS.h:610
void clear()
\clear all stored data except the buffer
Definition DCS.cxx:305
TimeStampType getMaxTime() const
Definition DCS.cxx:135
float maxDist
maximum allowed time distance between sensors to be accepted for robust pressure calculation
Definition DCS.h:563
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
float maxDiff
maximum allowed pressure difference between sensors to be accepted for robust pressure calculation
Definition DCS.h:564
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
static constexpr std::array< Position, SensorsPerSide *SIDES > SensorPosition
Definition DCS.h:246
StatsDPs statsA
statistics fit values per integration time A-Side
Definition DCS.h:287
Temperature() noexcept
Definition DCS.cxx:48
StatsDPs statsC
statistics fit values per integration time C-Side
Definition DCS.h:288
void fitTemperature(Side side, dcs::TimeStampType fitInterval=5 *60 *1000, const bool roundToInterval=false)
make fit of the mean temperature and gradients in time intervals
Definition DCS.cxx:165
static constexpr int SensorsPerSide
number of temperature sensors in the active volume per side
Definition DCS.h:242
static const std::unordered_map< std::string, int > SensorNameMap
Definition DCS.h:244
std::vector< RawDPsF > raw
raw temperature values from DCS for
Definition DCS.h:289
constexpr size_t min
constexpr size_t max
VectorOfTObjectPtrs other
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))