Project
Loading...
Searching...
No Matches
MFTDCSProcessor.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
13#include "Rtypes.h"
14#include <deque>
15#include <string>
16#include <algorithm>
17#include <iterator>
18#include <cstring>
19#include <bitset>
20
21using namespace o2::mft;
22using namespace o2::dcs;
23
27
29
31{
32 /*
33 LOG(info) << "First Value: timestamp = " << firstValue.first << ", value = " << firstValue.second;
34 LOG(info) << "Last Value: timestamp = " << lastValue.first << ", value = " << lastValue.second;
35 LOG(info) << "Mean Value: timestamp = " << meanValue.first << ", value = " << meanValue.second;
36 LOG(info) << "Std Dev Value: timestamp = " << stddevValue.first << ", value = " << stddevValue.second;
37 LOG(info) << "Mid Value: timestamp = " << midValue.first << ", value = " << midValue.second;
38 LOG(info) << "Max Change: timestamp = " << maxChange.first << ", value = " << maxChange.second;
39 LOG(info) << "Summary: duration = " << summary.first << ", value = " << summary.second;
40 */
41}
42
43//__________________________________________________________________
44
45void MFTDCSProcessor::init(const std::vector<DPID>& pids)
46{
47 // fill the array of the DPIDs that will be used by MFT
48 // pids should be provided by CCDB
49
50 for (const auto& it : pids) {
51 mPids[it] = false;
52 mMFTDCS[it].makeEmpty();
53 }
54}
55
56//__________________________________________________________________
57
58int MFTDCSProcessor::process(const gsl::span<const DPCOM> dps)
59{
60
61 // first we check which DPs are missing - if some are, it means that
62 // the delta map was sent
63 if (mVerbose) {
64 LOG(info) << "\n\n\nProcessing new TF\n-----------------";
65 }
66 if (!mStartTFset) {
67 mStartTF = mTF;
68 mStartTFset = true;
69 }
70
71 // now we process all DPs, one by one
72 for (const auto& it : dps) {
73
74 // we process only the DPs defined in the configuration
75 const auto& el = mPids.find(it.id);
76
77 if (el == mPids.end()) {
78 LOG(info) << "DP " << it.id << " not found in MFTDCSProcessor, we will not process it";
79 continue;
80 }
81
82 processDP(it);
83 mPids[it.id] = true;
84 }
85
87
88 return 0;
89}
90
91//__________________________________________________________________
92
94{
95
96 // processing single DP
97
98 auto& dpid = dpcom.id;
99 const auto& type = dpid.get_type();
100 auto& val = dpcom.data;
101
102 /*
103 if (mVerbose) {
104 if (type == DPVAL_DOUBLE) {
105 LOG(info);
106 LOG(info) << "Processing DP = " << dpcom << ", with value = " << o2::dcs::getValue<double>(dpcom);
107 } else if (type == DPVAL_INT) {
108 LOG(info);
109 LOG(info) << "Processing DP = " << dpcom << ", with value = " << o2::dcs::getValue<int32_t>(dpcom);
110 }
111 }
112 */
113
114 auto flags = val.get_flags();
115
116 // now I need to access the correct element
117 // if (type == DPVAL_DOUBLE) {
118 // for these DPs, we will store the first, last, mid value, plus the value where the maximum variation occurred
119 auto& dvect = mDpsdoublesmap[dpid];
120
121 if (mVerbose) {
122 LOG(info) << "Processing DP = " << dpcom << ", with value = " << o2::dcs::getValue<double>(dpcom) << ", # is " << dvect.size();
123 }
124
125 auto etime = val.get_epoch_time();
126
127 // Checking if the DP is updated with time stamp information
128 if (dvect.size() == 0 || etime != dvect.back().get_epoch_time()) {
129 dvect.push_back(val);
130 }
131
132 // }
133
134 return 0;
135}
136
137//______________________________________________________________________
138
140{
141 if (mSendToCCDB) {
142 LOG(info) << "Detect larger change than threshold...";
143 }
144 return mSendToCCDB;
145}
146
148{
149
150 mSendToCCDB = false;
151
152 // here we create the object to then be sent to CCDB
153 if (mVerbose) {
154 LOG(info) << "Updating CCDB";
155 }
156
157 union Converter {
158 uint64_t raw_data;
159 double double_value;
160 } converter0, converter1;
161
162 for (auto& it : mPids) {
163 const auto& type = it.first.get_type();
164
165 // if (type == o2::dcs::DPVAL_DOUBLE) {
166 auto& mftdcs = mMFTDCS[it.first];
167
168 if (it.second) { // we processed the DP at least 1x
169
170 it.second = false; // once the point was used, reset it
171
172 // Accumulating the statistics of the DP
173 auto& dpvect = mDpsdoublesmap[it.first];
174
175 // now checking the first value
176 mftdcs.firstValue.first = dpvect[0].get_epoch_time();
177 converter0.raw_data = dpvect[0].payload_pt1;
178 mftdcs.firstValue.second = converter0.double_value;
179
180 // now checking the last value
181 mftdcs.lastValue.first = dpvect.back().get_epoch_time();
182 converter0.raw_data = dpvect.back().payload_pt1;
183 mftdcs.lastValue.second = converter0.double_value;
184
185 // now checking the number of entries
186 mftdcs.summary.first = dpvect[dpvect.size() - 1].get_epoch_time() - dpvect[0].get_epoch_time();
187 mftdcs.summary.second = dpvect.size();
188
189 // now checking the maximum change
190 if (dpvect.size() > 1) {
191
192 auto deltatime = dpvect.back().get_epoch_time() - dpvect[0].get_epoch_time();
193
194 double mean = 0.;
195
196 for (auto i = 0; i < dpvect.size(); ++i) {
197
198 converter0.raw_data = dpvect[i].payload_pt1;
199
200 mean += converter0.double_value;
201
202 for (auto j = i + 1; j < dpvect.size(); ++j) {
203
204 auto deltatime = dpvect[j].get_epoch_time() - dpvect[i].get_epoch_time();
205
206 converter1.raw_data = dpvect[j].payload_pt1;
207
208 double delta = std::abs(converter0.double_value - converter1.double_value);
209
210 if (delta > mftdcs.maxChange.second) {
211 mftdcs.maxChange.first = deltatime; // is it ok to do like this, as in Run 2?
212 mftdcs.maxChange.second = delta;
213 }
214 }
215 }
216
217 mean /= dpvect.size();
218
219 // mean value
220 mftdcs.meanValue.first = (dpvect[dpvect.size() - 1].get_epoch_time() + dpvect[0].get_epoch_time()) / 2.;
221 mftdcs.meanValue.second = mean;
222
223 // standard deviation
224 double stddev = 0;
225 for (auto i = 0; i < dpvect.size(); ++i) {
226 converter0.raw_data = dpvect[i].payload_pt1;
227 stddev += pow(converter0.double_value - mean, 2);
228 }
229
230 stddev = stddev / dpvect.size();
231 stddev > 0 ? stddev = sqrt(stddev) : 0;
232
233 mftdcs.stddevValue.first = mftdcs.meanValue.first;
234 mftdcs.stddevValue.second = stddev;
235
236 // mid value
237 auto midIdx = 0;
238
239 if (dpvect.size() % 2 == 0) {
240 midIdx = dpvect.size() / 2;
241 } else {
242 midIdx = (dpvect.size() + 1) / 2 - 1;
243 }
244
245 mftdcs.midValue.first = dpvect[midIdx].get_epoch_time();
246 converter0.raw_data = dpvect[midIdx].payload_pt1;
247 mftdcs.midValue.second = converter0.double_value;
248
249 } else {
250
251 /*
252 LOG(info) << "outside "<<dpvect.size();
253 //if the number of entries is less than 2, the first value is used to max change and mid value
254 mftdcs.maxChange.first = dpvect[0].get_epoch_time();
255 converter0.raw_data = dpvect[0].payload_pt1;
256 mftdcs.maxChange.second = converter0.double_value;
257
258 mftdcs.midValue.first = dpvect[0].get_epoch_time();
259 converter0.raw_data = dpvect[0].payload_pt1;
260 mftdcs.midValue.second = converter0.double_value;
261 */
262 }
263 }
264
265 if (mVerbose) {
266 LOG(info) << it.first.get_alias();
267 mftdcs.print();
268 LOG(info);
269 }
270
271 if (strstr(it.first.get_alias(), "MFT_RU_LV") &&
272 mftdcs.maxChange.second > mThresholdRULV) {
273 mSendToCCDB = true;
274 }
275 if (strstr(it.first.get_alias(), "Current/Analog") &&
276 mftdcs.maxChange.second > mThresholdAnalogCurrent) {
277 mSendToCCDB = true;
278 }
279 if (strstr(it.first.get_alias(), "Current/Digit") &&
280 mftdcs.maxChange.second > mThresholdDigitalCurrent) {
281 mSendToCCDB = true;
282 }
283 if (strstr(it.first.get_alias(), "Current/BackBias") &&
284 mftdcs.maxChange.second > mThresholdBackBiasCurrent) {
285 mSendToCCDB = true;
286 }
287 if (strstr(it.first.get_alias(), "Voltage/BackBias") &&
288 mftdcs.maxChange.second > mThresholdBackBiasVoltage) {
289 mSendToCCDB = true;
290 }
291
292 //}
293 }
294
295 std::map<std::string, std::string> md;
296 md["responsible"] = "Satoshi Yano";
297 prepareCCDBobjectInfo(mMFTDCS, mccdbDPsInfo, "MFT/Condition/DCSDPs", mTF, md);
298
299 return;
300}
int32_t i
ClassImp(o2::mft::MFTDCSinfo)
uint32_t j
Definition RawData.h:0
DeliveryType get_type() const noexcept
void prepareCCDBobjectInfo(T &obj, CcdbObjectInfo &info, const std::string &path, TFType tf, const std::map< std::string, std::string > &md)
int processDP(const DPCOM &dpcom)
int process(const gsl::span< const DPCOM > dps)
void init(const std::vector< DPID > &pids)
GLint GLint GLsizei GLint GLenum GLenum type
Definition glcorearb.h:275
GLuint GLfloat * val
Definition glcorearb.h:1582
GLbitfield flags
Definition glcorearb.h:1570
uint16_t get_flags() const noexcept
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"