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

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