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

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