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

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