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

Last change on this file since 11223 was 11223, checked in by neise, 13 years ago
Fixed ADC pipeline display
File size: 82.5 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.00, 0.25, 0.50, 0.75, 1.00};
51 double rr[5] = {0.15, 0.00, 0.00, 1.00, 0.85};
52 double gg[5] = {0.15, 0.00, 1.00, 0.00, 0.85};
53 double bb[5] = {0.15, 1.00, 0.00, 0.00, 0.85};
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 double align(double min, double val, double max) const
177 {
178 if (val<min)
179 return min;
180 if (val>max)
181 return max;
182 return val;
183 }
184
185 void Paint(Option_t *)
186 {
187 gStyle->SetPalette(fPalette.size(), fPalette.data());
188
189 const double r = double(gPad->GetWw())/gPad->GetWh();
190 const double max = 20.5; // 20.5 rings in x and y
191
192 if (r>1)
193 gPad->Range(-r*max, -max, r*max, max);
194 else
195 gPad->Range(-max, -max/r, max, max/r);
196
197 Double_t x1, x2, y1, y2;
198 gPad->GetRange(x1, x2, y1, y2);
199
200 double dmin = fData[0];
201 double dmax = fData[0];
202
203 for (unsigned int i=0; i<fData.size(); i++)
204 {
205 if (!fEnable[i])
206 continue;
207
208 if (fData[i]>dmax)
209 dmax = fData[i];
210 if (fData[i]<dmin)
211 dmin = fData[i];
212 }
213
214 const double min = dmin;
215 const double scale = dmax==dmin ? 1 : dmax-dmin;
216
217 TAttFill fill(0, 1001);
218 TAttLine line;
219
220 int cnt=0;
221 for (Positions::iterator p=fGeom.begin(); p!=fGeom.end(); p++, cnt++)
222 {
223 if (fBold[cnt])
224 continue;
225
226 const double val = align(dmin, fData[cnt], dmax);
227
228 const int col = (val-min)/scale*(fPalette.size()-1);
229
230 if (fEnable[cnt])
231 fill.SetFillColor(gStyle->GetColorPalette(col));
232 else
233 fill.SetFillColor(kWhite);
234
235 fill.Modify();
236
237 Paint(*p);
238 }
239
240 line.SetLineWidth(2);
241 line.Modify();
242
243 cnt = 0;
244 for (Positions::iterator p=fGeom.begin(); p!=fGeom.end(); p++, cnt++)
245 {
246 if (!fBold[cnt])
247 continue;
248
249 const double val = align(dmin, fData[cnt], dmax);
250
251 const int col = (val-min)/scale*(fPalette.size()-1);
252
253 if (fEnable[cnt])
254 fill.SetFillColor(gStyle->GetColorPalette(col));
255 else
256 fill.SetFillColor(kWhite);
257 fill.Modify();
258
259 Paint(*p);
260 }
261
262 TMarker m(0,0,kStar);
263 m.DrawMarker(0, 0);
264
265 if (fWhite<0)
266 return;
267
268 const Position &p = fGeom[fWhite];
269
270 line.SetLineColor(kWhite);
271 line.Modify();
272
273 const double val = align(dmin, fData[fWhite], dmax);
274
275 const int col = (val-min)/scale*(fPalette.size()-1);
276
277 if (fEnable[fWhite])
278 fill.SetFillColor(gStyle->GetColorPalette(col));
279 else
280 fill.SetFillColor(kWhite);
281 fill.Modify();
282
283 Paint(p);
284 }
285
286 int GetIdx(float px, float py) const
287 {
288 static const double sqrt3 = sqrt(3);
289
290 int idx = 0;
291 for (Positions::const_iterator p=fGeom.begin(); p!=fGeom.end(); p++, idx++)
292 {
293 const Double_t dy = py - p->second;
294 if (fabs(dy)>0.5)
295 continue;
296
297 const Double_t dx = px - p->first;
298
299 if (TMath::Abs(dy + dx*sqrt3) > 1)
300 continue;
301
302 if (TMath::Abs(dy - dx*sqrt3) > 1)
303 continue;
304
305 return idx;
306 }
307 return -1;
308 }
309
310 char *GetObjectInfo(Int_t px, Int_t py) const
311 {
312 static stringstream stream;
313 static string str;
314
315 const float x = gPad->AbsPixeltoX(px);
316 const float y = gPad->AbsPixeltoY(py);
317
318 const int idx = GetIdx(x, y);
319
320 stream.seekp(0);
321 if (idx>=0)
322 {
323 stream << "Pixel=" << idx << " Data=" << fData[idx] << '\0';
324 }
325
326 str = stream.str();
327 return const_cast<char*>(str.c_str());
328 }
329
330 Int_t DistancetoPrimitive(Int_t px, Int_t py)
331 {
332 const float x = gPad->AbsPixeltoX(px);
333 const float y = gPad->AbsPixeltoY(py);
334
335 return GetIdx(x, y)>=0 ? 0 : 99999;
336 }
337
338 void SetData(const valarray<double> &data)
339 {
340 fData = data;
341 }
342};
343
344// #########################################################################
345
346
347class FactGui : public MainWindow, public DimNetwork
348{
349private:
350 class FunctionEvent : public QEvent
351 {
352 public:
353 boost::function<void(const QEvent &)> fFunction;
354
355 FunctionEvent(const boost::function<void(const QEvent &)> &f)
356 : QEvent((QEvent::Type)QEvent::registerEventType()),
357 fFunction(f) { }
358
359 bool Exec() { fFunction(*this); return true; }
360 };
361
362 valarray<int8_t> fFtuStatus;
363
364 vector<int> fPixelMapHW; // Software -> Hardware
365 vector<int> fPatchMapHW; // Software -> Hardware
366 vector<int> fPatchHW; // Maps the software(!) pixel id to the hardware(!) patch id
367
368 bool fInChoosePatch; // FIXME. Find a better solution
369
370 DimStampedInfo fDimDNS;
371
372 DimStampedInfo fDimLoggerStats;
373 DimStampedInfo fDimLoggerFilenameNight;
374 DimStampedInfo fDimLoggerFilenameRun;
375 DimStampedInfo fDimLoggerNumSubs;
376
377 DimStampedInfo fDimFtmPassport;
378 DimStampedInfo fDimFtmTriggerCounter;
379 DimStampedInfo fDimFtmError;
380 DimStampedInfo fDimFtmFtuList;
381 DimStampedInfo fDimFtmStaticData;
382 DimStampedInfo fDimFtmDynamicData;
383 DimStampedInfo fDimFtmCounter;
384
385 DimStampedInfo fDimFadRuns;
386 DimStampedInfo fDimFadEvents;
387 DimStampedInfo fDimFadEventData;
388 DimStampedInfo fDimFadConnections;
389 DimStampedInfo fDimFadFwVersion;
390 DimStampedInfo fDimFadRunNumber;
391 DimStampedInfo fDimFadDNA;
392 DimStampedInfo fDimFadTemperature;
393 DimStampedInfo fDimFadStatus;
394 DimStampedInfo fDimFadStatistics;
395
396 map<string, DimInfo*> fServices;
397
398 // ========================== LED Colors ================================
399
400 enum LedColor_t
401 {
402 kLedRed,
403 kLedGreen,
404 kLedYellow,
405 kLedOrange,
406 kLedGray
407 };
408
409 void SetLedColor(QPushButton *button, LedColor_t col, const Time &t)
410 {
411 switch (col)
412 {
413 case kLedRed:
414 button->setIcon(QIcon(":/Resources/icons/red circle 1.png"));
415 break;
416
417 case kLedGreen:
418 button->setIcon(QIcon(":/Resources/icons/green circle 1.png"));
419 break;
420
421 case kLedYellow:
422 button->setIcon(QIcon(":/Resources/icons/yellow circle 1.png"));
423 break;
424
425 case kLedOrange:
426 button->setIcon(QIcon(":/Resources/icons/orange circle 1.png"));
427 break;
428
429 case kLedGray:
430 button->setIcon(QIcon(":/Resources/icons/gray circle 1.png"));
431 break;
432 }
433
434 //button->setToolTip("Last change: "+QDateTime::currentDateTimeUtc().toString()+" UTC");
435 button->setToolTip(("Last change: "+t.GetAsStr()+" (UTC)").c_str());
436 }
437
438 // ===================== Services and Commands ==========================
439
440 QStandardItem *AddServiceItem(const std::string &server, const std::string &service, bool iscmd)
441 {
442 QListView *servers = iscmd ? fDimCmdServers : fDimSvcServers;
443 QListView *services = iscmd ? fDimCmdCommands : fDimSvcServices;
444 QListView *description = iscmd ? fDimCmdDescription : fDimSvcDescription;
445
446 QStandardItemModel *m = dynamic_cast<QStandardItemModel*>(servers->model());
447 if (!m)
448 {
449 m = new QStandardItemModel(this);
450 servers->setModel(m);
451 services->setModel(m);
452 description->setModel(m);
453 }
454
455 QList<QStandardItem*> l = m->findItems(server.c_str());
456
457 if (l.size()>1)
458 {
459 cout << "hae" << endl;
460 return 0;
461 }
462
463 QStandardItem *col = l.size()==0 ? NULL : l[0];
464
465 if (!col)
466 {
467 col = new QStandardItem(server.c_str());
468 m->appendRow(col);
469
470 if (!services->rootIndex().isValid())
471 {
472 services->setRootIndex(col->index());
473 servers->setCurrentIndex(col->index());
474 }
475 }
476
477 QStandardItem *item = 0;
478 for (int i=0; i<col->rowCount(); i++)
479 {
480 QStandardItem *coli = col->child(i);
481 if (coli->text().toStdString()==service)
482 return coli;
483 }
484
485 item = new QStandardItem(service.c_str());
486 col->appendRow(item);
487 col->sortChildren(0);
488
489 if (!description->rootIndex().isValid())
490 {
491 description->setRootIndex(item->index());
492 services->setCurrentIndex(item->index());
493 }
494
495 if (!iscmd)
496 item->setCheckable(true);
497
498 return item;
499 }
500
501 void AddDescription(QStandardItem *item, const vector<Description> &vec)
502 {
503 if (!item)
504 return;
505 if (vec.size()==0)
506 return;
507
508 item->setToolTip(vec[0].comment.c_str());
509
510 const string str = Description::GetHtmlDescription(vec);
511
512 QStandardItem *desc = new QStandardItem(str.c_str());
513 desc->setSelectable(false);
514 item->setChild(0, 0, desc);
515 }
516
517 void AddServer(const std::string &s)
518 {
519 DimNetwork::AddServer(s);
520
521 QApplication::postEvent(this,
522 new FunctionEvent(boost::bind(&FactGui::handleAddServer, this, s)));
523 }
524
525 void RemoveServer(const std::string &s)
526 {
527 UnsubscribeServer(s);
528
529 DimNetwork::RemoveServer(s);
530
531 QApplication::postEvent(this,
532 new FunctionEvent(boost::bind(&FactGui::handleRemoveServer, this, s)));
533 }
534
535 void RemoveAllServers()
536 {
537 UnsubscribeAllServers();
538
539 vector<string> v = GetServerList();
540 for (vector<string>::iterator i=v.begin(); i<v.end(); i++)
541 QApplication::postEvent(this,
542 new FunctionEvent(boost::bind(&FactGui::handleStateOffline, this, *i)));
543
544 DimNetwork::RemoveAllServers();
545
546 QApplication::postEvent(this,
547 new FunctionEvent(boost::bind(&FactGui::handleRemoveAllServers, this)));
548 }
549
550 void AddService(const std::string &server, const std::string &service, const std::string &fmt, bool iscmd)
551 {
552 QApplication::postEvent(this,
553 new FunctionEvent(boost::bind(&FactGui::handleAddService, this, server, service, fmt, iscmd)));
554 }
555
556 void RemoveService(const std::string &server, const std::string &service, bool iscmd)
557 {
558 if (fServices.find(server+'/'+service)!=fServices.end())
559 UnsubscribeService(server+'/'+service);
560
561 QApplication::postEvent(this,
562 new FunctionEvent(boost::bind(&FactGui::handleRemoveService, this, server, service, iscmd)));
563 }
564
565 void RemoveAllServices(const std::string &server)
566 {
567 UnsubscribeServer(server);
568
569 QApplication::postEvent(this,
570 new FunctionEvent(boost::bind(&FactGui::handleRemoveAllServices, this, server)));
571 }
572
573 void AddDescription(const std::string &server, const std::string &service, const vector<Description> &vec)
574 {
575 QApplication::postEvent(this,
576 new FunctionEvent(boost::bind(&FactGui::handleAddDescription, this, server, service, vec)));
577 }
578
579 // ======================================================================
580
581 void handleAddServer(const std::string &server)
582 {
583 const State s = GetState(server, GetCurrentState(server));
584 handleStateChanged(Time(), server, s);
585 }
586
587 void handleRemoveServer(const string &server)
588 {
589 handleStateOffline(server);
590 handleRemoveAllServices(server);
591 }
592
593 void handleRemoveAllServers()
594 {
595 QStandardItemModel *m = 0;
596 if ((m=dynamic_cast<QStandardItemModel*>(fDimCmdServers->model())))
597 m->removeRows(0, m->rowCount());
598
599 if ((m = dynamic_cast<QStandardItemModel*>(fDimSvcServers->model())))
600 m->removeRows(0, m->rowCount());
601 }
602
603 void handleAddService(const std::string &server, const std::string &service, const std::string &/*fmt*/, bool iscmd)
604 {
605 QStandardItem *item = AddServiceItem(server, service, iscmd);
606 const vector<Description> v = GetDescription(server, service);
607 AddDescription(item, v);
608 }
609
610 void handleRemoveService(const std::string &server, const std::string &service, bool iscmd)
611 {
612 QListView *servers = iscmd ? fDimCmdServers : fDimSvcServers;
613
614 QStandardItemModel *m = dynamic_cast<QStandardItemModel*>(servers->model());
615 if (!m)
616 return;
617
618 QList<QStandardItem*> l = m->findItems(server.c_str());
619 if (l.size()!=1)
620 return;
621
622 for (int i=0; i<l[0]->rowCount(); i++)
623 {
624 QStandardItem *row = l[0]->child(i);
625 if (row->text().toStdString()==service)
626 {
627 l[0]->removeRow(row->index().row());
628 return;
629 }
630 }
631 }
632
633 void handleRemoveAllServices(const std::string &server)
634 {
635 QStandardItemModel *m = 0;
636 if ((m=dynamic_cast<QStandardItemModel*>(fDimCmdServers->model())))
637 {
638 QList<QStandardItem*> l = m->findItems(server.c_str());
639 if (l.size()==1)
640 m->removeRow(l[0]->index().row());
641 }
642
643 if ((m = dynamic_cast<QStandardItemModel*>(fDimSvcServers->model())))
644 {
645 QList<QStandardItem*> l = m->findItems(server.c_str());
646 if (l.size()==1)
647 m->removeRow(l[0]->index().row());
648 }
649 }
650
651 void handleAddDescription(const std::string &server, const std::string &service, const vector<Description> &vec)
652 {
653 const bool iscmd = IsCommand(server, service)==true;
654
655 QStandardItem *item = AddServiceItem(server, service, iscmd);
656 AddDescription(item, vec);
657 }
658
659 // ======================================================================
660
661 void SubscribeService(const string &service)
662 {
663 if (fServices.find(service)!=fServices.end())
664 {
665 cout << "ERROR - We are already subscribed to " << service << endl;
666 return;
667 }
668
669 fServices[service] = new DimStampedInfo(service.c_str(), (void*)NULL, 0, this);
670 }
671
672 void UnsubscribeService(const string &service)
673 {
674 const map<string,DimInfo*>::iterator i=fServices.find(service);
675
676 if (i==fServices.end())
677 {
678 cout << "ERROR - We are not subscribed to " << service << endl;
679 return;
680 }
681
682 delete i->second;
683
684 fServices.erase(i);
685 }
686
687 void UnsubscribeServer(const string &server)
688 {
689 for (map<string,DimInfo*>::iterator i=fServices.begin();
690 i!=fServices.end(); i++)
691 if (i->first.substr(0, server.length()+1)==server+'/')
692 {
693 delete i->second;
694 fServices.erase(i);
695 }
696 }
697
698 void UnsubscribeAllServers()
699 {
700 for (map<string,DimInfo*>::iterator i=fServices.begin();
701 i!=fServices.end(); i++)
702 delete i->second;
703
704 fServices.clear();
705 }
706
707 // ======================================================================
708
709 struct DimData
710 {
711 const int qos;
712 const string name;
713 const string format;
714 const vector<char> data;
715 const Time time;
716
717 Time extract(DimInfo *inf) const
718 {
719 // Must be called in exactly this order!
720 const int tsec = inf->getTimestamp();
721 const int tms = inf->getTimestampMillisecs();
722
723 return Time(tsec, tms*1000);
724 }
725
726// DimInfo *info; // this is ONLY for a fast check of the type of the DimData!!
727
728 DimData(DimInfo *inf) :
729 qos(inf->getQuality()),
730 name(inf->getName()),
731 format(inf->getFormat()),
732 data(inf->getString(), inf->getString()+inf->getSize()),
733 time(extract(inf))/*,
734 info(inf)*/
735 {
736 }
737
738 template<typename T>
739 T get(uint32_t offset=0) const { return *reinterpret_cast<const T*>(data.data()+offset); }
740
741 template<typename T>
742 const T *ptr(uint32_t offset=0) const { return reinterpret_cast<const T*>(data.data()+offset); }
743
744 template<typename T>
745 const T &ref(uint32_t offset=0) const { return *reinterpret_cast<const T*>(data.data()+offset); }
746
747// vector<char> vec(int b) const { return vector<char>(data.begin()+b, data.end()); }
748// string str(unsigned int b) const { return b>=data.size()?string():string(data.data()+b, data.size()-b); }
749 const char *c_str() const { return (char*)data.data(); }
750/*
751 vector<boost::any> any() const
752 {
753 const Converter conv(format);
754 conv.Print();
755 return conv.GetAny(data.data(), data.size());
756 }*/
757 size_t size() const { return data.size(); }
758 };
759
760 // ======================= DNS ==========================================
761
762 void handleDimDNS(const DimData &d)
763 {
764 const int version = d.size()!=4 ? 0 : d.get<uint32_t>();
765
766 ostringstream str;
767 str << "V" << version/100 << 'r' << version%100;
768
769 SetLedColor(fStatusDNSLed, version==0 ? kLedRed : kLedGreen, Time());
770
771 fStatusDNSLabel->setText(version==0?"Offline":str.str().c_str());
772 fStatusDNSLabel->setToolTip(version==0?"No connection to DIM DNS.":"Connection to DIM DNS established.");
773 }
774
775
776 // ======================= Logger =======================================
777
778 void handleLoggerStats(const DimData &d)
779 {
780 const bool connected = d.size()!=0;
781
782 fLoggerET->setEnabled(connected);
783 fLoggerRate->setEnabled(connected);
784 fLoggerWritten->setEnabled(connected);
785 fLoggerFreeSpace->setEnabled(connected);
786 fLoggerSpaceLeft->setEnabled(connected);
787
788 if (!connected)
789 return;
790
791 const uint64_t *vals = d.ptr<uint64_t>();
792
793 const size_t written = vals[0];
794 const size_t space = vals[1];
795 const size_t rate = vals[2];
796
797 fLoggerFreeSpace->setSuffix(" MB");
798 fLoggerFreeSpace->setDecimals(0);
799 fLoggerFreeSpace->setValue(space*1e-6);
800
801 if (space> 1000000) // > 1GB
802 {
803 fLoggerFreeSpace->setSuffix(" GB");
804 fLoggerFreeSpace->setDecimals(2);
805 fLoggerFreeSpace->setValue(space*1e-9);
806 }
807 if (space>= 3000000) // >= 3GB
808 {
809 fLoggerFreeSpace->setSuffix(" GB");
810 fLoggerFreeSpace->setDecimals(1);
811 fLoggerFreeSpace->setValue(space*1e-9);
812 }
813 if (space>=100000000) // >= 100GB
814 {
815 fLoggerFreeSpace->setSuffix(" GB");
816 fLoggerFreeSpace->setDecimals(0);
817 fLoggerFreeSpace->setValue(space*1e-9);
818 }
819
820 fLoggerET->setTime(QTime().addSecs(rate>0?space/rate:0));
821 fLoggerRate->setValue(rate*1e-3); // kB/s
822 fLoggerWritten->setValue(written*1e-6);
823
824 fLoggerRate->setSuffix(" kB/s");
825 fLoggerRate->setDecimals(2);
826 fLoggerRate->setValue(rate*1e-3);
827 if (rate> 2000) // > 2kB/s
828 {
829 fLoggerRate->setSuffix(" kB/s");
830 fLoggerRate->setDecimals(1);
831 fLoggerRate->setValue(rate*1e-3);
832 }
833 if (rate>=100000) // >100kB/s
834 {
835 fLoggerRate->setSuffix(" kB/s");
836 fLoggerRate->setDecimals(0);
837 fLoggerRate->setValue(rate*1e-3);
838 }
839 if (rate>=1000000) // >100kB/s
840 {
841 fLoggerRate->setSuffix(" MB/s");
842 fLoggerRate->setDecimals(2);
843 fLoggerRate->setValue(rate*1e-6);
844 }
845 if (rate>=10000000) // >1MB/s
846 {
847 fLoggerRate->setSuffix(" MB/s");
848 fLoggerRate->setDecimals(1);
849 fLoggerRate->setValue(rate*1e-6);
850 }
851 if (rate>=100000000) // >10MB/s
852 {
853 fLoggerRate->setSuffix(" MB/s");
854 fLoggerRate->setDecimals(0);
855 fLoggerRate->setValue(rate*1e-6);
856 }
857
858 if (space/1000000>static_cast<size_t>(fLoggerSpaceLeft->maximum()))
859 fLoggerSpaceLeft->setValue(fLoggerSpaceLeft->maximum()); // GB
860 else
861 fLoggerSpaceLeft->setValue(space/1000000); // MB
862 }
863
864 void handleLoggerFilenameNight(const DimData &d)
865 {
866 const bool connected = d.size()!=0;
867
868 fLoggerFilenameNight->setEnabled(connected);
869 if (!connected)
870 return;
871
872 fLoggerFilenameNight->setText(d.c_str()+4);
873
874 const uint32_t files = d.get<uint32_t>();
875
876 SetLedColor(fLoggerLedLog, files&1 ? kLedGreen : kLedGray, d.time);
877 SetLedColor(fLoggerLedRep, files&2 ? kLedGreen : kLedGray, d.time);
878 SetLedColor(fLoggerLedFits, files&4 ? kLedGreen : kLedGray, d.time);
879 }
880
881 void handleLoggerFilenameRun(const DimData &d)
882 {
883 const bool connected = d.size()!=0;
884
885 fLoggerFilenameRun->setEnabled(connected);
886 if (!connected)
887 return;
888
889 fLoggerFilenameRun->setText(d.c_str()+4);
890
891 const uint32_t files = d.get<uint32_t>();
892
893 SetLedColor(fLoggerLedLog, files&1 ? kLedGreen : kLedGray, d.time);
894 SetLedColor(fLoggerLedRep, files&2 ? kLedGreen : kLedGray, d.time);
895 SetLedColor(fLoggerLedFits, files&4 ? kLedGreen : kLedGray, d.time);
896 }
897
898 void handleLoggerNumSubs(const DimData &d)
899 {
900 const bool connected = d.size()!=0;
901
902 fLoggerSubscriptions->setEnabled(connected);
903 fLoggerOpenFiles->setEnabled(connected);
904 if (!connected)
905 return;
906
907 const uint32_t *vals = d.ptr<uint32_t>();
908
909 fLoggerSubscriptions->setValue(vals[0]);
910 fLoggerOpenFiles->setValue(vals[1]);
911 }
912
913
914 // ===================== All ============================================
915
916 bool CheckSize(const DimData &d, size_t sz) const
917 {
918 if (d.size()==0)
919 return false;
920
921 if (d.size()!=sz)
922 {
923 cout << "Size mismatch in " << d.name << ": Found=" << d.size() << " Expected=" << sz << endl;
924 return false;
925 }
926
927 return true;
928 }
929
930 // ===================== FAD ============================================
931
932 void handleFadRuns(const DimData &d)
933 {
934 if (!CheckSize(d, 20))
935 return;
936
937 const uint32_t *ptr = d.ptr<uint32_t>();
938
939 fEvtBldOpenFiles->setValue(ptr[0]);
940 fEvtBldOpenStreams->setValue(ptr[0]);
941 fEvtBldRunNumberMin->setValue(ptr[1]);
942 fEvtBldRunNumberMax->setValue(ptr[2]);
943 fEvtBldLastOpened->setValue(ptr[3]);
944 fEvtBldLastClosed->setValue(ptr[4]);
945 }
946
947 void handleFadEvents(const DimData &d)
948 {
949 if (!CheckSize(d, 16))
950 return;
951
952 const uint32_t *ptr = d.ptr<uint32_t>();
953
954 fEvtsSuccessCurRun->setValue(ptr[0]);
955 fEvtsSuccessTotal->setValue(ptr[1]);
956 fEvtBldEventId->setValue(ptr[2]);
957 fEvtBldTriggerId->setValue(ptr[3]);
958 }
959
960 void handleFadTemperature(const DimData &d)
961 {
962 if (d.size()==0)
963 {
964 fFadTempMin->setEnabled(false);
965 fFadTempMax->setEnabled(false);
966 return;
967 }
968
969 if (!CheckSize(d, 82*sizeof(float)))
970 return;
971
972 const float *ptr = d.ptr<float>();
973
974 fFadTempMin->setEnabled(true);
975 fFadTempMax->setEnabled(true);
976
977 fFadTempMin->setValue(ptr[0]);
978 fFadTempMax->setValue(ptr[40]);
979
980 handleFadToolTip(d.time, fFadTempMin, ptr+1);
981 handleFadToolTip(d.time, fFadTempMax, ptr+41);
982 }
983
984 struct DimEventData
985 {
986 uint16_t Roi ; // #slices per pixel (same for all pixels and tmarks)
987 uint32_t EventNum ; // EventNumber as from FTM
988 uint16_t TriggerType ; // Trigger Type from FTM
989
990 uint32_t PCTime ; // when did event start to arrive at PC
991 uint32_t BoardTime; //
992
993 int16_t StartPix; // First Channel per Pixel (Pixels sorted according Software ID) ; -1 if not filled
994 int16_t StartTM; // First Channel for TimeMark (sorted Hardware ID) ; -1 if not filled
995
996 int16_t Adc_Data[]; // final length defined by malloc ....
997
998 } __attribute__((__packed__));;
999
1000 void handleFadEventData(const DimData &d)
1001 {
1002 if (d.size()==0)
1003 return;
1004
1005#ifdef HAVE_ROOT
1006 const DimEventData &dat = d.ref<DimEventData>();
1007
1008 if (d.size()<sizeof(DimEventData))
1009 {
1010 cout << "Size mismatch in " << d.name << ": Found=" << d.size() << " Expected=" << sizeof(DimEventData) << endl;
1011 return;
1012 }
1013
1014 if (d.size()!=dat.Roi*2+sizeof(DimEventData))
1015 {
1016 cout << "Size mismatch in " << d.name << ": Found=" << d.size() << " Expected=" << dat.Roi*2+sizeof(DimEventData) << endl;
1017 return;
1018 }
1019
1020 TCanvas *c = fAdcDataCanv->GetCanvas();
1021
1022 TH1 *h = dynamic_cast<TH1*>(c->FindObject("EventData"));
1023 if (h && h->GetNbinsX()!=dat.Roi)
1024 {
1025 delete h;
1026 h = 0;
1027 }
1028
1029 if (!h)
1030 {
1031 c->cd();
1032
1033 TH1D hist("EventData", "", dat.Roi, -0.5, dat.Roi-0.5);
1034 hist.SetStats(kFALSE);
1035 //hist->SetBit(TH1::kNoTitle);
1036 hist.SetMarkerStyle(kFullDotMedium);
1037 hist.SetMarkerColor(kBlue);
1038 hist.SetYTitle("Voltage [mV]");
1039 hist.GetXaxis()->CenterTitle();
1040 hist.GetYaxis()->CenterTitle();
1041 hist.SetMinimum(-1026);
1042 hist.SetMaximum(1025);
1043 h = hist.DrawCopy("PL");
1044 h->SetDirectory(0);
1045 }
1046
1047 ostringstream str;
1048 str << "ADC Pipeline (start=" << dat.StartPix << ") " << dat.EventNum;
1049 h->SetXTitle(str.str().c_str());
1050
1051 //str.str("");
1052 //str << "Crate=" << crate << " Board=" << board << " Channel=" << channel << " [" << d.time() << "]" << endl;
1053 //hist->SetTitle(str.str().c_str());
1054
1055 for (int i=0; i<dat.Roi; i++)
1056 h->SetBinContent(i+1, dat.Adc_Data[i]*0.5);
1057
1058 c->Modified();
1059 c->Update();
1060#endif
1061 }
1062
1063// vector<uint8_t> fFadConnections;
1064
1065 void handleFadConnections(const DimData &d)
1066 {
1067 if (!CheckSize(d, 41))
1068 return;
1069
1070 const uint8_t *ptr = d.ptr<uint8_t>();
1071
1072 for (int i=0; i<40; i++)
1073 {
1074 const uint8_t stat1 = ptr[i]&3;
1075 const uint8_t stat2 = ptr[i]>>3;
1076
1077 if (stat1==0 && stat2==0)
1078 {
1079 SetLedColor(fFadLED[i], kLedGray, d.time);
1080 continue;
1081 }
1082 if (stat1==2 && stat2==8)
1083 {
1084 SetLedColor(fFadLED[i], kLedGreen, d.time);
1085 continue;
1086 }
1087
1088 if (stat1==1 && stat2==1)
1089 SetLedColor(fFadLED[i], kLedRed, d.time);
1090 else
1091 SetLedColor(fFadLED[i], kLedOrange, d.time);
1092 }
1093
1094
1095 const bool runs = ptr[40]!=0;
1096
1097 fStatusEventBuilderLabel->setText(runs?"Running":"Not running");
1098 fStatusEventBuilderLabel->setToolTip(runs?"Event builder thread running.":"Event builder thread stopped.");
1099 fEvtBldWidget->setEnabled(runs);
1100
1101 SetLedColor(fStatusEventBuilderLed, runs?kLedGreen:kLedRed, d.time);
1102
1103// fFadConnections.assign(ptr, ptr+40);
1104 }
1105
1106 template<typename T>
1107 void handleFadToolTip(const Time &time, QWidget *w, T *ptr)
1108 {
1109 ostringstream tip;
1110 tip << "<table border='1'><tr><th colspan='11'>" << time.GetAsStr() << " (UTC)</th></tr><tr><th></th>";
1111 for (int b=0; b<10; b++)
1112 tip << "<th>" << b << "</th>";
1113 tip << "</tr>";
1114
1115 for (int c=0; c<4; c++)
1116 {
1117 tip << "<tr><th>" << c << "</th>";
1118 for (int b=0; b<10; b++)
1119 tip << "<td>" << ptr[c*10+b] << "</td>";
1120 tip << "</tr>";
1121 }
1122 tip << "</table>";
1123
1124 w->setToolTip(tip.str().c_str());
1125 }
1126
1127 template<typename T, class S>
1128 void handleFadMinMax(const DimData &d, QPushButton *led, S *wmin, S *wmax=0)
1129 {
1130 if (!CheckSize(d, 42*sizeof(T)))
1131 return;
1132
1133 const T *ptr = d.ptr<T>();
1134 const T min = ptr[40];
1135 const T max = ptr[41];
1136
1137 if (max<min)
1138 SetLedColor(led, kLedGray, d.time);
1139 else
1140 SetLedColor(led, min==max?kLedGreen: kLedOrange, d.time);
1141
1142 if (!wmax && max!=min)
1143 wmin->setValue(0);
1144 else
1145 wmin->setValue(min);
1146
1147 if (wmax)
1148 wmax->setValue(max);
1149
1150 handleFadToolTip(d.time, led, ptr);
1151 }
1152
1153 void handleFadFwVersion(const DimData &d)
1154 {
1155 handleFadMinMax<float, QDoubleSpinBox>(d, fFadLedFwVersion, fFadFwVersion);
1156 }
1157
1158 void handleFadRunNumber(const DimData &d)
1159 {
1160 handleFadMinMax<uint32_t, QSpinBox>(d, fFadLedRunNumber, fFadRunNumber);
1161 }
1162
1163 void handleFadDNA(const DimData &d)
1164 {
1165 if (!CheckSize(d, 40*sizeof(uint64_t)))
1166 return;
1167
1168 const uint64_t *ptr = d.ptr<uint64_t>();
1169
1170 ostringstream tip;
1171 tip << "<table width='100%'>";
1172 tip << "<tr><th>Crate</th><td></td><th>Board</th><td></td><th>DNA</th></tr>";
1173
1174 for (int i=0; i<40; i++)
1175 {
1176 tip << dec;
1177 tip << "<tr>";
1178 tip << "<td align='center'>" << i/10 << "</td><td>:</td>";
1179 tip << "<td align='center'>" << i%10 << "</td><td>:</td>";
1180 tip << hex;
1181 tip << "<td>0x" << setfill('0') << setw(16) << ptr[i] << "</td>";
1182 tip << "</tr>";
1183 }
1184 tip << "</table>";
1185
1186 fFadDNA->setText(tip.str().c_str());
1187 }
1188
1189 void SetFadLed(QPushButton *led, const DimData &d, uint16_t bitmask, bool invert=false)
1190 {
1191 if (d.size()==0)
1192 {
1193 SetLedColor(led, kLedGray, d.time);
1194 return;
1195 }
1196
1197 const bool quality = d.ptr<uint16_t>()[0]&bitmask;
1198 const bool value = d.ptr<uint16_t>()[1]&bitmask;
1199 const uint16_t *ptr = d.ptr<uint16_t>()+2;
1200
1201 SetLedColor(led, quality?kLedOrange:(value^invert?kLedGreen:kLedRed), d.time);
1202
1203 ostringstream tip;
1204 tip << "<table border='1'><tr><th colspan='11'>" << d.time.GetAsStr() << " (UTC)</th></tr><tr><th></th>";
1205 for (int b=0; b<10; b++)
1206 tip << "<th>" << b << "</th>";
1207 tip << "</tr>";
1208
1209 /*
1210 tip << "<tr>" << hex;
1211 tip << "<th>" << d.ptr<uint16_t>()[0] << " " << (d.ptr<uint16_t>()[0]&bitmask) << "</th>";
1212 tip << "<th>" << d.ptr<uint16_t>()[1] << " " << (d.ptr<uint16_t>()[1]&bitmask) << "</th>";
1213 tip << "</tr>";
1214 */
1215
1216 for (int c=0; c<4; c++)
1217 {
1218 tip << "<tr><th>" << dec << c << "</th>" << hex;
1219 for (int b=0; b<10; b++)
1220 {
1221 tip << "<td>"
1222 << (ptr[c*10+b]&bitmask)
1223 << "</td>";
1224 }
1225 tip << "</tr>";
1226 }
1227 tip << "</table>";
1228
1229 led->setToolTip(tip.str().c_str());
1230 }
1231
1232 void handleFadStatus(const DimData &d)
1233 {
1234 if (d.size()!=0 && !CheckSize(d, 42*sizeof(uint16_t)))
1235 return;
1236
1237 SetFadLed(fFadLedDrsEnabled, d, FAD::EventHeader::kDenable);
1238 SetFadLed(fFadLedDrsWrite, d, FAD::EventHeader::kDwrite);
1239 SetFadLed(fFadLedDcmLocked, d, FAD::EventHeader::kDcmLocked);
1240 SetFadLed(fFadLedDcmReady, d, FAD::EventHeader::kDcmReady);
1241 SetFadLed(fFadLedSpiSclk, d, FAD::EventHeader::kSpiSclk);
1242 SetFadLed(fFadLedRefClockTooLow, d, FAD::EventHeader::kRefClkTooLow, true);
1243 SetFadLed(fFadLedBusy, d, FAD::EventHeader::kBusy);
1244 SetFadLed(fFadLedTriggerLine, d, FAD::EventHeader::kTriggerLine);
1245 SetFadLed(fFadLedContTrigger, d, FAD::EventHeader::kContTrigger);
1246 SetFadLed(fFadLedSocket, d, FAD::EventHeader::kSock17);
1247 SetFadLed(fFadLedPllLock, d, 0xf000);
1248 }
1249
1250 void handleFadStatistics(const DimData &d)
1251 {
1252 if (!CheckSize(d, 8*sizeof(int64_t)))
1253 return;
1254
1255 const int64_t *stat = d.ptr<int64_t>();
1256
1257 fFadBufferMax->setValue(stat[0]/1000000);
1258 fFadBuffer->setMaximum(stat[0]);
1259 fFadBuffer->setValue(stat[5]);
1260
1261 fFadEvtWait->setValue(stat[1]);
1262 fFadEvtSkip->setValue(stat[2]);
1263 fFadEvtDel->setValue(stat[3]);
1264 fFadEvtTot->setValue(stat[4]);
1265 fFadEthernetRateTot->setValue(stat[6]/1024.);
1266 fFadEthernetRateAvg->setValue(stat[6]/1024./stat[7]);
1267 fFadEvtConn->setValue(stat[7]);
1268 }
1269
1270
1271 // ===================== FTM ============================================
1272
1273 double fTimeStamp1;
1274
1275 void handleFtmTriggerCounter(const DimData &d)
1276 {
1277 if (!CheckSize(d, sizeof(FTM::DimTriggerCounter)))
1278 return;
1279
1280 const FTM::DimTriggerCounter &sdata = d.ref<FTM::DimTriggerCounter>();
1281
1282 fFtmTime->setText(QString::number(sdata.fTimeStamp/1000000., 'f', 6)+ " s");
1283 fTriggerCounter->setText(QString::number(sdata.fTriggerCounter));
1284
1285 if (sdata.fTimeStamp>0)
1286 fTriggerCounterRate->setValue(1000000.*sdata.fTriggerCounter/sdata.fTimeStamp);
1287 else
1288 fTriggerCounterRate->setValue(0);
1289
1290
1291 // ----------------------------------------------
1292#ifdef HAVE_ROOT
1293
1294 if (fTriggerCounter0<0)
1295 {
1296 fTriggerCounter0 = sdata.fTriggerCounter;
1297 fTimeStamp1 = sdata.fTimeStamp;
1298 return;
1299 }
1300
1301 TCanvas *c = fFtmRateCanv->GetCanvas();
1302
1303 TH1 *h = (TH1*)c->FindObject("TimeFrame");
1304
1305 const double rate = sdata.fTriggerCounter-fTriggerCounter0;
1306 const double tdiff = sdata.fTimeStamp -fTimeStamp1;
1307
1308 fTriggerCounter0 = sdata.fTriggerCounter;
1309 fTimeStamp1 = sdata.fTimeStamp;
1310
1311 if (rate<0 && tdiff<=0)
1312 {
1313 fGraphFtmRate.Set(0);
1314
1315 const double tm = Time().RootTime();
1316
1317 h->SetBins(1, tm, tm+60);
1318 h->GetXaxis()->SetTimeFormat("%M'%S\"");
1319 h->GetXaxis()->SetTitle("Time");
1320
1321 c->Modified();
1322 c->Update();
1323 return;
1324 }
1325
1326 if (rate<0)
1327 return;
1328
1329// const double avgrate = sdata.fTimeStamp>0 ? double(sdata.fTriggerCounter)/sdata.fTimeStamp*1000000 : 1;
1330
1331 const double t1 = h->GetXaxis()->GetXmax();
1332 const double t0 = h->GetXaxis()->GetXmin();
1333
1334 h->SetBins(h->GetNbinsX()+1, t0, t0+sdata.fTimeStamp/1000000.+1);
1335 fGraphFtmRate.SetPoint(fGraphFtmRate.GetN(),
1336 t0+sdata.fTimeStamp/1000000., 1000000*rate/tdiff);
1337
1338 if (t1-t0>60)
1339 {
1340 h->GetXaxis()->SetTimeFormat("%Hh%M'");
1341 h->GetXaxis()->SetTitle("Time");
1342 }
1343
1344 h->SetMinimum(0);
1345// h->SetMaximum(2*avgrate);
1346
1347 c->Modified();
1348 c->Update();
1349#endif
1350 // ----------------------------------------------
1351 }
1352
1353 void handleFtmCounter(const DimData &d)
1354 {
1355 if (!CheckSize(d, sizeof(uint32_t)*6))
1356 return;
1357
1358 const uint32_t *sdata = d.ptr<uint32_t>();
1359
1360 fFtmCounterH->setValue(sdata[0]);
1361 fFtmCounterS->setValue(sdata[1]);
1362 fFtmCounterD->setValue(sdata[2]);
1363 fFtmCounterF->setValue(sdata[3]);
1364 fFtmCounterE->setValue(sdata[4]);
1365 fFtmCounterR->setValue(sdata[5]);
1366 }
1367
1368 int64_t fTriggerCounter0;
1369 int64_t fTimeStamp0;
1370
1371 void handleFtmDynamicData(const DimData &d)
1372 {
1373 if (!CheckSize(d, sizeof(FTM::DimDynamicData)))
1374 return;
1375
1376 const FTM::DimDynamicData &sdata = d.ref<FTM::DimDynamicData>();
1377
1378 fOnTime->setText(QString::number(sdata.fOnTimeCounter/1000000., 'f', 6)+" s");
1379
1380 if (sdata.fTimeStamp>0)
1381 fOnTimeRel->setValue(100.*sdata.fOnTimeCounter/sdata.fTimeStamp);
1382 else
1383 fOnTimeRel->setValue(0);
1384
1385 fFtmTemp0->setValue(sdata.fTempSensor[0]*0.1);
1386 fFtmTemp1->setValue(sdata.fTempSensor[1]*0.1);
1387 fFtmTemp2->setValue(sdata.fTempSensor[2]*0.1);
1388 fFtmTemp3->setValue(sdata.fTempSensor[3]*0.1);
1389
1390
1391#ifdef HAVE_ROOT
1392
1393 // ----------------------------------------------
1394
1395 if (fTimeStamp0<0)
1396 {
1397 fTimeStamp0 = sdata.fTimeStamp;
1398 return;
1399 }
1400
1401 TCanvas *c = fFtmRateCanv->GetCanvas();
1402
1403 TH1 *h = (TH1*)c->FindObject("TimeFrame");
1404
1405 const double tdiff = sdata.fTimeStamp-fTimeStamp0;
1406 fTimeStamp0 = sdata.fTimeStamp;
1407
1408 if (tdiff<0)
1409 {
1410 for (int i=0; i<160; i++)
1411 fGraphPatchRate[i].Set(0);
1412 for (int i=0; i<40; i++)
1413 fGraphBoardRate[i].Set(0);
1414
1415 return;
1416 }
1417
1418 //const double t1 = h->GetXaxis()->GetXmax();
1419 const double t0 = h->GetXaxis()->GetXmin();
1420
1421 for (int i=0; i<160; i++)
1422 fGraphPatchRate[i].SetPoint(fGraphPatchRate[i].GetN(),
1423 t0+sdata.fTimeStamp/1000000., float(sdata.fRatePatch[i])*2/fFtmStaticData.fPrescaling[i]);
1424 for (int i=0; i<40; i++)
1425 fGraphBoardRate[i].SetPoint(fGraphBoardRate[i].GetN(),
1426 t0+sdata.fTimeStamp/1000000., float(sdata.fRateBoard[i])*2/fFtmStaticData.fPrescaling[i]);
1427
1428 c->Modified();
1429 c->Update();
1430
1431 //fGraphFtmRate.ComputeRange(x[0], x[1], x[2], x[3]);
1432
1433 // ----------------------------------------------
1434
1435 if (fThresholdIdx->value()>=0)
1436 {
1437 const int isw = fThresholdIdx->value();
1438 const int ihw = fPatchMapHW[isw];
1439 fPatchRate->setValue(sdata.fRatePatch[ihw]);
1440 }
1441
1442 valarray<double> dat(0., 1440);
1443
1444 // fPatch converts from software id to software patch id
1445 for (int i=0; i<1440; i++)
1446 {
1447 const int ihw = fPatchHW[i];
1448// const int isw = fPatch[i];
1449// const int ihw = fPatchMapHW[isw];
1450 dat[i] = sdata.fRatePatch[ihw];
1451 }
1452
1453 c = fRatesCanv->GetCanvas();
1454 Camera *cam = (Camera*)c->FindObject("Camera");
1455
1456 cam->SetData(dat);
1457
1458 c->Modified();
1459 c->Update();
1460
1461 // ----------------------------------------------
1462#endif
1463 }
1464
1465 void DisplayRates()
1466 {
1467#ifdef HAVE_ROOT
1468 TCanvas *c = fFtmRateCanv->GetCanvas();
1469
1470 while (c->FindObject("PatchRate"))
1471 c->GetListOfPrimitives()->Remove(c->FindObject("PatchRate"));
1472
1473 while (c->FindObject("BoardRate"))
1474 c->GetListOfPrimitives()->Remove(c->FindObject("BoardRate"));
1475
1476 c->cd();
1477
1478 if (fRatePatch1->value()>=0)
1479 {
1480 fGraphPatchRate[fRatePatch1->value()].SetLineColor(kRed);
1481 fGraphPatchRate[fRatePatch1->value()].SetMarkerColor(kRed);
1482 fGraphPatchRate[fRatePatch1->value()].Draw("PL");
1483 }
1484 if (fRatePatch2->value()>=0)
1485 {
1486 fGraphPatchRate[fRatePatch2->value()].SetLineColor(kGreen);
1487 fGraphPatchRate[fRatePatch2->value()].SetMarkerColor(kGreen);
1488 fGraphPatchRate[fRatePatch2->value()].Draw("PL");
1489 }
1490 if (fRateBoard1->value()>=0)
1491 {
1492 fGraphBoardRate[fRateBoard1->value()].SetLineColor(kMagenta);
1493 fGraphBoardRate[fRateBoard1->value()].SetMarkerColor(kMagenta);
1494 fGraphBoardRate[fRateBoard1->value()].Draw("PL");
1495 }
1496 if (fRateBoard2->value()>=0)
1497 {
1498 fGraphBoardRate[fRateBoard2->value()].SetLineColor(kCyan);
1499 fGraphBoardRate[fRateBoard2->value()].SetMarkerColor(kCyan);
1500 fGraphBoardRate[fRateBoard2->value()].Draw("PL");
1501 }
1502#endif
1503 }
1504
1505 void on_fRatePatch1_valueChanged(int)
1506 {
1507 DisplayRates();
1508 }
1509
1510 void on_fRatePatch2_valueChanged(int)
1511 {
1512 DisplayRates();
1513 }
1514
1515 void on_fRateBoard1_valueChanged(int)
1516 {
1517 DisplayRates();
1518 }
1519
1520 void on_fRateBoard2_valueChanged(int)
1521 {
1522 DisplayRates();
1523 }
1524
1525 FTM::DimStaticData fFtmStaticData;
1526
1527 void SetFtuLed(int idx, int counter, const Time &t)
1528 {
1529 if (counter==0 || counter>3)
1530 counter = 3;
1531
1532 if (counter<0)
1533 counter = 0;
1534
1535 const LedColor_t col[4] = { kLedGray, kLedGreen, kLedOrange, kLedRed };
1536
1537 SetLedColor(fFtuLED[idx], col[counter], t);
1538
1539 fFtuStatus[idx] = counter;
1540 }
1541
1542 void SetFtuStatusLed(const Time &t)
1543 {
1544 const int max = fFtuStatus.max();
1545
1546 switch (max)
1547 {
1548 case 0:
1549 SetLedColor(fStatusFTULed, kLedGray, t);
1550 fStatusFTULabel->setText("All disabled");
1551 fStatusFTULabel->setToolTip("All FTUs are disabled");
1552 break;
1553
1554 case 1:
1555 SetLedColor(fStatusFTULed, kLedGreen, t);
1556 fStatusFTULabel->setToolTip("Communication with FTU is smooth.");
1557 fStatusFTULabel->setText("ok");
1558 break;
1559
1560 case 2:
1561 SetLedColor(fStatusFTULed, kLedOrange, t);
1562 fStatusFTULabel->setText("Warning");
1563 fStatusFTULabel->setToolTip("At least one FTU didn't answer immediately");
1564 break;
1565
1566 case 3:
1567 SetLedColor(fStatusFTULed, kLedRed, t);
1568 fStatusFTULabel->setToolTip("At least one FTU didn't answer!");
1569 fStatusFTULabel->setText("ERROR");
1570 break;
1571 }
1572
1573 const int cnt = count(&fFtuStatus[0], &fFtuStatus[40], 0);
1574 fFtuAllOn->setEnabled(cnt!=0);
1575 fFtuAllOff->setEnabled(cnt!=40);
1576 }
1577
1578 void handleFtmStaticData(const DimData &d)
1579 {
1580 if (!CheckSize(d, sizeof(FTM::DimStaticData)))
1581 return;
1582
1583 const FTM::DimStaticData &sdata = d.ref<FTM::DimStaticData>();
1584
1585 fTriggerInterval->setValue(sdata.fTriggerInterval);
1586 fPhysicsCoincidence->setValue(sdata.fMultiplicityPhysics);
1587 fCalibCoincidence->setValue(sdata.fMultiplicityCalib);
1588 fPhysicsWindow->setValue(sdata.fWindowPhysics);
1589 fCalibWindow->setValue(sdata.fWindowCalib);
1590
1591 fTriggerDelay->setValue(sdata.fDelayTrigger);
1592 fTimeMarkerDelay->setValue(sdata.fDelayTimeMarker);
1593 fDeadTime->setValue(sdata.fDeadTime);
1594
1595 fClockCondR0->setValue(sdata.fClockConditioner[0]);
1596 fClockCondR1->setValue(sdata.fClockConditioner[1]);
1597 fClockCondR8->setValue(sdata.fClockConditioner[2]);
1598 fClockCondR9->setValue(sdata.fClockConditioner[3]);
1599 fClockCondR11->setValue(sdata.fClockConditioner[4]);
1600 fClockCondR13->setValue(sdata.fClockConditioner[5]);
1601 fClockCondR14->setValue(sdata.fClockConditioner[6]);
1602 fClockCondR15->setValue(sdata.fClockConditioner[7]);
1603
1604 const uint32_t R0 = sdata.fClockConditioner[0];
1605 const uint32_t R14 = sdata.fClockConditioner[6];
1606 const uint32_t R15 = sdata.fClockConditioner[7];
1607
1608 const uint32_t Ndiv = (R15&0x1ffff00)<<2;
1609 const uint32_t Rdiv = (R14&0x007ff00)>>8;
1610 const uint32_t Cdiv = (R0 &0x000ff00)>>8;
1611
1612 double freq = 40.*Ndiv/(Rdiv*Cdiv);
1613
1614 fClockCondFreqRes->setValue(freq);
1615
1616 //fClockCondFreq->setEditText("");
1617 fClockCondFreq->setCurrentIndex(0);
1618
1619 fTriggerSeqPed->setValue(sdata.fTriggerSeqPed);
1620 fTriggerSeqLPint->setValue(sdata.fTriggerSeqLPint);
1621 fTriggerSeqLPext->setValue(sdata.fTriggerSeqLPext);
1622
1623 fEnableTrigger->setChecked(sdata.HasTrigger());
1624 fEnableVeto->setChecked(sdata.HasVeto());
1625 fEnableExt1->setChecked(sdata.HasExt1());
1626 fEnableExt2->setChecked(sdata.HasExt2());
1627 fEnableClockCond->setChecked(sdata.HasClockConditioner());
1628
1629 for (int i=0; i<40; i++)
1630 {
1631 if (!sdata.IsActive(i))
1632 SetFtuLed(i, -1, d.time);
1633 else
1634 {
1635 if (fFtuStatus[i]==0)
1636 SetFtuLed(i, 1, d.time);
1637 }
1638 fFtuLED[i]->setChecked(false);
1639 }
1640 SetFtuStatusLed(d.time);
1641
1642#ifdef HAVE_ROOT
1643 Camera *cam = (Camera*)fRatesCanv->GetCanvas()->FindObject("Camera");
1644 for (int isw=0; isw<1440; isw++)
1645 {
1646 const int ihw = fPixelMapHW[isw];
1647 cam->SetEnable(isw, sdata.IsEnabled(ihw));
1648 }
1649
1650 fRatesCanv->GetCanvas()->Modified();
1651 fRatesCanv->GetCanvas()->Update();
1652#endif
1653
1654 {
1655 const int isw = fPixelIdx->value();
1656 const int ihw = fPixelMapHW[isw];
1657 const bool on = sdata.IsEnabled(ihw);
1658 fPixelEnable->setChecked(on);
1659 }
1660
1661 if (fThresholdIdx->value()>=0)
1662 {
1663 const int isw = fThresholdIdx->value();
1664 const int ihw = fPatchMapHW[isw];
1665 fThresholdVal->setValue(sdata.fThreshold[ihw]);
1666 }
1667
1668 fPrescalingVal->setValue(sdata.fPrescaling[0]);
1669
1670 fFtmStaticData = sdata;
1671 }
1672
1673 void handleFtmPassport(const DimData &d)
1674 {
1675 if (!CheckSize(d, sizeof(FTM::DimPassport)))
1676 return;
1677
1678 const FTM::DimPassport &sdata = d.ref<FTM::DimPassport>();
1679
1680 stringstream str1, str2;
1681 str1 << hex << "0x" << setfill('0') << setw(16) << sdata.fBoardId;
1682 str2 << sdata.fFirmwareId;
1683
1684 fFtmBoardId->setText(str1.str().c_str());
1685 fFtmFirmwareId->setText(str2.str().c_str());
1686 }
1687
1688 void handleFtmFtuList(const DimData &d)
1689 {
1690 if (!CheckSize(d, sizeof(FTM::DimFtuList)))
1691 return;
1692
1693 fFtuPing->setChecked(false);
1694
1695 const FTM::DimFtuList &sdata = d.ref<FTM::DimFtuList>();
1696
1697 stringstream str;
1698 str << "<table width='100%'>" << setfill('0');
1699 str << "<tr><th>Num</th><th></th><th>Addr</th><th></th><th>DNA</th></tr>";
1700 for (int i=0; i<40; i++)
1701 {
1702 str << "<tr>";
1703 str << "<td align='center'>" << dec << i << hex << "</td>";
1704 str << "<td align='center'>:</td>";
1705 str << "<td align='center'>0x" << setw(2) << (int)sdata.fAddr[i] << "</td>";
1706 str << "<td align='center'>:</td>";
1707 str << "<td align='center'>0x" << setw(16) << sdata.fDNA[i] << "</td>";
1708 str << "</tr>";
1709 }
1710 str << "</table>";
1711
1712 fFtuDNA->setText(str.str().c_str());
1713
1714 fFtuAnswersTotal->setValue(sdata.fNumBoards);
1715 fFtuAnswersCrate0->setValue(sdata.fNumBoardsCrate[0]);
1716 fFtuAnswersCrate1->setValue(sdata.fNumBoardsCrate[1]);
1717 fFtuAnswersCrate2->setValue(sdata.fNumBoardsCrate[2]);
1718 fFtuAnswersCrate3->setValue(sdata.fNumBoardsCrate[3]);
1719
1720 for (int i=0; i<40; i++)
1721 SetFtuLed(i, sdata.IsActive(i) ? sdata.fPing[i] : -1, d.time);
1722
1723 SetFtuStatusLed(d.time);
1724 }
1725
1726 void handleFtmError(const DimData &d)
1727 {
1728 if (!CheckSize(d, sizeof(FTM::DimError)))
1729 return;
1730
1731 const FTM::DimError &sdata = d.ref<FTM::DimError>();
1732
1733 SetFtuLed(sdata.fError.fDestAddress , sdata.fError.fNumCalls, d.time);
1734 SetFtuStatusLed(d.time);
1735
1736 // FIXME: Write to special window!
1737 //Out() << "Error:" << endl;
1738 //Out() << sdata.fError << endl;
1739 }
1740
1741 // ====================== MessageImp ====================================
1742
1743 bool fChatOnline;
1744
1745 void handleStateChanged(const Time &time, const std::string &server,
1746 const State &s)
1747 {
1748 // FIXME: Prefix tooltip with time
1749 if (server=="FTM_CONTROL")
1750 {
1751 // FIXME: Enable FTU page!!!
1752 fStatusFTMLabel->setText(s.name.c_str());
1753 fStatusFTMLabel->setToolTip(s.comment.c_str());
1754
1755 bool enable = false;
1756
1757 if (s.index<FTM::kDisconnected) // No Dim connection
1758 SetLedColor(fStatusFTMLed, kLedGray, time);
1759 if (s.index==FTM::kDisconnected) // Dim connection / FTM disconnected
1760 SetLedColor(fStatusFTMLed, kLedYellow, time);
1761 if (s.index==FTM::kConnected || s.index==FTM::kIdle || s.index==FTM::kTakingData) // Dim connection / FTM connected
1762 SetLedColor(fStatusFTMLed, kLedGreen, time);
1763
1764 if (s.index==FTM::kConnected || s.index==FTM::kIdle) // Dim connection / FTM connected
1765 enable = true;
1766
1767 fTriggerWidget->setEnabled(enable);
1768 fFtuWidget->setEnabled(enable);
1769 fRatesWidget->setEnabled(enable);
1770
1771 if (!enable)
1772 {
1773 SetLedColor(fStatusFTULed, kLedGray, time);
1774 fStatusFTULabel->setText("Offline");
1775 fStatusFTULabel->setToolTip("FTM is not online.");
1776 }
1777 }
1778
1779 if (server=="FAD_CONTROL")
1780 {
1781 fStatusFADLabel->setText(s.name.c_str());
1782 fStatusFADLabel->setToolTip(s.comment.c_str());
1783
1784 bool enable = false;
1785
1786 if (s.index<FAD::kOffline) // No Dim connection
1787 {
1788 SetLedColor(fStatusFADLed, kLedGray, time);
1789
1790 fStatusEventBuilderLabel->setText("Offline");
1791 fStatusEventBuilderLabel->setToolTip("No connection to fadctrl.");
1792 fEvtBldWidget->setEnabled(false);
1793
1794 SetLedColor(fStatusEventBuilderLed, kLedGray, time);
1795 }
1796 if (s.index==FAD::kOffline) // Dim connection / FTM disconnected
1797 SetLedColor(fStatusFADLed, kLedRed, time);
1798 if (s.index==FAD::kDisconnected) // Dim connection / FTM disconnected
1799 SetLedColor(fStatusFADLed, kLedOrange, time);
1800 if (s.index==FAD::kConnecting) // Dim connection / FTM disconnected
1801 {
1802 SetLedColor(fStatusFADLed, kLedYellow, time);
1803 // FIXME FIXME FIXME: The LEDs are not displayed when disabled!
1804 enable = true;
1805 }
1806 if (s.index>=FAD::kConnected) // Dim connection / FTM connected
1807 {
1808 SetLedColor(fStatusFADLed, kLedGreen, time);
1809 enable = true;
1810 }
1811
1812 fFadWidget->setEnabled(enable);
1813 }
1814
1815 if (server=="FSC_CONTROL")
1816 {
1817 fStatusFSCLabel->setText(s.name.c_str());
1818 fStatusFSCLabel->setToolTip(s.comment.c_str());
1819
1820 bool enable = false;
1821
1822 if (s.index<1) // No Dim connection
1823 SetLedColor(fStatusFSCLed, kLedGray, time);
1824 if (s.index==1) // Dim connection / FTM disconnected
1825 SetLedColor(fStatusFSCLed, kLedRed, time);
1826 if (s.index>=2) // Dim connection / FTM disconnected
1827 {
1828 SetLedColor(fStatusFSCLed, kLedGreen, time);
1829 enable = true;
1830 }
1831
1832 //fFscWidget->setEnabled(enable);
1833 }
1834
1835 if (server=="DATA_LOGGER")
1836 {
1837 fStatusLoggerLabel->setText(s.name.c_str());
1838 fStatusLoggerLabel->setToolTip(s.comment.c_str());
1839
1840 bool enable = true;
1841
1842 if (s.index<=30) // Ready/Waiting
1843 SetLedColor(fStatusLoggerLed, kLedYellow, time);
1844 if (s.index<-1) // Offline
1845 {
1846 SetLedColor(fStatusLoggerLed, kLedGray, time);
1847 enable = false;
1848 }
1849 if (s.index>=0x100) // Error
1850 SetLedColor(fStatusLoggerLed, kLedRed, time);
1851 if (s.index==40) // Logging
1852 SetLedColor(fStatusLoggerLed, kLedGreen, time);
1853
1854 fLoggerWidget->setEnabled(enable);
1855 }
1856
1857 if (server=="CHAT")
1858 {
1859 fStatusChatLabel->setText(s.name.c_str());
1860
1861 fChatOnline = s.index==0;
1862
1863 SetLedColor(fStatusChatLed, fChatOnline ? kLedGreen : kLedGray, time);
1864
1865 fChatSend->setEnabled(fChatOnline);
1866 fChatMessage->setEnabled(fChatOnline);
1867 }
1868
1869 if (server=="SCHEDULER")
1870 {
1871 fStatusSchedulerLabel->setText(s.name.c_str());
1872
1873 SetLedColor(fStatusSchedulerLed, s.index>=0 ? kLedGreen : kLedRed, time);
1874 }
1875 }
1876
1877 void handleStateOffline(const string &server)
1878 {
1879 handleStateChanged(Time(), server, State(-2, "Offline", "No connection via DIM."));
1880 }
1881
1882 void on_fTabWidget_currentChanged(int which)
1883 {
1884 if (fTabWidget->tabText(which)=="Chat")
1885 fTabWidget->setTabIcon(which, QIcon());
1886 }
1887
1888 void handleWrite(const Time &time, const string &text, int qos)
1889 {
1890 stringstream out;
1891
1892 if (text.substr(0, 6)=="CHAT: ")
1893 {
1894 if (qos==MessageImp::kDebug)
1895 return;
1896
1897 out << "<font size='-1' color='navy'>[<B>";
1898 out << Time::fmt("%H:%M:%S") << time << "</B>]</FONT> ";
1899 out << text.substr(6);
1900 fChatText->append(out.str().c_str());
1901
1902 if (fTabWidget->tabText(fTabWidget->currentIndex())=="Chat")
1903 return;
1904
1905 static int num = 0;
1906 if (num++<2)
1907 return;
1908
1909 for (int i=0; i<fTabWidget->count(); i++)
1910 if (fTabWidget->tabText(i)=="Chat")
1911 {
1912 fTabWidget->setTabIcon(i, QIcon(":/Resources/icons/warning 3.png"));
1913 break;
1914 }
1915
1916 return;
1917 }
1918
1919
1920 out << "<font style='font-family:monospace' color='";
1921
1922 switch (qos)
1923 {
1924 case kMessage: out << "black"; break;
1925 case kInfo: out << "green"; break;
1926 case kWarn: out << "#FF6600"; break;
1927 case kError: out << "maroon"; break;
1928 case kFatal: out << "maroon"; break;
1929 case kDebug: out << "navy"; break;
1930 default: out << "navy"; break;
1931 }
1932 out << "'>" << time.GetAsStr() << " - " << text << "</font>";
1933
1934 fLogText->append(out.str().c_str());
1935
1936 if (qos>=kWarn)
1937 fTextEdit->append(out.str().c_str());
1938 }
1939
1940 void IndicateStateChange(const Time &time, const std::string &server)
1941 {
1942 const State s = GetState(server, GetCurrentState(server));
1943
1944 QApplication::postEvent(this,
1945 new FunctionEvent(boost::bind(&FactGui::handleStateChanged, this, time, server, s)));
1946 }
1947
1948 int Write(const Time &time, const string &txt, int qos)
1949 {
1950 QApplication::postEvent(this,
1951 new FunctionEvent(boost::bind(&FactGui::handleWrite, this, time, txt, qos)));
1952
1953 return 0;
1954 }
1955
1956 // ====================== Dim infoHandler================================
1957
1958 void handleDimService(const string &txt)
1959 {
1960 fDimSvcText->append(txt.c_str());
1961 }
1962
1963 void infoHandlerService(DimInfo &info)
1964 {
1965 const string fmt = string(info.getFormat()).empty() ? "C" : info.getFormat();
1966
1967 stringstream dummy;
1968 const Converter conv(dummy, fmt, false);
1969
1970 const Time tm(info.getTimestamp(), info.getTimestampMillisecs()*1000);
1971
1972 stringstream out;
1973 out << "<font size'-1' color='navy'>[" << Time::fmt("%H:%M:%S.%f") << tm << "]</font> <B>" << info.getName() << "</B> - ";
1974
1975 bool iserr = true;
1976 if (!conv)
1977 {
1978 out << "Compilation of format string '" << fmt << "' failed!";
1979 }
1980 else
1981 {
1982 try
1983 {
1984 const string dat = conv.GetString(info.getData(), info.getSize());
1985 out << dat;
1986 iserr = false;
1987 }
1988 catch (const runtime_error &e)
1989 {
1990 out << "Conversion to string failed!<pre>" << e.what() << "</pre>";
1991 }
1992 }
1993
1994 // srand(hash<string>()(string(info.getName())));
1995 // int bg = rand()&0xffffff;
1996
1997 int bg = hash<string>()(string(info.getName()));
1998
1999 // allow only light colors
2000 bg = ~(bg&0x1f1f1f)&0xffffff;
2001
2002 if (iserr)
2003 bg = 0xffffff;
2004
2005 stringstream bgcol;
2006 bgcol << hex << setfill('0') << setw(6) << bg;
2007
2008 const string col = iserr ? "red" : "black";
2009 const string str = "<table width='100%' bgcolor=#"+bgcol.str()+"><tr><td><font color='"+col+"'>"+out.str()+"</font></td></tr></table>";
2010
2011 QApplication::postEvent(this,
2012 new FunctionEvent(boost::bind(&FactGui::handleDimService, this, str)));
2013 }
2014
2015 void CallInfoHandler(void (FactGui::*handler)(const DimData&), const DimData &d)
2016 {
2017 fInHandler = true;
2018 (this->*handler)(d);
2019 fInHandler = false;
2020 }
2021
2022 /*
2023 void CallInfoHandler(const boost::function<void()> &func)
2024 {
2025 // This ensures that newly received values are not sent back to the emitter
2026 // because changing the value emits the valueChanged signal (or similar)
2027 fInHandler = true;
2028 func();
2029 fInHandler = false;
2030 }*/
2031
2032 void PostInfoHandler(void (FactGui::*handler)(const DimData&))
2033 {
2034 //const boost::function<void()> f = boost::bind(handler, this, DimData(getInfo()));
2035
2036 FunctionEvent *evt = new FunctionEvent(boost::bind(&FactGui::CallInfoHandler, this, handler, DimData(getInfo())));
2037 // FunctionEvent *evt = new FunctionEvent(boost::bind(&FactGui::CallInfoHandler, this, f));
2038 // FunctionEvent *evt = new FunctionEvent(boost::bind(handler, this, DimData(getInfo()))));
2039
2040 QApplication::postEvent(this, evt);
2041 }
2042
2043 void infoHandler()
2044 {
2045 // Initialize the time-stamp (what a weird workaround...)
2046 if (getInfo())
2047 getInfo()->getTimestamp();
2048
2049 if (getInfo()==&fDimDNS)
2050 return PostInfoHandler(&FactGui::handleDimDNS);
2051#ifdef DEBUG_DIM
2052 cout << "HandleDimInfo " << getInfo()->getName() << endl;
2053#endif
2054 if (getInfo()==&fDimLoggerStats)
2055 return PostInfoHandler(&FactGui::handleLoggerStats);
2056
2057// if (getInfo()==&fDimFadFiles)
2058// return PostInfoHandler(&FactGui::handleFadFiles);
2059
2060 if (getInfo()==&fDimFadConnections)
2061 return PostInfoHandler(&FactGui::handleFadConnections);
2062
2063 if (getInfo()==&fDimFadFwVersion)
2064 return PostInfoHandler(&FactGui::handleFadFwVersion);
2065
2066 if (getInfo()==&fDimFadRunNumber)
2067 return PostInfoHandler(&FactGui::handleFadRunNumber);
2068
2069 if (getInfo()==&fDimFadDNA)
2070 return PostInfoHandler(&FactGui::handleFadDNA);
2071
2072 if (getInfo()==&fDimFadTemperature)
2073 return PostInfoHandler(&FactGui::handleFadTemperature);
2074
2075 if (getInfo()==&fDimFadStatus)
2076 return PostInfoHandler(&FactGui::handleFadStatus);
2077
2078 if (getInfo()==&fDimFadStatistics)
2079 return PostInfoHandler(&FactGui::handleFadStatistics);
2080
2081 if (getInfo()==&fDimFadEvents)
2082 return PostInfoHandler(&FactGui::handleFadEvents);
2083
2084 if (getInfo()==&fDimFadRuns)
2085 return PostInfoHandler(&FactGui::handleFadRuns);
2086
2087 if (getInfo()==&fDimFadEventData)
2088 return PostInfoHandler(&FactGui::handleFadEventData);
2089
2090/*
2091 if (getInfo()==&fDimFadSetup)
2092 return PostInfoHandler(&FactGui::handleFadSetup);
2093*/
2094 if (getInfo()==&fDimLoggerFilenameNight)
2095 return PostInfoHandler(&FactGui::handleLoggerFilenameNight);
2096
2097 if (getInfo()==&fDimLoggerNumSubs)
2098 return PostInfoHandler(&FactGui::handleLoggerNumSubs);
2099
2100 if (getInfo()==&fDimLoggerFilenameRun)
2101 return PostInfoHandler(&FactGui::handleLoggerFilenameRun);
2102
2103 if (getInfo()==&fDimFtmTriggerCounter)
2104 return PostInfoHandler(&FactGui::handleFtmTriggerCounter);
2105
2106 if (getInfo()==&fDimFtmCounter)
2107 return PostInfoHandler(&FactGui::handleFtmCounter);
2108
2109 if (getInfo()==&fDimFtmDynamicData)
2110 return PostInfoHandler(&FactGui::handleFtmDynamicData);
2111
2112 if (getInfo()==&fDimFtmPassport)
2113 return PostInfoHandler(&FactGui::handleFtmPassport);
2114
2115 if (getInfo()==&fDimFtmFtuList)
2116 return PostInfoHandler(&FactGui::handleFtmFtuList);
2117
2118 if (getInfo()==&fDimFtmStaticData)
2119 return PostInfoHandler(&FactGui::handleFtmStaticData);
2120
2121 if (getInfo()==&fDimFtmError)
2122 return PostInfoHandler(&FactGui::handleFtmError);
2123
2124// if (getInfo()==&fDimFadFiles)
2125// return PostInfoHandler(&FactGui::handleFadFiles);
2126
2127 for (map<string,DimInfo*>::iterator i=fServices.begin(); i!=fServices.end(); i++)
2128 if (i->second==getInfo())
2129 {
2130 infoHandlerService(*i->second);
2131 return;
2132 }
2133
2134 DimNetwork::infoHandler();
2135 }
2136
2137
2138 // ======================================================================
2139
2140 bool event(QEvent *evt)
2141 {
2142 if (dynamic_cast<FunctionEvent*>(evt))
2143 return static_cast<FunctionEvent*>(evt)->Exec();
2144
2145 if (dynamic_cast<CheckBoxEvent*>(evt))
2146 {
2147 const QStandardItem &item = static_cast<CheckBoxEvent*>(evt)->item;
2148 const QStandardItem *par = item.parent();
2149 if (par)
2150 {
2151 const QString server = par->text();
2152 const QString service = item.text();
2153
2154 const string s = (server+'/'+service).toStdString();
2155
2156 if (item.checkState()==Qt::Checked)
2157 SubscribeService(s);
2158 else
2159 UnsubscribeService(s);
2160 }
2161 }
2162
2163 return MainWindow::event(evt); // unrecognized
2164 }
2165
2166 void on_fDimCmdSend_clicked()
2167 {
2168 const QString server = fDimCmdServers->currentIndex().data().toString();
2169 const QString command = fDimCmdCommands->currentIndex().data().toString();
2170 const QString arguments = fDimCmdLineEdit->displayText();
2171
2172 // FIXME: Sending a command exactly when the info Handler changes
2173 // the list it might lead to confusion.
2174 try
2175 {
2176 SendDimCommand(server.toStdString(), command.toStdString()+" "+arguments.toStdString());
2177 fTextEdit->append("<font color='green'>Command '"+server+'/'+command+"' successfully emitted.</font>");
2178 fDimCmdLineEdit->clear();
2179 }
2180 catch (const runtime_error &e)
2181 {
2182 stringstream txt;
2183 txt << e.what();
2184
2185 string buffer;
2186 while (getline(txt, buffer, '\n'))
2187 fTextEdit->append(("<font color='red'><pre>"+buffer+"</pre></font>").c_str());
2188 }
2189 }
2190
2191#ifdef HAVE_ROOT
2192 void slot_RootEventProcessed(TObject *obj, unsigned int evt, TCanvas *canv)
2193 {
2194 // kMousePressEvent // TCanvas processed QEvent mousePressEvent
2195 // kMouseMoveEvent // TCanvas processed QEvent mouseMoveEvent
2196 // kMouseReleaseEvent // TCanvas processed QEvent mouseReleaseEvent
2197 // kMouseDoubleClickEvent // TCanvas processed QEvent mouseDoubleClickEvent
2198 // kKeyPressEvent // TCanvas processed QEvent keyPressEvent
2199 // kEnterEvent // TCanvas processed QEvent enterEvent
2200 // kLeaveEvent // TCanvas processed QEvent leaveEvent
2201 if (dynamic_cast<TCanvas*>(obj))
2202 return;
2203
2204 TQtWidget *tipped = static_cast<TQtWidget*>(sender());
2205
2206 if (evt==11/*kMouseReleaseEvent*/)
2207 {
2208 if (dynamic_cast<Camera*>(obj))
2209 {
2210 const float xx = canv->AbsPixeltoX(tipped->GetEventX());
2211 const float yy = canv->AbsPixeltoY(tipped->GetEventY());
2212
2213 Camera *cam = static_cast<Camera*>(obj);
2214 const int isw = cam->GetIdx(xx, yy);
2215
2216 fPixelIdx->setValue(isw);
2217 ChoosePixel(*cam, isw);
2218 }
2219 return;
2220 }
2221
2222 if (evt==61/*kMouseDoubleClickEvent*/)
2223 {
2224 if (dynamic_cast<Camera*>(obj))
2225 {
2226 const float xx = canv->AbsPixeltoX(tipped->GetEventX());
2227 const float yy = canv->AbsPixeltoY(tipped->GetEventY());
2228
2229 Camera *cam = static_cast<Camera*>(obj);
2230 const int isw = cam->GetIdx(xx, yy);
2231
2232 ChoosePixel(*cam, isw);
2233
2234 fPixelIdx->setValue(isw);
2235
2236 const uint16_t ihw = fPixelMapHW[isw];
2237
2238 Dim::SendCommand("FTM_CONTROL/TOGGLE_PIXEL", ihw);
2239 }
2240
2241 if (dynamic_cast<TAxis*>(obj))
2242 static_cast<TAxis*>(obj)->UnZoom();
2243
2244 return;
2245 }
2246
2247 // Find the object which will get picked by the GetObjectInfo
2248 // due to buffer overflows in many root-versions
2249 // in TH1 and TProfile we have to work around and implement
2250 // our own GetObjectInfo which make everything a bit more
2251 // complicated.
2252 canv->cd();
2253#if ROOT_VERSION_CODE > ROOT_VERSION(5,22,00)
2254 const char *objectInfo =
2255 obj->GetObjectInfo(tipped->GetEventX(),tipped->GetEventY());
2256#else
2257 const char *objectInfo = dynamic_cast<TH1*>(obj) ?
2258 "" : obj->GetObjectInfo(tipped->GetEventX(),tipped->GetEventY());
2259#endif
2260
2261 QString tipText;
2262 tipText += obj->GetName();
2263 tipText += " [";
2264 tipText += obj->ClassName();
2265 tipText += "]: ";
2266 tipText += objectInfo;
2267
2268 if (dynamic_cast<Camera*>(obj))
2269 {
2270 const float xx = canv->AbsPixeltoX(tipped->GetEventX());
2271 const float yy = canv->AbsPixeltoY(tipped->GetEventY());
2272
2273 Camera *cam = static_cast<Camera*>(obj);
2274
2275 const int isw = cam->GetIdx(xx, yy);
2276 const int ihw = fPixelMapHW[isw];
2277
2278 const int idx = fPatchHW[isw];
2279
2280 int ii = 0;
2281 for (; ii<160; ii++)
2282 if (idx==fPatchMapHW[ii])
2283 break;
2284
2285
2286 const int patch = ihw%4;
2287 const int board = (ihw/4)%10;
2288 const int crate = (ihw/4)/10;
2289
2290 ostringstream str;
2291 str << " (hw=" << ihw << ") Patch=" << ii << " (hw=" << fPatchMapHW[idx] << "; Crate=" << crate << " Board=" << board << " Patch=" << patch << ")";
2292
2293 tipText += str.str().c_str();
2294 }
2295
2296
2297 fStatusBar->showMessage(tipText, 3000);
2298
2299 gSystem->ProcessEvents();
2300 //QWhatsThis::display(tipText)
2301 }
2302
2303 void slot_RootUpdate()
2304 {
2305 gSystem->ProcessEvents();
2306 QTimer::singleShot(0, this, SLOT(slot_RootUpdate()));
2307 }
2308
2309 void ChoosePatch(Camera &cam, int isw)
2310 {
2311 cam.Reset();
2312
2313 fThresholdIdx->setValue(isw);
2314
2315 const int ihw = isw<0 ? 0 : fPatchMapHW[isw];
2316
2317 fPatchRate->setEnabled(isw>=0);
2318 fThresholdCrate->setEnabled(isw>=0);
2319 fThresholdBoard->setEnabled(isw>=0);
2320 fThresholdPatch->setEnabled(isw>=0);
2321
2322 if (isw<0)
2323 return;
2324
2325 const int patch = ihw%4;
2326 const int board = (ihw/4)%10;
2327 const int crate = (ihw/4)/10;
2328
2329 fInChoosePatch = true;
2330
2331 fThresholdCrate->setValue(crate);
2332 fThresholdBoard->setValue(board);
2333 fThresholdPatch->setValue(patch);
2334
2335 fInChoosePatch = false;
2336
2337 fThresholdVal->setValue(fFtmStaticData.fThreshold[ihw]);
2338 fPatchRate->setValue(cam.GetData(isw));
2339
2340 // Loop over the software idx of all pixels
2341 for (unsigned int i=0; i<1440; i++)
2342 if (fPatchHW[i]==ihw)
2343 cam.SetBold(i);
2344 }
2345
2346 void ChoosePixel(Camera &cam, int isw)
2347 {
2348 const int ihw = fPixelMapHW[isw];
2349
2350 int ii = 0;
2351 for (; ii<160; ii++)
2352 if (fPatchHW[isw]==fPatchMapHW[ii])
2353 break;
2354
2355 cam.SetWhite(isw);
2356 ChoosePatch(cam, ii);
2357
2358 const bool on = fFtmStaticData.IsEnabled(ihw);
2359 fPixelEnable->setChecked(on);
2360 }
2361
2362 void UpdatePatch(int isw)
2363 {
2364 Camera *cam = (Camera*)fRatesCanv->GetCanvas()->FindObject("Camera");
2365 ChoosePatch(*cam, isw);
2366 }
2367
2368 void on_fThresholdIdx_valueChanged(int isw)
2369 {
2370 UpdatePatch(isw);
2371
2372 fRatesCanv->GetCanvas()->Modified();
2373 fRatesCanv->GetCanvas()->Update();
2374 }
2375
2376 void UpdateThresholdIdx()
2377 {
2378 if (fInChoosePatch)
2379 return;
2380
2381 const int crate = fThresholdCrate->value();
2382 const int board = fThresholdBoard->value();
2383 const int patch = fThresholdPatch->value();
2384
2385 const int ihw = patch + board*4 + crate*40;
2386
2387 int isw = 0;
2388 for (; isw<160; isw++)
2389 if (ihw==fPatchMapHW[isw])
2390 break;
2391
2392 UpdatePatch(isw);
2393 }
2394
2395 void on_fThresholdPatch_valueChanged(int)
2396 {
2397 UpdateThresholdIdx();
2398 }
2399 void on_fThresholdBoard_valueChanged(int)
2400 {
2401 UpdateThresholdIdx();
2402 }
2403 void on_fThresholdCrate_valueChanged(int)
2404 {
2405 UpdateThresholdIdx();
2406 }
2407
2408 void on_fPixelIdx_valueChanged(int isw)
2409 {
2410 Camera *cam = (Camera*)fRatesCanv->GetCanvas()->FindObject("Camera");
2411 ChoosePixel(*cam, isw);
2412
2413 fRatesCanv->GetCanvas()->Modified();
2414 fRatesCanv->GetCanvas()->Update();
2415 }
2416#endif
2417
2418 void on_fPixelEnable_stateChanged(int b)
2419 {
2420 if (fInHandler)
2421 return;
2422
2423 const uint16_t isw = fPixelIdx->value();
2424 const uint16_t ihw = fPixelMapHW[isw];
2425
2426 Dim::SendCommand(b==Qt::Unchecked ?
2427 "FTM_CONTROL/DISABLE_PIXEL" : "FTM_CONTROL/ENABLE_PIXEL",
2428 ihw);
2429 }
2430
2431 void on_fPixelDisableOthers_clicked()
2432 {
2433 const uint16_t isw = fPixelIdx->value();
2434 const uint16_t ihw = fPixelMapHW[isw];
2435
2436 Dim::SendCommand("FTM_CONTROL/DISABLE_ALL_PIXELS_EXCEPT", ihw);
2437 }
2438
2439 void on_fThresholdDisableOthers_clicked()
2440 {
2441 const uint16_t isw = fThresholdIdx->value();
2442 const uint16_t ihw = fPatchMapHW[isw];
2443
2444 Dim::SendCommand("FTM_CONTROL/DISABLE_ALL_PATCHES_EXCEPT", ihw);
2445 }
2446
2447 void on_fThresholdVal_valueChanged(int v)
2448 {
2449 fThresholdVolt->setValue(2500./4095*v);
2450
2451 const int32_t isw = fThresholdIdx->value();
2452 const int32_t ihw = fPatchMapHW[isw];
2453
2454 const int32_t d[2] = { ihw, v };
2455
2456 if (!fInHandler)
2457 Dim::SendCommand("FTM_CONTROL/SET_THRESHOLD", d);
2458 }
2459
2460 TGraph fGraphFtmTemp[4];
2461 TGraph fGraphFtmRate;
2462 TGraph fGraphPatchRate[160];
2463 TGraph fGraphBoardRate[40];
2464
2465#ifdef HAVE_ROOT
2466 void DrawTimeFrame(const char *ytitle)
2467 {
2468 const double tm = Time().RootTime();
2469
2470 TH1F h("TimeFrame", "", 1, tm, tm+60);//Time().RootTime()-1./24/60/60, Time().RootTime());
2471 h.SetDirectory(0);
2472// h.SetBit(TH1::kCanRebin);
2473 h.SetStats(kFALSE);
2474// h.SetMinimum(0);
2475// h.SetMaximum(1);
2476 h.SetXTitle("Time");
2477 h.SetYTitle(ytitle);
2478 h.GetXaxis()->CenterTitle();
2479 h.GetYaxis()->CenterTitle();
2480 h.GetXaxis()->SetTimeDisplay(true);
2481 h.GetXaxis()->SetTimeFormat("%Mh%S'");
2482 h.GetXaxis()->SetLabelSize(0.025);
2483 h.GetYaxis()->SetLabelSize(0.025);
2484 h.GetYaxis()->SetTitleOffset(1.2);
2485// h.GetYaxis()->SetTitleSize(1.2);
2486 h.DrawCopy()->SetDirectory(0);
2487 }
2488#endif
2489
2490public:
2491 FactGui() :
2492 fFtuStatus(40),
2493 fPixelMapHW(1440), fPatchMapHW(160), fPatchHW(1440),
2494 fInChoosePatch(false),
2495 fDimDNS("DIS_DNS/VERSION_NUMBER", 1, int(0), this),
2496 //-
2497 fDimLoggerStats ("DATA_LOGGER/STATS", (void*)NULL, 0, this),
2498 fDimLoggerFilenameNight("DATA_LOGGER/FILENAME_NIGHTLY", (void*)NULL, 0, this),
2499 fDimLoggerFilenameRun ("DATA_LOGGER/FILENAME_RUN", (void*)NULL, 0, this),
2500 fDimLoggerNumSubs ("DATA_LOGGER/NUM_SUBS", (void*)NULL, 0, this),
2501 //-
2502 fDimFtmPassport ("FTM_CONTROL/PASSPORT", (void*)NULL, 0, this),
2503 fDimFtmTriggerCounter ("FTM_CONTROL/TRIGGER_COUNTER", (void*)NULL, 0, this),
2504 fDimFtmError ("FTM_CONTROL/ERROR", (void*)NULL, 0, this),
2505 fDimFtmFtuList ("FTM_CONTROL/FTU_LIST", (void*)NULL, 0, this),
2506 fDimFtmStaticData ("FTM_CONTROL/STATIC_DATA", (void*)NULL, 0, this),
2507 fDimFtmDynamicData ("FTM_CONTROL/DYNAMIC_DATA", (void*)NULL, 0, this),
2508 fDimFtmCounter ("FTM_CONTROL/COUNTER", (void*)NULL, 0, this),
2509 //-
2510 fDimFadRuns ("FAD_CONTROL/RUNS", (void*)NULL, 0, this),
2511 fDimFadEvents ("FAD_CONTROL/EVENTS", (void*)NULL, 0, this),
2512 fDimFadEventData ("FAD_CONTROL/EVENT_DATA", (void*)NULL, 0, this),
2513 fDimFadConnections ("FAD_CONTROL/CONNECTIONS", (void*)NULL, 0, this),
2514 fDimFadFwVersion ("FAD_CONTROL/FIRMWARE_VERSION", (void*)NULL, 0, this),
2515 fDimFadRunNumber ("FAD_CONTROL/RUN_NUMBER", (void*)NULL, 0, this),
2516 fDimFadDNA ("FAD_CONTROL/DNA", (void*)NULL, 0, this),
2517 fDimFadTemperature ("FAD_CONTROL/TEMPERATURE", (void*)NULL, 0, this),
2518 fDimFadStatus ("FAD_CONTROL/STATUS", (void*)NULL, 0, this),
2519 fDimFadStatistics ("FAD_CONTROL/STATISTICS", (void*)NULL, 0, this)
2520 {
2521 fClockCondFreq->addItem("--- Hz", QVariant(-1));
2522 fClockCondFreq->addItem("800 MHz", QVariant(800));
2523 fClockCondFreq->addItem("1 GHz", QVariant(1000));
2524 fClockCondFreq->addItem("2 GHz", QVariant(2000));
2525 fClockCondFreq->addItem("3 GHz", QVariant(3000));
2526 fClockCondFreq->addItem("4 GHz", QVariant(4000));
2527 fClockCondFreq->addItem("5 GHz", QVariant(5000));
2528
2529 fTriggerWidget->setEnabled(false);
2530 fFtuWidget->setEnabled(false);
2531 fRatesWidget->setEnabled(false);
2532// fFadWidget->setEnabled(false);
2533 fLoggerWidget->setEnabled(false);
2534
2535 fChatSend->setEnabled(false);
2536 fChatMessage->setEnabled(false);
2537
2538 DimClient::sendCommand("CHAT/MSG", "GUI online.");
2539 // + MessageDimRX
2540
2541 // --------------------------------------------------------------------------
2542
2543 ifstream fin1("Trigger-Patches.txt");
2544
2545 int l = 0;
2546
2547 string buf;
2548 while (getline(fin1, buf, '\n'))
2549 {
2550 buf = Tools::Trim(buf);
2551 if (buf[0]=='#')
2552 continue;
2553
2554 stringstream str(buf);
2555 for (int i=0; i<9; i++)
2556 {
2557 unsigned int n;
2558 str >> n;
2559
2560 if (n>=fPatchHW.size())
2561 continue;
2562
2563 fPatchHW[n] = l;
2564 }
2565 l++;
2566 }
2567
2568 if (l!=160)
2569 cerr << "WARNING - Problems reading Trigger-Patches.txt" << endl;
2570
2571 // --------------------------------------------------------------------------
2572
2573 ifstream fin2("MasterList-v3.txt");
2574
2575 l = 0;
2576
2577 while (getline(fin2, buf, '\n'))
2578 {
2579 buf = Tools::Trim(buf);
2580 if (buf[0]=='#')
2581 continue;
2582
2583 unsigned int softid, hardid, dummy;
2584
2585 stringstream str(buf);
2586
2587 str >> softid;
2588 str >> dummy;
2589 str >> hardid;
2590
2591 if (softid>=fPixelMapHW.size())
2592 continue;
2593
2594 fPixelMapHW[softid] = hardid;
2595
2596 l++;
2597 }
2598
2599 if (l!=1440)
2600 cerr << "WARNING - Problems reading MasterList-v3.txt" << endl;
2601
2602 // --------------------------------------------------------------------------
2603
2604 ifstream fin3("PatchList.txt");
2605
2606 l = 0;
2607
2608 while (getline(fin3, buf, '\n'))
2609 {
2610 buf = Tools::Trim(buf);
2611 if (buf[0]=='#')
2612 continue;
2613
2614 unsigned int softid, hardid;
2615
2616 stringstream str(buf);
2617
2618 str >> softid;
2619 str >> hardid;
2620
2621 if (softid>=fPatchMapHW.size())
2622 continue;
2623
2624 fPatchMapHW[softid] = hardid-1;
2625
2626 l++;
2627 }
2628
2629 if (l!=160)
2630 cerr << "WARNING - Problems reading PatchList.txt" << endl;
2631
2632 // --------------------------------------------------------------------------
2633#ifdef HAVE_ROOT
2634
2635 fGraphFtmRate.SetLineColor(kBlue);
2636 fGraphFtmRate.SetMarkerColor(kBlue);
2637 fGraphFtmRate.SetMarkerStyle(kFullDotMedium);
2638
2639 for (int i=0; i<160; i++)
2640 {
2641 fGraphPatchRate[i].SetName("PatchRate");
2642 //fGraphPatchRate[i].SetLineColor(kBlue);
2643 //fGraphPatchRate[i].SetMarkerColor(kBlue);
2644 fGraphPatchRate[i].SetMarkerStyle(kFullDotMedium);
2645 }
2646 for (int i=0; i<40; i++)
2647 {
2648 fGraphBoardRate[i].SetName("BoardRate");
2649 //fGraphBoardRate[i].SetLineColor(kBlue);
2650 //fGraphBoardRate[i].SetMarkerColor(kBlue);
2651 fGraphBoardRate[i].SetMarkerStyle(kFullDotMedium);
2652 }
2653 /*
2654 TCanvas *c = fFtmTempCanv->GetCanvas();
2655 c->SetBit(TCanvas::kNoContextMenu);
2656 c->SetBorderMode(0);
2657 c->SetFrameBorderMode(0);
2658 c->SetFillColor(kWhite);
2659 c->SetRightMargin(0.03);
2660 c->SetTopMargin(0.03);
2661 c->cd();
2662 */
2663 //CreateTimeFrame("Temperature / °C");
2664
2665 fGraphFtmTemp[0].SetMarkerStyle(kFullDotSmall);
2666 fGraphFtmTemp[1].SetMarkerStyle(kFullDotSmall);
2667 fGraphFtmTemp[2].SetMarkerStyle(kFullDotSmall);
2668 fGraphFtmTemp[3].SetMarkerStyle(kFullDotSmall);
2669
2670 fGraphFtmTemp[1].SetLineColor(kBlue);
2671 fGraphFtmTemp[2].SetLineColor(kRed);
2672 fGraphFtmTemp[3].SetLineColor(kGreen);
2673
2674 fGraphFtmTemp[1].SetMarkerColor(kBlue);
2675 fGraphFtmTemp[2].SetMarkerColor(kRed);
2676 fGraphFtmTemp[3].SetMarkerColor(kGreen);
2677
2678 //fGraphFtmTemp[0].Draw("LP");
2679 //fGraphFtmTemp[1].Draw("LP");
2680 //fGraphFtmTemp[2].Draw("LP");
2681 //fGraphFtmTemp[3].Draw("LP");
2682
2683 // --------------------------------------------------------------------------
2684
2685 TCanvas *c = fFtmRateCanv->GetCanvas();
2686 //c->SetBit(TCanvas::kNoContextMenu);
2687 c->SetBorderMode(0);
2688 c->SetFrameBorderMode(0);
2689 c->SetFillColor(kWhite);
2690 c->SetRightMargin(0.03);
2691 c->SetTopMargin(0.03);
2692 c->SetGrid();
2693 c->cd();
2694
2695 DrawTimeFrame("Trigger rate [Hz]");
2696
2697 fTriggerCounter0 = -1;
2698
2699 fGraphFtmRate.SetMarkerStyle(kFullDotSmall);
2700 fGraphFtmRate.Draw("LP");
2701
2702 // --------------------------------------------------------------------------
2703
2704 c = fRatesCanv->GetCanvas();
2705 //c->SetBit(TCanvas::kNoContextMenu);
2706 c->SetBorderMode(0);
2707 c->SetFrameBorderMode(0);
2708 c->SetFillColor(kWhite);
2709 c->cd();
2710
2711 Camera *cam = new Camera;
2712 cam->SetBit(kCanDelete);
2713 cam->Draw();
2714
2715 ChoosePixel(*cam, 0);
2716
2717 // --------------------------------------------------------------------------
2718
2719 c = fAdcDataCanv->GetCanvas();
2720 c->SetBit(TCanvas::kNoContextMenu);
2721 c->SetBorderMode(0);
2722 c->SetFrameBorderMode(0);
2723 c->SetFillColor(kWhite);
2724 c->SetGrid();
2725 c->cd();
2726
2727 // Create histogram?
2728
2729 // --------------------------------------------------------------------------
2730
2731// QTimer::singleShot(0, this, SLOT(slot_RootUpdate()));
2732
2733 //widget->setMouseTracking(true);
2734 //widget->EnableSignalEvents(kMouseMoveEvent);
2735
2736 fFtmRateCanv->setMouseTracking(true);
2737 fFtmRateCanv->EnableSignalEvents(kMouseMoveEvent);
2738
2739 fAdcDataCanv->setMouseTracking(true);
2740 fAdcDataCanv->EnableSignalEvents(kMouseMoveEvent);
2741
2742 fRatesCanv->setMouseTracking(true);
2743 fRatesCanv->EnableSignalEvents(kMouseMoveEvent|kMouseReleaseEvent|kMouseDoubleClickEvent);
2744
2745 connect(fRatesCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)),
2746 this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*)));
2747 connect(fFtmRateCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)),
2748 this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*)));
2749 connect(fAdcDataCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)),
2750 this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*)));
2751#endif
2752 }
2753
2754 ~FactGui()
2755 {
2756 UnsubscribeAllServers();
2757 }
2758};
2759
2760#endif
Note: See TracBrowser for help on using the repository browser.