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

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