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

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