BmnRoot
Loading...
Searching...
No Matches
TangoData.cxx
Go to the documentation of this file.
1#include "TangoData.h"
2
3#include "TColor.h"
4#include "TROOT.h"
5#include "TRandom.h"
6#include "TangoConnection.h"
7
8#include <TAxis.h>
9#include <TCanvas.h>
10#include <TGraph.h>
11#include <TGraph2D.h>
12#include <TH2D.h>
13#include <TLegend.h>
14#include <TMultiGraph.h>
15#include <TSQLServer.h>
16#include <TSQLStatement.h>
17#include <TStyle.h>
18#include <fstream>
19#include <iostream>
20using namespace std;
21
22// Tango Database connection based on MySQL before 2020-03-24
23const char* const TANGO_DB_USERNAME_b2020 = "tango";
24const char* const TANGO_DB_PASSWORD_b2020 = "tangompd";
25const char* const TANGO_DB_HOST_b2020 = "10.18.11.66";
26const char* const TANGO_DB_NAME_b2020 = "hdbpp";
27
29
31{
32 parameter_time = par_time;
33 parameter_type = par_type;
34}
35
36// Copy constructor
38 : TObject(ttp)
39 , parameter_time(ttp.parameter_time)
40 , parameter_type(ttp.parameter_type)
41{
44}
45
47
49
50TangoTimeInterval::TangoTimeInterval(TDatime start_time_interval, TDatime end_time_interval)
51{
52 start_time = start_time_interval;
53 end_time = end_time_interval;
54}
55
57
70TangoData::TangoData(const char* start_date,
71 const char* end_date,
72 const char* system_name,
73 const char* parameter_name,
74 const char* member_name,
75 int verbose)
76 : strSystemName(system_name)
77 , strParameterName(parameter_name)
78 , strMemberName(member_name)
79 , strUserName("")
80 , strStartDate(start_date)
81 , strEndDate(end_date)
82 , iVerbose(verbose)
83{
84 if (strcmp(start_date, "2020-03-25") < 0) {
85 IsOldMySQL = true;
86 if (iVerbose)
87 cout << "Old MySQL Database is used to get Tango data" << endl;
88 } else if (iVerbose)
89 cout << "PostgreSQL Database is used to get Tango data" << endl;
90
91 GetTangoParameter();
92}
93
95{
96 if (arrTangoData != nullptr) {
97 arrTangoData->Delete();
98 delete arrTangoData;
99 }
100}
101
103{
104 TString strFullName = strSystemName + ":" + strParameterName;
105 if (strMemberName != "")
106 strFullName += " (" + strMemberName + ")";
107
108 return strFullName;
109}
110
111// non-user function GetTangoParameter gets hardware data from the Tango database and write to the arrTangoData
112// First, name of the target table with required parameter is extracted from the Tango Base Table,
113// then required data are selected from the target table corresponding the given time interval.
114// Returns: 0 - in case of the success, < 0 - if an error occured
115int TangoData::GetTangoParameter()
116{
117 if (iVerbose)
118 cout << "Input Start Date = " << strStartDate.Data() << endl;
119 if (iVerbose)
120 cout << "Input End Date = " << strEndDate.Data() << endl;
121 if ((strStartDate == "") || (strEndDate == "")) {
122 cout << "ERROR: start datetime and end datetime should not be empty!" << endl;
123 return -1;
124 }
125 if (strStartDate < "2000-01-01") {
126 cout << "ERROR: start date cannot be less than 2000 year" << endl;
127 return -2;
128 }
129
130 // new start and end datetime with time zone if PgSQL
131 TString start_date_new(strStartDate), end_date_new(strEndDate);
132 if (!IsOldMySQL)
133 start_date_new += " Europe/Moscow", end_date_new += " Europe/Moscow";
134
135 // TANGO database connection (MySQL before 2020-03-24 and PgSQL after)
136 TangoConnection* connDb = nullptr;
137 if (IsOldMySQL)
140 else
141 connDb = TangoConnection::Open();
142 if (connDb == nullptr)
143 return -3;
144 TSQLServer* db_server = connDb->GetSQLServer();
145 if (db_server == nullptr)
146 return -4;
147
148 if (db_server->GetTables(db_server->GetDB()) == nullptr)
149 return -5;
150
151 // searching for a table name with corresponding parametter type, where the parameter with given system and
152 // parameter names is stored Statement returns parameter ID and parameter table
153 TString strStatement;
154 if (IsOldMySQL)
155 strStatement = TString::Format(
156 "SELECT att_conf_id, data_type "
157 "FROM att_conf ac join att_conf_data_type acdt on ac.att_conf_data_type_id = acdt.att_conf_data_type_id "
158 "WHERE family='%s' and name='%s' ",
159 strSystemName.Data(), strParameterName.Data());
160 else {
161 strStatement = TString::Format("SELECT att_conf_id, table_name "
162 "FROM att_conf "
163 "WHERE domain='%s' and name='%s' ",
164 strSystemName.Data(), strParameterName.Data());
165 if (strMemberName != "")
166 strStatement += TString::Format("and member = '%s' ", strMemberName.Data());
167 }
168
169 if (iVerbose)
170 cout << "Processing the following SQL request to get info on the Tango parameter:" << endl
171 << strStatement << endl;
172 TSQLStatement* stmt_select = db_server->Statement(strStatement);
173 if (!stmt_select->Process()) {
174 cout << "ERROR: getting info on parameter from Tango has been failed: " << GetFullName() << endl;
175 delete stmt_select;
176 return -6;
177 }
178
179 stmt_select->StoreResult();
180 if (!stmt_select->NextResultRow()) {
181 cout << "ERROR: There is no Tango parameter '" << GetFullName() << endl;
182 delete stmt_select;
183 return -7;
184 }
185 // Tango team duplicated (old MySQL solution) parameters for every Nuclotron session
186 if ((IsOldMySQL) && (stmt_select->GetNumAffectedRows() > 1) && (strcmp(strEndDate.Data(), "2018-01-01") > 0)) {
187 if (!stmt_select->NextResultRow()) {
188 cout << "ERROR: There is no second row for parameter '" << strParameterName << "' for " << strSystemName
189 << " detector" << endl;
190 delete stmt_select;
191 return -8;
192 }
193 }
194
195 int parameter_id = stmt_select->GetInt(0);
196 TString table_name(stmt_select->GetString(1));
197 if (IsOldMySQL)
198 table_name = TString::Format("att_%s", table_name.Data());
199 if (iVerbose)
200 cout << "Found Data Table name = " << table_name << ". Parameter ID = " << parameter_id << endl;
201 delete stmt_select;
202
203 // parse parameter type. current support for att_array_devdouble, att_array_devboolean, att_scalar_devdouble
204 Tango_Parameter_Type par_type;
205 if (table_name.Contains("array_devdouble"))
206 par_type = Tango_Double_Array;
207 else {
208 if (table_name.Contains("array_devboolean"))
209 par_type = Tango_Bool_Array;
210 else {
211 if (table_name.Contains("scalar_devdouble"))
212 par_type = Tango_Double;
213 else {
214 cout << "ERROR: This Tango type is not supported: '" << table_name << "'" << endl;
215 return -9;
216 }
217 }
218 }
219
220 // getting data from the table found by the attribute type
221 TString query_data;
222 if (IsOldMySQL)
223 query_data = "SELECT date_format(data_time, '%Y-%m-%d %H:%i:%S'), value_r ";
224 else
225 query_data = "SELECT to_char(data_time, 'YYYY-MM-DD HH24:MI:SS.MS'), value_r ";
226
227 if (par_type > 10) // if the parameter is stored as array of values
228 query_data += ", dim_x_r, dim_x_w, idx ";
229
230 // add a new point with the previous value (<=date_start)
231 query_data += TString::Format("FROM %s "
232 "WHERE att_conf_id='%d' and ((data_time > '%s' and data_time <= '%s') "
233 "or (data_time = (SELECT max(data_time) FROM %s WHERE att_conf_id='%d' and data_time "
234 "<= '%s' and value_r is not null))) "
235 "and value_r is not null ",
236 table_name.Data(), parameter_id, start_date_new.Data(), end_date_new.Data(),
237 table_name.Data(), parameter_id, start_date_new.Data());
238
239 if (par_type > 10) // if the parameter is stored as array of values
240 query_data += "ORDER BY data_time,idx";
241 else
242 query_data += "ORDER BY data_time";
243
244 if (iVerbose)
245 cout << "Query data with the following SQL request:" << endl << query_data << endl;
246 stmt_select = db_server->Statement(query_data);
247 if (!stmt_select->Process()) {
248 cout << "ERROR: getting parameter values from Tango has been failed" << endl;
249 delete stmt_select;
250 return -10;
251 }
252
253 stmt_select->StoreResult();
254
255 Int_t cur_num = 0;
256 TangoTimeParameter* par = nullptr;
257 // create Tango data array and write data to it
258 arrTangoData = new TObjArray();
259 arrTangoData->SetName(
260 TString::Format("'%s' parameter for %s detector", strParameterName.Data(), strSystemName.Data()));
261 arrTangoData->SetOwner(kTRUE);
262 while (stmt_select->NextResultRow()) {
263 const char* pc_datetime = stmt_select->GetString(0);
264 TDatime datetime(pc_datetime);
265 // shift the previous time va;ue to the date_start position
266 if ((cur_num == 0) && (strcmp(pc_datetime, strStartDate) < 0))
267 datetime.Set(strStartDate);
268
269 int i_par_len = 1;
270 if (par_type > 10)
271 i_par_len = stmt_select->GetInt(2);
272 if (i_par_len == 0) {
273 cout << "ERROR: Parameter length cannot be equal 0" << endl;
274 delete stmt_select;
275 DeleteTangoParameter();
276 return -11;
277 }
278
279 int i_real_par_len = 1;
280 if (par_type > 10)
281 i_real_par_len = stmt_select->GetInt(3);
282 if (i_real_par_len == 0) {
283 cout << "ERROR: Real parameter length cannot be equal 0" << endl;
284 delete stmt_select;
285 DeleteTangoParameter();
286 return -12;
287 }
288
289 par = new TangoTimeParameter(datetime, par_type);
290 // cout<<par.parameter_time.AsString()<<endl;
291 for (int ind = 0; ind < i_par_len; ind++) {
292 if (ind > 0)
293 stmt_select->NextResultRow();
294
295 int i_idx = 0;
296 if (par_type > 10)
297 i_idx = stmt_select->GetInt(4);
298 // cout<<"idx:ind - "<<idx<<":"<<ind<<endl;
299 if (i_idx != ind) {
300 cout << "ERROR: idx should be equal index of the parameter array" << endl;
301 delete stmt_select;
302 DeleteTangoParameter();
303 return -13;
304 }
305
306 if (ind >= i_real_par_len)
307 continue;
308
309 if ((par_type == Tango_Bool_Array) || (par_type == Tango_Bool)) {
310 bool b_val = (bool)stmt_select->GetInt(1);
311 par->bool_parameter_value.push_back(b_val);
312 par->double_parameter_value.push_back(b_val);
313 // cout<<par.bool_parameter_value[par.bool_parameter_value.size()-1]<<endl;
314 } else {
315 double d_val = stmt_select->GetDouble(1);
316 par->double_parameter_value.push_back(d_val);
317 // cout<<par.double_parameter_value[par.double_parameter_value.size()-1]<<endl;
318 }
319 }
320 if (iVerbose)
321 cout << "Boolean parameter value size = " << par->bool_parameter_value.size() << endl;
322 if (iVerbose)
323 cout << "Double parameter value size = " << par->double_parameter_value.size() << endl;
324
325 arrTangoData->Add(par);
326 cur_num++;
327 }
328 delete stmt_select;
329
330 // add date_end point (if not exists) equal to the the previous value
331 if ((par != nullptr) && (strcmp(par->parameter_time.AsSQLString(), strEndDate.Data()) < 0)) {
332 TangoTimeParameter* par_last = new TangoTimeParameter(*par);
333 par_last->parameter_time.Set(strEndDate);
334 arrTangoData->Add(par_last);
335 }
336
337 return 0;
338}
339
340// Function displays hardware data obtained from Tango, e.g. ZDC voltage in time interval, in console
342{
343 if (arrTangoData == nullptr) {
344 cout << "ERROR: Tango parameter has not been obtained" << endl;
345 return;
346 }
347
348 int def_precision = cout.precision();
349 cout.precision(17);
350
351 int par_length = 0;
352 for (int i = 0; i < arrTangoData->GetEntriesFast(); i++) {
353 TangoTimeParameter* pParameter = (TangoTimeParameter*)arrTangoData->At(i);
354 cout << pParameter->parameter_time.AsSQLString() << endl;
355
356 // cout<<TD->dataArray[i].parameter_length<<endl;
357 par_length = pParameter->double_parameter_value.size();
358 for (int j = 0; j < par_length; j++)
359 cout << pParameter->double_parameter_value[j] << " ";
360 cout << "" << endl << endl;
361 }
362
363 cout.precision(def_precision);
364 return;
365}
366
367// Function displays a set of "simple" parameters obtained from Tango, e.g. GEMs high voltages voltage, in console
368void TangoData::PrintTangoArrayConsole(vector<TangoData*> vecTangoData)
369{
370 for (const auto& tango_data : vecTangoData) {
371 cout << "The current parameter: " << tango_data->GetFullName() << endl;
372 tango_data->PrintTangoDataConsole();
373 }
374}
375
376// Function displays hardware vector data obtained from Tango, e.g. ZDC voltage in time interval, graphically as 2D
377// Surface Graph Parameter: y_axis - label of Y axis
378void TangoData::PrintTangoDataSurface(const char* y_axis)
379{
380 if (arrTangoData == nullptr) {
381 cout << "ERROR: Tango parameter has not been obtained" << endl;
382 return;
383 }
384
385 TCanvas* c1 = new TCanvas("c1", "Tango Data", 800, 600);
386 TGraph2D* tango_graph = new TGraph2D();
387 tango_graph->SetTitle(arrTangoData->GetName());
388
389 int par_length = 0;
390 for (int i = 0; i < arrTangoData->GetEntriesFast(); i++) {
391 TangoTimeParameter* pParameter = (TangoTimeParameter*)arrTangoData->At(i);
392
393 par_length = pParameter->double_parameter_value.size();
394 // cout<<"Parameter length = "<<par_length<<endl;
395 for (int j = 0; j < par_length; j++) {
396 int cur_time = pParameter->parameter_time.Convert();
397 double value = pParameter->double_parameter_value[j];
398 // cout<<x<<" "<<y<<" "<<z<<endl;
399 tango_graph->SetPoint(i * par_length + j, cur_time, j + 1, value);
400 }
401 }
402
403 tango_graph->Draw("SURF1");
404 gPad->Update();
405
406 tango_graph->GetXaxis()->SetTitle("time");
407 tango_graph->GetXaxis()->CenterTitle();
408 tango_graph->GetXaxis()->SetTitleOffset(1.9);
409 tango_graph->GetXaxis()->SetLabelSize(0.025);
410 tango_graph->GetXaxis()->SetLabelOffset(0.009);
411 tango_graph->GetXaxis()->SetNdivisions(-503);
412
413 tango_graph->GetYaxis()->SetTitle(y_axis);
414 tango_graph->GetYaxis()->CenterTitle();
415 tango_graph->GetYaxis()->SetTitleOffset(1.9);
416 tango_graph->GetYaxis()->SetLabelSize(0.025);
417 tango_graph->GetYaxis()->SetLabelOffset(0.001);
418 tango_graph->GetYaxis()->CenterLabels();
419 tango_graph->GetYaxis()->SetNdivisions(par_length + 1, 0, 0);
420
421 tango_graph->GetZaxis()->SetLabelSize(0.025);
422
423 // form X-axis with time ticks
424 tango_graph->GetXaxis()->SetTimeDisplay(1);
425 tango_graph->GetXaxis()->SetTimeFormat("%Y.%m.%d %H:%M");
426 tango_graph->GetXaxis()->SetTimeOffset(0, "local");
427
428 c1->Modified();
429
430 return;
431}
432
433// Function PrintTangoDataMulti3D display hardware vector data obtained from Tango, e.g. ZDC voltage in time interval,
434// graphically as a set of Line Graphs Parameter: tango_data - TObjArray with TangoTimeParameter objects obtained from
435// 'GetTangoParameter' function
436int TangoData::PrintTangoDataMultiGraph(const char* y_axis, bool is3D)
437{
438 if (arrTangoData == nullptr) {
439 cout << "ERROR: Tango parameter has not been obtained" << endl;
440 return -1;
441 }
442
443 if (arrTangoData->GetEntries() < 1) {
444 cout << "WARNING: There are no elements in the Tango array" << endl;
445 return -2;
446 }
447
448 TCanvas* c1 = new TCanvas("c1", "Tango Data", 800, 600);
449
450 // cout<<"Tango data array size = "<<arrTangoData->GetEntries()<<endl;
451 int par_length = ((TangoTimeParameter*)arrTangoData->At(0))->double_parameter_value.size();
452 // cout<<"par_length = "<<par_length<<endl;
453 TGraph* tango_graphs = new TGraph[par_length]();
454 gRandom->SetSeed();
455 for (int j = 0; j < par_length; j++) {
456 Int_t color = gRandom->Integer(50);
457 if ((color == 0) || (color == 10) || ((color > 16) && (color < 20)))
458 color += 20;
459 tango_graphs[j].SetLineColor(color);
460 }
461
462 for (int i = 0; i < arrTangoData->GetEntriesFast(); i++) {
463 TangoTimeParameter* pParameter = (TangoTimeParameter*)arrTangoData->At(i);
464 par_length = pParameter->double_parameter_value.size();
465 for (int j = 0; j < par_length; j++) {
466 int cur_time = pParameter->parameter_time.Convert();
467 double value = pParameter->double_parameter_value[j];
468 tango_graphs[j].SetPoint(i, cur_time, value);
469 }
470 }
471
472 TMultiGraph* tango_multi = new TMultiGraph();
473 tango_multi->SetTitle(arrTangoData->GetName());
474 for (int j = 0; j < par_length; j++) {
475 tango_multi->Add(&tango_graphs[j]);
476 tango_graphs[j].SetTitle(TString::Format("%d", j));
477 tango_graphs[j].SetLineWidth(3);
478 }
479
480 TString draw_par = "AL";
481 if (is3D)
482 draw_par += "3D";
483 tango_multi->Draw(draw_par.Data());
484 gPad->Update();
485
486 if (!is3D) {
487 tango_multi->GetXaxis()->SetTitle("time");
488 tango_multi->GetXaxis()->CenterTitle();
489 tango_multi->GetXaxis()->SetTitleOffset(1.3);
490 tango_multi->GetXaxis()->SetLabelSize(0.025);
491 tango_multi->GetXaxis()->SetLabelOffset(0.009);
492 tango_multi->GetXaxis()->SetNdivisions(-503);
493 // form X-axis with time ticks
494 tango_multi->GetXaxis()->SetTimeDisplay(1);
495 tango_multi->GetXaxis()->SetTimeFormat("%Y.%m.%d %H:%M");
496 tango_multi->GetXaxis()->SetTimeOffset(0, "local");
497
498 tango_multi->GetYaxis()->SetTitle(y_axis);
499 tango_multi->GetYaxis()->CenterTitle();
500 tango_multi->GetYaxis()->SetTitleOffset(1.3);
501 tango_multi->GetYaxis()->SetLabelSize(0.025);
502 tango_multi->GetYaxis()->SetLabelOffset(0.001);
503 tango_multi->GetYaxis()->CenterLabels();
504 // gr->GetYaxis()->SetNdivisions(10, 0, 0);
505 }
506
507 TLegend* pLegend = c1->BuildLegend(0.92, 0.77, 0.99, 0.98, "");
508 pLegend->SetMargin(0.80);
509
510 c1->Modified();
511 return 0;
512}
513
514// Function displays a set of "simple" parameters obtained from Tango, e.g. GEMs high voltages voltage, graphically as a
515// set of Line Graphs
516int TangoData::PrintTangoArrayMultiGraph(vector<TangoData*> vecTangoData, const char* y_axis, bool is3D)
517{
518 if (vecTangoData.size() < 1) {
519 cout << "WARNING: There are no parameters in the specified array" << endl;
520 return -1;
521 }
522
523 // cout<<"Tango data array size = "<<vecTangoData.size()<<endl;
524 int par_length = vecTangoData.size();
525 // cout<<"par_length = "<<par_length<<endl;
526
527 TCanvas* c1 = new TCanvas("c1", "Tango Data", 800, 600);
528 TGraph* tango_graphs = new TGraph[par_length]();
529 gRandom->SetSeed();
530 int j;
531 for (j = 0; j < par_length; j++) {
532 Int_t color = gRandom->Integer(50);
533 if ((color == 0) || (color == 10) || ((color > 16) && (color < 20)))
534 color += 20;
535 tango_graphs[j].SetLineColor(color);
536 }
537
538 j = 0;
539 for (const auto& current_parameter : vecTangoData) {
540 if (current_parameter->GetTangoData()->IsEmpty()) {
541 cout << "ERROR: There are no elements in the parameter (" << current_parameter->GetFullName() << ")"
542 << endl;
543 return -2;
544 }
545
546 if ((((TangoTimeParameter*)current_parameter->GetTangoData()->At(0))->double_parameter_value.size()) != 1) {
547 cout << "ERROR: the parameter " << current_parameter->GetFullName() << " must have single value" << endl;
548 return -3;
549 }
550
551 TObjArray* arrTangoData = current_parameter->GetTangoData();
552 for (int i = 0; i < arrTangoData->GetEntriesFast(); i++) {
553 int cur_time = ((TangoTimeParameter*)arrTangoData->At(i))->parameter_time.Convert();
554 double value = ((TangoTimeParameter*)arrTangoData->At(i))->double_parameter_value[0];
555 tango_graphs[j].SetPoint(i, cur_time, value);
556 }
557 j++;
558 }
559
560 TMultiGraph* tango_multi = new TMultiGraph();
561 tango_multi->SetTitle(vecTangoData[0]->GetFullName());
562 for (j = 0; j < par_length; j++) {
563 tango_multi->Add(&tango_graphs[j]);
564 tango_graphs[j].SetTitle(TString::Format("%d", j));
565 tango_graphs[j].SetLineWidth(3);
566 }
567
568 TString draw_par = "AL";
569 if (is3D)
570 draw_par += "3D";
571 tango_multi->Draw(draw_par.Data());
572 gPad->Update();
573
574 if (!is3D) {
575 tango_multi->GetXaxis()->SetTitle("time");
576 tango_multi->GetXaxis()->CenterTitle();
577 tango_multi->GetXaxis()->SetTitleOffset(1.3);
578 tango_multi->GetXaxis()->SetLabelSize(0.025);
579 tango_multi->GetXaxis()->SetLabelOffset(0.009);
580 tango_multi->GetXaxis()->SetNdivisions(-503);
581 // form X-axis with time ticks
582 tango_multi->GetXaxis()->SetTimeDisplay(1);
583 tango_multi->GetXaxis()->SetTimeFormat("%Y.%m.%d %H:%M");
584 tango_multi->GetXaxis()->SetTimeOffset(0, "local");
585
586 tango_multi->GetYaxis()->SetTitle(y_axis);
587 tango_multi->GetYaxis()->CenterTitle();
588 tango_multi->GetYaxis()->SetTitleOffset(1.3);
589 tango_multi->GetYaxis()->SetLabelSize(0.025);
590 tango_multi->GetYaxis()->SetLabelOffset(0.001);
591 tango_multi->GetYaxis()->CenterLabels();
592 // gr->GetYaxis()->SetNdivisions(10, 0, 0);
593 }
594
595 TLegend* pLegend = c1->BuildLegend(0.92, 0.77, 0.99, 0.98, "");
596 pLegend->SetMargin(0.80);
597
598 c1->Modified();
599 return 0;
600}
601
602// Function calculates and returns average value for Tango data array (result vector with size > 1 is used in case of
603// many channels)
605{
606 vector<double> result;
607 if (arrTangoData == nullptr) {
608 cout << "ERROR: Tango parameter has not been obtained" << endl;
609 return result;
610 }
611
612 if (iVerbose)
613 cout << "strStartDateAvg = " << strStartDate.Data() << endl;
614 if (iVerbose)
615 cout << "strEndDateAvg = " << strEndDate.Data() << endl;
616 int time_count = arrTangoData->GetEntriesFast();
617 TDatime start_date(strStartDate), end_date(strEndDate);
618
619 // get arithmetic average value
620 if ((IsOldMySQL) || (time_count < 2)) {
621 for (int i = 0; i < time_count; i++) {
622 TangoTimeParameter* pParameter = (TangoTimeParameter*)arrTangoData->At(i);
623 // cycle for Tango parameter array (from 1 to array size)
624 for (size_t j = 0; j < pParameter->double_parameter_value.size(); j++) {
625 if (i == 0)
626 result.push_back(pParameter->double_parameter_value[j]);
627 else
628 result[j] += pParameter->double_parameter_value[j];
629 }
630 }
631
632 for (size_t j = 0; j < result.size(); j++)
633 result[j] /= time_count;
634 }
635 // get interval average value (for the new architecture of the Tango database)
636 else
637 {
638 TDatime previousTime;
639 TangoTimeParameter* pParameter;
640 for (int i = 0; i < time_count; previousTime = pParameter->parameter_time, i++) {
641 pParameter = (TangoTimeParameter*)arrTangoData->At(i);
642
643 if (i == 0) {
644 if (start_date < pParameter->parameter_time) {
645 UInt_t sec = pParameter->parameter_time.Convert() - start_date.Convert();
646 // cycle for Tango parameter array (from 1 to array size)
647 for (size_t j = 0; j < pParameter->double_parameter_value.size(); j++)
648 result.push_back(pParameter->double_parameter_value[j] * sec);
649 }
650 continue;
651 }
652
653 UInt_t sec = pParameter->parameter_time.Convert() - previousTime.Convert();
654 // cycle for Tango parameter array (from 1 to array size)
655 for (size_t j = 0; j < pParameter->double_parameter_value.size(); j++) {
656 if (result.empty())
657 result.push_back(pParameter->double_parameter_value[j] * sec);
658 else
659 result[j] += pParameter->double_parameter_value[j] * sec;
660 }
661
662 } // for (int i = 0; i < time_count; previousTime = pParameter->parameter_time, i++)
663
664 if (end_date > pParameter->parameter_time) {
665 UInt_t sec = end_date.Convert() - pParameter->parameter_time.Convert();
666 // cycle for Tango parameter array (from 1 to array size)
667 for (size_t j = 0; j < pParameter->double_parameter_value.size(); j++)
668 result[j] += pParameter->double_parameter_value[j] * sec;
669 }
670
671 UInt_t sec = end_date.Convert() - start_date.Convert();
672 for (size_t j = 0; j < result.size(); j++)
673 result[j] /= sec;
674 } // else - get interval average value (for the new architecture of the Tango database)
675
676 return result;
677}
678
689TObjArray* TangoData::SearchTangoIntervals(enumConditions condition, bool value, vector<int>* mapChannel)
690{
691 if (arrTangoData == nullptr) {
692 cout << "ERROR: Tango parameter has not been obtained" << endl;
693 return nullptr;
694 }
695
696 TObjArray* pTimeIntervals = new TObjArray();
697 pTimeIntervals->SetOwner(kTRUE);
698
699 // if there is no points in the Tango period then return empty common TObjArray (without any elements)
700 if (arrTangoData->GetEntriesFast() == 0) {
701 delete arrTangoData;
702 return pTimeIntervals;
703 }
704
705 // cycle for all Tango Data Array
706 vector<int>
707 vecStart; // vector with start indices of the found intervals [size = parameter array size if it is array]
708 vector<bool> vecCondition; // vector with flags indicating whether the current interval satisfies the condition
709 // [size = parameter array size if it is array]
710 TangoTimeParameter* pParameter = nullptr;
711 // cout<<"arrTangoData->GetEntriesFast(): "<<arrTangoData->GetEntriesFast()<<endl;
712 for (int i = 0; i < arrTangoData->GetEntriesFast(); i++) {
713 pParameter = (TangoTimeParameter*)arrTangoData->At(i);
714 // initialization of the vectors (vecCondition = false, vecStart = 0)
715 if (i == 0) {
716 for (size_t j = 0; j < pParameter->bool_parameter_value.size(); j++) {
717 vecCondition.push_back(false);
718 vecStart.push_back(0);
719
720 TObjArray* pChannel = new TObjArray();
721 pChannel->SetOwner(kTRUE);
722 pTimeIntervals->Add(pChannel);
723 }
724 }
725
726 // cycle for array parameter data (if the parameter is an array) and checking the given condition
727 for (size_t j = 0; j < pParameter->bool_parameter_value.size(); j++) {
728 bool isCondition;
729 switch (condition) {
730 case conditionLess:
731 isCondition = pParameter->bool_parameter_value[j] < value;
732 break;
734 isCondition = pParameter->bool_parameter_value[j] <= value;
735 break;
736 case conditionEqual:
737 isCondition = pParameter->bool_parameter_value[j] == value;
738 break;
740 isCondition = pParameter->bool_parameter_value[j] != value;
741 break;
742 case conditionGreater:
743 isCondition = pParameter->bool_parameter_value[j] > value;
744 break;
746 isCondition = pParameter->bool_parameter_value[j] >= value;
747 break;
748 default: {
749 cout << "ERROR: comparison operator in the searching of intervals is not appropriable for boolean "
750 "type"
751 << endl;
752 delete arrTangoData;
753 delete pTimeIntervals;
754 return nullptr;
755 }
756 }
757
758 // if found then set start index in vecStart and set vecCondition to TRUE
759 if (isCondition) {
760 // save start interval
761 if (!vecCondition[j]) {
762 vecCondition[j] = true;
763 vecStart[j] = i;
764 // cout<<"vecCondition "<<j<<": true"<<endl<<"Start: "<<i<<endl<<endl;
765 }
766 }
767 // if the conidition is not satisfied
768 else
769 {
770 // finally write interval if vecCondition == TRUE
771 if (vecCondition[j]) {
772 vecCondition[j] = false; // reset condition flag (found interval has ended)
773
774 int start_i = vecStart[j];
775 TDatime startInterval = ((TangoTimeParameter*)arrTangoData->At(start_i))->parameter_time;
776 if ((start_i > 0) && (IsOldMySQL)) {
777 TDatime previousTime = ((TangoTimeParameter*)arrTangoData->At(start_i - 1))->parameter_time;
778 TDatime middleTime((startInterval.Convert() + previousTime.Convert()) / 2);
779 startInterval = middleTime;
780 }
781 UInt_t uiEndTime = ((TangoTimeParameter*)arrTangoData->At(i))->parameter_time.Convert();
782 TDatime endInterval(uiEndTime - 1);
783 if (IsOldMySQL)
784 endInterval.Set(
785 (uiEndTime + ((TangoTimeParameter*)arrTangoData->At(i - 1))->parameter_time.Convert()) / 2);
786
787 // create TangoTimeInterval for the satisfied condition
788 TangoTimeInterval* pTimeInterval = new TangoTimeInterval(startInterval, endInterval);
789 int real_channel = j;
790 if (mapChannel != nullptr) {
791 if (mapChannel->size() > j) {
792 real_channel = mapChannel->at(j);
793 if (pTimeIntervals->GetEntriesFast() <= real_channel) {
794 cout << "CRITICAL WARNING: Tango array size is less than the corrected channel: "
795 << real_channel << endl;
796 continue;
797 }
798 } else
799 cout << "CRITICAL WARNING: map channel size is less than the current channel: " << j
800 << endl;
801 }
802 // cout<<"j = "<<j<<", real_channel = "<<real_channel<<", mapChannel->size() =
803 // "<<mapChannel->size()<<", pTimeIntervals->GetEntriesFast() =
804 // "<<pTimeIntervals->GetEntriesFast()<<endl;
805 ((TObjArray*)pTimeIntervals->At(real_channel))->Add(pTimeInterval);
806 }
807 }
808 } // for (int j = 0; j < pParameter->bool_parameter_value.size(); j++)
809 } // for (int i = 0; i < arrTangoData->GetEntriesFast(); i++)
810
811 // write the last period if neccessary
812 if (IsOldMySQL) {
813 for (size_t j = 0; j < pParameter->bool_parameter_value.size(); j++) {
814 if (vecCondition[j]) {
815 vecCondition[j] = false;
816
817 int start_i = vecStart[j];
818 TDatime startInterval = ((TangoTimeParameter*)arrTangoData->At(start_i))->parameter_time;
819 if (start_i > 0) {
820 TDatime previousTime = ((TangoTimeParameter*)arrTangoData->At(start_i - 1))->parameter_time;
821 TDatime middleTime((startInterval.Convert() + previousTime.Convert()) / 2);
822 startInterval = middleTime;
823 }
824 TDatime endInterval =
825 ((TangoTimeParameter*)arrTangoData->At(arrTangoData->GetEntriesFast() - 1))->parameter_time;
826
827 TangoTimeInterval* pTimeInterval = new TangoTimeInterval(startInterval, endInterval);
828 int real_channel = j;
829 if (mapChannel != nullptr) {
830 if (mapChannel->size() > j) {
831 real_channel = mapChannel->at(j);
832 if (pTimeIntervals->GetEntriesFast() <= real_channel) {
833 cout << "CRITICAL WARNING: Tango array size is less than the corrected channel: "
834 << real_channel << endl;
835 continue;
836 }
837 } else
838 cout << "CRITICAL WARNING: map channel size is less than the current channel: " << j << endl;
839 }
840 // cout<<"j = "<<j<<", real_channel = "<<real_channel<<", mapChannel->size() = "<<mapChannel->size()<<",
841 // pTimeIntervals->GetEntriesFast() = "<<pTimeIntervals->GetEntriesFast()<<endl;
842 ((TObjArray*)pTimeIntervals->At(real_channel))->Add(pTimeInterval);
843 }
844 } // write the last period if neccessary
845 }
846
847 return pTimeIntervals;
848}
849
856void TangoData::PrintTangoIntervalConsole(TObjArray* tango_intervals, TString channel_name, bool isShowOnlyExists)
857{
858 for (int i = 0; i < tango_intervals->GetEntriesFast(); i++) {
859 TObjArray* pChannel = (TObjArray*)tango_intervals->At(i);
860 if (pChannel->GetEntriesFast() == 0) {
861 if (!isShowOnlyExists)
862 cout << channel_name.Data() << " " << i << ":" << endl
863 << " No intervals correspond to the specified conditions" << endl;
864 continue;
865 } else
866 cout << channel_name.Data() << " " << i << ":" << endl;
867 for (int j = 0; j < pChannel->GetEntriesFast(); j++) {
868 TangoTimeInterval* pInterval = (TangoTimeInterval*)pChannel->At(j);
869 cout << " " << pInterval->start_time.AsSQLString();
870 cout << " - ";
871 cout << pInterval->end_time.AsSQLString();
872 }
873 cout << endl;
874 }
875
876 return;
877}
878
879// delete Tango parameter
880void TangoData::DeleteTangoParameter()
881{
882 IsOldMySQL = false;
883 strSystemName = "", strParameterName = "", strStartDate = "", strEndDate = "";
884 if (arrTangoData != nullptr) {
885 arrTangoData->Delete();
886 delete arrTangoData;
887 arrTangoData = nullptr;
888 }
889}
Bool_t Add(const vector< Double_t > &a, const vector< Double_t > &b, vector< Double_t > &c)
int i
Definition P4_F32vec4.h:22
const char *const TANGO_DB_USERNAME_b2020
Definition TangoData.cxx:23
const char *const TANGO_DB_NAME_b2020
Definition TangoData.cxx:26
const char *const TANGO_DB_PASSWORD_b2020
Definition TangoData.cxx:24
const char *const TANGO_DB_HOST_b2020
Definition TangoData.cxx:25
TSQLServer * GetSQLServer()
static TangoConnection * Open()
TString GetFullName()
std::vector< double > GetAverageTangoData()
static void PrintTangoArrayConsole(std::vector< TangoData * > vecTangoData)
TObjArray * SearchTangoIntervals(enumConditions condition=conditionEqual, bool value=true, std::vector< int > *mapChannel=nullptr)
void PrintTangoDataConsole()
@ conditionGreaterOrEqual
Definition TangoData.h:82
@ conditionGreater
Definition TangoData.h:81
@ conditionLess
Definition TangoData.h:77
@ conditionLessOrEqual
Definition TangoData.h:78
@ conditionNotEqual
Definition TangoData.h:80
@ conditionEqual
Definition TangoData.h:79
virtual ~TangoData()
Definition TangoData.cxx:94
void PrintTangoDataSurface(const char *y_axis="tango parameter")
static int PrintTangoArrayMultiGraph(std::vector< TangoData * > vecTangoData, const char *y_axis="parameter", bool is3D=false)
int PrintTangoDataMultiGraph(const char *y_axis="parameter", bool is3D=false)
TangoData(const char *start_date, const char *end_date, const char *system_name, const char *parameter_name, const char *member_name="", int verbose=0)
Definition TangoData.cxx:70
void PrintTangoIntervalConsole(TObjArray *tango_intervals, TString channel_name="Channel", bool isShowOnlyExists=false)
TDatime start_time
Definition TangoData.h:56
virtual ~TangoTimeInterval()
Definition TangoData.cxx:56
std::vector< bool > bool_parameter_value
Definition TangoData.h:37
Tango_Parameter_Type parameter_type
Definition TangoData.h:35
std::vector< double > double_parameter_value
Definition TangoData.h:38
TDatime parameter_time
Definition TangoData.h:33
virtual ~TangoTimeParameter()
Definition TangoData.cxx:46
Tango_Parameter_Type
Definition TangoData.h:22
Tango_Parameter_Type
Definition TangoData.h:22
@ Tango_Bool
Definition TangoData.h:23
@ Tango_Bool_Array
Definition TangoData.h:25
@ Tango_Double
Definition TangoData.h:24
@ Tango_Double_Array
Definition TangoData.h:26
STL namespace.