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

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