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

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