GSI Object Oriented Online Offline (Go4)  GO4-5.3.2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
TGo4DabcMonitor.cpp
Go to the documentation of this file.
1 // $Id: TGo4DabcMonitor.cpp 1483 2015-06-03 14:19:49Z linev $
2 //-----------------------------------------------------------------------
3 // The GSI Online Offline Object Oriented (Go4) Project
4 // Experiment Data Processing at EE department, GSI
5 //-----------------------------------------------------------------------
6 // Copyright (C) 2000- GSI Helmholtzzentrum für Schwerionenforschung GmbH
7 // Planckstr. 1, 64291 Darmstadt, Germany
8 // Contact: http://go4.gsi.de
9 //-----------------------------------------------------------------------
10 // This software can be used under the license agreements as stated
11 // in Go4License.txt file which is part of the distribution.
12 //-----------------------------------------------------------------------
13 
14 #include "TGo4DabcMonitor.h"
15 
16 #include "TGo4QSettings.h"
17 #include "TGo4BrowserProxy.h"
18 #include "TGo4Slot.h"
19 #include "TGo4LockGuard.h"
20 
21 #include <QDateTime>
22 #include <QtCore/QTimer>
23 
24 #include "TH1.h"
25 
26 #include <iostream>
27 
31 
33 {
34  fxOwner->infoUpdated(this);
35 }
36 
38 {
39  fxOwner->nodesUpdated(this);
40 }
41 
42 
44 {
45  fxOwner->servicesUpdated(this);
46 }
47 
49 {
50  fxOwner->stateUpdated(this);
51 }
52 
54 {
55  fxOwner->rateUpdated(this);
56 }
57 
63 
64 TGo4DabcMonitor::TGo4DabcMonitor( QWidget* parent, const char* name)
65  : QGo4Widget(parent,name)
66 {
67  setupUi(this);
68 
69 
70  strncpy(gNolinkStateRecord.status,"not available",16);
72  fxServerInfo = 0;
73  fxLastTimestamp = 0;
74  fbRebuildNodeTable=true;
75  fbDisplayNodeTable=false;
76  fbRebuildRateTable=true;
77  fbDisplayRateTable=false;
78 
79  fbTableBeingCreated=false;
80 
81 
82  NodeTable->setColumnCount(5);
83  //NodeTable->setLeftMargin(0);
84 
85  NodeTable->setColumnHidden( DABCMON_NODE_INDEXCOL, true) ;
86  NodeTable->setColumnWidth ( DABCMON_NODE_INDEXCOL, 1) ;
87 
88  //NodeTable->setColumnReadOnly (DABCMON_NODE_NODECOL,true );
89  //NodeTable->setColumnReadOnly (DABCMON_NODE_STATECOL,true );
90  //NodeTable->setColumnReadOnly (DABCMON_NODE_INDEXCOL,true );
91  NodeTable->setHorizontalHeaderItem(DABCMON_NODE_NODECOL, new QTableWidgetItem(tr( "Context" ) ));
92  NodeTable->setHorizontalHeaderItem(DABCMON_NODE_STATECOL, new QTableWidgetItem( tr( "State" ) ));
93  NodeTable->setHorizontalHeaderItem(DABCMON_NODE_CHECKCOL , new QTableWidgetItem( tr( "Ratemeters" ) ));
94  NodeTable->setHorizontalHeaderItem(DABCMON_NODE_LOGCOL, new QTableWidgetItem( tr( "Service list" ) ));
95 
96  RateTable->setColumnCount(5);
97  //RateTable->setLeftMargin(0);
98  RateTable->setColumnHidden( DABCMON_RATE_INDEXCOL, true) ;
99  RateTable->setColumnWidth ( DABCMON_RATE_INDEXCOL,1) ;
100  //RateTable->setColumnReadOnly (DABCMON_RATE_NAMECOL,true );
101  //RateTable->setColumnReadOnly (DABCMON_RATE_RATECOL,true );
102  //RateTable->setColumnReadOnly (DABCMON_RATE_INDEXCOL,true );
103  RateTable->setHorizontalHeaderItem(DABCMON_RATE_NAMECOL, new QTableWidgetItem(tr( "Name" ) ));
104  RateTable->setHorizontalHeaderItem(DABCMON_RATE_RATECOL, new QTableWidgetItem(tr( "Value" ) ));
105  RateTable->setHorizontalHeaderItem(DABCMON_RATE_TRENDCOL, new QTableWidgetItem(tr( "Trending" ) ));
106  RateTable->setHorizontalHeaderItem(DABCMON_RATE_STATSCOL, new QTableWidgetItem(tr( "Statistics" ) ));
107  FullPrintDIMButton->setDisabled(true);
108  dimServiceFilterEdit->setDisabled(true);
109 
110 
111 
112 
113  fxDabcNodes.clear();
114  fxServices.clear();
115  fxRates.clear();
116  fxStates.clear();
117  fxShowRateFlags.clear();
118  fxShowLogFlags.clear();
119  fxTrendingFlags.clear();
120  fbTrendingInit.clear();
121  fxStatsFlags.clear();
122  fbStatsInit.clear();
123  fxRateQueues.clear();
124  fxTrendHistoRefnames.clear();
125  fxStatHistoRefnames.clear();
126  fxStateRecords.clear();
127  fxRateRecords.clear();
128  fxRateSum.clear();
129  fxRateCount.clear();
130  fxDisplayTimer=new QTimer(this);
131  fxDisplayTimer->connect( fxDisplayTimer, SIGNAL(timeout()), this, SLOT(displayAll()) );
132  fxDisplayTimer->start(500); // ms period
133  fxAverageTimer=new QTimer(this);
134  fxAverageTimer->connect( fxAverageTimer, SIGNAL(timeout()), this, SLOT(displayAverageHistograms()));
135 
136 
137  fiTrendBins=100;
138  fiStatBins=100;
139  //TrendBinsBox->setValue(fiTrendBins);
140  fbTrendingForward=false;
141  fbHistogramming=false;
142  fbDisplayHistograms=false;
143 
144 
145  QString node=go4sett->getDabcMonitorNode();
146 
147  dimDnsNodeEdit->setText(node);
150  TrendBinsBox->setValue(fiTrendBins);
151  FrequencyBox->setValue(go4sett->getDabcMonitorFreq());
153 
154 
155  controlBox->setVisible(false);
156  //std::cout<<"found settings: node="<<node<<", bins="<<fiTrendBins<<", forward="<<fbTrendingForward <<std::endl;
157 
158  //ensurePolished();
159  //update();
160  //show();
161 }
162 
163 
165 {
166 }
167 
168 
172 
173 
174 
176 {
177  //std::cout<<"storeSettings" <<std::endl;
180  go4sett->setDabcMonitorFreq(FrequencyBox->value());
182 }
183 
184 
186 {
187  TGo4LockGuard gard;
188  //std::cout<<"refreshDIMSlot()" <<std::endl;
189  // first get list of dabc nodes from DIM server
190  fxDnsNode = dimDnsNodeEdit->text().trimmed();
191  if(fxDnsNode.isEmpty()) return; // avoid crash of DIM with fatal error ;-)
192  DimClient::setDnsNode(fxDnsNode.toLatin1().constData());
193  if (fxServerInfo!=0) {
194  delete fxServerInfo;
195  fxServerInfo = 0;
196  }
197 
198  FullPrintDIMButton->setDisabled(true);
199  dimServiceFilterEdit->setDisabled(true);
200  fxServerInfo = new TGo4DabcNodesInfo("DIS_DNS/SERVER_LIST",0,"Name server not available", this);
201  storeSettings();
202 }
203 
204 
206 {
207  TGo4LockGuard gard;
208  //std::cout<<"logDIMSlot()" <<std::endl;
209  for(int nix=0; nix<fxDabcNodes.size(); ++nix)
210  {
211  if(fxShowLogFlags[nix] )
212  {
213  // std::cout<<std::endl<< "retrieving current DIM variables from node "<<fxDabcNodes[nix]<<" ..." <<std::endl;
214  createLogServices(nix);
215  }
216  }
217 }
218 
219 
221 {
222  TGo4LockGuard gard;
223  //std::cout <<"---------------- histogramCheckToggled to "<<val<< std::endl;
224  fbHistogramming=val;
225  // better: reset all existing init flags of services!
226  if(val)
227  {
228  for(int nodeix=0;nodeix<fbTrendingInit.size();++nodeix) // dim node index
229  {
230  std::vector <std::vector <bool> > & nodevec=fbTrendingInit[nodeix];
231  for(int rateix=0; rateix<nodevec.size();++rateix) // raterecord index
232  {
233  std::vector <bool> & hisvec= nodevec[rateix];
234  for (int hisix=0; hisix<hisvec.size();++hisix) // histogram index
235  {
236  hisvec[hisix]=val;
237  }
238  }
239  }
240  for(int nodeix=0;nodeix<fbStatsInit.size();++nodeix)
241  {
242  std::vector <std::vector <bool> > & nodevec=fbStatsInit[nodeix];
243  for(int rateix=0; rateix<nodevec.size();++rateix)
244  {
245  std::vector <bool> & hisvec= nodevec[rateix];
246  for (int hisix=0; hisix<hisvec.size();++hisix)
247  {
248  hisvec[hisix]=val;
249  }
250  }
251  }
252  } // if val
253  // reset average counters:
254  for (int nodeix=0;nodeix<fxRateSum.size();++nodeix)
255  {
256  std::vector<float> & nodevec=fxRateSum[nodeix];
257  for(int rateix=0; rateix<nodevec.size();++rateix)
258  {
259  nodevec[rateix]=0;
260  }
261  }
262  for(int nodeix=0;nodeix<fxRateCount.size();++nodeix)
263  {
264  std::vector<unsigned int> & nodevec=fxRateCount[nodeix];
265  for(int rateix=0; rateix<nodevec.size();++rateix)
266  {
267  nodevec[rateix]=0;
268  }
269  }
270  TrendBinsBox->setDisabled(val);
271  storeSettings();
272 }
273 
274 
276 {
277  //std::cout <<"---------------- averageCheckToggled to "<<val<< std::endl;
278  FrequencyBox->setDisabled(val);
279  if(val)
280  {
281  //std::cout <<"---------------- start timer here"<< std::endl;
282  float milsecs=1000*FrequencyBox->value();
283  fxAverageTimer->start(milsecs);
284 
285  }
286  else
287  {
288  //std::cout <<"---------------- stop timer here"<< std::endl;
289  fxAverageTimer->stop();
290  }
291  storeSettings();
292 }
293 
294 
296 {
297  //std::cout <<"---------------- binsizeChanged to "<<val<< std::endl;
298  fiTrendBins=val;
299  fiStatBins=val;
300  //storeSettings();
301 }
302 
303 
304 
305 
306 
307 void TGo4DabcMonitor::nodeTableChangedSlot( int row, int column )
308 {
309  TGo4LockGuard gard;
310  if(fbTableBeingCreated) return;
311  //std::cout<<"nodeTableChangedSlot for " << row<<","<<column <<std::endl;
312  // get index from table:
313  QString ixtext;
314  if (NodeTable->item(row, DABCMON_NODE_INDEXCOL))
315  ixtext = NodeTable->item(row, DABCMON_NODE_INDEXCOL)->text();
316  int ix=ixtext.toInt();
317  //std::cout<<"nodeTableChangedSlot for row:"<<row<<" index: " << ix<<", ixtext:"<<ixtext.toLatin1().constData() <<std::endl;
318  if(column==DABCMON_NODE_CHECKCOL)
319  {
320  // get value from table:
321  bool on=false;
322  QTableWidgetItem* checkitem = NodeTable->item(row, DABCMON_NODE_CHECKCOL);
323  if(checkitem)
324  on = (checkitem->checkState() == Qt::Checked);
325  else
326  std::cout<<"!!!!!!!!!! NEVER COME HERE: wrong rate checktableitem at tablerow "<<row <<std::endl;
327 
328  // set value to vector
329  fxShowRateFlags[ix]=on;
330  // now create/delete rate services for this node:
331  if(on)
332  createRateServices(ix);
333  else
334  deleteRateServices(ix);
335  }
336  else if (column==DABCMON_NODE_LOGCOL)
337  {
338  QTableWidgetItem* checkitem = NodeTable->item(row, DABCMON_NODE_LOGCOL);
339  bool on=false;
340  if(checkitem)
341  on = (checkitem->checkState() == Qt::Checked);
342  else
343  std::cout<<"!!!!!!!!!! NEVER COME HERE: wrong log checktableitem at tablerow "<<row <<std::endl;
344  // set value to vector
345  fxShowLogFlags[ix]=on;
346  // switch filter and log buttons:
347  bool disablebutton=true;
348  for(int t=0;t<fxShowLogFlags.size();++t)
349  {
350  if(fxShowLogFlags[t])
351  {
352  disablebutton=false;
353  break;
354  }
355  }
356  FullPrintDIMButton->setDisabled(disablebutton);
357  dimServiceFilterEdit->setDisabled(disablebutton);
358 
359  }
360 }
361 
362 
363 void TGo4DabcMonitor::rateTableChangedSlot(int row, int column)
364 {
365  TGo4LockGuard gard;
366  if(fbTableBeingCreated) return;
367  //std::cout<<"rateTableChangedSlot for " << row<<","<<column <<std::endl;
368  if(column==DABCMON_RATE_TRENDCOL)
369  {
370  // get value from table:
371  bool on=false;
372  QTableWidgetItem* checkitem= RateTable->item(row, DABCMON_RATE_TRENDCOL);
373  if(checkitem)
374  on = (checkitem->checkState() == Qt::Checked);
375  else
376  std::cout<<"!!!!!!!!!! NEVER COME HERE: wrong checktableitem at tablerow "<<row <<std::endl;
377  // get index from table:
378  int nix=0;
379  int rix=0;
380  if(!getRateIndices(row, nix, rix))
381  std::cout<<"!!!!!!!!!! NEVER COME HERE: get RateIndices could not get indices for row "<<row <<std::endl;
382  fxTrendingFlags[nix].at(rix)=on;
383  //std::cout<<" rrrrrrrrrrrr set fxTrendingFlags["<<nix<<"]["<<rix<<"] to" << on<<std::endl;
384  fbTrendingInit[nix].at(rix).at(0)=on; // sample trending init
385  fbTrendingInit[nix].at(rix).at(1)=on; // average trending init
386  }
387  else if(column==DABCMON_RATE_STATSCOL)
388  {
389  // get value from table:
390  bool on=false;
391  QTableWidgetItem* checkitem = RateTable->item(row, DABCMON_RATE_STATSCOL);
392  if(checkitem)
393  on = (checkitem->checkState() == Qt::Checked);
394  else
395  std::cout<<"!!!!!!!!!! NEVER COME HERE: wrong checktableitem at tablerow "<<row <<std::endl;
396  // get index from table:
397  int nix=0;
398  int rix=0;
399  if(!getRateIndices(row, nix, rix))
400  std::cout<<"!!!!!!!!!! NEVER COME HERE: get RateIndices could not get indices for row "<<row <<std::endl;
401  // set value to vector
402  fxStatsFlags[nix].at(rix)=on;
403  //std::cout<<" rrrrrrrrrrrr set fxStatsFlags["<<nix<<"]["<<rix<<"] to" << on<<std::endl;
404  fbStatsInit[nix].at(rix).at(0)=on; // direct sample
405  fbStatsInit[nix].at(rix).at(1)=on; // average
406  }
407 }
408 
412 
413 
415 {
416  // handle log printout of all services here:
417  TGo4LockGuard gard;
418  //std::cout<"iiiiiiiiiii infoUpdated() for " << info->getName() <<std::endl;
419  QDateTime timestamp;
420  timestamp.setTime_t (info->getTimestamp());
421  std::cout<<"DIM service " << info->getName() <<":"<<std::endl;
422  //" at "<<timestamp.toString()<<":" <<std::endl;
423  if(info->getServiceType()=="int")
424  std::cout<<" - "<< info->getInt();//<<std::endl;
425  else if (info->getServiceType()=="float")
426  std::cout<<" - "<< info->getFloat();//<<std::endl;
427  else if (info->getServiceType()=="double")
428  std::cout<<" - "<< info->getDouble();//<<std::endl;
429  else if (info->getServiceType()=="char")
430  std::cout<<" - "<< info->getString();//<<std::endl;
431  else
432  {
433  // service is structure, parse the format string:
434  char* ptr=(char*) info->getData();
435  int size=info->getSize();
436  QString format=info->getServiceType();
437  std::cout<<" - structure of format " << format.toLatin1().constData() <<std::endl;
438  QStringList elements = format.split(";",QString::SkipEmptyParts);
439  for ( QStringList::Iterator it = elements.begin(); it != elements.end(); ++it )
440  {
441  QString component=*it;
442  QString type=component.section(':',0,0);
443  QString slen=component.section(':',1,1);
444  int length=slen.toInt();
445  //std::cout<<" - found member:" <<type<<" of length "<<slen<<" (value="<<length<<")"<<std::endl;
446  QString content="";
447  QString prompt=" - "+type+" ("+slen+") \t>";
448  if(type=="C")
449  {
450  content=ptr;
451  content.truncate(length);
452  ptr+=length;
453  }
454  else if(type=="L")
455  {
456  int* cursor= (int*) ptr;
457  for(int t=0; t<length; ++t)
458  {
459  QString val;
460  content+= val.setNum(*cursor,10); // decimal base
461  cursor++;
462  }
463  ptr= (char*) cursor;
464  }
465  else if(type=="F")
466  {
467  float* cursor= (float*) ptr;
468  for(int t=0; t<length; ++t)
469  {
470  QString val;
471  content+= val.setNum( *cursor, 'g',5);
472  cursor++;
473  }
474  ptr= (char*) cursor;
475  }
476 
477  else
478  {
479  // treat unknown type as list of char values:
480  for(int t=0; t<length; ++t)
481  {
482  QString val;
483  content+= val.setNum(*ptr,10);
484  content+=":";
485  ptr++;
486  }
487  }// if(type==)
488  std::cout<<prompt.toLatin1().constData()<<content.toLatin1().constData() << "< "<<std::endl;;
489  int currentposition= (long) ptr - (long) info->getData();
490  if(currentposition > size)
491  {
492  std::cout<<" !!!!!!!!!!!!!!!! structure iterator exceeds service size "<<size <<std::endl;
493  break;
494  }
495  }// for ( QStringList::Iterator it
496  }// if(info->getType()=="int")
497  std::cout<<" - (timestamp:"<<timestamp.toString().toLatin1().constData()<<")" <<std::endl;
498  delete info; // discard service after first update!
499 }
500 
501 
503 {
504  TGo4LockGuard gard;
505  //std::cout<<"nodes Updated()" <<std::endl;
506  QString servers=info->getString();
507  fxNodelist = servers.split("|", QString::SkipEmptyParts);
508  refreshNodes();
509  fbDisplayNodeTable=true;
510  fbDisplayRateTable=true;
511 }
512 
514 {
515  TGo4LockGuard gard;
516  //std::cout<<"servicesUpdated() for " << info->getName() <<std::endl;
517  //first find out index of this service:
518  unsigned int index=-1;
519  for(unsigned int ix=0; ix<fxServices.size(); ++ix)
520  {
521  if(info==fxServices[ix])
522  {
523  index=ix;
524  break;
525  }
526  }
527  if(index<0)
528  {
529  std::cout<<"!!!!!!!!!!!servicesUpdated: unknown service info" << (int*) info<<std::endl;
530  }
531  else
532  {
533  if(index>fxStates.size() )
534  {
535  std::cout<<"!!!!!!!!!!!NEVER COME HERE: services updated out of bounds, index=" << index<<std::endl;
536  return;
537  }
538  QString services=info->getString();
539  //std::cout<<"+++ got service list: " << services.toLatin1().constData() <<std::endl;
540 
541  // find full name of nodestate in services:
542  QStringList servlist = services.split(0x0A, QString::SkipEmptyParts);
543  QString stateservice="";
544  for ( QStringList::Iterator sit = servlist.begin(); sit != servlist.end(); ++sit )
545  {
546  QString service=*sit;
547  //std::cout<<"++++++ scanning service" << service.toLatin1().constData() <<std::endl;
548  if(service.contains("RunStatus") || service.contains("Acquisition") )
549  {
550  stateservice=service.section('|',0,0); // strip additional service info from name
551  break;
552  }
553  } // for
554  // now create info for node's state:
555  if(!stateservice.isEmpty())
556  {
557  // check if we already have state info for index:
558  bool recreate=false;
559  if(fxStates[index]!=0)
560  {
561  //std::cout<<"found existing state service("<<index<<"): " << fxStates[index]->getName() <<std::endl;
562  if(stateservice==fxStates[index]->getName())
563  {
564  //std::cout<<"-------Name is the same, do nothing."<<std::endl;
565  recreate=false;
566  }
567  else
568  {
569  //std::cout<<"-------Name has changed, recreate service!"<<std::endl;
570  delete fxStates[index];
571  fxStates[index]=0;
572  recreate=true;
573  }
574 
575  }
576  else
577  {
578  //std::cout<<"------ Service not existing, create it!."<<std::endl;
579  recreate= true;
580  } // if(fxStates[index]!=0)
581 
582  if(recreate)
583  {
584  //std::cout<<"+++ creating state service: " << stateservice.toLatin1().constData() <<std::endl;
585  TGo4DabcStateInfo* sinfo= new TGo4DabcStateInfo(stateservice.toLatin1().constData(), 0, &gNolinkStateRecord, sizeof(dabc::StatusRec), this);
586  fxStates[index]=sinfo;
587  } //if recreate
588  } // if(!stateservice.isEmpty())
589  else
590  {
591  //std::cout<<"+++ empty state service for index " << index<<", ignored."<<std::endl;
592  //std::cout<<"+++ empty state service for index " << index<<", clear old entry" <<std::endl;
593  //delete fxStates[index];
594  //fxStates[index]=0;
595  //<- problematic if by some glitch state service is temporarily not found in service list!
596  } // if(!stateservice.isEmpty())
597  }//if(index<0)
598 }
599 
600 
602 {
603  TGo4LockGuard gard;
604  //std::cout<<"stateUpdated() for " << info->getName() <<std::endl;
605  // first find out index of this state:
606  unsigned int index=-1;
607  for(unsigned int ix=0; ix<fxStates.size(); ++ix)
608  {
609  if(info==fxStates[ix])
610  {
611  index=ix;
612  break;
613  }
614  }
615  //std::cout<<"- state index= " << index <<std::endl;
616  if(index<0)
617  {
618  std::cout<<"ERROR in stateUpdated(): object not in list, pointer " << (int*) info<<std::endl;
619  }
620  else
621  {
622  dabc::StatusRec* currentstate=(dabc::StatusRec*) info->getData();
623  if(index>fxStateRecords.size())
624  {
625  std::cout<<"!!!!!!!!!!!NEVER COME HERE: state updated out of bounds, index=" << index<<std::endl;
626  return;
627  }
628  fxStateRecords[index]=TGo4DabcState(currentstate);
629  fbDisplayNodeTable=true;
630  fxLastTimestamp=info->getTimestamp( );
631  }
632 }
633 
634 
636 {
637  TGo4LockGuard gard;
638  //std::cout<<"rateUpdated() for " << info->getName() <<std::endl;
639 
640  // first find out indexes for this rate info
641  unsigned int nodeindex=-1;
642  unsigned int rateindex=-1;
643  for(unsigned int ix=0; ix<fxRates.size(); ++ix)
644  {
645  std::vector<TGo4DabcRateInfo*> & rvec=fxRates[ix];
646  for(unsigned int rix=0;rix< rvec.size();++rix)
647  {
648 
649  if(info==rvec[rix])
650  {
651  nodeindex=ix;
652  rateindex=rix;
653  break;
654  }
655  } // for rix
656  }// for ix
657  //std::cout<<"- state index= " << index <<std::endl;
658  if(nodeindex<0)
659  {
660  std::cout<<"ERROR in rateUpdated(): object not in list, pointer " << (int*) info<<std::endl;
661  }
662  else
663  {
664  dabc::RateRec* currentrate=(dabc::RateRec*) info->getData();
665  if(nodeindex>fxRateRecords.size())
666  {
667  std::cout<<"!!!!!!!!!!!NEVER COME HERE: rate updated out of bounds, nodeindex=" << nodeindex<<std::endl;
668  return;
669  }
670  std::vector<TGo4DabcRate> & recordvec= fxRateRecords[nodeindex];
671  if(rateindex>recordvec.size())
672  {
673  std::cout<<"!!!!!!!!!!!NEVER COME HERE: rate updated out of bounds, rateindex=" << rateindex<<std::endl;
674  return;
675  }
676  recordvec[rateindex]=TGo4DabcRate(currentrate, info->getName());
677  bool trendon=fxTrendingFlags[nodeindex].at(rateindex);
678  bool statson=fxStatsFlags[nodeindex].at(rateindex);
679  if(fbHistogramming && (trendon || statson))
680  {
681  std::vector< std::deque <float> > & qvec= fxRateQueues[nodeindex];
682  if(rateindex>qvec.size())
683  {
684  std::cout<<"!!!!!!!!!!!NEVER COME HERE: rate queue vector out of bounds, rateindex=" << rateindex<<std::endl;
685  return;
686  }
687  qvec[rateindex].push_back(currentrate->value); // aquire values, display later!
688  fbDisplayHistograms=true;
689  }
690  fxLastTimestamp=info->getTimestamp( );
691  fbDisplayRateTable=true;
692  } //if(nodeindex<0)
693 }
694 
695 
699 
701 {
702  TGo4LockGuard gard;
703  //std::cout<<"*********refreshNodes()" <<std::endl;
704  fbRebuildNodeTable=true;
705  fbRebuildRateTable=true;
706  fxDabcNodes.clear();
707 
708  clearRates();
709  clearServices();
710  clearStates();
711  for ( QStringList::Iterator it = fxNodelist.begin(); it != fxNodelist.end(); ++it )
712  {
713  QString current=*it;
714  if(current.contains("DIS_DNS")) continue; // skip name server
715  //std::cout<<"+++ processing node entry " << current.toLatin1().constData() <<std::endl;
716  QString prefix=current.section('/', 0, 0 );
717  QString rest=current.section('/', 1, 1 );
718  QString reducednode=rest.section('@',0,0); // include port number into node name!
719  //std::cout<<"+++ prefix is " << prefix.toLatin1().constData() <<std::endl;
720  //if(prefix=="DABC")
721  if(prefix==current)
722  {
723  // no dabcnode (i.e. mbs)
724  reducednode=current.section('@',0,0);;
725  }
726  //std::cout<<"++++ found reduced node "<<reducednode.toLatin1().constData() <<std::endl;
727 
728  //std::cout<<"++++ found DABC prefix " <<std::endl;
729 
730  fxDabcNodes.push_back(reducednode);
731  // get full service list for this node:
732  QString sinfoname=current.section('@',0,0) + "/SERVICE_LIST";
733  //std::cout<<"++++ creating service info "<<sinfoname <<std::endl;
734  TGo4DabcServiceInfo* servinfo= new TGo4DabcServiceInfo(sinfoname.toLatin1().constData(), 0, "not available", this);
735  fxServices.push_back(servinfo);
736  fxStates.push_back(0); // make sure that for our index a slot in state service vector exists!
737  fxStateRecords.push_back(TGo4DabcState()); // dito for state record vector
738  // provide empty vectors of rateinfos and raterecords etc for this node:
739  std::vector<TGo4DabcRateInfo*> rinfovec;
740  rinfovec.clear();
741  fxRates.push_back(rinfovec);
742  std::vector<TGo4DabcRate> ratevec;
743  ratevec.clear();
744  fxRateRecords.push_back(ratevec);
745  fxShowRateFlags.push_back(false);
746  std::vector<float> sumvec;
747  fxRateSum.push_back(sumvec);
748  std::vector<unsigned int> countvec;
749  fxRateCount.push_back(countvec);
750  std::vector<bool> trendvec;
751  trendvec.clear();
752  fxTrendingFlags.push_back(trendvec);
753  std::vector <std::vector<bool> >initvec;
754  fbTrendingInit.push_back(initvec);
755  fxStatsFlags.push_back(trendvec);
756  fbStatsInit.push_back(initvec);
757  std::vector < std::vector <QString> >namesvec;
758  fxTrendHistoRefnames.push_back(namesvec);
759  fxStatHistoRefnames.push_back(namesvec);
760  fxShowLogFlags.push_back(false);
761  std::vector< std::deque <float> > rateqvec;
762  fxRateQueues.push_back(rateqvec);
763  //} // if XDAQ
764  } // for
765 }
766 
767 
768 
769 
771 {
772  TGo4LockGuard gard;
773  std::vector<TGo4DabcStateInfo*>::iterator iter;
774  for(iter=fxStates.begin(); iter!=fxStates.end(); ++iter)
775  {
776  delete *iter;
777  }
778  fxStates.clear();
779  fxStateRecords.clear();
780  fxShowRateFlags.clear();
781  fxShowLogFlags.clear();
782 }
783 
785 {
786  TGo4LockGuard gard;
787  std::vector<TGo4DabcServiceInfo*>::iterator iter;
788  for(iter=fxServices.begin(); iter!=fxServices.end(); ++iter)
789  {
790  delete *iter;
791  }
792  fxServices.clear();
793 }
794 
795 
797 {
798  TGo4LockGuard gard;
799  std::vector<std::vector<TGo4DabcRateInfo*> >::iterator nodeiter;
800  for(nodeiter=fxRates.begin(); nodeiter!=fxRates.end(); ++nodeiter)
801  {
802  std::vector<TGo4DabcRateInfo*> nodevec=*nodeiter; // each node has vector of rate services!
803  std::vector<TGo4DabcRateInfo*>::iterator iter;
804  for(iter=nodevec.begin(); iter!=nodevec.end(); ++iter)
805  {
806  delete *iter;
807  }
808  }
809  fxRates.clear();
810  fxTrendingFlags.clear();
811  fbTrendingInit.clear();
812  fxStatsFlags.clear();
813  fbStatsInit.clear();
814  fxTrendHistoRefnames.clear();
815  fxStatHistoRefnames.clear();
816  fxRateRecords.clear();
817  fxRateQueues.clear();
818  fxRateSum.clear();
819  fxRateCount.clear();
820 }
821 
822 
824 {
825  TGo4LockGuard gard;
826  //std::cout<<"rrrrrrrr createRateServices for "<<nodeindex <<std::endl;
827  //search the service list for our node for all rate services:
828  QString services=fxServices[nodeindex]->getString();
829  // std::cout<<"+++ createRateServices got service list: " << services.toLatin1().constData() <<std::endl;
830 
831  // find full name of nodestate in services:
832  QStringList servlist = services.split(0x0A, QString::SkipEmptyParts);
833  QString rateservice="";
834  for ( QStringList::Iterator sit = servlist.begin(); sit != servlist.end(); ++sit )
835  {
836  QString service = *sit;
837  // std::cout<<"++++++ scanning service" << service.toLatin1().constData() <<std::endl;
838  //if(service.contains("F:1;L:1;F:1;F:1;F:1;F:1;C:16;C:16;C:16")
839  if(service.contains("F:1;L:1;F:1;F:1;F:1;F:1;C:16;C:16;C")) //check for dabc rate structure info
840  {
841  // provide slots for aux vectors first, since dim info may call update on creation time!
842  fxRateRecords[nodeindex].push_back(TGo4DabcRate()); // need initial dummy record
843  std::deque <float> ratequeue;
844  fxRateQueues[nodeindex].push_back(ratequeue);
845  fxRateSum[nodeindex].push_back(0); // init average rate variables
846  fxRateCount[nodeindex].push_back(0);
847 
848  fxTrendingFlags[nodeindex].push_back(false); // initial value for trending flag
849  std::vector <bool> hisvec;
850  hisvec.push_back(false); // flags for 2 histograms each rate
851  hisvec.push_back(false);
852  fbTrendingInit[nodeindex].push_back(hisvec);
853  std::vector <QString> namesvec;
854  namesvec.push_back("undefined histogram"); // dito for reference names
855  namesvec.push_back("undefined histogram");
856  fxTrendHistoRefnames[nodeindex].push_back(namesvec);
857 
858  fxStatsFlags[nodeindex].push_back(false); // initial value for statistic hisot flag
859  fbStatsInit[nodeindex].push_back(hisvec);
860  fxStatHistoRefnames[nodeindex].push_back(namesvec);
861  QString rname=service.section('|',0,0); // strip additional service info from name
862  //std::cout<<"++++++ creating rate info " << rname <<std::endl;
863  TGo4DabcRateInfo* rinfo=new TGo4DabcRateInfo(rname.toLatin1().constData(), 0, &gNolinkRateRecord , sizeof(dabc:: RateRec), this);
864  fxRates[nodeindex].push_back(rinfo); // keep dim info here
865  }
866  } // for
867 }
868 
869 
871 {
872  TGo4LockGuard gard;
873  //std::cout<<"rrrrrrrr deleteRateServices for "<<nodeindex <<std::endl;
874  std::vector<TGo4DabcRateInfo*> & nodevec=fxRates[nodeindex];
875  std::vector<TGo4DabcRateInfo*>::iterator iter;
876  for(iter=nodevec.begin(); iter!=nodevec.end(); ++iter)
877  {
878  delete *iter;
879  }
880  nodevec.clear();
881  fxTrendingFlags[nodeindex].clear();
882  fbTrendingInit[nodeindex].clear();
883  fxTrendHistoRefnames[nodeindex].clear();
884  fxStatsFlags[nodeindex].clear();
885  fbStatsInit[nodeindex].clear();
886  fxStatHistoRefnames[nodeindex].clear();
887  fxRateRecords[nodeindex].clear();
888  fxRateSum[nodeindex].clear();
889  fxRateCount[nodeindex].clear();
890  fbDisplayRateTable=true; // update view in case of last service is gone!
891 
892 }
893 
895 {
896  TGo4LockGuard gard;
897  //std::cout<<"rrrrrrrr createLogServices for "<<nodeindex <<std::endl;
898  QRegExp filter(dimServiceFilterEdit->text().trimmed());
899  filter.setPatternSyntax(QRegExp::Wildcard); // use simple wildcard matching, like shell
900  std::cout<<std::endl<< "---- Retrieving current DIM variables from node "<<fxDabcNodes[nodeindex].toLatin1().constData()<<" with filter:"<<filter.pattern().toLatin1().constData() <<std::endl;
901 
902  //search the service list for our node for all rate services:
903  QString services=fxServices[nodeindex]->getString();
904  //std::cout<<"+++ createLogServices got service list: " << services <<std::endl;
905 
906  // find full name of nodestate in services:
907  QStringList servlist = services.split(0x0A, QString::SkipEmptyParts);
908  QString logservice="";
909  for ( QStringList::Iterator sit = servlist.begin(); sit != servlist.end(); ++sit )
910  {
911  QString service=*sit;
912  QString sformat=service.section('|',1,1);
913  QString sname=service.section('|',0,0); // strip additional service info from name
914  QString scom=service.section('|',2,2); // command indicator
915  if(sname.contains("SERVICE_LIST")) continue; // skip service list
916  if(scom.contains("CMD")) continue; // skip command services
917  if(filter.indexIn(sname)<0) continue; // regexp does not match name, skip
918 
919  //std::cout<<"++++++ creating log info " << sname <<" for format "<<sformat <<std::endl;
920  if(sformat=="C")
921  {
922  TGo4DabcInfo* info= new TGo4DabcInfo(sname.toLatin1().constData(),1,"not available", this);
923  }
924  else if(sformat=="L")
925  {
926  TGo4DabcInfo* info= new TGo4DabcInfo(sname.toLatin1().constData(),1, (int) -1, this);
927  }
928  else
929  {
930  TGo4DabcInfo* info= new TGo4DabcInfo(sname.toLatin1().constData(),1, &gNolinkRateRecord , sizeof(dabc:: RateRec), sformat.toLatin1().constData(), this);
931  }
932  } // for ( QStringList::Iterator sit =
933 }
934 
935 
936 
937 
938 
939 
940 
944 
945 
947 {
948  TGo4LockGuard gard;
949  fbTableBeingCreated=true;
950  //std::cout<<"*********displayNodeTable()" <<std::endl;
952  {
953  //std::cout<<"********* - rebuild table" <<std::endl;
954  // first case: create table completely new
955  NodeTable->setRowCount(0);
956  int maxnodes = fxDabcNodes.size();
957  NodeTable->setRowCount(maxnodes);
958  for(int ix=0; ix<maxnodes; ++ix)
959  fillNodeTableRow(ix, ix, true);
960  fbRebuildNodeTable=false;
961  } // if(fbRebuildNodeTable)
962  else
963  {
964  //std::cout<<"********* - update table contents" <<std::endl;
965  int tablesize = NodeTable->rowCount();
966  int maxnodes = fxDabcNodes.size();
967  if(maxnodes!=tablesize)
968  {
969  std::cout<<"!!!!!!!!!! NEVER COME HERE: table size "<<tablesize<<" does not match number of nodes "<<maxnodes <<std::endl;
970  return;
971  }
972 
973  for(int ix=0; ix<maxnodes; ++ix)
974  {
975  int tableindex=-1;
976  for(int j=0; j<tablesize;++j)
977  {
978  QString ixtext;
979  if (NodeTable->item(j, DABCMON_NODE_INDEXCOL))
980  ixtext = NodeTable->item(j, DABCMON_NODE_INDEXCOL)->text();
981  int tix=ixtext.toInt();
982  if(tix==ix)
983  {
984  tableindex=j;
985  break;
986  }
987  }
988  if(tableindex<0)
989  {
990  std::cout<<"!!!!!!!!!! NEVER COME HERE: could not find tableindex for "<<ix <<std::endl;
991  continue;
992  }
993  else
994  {
995  //std::cout<<"***********tableindex for "<<ix<<" is "<<tableindex <<std::endl;
996  }
997  fillNodeTableRow(tableindex, ix, false);
998  }//for(int ix=0; ix<maxnodes; ++ix)
999  }//if(fbRebuildNodeTable)
1000  ensurePolished();
1001  update();
1002  show();
1003  fbTableBeingCreated=false;
1004 }
1005 
1006 
1007 void TGo4DabcMonitor::fillNodeTableRow( int tableindex, int nodeindex, bool createnew )
1008 {
1009  NodeTable->setSortingEnabled(false);
1010  //std::cout<<"***fillNodeTableRow - tableindex:"<<tableindex<<", nodeindex:"<<nodeindex<<", createnew:"<<createnew <<std::endl;
1011 
1012  //std::cout<<" nodename is "<<fxDabcNodes[nodeindex].toLatin1().constData()<<std::endl;
1013  NodeTable->setItem(tableindex, DABCMON_NODE_NODECOL, new QTableWidgetItem(fxDabcNodes[nodeindex]));
1014 
1015  QPixmap pixmap = QPixmap(":/icons/eventitem.png").scaledToHeight(NodeTable->rowHeight(tableindex),Qt::SmoothTransformation);
1016 
1017  QTableWidgetItem* item = 0;
1018  if(nodeindex>fxStateRecords.size())
1019  std::cout<<" !!!!!!!!!! nodeindex exceeds size of states "<<fxStateRecords.size()<<std::endl;
1020  QString col =fxStateRecords[nodeindex].fxColor.toLower();
1021  //std::cout<<" color is "<<fxStateRecords[nodeindex].fxColor.toLatin1().constData()<<std::endl;
1022  //std::cout<<" state is "<<fxStateRecords[nodeindex].fxState.toLatin1().constData()<<std::endl;
1023 
1024 
1025 
1026  // NodeTable->setItem(tableindex, DABCMON_NODE_STATECOL, new QTableWidgetItem(fxStateRecords[nodeindex].fxState));
1027  pixmap.fill(fxStateRecords[nodeindex].fxColor.toLower());
1028  item = new QTableWidgetItem(pixmap, fxStateRecords[nodeindex].fxState);
1029  item->setFlags(item->flags() & ~Qt::ItemIsEditable);
1030  NodeTable->setItem(tableindex, DABCMON_NODE_STATECOL, item);
1031  if(createnew) {
1032  item = new QTableWidgetItem(QString::number(nodeindex));
1033  //std::cout<<" nodeindextext is "<< QString::number(nodeindex).toLatin1().constData()<<std::endl;
1034  //std::cout<<" item text is "<< item->text().toLatin1().constData()<<std::endl;
1035 
1036  item->setFlags(item->flags() & ~Qt::ItemIsEditable);
1037  NodeTable->setItem(tableindex, DABCMON_NODE_INDEXCOL, item);
1038 
1039  item = new QTableWidgetItem("Show" );
1040  item->setFlags(item->flags() & ~Qt::ItemIsEditable);
1041  item->setCheckState(fxShowRateFlags[nodeindex] ? Qt::Checked : Qt::Unchecked);
1042  NodeTable->setItem( tableindex,DABCMON_NODE_CHECKCOL, item);
1043 
1044  item= new QTableWidgetItem("Dump");
1045  item->setFlags(item->flags() & ~Qt::ItemIsEditable);
1046  item->setCheckState(fxShowLogFlags[nodeindex] ? Qt::Checked : Qt::Unchecked);
1047  NodeTable->setItem(tableindex,DABCMON_NODE_LOGCOL, item);
1048  } else {
1049  QTableWidgetItem* checkitem= NodeTable->item(tableindex, DABCMON_NODE_CHECKCOL);
1050  if(checkitem)
1051  checkitem->setCheckState(fxShowRateFlags[nodeindex] ? Qt::Checked : Qt::Unchecked);
1052  else
1053  std::cout<<"!!!!!!!!!! NEVER COME HERE: wrong rate checktableitem at index "<<nodeindex <<std::endl;
1054  QTableWidgetItem* checklogitem = NodeTable->item(tableindex, DABCMON_NODE_LOGCOL);
1055  if(checklogitem)
1056  checklogitem->setCheckState(fxShowLogFlags[nodeindex] ? Qt::Checked : Qt::Unchecked);
1057  else
1058  std::cout<<"!!!!!!!!!! NEVER COME HERE: wrong logchecktableitem at index "<<nodeindex <<std::endl;
1059  }
1060  NodeTable->setSortingEnabled(true);
1061 }
1062 
1063 
1064 
1065 
1067 {
1068  TGo4LockGuard gard;
1069  fbTableBeingCreated=true;
1070  //std::cout<<"*********displayRateTable()" <<std::endl;
1071  // find number of existing rate services
1072  int numrates=0;
1073  int maxnodes=fxRateRecords.size();
1074  for(int ix=0; ix<maxnodes; ++ix)
1075  {
1076  numrates+=fxRateRecords[ix].size();
1077  }
1078  int tablesize = RateTable->rowCount();
1079  int tablecursor = -1;
1080  if(fbRebuildRateTable)
1081  {
1082  //std::cout<<"********* - rebuild table" <<std::endl;
1083  // first case: create table completely new
1084  //std::cout<<"* inserting "<<numrates<<" rows" <<std::endl;
1085  RateTable->setRowCount(0);
1086  RateTable->setRowCount(numrates);
1087  int tableindex=0;
1088  // now fill table with services:
1089  for(int ix=0; ix<maxnodes; ++ix)
1090  {
1091  std::vector<TGo4DabcRate> & rvec=fxRateRecords[ix];
1092  //std::cout<<"* looping rvec[ "<<ix<<"] with "<<rvec.size()<<" rate entries" <<std::endl;
1093  for(int rix=0; rix<rvec.size();++rix)
1094  {
1095  //std::cout<<"* found rvec[ "<<ix<<"]["<<rix <<"] with name "<< rvec[rix].fxName<< std::endl;
1096  fillRateTableRow(tableindex, ix, rix, true);
1097  tableindex++;
1098  //std::cout<<"* tableindex gets "<<tableindex<<std::endl;
1099  } // for rix
1100  }// for ix
1101  //std::cout<<"* after loop over maxnodes="<<maxnodes<<std::endl;
1102  fbRebuildRateTable=false;
1103  } // if(fbRebuildRateTable)
1104  else
1105  {
1106  //std::cout<<"********* - update table contents" <<std::endl;
1107  if(numrates>tablesize)
1108  {
1109  //std::cout<<"table size "<<tablesize<<" smaller than number of rate records "<<numrates <<std::endl;
1110  // int diff=numrates-tablesize;
1111  tablecursor=tablesize;
1112  //std::cout<<"* inserting "<<diff<<" rows" <<std::endl;
1113  RateTable->setRowCount(numrates);
1114  }
1115  else if(numrates<tablesize)
1116  {
1117  //std::cout<<"table size "<<tablesize<<" bigger than number of rate records "<<numrates <<std::endl;
1118  // here we have to find the obsolete rows and remove it! do this after updating contents
1119  }
1120  else
1121  {
1122  // size is the same, do nothing
1123  }
1124  tablesize = RateTable->rowCount();
1125  bool usedrows[tablesize]; // keep track of unused table rows for cleanup
1126  for(int t=0;t<tablesize;++t){usedrows[t]=false;}
1127  for(int nix=0; nix<maxnodes; ++nix)
1128  {
1129  std::vector<TGo4DabcRate> & rvec=fxRateRecords[nix];
1130  for(int rix=0; rix<rvec.size();++rix)
1131  {
1132  // find tableindex for nix and rix:
1133  int tableindex=-1;
1134  for(int j=0; j<tablesize;++j)
1135  {
1136  int tablenodeix=-1;
1137  int tablerateix=-1;
1138  if(!getRateIndices(j, tablenodeix, tablerateix)) continue; // skip newly created empty rows
1139  if(tablenodeix==nix && tablerateix==rix)
1140  {
1141  tableindex=j;
1142  break;
1143  }
1144  }// for j
1145  if(tableindex<0)
1146  {
1147  //std::cout<<"!!!!!!!!!! could not find tableindex for ("<<nix<<","<<rix<<")" <<std::endl;
1148  //std::cout<<"*********creating new table entry at "<<tablecursor;
1149  if(tablecursor<0)
1150  {
1151  std::cout<<"!!!!!!!!!! NEVER COME HERE: tablecursor undefined for new entry ("<<nix<<","<<rix<<")" <<std::endl;
1152  continue;
1153  }
1154  fillRateTableRow(tablecursor, nix, rix, true);
1155  usedrows[tablecursor]=true;
1156  tablecursor++;
1157  }
1158  else
1159  {
1160  //std::cout<<"***********tableindex for ("<<nix<<","<<rix<<") was "<<tableindex <<std::endl;
1161  usedrows[tableindex]=true;
1162  fillRateTableRow(tableindex, nix, rix, false);
1163  } // if(tableindex<0)
1164  }// for rix
1165  }// for nix
1166  int offset=0;
1167  for(int rownum=0;rownum<tablesize;++rownum)
1168  {
1169  if(usedrows[rownum]==false)
1170  {
1171  //std::cout<<"***********displayRateTable found unused row "<<rownum<<", remove it!"<<std::endl;
1172  RateTable->removeRow(rownum-offset);
1173  //std::cout<<"*********** removed at"<<rownum-offset<<std::endl;
1174  offset++; // correct index for already removed rows above!
1175  }
1176  }// for rownum
1177  }//if(fbRebuildRateTable)
1178  ensurePolished();
1179  update();
1180  show();
1181  fbTableBeingCreated=false;
1182 }
1183 
1184 void TGo4DabcMonitor::fillRateTableRow( int tableindex, int nodeindex, int rateindex, bool createnew )
1185 {
1186  RateTable->setSortingEnabled(false);
1187  //std::cout<<":fillRateTableRow for "<<tableindex<<std::endl;
1188  std::vector<TGo4DabcRate> & rvec=fxRateRecords[nodeindex];
1189  QString val;
1190  val.setNum(rvec[rateindex].fxRate);//setNum ( float n, char f = 'g', int prec = 6 )
1191  val+=" "+rvec[rateindex].fxUnits;
1192 
1193  QTableWidgetItem* item = 0;
1194  if(rvec[rateindex].fxRate<0) {
1195  QPixmap pixmap = QPixmap(":/icons/info1.png").scaledToHeight(RateTable->rowHeight(tableindex),Qt::SmoothTransformation);
1196  item = new QTableWidgetItem( QIcon(pixmap), val);
1197  } else
1198  item = new QTableWidgetItem(val);
1199  item->setFlags(item->flags() & ~Qt::ItemIsEditable);
1200  RateTable->setItem(tableindex, DABCMON_RATE_RATECOL, item);
1201 
1202  if(createnew) {
1203  QString namestring=rvec[rateindex].fxName.section('/',1); // strip DABC prefix
1204  QTableWidgetItem* item = new QTableWidgetItem(namestring);
1205  item->setFlags(item->flags() & ~Qt::ItemIsEditable);
1206  RateTable->setItem(tableindex, DABCMON_RATE_NAMECOL, item);
1207 
1208  QString indexstring = QString::number(nodeindex)+":"+QString::number(rateindex);
1209  item = new QTableWidgetItem(indexstring);
1210  item->setFlags(item->flags() & ~Qt::ItemIsEditable);
1211  RateTable->setItem(tableindex, DABCMON_RATE_INDEXCOL, item);
1212 
1213  item = new QTableWidgetItem("histogram" );
1214  item->setCheckState(fxTrendingFlags[nodeindex].at(rateindex) ? Qt::Checked : Qt::Unchecked);
1215  item->setFlags(item->flags() & ~Qt::ItemIsEditable);
1216  RateTable->setItem( tableindex,DABCMON_RATE_TRENDCOL, item);
1217 
1218  item = new QTableWidgetItem ("histogram" );
1219  item->setCheckState(fxStatsFlags[nodeindex].at(rateindex) ? Qt::Checked : Qt::Unchecked );
1220  item->setFlags(item->flags() & ~Qt::ItemIsEditable);
1221  RateTable->setItem( tableindex,DABCMON_RATE_STATSCOL, item);
1222  } else {
1223  QTableWidgetItem* trendcheckitem= RateTable->item(tableindex, DABCMON_RATE_TRENDCOL);
1224  if(trendcheckitem)
1225  trendcheckitem->setCheckState(fxTrendingFlags[nodeindex].at(rateindex) ? Qt::Checked : Qt::Unchecked);
1226  else
1227  std::cout<<"!!!!!!!!!! NEVER COME HERE: wrong trend checktableitem at table index "<<tableindex <<std::endl;
1228  QTableWidgetItem* statcheckitem = RateTable->item(tableindex, DABCMON_RATE_STATSCOL);
1229  if(statcheckitem)
1230  statcheckitem->setCheckState(fxStatsFlags[nodeindex].at(rateindex) ? Qt::Checked : Qt::Unchecked);
1231  else
1232  std::cout<<"!!!!!!!!!! NEVER COME HERE: wrong stat checktableitem at table index "<<tableindex <<std::endl;
1233  } // if(createnew)
1234  RateTable->setSortingEnabled(true);
1235 }
1236 
1237 
1238 bool TGo4DabcMonitor::getRateIndices( int tablerow, int & nodeix, int & rateix )
1239 {
1240  if (RateTable->item(tablerow, DABCMON_RATE_INDEXCOL)==0) return false;
1241 
1242  QString ixtext= RateTable->item(tablerow, DABCMON_RATE_INDEXCOL)->text();
1243  QString nstring=ixtext.section( ':', 0,0);
1244  if(nstring.isEmpty()) return false; // for newly created empty row, we would get 0,0 indices!
1245  nodeix=nstring.toInt();
1246  QString rstring=ixtext.section( ':', 1,1);
1247  rateix=rstring.toInt();
1248  return true;
1249 }
1250 
1251 
1252 
1253 
1255 {
1256  TGo4LockGuard gard;
1257  // iterate all rate indices:
1258  for(int nodeix=0;nodeix<fxTrendingFlags.size();++nodeix)
1259  {
1260  std::vector<bool> & trendvec=fxTrendingFlags[nodeix];
1261  if(nodeix>fxStatsFlags.size())
1262  {
1263  std::cout <<"--NEVER COME HERE: node index mismatch in displaySampleHistograms for nix="<< nodeix<<std::endl;
1264  return;
1265  }
1266  std::vector<bool> & statsvec=fxStatsFlags[nodeix];
1267  for(int rateix=0; rateix<trendvec.size();++rateix)
1268  {
1269  bool trending=trendvec[rateix];
1270  if(rateix>statsvec.size())
1271  {
1272  std::cout <<"--NEVER COME HERE: rate index mismatch in displaySampleHistograms for rix)"<< rateix<<std::endl;;
1273  return;
1274  }
1275  bool statisting=statsvec[rateix];
1276  if(trending || statisting)
1277  {
1278  // check if value queue for this index exists
1279  if(nodeix>fxRateQueues.size())
1280  {
1281  std::cout <<"--NEVER COME HERE: node index mismatch in displaySampleHistograms queues for nix="<< nodeix<<std::endl;
1282  return;
1283  }
1284  std::vector< std::deque <float> > & qvec =fxRateQueues[nodeix];
1285  if(rateix>qvec.size())
1286  {
1287  std::cout <<"--NEVER COME HERE: rate index mismatch in displaySampleHistograms queues for rix)"<< rateix<<std::endl;;
1288  return;
1289  }
1290  std::deque<float> &ratequeue = qvec[rateix];
1291  // read all values from queue and display in histogram
1292  while (!ratequeue.empty())
1293  {
1294  float val=ratequeue.front();
1295  ratequeue.pop_front();
1296  // sum value and update counter:
1297  fxRateSum[nodeix].at(rateix)+=val;
1298  fxRateCount[nodeix].at(rateix)++;
1299  if(!TrendSampleCheck->isChecked()) continue; // clear queue, but do not display sample histograms
1300  if(trending)
1301  updateTrending(nodeix,rateix, 0, val);
1302  if(statisting)
1303  updateStats(nodeix,rateix,0, val);
1304  }// while ratequeue
1305  } // if trending or statisting
1306  } // for rateix
1307  }//for nodeix
1308 }
1309 
1310 
1312 {
1313  TGo4LockGuard gard;
1314  if(!fbHistogramming) return;
1315  // iterate all rate indices:
1316  for(int nodeix=0;nodeix<fxTrendingFlags.size();++nodeix)
1317  {
1318  std::vector<bool> & trendvec=fxTrendingFlags[nodeix];
1319  if(nodeix>fxStatsFlags.size())
1320  {
1321  std::cout <<"--NEVER COME HERE: node index mismatch in displaySampleHistograms for nix="<< nodeix<<std::endl;
1322  return;
1323  }
1324  std::vector<bool> & statsvec=fxStatsFlags[nodeix];
1325  for(int rateix=0; rateix<trendvec.size();++rateix)
1326  {
1327  bool trending=trendvec[rateix];
1328  if(rateix>statsvec.size())
1329  {
1330  std::cout <<"--NEVER COME HERE: rate index mismatch in displaySampleHistograms for rix)"<< rateix<<std::endl;;
1331  return;
1332  }
1333  bool statisting=statsvec[rateix];
1334  if(trending || statisting)
1335  {
1336  float val=-2;
1337  float sum= fxRateSum[nodeix].at(rateix);
1338  unsigned int count= fxRateCount[nodeix].at(rateix);
1339  if(count!=0) val=sum/count;
1340  fxRateSum[nodeix].at(rateix)=0.;
1341  fxRateCount[nodeix].at(rateix)=0;
1342  if(trending)
1343  updateTrending(nodeix,rateix,1, val);
1344  if(statisting)
1345  updateStats(nodeix,rateix,1,val);
1346  }
1347  }// for rateix
1348  }// for nodeix
1349 }
1350 
1351 
1352 
1354 {
1355  //std::cout<<"ttttttt timer fired displayAll()" <<std::endl;
1356  TGo4LockGuard gard;
1357  QDateTime timestamp;
1358  timestamp.setTime_t (fxLastTimestamp);
1359  //DateLabel->setText(timestamp.toString(Qt::ISODate));
1360  DateLabel->setText(timestamp.toString());
1361  if(fbDisplayNodeTable)
1362  {
1363  displayNodeTable();
1364  fbDisplayNodeTable=false;
1365  }
1366  if(fbDisplayRateTable)
1367  {
1368  displayRateTable();
1369  fbDisplayRateTable=false;
1370  }
1371 
1372  // now treat direct sample histograms:
1374  {
1376  fbDisplayHistograms=false;
1377  }
1378 
1379 }
1380 
1384 
1385 
1386 
1387 void TGo4DabcMonitor::updateTrending( int nodeix, int rateix, int hisix, double value)
1388 {
1389  QString & refname= fxTrendHistoRefnames[nodeix].at(rateix).at(hisix);
1390  QString name=fxRateRecords[nodeix].at(rateix).fxName;
1391  QString foldername=name.section( '/', 1,2);
1392  name=name.section( '/', 3);
1393  name.replace( QChar('/'), "-" );
1394  switch(hisix)
1395  {
1396  case 0:
1397  default:
1398  name=name+"-TrendingFast";
1399  break;
1400  case 1:
1401  name=name+"-TrendingAverage";
1402  break;
1403  };
1404  foldername.replace( QChar('/'), "-" );
1405  QString & title=fxRateRecords[nodeix].at(rateix).fxUnits;
1406 
1407  //std::cout<<" val="<<value<<", name="<<name<<", refname="<<refname <<", folder="<<foldername<<std::endl;
1408  TH1* his=0;
1409  TGo4Slot* histoslot=0;
1410  if(!fbTrendingInit[nodeix].at(rateix).at(hisix)) histoslot=Browser()->BrowserSlot(refname.toLatin1().constData());
1411  if(histoslot==0)
1412  {
1413  Axis_t lo,up;
1414  if(fbTrendingForward)
1415  {
1416  lo=0;
1417  switch(hisix)
1418  {
1419  case 0:
1420  default:
1421  up=1*fiTrendBins;
1422  break;
1423  case 1:
1424  up=1*fiTrendBins*FrequencyBox->value();
1425  break;
1426  };
1427  }
1428  else
1429  {
1430  switch(hisix)
1431  {
1432  case 0:
1433  default:
1434  lo=-1*fiTrendBins;
1435  break;
1436  case 1:
1437  lo=-1*fiTrendBins*FrequencyBox->value();
1438  break;
1439  };
1440  up=0;
1441  }
1442  his=new TH1F(name.toLatin1().constData(), title.toLatin1().constData(), fiTrendBins,lo,up);
1443  TAxis* xax=his->GetXaxis();
1444  switch(hisix)
1445  {
1446  case 0:
1447  default:
1448  xax->SetTitle("updates");
1449  break;
1450  case 1:
1451  xax->SetTitle("s");
1452  break;
1453  };
1454  xax->CenterTitle();
1455  //xax->SetLimits(0,lo,up);
1456 
1457  TGo4Slot* hisdataslot=Browser()->DataSlot(refname.toLatin1().constData());
1458  if(hisdataslot)
1459  {
1460  hisdataslot->AssignObject(his,true);
1461  }
1462  else
1463  {
1464  //QString folder="Dabc/"+fxNodelist[nodeix];
1465  QString folder="DABC/"+foldername;
1466  refname=Browser()->SaveToMemory(folder.toLatin1().constData(), his, true);
1467  }
1468  histoslot=Browser()->BrowserSlot(refname.toLatin1().constData());
1469  }
1470  else
1471  {
1472  his=dynamic_cast<TH1*>(histoslot->GetAssignedObject());
1473  }
1474  IncTrending(his,value,fbTrendingForward);
1475  if(histoslot)
1476  {
1477  histoslot->ForwardEvent(histoslot, TGo4Slot::evObjUpdated);
1478  Browser()->SetItemTimeDate(histoslot);
1479  fbTrendingInit[nodeix].at(rateix).at(hisix)=false;
1480  }
1481 }
1482 
1483 
1484 void TGo4DabcMonitor::IncTrending( TH1 * histo, double value, bool forwards )
1485 {
1486  if(histo==0) return;
1487  int bins=histo->GetNbinsX();
1488  //bool forwards=true;
1489  int j,dj;
1490  if(forwards)
1491  dj=-1;
1492  else
1493  dj=+1;
1494  for(int i=0;i<bins;i++)
1495  {
1496  if(forwards)
1497  j=bins-i;
1498  else
1499  j=i;
1500  double oldval=histo->GetBinContent(j+dj);
1501  histo->SetBinContent(j,oldval);
1502  }
1503  histo->SetBinContent(j+dj,value);
1504 }
1505 
1506 
1507 
1508 void TGo4DabcMonitor::updateStats( int nodeix, int rateix, int hix , double value)
1509 {
1510 
1511  QString & refname= fxStatHistoRefnames[nodeix].at(rateix).at(hix);
1512  QString name=fxRateRecords[nodeix].at(rateix).fxName;
1513  QString foldername=name.section( '/', 1,2);
1514  name=name.section( '/', 3);
1515  name.replace( QChar('/'), "-" );
1516  switch(hix)
1517  {
1518  case 0:
1519  default:
1520  name=name+"-StatsFast";
1521  break;
1522  case 1:
1523  name=name+"-StatsAverage";
1524  break;
1525  };
1526  foldername.replace( QChar('/'), "-" );
1527  QString title="counts";
1528  QString & xtitle=fxRateRecords[nodeix].at(rateix).fxUnits;
1529  //std::cout<<" val="<<value<<", name="<<name<<", refname="<<refname <<", folder="<<foldername<<std::endl;
1530  TH1* his=0;
1531  TGo4Slot* histoslot=0;
1532  if(! fbStatsInit[nodeix].at(rateix).at(hix)) histoslot=Browser()->BrowserSlot(refname.toLatin1().constData());
1533  if(histoslot==0)
1534  {
1535  Axis_t lo,up;
1536  lo=fxRateRecords[nodeix].at(rateix).fxLower;
1537  up=fxRateRecords[nodeix].at(rateix).fxUpper;
1538  if(lo==up)
1539  {
1540  lo=0;
1541  up=100;
1542  //std::cout <<"using default histogram range for name: "<<name.toLatin1().constData()<<" ["<<lo<<","<<up<<"]" << std::endl;
1543  }
1544  his=new TH1F(name.toLatin1().constData(),title.toLatin1().constData(),fiStatBins,lo,up);
1545  TAxis* xax=his->GetXaxis();
1546  xax->SetTitle(xtitle.toLatin1().constData());
1547  xax->CenterTitle();
1548  TGo4Slot* hisdataslot=Browser()->DataSlot(refname.toLatin1().constData());
1549  if(hisdataslot)
1550  {
1551  hisdataslot->AssignObject(his,true);
1552  }
1553  else
1554  {
1555  //QString folder="Dabc/"+fxNodelist[nodeix];
1556  QString folder="DABC/"+foldername;
1557  refname=Browser()->SaveToMemory(folder.toLatin1().constData(), his, true);
1558  }
1559  histoslot=Browser()->BrowserSlot(refname.toLatin1().constData());
1560  }
1561  else
1562  {
1563  his=dynamic_cast<TH1*>(histoslot->GetAssignedObject());
1564  } // if(histoslot==0)
1565  his->Fill(value);
1566  if(histoslot)
1567  {
1568  histoslot->ForwardEvent(histoslot, TGo4Slot::evObjUpdated);
1569  Browser()->SetItemTimeDate(histoslot);
1570  fbStatsInit[nodeix].at(rateix).at(hix)=false;
1571  }
1572 }
1573 
1574 
1575 //#endif
1576 
1577 
virtual ~TGo4DabcMonitor()
std::vector< TGo4DabcStateInfo * > fxStates
virtual void updateStats(int nodeix, int rateix, int hix, double value)
void setDabcMonitorNode(const QString &name)
virtual void clearRates()
virtual void infoHandler()
std::vector< bool > fxShowLogFlags
static dabc::StatusRec gNolinkStateRecord
std::vector< std::vector< std::vector< bool > > > fbTrendingInit
virtual void refreshNodes()
std::vector< std::vector< float > > fxRateSum
std::vector< bool > fxShowRateFlags
TString SaveToMemory(const char *pathname, TObject *obj, Bool_t ownership, Bool_t overwrite=kFALSE)
virtual void histogramCheckToggled(bool val)
virtual void createRateServices(int nodeindex)
std::vector< std::vector< std::deque< float > > > fxRateQueues
#define DABCMON_RATE_TRENDCOL
QTimer * fxDisplayTimer
std::vector< TGo4DabcServiceInfo * > fxServices
virtual void rateTableChangedSlot(int row, int column)
virtual bool getRateIndices(int tablerow, int &nodeix, int &rateix)
virtual void averageCheckToggled(bool val)
std::vector< std::vector< TGo4DabcRate > > fxRateRecords
virtual void fillNodeTableRow(int tableindex, int nodeindex, bool createnew)
std::vector< std::vector< unsigned int > > fxRateCount
std::vector< std::vector< std::vector< bool > > > fbStatsInit
QTimer * fxAverageTimer
virtual void displayRateTable()
virtual void deleteRateServices(int nodeindex)
virtual void rateUpdated(TGo4DabcRateInfo *info)
virtual void infoHandler()
void setDabcMonitorFreq(int secs)
#define DABCMON_NODE_STATECOL
virtual void displaySampleHistograms()
#define DABCMON_NODE_LOGCOL
TGo4BrowserProxy * Browser()
Definition: QGo4Widget.cpp:223
void setDabcMonitorBins(int num)
void setDabcMonitorBackwardsTrending(bool on=true)
virtual void displayAll()
#define DABCMON_RATE_NAMECOL
TGo4Slot * DataSlot(const char *item)
const QString & getServiceType()
virtual void infoHandler()
virtual void createLogServices(int nodeindex)
TObject * GetAssignedObject()
Definition: TGo4Slot.cxx:373
virtual void IncTrending(TH1 *histo, double value, bool forwards)
virtual void refreshDIMSlot()
std::vector< std::vector< bool > > fxStatsFlags
TGo4DabcMonitor * fxOwner
virtual void infoHandler()
std::vector< QString > fxDabcNodes
#define DABCMON_NODE_NODECOL
virtual void displayNodeTable()
QStringList fxNodelist
int getDabcMonitorBins()
TGo4QSettings * go4sett
unsigned int fxLastTimestamp
QString getDabcMonitorNode()
TGo4Slot * BrowserSlot(const char *item)
virtual void stateUpdated(TGo4DabcStateInfo *info)
bool getMbsMonitorBackwardsTrending()
static dabc::RateRec gNolinkRateRecord
TGo4DabcMonitor(QWidget *parent=0, const char *name=0)
virtual void nodesUpdated(TGo4DabcNodesInfo *info)
TGo4DabcNodesInfo * fxServerInfo
virtual void clearServices()
void ForwardEvent(TGo4Slot *source, Int_t id, void *param=0)
Definition: TGo4Slot.cxx:585
std::vector< TGo4DabcState > fxStateRecords
virtual void displayAverageHistograms()
virtual void infoHandler()
std::vector< std::vector< std::vector< QString > > > fxStatHistoRefnames
std::vector< std::vector< bool > > fxTrendingFlags
Bool_t AssignObject(TObject *obj, Bool_t owner)
Definition: TGo4Slot.cxx:361
virtual void servicesUpdated(TGo4DabcServiceInfo *info)
std::vector< std::vector< std::vector< QString > > > fxTrendHistoRefnames
virtual void infoUpdated(TGo4DabcInfo *info)
#define DABCMON_NODE_CHECKCOL
virtual void binsizeChanged(int val)
#define DABCMON_RATE_RATECOL
virtual void clearStates()
int getDabcMonitorFreq()
#define DABCMON_NODE_INDEXCOL
std::vector< std::vector< TGo4DabcRateInfo * > > fxRates
virtual void storeSettings()
#define DABCMON_RATE_INDEXCOL
virtual void logDIMSlot()
virtual void fillRateTableRow(int tableindex, int nodeindex, int rateindex, bool createnew)
static void SetItemTimeDate(TGo4Slot *slot, const char *stime=0, const char *sdate=0)
#define DABCMON_RATE_STATSCOL
virtual void updateTrending(int nodeix, int rateix, int hisix, double value)
virtual void nodeTableChangedSlot(int row, int column)