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

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