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

Last change on this file since 11547 was 11547, checked in by tbretz, 13 years ago
Added new members to GUI_STAT
File size: 92.0 KB
Line 
1#ifndef FACT_FactGui
2#define FACT_FactGui
3
4#include "MainWindow.h"
5
6#include <iomanip>
7#include <valarray>
8
9#include <boost/bind.hpp>
10
11#include <QTimer>
12#include <QStandardItemModel>
13
14#include "CheckBoxDelegate.h"
15
16#include "src/Dim.h"
17#include "src/Converter.h"
18#include "src/HeadersFTM.h"
19#include "src/HeadersFAD.h"
20#include "src/DimNetwork.h"
21#include "src/tools.h"
22#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[41]);
1041
1042 handleFadToolTip(d.time, fFadTempMin, ptr+1);
1043 handleFadToolTip(d.time, fFadTempMax, ptr+42);
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 EVENT *fEventData;
1075
1076 void DisplayEventData()
1077 {
1078#ifdef HAVE_ROOT
1079 TCanvas *c = fAdcDataCanv->GetCanvas();
1080
1081 TH1 *h = dynamic_cast<TH1*>(c->FindObject("EventData"));
1082 if (h && h->GetNbinsX()!=fEventData->Roi)
1083 {
1084 delete h;
1085 h = 0;
1086 }
1087
1088 if (!h)
1089 {
1090 c->cd();
1091
1092 const int roi = fEventData->Roi>0 ? fEventData->Roi : 1;
1093
1094 TH1D hist("EventData", "", roi, -0.5, roi-0.5);
1095 hist.SetStats(kFALSE);
1096 //hist->SetBit(TH1::kNoTitle);
1097 hist.SetMarkerStyle(kFullDotMedium);
1098 hist.SetMarkerColor(kBlue);
1099 hist.SetYTitle("Voltage [mV]");
1100 hist.GetXaxis()->CenterTitle();
1101 hist.GetYaxis()->CenterTitle();
1102 hist.SetMinimum(-1026);
1103 hist.SetMaximum(1025);
1104 h = hist.DrawCopy("PL");
1105 h->SetDirectory(0);
1106 }
1107
1108 const uint32_t p = fAdcChannel->value()+fAdcBoard->value()*36+fAdcCrate->value()*360;
1109
1110 ostringstream str;
1111 str << "Event ID = " << fEventData->EventNum;
1112 str << " Trigger type = " << fEventData->TriggerType;
1113 str << " Board time[0] = " << fEventData->BoardTime[fAdcBoard->value()];
1114 str << " (" << Time(fEventData->PCTime, fEventData->PCUsec) << ")";
1115 h->SetTitle(str.str().c_str());
1116 str.str("");
1117 str << "ADC Pipeline (start=" << fEventData->StartPix[p] << ")";
1118 h->SetXTitle(str.str().c_str());
1119
1120 // str.str("");
1121 // str << "Crate=" << crate << " Board=" << board << " Channel=" << channel << " [" << d.time() << "]" << endl;
1122 // hist->SetTitle(str.str().c_str());
1123
1124 for (int i=0; i<fEventData->Roi; i++)
1125 h->SetBinContent(i+1, fEventData->Adc_Data[p*fEventData->Roi+i]*0.5);
1126
1127 if (fAdcAutoScale->isChecked())
1128 {
1129 h->SetMinimum(-1111);
1130 h->SetMaximum(-1111);
1131 }
1132 else
1133 {
1134 if (h->GetMinimumStored()==-1111)
1135 h->SetMinimum(-1026);
1136 if (h->GetMaximumStored()==-1111)
1137 h->SetMaximum(1025);
1138 }
1139
1140 c->Modified();
1141 c->Update();
1142#endif
1143 }
1144
1145 void handleFadEventData(const DimData &d)
1146 {
1147 if (d.size()==0)
1148 return;
1149
1150 if (fAdcStop->isChecked())
1151 return;
1152
1153 const EVENT &dat = d.ref<EVENT>();
1154
1155 if (d.size()<sizeof(EVENT))
1156 {
1157 cout << "Size mismatch in " << d.name << ": Found=" << d.size() << " Expected>=" << sizeof(EVENT) << endl;
1158 return;
1159 }
1160
1161 if (d.size()!=sizeof(EVENT)+dat.Roi*2*1440)
1162 {
1163 cout << "Size mismatch in " << d.name << ": Found=" << d.size() << " Expected=" << dat.Roi*2*1440+sizeof(EVENT) << endl;
1164 return;
1165 }
1166
1167 delete fEventData;
1168 fEventData = reinterpret_cast<EVENT*>(new char[d.size()]);
1169 memcpy(fEventData, d.ptr<void>(), d.size());
1170
1171 DisplayEventData();
1172 }
1173
1174// vector<uint8_t> fFadConnections;
1175
1176 void handleFadConnections(const DimData &d)
1177 {
1178 if (!CheckSize(d, 41))
1179 {
1180 fStatusEventBuilderLabel->setText("Offline");
1181 fStatusEventBuilderLabel->setToolTip("FADs or fadctrl seems to be offline.");
1182 fEvtBldWidget->setEnabled(false);
1183
1184 SetLedColor(fStatusEventBuilderLed, kLedGray, d.time);
1185 return;
1186 }
1187
1188 const uint8_t *ptr = d.ptr<uint8_t>();
1189
1190 for (int i=0; i<40; i++)
1191 {
1192 const uint8_t stat1 = ptr[i]&3;
1193 const uint8_t stat2 = ptr[i]>>3;
1194
1195 if (stat1==0 && stat2==0)
1196 {
1197 SetLedColor(fFadLED[i], kLedGray, d.time);
1198 continue;
1199 }
1200 if (stat1==2 && stat2==8)
1201 {
1202 SetLedColor(fFadLED[i], kLedGreen, d.time);
1203 continue;
1204 }
1205
1206 if (stat1==1 && stat2==1)
1207 SetLedColor(fFadLED[i], kLedRed, d.time);
1208 else
1209 SetLedColor(fFadLED[i], kLedOrange, d.time);
1210 }
1211
1212
1213 const bool runs = ptr[40]!=0;
1214
1215 fStatusEventBuilderLabel->setText(runs?"Running":"Not running");
1216 fStatusEventBuilderLabel->setToolTip(runs?"Event builder thread running.":"Event builder thread stopped.");
1217 fEvtBldWidget->setEnabled(runs);
1218
1219 SetLedColor(fStatusEventBuilderLed, runs?kLedGreen:kLedRed, d.time);
1220
1221// fFadConnections.assign(ptr, ptr+40);
1222 }
1223
1224 template<typename T>
1225 void handleFadToolTip(const Time &time, QWidget *w, T *ptr)
1226 {
1227 ostringstream tip;
1228 tip << "<table border='1'><tr><th colspan='11'>" << time.GetAsStr() << " (UTC)</th></tr><tr><th></th>";
1229 for (int b=0; b<10; b++)
1230 tip << "<th>" << b << "</th>";
1231 tip << "</tr>";
1232
1233 for (int c=0; c<4; c++)
1234 {
1235 tip << "<tr><th>" << c << "</th>";
1236 for (int b=0; b<10; b++)
1237 tip << "<td>" << ptr[c*10+b] << "</td>";
1238 tip << "</tr>";
1239 }
1240 tip << "</table>";
1241
1242 w->setToolTip(tip.str().c_str());
1243 }
1244
1245 template<typename T, class S>
1246 void handleFadMinMax(const DimData &d, QPushButton *led, S *wmin, S *wmax=0)
1247 {
1248 if (!CheckSize(d, 42*sizeof(T)))
1249 return;
1250
1251 const T *ptr = d.ptr<T>();
1252 const T min = ptr[40];
1253 const T max = ptr[41];
1254
1255 if (max<min)
1256 SetLedColor(led, kLedGray, d.time);
1257 else
1258 SetLedColor(led, min==max?kLedGreen: kLedOrange, d.time);
1259
1260 if (!wmax && max!=min)
1261 wmin->setValue(0);
1262 else
1263 wmin->setValue(min);
1264
1265 if (wmax)
1266 wmax->setValue(max);
1267
1268 handleFadToolTip(d.time, led, ptr);
1269 }
1270
1271 void handleFadFwVersion(const DimData &d)
1272 {
1273 handleFadMinMax<float, QDoubleSpinBox>(d, fFadLedFwVersion, fFadFwVersion);
1274 }
1275
1276 void handleFadRunNumber(const DimData &d)
1277 {
1278 handleFadMinMax<uint32_t, QSpinBox>(d, fFadLedRunNumber, fFadRunNumber);
1279 }
1280
1281 void handleFadPrescaler(const DimData &d)
1282 {
1283 handleFadMinMax<uint16_t, QSpinBox>(d, fFadLedPrescaler, fFadPrescaler);
1284 }
1285
1286 void handleFadDNA(const DimData &d)
1287 {
1288 if (!CheckSize(d, 40*sizeof(uint64_t)))
1289 return;
1290
1291 const uint64_t *ptr = d.ptr<uint64_t>();
1292
1293 ostringstream tip;
1294 tip << "<table width='100%'>";
1295 tip << "<tr><th>Crate</th><td></td><th>Board</th><td></td><th>DNA</th></tr>";
1296
1297 for (int i=0; i<40; i++)
1298 {
1299 tip << dec;
1300 tip << "<tr>";
1301 tip << "<td align='center'>" << i/10 << "</td><td>:</td>";
1302 tip << "<td align='center'>" << i%10 << "</td><td>:</td>";
1303 tip << hex;
1304 tip << "<td>0x" << setfill('0') << setw(16) << ptr[i] << "</td>";
1305 tip << "</tr>";
1306 }
1307 tip << "</table>";
1308
1309 fFadDNA->setText(tip.str().c_str());
1310 }
1311
1312 void SetFadLed(QPushButton *led, const DimData &d, uint16_t bitmask, bool invert=false)
1313 {
1314 if (d.size()==0)
1315 {
1316 SetLedColor(led, kLedGray, d.time);
1317 return;
1318 }
1319
1320 const bool quality = d.ptr<uint16_t>()[0]&bitmask;
1321 const bool value = d.ptr<uint16_t>()[1]&bitmask;
1322 const uint16_t *ptr = d.ptr<uint16_t>()+2;
1323
1324 SetLedColor(led, quality?kLedOrange:(value^invert?kLedGreen:kLedRed), d.time);
1325
1326 ostringstream tip;
1327 tip << "<table border='1'><tr><th colspan='11'>" << d.time.GetAsStr() << " (UTC)</th></tr><tr><th></th>";
1328 for (int b=0; b<10; b++)
1329 tip << "<th>" << b << "</th>";
1330 tip << "</tr>";
1331
1332 /*
1333 tip << "<tr>" << hex;
1334 tip << "<th>" << d.ptr<uint16_t>()[0] << " " << (d.ptr<uint16_t>()[0]&bitmask) << "</th>";
1335 tip << "<th>" << d.ptr<uint16_t>()[1] << " " << (d.ptr<uint16_t>()[1]&bitmask) << "</th>";
1336 tip << "</tr>";
1337 */
1338
1339 for (int c=0; c<4; c++)
1340 {
1341 tip << "<tr><th>" << dec << c << "</th>" << hex;
1342 for (int b=0; b<10; b++)
1343 {
1344 tip << "<td>"
1345 << (ptr[c*10+b]&bitmask)
1346 << "</td>";
1347 }
1348 tip << "</tr>";
1349 }
1350 tip << "</table>";
1351
1352 led->setToolTip(tip.str().c_str());
1353 }
1354
1355 void handleFadStatus(const DimData &d)
1356 {
1357 if (d.size()!=0 && !CheckSize(d, 42*sizeof(uint16_t)))
1358 return;
1359
1360 SetFadLed(fFadLedDrsEnabled, d, FAD::EventHeader::kDenable);
1361 SetFadLed(fFadLedDrsWrite, d, FAD::EventHeader::kDwrite);
1362 SetFadLed(fFadLedDcmLocked, d, FAD::EventHeader::kDcmLocked);
1363 SetFadLed(fFadLedDcmReady, d, FAD::EventHeader::kDcmReady);
1364 SetFadLed(fFadLedSpiSclk, d, FAD::EventHeader::kSpiSclk);
1365 SetFadLed(fFadLedRefClockTooLow, d, FAD::EventHeader::kRefClkTooLow, true);
1366 SetFadLed(fFadLedBusy, d, FAD::EventHeader::kBusy);
1367 SetFadLed(fFadLedTriggerLine, d, FAD::EventHeader::kTriggerLine);
1368 SetFadLed(fFadLedContTrigger, d, FAD::EventHeader::kContTrigger);
1369 SetFadLed(fFadLedSocket, d, FAD::EventHeader::kSock17);
1370 SetFadLed(fFadLedPllLock, d, 0xf000);
1371 }
1372
1373 void handleFadStatistics1(const DimData &d)
1374 {
1375 if (!CheckSize(d, sizeof(GUI_STAT)))
1376 return;
1377
1378 const GUI_STAT &stat = d.ref<GUI_STAT>();
1379
1380 /*
1381 //info about status of the main threads
1382 int32_t readStat ; //read thread
1383 int32_t procStat ; //processing thread(s)
1384 int32_t writStat ; //write thread
1385 */
1386
1387 fFadBufferMax->setValue(stat.totMem/1000000);
1388 fFadBuffer->setMaximum(stat.totMem/100);
1389 fFadBuffer->setValue((stat.maxMem>stat.totMem?stat.totMem:stat.maxMem)/100); // Max mem used in last second
1390
1391 uint32_t sum = 0;
1392 int32_t min = 0x7fffff;
1393 int32_t max = 0;
1394
1395 int cnt = 0;
1396 int err = 0;
1397
1398 for (int i=0; i<40; i++)
1399 {
1400 if (stat.numConn[i]!=7)
1401 continue;
1402
1403 cnt++;
1404
1405 sum += stat.rateBytes[i];
1406 err += stat.errConn[i];
1407
1408 if (stat.rateBytes[i]<min)
1409 min = stat.rateBytes[i];
1410 if (stat.rateBytes[i]>max)
1411 max = stat.rateBytes[i];
1412 }
1413
1414 fFadEvtConn->setValue(cnt);
1415 fFadEvtConnErr->setValue(err);
1416
1417 fFadEvtBufNew->setValue(stat.bufNew); // Incomplete in buffer
1418 fFadEvtBufEvt->setValue(stat.bufEvt); // Complete in buffer
1419 fFadEvtBufMax->setValue(stat.maxEvt); // Complete in buffer
1420 fFadEvtWrite->setValue(stat.evtWrite-stat.evtSkip-stat.evtErr);
1421 fFadEvtSkip->setValue(stat.evtSkip);
1422 fFadEvtErr->setValue(stat.evtErr);
1423
1424 if (stat.deltaT==0)
1425 return;
1426
1427 fFadEthernetRateMin->setValue(min/stat.deltaT);
1428 fFadEthernetRateMax->setValue(max/stat.deltaT);
1429 fFadEthernetRateTot->setValue(sum/stat.deltaT);
1430 fFadEthernetRateAvg->setValue(cnt==0 ? 0 : sum/cnt/stat.deltaT);
1431 fFadEvtRateNew->setValue(1000*stat.rateNew/stat.deltaT);
1432 fFadEvtRateWrite->setValue(1000*stat.rateWrite/stat.deltaT);
1433 }
1434
1435 void handleFadStatistics2(const DimData &d)
1436 {
1437 if (!CheckSize(d, sizeof(EVT_STAT)))
1438 return;
1439
1440 //const EVT_STAT &stat = d.ref<EVT_STAT>();
1441
1442 /*
1443 //some info about what happened since start of program (or last 'reset')
1444 uint32_t reset ; //#if increased, reset all counters
1445 uint32_t numRead[MAX_SOCK] ; //how often succesfull read from N sockets per loop
1446
1447 uint64_t gotByte[NBOARDS] ; //#Bytes read per Board
1448 uint32_t gotErr[NBOARDS] ; //#Communication Errors per Board
1449
1450 uint32_t evtGet; //#new Start of Events read
1451 uint32_t evtTot; //#complete Events read
1452
1453 uint32_t evtErr; //#Events with Errors
1454 uint32_t evtSkp; //#Events incomplete (timeout)
1455
1456
1457 uint32_t procTot; //#Events processed
1458 uint32_t procErr; //#Events showed problem in processing
1459 uint32_t procTrg; //#Events accepted by SW trigger
1460 uint32_t procSkp; //#Events rejected by SW trigger
1461
1462 uint32_t feedTot; //#Events used for feedBack system
1463 uint32_t feedErr; //#Events rejected by feedBack
1464
1465 uint32_t wrtTot; //#Events written to disk
1466 uint32_t wrtErr; //#Events with write-error
1467
1468 uint32_t runOpen; //#Runs opened
1469 uint32_t runClose; //#Runs closed
1470 uint32_t runErr; //#Runs with open/close errors
1471
1472
1473 //info about current connection status
1474 uint8_t numConn[NBOARDS] ; //#Sockets succesfully open per board
1475 */
1476 }
1477
1478 // ===================== FTM ============================================
1479
1480 double fTimeStamp1;
1481
1482 void handleFtmTriggerCounter(const DimData &d)
1483 {
1484 if (!CheckSize(d, sizeof(FTM::DimTriggerCounter)))
1485 return;
1486
1487 const FTM::DimTriggerCounter &sdata = d.ref<FTM::DimTriggerCounter>();
1488
1489 fFtmTime->setText(QString::number(sdata.fTimeStamp/1000000., 'f', 6)+ " s");
1490 fTriggerCounter->setText(QString::number(sdata.fTriggerCounter));
1491
1492 if (sdata.fTimeStamp>0)
1493 fTriggerCounterRate->setValue(1000000.*sdata.fTriggerCounter/sdata.fTimeStamp);
1494 else
1495 fTriggerCounterRate->setValue(0);
1496
1497
1498 // ----------------------------------------------
1499#ifdef HAVE_ROOT
1500
1501 if (fTriggerCounter0<0)
1502 {
1503 fTriggerCounter0 = sdata.fTriggerCounter;
1504 fTimeStamp1 = sdata.fTimeStamp;
1505 return;
1506 }
1507
1508 TCanvas *c = fFtmRateCanv->GetCanvas();
1509
1510 TH1 *h = (TH1*)c->FindObject("TimeFrame");
1511
1512 const double rate = sdata.fTriggerCounter-fTriggerCounter0;
1513 const double tdiff = sdata.fTimeStamp -fTimeStamp1;
1514
1515 fTriggerCounter0 = sdata.fTriggerCounter;
1516 fTimeStamp1 = sdata.fTimeStamp;
1517
1518 if (rate<0 && tdiff<=0)
1519 {
1520 fGraphFtmRate.Set(0);
1521
1522 const double tm = Time().RootTime();
1523
1524 h->SetBins(1, tm, tm+60);
1525 h->GetXaxis()->SetTimeFormat("%M'%S\"");
1526 h->GetXaxis()->SetTitle("Time");
1527
1528 c->Modified();
1529 c->Update();
1530 return;
1531 }
1532
1533 if (rate<0)
1534 return;
1535
1536// const double avgrate = sdata.fTimeStamp>0 ? double(sdata.fTriggerCounter)/sdata.fTimeStamp*1000000 : 1;
1537
1538 const double t1 = h->GetXaxis()->GetXmax();
1539 const double t0 = h->GetXaxis()->GetXmin();
1540
1541 h->SetBins(h->GetNbinsX()+1, t0, t0+sdata.fTimeStamp/1000000.+1);
1542 fGraphFtmRate.SetPoint(fGraphFtmRate.GetN(),
1543 t0+sdata.fTimeStamp/1000000., 1000000*rate/tdiff);
1544
1545 if (t1-t0>60)
1546 {
1547 h->GetXaxis()->SetTimeFormat("%Hh%M'");
1548 h->GetXaxis()->SetTitle("Time");
1549 }
1550
1551 h->SetMinimum(0);
1552// h->SetMaximum(2*avgrate);
1553
1554 c->Modified();
1555 c->Update();
1556#endif
1557 // ----------------------------------------------
1558 }
1559
1560 void handleFtmCounter(const DimData &d)
1561 {
1562 if (!CheckSize(d, sizeof(uint32_t)*6))
1563 return;
1564
1565 const uint32_t *sdata = d.ptr<uint32_t>();
1566
1567 fFtmCounterH->setValue(sdata[0]);
1568 fFtmCounterS->setValue(sdata[1]);
1569 fFtmCounterD->setValue(sdata[2]);
1570 fFtmCounterF->setValue(sdata[3]);
1571 fFtmCounterE->setValue(sdata[4]);
1572 fFtmCounterR->setValue(sdata[5]);
1573 }
1574
1575 int64_t fTriggerCounter0;
1576 int64_t fTimeStamp0;
1577
1578 void handleFtmDynamicData(const DimData &d)
1579 {
1580 if (!CheckSize(d, sizeof(FTM::DimDynamicData)))
1581 return;
1582
1583 const FTM::DimDynamicData &sdata = d.ref<FTM::DimDynamicData>();
1584
1585 fOnTime->setText(QString::number(sdata.fOnTimeCounter/1000000., 'f', 6)+" s");
1586
1587 if (sdata.fTimeStamp>0)
1588 fOnTimeRel->setValue(100.*sdata.fOnTimeCounter/sdata.fTimeStamp);
1589 else
1590 fOnTimeRel->setValue(0);
1591
1592 fFtmTemp0->setValue(sdata.fTempSensor[0]*0.1);
1593 fFtmTemp1->setValue(sdata.fTempSensor[1]*0.1);
1594 fFtmTemp2->setValue(sdata.fTempSensor[2]*0.1);
1595 fFtmTemp3->setValue(sdata.fTempSensor[3]*0.1);
1596
1597
1598#ifdef HAVE_ROOT
1599
1600 // ----------------------------------------------
1601
1602 if (fTimeStamp0<0)
1603 {
1604 fTimeStamp0 = sdata.fTimeStamp;
1605 return;
1606 }
1607
1608 TCanvas *c = fFtmRateCanv->GetCanvas();
1609
1610 TH1 *h = (TH1*)c->FindObject("TimeFrame");
1611
1612 const double tdiff = sdata.fTimeStamp-fTimeStamp0;
1613 fTimeStamp0 = sdata.fTimeStamp;
1614
1615 if (tdiff<0)
1616 {
1617 for (int i=0; i<160; i++)
1618 fGraphPatchRate[i].Set(0);
1619 for (int i=0; i<40; i++)
1620 fGraphBoardRate[i].Set(0);
1621
1622 return;
1623 }
1624
1625 //const double t1 = h->GetXaxis()->GetXmax();
1626 const double t0 = h->GetXaxis()->GetXmin();
1627
1628 for (int i=0; i<160; i++)
1629 fGraphPatchRate[i].SetPoint(fGraphPatchRate[i].GetN(),
1630 t0+sdata.fTimeStamp/1000000., float(sdata.fRatePatch[i])*2/fFtmStaticData.fPrescaling[i]);
1631 for (int i=0; i<40; i++)
1632 fGraphBoardRate[i].SetPoint(fGraphBoardRate[i].GetN(),
1633 t0+sdata.fTimeStamp/1000000., float(sdata.fRateBoard[i])*2/fFtmStaticData.fPrescaling[i]);
1634
1635 c->Modified();
1636 c->Update();
1637
1638 //fGraphFtmRate.ComputeRange(x[0], x[1], x[2], x[3]);
1639
1640 // ----------------------------------------------
1641
1642 if (fThresholdIdx->value()>=0)
1643 {
1644 const int isw = fThresholdIdx->value();
1645 const int ihw = fPatchMapHW[isw];
1646 fPatchRate->setValue(sdata.fRatePatch[ihw]);
1647 }
1648
1649 valarray<double> dat(0., 1440);
1650
1651 // fPatch converts from software id to software patch id
1652 for (int i=0; i<1440; i++)
1653 {
1654 const int ihw = fPatchHW[i];
1655// const int isw = fPatch[i];
1656// const int ihw = fPatchMapHW[isw];
1657 dat[i] = sdata.fRatePatch[ihw];
1658 }
1659
1660 c = fRatesCanv->GetCanvas();
1661 Camera *cam = (Camera*)c->FindObject("Camera");
1662
1663 cam->SetData(dat);
1664
1665 c->Modified();
1666 c->Update();
1667
1668 // ----------------------------------------------
1669#endif
1670 }
1671
1672 void DisplayRates()
1673 {
1674#ifdef HAVE_ROOT
1675 TCanvas *c = fFtmRateCanv->GetCanvas();
1676
1677 while (c->FindObject("PatchRate"))
1678 c->GetListOfPrimitives()->Remove(c->FindObject("PatchRate"));
1679
1680 while (c->FindObject("BoardRate"))
1681 c->GetListOfPrimitives()->Remove(c->FindObject("BoardRate"));
1682
1683 c->cd();
1684
1685 if (fRatePatch1->value()>=0)
1686 {
1687 fGraphPatchRate[fRatePatch1->value()].SetLineColor(kRed);
1688 fGraphPatchRate[fRatePatch1->value()].SetMarkerColor(kRed);
1689 fGraphPatchRate[fRatePatch1->value()].Draw("PL");
1690 }
1691 if (fRatePatch2->value()>=0)
1692 {
1693 fGraphPatchRate[fRatePatch2->value()].SetLineColor(kGreen);
1694 fGraphPatchRate[fRatePatch2->value()].SetMarkerColor(kGreen);
1695 fGraphPatchRate[fRatePatch2->value()].Draw("PL");
1696 }
1697 if (fRateBoard1->value()>=0)
1698 {
1699 fGraphBoardRate[fRateBoard1->value()].SetLineColor(kMagenta);
1700 fGraphBoardRate[fRateBoard1->value()].SetMarkerColor(kMagenta);
1701 fGraphBoardRate[fRateBoard1->value()].Draw("PL");
1702 }
1703 if (fRateBoard2->value()>=0)
1704 {
1705 fGraphBoardRate[fRateBoard2->value()].SetLineColor(kCyan);
1706 fGraphBoardRate[fRateBoard2->value()].SetMarkerColor(kCyan);
1707 fGraphBoardRate[fRateBoard2->value()].Draw("PL");
1708 }
1709#endif
1710 }
1711
1712 void on_fRatePatch1_valueChanged(int)
1713 {
1714 DisplayRates();
1715 }
1716
1717 void on_fRatePatch2_valueChanged(int)
1718 {
1719 DisplayRates();
1720 }
1721
1722 void on_fRateBoard1_valueChanged(int)
1723 {
1724 DisplayRates();
1725 }
1726
1727 void on_fRateBoard2_valueChanged(int)
1728 {
1729 DisplayRates();
1730 }
1731
1732 FTM::DimStaticData fFtmStaticData;
1733
1734 void SetFtuLed(int idx, int counter, const Time &t)
1735 {
1736 if (counter==0 || counter>3)
1737 counter = 3;
1738
1739 if (counter<0)
1740 counter = 0;
1741
1742 const LedColor_t col[4] = { kLedGray, kLedGreen, kLedOrange, kLedRed };
1743
1744 SetLedColor(fFtuLED[idx], col[counter], t);
1745
1746 fFtuStatus[idx] = counter;
1747 }
1748
1749 void SetFtuStatusLed(const Time &t)
1750 {
1751 const int max = fFtuStatus.max();
1752
1753 switch (max)
1754 {
1755 case 0:
1756 SetLedColor(fStatusFTULed, kLedGray, t);
1757 fStatusFTULabel->setText("All disabled");
1758 fStatusFTULabel->setToolTip("All FTUs are disabled");
1759 break;
1760
1761 case 1:
1762 SetLedColor(fStatusFTULed, kLedGreen, t);
1763 fStatusFTULabel->setToolTip("Communication with FTU is smooth.");
1764 fStatusFTULabel->setText("ok");
1765 break;
1766
1767 case 2:
1768 SetLedColor(fStatusFTULed, kLedOrange, t);
1769 fStatusFTULabel->setText("Warning");
1770 fStatusFTULabel->setToolTip("At least one FTU didn't answer immediately");
1771 break;
1772
1773 case 3:
1774 SetLedColor(fStatusFTULed, kLedRed, t);
1775 fStatusFTULabel->setToolTip("At least one FTU didn't answer!");
1776 fStatusFTULabel->setText("ERROR");
1777 break;
1778 }
1779
1780 const int cnt = count(&fFtuStatus[0], &fFtuStatus[40], 0);
1781 fFtuAllOn->setEnabled(cnt!=0);
1782 fFtuAllOff->setEnabled(cnt!=40);
1783 }
1784
1785 void handleFtmStaticData(const DimData &d)
1786 {
1787 if (!CheckSize(d, sizeof(FTM::DimStaticData)))
1788 return;
1789
1790 const FTM::DimStaticData &sdata = d.ref<FTM::DimStaticData>();
1791
1792 fTriggerInterval->setValue(sdata.fTriggerInterval);
1793 fPhysicsCoincidence->setValue(sdata.fMultiplicityPhysics);
1794 fCalibCoincidence->setValue(sdata.fMultiplicityCalib);
1795 fPhysicsWindow->setValue(sdata.fWindowPhysics);
1796 fCalibWindow->setValue(sdata.fWindowCalib);
1797
1798 fTriggerDelay->setValue(sdata.fDelayTrigger);
1799 fTimeMarkerDelay->setValue(sdata.fDelayTimeMarker);
1800 fDeadTime->setValue(sdata.fDeadTime);
1801
1802 fClockCondR0->setValue(sdata.fClockConditioner[0]);
1803 fClockCondR1->setValue(sdata.fClockConditioner[1]);
1804 fClockCondR8->setValue(sdata.fClockConditioner[2]);
1805 fClockCondR9->setValue(sdata.fClockConditioner[3]);
1806 fClockCondR11->setValue(sdata.fClockConditioner[4]);
1807 fClockCondR13->setValue(sdata.fClockConditioner[5]);
1808 fClockCondR14->setValue(sdata.fClockConditioner[6]);
1809 fClockCondR15->setValue(sdata.fClockConditioner[7]);
1810
1811 const uint32_t R0 = sdata.fClockConditioner[0];
1812 const uint32_t R14 = sdata.fClockConditioner[6];
1813 const uint32_t R15 = sdata.fClockConditioner[7];
1814
1815 const uint32_t Ndiv = (R15&0x1ffff00)<<2;
1816 const uint32_t Rdiv = (R14&0x007ff00)>>8;
1817 const uint32_t Cdiv = (R0 &0x000ff00)>>8;
1818
1819 double freq = 40.*Ndiv/(Rdiv*Cdiv);
1820
1821 fClockCondFreqRes->setValue(freq);
1822
1823 //fClockCondFreq->setEditText("");
1824 fClockCondFreq->setCurrentIndex(0);
1825
1826 fTriggerSeqPed->setValue(sdata.fTriggerSeqPed);
1827 fTriggerSeqLPint->setValue(sdata.fTriggerSeqLPint);
1828 fTriggerSeqLPext->setValue(sdata.fTriggerSeqLPext);
1829
1830 fEnableTrigger->setChecked(sdata.HasTrigger());
1831 fEnableVeto->setChecked(sdata.HasVeto());
1832 fEnableExt1->setChecked(sdata.HasExt1());
1833 fEnableExt2->setChecked(sdata.HasExt2());
1834 fEnableClockCond->setChecked(sdata.HasClockConditioner());
1835
1836 for (int i=0; i<40; i++)
1837 {
1838 if (!sdata.IsActive(i))
1839 SetFtuLed(i, -1, d.time);
1840 else
1841 {
1842 if (fFtuStatus[i]==0)
1843 SetFtuLed(i, 1, d.time);
1844 }
1845 fFtuLED[i]->setChecked(false);
1846 }
1847 SetFtuStatusLed(d.time);
1848
1849#ifdef HAVE_ROOT
1850 Camera *cam = (Camera*)fRatesCanv->GetCanvas()->FindObject("Camera");
1851 for (int isw=0; isw<1440; isw++)
1852 {
1853 const int ihw = fPixelMapHW[isw];
1854 cam->SetEnable(isw, sdata.IsEnabled(ihw));
1855 }
1856
1857 fRatesCanv->GetCanvas()->Modified();
1858 fRatesCanv->GetCanvas()->Update();
1859#endif
1860
1861 {
1862 const int isw = fPixelIdx->value();
1863 const int ihw = fPixelMapHW[isw];
1864 const bool on = sdata.IsEnabled(ihw);
1865 fPixelEnable->setChecked(on);
1866 }
1867
1868 if (fThresholdIdx->value()>=0)
1869 {
1870 const int isw = fThresholdIdx->value();
1871 const int ihw = fPatchMapHW[isw];
1872 fThresholdVal->setValue(sdata.fThreshold[ihw]);
1873 }
1874
1875 fPrescalingVal->setValue(sdata.fPrescaling[0]);
1876
1877 fFtmStaticData = sdata;
1878 }
1879
1880 void handleFtmPassport(const DimData &d)
1881 {
1882 if (!CheckSize(d, sizeof(FTM::DimPassport)))
1883 return;
1884
1885 const FTM::DimPassport &sdata = d.ref<FTM::DimPassport>();
1886
1887 stringstream str1, str2;
1888 str1 << hex << "0x" << setfill('0') << setw(16) << sdata.fBoardId;
1889 str2 << sdata.fFirmwareId;
1890
1891 fFtmBoardId->setText(str1.str().c_str());
1892 fFtmFirmwareId->setText(str2.str().c_str());
1893 }
1894
1895 void handleFtmFtuList(const DimData &d)
1896 {
1897 if (!CheckSize(d, sizeof(FTM::DimFtuList)))
1898 return;
1899
1900 fFtuPing->setChecked(false);
1901
1902 const FTM::DimFtuList &sdata = d.ref<FTM::DimFtuList>();
1903
1904 stringstream str;
1905 str << "<table width='100%'>" << setfill('0');
1906 str << "<tr><th>Num</th><th></th><th>Addr</th><th></th><th>DNA</th></tr>";
1907 for (int i=0; i<40; i++)
1908 {
1909 str << "<tr>";
1910 str << "<td align='center'>" << dec << i << hex << "</td>";
1911 str << "<td align='center'>:</td>";
1912 str << "<td align='center'>0x" << setw(2) << (int)sdata.fAddr[i] << "</td>";
1913 str << "<td align='center'>:</td>";
1914 str << "<td align='center'>0x" << setw(16) << sdata.fDNA[i] << "</td>";
1915 str << "</tr>";
1916 }
1917 str << "</table>";
1918
1919 fFtuDNA->setText(str.str().c_str());
1920
1921 fFtuAnswersTotal->setValue(sdata.fNumBoards);
1922 fFtuAnswersCrate0->setValue(sdata.fNumBoardsCrate[0]);
1923 fFtuAnswersCrate1->setValue(sdata.fNumBoardsCrate[1]);
1924 fFtuAnswersCrate2->setValue(sdata.fNumBoardsCrate[2]);
1925 fFtuAnswersCrate3->setValue(sdata.fNumBoardsCrate[3]);
1926
1927 for (int i=0; i<40; i++)
1928 SetFtuLed(i, sdata.IsActive(i) ? sdata.fPing[i] : -1, d.time);
1929
1930 SetFtuStatusLed(d.time);
1931 }
1932
1933 void handleFtmError(const DimData &d)
1934 {
1935 if (!CheckSize(d, sizeof(FTM::DimError)))
1936 return;
1937
1938 const FTM::DimError &sdata = d.ref<FTM::DimError>();
1939
1940 SetFtuLed(sdata.fError.fDestAddress, sdata.fError.fNumCalls, d.time);
1941 SetFtuStatusLed(d.time);
1942
1943 // FIXME: Write to special window!
1944 //Out() << "Error:" << endl;
1945 //Out() << sdata.fError << endl;
1946 }
1947
1948 // ====================== MessageImp ====================================
1949
1950 bool fChatOnline;
1951
1952 void handleStateChanged(const Time &time, const std::string &server,
1953 const State &s)
1954 {
1955 // FIXME: Prefix tooltip with time
1956 if (server=="FTM_CONTROL")
1957 {
1958 // FIXME: Enable FTU page!!!
1959 fStatusFTMLabel->setText(s.name.c_str());
1960 fStatusFTMLabel->setToolTip(s.comment.c_str());
1961
1962 bool enable = false;
1963
1964 if (s.index<FTM::StateMachine::kDisconnected) // No Dim connection
1965 SetLedColor(fStatusFTMLed, kLedGray, time);
1966 if (s.index==FTM::StateMachine::kDisconnected) // Dim connection / FTM disconnected
1967 SetLedColor(fStatusFTMLed, kLedYellow, time);
1968 if (s.index==FTM::StateMachine::kConnected ||
1969 s.index==FTM::StateMachine::kIdle ||
1970 s.index==FTM::StateMachine::kConfiguring1 ||
1971 s.index==FTM::StateMachine::kConfiguring2 ||
1972 s.index==FTM::StateMachine::kConfigured ||
1973 s.index==FTM::StateMachine::kTakingData) // Dim connection / FTM connected
1974 SetLedColor(fStatusFTMLed, kLedGreen, time);
1975
1976 if (s.index==FTM::StateMachine::kConnected ||
1977 s.index==FTM::StateMachine::kIdle) // Dim connection / FTM connected
1978 enable = true;
1979
1980 fTriggerWidget->setEnabled(enable);
1981 fFtuWidget->setEnabled(enable);
1982 fRatesWidget->setEnabled(enable);
1983
1984 if (s.index>=FTM::StateMachine::kConnected)
1985 SetFtuStatusLed(time);
1986 else
1987 {
1988 SetLedColor(fStatusFTULed, kLedGray, time);
1989 fStatusFTULabel->setText("Offline");
1990 fStatusFTULabel->setToolTip("FTM is not online.");
1991 }
1992 }
1993
1994 if (server=="FAD_CONTROL")
1995 {
1996 fStatusFADLabel->setText(s.name.c_str());
1997 fStatusFADLabel->setToolTip(s.comment.c_str());
1998
1999 bool enable = false;
2000
2001 if (s.index<FAD::kOffline) // No Dim connection
2002 {
2003 SetLedColor(fStatusFADLed, kLedGray, time);
2004
2005 /*
2006 fStatusEventBuilderLabel->setText("Offline");
2007 fStatusEventBuilderLabel->setToolTip("No connection to fadctrl.");
2008 fEvtBldWidget->setEnabled(false);
2009
2010 SetLedColor(fStatusEventBuilderLed, kLedGray, time);
2011 */
2012 }
2013 if (s.index==FAD::kOffline) // Dim connection / FTM disconnected
2014 SetLedColor(fStatusFADLed, kLedRed, time);
2015 if (s.index==FAD::kDisconnected) // Dim connection / FTM disconnected
2016 SetLedColor(fStatusFADLed, kLedOrange, time);
2017 if (s.index==FAD::kConnecting) // Dim connection / FTM disconnected
2018 {
2019 SetLedColor(fStatusFADLed, kLedYellow, time);
2020 // FIXME FIXME FIXME: The LEDs are not displayed when disabled!
2021 enable = true;
2022 }
2023 if (s.index>=FAD::kConnected) // Dim connection / FTM connected
2024 {
2025 SetLedColor(fStatusFADLed, kLedGreen, time);
2026 enable = true;
2027 }
2028
2029 fFadWidget->setEnabled(enable);
2030 }
2031
2032 if (server=="FSC_CONTROL")
2033 {
2034 fStatusFSCLabel->setText(s.name.c_str());
2035 fStatusFSCLabel->setToolTip(s.comment.c_str());
2036
2037 bool enable = false;
2038
2039 if (s.index<1) // No Dim connection
2040 SetLedColor(fStatusFSCLed, kLedGray, time);
2041 if (s.index==1) // Dim connection / FTM disconnected
2042 SetLedColor(fStatusFSCLed, kLedRed, time);
2043 if (s.index>=2) // Dim connection / FTM disconnected
2044 {
2045 SetLedColor(fStatusFSCLed, kLedGreen, time);
2046 enable = true;
2047 }
2048
2049 //fFscWidget->setEnabled(enable);
2050 }
2051
2052 if (server=="DATA_LOGGER")
2053 {
2054 fStatusLoggerLabel->setText(s.name.c_str());
2055 fStatusLoggerLabel->setToolTip(s.comment.c_str());
2056
2057 bool enable = true;
2058
2059 if (s.index<=30) // Ready/Waiting
2060 SetLedColor(fStatusLoggerLed, kLedYellow, time);
2061 if (s.index<-1) // Offline
2062 {
2063 SetLedColor(fStatusLoggerLed, kLedGray, time);
2064 enable = false;
2065 }
2066 if (s.index>=0x100) // Error
2067 SetLedColor(fStatusLoggerLed, kLedRed, time);
2068 if (s.index==40) // Logging
2069 SetLedColor(fStatusLoggerLed, kLedGreen, time);
2070
2071 fLoggerWidget->setEnabled(enable);
2072 }
2073
2074 if (server=="CHAT")
2075 {
2076 fStatusChatLabel->setText(s.name.c_str());
2077
2078 fChatOnline = s.index==0;
2079
2080 SetLedColor(fStatusChatLed, fChatOnline ? kLedGreen : kLedGray, time);
2081
2082 fChatSend->setEnabled(fChatOnline);
2083 fChatMessage->setEnabled(fChatOnline);
2084 }
2085
2086 if (server=="SCHEDULER")
2087 {
2088 fStatusSchedulerLabel->setText(s.name.c_str());
2089
2090 SetLedColor(fStatusSchedulerLed, s.index>=0 ? kLedGreen : kLedRed, time);
2091 }
2092 }
2093
2094 void on_fTabWidget_currentChanged(int which)
2095 {
2096 if (fTabWidget->tabText(which)=="Chat")
2097 fTabWidget->setTabIcon(which, QIcon());
2098 }
2099
2100 void handleWrite(const Time &time, const string &text, int qos)
2101 {
2102 stringstream out;
2103
2104 if (text.substr(0, 6)=="CHAT: ")
2105 {
2106 if (qos==MessageImp::kDebug)
2107 return;
2108
2109 out << "<font size='-1' color='navy'>[<B>";
2110 out << time.GetAsStr("%H:%M:%S");
2111 out << "</B>]</FONT> " << text.substr(6);
2112 fChatText->append(out.str().c_str());
2113
2114 if (fTabWidget->tabText(fTabWidget->currentIndex())=="Chat")
2115 return;
2116
2117 static int num = 0;
2118 if (num++<2)
2119 return;
2120
2121 for (int i=0; i<fTabWidget->count(); i++)
2122 if (fTabWidget->tabText(i)=="Chat")
2123 {
2124 fTabWidget->setTabIcon(i, QIcon(":/Resources/icons/warning 3.png"));
2125 break;
2126 }
2127
2128 return;
2129 }
2130
2131
2132 out << "<font style='font-family:monospace' color='";
2133
2134 switch (qos)
2135 {
2136 case kMessage: out << "black"; break;
2137 case kInfo: out << "green"; break;
2138 case kWarn: out << "#FF6600"; break;
2139 case kError: out << "maroon"; break;
2140 case kFatal: out << "maroon"; break;
2141 case kDebug: out << "navy"; break;
2142 default: out << "navy"; break;
2143 }
2144 out << "'>";
2145 out << time.GetAsStr("%H:%M:%S.%f").substr(0,12);
2146 out << " - " << text << "</font>";
2147
2148 fLogText->append(out.str().c_str());
2149
2150 if (qos>=kWarn && qos!=kDebug)
2151 fTextEdit->append(out.str().c_str());
2152 }
2153
2154 void IndicateStateChange(const Time &time, const std::string &server)
2155 {
2156 const State s = GetState(server, GetCurrentState(server));
2157
2158 QApplication::postEvent(this,
2159 new FunctionEvent(boost::bind(&FactGui::handleStateChanged, this, time, server, s)));
2160 }
2161
2162 int Write(const Time &time, const string &txt, int qos)
2163 {
2164 QApplication::postEvent(this,
2165 new FunctionEvent(boost::bind(&FactGui::handleWrite, this, time, txt, qos)));
2166
2167 return 0;
2168 }
2169
2170 // ====================== Dim infoHandler================================
2171
2172 void handleDimService(const string &txt)
2173 {
2174 fDimSvcText->append(txt.c_str());
2175 }
2176
2177 void infoHandlerService(DimInfo &info)
2178 {
2179 const string fmt = string(info.getFormat()).empty() ? "C" : info.getFormat();
2180
2181 stringstream dummy;
2182 const Converter conv(dummy, fmt, false);
2183
2184 const Time tm(info.getTimestamp(), info.getTimestampMillisecs()*1000);
2185
2186 stringstream out;
2187 out << "<font size'-1' color='navy'>[";
2188 out << tm.GetAsStr("%H:%M:%S.%f").substr(0,12);
2189 out << "]</font> <B>" << info.getName() << "</B> - ";
2190
2191 bool iserr = true;
2192 if (!conv)
2193 {
2194 out << "Compilation of format string '" << fmt << "' failed!";
2195 }
2196 else
2197 {
2198 try
2199 {
2200 const string dat = conv.GetString(info.getData(), info.getSize());
2201 out << dat;
2202 iserr = false;
2203 }
2204 catch (const runtime_error &e)
2205 {
2206 out << "Conversion to string failed!<pre>" << e.what() << "</pre>";
2207 }
2208 }
2209
2210 // srand(hash<string>()(string(info.getName())));
2211 // int bg = rand()&0xffffff;
2212
2213 int bg = hash<string>()(string(info.getName()));
2214
2215 // allow only light colors
2216 bg = ~(bg&0x1f1f1f)&0xffffff;
2217
2218 if (iserr)
2219 bg = 0xffffff;
2220
2221 stringstream bgcol;
2222 bgcol << hex << setfill('0') << setw(6) << bg;
2223
2224 const string col = iserr ? "red" : "black";
2225 const string str = "<table width='100%' bgcolor=#"+bgcol.str()+"><tr><td><font color='"+col+"'>"+out.str()+"</font></td></tr></table>";
2226
2227 QApplication::postEvent(this,
2228 new FunctionEvent(boost::bind(&FactGui::handleDimService, this, str)));
2229 }
2230
2231 void CallInfoHandler(void (FactGui::*handler)(const DimData&), const DimData &d)
2232 {
2233 fInHandler = true;
2234 (this->*handler)(d);
2235 fInHandler = false;
2236 }
2237
2238 /*
2239 void CallInfoHandler(const boost::function<void()> &func)
2240 {
2241 // This ensures that newly received values are not sent back to the emitter
2242 // because changing the value emits the valueChanged signal (or similar)
2243 fInHandler = true;
2244 func();
2245 fInHandler = false;
2246 }*/
2247
2248 void PostInfoHandler(void (FactGui::*handler)(const DimData&))
2249 {
2250 //const boost::function<void()> f = boost::bind(handler, this, DimData(getInfo()));
2251
2252 FunctionEvent *evt = new FunctionEvent(boost::bind(&FactGui::CallInfoHandler, this, handler, DimData(getInfo())));
2253 // FunctionEvent *evt = new FunctionEvent(boost::bind(&FactGui::CallInfoHandler, this, f));
2254 // FunctionEvent *evt = new FunctionEvent(boost::bind(handler, this, DimData(getInfo()))));
2255
2256 QApplication::postEvent(this, evt);
2257 }
2258
2259 void infoHandler()
2260 {
2261 // Initialize the time-stamp (what a weird workaround...)
2262 if (getInfo())
2263 getInfo()->getTimestamp();
2264
2265 if (getInfo()==&fDimDNS)
2266 return PostInfoHandler(&FactGui::handleDimDNS);
2267#ifdef DEBUG_DIM
2268 cout << "HandleDimInfo " << getInfo()->getName() << endl;
2269#endif
2270 if (getInfo()==&fDimLoggerStats)
2271 return PostInfoHandler(&FactGui::handleLoggerStats);
2272
2273// if (getInfo()==&fDimFadFiles)
2274// return PostInfoHandler(&FactGui::handleFadFiles);
2275
2276 if (getInfo()==&fDimFadWriteStats)
2277 return PostInfoHandler(&FactGui::handleFadWriteStats);
2278
2279 if (getInfo()==&fDimFadConnections)
2280 return PostInfoHandler(&FactGui::handleFadConnections);
2281
2282 if (getInfo()==&fDimFadFwVersion)
2283 return PostInfoHandler(&FactGui::handleFadFwVersion);
2284
2285 if (getInfo()==&fDimFadRunNumber)
2286 return PostInfoHandler(&FactGui::handleFadRunNumber);
2287
2288 if (getInfo()==&fDimFadDNA)
2289 return PostInfoHandler(&FactGui::handleFadDNA);
2290
2291 if (getInfo()==&fDimFadTemperature)
2292 return PostInfoHandler(&FactGui::handleFadTemperature);
2293
2294 if (getInfo()==&fDimFadRefClock)
2295 return PostInfoHandler(&FactGui::handleFadRefClock);
2296
2297 if (getInfo()==&fDimFadPrescaler)
2298 return PostInfoHandler(&FactGui::handleFadPrescaler);
2299
2300 if (getInfo()==&fDimFadStatus)
2301 return PostInfoHandler(&FactGui::handleFadStatus);
2302
2303 if (getInfo()==&fDimFadStatistics1)
2304 return PostInfoHandler(&FactGui::handleFadStatistics1);
2305
2306 if (getInfo()==&fDimFadStatistics2)
2307 return PostInfoHandler(&FactGui::handleFadStatistics2);
2308
2309 if (getInfo()==&fDimFadEvents)
2310 return PostInfoHandler(&FactGui::handleFadEvents);
2311
2312 if (getInfo()==&fDimFadRuns)
2313 return PostInfoHandler(&FactGui::handleFadRuns);
2314
2315 if (getInfo()==&fDimFadEventData)
2316 return PostInfoHandler(&FactGui::handleFadEventData);
2317
2318/*
2319 if (getInfo()==&fDimFadSetup)
2320 return PostInfoHandler(&FactGui::handleFadSetup);
2321*/
2322 if (getInfo()==&fDimLoggerFilenameNight)
2323 return PostInfoHandler(&FactGui::handleLoggerFilenameNight);
2324
2325 if (getInfo()==&fDimLoggerNumSubs)
2326 return PostInfoHandler(&FactGui::handleLoggerNumSubs);
2327
2328 if (getInfo()==&fDimLoggerFilenameRun)
2329 return PostInfoHandler(&FactGui::handleLoggerFilenameRun);
2330
2331 if (getInfo()==&fDimFtmTriggerCounter)
2332 return PostInfoHandler(&FactGui::handleFtmTriggerCounter);
2333
2334 if (getInfo()==&fDimFtmCounter)
2335 return PostInfoHandler(&FactGui::handleFtmCounter);
2336
2337 if (getInfo()==&fDimFtmDynamicData)
2338 return PostInfoHandler(&FactGui::handleFtmDynamicData);
2339
2340 if (getInfo()==&fDimFtmPassport)
2341 return PostInfoHandler(&FactGui::handleFtmPassport);
2342
2343 if (getInfo()==&fDimFtmFtuList)
2344 return PostInfoHandler(&FactGui::handleFtmFtuList);
2345
2346 if (getInfo()==&fDimFtmStaticData)
2347 return PostInfoHandler(&FactGui::handleFtmStaticData);
2348
2349 if (getInfo()==&fDimFtmError)
2350 return PostInfoHandler(&FactGui::handleFtmError);
2351
2352// if (getInfo()==&fDimFadFiles)
2353// return PostInfoHandler(&FactGui::handleFadFiles);
2354
2355 for (map<string,DimInfo*>::iterator i=fServices.begin(); i!=fServices.end(); i++)
2356 if (i->second==getInfo())
2357 {
2358 infoHandlerService(*i->second);
2359 return;
2360 }
2361
2362 DimNetwork::infoHandler();
2363 }
2364
2365
2366 // ======================================================================
2367
2368 bool event(QEvent *evt)
2369 {
2370 if (dynamic_cast<FunctionEvent*>(evt))
2371 return static_cast<FunctionEvent*>(evt)->Exec();
2372
2373 if (dynamic_cast<CheckBoxEvent*>(evt))
2374 {
2375 const QStandardItem &item = static_cast<CheckBoxEvent*>(evt)->item;
2376 const QStandardItem *par = item.parent();
2377 if (par)
2378 {
2379 const QString server = par->text();
2380 const QString service = item.text();
2381
2382 const string s = (server+'/'+service).toStdString();
2383
2384 if (item.checkState()==Qt::Checked)
2385 SubscribeService(s);
2386 else
2387 UnsubscribeService(s);
2388 }
2389 }
2390
2391 return MainWindow::event(evt); // unrecognized
2392 }
2393
2394 void on_fDimCmdSend_clicked()
2395 {
2396 const QString server = fDimCmdServers->currentIndex().data().toString();
2397 const QString command = fDimCmdCommands->currentIndex().data().toString();
2398 const QString arguments = fDimCmdLineEdit->displayText();
2399
2400 // FIXME: Sending a command exactly when the info Handler changes
2401 // the list it might lead to confusion.
2402 try
2403 {
2404 SendDimCommand(server.toStdString(), command.toStdString()+" "+arguments.toStdString());
2405 fTextEdit->append("<font color='green'>Command '"+server+'/'+command+"' successfully emitted.</font>");
2406 fDimCmdLineEdit->clear();
2407 }
2408 catch (const runtime_error &e)
2409 {
2410 stringstream txt;
2411 txt << e.what();
2412
2413 string buffer;
2414 while (getline(txt, buffer, '\n'))
2415 fTextEdit->append(("<font color='red'><pre>"+buffer+"</pre></font>").c_str());
2416 }
2417 }
2418
2419#ifdef HAVE_ROOT
2420 void slot_RootEventProcessed(TObject *obj, unsigned int evt, TCanvas *canv)
2421 {
2422 // kMousePressEvent // TCanvas processed QEvent mousePressEvent
2423 // kMouseMoveEvent // TCanvas processed QEvent mouseMoveEvent
2424 // kMouseReleaseEvent // TCanvas processed QEvent mouseReleaseEvent
2425 // kMouseDoubleClickEvent // TCanvas processed QEvent mouseDoubleClickEvent
2426 // kKeyPressEvent // TCanvas processed QEvent keyPressEvent
2427 // kEnterEvent // TCanvas processed QEvent enterEvent
2428 // kLeaveEvent // TCanvas processed QEvent leaveEvent
2429 if (dynamic_cast<TCanvas*>(obj))
2430 return;
2431
2432 TQtWidget *tipped = static_cast<TQtWidget*>(sender());
2433
2434 if (evt==11/*kMouseReleaseEvent*/)
2435 {
2436 if (dynamic_cast<Camera*>(obj))
2437 {
2438 const float xx = canv->AbsPixeltoX(tipped->GetEventX());
2439 const float yy = canv->AbsPixeltoY(tipped->GetEventY());
2440
2441 Camera *cam = static_cast<Camera*>(obj);
2442 const int isw = cam->GetIdx(xx, yy);
2443
2444 fPixelIdx->setValue(isw);
2445 ChoosePixel(*cam, isw);
2446 }
2447 return;
2448 }
2449
2450 if (evt==61/*kMouseDoubleClickEvent*/)
2451 {
2452 if (dynamic_cast<Camera*>(obj))
2453 {
2454 const float xx = canv->AbsPixeltoX(tipped->GetEventX());
2455 const float yy = canv->AbsPixeltoY(tipped->GetEventY());
2456
2457 Camera *cam = static_cast<Camera*>(obj);
2458 const int isw = cam->GetIdx(xx, yy);
2459
2460 ChoosePixel(*cam, isw);
2461
2462 fPixelIdx->setValue(isw);
2463
2464 const uint16_t ihw = fPixelMapHW[isw];
2465
2466 Dim::SendCommand("FTM_CONTROL/TOGGLE_PIXEL", ihw);
2467 }
2468
2469 if (dynamic_cast<TAxis*>(obj))
2470 static_cast<TAxis*>(obj)->UnZoom();
2471
2472 return;
2473 }
2474
2475 // Find the object which will get picked by the GetObjectInfo
2476 // due to buffer overflows in many root-versions
2477 // in TH1 and TProfile we have to work around and implement
2478 // our own GetObjectInfo which make everything a bit more
2479 // complicated.
2480 canv->cd();
2481#if ROOT_VERSION_CODE > ROOT_VERSION(5,22,00)
2482 const char *objectInfo =
2483 obj->GetObjectInfo(tipped->GetEventX(),tipped->GetEventY());
2484#else
2485 const char *objectInfo = dynamic_cast<TH1*>(obj) ?
2486 "" : obj->GetObjectInfo(tipped->GetEventX(),tipped->GetEventY());
2487#endif
2488
2489 QString tipText;
2490 tipText += obj->GetName();
2491 tipText += " [";
2492 tipText += obj->ClassName();
2493 tipText += "]: ";
2494 tipText += objectInfo;
2495
2496 if (dynamic_cast<Camera*>(obj))
2497 {
2498 const float xx = canv->AbsPixeltoX(tipped->GetEventX());
2499 const float yy = canv->AbsPixeltoY(tipped->GetEventY());
2500
2501 Camera *cam = static_cast<Camera*>(obj);
2502
2503 const int isw = cam->GetIdx(xx, yy);
2504 const int ihw = fPixelMapHW[isw];
2505
2506 const int idx = fPatchHW[isw];
2507
2508 int ii = 0;
2509 for (; ii<160; ii++)
2510 if (idx==fPatchMapHW[ii])
2511 break;
2512
2513
2514 const int patch = ihw%4;
2515 const int board = (ihw/4)%10;
2516 const int crate = (ihw/4)/10;
2517
2518 ostringstream str;
2519 str << " (hw=" << ihw << ") Patch=" << ii << " (hw=" << fPatchMapHW[idx] << "; Crate=" << crate << " Board=" << board << " Patch=" << patch << ")";
2520
2521 tipText += str.str().c_str();
2522 }
2523
2524
2525 fStatusBar->showMessage(tipText, 3000);
2526
2527 gSystem->ProcessEvents();
2528 //QWhatsThis::display(tipText)
2529 }
2530
2531 void slot_RootUpdate()
2532 {
2533 gSystem->ProcessEvents();
2534 QTimer::singleShot(0, this, SLOT(slot_RootUpdate()));
2535 }
2536
2537 void ChoosePatch(Camera &cam, int isw)
2538 {
2539 cam.Reset();
2540
2541 fThresholdIdx->setValue(isw);
2542
2543 const int ihw = isw<0 ? 0 : fPatchMapHW[isw];
2544
2545 fPatchRate->setEnabled(isw>=0);
2546 fThresholdCrate->setEnabled(isw>=0);
2547 fThresholdBoard->setEnabled(isw>=0);
2548 fThresholdPatch->setEnabled(isw>=0);
2549
2550 if (isw<0)
2551 return;
2552
2553 const int patch = ihw%4;
2554 const int board = (ihw/4)%10;
2555 const int crate = (ihw/4)/10;
2556
2557 fInChoosePatch = true;
2558
2559 fThresholdCrate->setValue(crate);
2560 fThresholdBoard->setValue(board);
2561 fThresholdPatch->setValue(patch);
2562
2563 fInChoosePatch = false;
2564
2565 fThresholdVal->setValue(fFtmStaticData.fThreshold[ihw]);
2566 fPatchRate->setValue(cam.GetData(isw));
2567
2568 // Loop over the software idx of all pixels
2569 for (unsigned int i=0; i<1440; i++)
2570 if (fPatchHW[i]==ihw)
2571 cam.SetBold(i);
2572 }
2573
2574 void ChoosePixel(Camera &cam, int isw)
2575 {
2576 const int ihw = fPixelMapHW[isw];
2577
2578 int ii = 0;
2579 for (; ii<160; ii++)
2580 if (fPatchHW[isw]==fPatchMapHW[ii])
2581 break;
2582
2583 cam.SetWhite(isw);
2584 ChoosePatch(cam, ii);
2585
2586 const bool on = fFtmStaticData.IsEnabled(ihw);
2587 fPixelEnable->setChecked(on);
2588 }
2589
2590 void UpdatePatch(int isw)
2591 {
2592 Camera *cam = (Camera*)fRatesCanv->GetCanvas()->FindObject("Camera");
2593 ChoosePatch(*cam, isw);
2594 }
2595
2596 void on_fThresholdIdx_valueChanged(int isw)
2597 {
2598 UpdatePatch(isw);
2599
2600 fRatesCanv->GetCanvas()->Modified();
2601 fRatesCanv->GetCanvas()->Update();
2602 }
2603
2604 void UpdateThresholdIdx()
2605 {
2606 if (fInChoosePatch)
2607 return;
2608
2609 const int crate = fThresholdCrate->value();
2610 const int board = fThresholdBoard->value();
2611 const int patch = fThresholdPatch->value();
2612
2613 const int ihw = patch + board*4 + crate*40;
2614
2615 int isw = 0;
2616 for (; isw<160; isw++)
2617 if (ihw==fPatchMapHW[isw])
2618 break;
2619
2620 UpdatePatch(isw);
2621 }
2622
2623 void on_fThresholdPatch_valueChanged(int)
2624 {
2625 UpdateThresholdIdx();
2626 }
2627 void on_fThresholdBoard_valueChanged(int)
2628 {
2629 UpdateThresholdIdx();
2630 }
2631 void on_fThresholdCrate_valueChanged(int)
2632 {
2633 UpdateThresholdIdx();
2634 }
2635
2636 void on_fPixelIdx_valueChanged(int isw)
2637 {
2638 Camera *cam = (Camera*)fRatesCanv->GetCanvas()->FindObject("Camera");
2639 ChoosePixel(*cam, isw);
2640
2641 fRatesCanv->GetCanvas()->Modified();
2642 fRatesCanv->GetCanvas()->Update();
2643 }
2644#endif
2645
2646 void on_fPixelEnable_stateChanged(int b)
2647 {
2648 if (fInHandler)
2649 return;
2650
2651 const uint16_t isw = fPixelIdx->value();
2652 const uint16_t ihw = fPixelMapHW[isw];
2653
2654 Dim::SendCommand(b==Qt::Unchecked ?
2655 "FTM_CONTROL/DISABLE_PIXEL" : "FTM_CONTROL/ENABLE_PIXEL",
2656 ihw);
2657 }
2658
2659 void on_fPixelDisableOthers_clicked()
2660 {
2661 const uint16_t isw = fPixelIdx->value();
2662 const uint16_t ihw = fPixelMapHW[isw];
2663
2664 Dim::SendCommand("FTM_CONTROL/DISABLE_ALL_PIXELS_EXCEPT", ihw);
2665 }
2666
2667 void on_fThresholdDisableOthers_clicked()
2668 {
2669 const uint16_t isw = fThresholdIdx->value();
2670 const uint16_t ihw = fPatchMapHW[isw];
2671
2672 Dim::SendCommand("FTM_CONTROL/DISABLE_ALL_PATCHES_EXCEPT", ihw);
2673 }
2674
2675 void on_fThresholdVal_valueChanged(int v)
2676 {
2677 fThresholdVolt->setValue(2500./4095*v);
2678
2679 const int32_t isw = fThresholdIdx->value();
2680 const int32_t ihw = fPatchMapHW[isw];
2681
2682 const int32_t d[2] = { ihw, v };
2683
2684 if (!fInHandler)
2685 Dim::SendCommand("FTM_CONTROL/SET_THRESHOLD", d);
2686 }
2687
2688 TGraph fGraphFtmTemp[4];
2689 TGraph fGraphFtmRate;
2690 TGraph fGraphPatchRate[160];
2691 TGraph fGraphBoardRate[40];
2692
2693#ifdef HAVE_ROOT
2694 TH1 *DrawTimeFrame(const char *ytitle)
2695 {
2696 const double tm = Time().RootTime();
2697
2698 TH1F h("TimeFrame", "", 1, tm, tm+60);//Time().RootTime()-1./24/60/60, Time().RootTime());
2699 h.SetDirectory(0);
2700// h.SetBit(TH1::kCanRebin);
2701 h.SetStats(kFALSE);
2702// h.SetMinimum(0);
2703// h.SetMaximum(1);
2704 h.SetXTitle("Time");
2705 h.SetYTitle(ytitle);
2706 h.GetXaxis()->CenterTitle();
2707 h.GetYaxis()->CenterTitle();
2708 h.GetXaxis()->SetTimeDisplay(true);
2709 h.GetXaxis()->SetTimeFormat("%Mh%S'");
2710 h.GetXaxis()->SetLabelSize(0.025);
2711 h.GetYaxis()->SetLabelSize(0.025);
2712 h.GetYaxis()->SetTitleOffset(1.2);
2713 // h.GetYaxis()->SetTitleSize(1.2);
2714
2715 TH1 *cpy = h.DrawCopy();
2716 cpy->SetDirectory(0);
2717 return cpy;
2718 }
2719#endif
2720
2721public:
2722 FactGui() :
2723 fFtuStatus(40),
2724 fPixelMapHW(1440), fPatchMapHW(160), fPatchHW(1440),
2725 fInChoosePatch(false),
2726 fDimDNS("DIS_DNS/VERSION_NUMBER", 1, int(0), this),
2727 //-
2728 fDimLoggerStats ("DATA_LOGGER/STATS", (void*)NULL, 0, this),
2729 fDimLoggerFilenameNight("DATA_LOGGER/FILENAME_NIGHTLY", (void*)NULL, 0, this),
2730 fDimLoggerFilenameRun ("DATA_LOGGER/FILENAME_RUN", (void*)NULL, 0, this),
2731 fDimLoggerNumSubs ("DATA_LOGGER/NUM_SUBS", (void*)NULL, 0, this),
2732 //-
2733 fDimFtmPassport ("FTM_CONTROL/PASSPORT", (void*)NULL, 0, this),
2734 fDimFtmTriggerCounter ("FTM_CONTROL/TRIGGER_COUNTER", (void*)NULL, 0, this),
2735 fDimFtmError ("FTM_CONTROL/ERROR", (void*)NULL, 0, this),
2736 fDimFtmFtuList ("FTM_CONTROL/FTU_LIST", (void*)NULL, 0, this),
2737 fDimFtmStaticData ("FTM_CONTROL/STATIC_DATA", (void*)NULL, 0, this),
2738 fDimFtmDynamicData ("FTM_CONTROL/DYNAMIC_DATA", (void*)NULL, 0, this),
2739 fDimFtmCounter ("FTM_CONTROL/COUNTER", (void*)NULL, 0, this),
2740 //-
2741 fDimFadWriteStats ("FAD_CONTROL/STATS", (void*)NULL, 0, this),
2742 fDimFadRuns ("FAD_CONTROL/RUNS", (void*)NULL, 0, this),
2743 fDimFadEvents ("FAD_CONTROL/EVENTS", (void*)NULL, 0, this),
2744 fDimFadEventData ("FAD_CONTROL/EVENT_DATA", (void*)NULL, 0, this),
2745 fDimFadConnections ("FAD_CONTROL/CONNECTIONS", (void*)NULL, 0, this),
2746 fDimFadFwVersion ("FAD_CONTROL/FIRMWARE_VERSION", (void*)NULL, 0, this),
2747 fDimFadRunNumber ("FAD_CONTROL/RUN_NUMBER", (void*)NULL, 0, this),
2748 fDimFadDNA ("FAD_CONTROL/DNA", (void*)NULL, 0, this),
2749 fDimFadTemperature ("FAD_CONTROL/TEMPERATURE", (void*)NULL, 0, this),
2750 fDimFadPrescaler ("FAD_CONTROL/PRESCALER", (void*)NULL, 0, this),
2751 fDimFadRefClock ("FAD_CONTROL/REFERENCE_CLOCK", (void*)NULL, 0, this),
2752 fDimFadStatus ("FAD_CONTROL/STATUS", (void*)NULL, 0, this),
2753 fDimFadStatistics1 ("FAD_CONTROL/STATISTICS1", (void*)NULL, 0, this),
2754 fDimFadStatistics2 ("FAD_CONTROL/STATISTICS2", (void*)NULL, 0, this),
2755 //-
2756 fEventData(0)
2757 {
2758 fClockCondFreq->addItem("--- Hz", QVariant(-1));
2759 fClockCondFreq->addItem("800 MHz", QVariant(800));
2760 fClockCondFreq->addItem("1 GHz", QVariant(1000));
2761 fClockCondFreq->addItem("2 GHz", QVariant(2000));
2762 fClockCondFreq->addItem("3 GHz", QVariant(3000));
2763 fClockCondFreq->addItem("4 GHz", QVariant(4000));
2764 fClockCondFreq->addItem("5 GHz", QVariant(5000));
2765
2766 fMcpNumEvents->addItem("unlimited", QVariant(0));
2767 fMcpNumEvents->addItem("100", QVariant(100));
2768 fMcpNumEvents->addItem("300", QVariant(300));
2769 fMcpNumEvents->addItem("1000", QVariant(1000));
2770 fMcpNumEvents->addItem("3000", QVariant(3000));
2771 fMcpNumEvents->addItem("10000", QVariant(10000));
2772 fMcpNumEvents->addItem("30000", QVariant(30000));
2773
2774 fMcpTime->addItem("unlimited", QVariant(0));
2775 fMcpTime->addItem("00:30", QVariant(30));
2776 fMcpTime->addItem("01:00", QVariant(60));
2777 fMcpTime->addItem("02:30", QVariant(150));
2778 fMcpTime->addItem("05:00", QVariant(300));
2779 fMcpTime->addItem("10:00", QVariant(600));
2780 fMcpTime->addItem("15:00", QVariant(900));
2781 fMcpTime->addItem("20:00", QVariant(1200));
2782 fMcpTime->addItem("30:00", QVariant(1800));
2783 fMcpTime->addItem("60:00", QVariant(3600));
2784
2785 fMcpRunType->addItem("Data", QVariant("data"));
2786 fMcpRunType->addItem("Pedestal", QVariant("pedestal"));
2787 fMcpRunType->addItem("DRS Calib", QVariant("drs-calib"));
2788
2789 fTriggerWidget->setEnabled(false);
2790 fFtuWidget->setEnabled(false);
2791 fRatesWidget->setEnabled(false);
2792 fFadWidget->setEnabled(false);
2793 fEvtBldWidget->setEnabled(false);
2794 fLoggerWidget->setEnabled(false);
2795
2796 fChatSend->setEnabled(false);
2797 fChatMessage->setEnabled(false);
2798
2799 DimClient::sendCommand("CHAT/MSG", "GUI online.");
2800 // + MessageDimRX
2801
2802 // --------------------------------------------------------------------------
2803
2804 ifstream fin1("Trigger-Patches.txt");
2805
2806 int l = 0;
2807
2808 string buf;
2809 while (getline(fin1, buf, '\n'))
2810 {
2811 buf = Tools::Trim(buf);
2812 if (buf[0]=='#')
2813 continue;
2814
2815 stringstream str(buf);
2816 for (int i=0; i<9; i++)
2817 {
2818 unsigned int n;
2819 str >> n;
2820
2821 if (n>=fPatchHW.size())
2822 continue;
2823
2824 fPatchHW[n] = l;
2825 }
2826 l++;
2827 }
2828
2829 if (l!=160)
2830 cerr << "WARNING - Problems reading Trigger-Patches.txt" << endl;
2831
2832 // --------------------------------------------------------------------------
2833
2834 ifstream fin2("MasterList-v3.txt");
2835
2836 l = 0;
2837
2838 while (getline(fin2, buf, '\n'))
2839 {
2840 buf = Tools::Trim(buf);
2841 if (buf[0]=='#')
2842 continue;
2843
2844 unsigned int softid, hardid, dummy;
2845
2846 stringstream str(buf);
2847
2848 str >> softid;
2849 str >> dummy;
2850 str >> hardid;
2851
2852 if (softid>=fPixelMapHW.size())
2853 continue;
2854
2855 fPixelMapHW[softid] = hardid;
2856
2857 l++;
2858 }
2859
2860 if (l!=1440)
2861 cerr << "WARNING - Problems reading MasterList-v3.txt" << endl;
2862
2863 // --------------------------------------------------------------------------
2864
2865 ifstream fin3("PatchList.txt");
2866
2867 l = 0;
2868
2869 while (getline(fin3, buf, '\n'))
2870 {
2871 buf = Tools::Trim(buf);
2872 if (buf[0]=='#')
2873 continue;
2874
2875 unsigned int softid, hardid;
2876
2877 stringstream str(buf);
2878
2879 str >> softid;
2880 str >> hardid;
2881
2882 if (softid>=fPatchMapHW.size())
2883 continue;
2884
2885 fPatchMapHW[softid] = hardid-1;
2886
2887 l++;
2888 }
2889
2890 if (l!=160)
2891 cerr << "WARNING - Problems reading PatchList.txt" << endl;
2892
2893 // --------------------------------------------------------------------------
2894#ifdef HAVE_ROOT
2895
2896 fGraphFtmRate.SetLineColor(kBlue);
2897 fGraphFtmRate.SetMarkerColor(kBlue);
2898 fGraphFtmRate.SetMarkerStyle(kFullDotMedium);
2899
2900 for (int i=0; i<160; i++)
2901 {
2902 fGraphPatchRate[i].SetName("PatchRate");
2903 //fGraphPatchRate[i].SetLineColor(kBlue);
2904 //fGraphPatchRate[i].SetMarkerColor(kBlue);
2905 fGraphPatchRate[i].SetMarkerStyle(kFullDotMedium);
2906 }
2907 for (int i=0; i<40; i++)
2908 {
2909 fGraphBoardRate[i].SetName("BoardRate");
2910 //fGraphBoardRate[i].SetLineColor(kBlue);
2911 //fGraphBoardRate[i].SetMarkerColor(kBlue);
2912 fGraphBoardRate[i].SetMarkerStyle(kFullDotMedium);
2913 }
2914 /*
2915 TCanvas *c = fFtmTempCanv->GetCanvas();
2916 c->SetBit(TCanvas::kNoContextMenu);
2917 c->SetBorderMode(0);
2918 c->SetFrameBorderMode(0);
2919 c->SetFillColor(kWhite);
2920 c->SetRightMargin(0.03);
2921 c->SetTopMargin(0.03);
2922 c->cd();
2923 */
2924 //CreateTimeFrame("Temperature / °C");
2925
2926 fGraphFtmTemp[0].SetMarkerStyle(kFullDotSmall);
2927 fGraphFtmTemp[1].SetMarkerStyle(kFullDotSmall);
2928 fGraphFtmTemp[2].SetMarkerStyle(kFullDotSmall);
2929 fGraphFtmTemp[3].SetMarkerStyle(kFullDotSmall);
2930
2931 fGraphFtmTemp[1].SetLineColor(kBlue);
2932 fGraphFtmTemp[2].SetLineColor(kRed);
2933 fGraphFtmTemp[3].SetLineColor(kGreen);
2934
2935 fGraphFtmTemp[1].SetMarkerColor(kBlue);
2936 fGraphFtmTemp[2].SetMarkerColor(kRed);
2937 fGraphFtmTemp[3].SetMarkerColor(kGreen);
2938
2939 //fGraphFtmTemp[0].Draw("LP");
2940 //fGraphFtmTemp[1].Draw("LP");
2941 //fGraphFtmTemp[2].Draw("LP");
2942 //fGraphFtmTemp[3].Draw("LP");
2943
2944 // --------------------------------------------------------------------------
2945
2946 TCanvas *c = fFtmRateCanv->GetCanvas();
2947 //c->SetBit(TCanvas::kNoContextMenu);
2948 c->SetBorderMode(0);
2949 c->SetFrameBorderMode(0);
2950 c->SetFillColor(kWhite);
2951 c->SetRightMargin(0.03);
2952 c->SetTopMargin(0.03);
2953 c->SetGrid();
2954 c->cd();
2955
2956 TH1 *hf = DrawTimeFrame("Trigger rate [Hz]");
2957 hf->GetYaxis()->SetRangeUser(0, 1010);
2958
2959 fTriggerCounter0 = -1;
2960
2961 fGraphFtmRate.SetMarkerStyle(kFullDotSmall);
2962 fGraphFtmRate.Draw("LP");
2963
2964 // --------------------------------------------------------------------------
2965
2966 c = fRatesCanv->GetCanvas();
2967 //c->SetBit(TCanvas::kNoContextMenu);
2968 c->SetBorderMode(0);
2969 c->SetFrameBorderMode(0);
2970 c->SetFillColor(kWhite);
2971 c->cd();
2972
2973 Camera *cam = new Camera;
2974 cam->SetBit(kCanDelete);
2975 cam->Draw();
2976
2977 ChoosePixel(*cam, 0);
2978
2979 // --------------------------------------------------------------------------
2980
2981 c = fAdcDataCanv->GetCanvas();
2982 //c->SetBit(TCanvas::kNoContextMenu);
2983 c->SetBorderMode(0);
2984 c->SetFrameBorderMode(0);
2985 c->SetFillColor(kWhite);
2986 c->SetGrid();
2987 c->cd();
2988
2989 // Create histogram?
2990
2991 // --------------------------------------------------------------------------
2992
2993// QTimer::singleShot(0, this, SLOT(slot_RootUpdate()));
2994
2995 //widget->setMouseTracking(true);
2996 //widget->EnableSignalEvents(kMouseMoveEvent);
2997
2998 fFtmRateCanv->setMouseTracking(true);
2999 fFtmRateCanv->EnableSignalEvents(kMouseMoveEvent);
3000
3001 fAdcDataCanv->setMouseTracking(true);
3002 fAdcDataCanv->EnableSignalEvents(kMouseMoveEvent);
3003
3004 fRatesCanv->setMouseTracking(true);
3005 fRatesCanv->EnableSignalEvents(kMouseMoveEvent|kMouseReleaseEvent|kMouseDoubleClickEvent);
3006
3007 connect(fRatesCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)),
3008 this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*)));
3009 connect(fFtmRateCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)),
3010 this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*)));
3011 connect(fAdcDataCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)),
3012 this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*)));
3013#endif
3014 }
3015
3016 ~FactGui()
3017 {
3018 // Unsubscribe all services
3019 for (map<string,DimInfo*>::iterator i=fServices.begin();
3020 i!=fServices.end(); i++)
3021 delete i->second;
3022
3023 delete fEventData;
3024 }
3025};
3026
3027#endif
Note: See TracBrowser for help on using the repository browser.