source: trunk/FACT++/gui/FactGui.h@ 10942

Last change on this file since 10942 was 10937, checked in by tbretz, 15 years ago
Implemented some first FAD stuff.
File size: 65.0 KB
Line 
1#ifndef FACT_FactGui
2#define FACT_FactGui
3
4#include "MainWindow.h"
5
6#include <iomanip>
7#include <valarray>
8
9#include <boost/bind.hpp>
10
11#include <QTimer>
12#include <QStandardItemModel>
13
14#include "CheckBoxDelegate.h"
15
16#include "src/Dim.h"
17#include "src/Converter.h"
18#include "src/HeadersFTM.h"
19#include "src/HeadersFAD.h"
20#include "src/DimNetwork.h"
21#include "src/tools.h"
22
23#include "TROOT.h"
24#include "TSystem.h"
25#include "TGraph.h"
26#include "TH1.h"
27#include "TStyle.h"
28#include "TMarker.h"
29#include "TColor.h"
30
31using namespace std;
32
33// #########################################################################
34
35class Camera : public TObject
36{
37 typedef pair<double,double> Position;
38 typedef vector<Position> Positions;
39
40 Positions fGeom;
41
42 void CreatePalette()
43 {
44 /*
45 double ss[5] = {0., 0.10, 0.45, 0.75, 1.00};
46 double rr[5] = {0., 0.35, 0.85, 1.00, 1.00};
47 double gg[5] = {0., 0.10, 0.20, 0.73, 1.00};
48 double bb[5] = {0., 0.03, 0.06, 0.00, 1.00};
49 */
50 double ss[5] = {0., 0.25, 0.50, 0.75, 1.00};
51 double rr[5] = {0., 0.00, 0.00, 1.00, 1.00};
52 double gg[5] = {0., 0.00, 1.00, 0.00, 1.00};
53 double bb[5] = {0., 1.00, 0.00, 0.00, 1.00};
54
55 const Int_t nn = 1440;
56
57 Int_t idx = TColor::CreateGradientColorTable(5, ss, rr, gg, bb, nn);
58 for (int i=0; i<nn; i++)
59 fPalette.push_back(idx++);
60 }
61
62 void CreateGeometry()
63 {
64 const double gsSin60 = sqrt(3.)/2;
65
66 const int rings = 23;
67
68 // add the first pixel to the list
69
70 fGeom.push_back(make_pair(0, -0.5));
71
72 for (int ring=1; ring<=rings; ring++)
73 {
74 for (int s=0; s<6; s++)
75 {
76 for (int i=1; i<=ring; i++)
77 {
78 double xx, yy;
79 switch (s)
80 {
81 case 0: // Direction South East
82 xx = (ring+i)*0.5;
83 yy = (-ring+i)*gsSin60;
84 break;
85
86 case 1: // Direction North East
87 xx = ring-i*0.5;
88 yy = i*gsSin60;
89 break;
90
91 case 2: // Direction North
92 xx = ring*0.5-i;
93 yy = ring*gsSin60;
94 break;
95
96 case 3: // Direction North West
97 xx = -(ring+i)*0.5;
98 yy = (ring-i)*gsSin60;
99 break;
100
101 case 4: // Direction South West
102 xx = 0.5*i-ring;
103 yy = -i*gsSin60;
104 break;
105
106 case 5: // Direction South
107 xx = i-ring*0.5;
108 yy = -ring*gsSin60;
109 break;
110 }
111
112 if (xx*xx + yy*yy - xx > 395.75)
113 continue;
114
115 fGeom.push_back(make_pair(yy, xx-0.5));
116 }
117 }
118 }
119 }
120
121 valarray<double> fData;
122 vector<bool> fBold;
123 vector<bool> fEnable;
124
125 int fWhite;
126
127public:
128 Camera() : fData(1440), fBold(1440), fEnable(1440), fWhite(-1)
129 {
130 CreatePalette();
131 CreateGeometry();
132
133 for (int i=0; i<1440; i++)
134 {
135 fData[i] = i;
136 fBold[i]=false;
137 fEnable[i]=true;
138 }
139 }
140
141 void Reset() { fBold.assign(1440, false); }
142
143 void SetBold(int idx) { fBold[idx]=true; }
144 void SetWhite(int idx) { fWhite=idx; }
145 void SetEnable(int idx, bool b) { fEnable[idx]=b; }
146 void Toggle(int idx) { fEnable[idx]=!fEnable[idx]; }
147 double GetData(int idx) const { return fData[idx]; }
148
149 const char *GetName() const { return "Camera"; }
150
151 vector<Int_t> fPalette;
152
153 void Paint(const Position &p)
154 {
155 static const Double_t fgCos60 = 0.5; // TMath::Cos(60/TMath::RadToDeg());
156 static const Double_t fgSin60 = sqrt(3.)/2; // TMath::Sin(60/TMath::RadToDeg());
157
158 static const Double_t fgDy[6] = { fgCos60, 0., -fgCos60, -fgCos60, 0., fgCos60 };
159 static const Double_t fgDx[6] = { fgSin60/3, fgSin60*2/3, fgSin60/3, -fgSin60/3, -fgSin60*2/3, -fgSin60/3 };
160
161 //
162 // calculate the positions of the pixel corners
163 //
164 Double_t x[7], y[7];
165 for (Int_t i=0; i<7; i++)
166 {
167 x[i] = p.first + fgDx[i%6];
168 y[i] = p.second + fgDy[i%6];
169 }
170
171 gPad->PaintFillArea(6, x, y);
172 gPad->PaintPolyLine(7, x, y);
173
174 }
175
176 void Paint(Option_t *)
177 {
178 gStyle->SetPalette(fPalette.size(), fPalette.data());
179
180
181 const double r = double(gPad->GetWw())/gPad->GetWh();
182 const double max = 20.5; // 20.5 rings in x and y
183
184 if (r>1)
185 gPad->Range(-r*max, -max, r*max, max);
186 else
187 gPad->Range(-max, -max/r, max, max/r);
188
189
190 const double min = fData.min();
191 const double scale = fData.max()==fData.min() ? 1 : fData.max()-fData.min();
192
193 TAttFill fill(0, 1001);
194 TAttLine line;
195
196 int cnt=0;
197 for (Positions::iterator p=fGeom.begin(); p!=fGeom.end(); p++, cnt++)
198 {
199 if (fBold[cnt])
200 continue;
201
202 const int col = (fData[cnt]-min)/scale*(fPalette.size()-1);
203
204 if (fEnable[cnt])
205 fill.SetFillColor(gStyle->GetColorPalette(col));
206 else
207 fill.SetFillColor(kWhite);
208
209 fill.Modify();
210
211 Paint(*p);
212 }
213
214 line.SetLineWidth(2);
215 line.Modify();
216
217 cnt = 0;
218 for (Positions::iterator p=fGeom.begin(); p!=fGeom.end(); p++, cnt++)
219 {
220 if (!fBold[cnt])
221 continue;
222
223 const int col = (fData[cnt]-min)/scale*(fPalette.size()-1);
224
225 if (fEnable[cnt])
226 fill.SetFillColor(gStyle->GetColorPalette(col));
227 else
228 fill.SetFillColor(kWhite);
229 fill.Modify();
230
231 Paint(*p);
232 }
233
234 TMarker m(0,0,kStar);
235 m.DrawMarker(0, 0);
236
237 if (fWhite<0)
238 return;
239
240 const Position &p = fGeom[fWhite];
241
242 line.SetLineColor(kWhite);
243 line.Modify();
244
245 const int col = (fData[fWhite]-min)/scale*(fPalette.size()-1);
246
247 if (fEnable[fWhite])
248 fill.SetFillColor(gStyle->GetColorPalette(col));
249 else
250 fill.SetFillColor(kWhite);
251 fill.Modify();
252
253 Paint(p);
254 }
255
256 int GetIdx(float px, float py) const
257 {
258 static const double sqrt3 = sqrt(3);
259
260 int idx = 0;
261 for (Positions::const_iterator p=fGeom.begin(); p!=fGeom.end(); p++, idx++)
262 {
263 const Double_t dy = py - p->second;
264 if (fabs(dy)>0.5)
265 continue;
266
267 const Double_t dx = px - p->first;
268
269 if (TMath::Abs(dy + dx*sqrt3) > 1)
270 continue;
271
272 if (TMath::Abs(dy - dx*sqrt3) > 1)
273 continue;
274
275 return idx;
276 }
277 return -1;
278 }
279
280 char* GetObjectInfo(Int_t px, Int_t py) const
281 {
282 static stringstream stream;
283 static string str;
284
285 const float x = gPad->PadtoX(gPad->AbsPixeltoX(px));
286 const float y = gPad->PadtoY(gPad->AbsPixeltoY(py));
287
288 const int idx = GetIdx(x, y);
289
290 stream.seekp(0);
291 if (idx>=0)
292 stream << "Pixel=" << idx << "(" <</* fMapHW[idx] <<*/ ") Data=" << fData[idx] << '\0';
293
294 str = stream.str();
295 return const_cast<char*>(str.c_str());
296 }
297
298 Int_t DistancetoPrimitive(Int_t px, Int_t py)
299 {
300 const float x = gPad->PadtoX(gPad->AbsPixeltoX(px));
301 const float y = gPad->PadtoY(gPad->AbsPixeltoY(py));
302
303 return GetIdx(x, y)>=0 ? 0 : 99999;
304 }
305
306 void SetData(const valarray<double> &data)
307 {
308 fData = data;
309 }
310};
311
312// #########################################################################
313
314
315class FactGui : public MainWindow, public DimNetwork
316{
317private:
318 class FunctionEvent : public QEvent
319 {
320 public:
321 boost::function<void(const QEvent &)> fFunction;
322
323 FunctionEvent(const boost::function<void(const QEvent &)> &f)
324 : QEvent((QEvent::Type)QEvent::registerEventType()),
325 fFunction(f) { }
326
327 bool Exec() { fFunction(*this); return true; }
328 };
329
330 valarray<int8_t> fFtuStatus;
331
332// vector<int> fMapHW; // Software -> Hardware
333// map<int,int> fMapSW; // Hardware -> Software
334
335 DimStampedInfo fDimDNS;
336
337 DimStampedInfo fDimLoggerStats;
338 DimStampedInfo fDimLoggerFilenameNight;
339 DimStampedInfo fDimLoggerFilenameRun;
340 DimStampedInfo fDimLoggerNumSubs;
341
342 DimStampedInfo fDimFtmPassport;
343 DimStampedInfo fDimFtmTriggerCounter;
344 DimStampedInfo fDimFtmError;
345 DimStampedInfo fDimFtmFtuList;
346 DimStampedInfo fDimFtmStaticData;
347 DimStampedInfo fDimFtmDynamicData;
348 DimStampedInfo fDimFtmCounter;
349
350 DimStampedInfo fDimFadFiles;
351 DimStampedInfo fDimFadRuns;
352 DimStampedInfo fDimFadEvents;
353 DimStampedInfo fDimFadCurrentEvent;
354 DimStampedInfo fDimFadConnections;
355
356 map<string, DimInfo*> fServices;
357
358 // ========================== LED Colors ================================
359
360 enum LedColor_t
361 {
362 kLedRed,
363 kLedGreen,
364 kLedYellow,
365 kLedOrange,
366 kLedGray
367 };
368
369 void SetLedColor(QPushButton *button, LedColor_t col, const Time &t)
370 {
371 switch (col)
372 {
373 case kLedRed:
374 button->setIcon(QIcon(":/Resources/icons/red circle 1.png"));
375 break;
376
377 case kLedGreen:
378 button->setIcon(QIcon(":/Resources/icons/green circle 1.png"));
379 break;
380
381 case kLedYellow:
382 button->setIcon(QIcon(":/Resources/icons/yellow circle 1.png"));
383 break;
384
385 case kLedOrange:
386 button->setIcon(QIcon(":/Resources/icons/orange circle 1.png"));
387 break;
388
389 case kLedGray:
390 button->setIcon(QIcon(":/Resources/icons/gray circle 1.png"));
391 break;
392 }
393
394 //button->setToolTip("Last change: "+QDateTime::currentDateTimeUtc().toString()+" UTC");
395 button->setToolTip(("Last change: "+t.GetAsStr()+" UTC").c_str());
396 }
397
398 // ===================== Services and Commands ==========================
399
400 QStandardItem *AddServiceItem(const std::string &server, const std::string &service, bool iscmd)
401 {
402 QListView *servers = iscmd ? fDimCmdServers : fDimSvcServers;
403 QListView *services = iscmd ? fDimCmdCommands : fDimSvcServices;
404 QListView *description = iscmd ? fDimCmdDescription : fDimSvcDescription;
405
406 QStandardItemModel *m = dynamic_cast<QStandardItemModel*>(servers->model());
407 if (!m)
408 {
409 m = new QStandardItemModel(this);
410 servers->setModel(m);
411 services->setModel(m);
412 description->setModel(m);
413 }
414
415 QList<QStandardItem*> l = m->findItems(server.c_str());
416
417 if (l.size()>1)
418 {
419 cout << "hae" << endl;
420 return 0;
421 }
422
423 QStandardItem *col = l.size()==0 ? NULL : l[0];
424
425 if (!col)
426 {
427 col = new QStandardItem(server.c_str());
428 m->appendRow(col);
429
430 if (!services->rootIndex().isValid())
431 {
432 services->setRootIndex(col->index());
433 servers->setCurrentIndex(col->index());
434 }
435 }
436
437 QStandardItem *item = 0;
438 for (int i=0; i<col->rowCount(); i++)
439 {
440 QStandardItem *coli = col->child(i);
441 if (coli->text().toStdString()==service)
442 return coli;
443 }
444
445 item = new QStandardItem(service.c_str());
446 col->appendRow(item);
447 col->sortChildren(0);
448
449 if (!description->rootIndex().isValid())
450 {
451 description->setRootIndex(item->index());
452 services->setCurrentIndex(item->index());
453 }
454
455 if (!iscmd)
456 item->setCheckable(true);
457
458 return item;
459 }
460
461 void AddDescription(QStandardItem *item, const vector<Description> &vec)
462 {
463 if (!item)
464 return;
465 if (vec.size()==0)
466 return;
467
468 item->setToolTip(vec[0].comment.c_str());
469
470 const string str = Description::GetHtmlDescription(vec);
471
472 QStandardItem *desc = new QStandardItem(str.c_str());
473 desc->setSelectable(false);
474 item->setChild(0, 0, desc);
475 }
476
477 void AddServer(const std::string &s)
478 {
479 DimNetwork::AddServer(s);
480
481 QApplication::postEvent(this,
482 new FunctionEvent(boost::bind(&FactGui::handleAddServer, this, s)));
483 }
484
485 void RemoveServer(const std::string &s)
486 {
487 UnsubscribeServer(s);
488
489 DimNetwork::RemoveServer(s);
490
491 QApplication::postEvent(this,
492 new FunctionEvent(boost::bind(&FactGui::handleRemoveServer, this, s)));
493 }
494
495 void RemoveAllServers()
496 {
497 UnsubscribeAllServers();
498
499 vector<string> v = GetServerList();
500 for (vector<string>::iterator i=v.begin(); i<v.end(); i++)
501 QApplication::postEvent(this,
502 new FunctionEvent(boost::bind(&FactGui::handleStateOffline, this, *i)));
503
504 DimNetwork::RemoveAllServers();
505
506 QApplication::postEvent(this,
507 new FunctionEvent(boost::bind(&FactGui::handleRemoveAllServers, this)));
508 }
509
510 void AddService(const std::string &server, const std::string &service, const std::string &fmt, bool iscmd)
511 {
512 QApplication::postEvent(this,
513 new FunctionEvent(boost::bind(&FactGui::handleAddService, this, server, service, fmt, iscmd)));
514 }
515
516 void RemoveService(const std::string &server, const std::string &service, bool iscmd)
517 {
518 if (fServices.find(server+'/'+service)!=fServices.end())
519 UnsubscribeService(server+'/'+service);
520
521 QApplication::postEvent(this,
522 new FunctionEvent(boost::bind(&FactGui::handleRemoveService, this, server, service, iscmd)));
523 }
524
525 void RemoveAllServices(const std::string &server)
526 {
527 UnsubscribeServer(server);
528
529 QApplication::postEvent(this,
530 new FunctionEvent(boost::bind(&FactGui::handleRemoveAllServices, this, server)));
531 }
532
533 void AddDescription(const std::string &server, const std::string &service, const vector<Description> &vec)
534 {
535 QApplication::postEvent(this,
536 new FunctionEvent(boost::bind(&FactGui::handleAddDescription, this, server, service, vec)));
537 }
538
539 // ======================================================================
540
541 void handleAddServer(const std::string &server)
542 {
543 const State s = GetState(server, GetCurrentState(server));
544 handleStateChanged(Time(), server, s);
545 }
546
547 void handleRemoveServer(const string &server)
548 {
549 handleStateOffline(server);
550 handleRemoveAllServices(server);
551 }
552
553 void handleRemoveAllServers()
554 {
555 QStandardItemModel *m = 0;
556 if ((m=dynamic_cast<QStandardItemModel*>(fDimCmdServers->model())))
557 m->removeRows(0, m->rowCount());
558
559 if ((m = dynamic_cast<QStandardItemModel*>(fDimSvcServers->model())))
560 m->removeRows(0, m->rowCount());
561 }
562
563 void handleAddService(const std::string &server, const std::string &service, const std::string &/*fmt*/, bool iscmd)
564 {
565 QStandardItem *item = AddServiceItem(server, service, iscmd);
566 const vector<Description> v = GetDescription(server, service);
567 AddDescription(item, v);
568 }
569
570 void handleRemoveService(const std::string &server, const std::string &service, bool iscmd)
571 {
572 QListView *servers = iscmd ? fDimCmdServers : fDimSvcServers;
573
574 QStandardItemModel *m = dynamic_cast<QStandardItemModel*>(servers->model());
575 if (!m)
576 return;
577
578 QList<QStandardItem*> l = m->findItems(server.c_str());
579 if (l.size()!=1)
580 return;
581
582 for (int i=0; i<l[0]->rowCount(); i++)
583 {
584 QStandardItem *row = l[0]->child(i);
585 if (row->text().toStdString()==service)
586 {
587 l[0]->removeRow(row->index().row());
588 return;
589 }
590 }
591 }
592
593 void handleRemoveAllServices(const std::string &server)
594 {
595 QStandardItemModel *m = 0;
596 if ((m=dynamic_cast<QStandardItemModel*>(fDimCmdServers->model())))
597 {
598 QList<QStandardItem*> l = m->findItems(server.c_str());
599 if (l.size()==1)
600 m->removeRow(l[0]->index().row());
601 }
602
603 if ((m = dynamic_cast<QStandardItemModel*>(fDimSvcServers->model())))
604 {
605 QList<QStandardItem*> l = m->findItems(server.c_str());
606 if (l.size()==1)
607 m->removeRow(l[0]->index().row());
608 }
609 }
610
611 void handleAddDescription(const std::string &server, const std::string &service, const vector<Description> &vec)
612 {
613 const bool iscmd = IsCommand(server, service)==true;
614
615 QStandardItem *item = AddServiceItem(server, service, iscmd);
616 AddDescription(item, vec);
617 }
618
619 // ======================================================================
620
621 void SubscribeService(const string &service)
622 {
623 if (fServices.find(service)!=fServices.end())
624 {
625 cout << "ERROR - We are already subscribed to " << service << endl;
626 return;
627 }
628
629 fServices[service] = new DimStampedInfo(service.c_str(), (void*)NULL, 0, this);
630 }
631
632 void UnsubscribeService(const string &service)
633 {
634 const map<string,DimInfo*>::iterator i=fServices.find(service);
635
636 if (i==fServices.end())
637 {
638 cout << "ERROR - We are not subscribed to " << service << endl;
639 return;
640 }
641
642 delete i->second;
643
644 fServices.erase(i);
645 }
646
647 void UnsubscribeServer(const string &server)
648 {
649 for (map<string,DimInfo*>::iterator i=fServices.begin();
650 i!=fServices.end(); i++)
651 if (i->first.substr(0, server.length()+1)==server+'/')
652 {
653 delete i->second;
654 fServices.erase(i);
655 }
656 }
657
658 void UnsubscribeAllServers()
659 {
660 for (map<string,DimInfo*>::iterator i=fServices.begin();
661 i!=fServices.end(); i++)
662 delete i->second;
663
664 fServices.clear();
665 }
666
667 // ======================================================================
668
669 struct DimData
670 {
671 Time time;
672 int qos;
673 string name;
674 string format;
675 vector<char> data;
676
677 DimInfo *info; // this is ONLY for a fast check of the type of the DimData!!
678
679 DimData(DimInfo *inf) :
680 qos(inf->getQuality()),
681 name(inf->getName()),
682 format(inf->getFormat()),
683 data(inf->getString(), inf->getString()+inf->getSize()),
684 info(inf)
685 {
686 // Must be called in exactly this order!
687 const int tsec = inf->getTimestamp();
688 const int tms = inf->getTimestampMillisecs();
689
690 time = Time(tsec, tms*1000);
691 }
692
693 template<typename T>
694 T get(uint32_t offset=0) const { return *reinterpret_cast<const T*>(data.data()+offset); }
695
696 template<typename T>
697 const T *ptr(uint32_t offset=0) const { return reinterpret_cast<const T*>(data.data()+offset); }
698
699 template<typename T>
700 const T &ref(uint32_t offset=0) const { return *reinterpret_cast<const T*>(data.data()+offset); }
701
702 vector<char> vec(int b) const { return vector<char>(data.begin()+b, data.end()); }
703 string str(unsigned int b) const { return b>=data.size()?string():string(data.data()+b, data.size()-b); }
704 const char *c_str() const { return (char*)data.data(); }
705
706 vector<boost::any> any() const
707 {
708 const Converter conv(format);
709 conv.Print();
710 return conv.GetAny(data.data(), data.size());
711 }
712 int size() const { return data.size(); }
713 };
714
715 // ======================= DNS ==========================================
716
717 void handleDimDNS(const DimData &d)
718 {
719 const int version = d.get<unsigned int>();
720
721 ostringstream str;
722 str << "V" << version/100 << 'r' << version%100;
723
724 SetLedColor(fStatusDNSLed, version==0 ? kLedRed : kLedGreen, Time());
725
726 fStatusDNSLabel->setText(version==0?"Offline":str.str().c_str());
727 fStatusDNSLabel->setToolTip(version==0?"No connection to DIM DNS.":"Connection to DIM DNS established.");
728 }
729
730
731 // ======================= Logger =======================================
732
733 void handleLoggerStats(const DimData &d)
734 {
735 const bool connected = d.size()!=0;
736
737 fLoggerET->setEnabled(connected);
738 fLoggerRate->setEnabled(connected);
739 fLoggerWritten->setEnabled(connected);
740 fLoggerFreeSpace->setEnabled(connected);
741 fLoggerSpaceLeft->setEnabled(connected);
742
743 if (!connected)
744 return;
745
746 const uint64_t *vals = d.ptr<uint64_t>();
747
748 const size_t written = vals[0];
749 const size_t space = vals[1];
750 const size_t rate = vals[2];
751
752 fLoggerFreeSpace->setSuffix(" MB");
753 fLoggerFreeSpace->setDecimals(0);
754 fLoggerFreeSpace->setValue(space*1e-6);
755
756 if (space> 1000000) // > 1GB
757 {
758 fLoggerFreeSpace->setSuffix(" GB");
759 fLoggerFreeSpace->setDecimals(2);
760 fLoggerFreeSpace->setValue(space*1e-9);
761 }
762 if (space>= 3000000) // >= 3GB
763 {
764 fLoggerFreeSpace->setSuffix(" GB");
765 fLoggerFreeSpace->setDecimals(1);
766 fLoggerFreeSpace->setValue(space*1e-9);
767 }
768 if (space>=100000000) // >= 100GB
769 {
770 fLoggerFreeSpace->setSuffix(" GB");
771 fLoggerFreeSpace->setDecimals(0);
772 fLoggerFreeSpace->setValue(space*1e-9);
773 }
774
775 fLoggerET->setTime(QTime().addSecs(rate>0?space/rate:0));
776 fLoggerRate->setValue(rate*1e-3); // kB/s
777 fLoggerWritten->setValue(written*1e-6);
778
779 fLoggerRate->setSuffix(" kB/s");
780 fLoggerRate->setDecimals(2);
781 fLoggerRate->setValue(rate*1e-3);
782 if (rate> 2000) // > 2kB/s
783 {
784 fLoggerRate->setSuffix(" kB/s");
785 fLoggerRate->setDecimals(1);
786 fLoggerRate->setValue(rate*1e-3);
787 }
788 if (rate>=100000) // >100kB/s
789 {
790 fLoggerRate->setSuffix(" kB/s");
791 fLoggerRate->setDecimals(0);
792 fLoggerRate->setValue(rate*1e-3);
793 }
794 if (rate>=1000000) // >100kB/s
795 {
796 fLoggerRate->setSuffix(" MB/s");
797 fLoggerRate->setDecimals(2);
798 fLoggerRate->setValue(rate*1e-6);
799 }
800 if (rate>=10000000) // >1MB/s
801 {
802 fLoggerRate->setSuffix(" MB/s");
803 fLoggerRate->setDecimals(1);
804 fLoggerRate->setValue(rate*1e-6);
805 }
806 if (rate>=100000000) // >10MB/s
807 {
808 fLoggerRate->setSuffix(" MB/s");
809 fLoggerRate->setDecimals(0);
810 fLoggerRate->setValue(rate*1e-6);
811 }
812
813 if (space/1000000>static_cast<size_t>(fLoggerSpaceLeft->maximum()))
814 fLoggerSpaceLeft->setValue(fLoggerSpaceLeft->maximum()); // GB
815 else
816 fLoggerSpaceLeft->setValue(space/1000000); // MB
817 }
818
819 void handleLoggerFilenameNight(const DimData &d)
820 {
821 const bool connected = d.size()!=0;
822
823 fLoggerFilenameNight->setEnabled(connected);
824 if (!connected)
825 return;
826
827 fLoggerFilenameNight->setText(d.c_str()+4);
828
829 const uint32_t files = d.get<uint32_t>();
830
831 SetLedColor(fLoggerLedLog, files&1 ? kLedGreen : kLedGray, d.time);
832 SetLedColor(fLoggerLedRep, files&2 ? kLedGreen : kLedGray, d.time);
833 SetLedColor(fLoggerLedFits, files&4 ? kLedGreen : kLedGray, d.time);
834 }
835
836 void handleLoggerFilenameRun(const DimData &d)
837 {
838 const bool connected = d.size()!=0;
839
840 fLoggerFilenameRun->setEnabled(connected);
841 if (!connected)
842 return;
843
844 fLoggerFilenameRun->setText(d.c_str()+4);
845
846 const uint32_t files = d.get<uint32_t>();
847
848 SetLedColor(fLoggerLedLog, files&1 ? kLedGreen : kLedGray, d.time);
849 SetLedColor(fLoggerLedRep, files&2 ? kLedGreen : kLedGray, d.time);
850 SetLedColor(fLoggerLedFits, files&4 ? kLedGreen : kLedGray, d.time);
851 }
852
853 void handleLoggerNumSubs(const DimData &d)
854 {
855 const bool connected = d.size()!=0;
856
857 fLoggerSubscriptions->setEnabled(connected);
858 fLoggerOpenFiles->setEnabled(connected);
859 if (!connected)
860 return;
861
862 const uint32_t *vals = d.ptr<uint32_t>();
863
864 fLoggerSubscriptions->setValue(vals[0]);
865 fLoggerOpenFiles->setValue(vals[1]);
866 }
867
868 // ===================== FAD ============================================
869
870 void handleFadFiles(const DimData &d)
871 {
872 if (d.size()==0)
873 return;
874
875 if (d.size()!=8)
876 {
877 cout << "Size mismatch: " << d.size() << " " << 8 << endl;
878 return;
879 }
880
881 fEvtBuilderOpenFiles->setValue(d.get<uint64_t>());
882 }
883
884 void handleFadRuns(const DimData &d)
885 {
886 if (d.size()==0)
887 return;
888
889 if (d.size()!=4)
890 {
891 cout << "Size mismatch: " << d.size() << " " << 8 << endl;
892 return;
893 }
894
895 fEvtsRunMax->setValue(d.get<uint32_t>());
896 }
897
898 void handleFadEvents(const DimData &d)
899 {
900 if (d.size()==0)
901 return;
902
903 if (d.size()!=8)
904 {
905 cout << "Size mismatch: " << d.size() << " " << 8 << endl;
906 return;
907 }
908
909 const uint32_t *ptr = d.ptr<uint32_t>();
910
911 fEvtsSuccessCurRun->setValue(ptr[0]);
912 fEvtsSuccessTotal->setValue(ptr[1]);
913 }
914
915 void handleFadCurrentEvent(const DimData &d)
916 {
917 if (d.size()==0)
918 return;
919
920 if (d.size()!=4)
921 {
922 cout << "Size mismatch: " << d.size() << " " << 4 << endl;
923 return;
924 }
925
926 fEvtsTriggerId->setValue(d.get<uint32_t>());
927 }
928
929 void handleFadConnections(const DimData &d)
930 {
931 if (d.size()==0)
932 return;
933
934 if (d.size()!=40)
935 {
936 cout << "Size mismatch: " << d.size() << " " << 40 << endl;
937 return;
938 }
939
940 const uint8_t *ptr = d.ptr<uint8_t>();
941
942 for (int i=0; i<40; i++)
943 {
944 switch (ptr[i])
945 {
946 case 0: SetLedColor(fFadLED[i], kLedGray, d.time); break;
947 case 9: SetLedColor(fFadLED[i], kLedGreen, d.time); break;
948 default: SetLedColor(fFadLED[i], kLedOrange, d.time);
949 }
950 }
951 }
952
953 // ===================== FTM ============================================
954
955 double fTimeStamp1;
956
957 void handleFtmTriggerCounter(const DimData &d)
958 {
959 if (d.size()==0)
960 return;
961
962 if (d.size()!=sizeof(FTM::DimTriggerCounter))
963 {
964 cout << "Size mismatch: " << d.size() << " " << sizeof(FTM::DimTriggerCounter) << endl;
965 return;
966 }
967
968 const FTM::DimTriggerCounter &sdata = d.ref<FTM::DimTriggerCounter>();
969
970 fFtmTime->setText(QString::number(sdata.fTimeStamp/1000000., 'f', 6)+ " s");
971 fTriggerCounter->setText(QString::number(sdata.fTriggerCounter));
972
973 if (sdata.fTimeStamp>0)
974 fTriggerCounterRate->setValue(1000000.*sdata.fTriggerCounter/sdata.fTimeStamp);
975 else
976 fTriggerCounterRate->setValue(0);
977
978
979 // ----------------------------------------------
980#ifdef HAVE_ROOT
981
982 if (fTriggerCounter0<0)
983 {
984 fTriggerCounter0 = sdata.fTriggerCounter;
985 fTimeStamp1 = sdata.fTimeStamp;
986 return;
987 }
988
989 TCanvas *c = fFtmRateCanv->GetCanvas();
990
991 TH1 *h = (TH1*)c->FindObject("TimeFrame");
992
993 const double rate = sdata.fTriggerCounter-fTriggerCounter0;
994 const double tdiff = sdata.fTimeStamp -fTimeStamp1;
995
996 fTriggerCounter0 = sdata.fTriggerCounter;
997 fTimeStamp1 = sdata.fTimeStamp;
998
999 if (rate<0 && tdiff<=0)
1000 {
1001 fGraphFtmRate.Set(0);
1002
1003 const double tm = Time().RootTime();
1004
1005 h->SetBins(1, tm, tm+60);
1006 h->GetXaxis()->SetTimeFormat("%M'%S\"");
1007 h->GetXaxis()->SetTitle("Time");
1008
1009 c->Modified();
1010 c->Update();
1011 return;
1012 }
1013
1014 if (rate<0)
1015 return;
1016
1017 const double avgrate = sdata.fTimeStamp>0 ? double(sdata.fTriggerCounter)/sdata.fTimeStamp*1000000 : 1;
1018
1019 const double t1 = h->GetXaxis()->GetXmax();
1020 const double t0 = h->GetXaxis()->GetXmin();
1021
1022 h->SetBins(h->GetNbinsX()+1, t0, t0+sdata.fTimeStamp/1000000.+1);
1023 fGraphFtmRate.SetPoint(fGraphFtmRate.GetN(),
1024 t0+sdata.fTimeStamp/1000000., 1000000*rate/tdiff);
1025
1026 if (t1-t0>60)
1027 {
1028 h->GetXaxis()->SetTimeFormat("%Hh%M'");
1029 h->GetXaxis()->SetTitle("Time");
1030 }
1031
1032 h->SetMinimum(0);
1033 h->SetMaximum(2*avgrate);
1034
1035 c->Modified();
1036 c->Update();
1037#endif
1038 // ----------------------------------------------
1039 }
1040
1041 void handleFtmCounter(const DimData &d)
1042 {
1043 if (d.size()==0)
1044 return;
1045
1046 if (d.size()!=sizeof(uint32_t)*6)
1047 {
1048 cout << "Size mismatch: " << d.size() << " " << sizeof(uint32_t)*6 << endl;
1049 return;
1050 }
1051
1052 const uint32_t *sdata = d.ptr<uint32_t>();
1053
1054 fFtmCounterH->setValue(sdata[0]);
1055 fFtmCounterS->setValue(sdata[1]);
1056 fFtmCounterD->setValue(sdata[2]);
1057 fFtmCounterF->setValue(sdata[3]);
1058 fFtmCounterE->setValue(sdata[4]);
1059 fFtmCounterR->setValue(sdata[5]);
1060 }
1061
1062 int64_t fTriggerCounter0;
1063 int64_t fTimeStamp0;
1064
1065 void handleFtmDynamicData(const DimData &d)
1066 {
1067 if (d.size()==0)
1068 return;
1069
1070 if (d.size()!=sizeof(FTM::DimDynamicData))
1071 {
1072 cout << "Size mismatch: " << d.size() << " " << sizeof(FTM::DimDynamicData) << endl;
1073 return;
1074 }
1075
1076 const FTM::DimDynamicData &sdata = d.ref<FTM::DimDynamicData>();
1077
1078 fOnTime->setText(QString::number(sdata.fOnTimeCounter/1000000., 'f', 6)+" s");
1079
1080 if (sdata.fTimeStamp>0)
1081 fOnTimeRel->setValue(100.*sdata.fOnTimeCounter/sdata.fTimeStamp);
1082 else
1083 fOnTimeRel->setValue(0);
1084
1085 fFtmTemp0->setValue(sdata.fTempSensor[0]*0.1);
1086 fFtmTemp1->setValue(sdata.fTempSensor[1]*0.1);
1087 fFtmTemp2->setValue(sdata.fTempSensor[2]*0.1);
1088 fFtmTemp3->setValue(sdata.fTempSensor[3]*0.1);
1089
1090
1091#ifdef HAVE_ROOT
1092
1093 // ----------------------------------------------
1094/*
1095 TCanvas *c = fFtmTempCanv->GetCanvas();
1096
1097// static int cntr = 0;
1098// double_t tm = cntr++;//Time().RootTime();
1099
1100 double tm = d.time.RootTime();
1101
1102 TH1 *h = (TH1*)c->FindObject("TimeFrame");
1103 h->FindBin(tm);
1104
1105 fGraphFtmTemp[0].SetPoint(fGraphFtmTemp[0].GetN(), tm, sdata.fTempSensor[0]*0.1);
1106 fGraphFtmTemp[1].SetPoint(fGraphFtmTemp[1].GetN(), tm, sdata.fTempSensor[1]*0.1);
1107 fGraphFtmTemp[2].SetPoint(fGraphFtmTemp[2].GetN(), tm, sdata.fTempSensor[2]*0.1);
1108 fGraphFtmTemp[3].SetPoint(fGraphFtmTemp[3].GetN(), tm, sdata.fTempSensor[3]*0.1);
1109
1110 c->Modified();
1111 c->Update();
1112*/
1113 // ----------------------------------------------
1114
1115 if (fTimeStamp0<0)
1116 {
1117 fTimeStamp0 = sdata.fTimeStamp;
1118 return;
1119 }
1120
1121 TCanvas *c = fFtmRateCanv->GetCanvas();
1122
1123 TH1 *h = (TH1*)c->FindObject("TimeFrame");
1124
1125 const double tdiff = sdata.fTimeStamp-fTimeStamp0;
1126 fTimeStamp0 = sdata.fTimeStamp;
1127
1128 if (tdiff<0)
1129 {
1130 for (int i=0; i<160; i++)
1131 fGraphPatchRate[i].Set(0);
1132 for (int i=0; i<40; i++)
1133 fGraphBoardRate[i].Set(0);
1134
1135 return;
1136 }
1137
1138 //const double t1 = h->GetXaxis()->GetXmax();
1139 const double t0 = h->GetXaxis()->GetXmin();
1140
1141 for (int i=0; i<160; i++)
1142 fGraphPatchRate[i].SetPoint(fGraphPatchRate[i].GetN(),
1143 t0+sdata.fTimeStamp, float(sdata.fRatePatch[i])/fFtmStaticData.fPrescaling[i]/1000);
1144 for (int i=0; i<40; i++)
1145 fGraphBoardRate[i].SetPoint(fGraphBoardRate[i].GetN(),
1146 t0+sdata.fTimeStamp, float(sdata.fRateBoard[i])/fFtmStaticData.fPrescaling[i]/1000);
1147
1148 c->Modified();
1149 c->Update();
1150
1151 // ----------------------------------------------
1152
1153 if (fThresholdIdx->value()>=0)
1154 fPatchRate->setValue(sdata.fRatePatch[fThresholdIdx->value()]);
1155
1156 valarray<double> dat(0., 1440);
1157
1158 for (int i=0; i<1440; i++)
1159 dat[i] = sdata.fRatePatch[fPatch[i]];
1160
1161 c = fRatesCanv->GetCanvas();
1162 Camera *cam = (Camera*)c->FindObject("Camera");
1163
1164 cam->SetData(dat);
1165
1166 c->Modified();
1167 c->Update();
1168#endif
1169 }
1170
1171 void DisplayRates()
1172 {
1173#ifdef HAVE_ROOT
1174 TCanvas *c = fFtmRateCanv->GetCanvas();
1175
1176 while (c->FindObject("PatchRate"))
1177 c->GetListOfPrimitives()->Remove(c->FindObject("PatchRate"));
1178
1179 while (c->FindObject("BoardRate"))
1180 c->GetListOfPrimitives()->Remove(c->FindObject("BoardRate"));
1181
1182 if (fRatePatch1->value()>=0)
1183 fGraphPatchRate[fRatePatch1->value()].Draw("PL");
1184 if (fRatePatch2->value()>=0)
1185 fGraphPatchRate[fRatePatch2->value()].Draw("PL");
1186 if (fRateBoard1->value()>=0)
1187 fGraphBoardRate[fRateBoard1->value()].Draw("PL");
1188 if (fRateBoard2->value()>=0)
1189 fGraphBoardRate[fRateBoard2->value()].Draw("PL");
1190#endif
1191 }
1192
1193 void on_fRatePatch1_valueChanged(int)
1194 {
1195 DisplayRates();
1196 }
1197
1198 void on_fRatePatch2_valueChanged(int)
1199 {
1200 DisplayRates();
1201 }
1202
1203 void on_fRateBoard1_valueChanged(int)
1204 {
1205 DisplayRates();
1206 }
1207
1208 void on_fRateBoard2_valueChanged(int)
1209 {
1210 DisplayRates();
1211 }
1212
1213 FTM::DimStaticData fFtmStaticData;
1214
1215 void SetFtuLed(int idx, int counter, const Time &t)
1216 {
1217 if (counter==0 || counter>3)
1218 counter = 3;
1219
1220 if (counter<0)
1221 counter = 0;
1222
1223 const LedColor_t col[4] = { kLedGray, kLedGreen, kLedOrange, kLedRed };
1224
1225 SetLedColor(fFtuLED[idx], col[counter], t);
1226
1227 fFtuStatus[idx] = counter;
1228 }
1229
1230 void SetFtuStatusLed(const Time &t)
1231 {
1232 const int max = fFtuStatus.max();
1233
1234 switch (max)
1235 {
1236 case 0:
1237 SetLedColor(fStatusFTULed, kLedGray, t);
1238 fStatusFTULabel->setText("All disabled");
1239 fStatusFTULabel->setToolTip("All FTUs are disabled");
1240 break;
1241
1242 case 1:
1243 SetLedColor(fStatusFTULed, kLedGreen, t);
1244 fStatusFTULabel->setToolTip("Communication with FTU is smooth.");
1245 fStatusFTULabel->setText("ok");
1246 break;
1247
1248 case 2:
1249 SetLedColor(fStatusFTULed, kLedOrange, t);
1250 fStatusFTULabel->setText("Warning");
1251 fStatusFTULabel->setToolTip("At least one FTU didn't answer immediately");
1252 break;
1253
1254 case 3:
1255 SetLedColor(fStatusFTULed, kLedRed, t);
1256 fStatusFTULabel->setToolTip("At least one FTU didn't answer!");
1257 fStatusFTULabel->setText("ERROR");
1258 break;
1259 }
1260
1261 const int cnt = count(&fFtuStatus[0], &fFtuStatus[40], 0);
1262 fFtuAllOn->setEnabled(cnt!=0);
1263 fFtuAllOff->setEnabled(cnt!=40);
1264 }
1265
1266 void handleFtmStaticData(const DimData &d)
1267 {
1268 if (d.size()==0)
1269 return;
1270
1271 if (d.size()!=sizeof(FTM::DimStaticData))
1272 {
1273 cout << "Size mismatch: " << d.size() << " " << sizeof(FTM::DimStaticData) << endl;
1274 return;
1275 }
1276
1277 const FTM::DimStaticData &sdata = d.ref<FTM::DimStaticData>();
1278
1279 fTriggerInterval->setValue(sdata.fTriggerInterval);
1280 fPhysicsCoincidence->setValue(sdata.fMultiplicityPhysics);
1281 fCalibCoincidence->setValue(sdata.fMultiplicityCalib);
1282 fPhysicsWindow->setValue(sdata.fWindowPhysics);
1283 fCalibWindow->setValue(sdata.fWindowCalib);
1284
1285 fTriggerDelay->setValue(sdata.fDelayTrigger);
1286 fTimeMarkerDelay->setValue(sdata.fDelayTimeMarker);
1287 fDeadTime->setValue(sdata.fDeadTime);
1288
1289 fClockCondR0->setValue(sdata.fClockConditioner[0]);
1290 fClockCondR1->setValue(sdata.fClockConditioner[1]);
1291 fClockCondR8->setValue(sdata.fClockConditioner[2]);
1292 fClockCondR9->setValue(sdata.fClockConditioner[3]);
1293 fClockCondR11->setValue(sdata.fClockConditioner[4]);
1294 fClockCondR13->setValue(sdata.fClockConditioner[5]);
1295 fClockCondR14->setValue(sdata.fClockConditioner[6]);
1296 fClockCondR15->setValue(sdata.fClockConditioner[7]);
1297
1298 fTriggerSeqPed->setValue(sdata.fTriggerSeqPed);
1299 fTriggerSeqLPint->setValue(sdata.fTriggerSeqLPint);
1300 fTriggerSeqLPext->setValue(sdata.fTriggerSeqLPext);
1301
1302 fEnableTrigger->setChecked(sdata.HasTrigger());
1303 fEnableVeto->setChecked(sdata.HasVeto());
1304 fEnableExt1->setChecked(sdata.HasExt1());
1305 fEnableExt2->setChecked(sdata.HasExt2());
1306 fEnableClockCond->setChecked(sdata.HasClockConditioner());
1307
1308 for (int i=0; i<40; i++)
1309 {
1310 if (!sdata.IsActive(i))
1311 SetFtuLed(i, -1, d.time);
1312 else
1313 {
1314 if (fFtuStatus[i]==0)
1315 SetFtuLed(i, 1, d.time);
1316 }
1317 fFtuLED[i]->setChecked(false);
1318 }
1319 SetFtuStatusLed(d.time);
1320
1321#ifdef HAVE_ROOT
1322 Camera *cam = (Camera*)fRatesCanv->GetCanvas()->FindObject("Camera");
1323 for (int i=0; i<1440; i++)
1324 cam->SetEnable(i, sdata.IsEnabled(i));
1325#endif
1326
1327 fPixelEnable->setChecked(sdata.IsEnabled(fPixelIdx->value()));
1328
1329 const int patch1 = fThresholdIdx->value();
1330 if (patch1>=0)
1331 fThresholdVal->setValue(sdata.fThreshold[patch1]);
1332
1333 fPrescalingVal->setValue(sdata.fPrescaling[0]);
1334
1335 fFtmStaticData = sdata;
1336 }
1337
1338 void handleFtmPassport(const DimData &d)
1339 {
1340 if (d.size()==0)
1341 return;
1342
1343 if (d.size()!=sizeof(FTM::DimPassport))
1344 {
1345 cout << "Size mismatch: " << d.size() << " " << sizeof(FTM::DimPassport) << endl;
1346 return;
1347 }
1348
1349 const FTM::DimPassport &sdata = d.ref<FTM::DimPassport>();
1350
1351 stringstream str1, str2;
1352 str1 << hex << "0x" << setfill('0') << setw(16) << sdata.fBoardId;
1353 str2 << sdata.fFirmwareId;
1354
1355 fFtmBoardId->setText(str1.str().c_str());
1356 fFtmFirmwareId->setText(str2.str().c_str());
1357 }
1358
1359 void handleFtmFtuList(const DimData &d)
1360 {
1361 if (d.size()==0)
1362 return;
1363
1364 if (d.size()!=sizeof(FTM::DimFtuList))
1365 {
1366 cout << "Size mismatch: " << d.size() << " " << sizeof(FTM::DimFtuList) << endl;
1367 return;
1368 }
1369
1370 fFtuPing->setChecked(false);
1371
1372 const FTM::DimFtuList &sdata = d.ref<FTM::DimFtuList>();
1373
1374 stringstream str;
1375 str << "<table width='100%'>" << setfill('0');
1376 str << "<tr><th>Num</th><th></th><th>Addr</th><th></th><th>DNA</th></tr>";
1377 for (int i=0; i<40; i++)
1378 {
1379 str << "<tr>";
1380 str << "<td align='center'>" << dec << i << hex << "</td>";
1381 str << "<td align='center'>:</td>";
1382 str << "<td align='center'>0x" << setw(2) << (int)sdata.fAddr[i] << "</td>";
1383 str << "<td align='center'>:</td>";
1384 str << "<td align='center'>0x" << setw(16) << sdata.fDNA[i] << "</td>";
1385 str << "</tr>";
1386 }
1387 str << "</table>";
1388
1389 fFtuDNA->setText(str.str().c_str());
1390
1391 fFtuAnswersTotal->setValue(sdata.fNumBoards);
1392 fFtuAnswersCrate0->setValue(sdata.fNumBoardsCrate[0]);
1393 fFtuAnswersCrate1->setValue(sdata.fNumBoardsCrate[1]);
1394 fFtuAnswersCrate2->setValue(sdata.fNumBoardsCrate[2]);
1395 fFtuAnswersCrate3->setValue(sdata.fNumBoardsCrate[3]);
1396
1397 for (int i=0; i<40; i++)
1398 SetFtuLed(i, sdata.IsActive(i) ? sdata.fPing[i] : -1, d.time);
1399
1400 SetFtuStatusLed(d.time);
1401 }
1402
1403 void handleFtmError(const DimData &d)
1404 {
1405 if (d.size()==0)
1406 return;
1407
1408 const FTM::DimError &sdata = d.ref<FTM::DimError>();
1409
1410 SetFtuLed(sdata.fError.fDestAddress , sdata.fError.fNumCalls, d.time);
1411 SetFtuStatusLed(d.time);
1412
1413 // FIXME: Write to special window!
1414 //Out() << "Error:" << endl;
1415 //Out() << sdata.fError << endl;
1416 }
1417
1418 // ====================== MessageImp ====================================
1419
1420 bool fChatOnline;
1421
1422 void handleStateChanged(const Time &time, const std::string &server,
1423 const State &s)
1424 {
1425 // FIXME: Prefix tooltip with time
1426 if (server=="FTM_CONTROL")
1427 {
1428 fStatusFTMLabel->setText(s.name.c_str());
1429 fStatusFTMLabel->setToolTip(s.comment.c_str());
1430
1431 bool enable = false;
1432
1433 if (s.index<FTM::kDisconnected) // No Dim connection
1434 SetLedColor(fStatusFTMLed, kLedGray, time);
1435 if (s.index==FTM::kDisconnected) // Dim connection / FTM disconnected
1436 SetLedColor(fStatusFTMLed, kLedYellow, time);
1437 if (s.index==FTM::kConnected || s.index==FTM::kIdle || s.index==FTM::kTakingData) // Dim connection / FTM connected
1438 SetLedColor(fStatusFTMLed, kLedGreen, time);
1439
1440 if (s.index==FTM::kConnected || s.index==FTM::kIdle) // Dim connection / FTM connected
1441 enable = true;
1442
1443 fTriggerWidget->setEnabled(enable);
1444 fFtuWidget->setEnabled(enable);
1445 fRatesWidget->setEnabled(enable);
1446
1447 if (!enable)
1448 {
1449 SetLedColor(fStatusFTULed, kLedGray, time);
1450 fStatusFTULabel->setText("Offline");
1451 fStatusFTULabel->setToolTip("FTM is not online.");
1452 }
1453 }
1454
1455 if (server=="FAD_CONTROL")
1456 {
1457 fStatusFADLabel->setText(s.name.c_str());
1458 fStatusFADLabel->setToolTip(s.comment.c_str());
1459
1460 bool enable = false;
1461
1462 if (s.index<FAD::kDisconnected) // No Dim connection
1463 SetLedColor(fStatusFADLed, kLedGray, time);
1464 if (s.index==FAD::kOffline) // Dim connection / FTM disconnected
1465 SetLedColor(fStatusFADLed, kLedRed, time);
1466 if (s.index==FAD::kDisconnected) // Dim connection / FTM disconnected
1467 SetLedColor(fStatusFADLed, kLedOrange, time);
1468 if (s.index==FAD::kConnecting) // Dim connection / FTM disconnected
1469 SetLedColor(fStatusFADLed, kLedYellow, time);
1470 if (s.index>=FAD::kConnected) // Dim connection / FTM connected
1471 {
1472 SetLedColor(fStatusFADLed, kLedGreen, time);
1473 enable = true;
1474 }
1475
1476 fFadWidget->setEnabled(enable);
1477 }
1478
1479 if (server=="DATA_LOGGER")
1480 {
1481 fStatusLoggerLabel->setText(s.name.c_str());
1482 fStatusLoggerLabel->setToolTip(s.comment.c_str());
1483
1484 bool enable = true;
1485
1486 if (s.index<=30) // Ready/Waiting
1487 SetLedColor(fStatusLoggerLed, kLedYellow, time);
1488 if (s.index<-1) // Offline
1489 {
1490 SetLedColor(fStatusLoggerLed, kLedGray, time);
1491 enable = false;
1492 }
1493 if (s.index>=0x100) // Error
1494 SetLedColor(fStatusLoggerLed, kLedRed, time);
1495 if (s.index==40) // Logging
1496 SetLedColor(fStatusLoggerLed, kLedGreen, time);
1497
1498 fLoggerWidget->setEnabled(enable);
1499 }
1500
1501 if (server=="CHAT")
1502 {
1503 fStatusChatLabel->setText(s.name.c_str());
1504
1505 fChatOnline = s.index==0;
1506
1507 SetLedColor(fStatusChatLed, fChatOnline ? kLedGreen : kLedRed, time);
1508
1509 fChatSend->setEnabled(fChatOnline);
1510 fChatMessage->setEnabled(fChatOnline);
1511 }
1512
1513 if (server=="SCHEDULER")
1514 {
1515 fStatusSchedulerLabel->setText(s.name.c_str());
1516
1517 SetLedColor(fStatusSchedulerLed, s.index>=0 ? kLedGreen : kLedRed, time);
1518 }
1519 }
1520
1521 void handleStateOffline(const string &server)
1522 {
1523 handleStateChanged(Time(), server, State(-2, "Offline", "No connection via DIM."));
1524 }
1525
1526 void on_fTabWidget_currentChanged(int which)
1527 {
1528 if (fTabWidget->tabText(which)=="Chat")
1529 fTabWidget->setTabIcon(which, QIcon());
1530 }
1531
1532 void handleWrite(const Time &time, const string &text, int qos)
1533 {
1534 stringstream out;
1535
1536 if (text.substr(0, 6)=="CHAT: ")
1537 {
1538 out << "<font size='-1' color='navy'>[<B>";
1539 out << Time::fmt("%H:%M:%S") << time << "</B>]</FONT> ";
1540 out << text.substr(6);
1541 fChatText->append(out.str().c_str());
1542
1543 if (fTabWidget->tabText(fTabWidget->currentIndex())=="Chat")
1544 return;
1545
1546 static int num = 0;
1547 if (num++<2)
1548 return;
1549
1550 for (int i=0; i<fTabWidget->count(); i++)
1551 if (fTabWidget->tabText(i)=="Chat")
1552 {
1553 fTabWidget->setTabIcon(i, QIcon(":/Resources/icons/warning 3.png"));
1554 break;
1555 }
1556
1557 return;
1558 }
1559
1560
1561 out << "<font style='font-family:monospace' color='";
1562
1563 switch (qos)
1564 {
1565 case kMessage: out << "black"; break;
1566 case kInfo: out << "green"; break;
1567 case kWarn: out << "#FF6600"; break;
1568 case kError: out << "maroon"; break;
1569 case kFatal: out << "maroon"; break;
1570 case kDebug: out << "navy"; break;
1571 default: out << "navy"; break;
1572 }
1573 out << "'>" << time.GetAsStr() << " - " << text << "</font>";
1574
1575 fLogText->append(out.str().c_str());
1576
1577 if (qos>=kWarn)
1578 fTextEdit->append(out.str().c_str());
1579 }
1580
1581 void IndicateStateChange(const Time &time, const std::string &server)
1582 {
1583 const State s = GetState(server, GetCurrentState(server));
1584
1585 QApplication::postEvent(this,
1586 new FunctionEvent(boost::bind(&FactGui::handleStateChanged, this, time, server, s)));
1587 }
1588
1589 int Write(const Time &time, const string &txt, int qos)
1590 {
1591 QApplication::postEvent(this,
1592 new FunctionEvent(boost::bind(&FactGui::handleWrite, this, time, txt, qos)));
1593
1594 return 0;
1595 }
1596
1597 // ====================== Dim infoHandler================================
1598
1599 void handleDimService(const string &txt)
1600 {
1601 fDimSvcText->append(txt.c_str());
1602 }
1603
1604 void infoHandlerService(DimInfo &info)
1605 {
1606 const string fmt = string(info.getFormat()).empty() ? "C" : info.getFormat();
1607
1608 stringstream dummy;
1609 const Converter conv(dummy, fmt, false);
1610
1611 const Time tm(info.getTimestamp(), info.getTimestampMillisecs()*1000);
1612
1613 stringstream out;
1614 out << "<font size'-1' color='navy'>[" << Time::fmt("%H:%M:%S.%f") << tm << "]</font> <B>" << info.getName() << "</B> - ";
1615
1616 bool iserr = true;
1617 if (!conv)
1618 {
1619 out << "Compilation of format string '" << fmt << "' failed!";
1620 }
1621 else
1622 {
1623 try
1624 {
1625 const string dat = conv.GetString(info.getData(), info.getSize());
1626 out << dat;
1627 iserr = false;
1628 }
1629 catch (const runtime_error &e)
1630 {
1631 out << "Conversion to string failed!<pre>" << e.what() << "</pre>";
1632 }
1633 }
1634
1635 // srand(hash<string>()(string(info.getName())));
1636 // int bg = rand()&0xffffff;
1637
1638 int bg = hash<string>()(string(info.getName()));
1639
1640 // allow only light colors
1641 bg = ~(bg&0x1f1f1f)&0xffffff;
1642
1643 if (iserr)
1644 bg = 0xffffff;
1645
1646 stringstream bgcol;
1647 bgcol << hex << setfill('0') << setw(6) << bg;
1648
1649 const string col = iserr ? "red" : "black";
1650 const string str = "<table width='100%' bgcolor=#"+bgcol.str()+"><tr><td><font color='"+col+"'>"+out.str()+"</font></td></tr></table>";
1651
1652 QApplication::postEvent(this,
1653 new FunctionEvent(boost::bind(&FactGui::handleDimService, this, str)));
1654 }
1655
1656 void CallInfoHandler(void (FactGui::*handler)(const DimData&), const DimData &d)
1657 {
1658 fInHandler = true;
1659 (this->*handler)(d);
1660 fInHandler = false;
1661 }
1662
1663 /*
1664 void CallInfoHandler(const boost::function<void()> &func)
1665 {
1666 // This ensures that newly received values are not sent back to the emitter
1667 // because changing the value emits the valueChanged signal (or similar)
1668 fInHandler = true;
1669 func();
1670 fInHandler = false;
1671 }*/
1672
1673 void PostInfoHandler(void (FactGui::*handler)(const DimData&))
1674 {
1675 //const boost::function<void()> f = boost::bind(handler, this, DimData(getInfo()));
1676
1677 FunctionEvent *evt = new FunctionEvent(boost::bind(&FactGui::CallInfoHandler, this, handler, DimData(getInfo())));
1678 // FunctionEvent *evt = new FunctionEvent(boost::bind(&FactGui::CallInfoHandler, this, f));
1679 // FunctionEvent *evt = new FunctionEvent(boost::bind(handler, this, DimData(getInfo()))));
1680
1681 QApplication::postEvent(this, evt);
1682 }
1683
1684 void infoHandler()
1685 {
1686 // Initialize the time-stamp (what a weird workaround...)
1687 if (getInfo())
1688 getInfo()->getTimestamp();
1689
1690 if (getInfo()==&fDimDNS)
1691 return PostInfoHandler(&FactGui::handleDimDNS);
1692#ifdef DEBUG_DIM
1693 cout << "HandleDimInfo " << getInfo()->getName() << endl;
1694#endif
1695 if (getInfo()==&fDimLoggerStats)
1696 return PostInfoHandler(&FactGui::handleLoggerStats);
1697
1698 if (getInfo()==&fDimFadFiles)
1699 return PostInfoHandler(&FactGui::handleFadFiles);
1700
1701 if (getInfo()==&fDimFadConnections)
1702 return PostInfoHandler(&FactGui::handleFadConnections);
1703
1704 if (getInfo()==&fDimFadEvents)
1705 return PostInfoHandler(&FactGui::handleFadEvents);
1706
1707 if (getInfo()==&fDimFadRuns)
1708 return PostInfoHandler(&FactGui::handleFadRuns);
1709
1710 if (getInfo()==&fDimFadCurrentEvent)
1711 return PostInfoHandler(&FactGui::handleFadCurrentEvent);
1712
1713/*
1714 if (getInfo()==&fDimFadSetup)
1715 return PostInfoHandler(&FactGui::handleFadSetup);
1716*/
1717 if (getInfo()==&fDimLoggerFilenameNight)
1718 return PostInfoHandler(&FactGui::handleLoggerFilenameNight);
1719
1720 if (getInfo()==&fDimLoggerNumSubs)
1721 return PostInfoHandler(&FactGui::handleLoggerNumSubs);
1722
1723 if (getInfo()==&fDimLoggerFilenameRun)
1724 return PostInfoHandler(&FactGui::handleLoggerFilenameRun);
1725
1726 if (getInfo()==&fDimFtmTriggerCounter)
1727 return PostInfoHandler(&FactGui::handleFtmTriggerCounter);
1728
1729 if (getInfo()==&fDimFtmCounter)
1730 return PostInfoHandler(&FactGui::handleFtmCounter);
1731
1732 if (getInfo()==&fDimFtmDynamicData)
1733 return PostInfoHandler(&FactGui::handleFtmDynamicData);
1734
1735 if (getInfo()==&fDimFtmPassport)
1736 return PostInfoHandler(&FactGui::handleFtmPassport);
1737
1738 if (getInfo()==&fDimFtmFtuList)
1739 return PostInfoHandler(&FactGui::handleFtmFtuList);
1740
1741 if (getInfo()==&fDimFtmStaticData)
1742 return PostInfoHandler(&FactGui::handleFtmStaticData);
1743
1744 if (getInfo()==&fDimFtmError)
1745 return PostInfoHandler(&FactGui::handleFtmError);
1746
1747 for (map<string,DimInfo*>::iterator i=fServices.begin(); i!=fServices.end(); i++)
1748 if (i->second==getInfo())
1749 {
1750 infoHandlerService(*i->second);
1751 return;
1752 }
1753
1754 DimNetwork::infoHandler();
1755 }
1756
1757
1758 // ======================================================================
1759
1760 bool event(QEvent *evt)
1761 {
1762 if (dynamic_cast<FunctionEvent*>(evt))
1763 return static_cast<FunctionEvent*>(evt)->Exec();
1764
1765 if (dynamic_cast<CheckBoxEvent*>(evt))
1766 {
1767 const QStandardItem &item = static_cast<CheckBoxEvent*>(evt)->item;
1768 const QStandardItem *par = item.parent();
1769 if (par)
1770 {
1771 const QString server = par->text();
1772 const QString service = item.text();
1773
1774 const string s = (server+'/'+service).toStdString();
1775
1776 if (item.checkState()==Qt::Checked)
1777 SubscribeService(s);
1778 else
1779 UnsubscribeService(s);
1780 }
1781 }
1782
1783 return MainWindow::event(evt); // unrecognized
1784 }
1785
1786 void on_fDimCmdSend_clicked()
1787 {
1788 const QString server = fDimCmdServers->currentIndex().data().toString();
1789 const QString command = fDimCmdCommands->currentIndex().data().toString();
1790 const QString arguments = fDimCmdLineEdit->displayText();
1791
1792 // FIXME: Sending a command exactly when the info Handler changes
1793 // the list it might lead to confusion.
1794 try
1795 {
1796 SendDimCommand(server.toStdString(), command.toStdString()+" "+arguments.toStdString());
1797 fTextEdit->append("<font color='green'>Command '"+server+'/'+command+"' successfully emitted.</font>");
1798 fDimCmdLineEdit->clear();
1799 }
1800 catch (const runtime_error &e)
1801 {
1802 stringstream txt;
1803 txt << e.what();
1804
1805 string buffer;
1806 while (getline(txt, buffer, '\n'))
1807 fTextEdit->append(("<font color='red'><pre>"+buffer+"</pre></font>").c_str());
1808 }
1809 }
1810 void ChoosePatch(Camera &cam, int idx)
1811 {
1812 cam.Reset();
1813
1814 fThresholdIdx->setValue(idx);
1815
1816 //fThresholdVal->setEnabled(idx>=0);
1817 //fThresholdVolt->setEnabled(idx>=0);
1818 fPatchRate->setEnabled(idx>=0);
1819 if (idx<0)
1820 return;
1821
1822 fThresholdVal->setValue(fFtmStaticData.fThreshold[idx]);
1823 fPatchRate->setValue(cam.GetData(idx));
1824
1825 for (unsigned int i=0; i<fPatch.size(); i++)
1826 if (fPatch[i]==idx)
1827 cam.SetBold(i);
1828 }
1829
1830 void ChoosePixel(Camera &cam, int idx)
1831 {
1832 cam.SetWhite(idx);
1833 ChoosePatch(cam, fPatch[idx]);
1834
1835 fPixelEnable->setChecked(fFtmStaticData.IsEnabled(idx));
1836 }
1837
1838#ifdef HAVE_ROOT
1839 void slot_RootEventProcessed(TObject *obj, unsigned int evt, TCanvas *)
1840 {
1841 // kMousePressEvent // TCanvas processed QEvent mousePressEvent
1842 // kMouseMoveEvent // TCanvas processed QEvent mouseMoveEvent
1843 // kMouseReleaseEvent // TCanvas processed QEvent mouseReleaseEvent
1844 // kMouseDoubleClickEvent // TCanvas processed QEvent mouseDoubleClickEvent
1845 // kKeyPressEvent // TCanvas processed QEvent keyPressEvent
1846 // kEnterEvent // TCanvas processed QEvent enterEvent
1847 // kLeaveEvent // TCanvas processed QEvent leaveEvent
1848 if (dynamic_cast<TCanvas*>(obj))
1849 return;
1850
1851 TQtWidget *tipped = static_cast<TQtWidget*>(sender());
1852
1853 if (evt==11/*kMouseReleaseEvent*/)
1854 {
1855 if (dynamic_cast<Camera*>(obj))
1856 {
1857 const float xx = gPad->PadtoX(gPad->AbsPixeltoX(tipped->GetEventX()));
1858 const float yy = gPad->PadtoY(gPad->AbsPixeltoY(tipped->GetEventY()));
1859
1860 Camera *cam = static_cast<Camera*>(obj);
1861 const int idx = cam->GetIdx(xx, yy);
1862
1863 ChoosePixel(*cam, idx);
1864
1865 fPixelIdx->setValue(idx);
1866 }
1867 return;
1868 }
1869
1870 if (evt==61/*kMouseDoubleClickEvent*/)
1871 {
1872 if (dynamic_cast<Camera*>(obj))
1873 {
1874 const float xx = gPad->PadtoX(gPad->AbsPixeltoX(tipped->GetEventX()));
1875 const float yy = gPad->PadtoY(gPad->AbsPixeltoY(tipped->GetEventY()));
1876
1877 Camera *cam = static_cast<Camera*>(obj);
1878 const int idx = cam->GetIdx(xx, yy);
1879
1880 //cam->Toggle(idx);
1881
1882 Dim::SendCommand("FTM_CONTROL/TOGGLE_PIXEL", uint16_t(idx));
1883 }
1884
1885 if (dynamic_cast<TAxis*>(obj))
1886 static_cast<TAxis*>(obj)->UnZoom();
1887
1888 return;
1889 }
1890
1891 // Find the object which will get picked by the GetObjectInfo
1892 // due to buffer overflows in many root-versions
1893 // in TH1 and TProfile we have to work around and implement
1894 // our own GetObjectInfo which make everything a bit more
1895 // complicated.
1896#if ROOT_VERSION_CODE > ROOT_VERSION(5,22,00)
1897 const char *objectInfo =
1898 obj->GetObjectInfo(tipped->GetEventX(),tipped->GetEventY());
1899#else
1900 const char *objectInfo = dynamic_cast<TH1*>(obj) ?
1901 "" : obj->GetObjectInfo(tipped->GetEventX(),tipped->GetEventY());
1902#endif
1903
1904 QString tipText;
1905 tipText += obj->GetName();
1906 tipText += " [";
1907 tipText += obj->ClassName();
1908 tipText += "]: ";
1909 tipText += objectInfo;
1910
1911 if (dynamic_cast<Camera*>(obj))
1912 {
1913 const float xx = gPad->PadtoX(gPad->AbsPixeltoX(tipped->GetEventX()));
1914 const float yy = gPad->PadtoY(gPad->AbsPixeltoY(tipped->GetEventY()));
1915
1916 Camera *cam = static_cast<Camera*>(obj);
1917 int idx = fPatch[cam->GetIdx(xx, yy)];
1918
1919 tipText+=" Patch=";
1920 tipText+=QString::number(idx);
1921 }
1922
1923
1924 fStatusBar->showMessage(tipText, 3000);
1925
1926 gSystem->ProcessEvents();
1927 //QWhatsThis::display(tipText)
1928 }
1929
1930 void slot_RootUpdate()
1931 {
1932 gSystem->ProcessEvents();
1933 QTimer::singleShot(0, this, SLOT(slot_RootUpdate()));
1934 }
1935
1936 void on_fThresholdIdx_valueChanged(int idx)
1937 {
1938 Camera *cam = (Camera*)fRatesCanv->GetCanvas()->FindObject("Camera");
1939 ChoosePatch(*cam, idx);
1940 }
1941
1942 void on_fPixelIdx_valueChanged(int idx)
1943 {
1944 Camera *cam = (Camera*)fRatesCanv->GetCanvas()->FindObject("Camera");
1945 ChoosePixel(*cam, idx);
1946 }
1947#endif
1948
1949 TGraph fGraphFtmTemp[4];
1950 TGraph fGraphFtmRate;
1951 TGraph fGraphPatchRate[160];
1952 TGraph fGraphBoardRate[40];
1953
1954 map<int, int> fPatch;
1955
1956#ifdef HAVE_ROOT
1957 void DrawTimeFrame(const char *ytitle)
1958 {
1959 const double tm = Time().RootTime();
1960
1961 TH1F h("TimeFrame", "", 1, tm, tm+60);//Time().RootTime()-1./24/60/60, Time().RootTime());
1962 h.SetDirectory(0);
1963// h.SetBit(TH1::kCanRebin);
1964 h.SetStats(kFALSE);
1965// h.SetMinimum(0);
1966// h.SetMaximum(1);
1967 h.SetXTitle("Time");
1968 h.SetYTitle(ytitle);
1969 h.GetXaxis()->CenterTitle();
1970 h.GetYaxis()->CenterTitle();
1971 h.GetXaxis()->SetTimeDisplay(true);
1972 h.GetXaxis()->SetTimeFormat("%Mh%S'");
1973 h.GetXaxis()->SetLabelSize(0.025);
1974 h.GetYaxis()->SetLabelSize(0.025);
1975 h.GetYaxis()->SetTitleOffset(1.2);
1976// h.GetYaxis()->SetTitleSize(1.2);
1977 h.DrawCopy()->SetDirectory(0);
1978 }
1979#endif
1980
1981public:
1982 FactGui() :
1983 fFtuStatus(40), //fMapHW(1440)
1984 fDimDNS("DIS_DNS/VERSION_NUMBER", 1, int(0), this),
1985
1986 fDimLoggerStats ("DATA_LOGGER/STATS", (void*)NULL, 0, this),
1987 fDimLoggerFilenameNight("DATA_LOGGER/FILENAME_NIGHTLY", const_cast<char*>(""), 0, this),
1988 fDimLoggerFilenameRun ("DATA_LOGGER/FILENAME_RUN", const_cast<char*>(""), 0, this),
1989 fDimLoggerNumSubs ("DATA_LOGGER/NUM_SUBS", const_cast<char*>(""), 0, this),
1990
1991 fDimFtmPassport ("FTM_CONTROL/PASSPORT", (void*)NULL, 0, this),
1992 fDimFtmTriggerCounter("FTM_CONTROL/TRIGGER_COUNTER", (void*)NULL, 0, this),
1993 fDimFtmError ("FTM_CONTROL/ERROR", (void*)NULL, 0, this),
1994 fDimFtmFtuList ("FTM_CONTROL/FTU_LIST", (void*)NULL, 0, this),
1995 fDimFtmStaticData ("FTM_CONTROL/STATIC_DATA", (void*)NULL, 0, this),
1996 fDimFtmDynamicData ("FTM_CONTROL/DYNAMIC_DATA", (void*)NULL, 0, this),
1997 fDimFtmCounter ("FTM_CONTROL/COUNTER", (void*)NULL, 0, this),
1998 fDimFadFiles ("FAD_CONTROL/FILES", (void*)NULL, 0, this),
1999 fDimFadRuns ("FAD_CONTROL/RUNS", (void*)NULL, 0, this),
2000 fDimFadEvents ("FAD_CONTROL/EVENTS", (void*)NULL, 0, this),
2001 fDimFadCurrentEvent ("FAD_CONTROL/CURRENT_EVENT", (void*)NULL, 0, this),
2002 fDimFadConnections ("FAD_CONTROL/CONNECTIONS", (void*)NULL, 0, this)
2003 {
2004 fTriggerWidget->setEnabled(false);
2005 fFtuWidget->setEnabled(false);
2006 fRatesWidget->setEnabled(false);
2007 fFadWidget->setEnabled(false);
2008 fLoggerWidget->setEnabled(false);
2009
2010 fChatSend->setEnabled(false);
2011 fChatMessage->setEnabled(false);
2012
2013 DimClient::sendCommand("CHAT/MSG", "GUI online.");
2014 // + MessageDimRX
2015
2016 // --------------------------------------------------------------------------
2017
2018 ifstream fin1("fact-trigger-all.txt");
2019
2020 int l = 0;
2021
2022 string buf;
2023 while (getline(fin1, buf, '\n'))
2024 {
2025 buf = Tools::Trim(buf);
2026 if (buf[0]=='#')
2027 continue;
2028
2029 stringstream str(buf);
2030 for (int i=0; i<9; i++)
2031 {
2032 int n;
2033 str >> n;
2034
2035 fPatch[n] = l;
2036 }
2037 l++;
2038 }
2039
2040 // --------------------------------------------------------------------------
2041/*
2042 ifstream fin2("FACTmapV3.txt");
2043
2044 l = 0;
2045
2046 while (getline(fin2, buf, '\n'))
2047 {
2048 buf = Tools::Trim(buf);
2049 if (buf[0]=='#')
2050 continue;
2051
2052 int softid, hardid, geom_i, geom_j, gapd;
2053
2054 stringstream str(buf);
2055
2056 str >> softid;
2057 str >> hardid;
2058 str >> geom_i;
2059 str >> geom_j;
2060 str >> gapd;
2061
2062 fMapHW[softid] = hardid;
2063 fMapSW[hardid] = softid;
2064
2065 l++;
2066 }
2067*/
2068 // --------------------------------------------------------------------------
2069#ifdef HAVE_ROOT
2070
2071 fGraphFtmRate.SetLineColor(kBlue);
2072 fGraphFtmRate.SetMarkerColor(kBlue);
2073 fGraphFtmRate.SetMarkerStyle(kFullDotMedium);
2074
2075 for (int i=0; i<160; i++)
2076 {
2077 fGraphPatchRate[i].SetName("PatchRate");
2078 fGraphPatchRate[i].SetLineColor(kBlue);
2079 fGraphPatchRate[i].SetMarkerColor(kBlue);
2080 fGraphPatchRate[i].SetMarkerStyle(kFullDotMedium);
2081 }
2082 for (int i=0; i<40; i++)
2083 {
2084 fGraphBoardRate[i].SetName("BoardRate");
2085 fGraphBoardRate[i].SetLineColor(kBlue);
2086 fGraphBoardRate[i].SetMarkerColor(kBlue);
2087 fGraphBoardRate[i].SetMarkerStyle(kFullDotMedium);
2088 }
2089 /*
2090 TCanvas *c = fFtmTempCanv->GetCanvas();
2091 c->SetBit(TCanvas::kNoContextMenu);
2092 c->SetBorderMode(0);
2093 c->SetFrameBorderMode(0);
2094 c->SetFillColor(kWhite);
2095 c->SetRightMargin(0.03);
2096 c->SetTopMargin(0.03);
2097 c->cd();
2098 */
2099 //CreateTimeFrame("Temperature / °C");
2100
2101 fGraphFtmTemp[0].SetMarkerStyle(kFullDotSmall);
2102 fGraphFtmTemp[1].SetMarkerStyle(kFullDotSmall);
2103 fGraphFtmTemp[2].SetMarkerStyle(kFullDotSmall);
2104 fGraphFtmTemp[3].SetMarkerStyle(kFullDotSmall);
2105
2106 fGraphFtmTemp[1].SetLineColor(kBlue);
2107 fGraphFtmTemp[2].SetLineColor(kRed);
2108 fGraphFtmTemp[3].SetLineColor(kGreen);
2109
2110 fGraphFtmTemp[1].SetMarkerColor(kBlue);
2111 fGraphFtmTemp[2].SetMarkerColor(kRed);
2112 fGraphFtmTemp[3].SetMarkerColor(kGreen);
2113
2114 //fGraphFtmTemp[0].Draw("LP");
2115 //fGraphFtmTemp[1].Draw("LP");
2116 //fGraphFtmTemp[2].Draw("LP");
2117 //fGraphFtmTemp[3].Draw("LP");
2118
2119 // --------------------------------------------------------------------------
2120
2121 TCanvas *c = fFtmRateCanv->GetCanvas();
2122 c->SetBit(TCanvas::kNoContextMenu);
2123 c->SetBorderMode(0);
2124 c->SetFrameBorderMode(0);
2125 c->SetFillColor(kWhite);
2126 c->SetRightMargin(0.03);
2127 c->SetTopMargin(0.03);
2128 c->SetGrid();
2129 c->cd();
2130
2131 DrawTimeFrame("Trigger rate [Hz]");
2132
2133 fTriggerCounter0 = -1;
2134
2135 fGraphFtmRate.SetMarkerStyle(kFullDotSmall);
2136 fGraphFtmRate.Draw("LP");
2137
2138 // --------------------------------------------------------------------------
2139
2140 c = fRatesCanv->GetCanvas();
2141 c->SetBit(TCanvas::kNoContextMenu);
2142 c->SetBorderMode(0);
2143 c->SetFrameBorderMode(0);
2144 c->SetFillColor(kWhite);
2145 c->cd();
2146
2147 Camera *cam = new Camera;
2148 cam->SetBit(kCanDelete);
2149 cam->Draw();
2150
2151 ChoosePixel(*cam, 1);
2152
2153// QTimer::singleShot(0, this, SLOT(slot_RootUpdate()));
2154
2155 //widget->setMouseTracking(true);
2156 //widget->EnableSignalEvents(kMouseMoveEvent);
2157
2158 fFtmRateCanv->setMouseTracking(true);
2159 fFtmRateCanv->EnableSignalEvents(kMouseMoveEvent);
2160
2161 fRatesCanv->setMouseTracking(true);
2162 fRatesCanv->EnableSignalEvents(kMouseMoveEvent|kMouseReleaseEvent|kMouseDoubleClickEvent);
2163
2164 connect(fRatesCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)),
2165 this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*)));
2166 connect(fFtmRateCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)),
2167 this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*)));
2168#endif
2169 }
2170
2171 ~FactGui()
2172 {
2173 UnsubscribeAllServers();
2174 }
2175};
2176
2177#endif
Note: See TracBrowser for help on using the repository browser.