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

Last change on this file since 11164 was 11159, checked in by tbretz, 14 years ago
Updated display of version number; display ethernet rate in kB/s
File size: 76.6 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
23#include "TROOT.h"
24#include "TSystem.h"
25#include "TGraph.h"
26#include "TH1.h"
27#include "TStyle.h"
28#include "TMarker.h"
29#include "TColor.h"
30
31using namespace std;
32
33// #########################################################################
34
35class Camera : public TObject
36{
37 typedef pair<double,double> Position;
38 typedef vector<Position> Positions;
39
40 Positions fGeom;
41
42 void CreatePalette()
43 {
44 /*
45 double ss[5] = {0., 0.10, 0.45, 0.75, 1.00};
46 double rr[5] = {0., 0.35, 0.85, 1.00, 1.00};
47 double gg[5] = {0., 0.10, 0.20, 0.73, 1.00};
48 double bb[5] = {0., 0.03, 0.06, 0.00, 1.00};
49 */
50 double ss[5] = {0.00, 0.25, 0.50, 0.75, 1.00};
51 double rr[5] = {0.15, 0.00, 0.00, 1.00, 0.85};
52 double gg[5] = {0.15, 0.00, 1.00, 0.00, 0.85};
53 double bb[5] = {0.15, 1.00, 0.00, 0.00, 0.85};
54
55 const Int_t nn = 1440;
56
57 Int_t idx = TColor::CreateGradientColorTable(5, ss, rr, gg, bb, nn);
58 for (int i=0; i<nn; i++)
59 fPalette.push_back(idx++);
60 }
61
62 void CreateGeometry()
63 {
64 const double gsSin60 = sqrt(3.)/2;
65
66 const int rings = 23;
67
68 // add the first pixel to the list
69
70 fGeom.push_back(make_pair(0, -0.5));
71
72 for (int ring=1; ring<=rings; ring++)
73 {
74 for (int s=0; s<6; s++)
75 {
76 for (int i=1; i<=ring; i++)
77 {
78 double xx, yy;
79 switch (s)
80 {
81 case 0: // Direction South East
82 xx = (ring+i)*0.5;
83 yy = (-ring+i)*gsSin60;
84 break;
85
86 case 1: // Direction North East
87 xx = ring-i*0.5;
88 yy = i*gsSin60;
89 break;
90
91 case 2: // Direction North
92 xx = ring*0.5-i;
93 yy = ring*gsSin60;
94 break;
95
96 case 3: // Direction North West
97 xx = -(ring+i)*0.5;
98 yy = (ring-i)*gsSin60;
99 break;
100
101 case 4: // Direction South West
102 xx = 0.5*i-ring;
103 yy = -i*gsSin60;
104 break;
105
106 case 5: // Direction South
107 xx = i-ring*0.5;
108 yy = -ring*gsSin60;
109 break;
110 }
111
112 if (xx*xx + yy*yy - xx > 395.75)
113 continue;
114
115 fGeom.push_back(make_pair(yy, xx-0.5));
116 }
117 }
118 }
119 }
120
121 valarray<double> fData;
122 vector<bool> fBold;
123 vector<bool> fEnable;
124
125 int fWhite;
126
127public:
128 Camera() : fData(1440), fBold(1440), fEnable(1440), fWhite(-1)
129 {
130 CreatePalette();
131 CreateGeometry();
132
133 for (int i=0; i<1440; i++)
134 {
135 fData[i] = i;
136 fBold[i]=false;
137 fEnable[i]=true;
138 }
139 }
140
141 void Reset() { fBold.assign(1440, false); }
142
143 void SetBold(int idx) { fBold[idx]=true; }
144 void SetWhite(int idx) { fWhite=idx; }
145 void SetEnable(int idx, bool b) { fEnable[idx]=b; }
146 void Toggle(int idx) { fEnable[idx]=!fEnable[idx]; }
147 double GetData(int idx) const { return fData[idx]; }
148
149 const char *GetName() const { return "Camera"; }
150
151 vector<Int_t> fPalette;
152
153 void Paint(const Position &p)
154 {
155 static const Double_t fgCos60 = 0.5; // TMath::Cos(60/TMath::RadToDeg());
156 static const Double_t fgSin60 = sqrt(3.)/2; // TMath::Sin(60/TMath::RadToDeg());
157
158 static const Double_t fgDy[6] = { fgCos60, 0., -fgCos60, -fgCos60, 0., fgCos60 };
159 static const Double_t fgDx[6] = { fgSin60/3, fgSin60*2/3, fgSin60/3, -fgSin60/3, -fgSin60*2/3, -fgSin60/3 };
160
161 //
162 // calculate the positions of the pixel corners
163 //
164 Double_t x[7], y[7];
165 for (Int_t i=0; i<7; i++)
166 {
167 x[i] = p.first + fgDx[i%6];
168 y[i] = p.second + fgDy[i%6];
169 }
170
171 gPad->PaintFillArea(6, x, y);
172 gPad->PaintPolyLine(7, x, y);
173
174 }
175
176 double align(double min, double val, double max) const
177 {
178 if (val<min)
179 return min;
180 if (val>max)
181 return max;
182 return val;
183 }
184
185 void Paint(Option_t *)
186 {
187 gStyle->SetPalette(fPalette.size(), fPalette.data());
188
189 const double r = double(gPad->GetWw())/gPad->GetWh();
190 const double max = 20.5; // 20.5 rings in x and y
191
192 if (r>1)
193 gPad->Range(-r*max, -max, r*max, max);
194 else
195 gPad->Range(-max, -max/r, max, max/r);
196
197 Double_t x1, x2, y1, y2;
198 gPad->GetRange(x1, x2, y1, y2);
199
200 double dmin = fData[0];
201 double dmax = fData[0];
202
203 for (unsigned int i=0; i<fData.size(); i++)
204 {
205 if (!fEnable[i])
206 continue;
207
208 if (fData[i]>dmax)
209 dmax = fData[i];
210 if (fData[i]<dmin)
211 dmin = fData[i];
212 }
213
214 const double min = dmin;
215 const double scale = dmax==dmin ? 1 : dmax-dmin;
216
217 TAttFill fill(0, 1001);
218 TAttLine line;
219
220 int cnt=0;
221 for (Positions::iterator p=fGeom.begin(); p!=fGeom.end(); p++, cnt++)
222 {
223 if (fBold[cnt])
224 continue;
225
226 const double val = align(dmin, fData[cnt], dmax);
227
228 const int col = (val-min)/scale*(fPalette.size()-1);
229
230 if (fEnable[cnt])
231 fill.SetFillColor(gStyle->GetColorPalette(col));
232 else
233 fill.SetFillColor(kWhite);
234
235 fill.Modify();
236
237 Paint(*p);
238 }
239
240 line.SetLineWidth(2);
241 line.Modify();
242
243 cnt = 0;
244 for (Positions::iterator p=fGeom.begin(); p!=fGeom.end(); p++, cnt++)
245 {
246 if (!fBold[cnt])
247 continue;
248
249 const double val = align(dmin, fData[cnt], dmax);
250
251 const int col = (val-min)/scale*(fPalette.size()-1);
252
253 if (fEnable[cnt])
254 fill.SetFillColor(gStyle->GetColorPalette(col));
255 else
256 fill.SetFillColor(kWhite);
257 fill.Modify();
258
259 Paint(*p);
260 }
261
262 TMarker m(0,0,kStar);
263 m.DrawMarker(0, 0);
264
265 if (fWhite<0)
266 return;
267
268 const Position &p = fGeom[fWhite];
269
270 line.SetLineColor(kWhite);
271 line.Modify();
272
273 const double val = align(dmin, fData[fWhite], dmax);
274
275 const int col = (val-min)/scale*(fPalette.size()-1);
276
277 if (fEnable[fWhite])
278 fill.SetFillColor(gStyle->GetColorPalette(col));
279 else
280 fill.SetFillColor(kWhite);
281 fill.Modify();
282
283 Paint(p);
284 }
285
286 int GetIdx(float px, float py) const
287 {
288 static const double sqrt3 = sqrt(3);
289
290 int idx = 0;
291 for (Positions::const_iterator p=fGeom.begin(); p!=fGeom.end(); p++, idx++)
292 {
293 const Double_t dy = py - p->second;
294 if (fabs(dy)>0.5)
295 continue;
296
297 const Double_t dx = px - p->first;
298
299 if (TMath::Abs(dy + dx*sqrt3) > 1)
300 continue;
301
302 if (TMath::Abs(dy - dx*sqrt3) > 1)
303 continue;
304
305 return idx;
306 }
307 return -1;
308 }
309
310 char *GetObjectInfo(Int_t px, Int_t py) const
311 {
312 static stringstream stream;
313 static string str;
314
315 const float x = gPad->AbsPixeltoX(px);
316 const float y = gPad->AbsPixeltoY(py);
317
318 const int idx = GetIdx(x, y);
319
320 stream.seekp(0);
321 if (idx>=0)
322 {
323 stream << "Pixel=" << idx << " Data=" << fData[idx] << '\0';
324 }
325
326 str = stream.str();
327 return const_cast<char*>(str.c_str());
328 }
329
330 Int_t DistancetoPrimitive(Int_t px, Int_t py)
331 {
332 const float x = gPad->AbsPixeltoX(px);
333 const float y = gPad->AbsPixeltoY(py);
334
335 return GetIdx(x, y)>=0 ? 0 : 99999;
336 }
337
338 void SetData(const valarray<double> &data)
339 {
340 fData = data;
341 }
342};
343
344// #########################################################################
345
346
347class FactGui : public MainWindow, public DimNetwork
348{
349private:
350 class FunctionEvent : public QEvent
351 {
352 public:
353 boost::function<void(const QEvent &)> fFunction;
354
355 FunctionEvent(const boost::function<void(const QEvent &)> &f)
356 : QEvent((QEvent::Type)QEvent::registerEventType()),
357 fFunction(f) { }
358
359 bool Exec() { fFunction(*this); return true; }
360 };
361
362 valarray<int8_t> fFtuStatus;
363
364 vector<int> fPixelMapHW; // Software -> Hardware
365 vector<int> fPatchMapHW; // Software -> Hardware
366 vector<int> fPatchHW; // Maps the software(!) pixel id to the hardware(!) patch id
367
368 bool fInChoosePatch; // FIXME. Find a better solution
369
370 DimStampedInfo fDimDNS;
371
372 DimStampedInfo fDimLoggerStats;
373 DimStampedInfo fDimLoggerFilenameNight;
374 DimStampedInfo fDimLoggerFilenameRun;
375 DimStampedInfo fDimLoggerNumSubs;
376
377 DimStampedInfo fDimFtmPassport;
378 DimStampedInfo fDimFtmTriggerCounter;
379 DimStampedInfo fDimFtmError;
380 DimStampedInfo fDimFtmFtuList;
381 DimStampedInfo fDimFtmStaticData;
382 DimStampedInfo fDimFtmDynamicData;
383 DimStampedInfo fDimFtmCounter;
384
385 DimStampedInfo fDimFadFiles;
386 DimStampedInfo fDimFadRuns;
387 DimStampedInfo fDimFadEvents;
388 DimStampedInfo fDimFadCurrentEvent;
389 DimStampedInfo fDimFadEventData;
390 DimStampedInfo fDimFadConnections;
391 DimStampedInfo fDimFadFwVersion;
392 DimStampedInfo fDimFadStatistics;
393
394 map<string, DimInfo*> fServices;
395
396 // ========================== LED Colors ================================
397
398 enum LedColor_t
399 {
400 kLedRed,
401 kLedGreen,
402 kLedYellow,
403 kLedOrange,
404 kLedGray
405 };
406
407 void SetLedColor(QPushButton *button, LedColor_t col, const Time &t)
408 {
409 switch (col)
410 {
411 case kLedRed:
412 button->setIcon(QIcon(":/Resources/icons/red circle 1.png"));
413 break;
414
415 case kLedGreen:
416 button->setIcon(QIcon(":/Resources/icons/green circle 1.png"));
417 break;
418
419 case kLedYellow:
420 button->setIcon(QIcon(":/Resources/icons/yellow circle 1.png"));
421 break;
422
423 case kLedOrange:
424 button->setIcon(QIcon(":/Resources/icons/orange circle 1.png"));
425 break;
426
427 case kLedGray:
428 button->setIcon(QIcon(":/Resources/icons/gray circle 1.png"));
429 break;
430 }
431
432 //button->setToolTip("Last change: "+QDateTime::currentDateTimeUtc().toString()+" UTC");
433 button->setToolTip(("Last change: "+t.GetAsStr()+" UTC").c_str());
434 }
435
436 // ===================== Services and Commands ==========================
437
438 QStandardItem *AddServiceItem(const std::string &server, const std::string &service, bool iscmd)
439 {
440 QListView *servers = iscmd ? fDimCmdServers : fDimSvcServers;
441 QListView *services = iscmd ? fDimCmdCommands : fDimSvcServices;
442 QListView *description = iscmd ? fDimCmdDescription : fDimSvcDescription;
443
444 QStandardItemModel *m = dynamic_cast<QStandardItemModel*>(servers->model());
445 if (!m)
446 {
447 m = new QStandardItemModel(this);
448 servers->setModel(m);
449 services->setModel(m);
450 description->setModel(m);
451 }
452
453 QList<QStandardItem*> l = m->findItems(server.c_str());
454
455 if (l.size()>1)
456 {
457 cout << "hae" << endl;
458 return 0;
459 }
460
461 QStandardItem *col = l.size()==0 ? NULL : l[0];
462
463 if (!col)
464 {
465 col = new QStandardItem(server.c_str());
466 m->appendRow(col);
467
468 if (!services->rootIndex().isValid())
469 {
470 services->setRootIndex(col->index());
471 servers->setCurrentIndex(col->index());
472 }
473 }
474
475 QStandardItem *item = 0;
476 for (int i=0; i<col->rowCount(); i++)
477 {
478 QStandardItem *coli = col->child(i);
479 if (coli->text().toStdString()==service)
480 return coli;
481 }
482
483 item = new QStandardItem(service.c_str());
484 col->appendRow(item);
485 col->sortChildren(0);
486
487 if (!description->rootIndex().isValid())
488 {
489 description->setRootIndex(item->index());
490 services->setCurrentIndex(item->index());
491 }
492
493 if (!iscmd)
494 item->setCheckable(true);
495
496 return item;
497 }
498
499 void AddDescription(QStandardItem *item, const vector<Description> &vec)
500 {
501 if (!item)
502 return;
503 if (vec.size()==0)
504 return;
505
506 item->setToolTip(vec[0].comment.c_str());
507
508 const string str = Description::GetHtmlDescription(vec);
509
510 QStandardItem *desc = new QStandardItem(str.c_str());
511 desc->setSelectable(false);
512 item->setChild(0, 0, desc);
513 }
514
515 void AddServer(const std::string &s)
516 {
517 DimNetwork::AddServer(s);
518
519 QApplication::postEvent(this,
520 new FunctionEvent(boost::bind(&FactGui::handleAddServer, this, s)));
521 }
522
523 void RemoveServer(const std::string &s)
524 {
525 UnsubscribeServer(s);
526
527 DimNetwork::RemoveServer(s);
528
529 QApplication::postEvent(this,
530 new FunctionEvent(boost::bind(&FactGui::handleRemoveServer, this, s)));
531 }
532
533 void RemoveAllServers()
534 {
535 UnsubscribeAllServers();
536
537 vector<string> v = GetServerList();
538 for (vector<string>::iterator i=v.begin(); i<v.end(); i++)
539 QApplication::postEvent(this,
540 new FunctionEvent(boost::bind(&FactGui::handleStateOffline, this, *i)));
541
542 DimNetwork::RemoveAllServers();
543
544 QApplication::postEvent(this,
545 new FunctionEvent(boost::bind(&FactGui::handleRemoveAllServers, this)));
546 }
547
548 void AddService(const std::string &server, const std::string &service, const std::string &fmt, bool iscmd)
549 {
550 QApplication::postEvent(this,
551 new FunctionEvent(boost::bind(&FactGui::handleAddService, this, server, service, fmt, iscmd)));
552 }
553
554 void RemoveService(const std::string &server, const std::string &service, bool iscmd)
555 {
556 if (fServices.find(server+'/'+service)!=fServices.end())
557 UnsubscribeService(server+'/'+service);
558
559 QApplication::postEvent(this,
560 new FunctionEvent(boost::bind(&FactGui::handleRemoveService, this, server, service, iscmd)));
561 }
562
563 void RemoveAllServices(const std::string &server)
564 {
565 UnsubscribeServer(server);
566
567 QApplication::postEvent(this,
568 new FunctionEvent(boost::bind(&FactGui::handleRemoveAllServices, this, server)));
569 }
570
571 void AddDescription(const std::string &server, const std::string &service, const vector<Description> &vec)
572 {
573 QApplication::postEvent(this,
574 new FunctionEvent(boost::bind(&FactGui::handleAddDescription, this, server, service, vec)));
575 }
576
577 // ======================================================================
578
579 void handleAddServer(const std::string &server)
580 {
581 const State s = GetState(server, GetCurrentState(server));
582 handleStateChanged(Time(), server, s);
583 }
584
585 void handleRemoveServer(const string &server)
586 {
587 handleStateOffline(server);
588 handleRemoveAllServices(server);
589 }
590
591 void handleRemoveAllServers()
592 {
593 QStandardItemModel *m = 0;
594 if ((m=dynamic_cast<QStandardItemModel*>(fDimCmdServers->model())))
595 m->removeRows(0, m->rowCount());
596
597 if ((m = dynamic_cast<QStandardItemModel*>(fDimSvcServers->model())))
598 m->removeRows(0, m->rowCount());
599 }
600
601 void handleAddService(const std::string &server, const std::string &service, const std::string &/*fmt*/, bool iscmd)
602 {
603 QStandardItem *item = AddServiceItem(server, service, iscmd);
604 const vector<Description> v = GetDescription(server, service);
605 AddDescription(item, v);
606 }
607
608 void handleRemoveService(const std::string &server, const std::string &service, bool iscmd)
609 {
610 QListView *servers = iscmd ? fDimCmdServers : fDimSvcServers;
611
612 QStandardItemModel *m = dynamic_cast<QStandardItemModel*>(servers->model());
613 if (!m)
614 return;
615
616 QList<QStandardItem*> l = m->findItems(server.c_str());
617 if (l.size()!=1)
618 return;
619
620 for (int i=0; i<l[0]->rowCount(); i++)
621 {
622 QStandardItem *row = l[0]->child(i);
623 if (row->text().toStdString()==service)
624 {
625 l[0]->removeRow(row->index().row());
626 return;
627 }
628 }
629 }
630
631 void handleRemoveAllServices(const std::string &server)
632 {
633 QStandardItemModel *m = 0;
634 if ((m=dynamic_cast<QStandardItemModel*>(fDimCmdServers->model())))
635 {
636 QList<QStandardItem*> l = m->findItems(server.c_str());
637 if (l.size()==1)
638 m->removeRow(l[0]->index().row());
639 }
640
641 if ((m = dynamic_cast<QStandardItemModel*>(fDimSvcServers->model())))
642 {
643 QList<QStandardItem*> l = m->findItems(server.c_str());
644 if (l.size()==1)
645 m->removeRow(l[0]->index().row());
646 }
647 }
648
649 void handleAddDescription(const std::string &server, const std::string &service, const vector<Description> &vec)
650 {
651 const bool iscmd = IsCommand(server, service)==true;
652
653 QStandardItem *item = AddServiceItem(server, service, iscmd);
654 AddDescription(item, vec);
655 }
656
657 // ======================================================================
658
659 void SubscribeService(const string &service)
660 {
661 if (fServices.find(service)!=fServices.end())
662 {
663 cout << "ERROR - We are already subscribed to " << service << endl;
664 return;
665 }
666
667 fServices[service] = new DimStampedInfo(service.c_str(), (void*)NULL, 0, this);
668 }
669
670 void UnsubscribeService(const string &service)
671 {
672 const map<string,DimInfo*>::iterator i=fServices.find(service);
673
674 if (i==fServices.end())
675 {
676 cout << "ERROR - We are not subscribed to " << service << endl;
677 return;
678 }
679
680 delete i->second;
681
682 fServices.erase(i);
683 }
684
685 void UnsubscribeServer(const string &server)
686 {
687 for (map<string,DimInfo*>::iterator i=fServices.begin();
688 i!=fServices.end(); i++)
689 if (i->first.substr(0, server.length()+1)==server+'/')
690 {
691 delete i->second;
692 fServices.erase(i);
693 }
694 }
695
696 void UnsubscribeAllServers()
697 {
698 for (map<string,DimInfo*>::iterator i=fServices.begin();
699 i!=fServices.end(); i++)
700 delete i->second;
701
702 fServices.clear();
703 }
704
705 // ======================================================================
706
707 struct DimData
708 {
709 const int qos;
710 const string name;
711 const string format;
712 const vector<char> data;
713 const Time time;
714
715 Time extract(DimInfo *inf) const
716 {
717 // Must be called in exactly this order!
718 const int tsec = inf->getTimestamp();
719 const int tms = inf->getTimestampMillisecs();
720
721 return Time(tsec, tms*1000);
722 }
723
724// DimInfo *info; // this is ONLY for a fast check of the type of the DimData!!
725
726 DimData(DimInfo *inf) :
727 qos(inf->getQuality()),
728 name(inf->getName()),
729 format(inf->getFormat()),
730 data(inf->getString(), inf->getString()+inf->getSize()),
731 time(extract(inf))/*,
732 info(inf)*/
733 {
734 }
735
736 template<typename T>
737 T get(uint32_t offset=0) const { return *reinterpret_cast<const T*>(data.data()+offset); }
738
739 template<typename T>
740 const T *ptr(uint32_t offset=0) const { return reinterpret_cast<const T*>(data.data()+offset); }
741
742 template<typename T>
743 const T &ref(uint32_t offset=0) const { return *reinterpret_cast<const T*>(data.data()+offset); }
744
745// vector<char> vec(int b) const { return vector<char>(data.begin()+b, data.end()); }
746// string str(unsigned int b) const { return b>=data.size()?string():string(data.data()+b, data.size()-b); }
747 const char *c_str() const { return (char*)data.data(); }
748/*
749 vector<boost::any> any() const
750 {
751 const Converter conv(format);
752 conv.Print();
753 return conv.GetAny(data.data(), data.size());
754 }*/
755 size_t size() const { return data.size(); }
756 };
757
758 // ======================= DNS ==========================================
759
760 void handleDimDNS(const DimData &d)
761 {
762 const int version = d.size()!=4 ? 0 : d.get<uint32_t>();
763
764 ostringstream str;
765 str << "V" << version/100 << 'r' << version%100;
766
767 SetLedColor(fStatusDNSLed, version==0 ? kLedRed : kLedGreen, Time());
768
769 fStatusDNSLabel->setText(version==0?"Offline":str.str().c_str());
770 fStatusDNSLabel->setToolTip(version==0?"No connection to DIM DNS.":"Connection to DIM DNS established.");
771 }
772
773
774 // ======================= Logger =======================================
775
776 void handleLoggerStats(const DimData &d)
777 {
778 const bool connected = d.size()!=0;
779
780 fLoggerET->setEnabled(connected);
781 fLoggerRate->setEnabled(connected);
782 fLoggerWritten->setEnabled(connected);
783 fLoggerFreeSpace->setEnabled(connected);
784 fLoggerSpaceLeft->setEnabled(connected);
785
786 if (!connected)
787 return;
788
789 const uint64_t *vals = d.ptr<uint64_t>();
790
791 const size_t written = vals[0];
792 const size_t space = vals[1];
793 const size_t rate = vals[2];
794
795 fLoggerFreeSpace->setSuffix(" MB");
796 fLoggerFreeSpace->setDecimals(0);
797 fLoggerFreeSpace->setValue(space*1e-6);
798
799 if (space> 1000000) // > 1GB
800 {
801 fLoggerFreeSpace->setSuffix(" GB");
802 fLoggerFreeSpace->setDecimals(2);
803 fLoggerFreeSpace->setValue(space*1e-9);
804 }
805 if (space>= 3000000) // >= 3GB
806 {
807 fLoggerFreeSpace->setSuffix(" GB");
808 fLoggerFreeSpace->setDecimals(1);
809 fLoggerFreeSpace->setValue(space*1e-9);
810 }
811 if (space>=100000000) // >= 100GB
812 {
813 fLoggerFreeSpace->setSuffix(" GB");
814 fLoggerFreeSpace->setDecimals(0);
815 fLoggerFreeSpace->setValue(space*1e-9);
816 }
817
818 fLoggerET->setTime(QTime().addSecs(rate>0?space/rate:0));
819 fLoggerRate->setValue(rate*1e-3); // kB/s
820 fLoggerWritten->setValue(written*1e-6);
821
822 fLoggerRate->setSuffix(" kB/s");
823 fLoggerRate->setDecimals(2);
824 fLoggerRate->setValue(rate*1e-3);
825 if (rate> 2000) // > 2kB/s
826 {
827 fLoggerRate->setSuffix(" kB/s");
828 fLoggerRate->setDecimals(1);
829 fLoggerRate->setValue(rate*1e-3);
830 }
831 if (rate>=100000) // >100kB/s
832 {
833 fLoggerRate->setSuffix(" kB/s");
834 fLoggerRate->setDecimals(0);
835 fLoggerRate->setValue(rate*1e-3);
836 }
837 if (rate>=1000000) // >100kB/s
838 {
839 fLoggerRate->setSuffix(" MB/s");
840 fLoggerRate->setDecimals(2);
841 fLoggerRate->setValue(rate*1e-6);
842 }
843 if (rate>=10000000) // >1MB/s
844 {
845 fLoggerRate->setSuffix(" MB/s");
846 fLoggerRate->setDecimals(1);
847 fLoggerRate->setValue(rate*1e-6);
848 }
849 if (rate>=100000000) // >10MB/s
850 {
851 fLoggerRate->setSuffix(" MB/s");
852 fLoggerRate->setDecimals(0);
853 fLoggerRate->setValue(rate*1e-6);
854 }
855
856 if (space/1000000>static_cast<size_t>(fLoggerSpaceLeft->maximum()))
857 fLoggerSpaceLeft->setValue(fLoggerSpaceLeft->maximum()); // GB
858 else
859 fLoggerSpaceLeft->setValue(space/1000000); // MB
860 }
861
862 void handleLoggerFilenameNight(const DimData &d)
863 {
864 const bool connected = d.size()!=0;
865
866 fLoggerFilenameNight->setEnabled(connected);
867 if (!connected)
868 return;
869
870 fLoggerFilenameNight->setText(d.c_str()+4);
871
872 const uint32_t files = d.get<uint32_t>();
873
874 SetLedColor(fLoggerLedLog, files&1 ? kLedGreen : kLedGray, d.time);
875 SetLedColor(fLoggerLedRep, files&2 ? kLedGreen : kLedGray, d.time);
876 SetLedColor(fLoggerLedFits, files&4 ? kLedGreen : kLedGray, d.time);
877 }
878
879 void handleLoggerFilenameRun(const DimData &d)
880 {
881 const bool connected = d.size()!=0;
882
883 fLoggerFilenameRun->setEnabled(connected);
884 if (!connected)
885 return;
886
887 fLoggerFilenameRun->setText(d.c_str()+4);
888
889 const uint32_t files = d.get<uint32_t>();
890
891 SetLedColor(fLoggerLedLog, files&1 ? kLedGreen : kLedGray, d.time);
892 SetLedColor(fLoggerLedRep, files&2 ? kLedGreen : kLedGray, d.time);
893 SetLedColor(fLoggerLedFits, files&4 ? kLedGreen : kLedGray, d.time);
894 }
895
896 void handleLoggerNumSubs(const DimData &d)
897 {
898 const bool connected = d.size()!=0;
899
900 fLoggerSubscriptions->setEnabled(connected);
901 fLoggerOpenFiles->setEnabled(connected);
902 if (!connected)
903 return;
904
905 const uint32_t *vals = d.ptr<uint32_t>();
906
907 fLoggerSubscriptions->setValue(vals[0]);
908 fLoggerOpenFiles->setValue(vals[1]);
909 }
910
911
912 // ===================== All ============================================
913
914 bool CheckSize(const DimData &d, size_t sz) const
915 {
916 if (d.size()==0)
917 return false;
918
919 if (d.size()!=sz)
920 {
921 cout << "Size mismatch in " << d.name << ": Found=" << d.size() << " Expected=" << sz << endl;
922 return false;
923 }
924
925 return true;
926 }
927
928 // ===================== FAD ============================================
929
930 void handleFadFiles(const DimData &d)
931 {
932 if (!CheckSize(d, 8))
933 return;
934
935 fEvtBuilderOpenFiles->setValue(d.get<uint64_t>());
936 }
937
938 void handleFadRuns(const DimData &d)
939 {
940 if (!CheckSize(d, 4))
941 return;
942
943 fEvtsRunMax->setValue(d.get<uint32_t>());
944 }
945
946 void handleFadEvents(const DimData &d)
947 {
948 if (!CheckSize(d, 8))
949 return;
950
951 const uint32_t *ptr = d.ptr<uint32_t>();
952
953 fEvtsSuccessCurRun->setValue(ptr[0]);
954 fEvtsSuccessTotal->setValue(ptr[1]);
955 }
956
957 void handleFadCurrentEvent(const DimData &d)
958 {
959 if (!CheckSize(d, 4))
960 return;
961
962 fEvtsEventId->setValue(d.get<uint32_t>());
963 }
964
965 struct DimEventData
966 {
967 uint16_t Roi ; // #slices per pixel (same for all pixels and tmarks)
968 uint32_t EventNum ; // EventNumber as from FTM
969 uint16_t TriggerType ; // Trigger Type from FTM
970
971 uint32_t PCTime ; // when did event start to arrive at PC
972 uint32_t BoardTime; //
973
974 int16_t StartPix; // First Channel per Pixel (Pixels sorted according Software ID) ; -1 if not filled
975 int16_t StartTM; // First Channel for TimeMark (sorted Hardware ID) ; -1 if not filled
976
977 uint16_t Adc_Data[]; // final length defined by malloc ....
978
979 } __attribute__((__packed__));;
980
981 void handleFadEventData(const DimData &d)
982 {
983 if (d.size()==0)
984 return;
985
986#ifdef HAVE_ROOT
987 const DimEventData &dat = d.ref<DimEventData>();
988
989 if (d.size()<sizeof(DimEventData))
990 {
991 cout << "Size mismatch in " << d.name << ": Found=" << d.size() << " Expected=" << sizeof(DimEventData) << endl;
992 return;
993 }
994
995 if (d.size()!=dat.Roi*2+sizeof(DimEventData))
996 {
997 cout << "Size mismatch in " << d.name << ": Found=" << d.size() << " Expected=" << dat.Roi*2+sizeof(DimEventData) << endl;
998 return;
999 }
1000
1001 TCanvas *c = fAdcDataCanv->GetCanvas();
1002
1003 TH1 *h = dynamic_cast<TH1*>(c->FindObject("EventData"));
1004 if (h && h->GetNbinsX()!=dat.Roi)
1005 {
1006 delete h;
1007 h = 0;
1008 }
1009
1010 if (!h)
1011 {
1012 c->cd();
1013
1014 TH1D hist("EventData", "", dat.Roi, -0.5, dat.Roi-0.5);
1015 hist.SetStats(kFALSE);
1016 //hist->SetBit(TH1::kNoTitle);
1017 hist.SetMarkerStyle(kFullDotMedium);
1018 hist.SetYTitle("Voltage [mV]");
1019 hist.GetXaxis()->CenterTitle();
1020 hist.GetYaxis()->CenterTitle();
1021 hist.SetMinimum(-1026);
1022 hist.SetMaximum(1025);
1023 h = hist.DrawCopy("P");
1024 h->SetDirectory(0);
1025 }
1026
1027 ostringstream str;
1028 str << "ADC Pipeline (start=" << dat.StartTM << ")";
1029 h->SetXTitle(str.str().c_str());
1030
1031 //str.str("");
1032 //str << "Crate=" << crate << " Board=" << board << " Channel=" << channel << " [" << d.time() << "]" << endl;
1033 //hist->SetTitle(str.str().c_str());
1034
1035 for (int i=0; i<dat.Roi; i++)
1036 h->SetBinContent(i+1, dat.Adc_Data[i]*0.5-1024);
1037
1038 c->Modified();
1039 c->Update();
1040#endif
1041 }
1042
1043 vector<uint8_t> fFadConnections;
1044
1045 void handleFadConnections(const DimData &d)
1046 {
1047 if (!CheckSize(d, 41))
1048 return;
1049
1050 const uint8_t *ptr = d.ptr<uint8_t>();
1051
1052 for (int i=0; i<40; i++)
1053 {
1054 switch (ptr[i])
1055 {
1056 case 0: SetLedColor(fFadLED[i], kLedGray, d.time); break;
1057 case 9: SetLedColor(fFadLED[i], kLedGreen, d.time); break;
1058 default: SetLedColor(fFadLED[i], kLedOrange, d.time);
1059 }
1060 }
1061
1062 SetLedColor(fFadLEDEventBuilder, ptr[40]==0?kLedRed:kLedGreen, d.time);
1063
1064 fFadConnections.assign(ptr, ptr+40);
1065 }
1066
1067 template<typename T>
1068 bool CheckConsistency(const T *v)
1069 {
1070 for (int i=1; i<40; i++)
1071 if (fFadConnections[i]==9 && v[i]!=v[0])
1072 return false;
1073
1074 return true;
1075 }
1076
1077 template<typename T>
1078 T GetFirst(const T *v)
1079 {
1080 for (int i=0; i<40; i++)
1081 if (fFadConnections[i]==9)
1082 return v[i];
1083
1084 return T();
1085 }
1086
1087 void handleFadFwVersion(const DimData &d)
1088 {
1089 if (!CheckSize(d, 43*sizeof(float)))
1090 return;
1091
1092 const float *ptr = d.ptr<float>();
1093 fFadFwVersion->setValue(ptr[1]);
1094
1095 ostringstream tip;
1096 tip << "<table border='1'><tr><th colspan='11'>" << Time().GetAsStr() << "</th></tr><tr><th></th>";
1097 for (int b=0; b<10; b++)
1098 tip << "<th>" << b << "</th>";
1099 tip << "</tr>";
1100
1101 for (int c=0; c<4; c++)
1102 {
1103 tip << "<tr><th>" << c << "</th>";
1104 for (int b=0; b<10; b++)
1105 tip << "<td>" << ptr[c*10+b+3] << "</td>";
1106 tip << "</tr>";
1107 }
1108 tip << "</table>";
1109
1110 fFadFwVersion->setToolTip(tip.str().c_str());
1111
1112 SetLedColor(fFadLEDFwVersion, d.qos?kLedGreen:kLedOrange, d.time);
1113 }
1114
1115 void handleFadStatistics(const DimData &d)
1116 {
1117 if (!CheckSize(d, 8*sizeof(int64_t)))
1118 return;
1119
1120 const int64_t *stat = d.ptr<int64_t>();
1121
1122 fFadBufferMax->setValue(stat[0]/1000000);
1123 fFadBuffer->setMaximum(stat[0]);
1124 fFadBuffer->setValue(stat[5]);
1125
1126 fFadEvtWait->setValue(stat[1]);
1127 fFadEvtSkip->setValue(stat[2]);
1128 fFadEvtDel->setValue(stat[3]);
1129 fFadEvtTot->setValue(stat[4]);
1130 fFadEvtRead->setValue(stat[6]/1024.);
1131 fFadEvtConn->setValue(stat[7]);
1132 }
1133
1134
1135 // ===================== FTM ============================================
1136
1137 double fTimeStamp1;
1138
1139 void handleFtmTriggerCounter(const DimData &d)
1140 {
1141 if (!CheckSize(d, sizeof(FTM::DimTriggerCounter)))
1142 return;
1143
1144 const FTM::DimTriggerCounter &sdata = d.ref<FTM::DimTriggerCounter>();
1145
1146 fFtmTime->setText(QString::number(sdata.fTimeStamp/1000000., 'f', 6)+ " s");
1147 fTriggerCounter->setText(QString::number(sdata.fTriggerCounter));
1148
1149 if (sdata.fTimeStamp>0)
1150 fTriggerCounterRate->setValue(1000000.*sdata.fTriggerCounter/sdata.fTimeStamp);
1151 else
1152 fTriggerCounterRate->setValue(0);
1153
1154
1155 // ----------------------------------------------
1156#ifdef HAVE_ROOT
1157
1158 if (fTriggerCounter0<0)
1159 {
1160 fTriggerCounter0 = sdata.fTriggerCounter;
1161 fTimeStamp1 = sdata.fTimeStamp;
1162 return;
1163 }
1164
1165 TCanvas *c = fFtmRateCanv->GetCanvas();
1166
1167 TH1 *h = (TH1*)c->FindObject("TimeFrame");
1168
1169 const double rate = sdata.fTriggerCounter-fTriggerCounter0;
1170 const double tdiff = sdata.fTimeStamp -fTimeStamp1;
1171
1172 fTriggerCounter0 = sdata.fTriggerCounter;
1173 fTimeStamp1 = sdata.fTimeStamp;
1174
1175 if (rate<0 && tdiff<=0)
1176 {
1177 fGraphFtmRate.Set(0);
1178
1179 const double tm = Time().RootTime();
1180
1181 h->SetBins(1, tm, tm+60);
1182 h->GetXaxis()->SetTimeFormat("%M'%S\"");
1183 h->GetXaxis()->SetTitle("Time");
1184
1185 c->Modified();
1186 c->Update();
1187 return;
1188 }
1189
1190 if (rate<0)
1191 return;
1192
1193// const double avgrate = sdata.fTimeStamp>0 ? double(sdata.fTriggerCounter)/sdata.fTimeStamp*1000000 : 1;
1194
1195 const double t1 = h->GetXaxis()->GetXmax();
1196 const double t0 = h->GetXaxis()->GetXmin();
1197
1198 h->SetBins(h->GetNbinsX()+1, t0, t0+sdata.fTimeStamp/1000000.+1);
1199 fGraphFtmRate.SetPoint(fGraphFtmRate.GetN(),
1200 t0+sdata.fTimeStamp/1000000., 1000000*rate/tdiff);
1201
1202 if (t1-t0>60)
1203 {
1204 h->GetXaxis()->SetTimeFormat("%Hh%M'");
1205 h->GetXaxis()->SetTitle("Time");
1206 }
1207
1208 h->SetMinimum(0);
1209// h->SetMaximum(2*avgrate);
1210
1211 c->Modified();
1212 c->Update();
1213#endif
1214 // ----------------------------------------------
1215 }
1216
1217 void handleFtmCounter(const DimData &d)
1218 {
1219 if (!CheckSize(d, sizeof(uint32_t)*6))
1220 return;
1221
1222 const uint32_t *sdata = d.ptr<uint32_t>();
1223
1224 fFtmCounterH->setValue(sdata[0]);
1225 fFtmCounterS->setValue(sdata[1]);
1226 fFtmCounterD->setValue(sdata[2]);
1227 fFtmCounterF->setValue(sdata[3]);
1228 fFtmCounterE->setValue(sdata[4]);
1229 fFtmCounterR->setValue(sdata[5]);
1230 }
1231
1232 int64_t fTriggerCounter0;
1233 int64_t fTimeStamp0;
1234
1235 void handleFtmDynamicData(const DimData &d)
1236 {
1237 if (!CheckSize(d, sizeof(FTM::DimDynamicData)))
1238 return;
1239
1240 const FTM::DimDynamicData &sdata = d.ref<FTM::DimDynamicData>();
1241
1242 fOnTime->setText(QString::number(sdata.fOnTimeCounter/1000000., 'f', 6)+" s");
1243
1244 if (sdata.fTimeStamp>0)
1245 fOnTimeRel->setValue(100.*sdata.fOnTimeCounter/sdata.fTimeStamp);
1246 else
1247 fOnTimeRel->setValue(0);
1248
1249 fFtmTemp0->setValue(sdata.fTempSensor[0]*0.1);
1250 fFtmTemp1->setValue(sdata.fTempSensor[1]*0.1);
1251 fFtmTemp2->setValue(sdata.fTempSensor[2]*0.1);
1252 fFtmTemp3->setValue(sdata.fTempSensor[3]*0.1);
1253
1254
1255#ifdef HAVE_ROOT
1256
1257 // ----------------------------------------------
1258
1259 if (fTimeStamp0<0)
1260 {
1261 fTimeStamp0 = sdata.fTimeStamp;
1262 return;
1263 }
1264
1265 TCanvas *c = fFtmRateCanv->GetCanvas();
1266
1267 TH1 *h = (TH1*)c->FindObject("TimeFrame");
1268
1269 const double tdiff = sdata.fTimeStamp-fTimeStamp0;
1270 fTimeStamp0 = sdata.fTimeStamp;
1271
1272 if (tdiff<0)
1273 {
1274 for (int i=0; i<160; i++)
1275 fGraphPatchRate[i].Set(0);
1276 for (int i=0; i<40; i++)
1277 fGraphBoardRate[i].Set(0);
1278
1279 return;
1280 }
1281
1282 //const double t1 = h->GetXaxis()->GetXmax();
1283 const double t0 = h->GetXaxis()->GetXmin();
1284
1285 for (int i=0; i<160; i++)
1286 fGraphPatchRate[i].SetPoint(fGraphPatchRate[i].GetN(),
1287 t0+sdata.fTimeStamp/1000000., float(sdata.fRatePatch[i])*2/fFtmStaticData.fPrescaling[i]);
1288 for (int i=0; i<40; i++)
1289 fGraphBoardRate[i].SetPoint(fGraphBoardRate[i].GetN(),
1290 t0+sdata.fTimeStamp/1000000., float(sdata.fRateBoard[i])*2/fFtmStaticData.fPrescaling[i]);
1291
1292 c->Modified();
1293 c->Update();
1294
1295 //fGraphFtmRate.ComputeRange(x[0], x[1], x[2], x[3]);
1296
1297 // ----------------------------------------------
1298
1299 if (fThresholdIdx->value()>=0)
1300 {
1301 const int isw = fThresholdIdx->value();
1302 const int ihw = fPatchMapHW[isw];
1303 fPatchRate->setValue(sdata.fRatePatch[ihw]);
1304 }
1305
1306 valarray<double> dat(0., 1440);
1307
1308 // fPatch converts from software id to software patch id
1309 for (int i=0; i<1440; i++)
1310 {
1311 const int ihw = fPatchHW[i];
1312// const int isw = fPatch[i];
1313// const int ihw = fPatchMapHW[isw];
1314 dat[i] = sdata.fRatePatch[ihw];
1315 }
1316
1317 c = fRatesCanv->GetCanvas();
1318 Camera *cam = (Camera*)c->FindObject("Camera");
1319
1320 cam->SetData(dat);
1321
1322 c->Modified();
1323 c->Update();
1324
1325 // ----------------------------------------------
1326#endif
1327 }
1328
1329 void DisplayRates()
1330 {
1331#ifdef HAVE_ROOT
1332 TCanvas *c = fFtmRateCanv->GetCanvas();
1333
1334 while (c->FindObject("PatchRate"))
1335 c->GetListOfPrimitives()->Remove(c->FindObject("PatchRate"));
1336
1337 while (c->FindObject("BoardRate"))
1338 c->GetListOfPrimitives()->Remove(c->FindObject("BoardRate"));
1339
1340 c->cd();
1341
1342 if (fRatePatch1->value()>=0)
1343 {
1344 fGraphPatchRate[fRatePatch1->value()].SetLineColor(kRed);
1345 fGraphPatchRate[fRatePatch1->value()].SetMarkerColor(kRed);
1346 fGraphPatchRate[fRatePatch1->value()].Draw("PL");
1347 }
1348 if (fRatePatch2->value()>=0)
1349 {
1350 fGraphPatchRate[fRatePatch2->value()].SetLineColor(kGreen);
1351 fGraphPatchRate[fRatePatch2->value()].SetMarkerColor(kGreen);
1352 fGraphPatchRate[fRatePatch2->value()].Draw("PL");
1353 }
1354 if (fRateBoard1->value()>=0)
1355 {
1356 fGraphBoardRate[fRateBoard1->value()].SetLineColor(kMagenta);
1357 fGraphBoardRate[fRateBoard1->value()].SetMarkerColor(kMagenta);
1358 fGraphBoardRate[fRateBoard1->value()].Draw("PL");
1359 }
1360 if (fRateBoard2->value()>=0)
1361 {
1362 fGraphBoardRate[fRateBoard2->value()].SetLineColor(kCyan);
1363 fGraphBoardRate[fRateBoard2->value()].SetMarkerColor(kCyan);
1364 fGraphBoardRate[fRateBoard2->value()].Draw("PL");
1365 }
1366#endif
1367 }
1368
1369 void on_fRatePatch1_valueChanged(int)
1370 {
1371 DisplayRates();
1372 }
1373
1374 void on_fRatePatch2_valueChanged(int)
1375 {
1376 DisplayRates();
1377 }
1378
1379 void on_fRateBoard1_valueChanged(int)
1380 {
1381 DisplayRates();
1382 }
1383
1384 void on_fRateBoard2_valueChanged(int)
1385 {
1386 DisplayRates();
1387 }
1388
1389 FTM::DimStaticData fFtmStaticData;
1390
1391 void SetFtuLed(int idx, int counter, const Time &t)
1392 {
1393 if (counter==0 || counter>3)
1394 counter = 3;
1395
1396 if (counter<0)
1397 counter = 0;
1398
1399 const LedColor_t col[4] = { kLedGray, kLedGreen, kLedOrange, kLedRed };
1400
1401 SetLedColor(fFtuLED[idx], col[counter], t);
1402
1403 fFtuStatus[idx] = counter;
1404 }
1405
1406 void SetFtuStatusLed(const Time &t)
1407 {
1408 const int max = fFtuStatus.max();
1409
1410 switch (max)
1411 {
1412 case 0:
1413 SetLedColor(fStatusFTULed, kLedGray, t);
1414 fStatusFTULabel->setText("All disabled");
1415 fStatusFTULabel->setToolTip("All FTUs are disabled");
1416 break;
1417
1418 case 1:
1419 SetLedColor(fStatusFTULed, kLedGreen, t);
1420 fStatusFTULabel->setToolTip("Communication with FTU is smooth.");
1421 fStatusFTULabel->setText("ok");
1422 break;
1423
1424 case 2:
1425 SetLedColor(fStatusFTULed, kLedOrange, t);
1426 fStatusFTULabel->setText("Warning");
1427 fStatusFTULabel->setToolTip("At least one FTU didn't answer immediately");
1428 break;
1429
1430 case 3:
1431 SetLedColor(fStatusFTULed, kLedRed, t);
1432 fStatusFTULabel->setToolTip("At least one FTU didn't answer!");
1433 fStatusFTULabel->setText("ERROR");
1434 break;
1435 }
1436
1437 const int cnt = count(&fFtuStatus[0], &fFtuStatus[40], 0);
1438 fFtuAllOn->setEnabled(cnt!=0);
1439 fFtuAllOff->setEnabled(cnt!=40);
1440 }
1441
1442 void handleFtmStaticData(const DimData &d)
1443 {
1444 if (!CheckSize(d, sizeof(FTM::DimStaticData)))
1445 return;
1446
1447 const FTM::DimStaticData &sdata = d.ref<FTM::DimStaticData>();
1448
1449 fTriggerInterval->setValue(sdata.fTriggerInterval);
1450 fPhysicsCoincidence->setValue(sdata.fMultiplicityPhysics);
1451 fCalibCoincidence->setValue(sdata.fMultiplicityCalib);
1452 fPhysicsWindow->setValue(sdata.fWindowPhysics);
1453 fCalibWindow->setValue(sdata.fWindowCalib);
1454
1455 fTriggerDelay->setValue(sdata.fDelayTrigger);
1456 fTimeMarkerDelay->setValue(sdata.fDelayTimeMarker);
1457 fDeadTime->setValue(sdata.fDeadTime);
1458
1459 fClockCondR0->setValue(sdata.fClockConditioner[0]);
1460 fClockCondR1->setValue(sdata.fClockConditioner[1]);
1461 fClockCondR8->setValue(sdata.fClockConditioner[2]);
1462 fClockCondR9->setValue(sdata.fClockConditioner[3]);
1463 fClockCondR11->setValue(sdata.fClockConditioner[4]);
1464 fClockCondR13->setValue(sdata.fClockConditioner[5]);
1465 fClockCondR14->setValue(sdata.fClockConditioner[6]);
1466 fClockCondR15->setValue(sdata.fClockConditioner[7]);
1467
1468 //fClockCondFreq->setEditText("");
1469 fClockCondFreq->setCurrentIndex(0);
1470
1471 fTriggerSeqPed->setValue(sdata.fTriggerSeqPed);
1472 fTriggerSeqLPint->setValue(sdata.fTriggerSeqLPint);
1473 fTriggerSeqLPext->setValue(sdata.fTriggerSeqLPext);
1474
1475 fEnableTrigger->setChecked(sdata.HasTrigger());
1476 fEnableVeto->setChecked(sdata.HasVeto());
1477 fEnableExt1->setChecked(sdata.HasExt1());
1478 fEnableExt2->setChecked(sdata.HasExt2());
1479 fEnableClockCond->setChecked(sdata.HasClockConditioner());
1480
1481 for (int i=0; i<40; i++)
1482 {
1483 if (!sdata.IsActive(i))
1484 SetFtuLed(i, -1, d.time);
1485 else
1486 {
1487 if (fFtuStatus[i]==0)
1488 SetFtuLed(i, 1, d.time);
1489 }
1490 fFtuLED[i]->setChecked(false);
1491 }
1492 SetFtuStatusLed(d.time);
1493
1494#ifdef HAVE_ROOT
1495 Camera *cam = (Camera*)fRatesCanv->GetCanvas()->FindObject("Camera");
1496 for (int isw=0; isw<1440; isw++)
1497 {
1498 const int ihw = fPixelMapHW[isw];
1499 cam->SetEnable(isw, sdata.IsEnabled(ihw));
1500 }
1501
1502 fRatesCanv->GetCanvas()->Modified();
1503 fRatesCanv->GetCanvas()->Update();
1504#endif
1505
1506 {
1507 const int isw = fPixelIdx->value();
1508 const int ihw = fPixelMapHW[isw];
1509 const bool on = sdata.IsEnabled(ihw);
1510 fPixelEnable->setChecked(on);
1511 }
1512
1513 if (fThresholdIdx->value()>=0)
1514 {
1515 const int isw = fThresholdIdx->value();
1516 const int ihw = fPatchMapHW[isw];
1517 fThresholdVal->setValue(sdata.fThreshold[ihw]);
1518 }
1519
1520 fPrescalingVal->setValue(sdata.fPrescaling[0]);
1521
1522 fFtmStaticData = sdata;
1523 }
1524
1525 void handleFtmPassport(const DimData &d)
1526 {
1527 if (!CheckSize(d, sizeof(FTM::DimPassport)))
1528 return;
1529
1530 const FTM::DimPassport &sdata = d.ref<FTM::DimPassport>();
1531
1532 stringstream str1, str2;
1533 str1 << hex << "0x" << setfill('0') << setw(16) << sdata.fBoardId;
1534 str2 << sdata.fFirmwareId;
1535
1536 fFtmBoardId->setText(str1.str().c_str());
1537 fFtmFirmwareId->setText(str2.str().c_str());
1538 }
1539
1540 void handleFtmFtuList(const DimData &d)
1541 {
1542 if (!CheckSize(d, sizeof(FTM::DimFtuList)))
1543 return;
1544
1545 fFtuPing->setChecked(false);
1546
1547 const FTM::DimFtuList &sdata = d.ref<FTM::DimFtuList>();
1548
1549 stringstream str;
1550 str << "<table width='100%'>" << setfill('0');
1551 str << "<tr><th>Num</th><th></th><th>Addr</th><th></th><th>DNA</th></tr>";
1552 for (int i=0; i<40; i++)
1553 {
1554 str << "<tr>";
1555 str << "<td align='center'>" << dec << i << hex << "</td>";
1556 str << "<td align='center'>:</td>";
1557 str << "<td align='center'>0x" << setw(2) << (int)sdata.fAddr[i] << "</td>";
1558 str << "<td align='center'>:</td>";
1559 str << "<td align='center'>0x" << setw(16) << sdata.fDNA[i] << "</td>";
1560 str << "</tr>";
1561 }
1562 str << "</table>";
1563
1564 fFtuDNA->setText(str.str().c_str());
1565
1566 fFtuAnswersTotal->setValue(sdata.fNumBoards);
1567 fFtuAnswersCrate0->setValue(sdata.fNumBoardsCrate[0]);
1568 fFtuAnswersCrate1->setValue(sdata.fNumBoardsCrate[1]);
1569 fFtuAnswersCrate2->setValue(sdata.fNumBoardsCrate[2]);
1570 fFtuAnswersCrate3->setValue(sdata.fNumBoardsCrate[3]);
1571
1572 for (int i=0; i<40; i++)
1573 SetFtuLed(i, sdata.IsActive(i) ? sdata.fPing[i] : -1, d.time);
1574
1575 SetFtuStatusLed(d.time);
1576 }
1577
1578 void handleFtmError(const DimData &d)
1579 {
1580 if (!CheckSize(d, sizeof(FTM::DimError)))
1581 return;
1582
1583 const FTM::DimError &sdata = d.ref<FTM::DimError>();
1584
1585 SetFtuLed(sdata.fError.fDestAddress , sdata.fError.fNumCalls, d.time);
1586 SetFtuStatusLed(d.time);
1587
1588 // FIXME: Write to special window!
1589 //Out() << "Error:" << endl;
1590 //Out() << sdata.fError << endl;
1591 }
1592
1593 // ====================== MessageImp ====================================
1594
1595 bool fChatOnline;
1596
1597 void handleStateChanged(const Time &time, const std::string &server,
1598 const State &s)
1599 {
1600 // FIXME: Prefix tooltip with time
1601 if (server=="FTM_CONTROL")
1602 {
1603 // FIXME: Enable FTU page!!!
1604 fStatusFTMLabel->setText(s.name.c_str());
1605 fStatusFTMLabel->setToolTip(s.comment.c_str());
1606
1607 bool enable = false;
1608
1609 if (s.index<FTM::kDisconnected) // No Dim connection
1610 SetLedColor(fStatusFTMLed, kLedGray, time);
1611 if (s.index==FTM::kDisconnected) // Dim connection / FTM disconnected
1612 SetLedColor(fStatusFTMLed, kLedYellow, time);
1613 if (s.index==FTM::kConnected || s.index==FTM::kIdle || s.index==FTM::kTakingData) // Dim connection / FTM connected
1614 SetLedColor(fStatusFTMLed, kLedGreen, time);
1615
1616 if (s.index==FTM::kConnected || s.index==FTM::kIdle) // Dim connection / FTM connected
1617 enable = true;
1618
1619 fTriggerWidget->setEnabled(enable);
1620 fFtuWidget->setEnabled(enable);
1621 fRatesWidget->setEnabled(enable);
1622
1623 if (!enable)
1624 {
1625 SetLedColor(fStatusFTULed, kLedGray, time);
1626 fStatusFTULabel->setText("Offline");
1627 fStatusFTULabel->setToolTip("FTM is not online.");
1628 }
1629 }
1630
1631 if (server=="FAD_CONTROL")
1632 {
1633 fStatusFADLabel->setText(s.name.c_str());
1634 fStatusFADLabel->setToolTip(s.comment.c_str());
1635
1636 bool enable = false;
1637
1638 if (s.index<FAD::kDisconnected) // No Dim connection
1639 SetLedColor(fStatusFADLed, kLedGray, time);
1640 if (s.index==FAD::kOffline) // Dim connection / FTM disconnected
1641 SetLedColor(fStatusFADLed, kLedRed, time);
1642 if (s.index==FAD::kDisconnected) // Dim connection / FTM disconnected
1643 SetLedColor(fStatusFADLed, kLedOrange, time);
1644 if (s.index==FAD::kConnecting) // Dim connection / FTM disconnected
1645 {
1646 SetLedColor(fStatusFADLed, kLedYellow, time);
1647 // FIXME FIXME FIXME: The LEDs are not displayed when disabled!
1648 enable = true;
1649 }
1650 if (s.index>=FAD::kConnected) // Dim connection / FTM connected
1651 {
1652 SetLedColor(fStatusFADLed, kLedGreen, time);
1653 enable = true;
1654 }
1655
1656 fFadWidget->setEnabled(enable);
1657 }
1658
1659 if (server=="FSC_CONTROL")
1660 {
1661 fStatusFSCLabel->setText(s.name.c_str());
1662 fStatusFSCLabel->setToolTip(s.comment.c_str());
1663
1664 bool enable = false;
1665
1666 if (s.index<1) // No Dim connection
1667 SetLedColor(fStatusFSCLed, kLedGray, time);
1668 if (s.index==1) // Dim connection / FTM disconnected
1669 SetLedColor(fStatusFSCLed, kLedRed, time);
1670 if (s.index>=2) // Dim connection / FTM disconnected
1671 {
1672 SetLedColor(fStatusFSCLed, kLedGreen, time);
1673 enable = true;
1674 }
1675
1676 //fFscWidget->setEnabled(enable);
1677 }
1678
1679 if (server=="DATA_LOGGER")
1680 {
1681 fStatusLoggerLabel->setText(s.name.c_str());
1682 fStatusLoggerLabel->setToolTip(s.comment.c_str());
1683
1684 bool enable = true;
1685
1686 if (s.index<=30) // Ready/Waiting
1687 SetLedColor(fStatusLoggerLed, kLedYellow, time);
1688 if (s.index<-1) // Offline
1689 {
1690 SetLedColor(fStatusLoggerLed, kLedGray, time);
1691 enable = false;
1692 }
1693 if (s.index>=0x100) // Error
1694 SetLedColor(fStatusLoggerLed, kLedRed, time);
1695 if (s.index==40) // Logging
1696 SetLedColor(fStatusLoggerLed, kLedGreen, time);
1697
1698 fLoggerWidget->setEnabled(enable);
1699 }
1700
1701 if (server=="CHAT")
1702 {
1703 fStatusChatLabel->setText(s.name.c_str());
1704
1705 fChatOnline = s.index==0;
1706
1707 SetLedColor(fStatusChatLed, fChatOnline ? kLedGreen : kLedGray, time);
1708
1709 fChatSend->setEnabled(fChatOnline);
1710 fChatMessage->setEnabled(fChatOnline);
1711 }
1712
1713 if (server=="SCHEDULER")
1714 {
1715 fStatusSchedulerLabel->setText(s.name.c_str());
1716
1717 SetLedColor(fStatusSchedulerLed, s.index>=0 ? kLedGreen : kLedRed, time);
1718 }
1719 }
1720
1721 void handleStateOffline(const string &server)
1722 {
1723 handleStateChanged(Time(), server, State(-2, "Offline", "No connection via DIM."));
1724 }
1725
1726 void on_fTabWidget_currentChanged(int which)
1727 {
1728 if (fTabWidget->tabText(which)=="Chat")
1729 fTabWidget->setTabIcon(which, QIcon());
1730 }
1731
1732 void handleWrite(const Time &time, const string &text, int qos)
1733 {
1734 stringstream out;
1735
1736 if (text.substr(0, 6)=="CHAT: ")
1737 {
1738 if (qos==MessageImp::kDebug)
1739 return;
1740
1741 out << "<font size='-1' color='navy'>[<B>";
1742 out << Time::fmt("%H:%M:%S") << time << "</B>]</FONT> ";
1743 out << text.substr(6);
1744 fChatText->append(out.str().c_str());
1745
1746 if (fTabWidget->tabText(fTabWidget->currentIndex())=="Chat")
1747 return;
1748
1749 static int num = 0;
1750 if (num++<2)
1751 return;
1752
1753 for (int i=0; i<fTabWidget->count(); i++)
1754 if (fTabWidget->tabText(i)=="Chat")
1755 {
1756 fTabWidget->setTabIcon(i, QIcon(":/Resources/icons/warning 3.png"));
1757 break;
1758 }
1759
1760 return;
1761 }
1762
1763
1764 out << "<font style='font-family:monospace' color='";
1765
1766 switch (qos)
1767 {
1768 case kMessage: out << "black"; break;
1769 case kInfo: out << "green"; break;
1770 case kWarn: out << "#FF6600"; break;
1771 case kError: out << "maroon"; break;
1772 case kFatal: out << "maroon"; break;
1773 case kDebug: out << "navy"; break;
1774 default: out << "navy"; break;
1775 }
1776 out << "'>" << time.GetAsStr() << " - " << text << "</font>";
1777
1778 fLogText->append(out.str().c_str());
1779
1780 if (qos>=kWarn)
1781 fTextEdit->append(out.str().c_str());
1782 }
1783
1784 void IndicateStateChange(const Time &time, const std::string &server)
1785 {
1786 const State s = GetState(server, GetCurrentState(server));
1787
1788 QApplication::postEvent(this,
1789 new FunctionEvent(boost::bind(&FactGui::handleStateChanged, this, time, server, s)));
1790 }
1791
1792 int Write(const Time &time, const string &txt, int qos)
1793 {
1794 QApplication::postEvent(this,
1795 new FunctionEvent(boost::bind(&FactGui::handleWrite, this, time, txt, qos)));
1796
1797 return 0;
1798 }
1799
1800 // ====================== Dim infoHandler================================
1801
1802 void handleDimService(const string &txt)
1803 {
1804 fDimSvcText->append(txt.c_str());
1805 }
1806
1807 void infoHandlerService(DimInfo &info)
1808 {
1809 const string fmt = string(info.getFormat()).empty() ? "C" : info.getFormat();
1810
1811 stringstream dummy;
1812 const Converter conv(dummy, fmt, false);
1813
1814 const Time tm(info.getTimestamp(), info.getTimestampMillisecs()*1000);
1815
1816 stringstream out;
1817 out << "<font size'-1' color='navy'>[" << Time::fmt("%H:%M:%S.%f") << tm << "]</font> <B>" << info.getName() << "</B> - ";
1818
1819 bool iserr = true;
1820 if (!conv)
1821 {
1822 out << "Compilation of format string '" << fmt << "' failed!";
1823 }
1824 else
1825 {
1826 try
1827 {
1828 const string dat = conv.GetString(info.getData(), info.getSize());
1829 out << dat;
1830 iserr = false;
1831 }
1832 catch (const runtime_error &e)
1833 {
1834 out << "Conversion to string failed!<pre>" << e.what() << "</pre>";
1835 }
1836 }
1837
1838 // srand(hash<string>()(string(info.getName())));
1839 // int bg = rand()&0xffffff;
1840
1841 int bg = hash<string>()(string(info.getName()));
1842
1843 // allow only light colors
1844 bg = ~(bg&0x1f1f1f)&0xffffff;
1845
1846 if (iserr)
1847 bg = 0xffffff;
1848
1849 stringstream bgcol;
1850 bgcol << hex << setfill('0') << setw(6) << bg;
1851
1852 const string col = iserr ? "red" : "black";
1853 const string str = "<table width='100%' bgcolor=#"+bgcol.str()+"><tr><td><font color='"+col+"'>"+out.str()+"</font></td></tr></table>";
1854
1855 QApplication::postEvent(this,
1856 new FunctionEvent(boost::bind(&FactGui::handleDimService, this, str)));
1857 }
1858
1859 void CallInfoHandler(void (FactGui::*handler)(const DimData&), const DimData &d)
1860 {
1861 fInHandler = true;
1862 (this->*handler)(d);
1863 fInHandler = false;
1864 }
1865
1866 /*
1867 void CallInfoHandler(const boost::function<void()> &func)
1868 {
1869 // This ensures that newly received values are not sent back to the emitter
1870 // because changing the value emits the valueChanged signal (or similar)
1871 fInHandler = true;
1872 func();
1873 fInHandler = false;
1874 }*/
1875
1876 void PostInfoHandler(void (FactGui::*handler)(const DimData&))
1877 {
1878 //const boost::function<void()> f = boost::bind(handler, this, DimData(getInfo()));
1879
1880 FunctionEvent *evt = new FunctionEvent(boost::bind(&FactGui::CallInfoHandler, this, handler, DimData(getInfo())));
1881 // FunctionEvent *evt = new FunctionEvent(boost::bind(&FactGui::CallInfoHandler, this, f));
1882 // FunctionEvent *evt = new FunctionEvent(boost::bind(handler, this, DimData(getInfo()))));
1883
1884 QApplication::postEvent(this, evt);
1885 }
1886
1887 void infoHandler()
1888 {
1889 // Initialize the time-stamp (what a weird workaround...)
1890 if (getInfo())
1891 getInfo()->getTimestamp();
1892
1893 if (getInfo()==&fDimDNS)
1894 return PostInfoHandler(&FactGui::handleDimDNS);
1895#ifdef DEBUG_DIM
1896 cout << "HandleDimInfo " << getInfo()->getName() << endl;
1897#endif
1898 if (getInfo()==&fDimLoggerStats)
1899 return PostInfoHandler(&FactGui::handleLoggerStats);
1900
1901 if (getInfo()==&fDimFadFiles)
1902 return PostInfoHandler(&FactGui::handleFadFiles);
1903
1904 if (getInfo()==&fDimFadConnections)
1905 return PostInfoHandler(&FactGui::handleFadConnections);
1906
1907 if (getInfo()==&fDimFadFwVersion)
1908 return PostInfoHandler(&FactGui::handleFadFwVersion);
1909
1910 if (getInfo()==&fDimFadStatistics)
1911 return PostInfoHandler(&FactGui::handleFadStatistics);
1912
1913 if (getInfo()==&fDimFadEvents)
1914 return PostInfoHandler(&FactGui::handleFadEvents);
1915
1916 if (getInfo()==&fDimFadRuns)
1917 return PostInfoHandler(&FactGui::handleFadRuns);
1918
1919 if (getInfo()==&fDimFadCurrentEvent)
1920 return PostInfoHandler(&FactGui::handleFadCurrentEvent);
1921
1922 if (getInfo()==&fDimFadEventData)
1923 return PostInfoHandler(&FactGui::handleFadEventData);
1924
1925/*
1926 if (getInfo()==&fDimFadSetup)
1927 return PostInfoHandler(&FactGui::handleFadSetup);
1928*/
1929 if (getInfo()==&fDimLoggerFilenameNight)
1930 return PostInfoHandler(&FactGui::handleLoggerFilenameNight);
1931
1932 if (getInfo()==&fDimLoggerNumSubs)
1933 return PostInfoHandler(&FactGui::handleLoggerNumSubs);
1934
1935 if (getInfo()==&fDimLoggerFilenameRun)
1936 return PostInfoHandler(&FactGui::handleLoggerFilenameRun);
1937
1938 if (getInfo()==&fDimFtmTriggerCounter)
1939 return PostInfoHandler(&FactGui::handleFtmTriggerCounter);
1940
1941 if (getInfo()==&fDimFtmCounter)
1942 return PostInfoHandler(&FactGui::handleFtmCounter);
1943
1944 if (getInfo()==&fDimFtmDynamicData)
1945 return PostInfoHandler(&FactGui::handleFtmDynamicData);
1946
1947 if (getInfo()==&fDimFtmPassport)
1948 return PostInfoHandler(&FactGui::handleFtmPassport);
1949
1950 if (getInfo()==&fDimFtmFtuList)
1951 return PostInfoHandler(&FactGui::handleFtmFtuList);
1952
1953 if (getInfo()==&fDimFtmStaticData)
1954 return PostInfoHandler(&FactGui::handleFtmStaticData);
1955
1956 if (getInfo()==&fDimFtmError)
1957 return PostInfoHandler(&FactGui::handleFtmError);
1958
1959 if (getInfo()==&fDimFadFiles)
1960 return PostInfoHandler(&FactGui::handleFadFiles);
1961
1962 for (map<string,DimInfo*>::iterator i=fServices.begin(); i!=fServices.end(); i++)
1963 if (i->second==getInfo())
1964 {
1965 infoHandlerService(*i->second);
1966 return;
1967 }
1968
1969 DimNetwork::infoHandler();
1970 }
1971
1972
1973 // ======================================================================
1974
1975 bool event(QEvent *evt)
1976 {
1977 if (dynamic_cast<FunctionEvent*>(evt))
1978 return static_cast<FunctionEvent*>(evt)->Exec();
1979
1980 if (dynamic_cast<CheckBoxEvent*>(evt))
1981 {
1982 const QStandardItem &item = static_cast<CheckBoxEvent*>(evt)->item;
1983 const QStandardItem *par = item.parent();
1984 if (par)
1985 {
1986 const QString server = par->text();
1987 const QString service = item.text();
1988
1989 const string s = (server+'/'+service).toStdString();
1990
1991 if (item.checkState()==Qt::Checked)
1992 SubscribeService(s);
1993 else
1994 UnsubscribeService(s);
1995 }
1996 }
1997
1998 return MainWindow::event(evt); // unrecognized
1999 }
2000
2001 void on_fDimCmdSend_clicked()
2002 {
2003 const QString server = fDimCmdServers->currentIndex().data().toString();
2004 const QString command = fDimCmdCommands->currentIndex().data().toString();
2005 const QString arguments = fDimCmdLineEdit->displayText();
2006
2007 // FIXME: Sending a command exactly when the info Handler changes
2008 // the list it might lead to confusion.
2009 try
2010 {
2011 SendDimCommand(server.toStdString(), command.toStdString()+" "+arguments.toStdString());
2012 fTextEdit->append("<font color='green'>Command '"+server+'/'+command+"' successfully emitted.</font>");
2013 fDimCmdLineEdit->clear();
2014 }
2015 catch (const runtime_error &e)
2016 {
2017 stringstream txt;
2018 txt << e.what();
2019
2020 string buffer;
2021 while (getline(txt, buffer, '\n'))
2022 fTextEdit->append(("<font color='red'><pre>"+buffer+"</pre></font>").c_str());
2023 }
2024 }
2025
2026#ifdef HAVE_ROOT
2027 void slot_RootEventProcessed(TObject *obj, unsigned int evt, TCanvas *canv)
2028 {
2029 // kMousePressEvent // TCanvas processed QEvent mousePressEvent
2030 // kMouseMoveEvent // TCanvas processed QEvent mouseMoveEvent
2031 // kMouseReleaseEvent // TCanvas processed QEvent mouseReleaseEvent
2032 // kMouseDoubleClickEvent // TCanvas processed QEvent mouseDoubleClickEvent
2033 // kKeyPressEvent // TCanvas processed QEvent keyPressEvent
2034 // kEnterEvent // TCanvas processed QEvent enterEvent
2035 // kLeaveEvent // TCanvas processed QEvent leaveEvent
2036 if (dynamic_cast<TCanvas*>(obj))
2037 return;
2038
2039 TQtWidget *tipped = static_cast<TQtWidget*>(sender());
2040
2041 if (evt==11/*kMouseReleaseEvent*/)
2042 {
2043 if (dynamic_cast<Camera*>(obj))
2044 {
2045 const float xx = canv->AbsPixeltoX(tipped->GetEventX());
2046 const float yy = canv->AbsPixeltoY(tipped->GetEventY());
2047
2048 Camera *cam = static_cast<Camera*>(obj);
2049 const int isw = cam->GetIdx(xx, yy);
2050
2051 fPixelIdx->setValue(isw);
2052 ChoosePixel(*cam, isw);
2053 }
2054 return;
2055 }
2056
2057 if (evt==61/*kMouseDoubleClickEvent*/)
2058 {
2059 if (dynamic_cast<Camera*>(obj))
2060 {
2061 const float xx = canv->AbsPixeltoX(tipped->GetEventX());
2062 const float yy = canv->AbsPixeltoY(tipped->GetEventY());
2063
2064 Camera *cam = static_cast<Camera*>(obj);
2065 const int isw = cam->GetIdx(xx, yy);
2066
2067 ChoosePixel(*cam, isw);
2068
2069 fPixelIdx->setValue(isw);
2070
2071 const uint16_t ihw = fPixelMapHW[isw];
2072
2073 Dim::SendCommand("FTM_CONTROL/TOGGLE_PIXEL", ihw);
2074 }
2075
2076 if (dynamic_cast<TAxis*>(obj))
2077 static_cast<TAxis*>(obj)->UnZoom();
2078
2079 return;
2080 }
2081
2082 // Find the object which will get picked by the GetObjectInfo
2083 // due to buffer overflows in many root-versions
2084 // in TH1 and TProfile we have to work around and implement
2085 // our own GetObjectInfo which make everything a bit more
2086 // complicated.
2087 canv->cd();
2088#if ROOT_VERSION_CODE > ROOT_VERSION(5,22,00)
2089 const char *objectInfo =
2090 obj->GetObjectInfo(tipped->GetEventX(),tipped->GetEventY());
2091#else
2092 const char *objectInfo = dynamic_cast<TH1*>(obj) ?
2093 "" : obj->GetObjectInfo(tipped->GetEventX(),tipped->GetEventY());
2094#endif
2095
2096 QString tipText;
2097 tipText += obj->GetName();
2098 tipText += " [";
2099 tipText += obj->ClassName();
2100 tipText += "]: ";
2101 tipText += objectInfo;
2102
2103 if (dynamic_cast<Camera*>(obj))
2104 {
2105 const float xx = canv->AbsPixeltoX(tipped->GetEventX());
2106 const float yy = canv->AbsPixeltoY(tipped->GetEventY());
2107
2108 Camera *cam = static_cast<Camera*>(obj);
2109
2110 const int isw = cam->GetIdx(xx, yy);
2111 const int ihw = fPixelMapHW[isw];
2112
2113 const int idx = fPatchHW[isw];
2114
2115 int ii = 0;
2116 for (; ii<160; ii++)
2117 if (idx==fPatchMapHW[ii])
2118 break;
2119
2120
2121 const int patch = ihw%4;
2122 const int board = (ihw/4)%10;
2123 const int crate = (ihw/4)/10;
2124
2125 ostringstream str;
2126 str << " (hw=" << ihw << ") Patch=" << ii << " (hw=" << fPatchMapHW[idx] << "; Crate=" << crate << " Board=" << board << " Patch=" << patch << ")";
2127
2128 tipText += str.str().c_str();
2129 }
2130
2131
2132 fStatusBar->showMessage(tipText, 3000);
2133
2134 gSystem->ProcessEvents();
2135 //QWhatsThis::display(tipText)
2136 }
2137
2138 void slot_RootUpdate()
2139 {
2140 gSystem->ProcessEvents();
2141 QTimer::singleShot(0, this, SLOT(slot_RootUpdate()));
2142 }
2143
2144 void ChoosePatch(Camera &cam, int isw)
2145 {
2146 cam.Reset();
2147
2148 fThresholdIdx->setValue(isw);
2149
2150 const int ihw = isw<0 ? 0 : fPatchMapHW[isw];
2151
2152 fPatchRate->setEnabled(isw>=0);
2153 fThresholdCrate->setEnabled(isw>=0);
2154 fThresholdBoard->setEnabled(isw>=0);
2155 fThresholdPatch->setEnabled(isw>=0);
2156
2157 if (isw<0)
2158 return;
2159
2160 const int patch = ihw%4;
2161 const int board = (ihw/4)%10;
2162 const int crate = (ihw/4)/10;
2163
2164 fInChoosePatch = true;
2165
2166 fThresholdCrate->setValue(crate);
2167 fThresholdBoard->setValue(board);
2168 fThresholdPatch->setValue(patch);
2169
2170 fInChoosePatch = false;
2171
2172 fThresholdVal->setValue(fFtmStaticData.fThreshold[ihw]);
2173 fPatchRate->setValue(cam.GetData(isw));
2174
2175 // Loop over the software idx of all pixels
2176 for (unsigned int i=0; i<1440; i++)
2177 if (fPatchHW[i]==ihw)
2178 cam.SetBold(i);
2179 }
2180
2181 void ChoosePixel(Camera &cam, int isw)
2182 {
2183 const int ihw = fPixelMapHW[isw];
2184
2185 int ii = 0;
2186 for (; ii<160; ii++)
2187 if (fPatchHW[isw]==fPatchMapHW[ii])
2188 break;
2189
2190 cam.SetWhite(isw);
2191 ChoosePatch(cam, ii);
2192
2193 const bool on = fFtmStaticData.IsEnabled(ihw);
2194 fPixelEnable->setChecked(on);
2195 }
2196
2197 void UpdatePatch(int isw)
2198 {
2199 Camera *cam = (Camera*)fRatesCanv->GetCanvas()->FindObject("Camera");
2200 ChoosePatch(*cam, isw);
2201 }
2202
2203 void on_fThresholdIdx_valueChanged(int isw)
2204 {
2205 UpdatePatch(isw);
2206
2207 fRatesCanv->GetCanvas()->Modified();
2208 fRatesCanv->GetCanvas()->Update();
2209 }
2210
2211 void UpdateThresholdIdx()
2212 {
2213 if (fInChoosePatch)
2214 return;
2215
2216 const int crate = fThresholdCrate->value();
2217 const int board = fThresholdBoard->value();
2218 const int patch = fThresholdPatch->value();
2219
2220 const int ihw = patch + board*4 + crate*40;
2221
2222 int isw = 0;
2223 for (; isw<160; isw++)
2224 if (ihw==fPatchMapHW[isw])
2225 break;
2226
2227 UpdatePatch(isw);
2228 }
2229
2230 void on_fThresholdPatch_valueChanged(int)
2231 {
2232 UpdateThresholdIdx();
2233 }
2234 void on_fThresholdBoard_valueChanged(int)
2235 {
2236 UpdateThresholdIdx();
2237 }
2238 void on_fThresholdCrate_valueChanged(int)
2239 {
2240 UpdateThresholdIdx();
2241 }
2242
2243 void on_fPixelIdx_valueChanged(int isw)
2244 {
2245 Camera *cam = (Camera*)fRatesCanv->GetCanvas()->FindObject("Camera");
2246 ChoosePixel(*cam, isw);
2247
2248 fRatesCanv->GetCanvas()->Modified();
2249 fRatesCanv->GetCanvas()->Update();
2250 }
2251#endif
2252
2253 void on_fPixelEnable_stateChanged(int b)
2254 {
2255 if (fInHandler)
2256 return;
2257
2258 const uint16_t isw = fPixelIdx->value();
2259 const uint16_t ihw = fPixelMapHW[isw];
2260
2261 Dim::SendCommand(b==Qt::Unchecked ?
2262 "FTM_CONTROL/DISABLE_PIXEL" : "FTM_CONTROL/ENABLE_PIXEL",
2263 ihw);
2264 }
2265
2266 void on_fPixelDisableOthers_clicked()
2267 {
2268 const uint16_t isw = fPixelIdx->value();
2269 const uint16_t ihw = fPixelMapHW[isw];
2270
2271 Dim::SendCommand("FTM_CONTROL/DISABLE_ALL_PIXELS_EXCEPT", ihw);
2272 }
2273
2274 void on_fThresholdDisableOthers_clicked()
2275 {
2276 const uint16_t isw = fThresholdIdx->value();
2277 const uint16_t ihw = fPatchMapHW[isw];
2278
2279 Dim::SendCommand("FTM_CONTROL/DISABLE_ALL_PATCHES_EXCEPT", ihw);
2280 }
2281
2282 void on_fThresholdVal_valueChanged(int v)
2283 {
2284 fThresholdVolt->setValue(2500./4095*v);
2285
2286 const int32_t isw = fThresholdIdx->value();
2287 const int32_t ihw = fPatchMapHW[isw];
2288
2289 const int32_t d[2] = { ihw, v };
2290
2291 if (!fInHandler)
2292 Dim::SendCommand("FTM_CONTROL/SET_THRESHOLD", d);
2293 }
2294
2295 TGraph fGraphFtmTemp[4];
2296 TGraph fGraphFtmRate;
2297 TGraph fGraphPatchRate[160];
2298 TGraph fGraphBoardRate[40];
2299
2300#ifdef HAVE_ROOT
2301 void DrawTimeFrame(const char *ytitle)
2302 {
2303 const double tm = Time().RootTime();
2304
2305 TH1F h("TimeFrame", "", 1, tm, tm+60);//Time().RootTime()-1./24/60/60, Time().RootTime());
2306 h.SetDirectory(0);
2307// h.SetBit(TH1::kCanRebin);
2308 h.SetStats(kFALSE);
2309// h.SetMinimum(0);
2310// h.SetMaximum(1);
2311 h.SetXTitle("Time");
2312 h.SetYTitle(ytitle);
2313 h.GetXaxis()->CenterTitle();
2314 h.GetYaxis()->CenterTitle();
2315 h.GetXaxis()->SetTimeDisplay(true);
2316 h.GetXaxis()->SetTimeFormat("%Mh%S'");
2317 h.GetXaxis()->SetLabelSize(0.025);
2318 h.GetYaxis()->SetLabelSize(0.025);
2319 h.GetYaxis()->SetTitleOffset(1.2);
2320// h.GetYaxis()->SetTitleSize(1.2);
2321 h.DrawCopy()->SetDirectory(0);
2322 }
2323#endif
2324
2325public:
2326 FactGui() :
2327 fFtuStatus(40),
2328 fPixelMapHW(1440), fPatchMapHW(160), fPatchHW(1440),
2329 fInChoosePatch(false),
2330 fDimDNS("DIS_DNS/VERSION_NUMBER", 1, int(0), this),
2331
2332 fDimLoggerStats ("DATA_LOGGER/STATS", (void*)NULL, 0, this),
2333 fDimLoggerFilenameNight("DATA_LOGGER/FILENAME_NIGHTLY", (void*)NULL, 0, this),
2334 fDimLoggerFilenameRun ("DATA_LOGGER/FILENAME_RUN", (void*)NULL, 0, this),
2335 fDimLoggerNumSubs ("DATA_LOGGER/NUM_SUBS", (void*)NULL, 0, this),
2336
2337 fDimFtmPassport ("FTM_CONTROL/PASSPORT", (void*)NULL, 0, this),
2338 fDimFtmTriggerCounter ("FTM_CONTROL/TRIGGER_COUNTER", (void*)NULL, 0, this),
2339 fDimFtmError ("FTM_CONTROL/ERROR", (void*)NULL, 0, this),
2340 fDimFtmFtuList ("FTM_CONTROL/FTU_LIST", (void*)NULL, 0, this),
2341 fDimFtmStaticData ("FTM_CONTROL/STATIC_DATA", (void*)NULL, 0, this),
2342 fDimFtmDynamicData ("FTM_CONTROL/DYNAMIC_DATA", (void*)NULL, 0, this),
2343 fDimFtmCounter ("FTM_CONTROL/COUNTER", (void*)NULL, 0, this),
2344 fDimFadFiles ("FAD_CONTROL/FILES", (void*)NULL, 0, this),
2345 fDimFadRuns ("FAD_CONTROL/RUNS", (void*)NULL, 0, this),
2346 fDimFadEvents ("FAD_CONTROL/EVENTS", (void*)NULL, 0, this),
2347 fDimFadCurrentEvent ("FAD_CONTROL/CURRENT_EVENT", (void*)NULL, 0, this),
2348 fDimFadEventData ("FAD_CONTROL/EVENT_DATA", (void*)NULL, 0, this),
2349 fDimFadConnections ("FAD_CONTROL/CONNECTIONS", (void*)NULL, 0, this),
2350 fDimFadFwVersion ("FAD_CONTROL/FIRMWARE_VERSION", (void*)NULL, 0, this),
2351 fDimFadStatistics ("FAD_CONTROL/STATISTICS", (void*)NULL, 0, this)
2352 {
2353 fClockCondFreq->addItem("--- Hz", QVariant(-1));
2354 fClockCondFreq->addItem("800 MHz", QVariant(800));
2355 fClockCondFreq->addItem("1 GHz", QVariant(1000));
2356 fClockCondFreq->addItem("2 GHz", QVariant(2000));
2357 fClockCondFreq->addItem("3 GHz", QVariant(3000));
2358 fClockCondFreq->addItem("4 GHz", QVariant(4000));
2359 fClockCondFreq->addItem("5 GHz", QVariant(5000));
2360
2361 fTriggerWidget->setEnabled(false);
2362 fFtuWidget->setEnabled(false);
2363 fRatesWidget->setEnabled(false);
2364// fFadWidget->setEnabled(false);
2365 fLoggerWidget->setEnabled(false);
2366
2367 fChatSend->setEnabled(false);
2368 fChatMessage->setEnabled(false);
2369
2370 DimClient::sendCommand("CHAT/MSG", "GUI online.");
2371 // + MessageDimRX
2372
2373 // --------------------------------------------------------------------------
2374
2375 ifstream fin1("Trigger-Patches.txt");
2376
2377 int l = 0;
2378
2379 string buf;
2380 while (getline(fin1, buf, '\n'))
2381 {
2382 buf = Tools::Trim(buf);
2383 if (buf[0]=='#')
2384 continue;
2385
2386 stringstream str(buf);
2387 for (int i=0; i<9; i++)
2388 {
2389 unsigned int n;
2390 str >> n;
2391
2392 if (n>=fPatchHW.size())
2393 continue;
2394
2395 fPatchHW[n] = l;
2396 }
2397 l++;
2398 }
2399
2400 if (l!=160)
2401 cerr << "WARNING - Problems reading Trigger-Patches.txt" << endl;
2402
2403 // --------------------------------------------------------------------------
2404
2405 ifstream fin2("MasterList-v3.txt");
2406
2407 l = 0;
2408
2409 while (getline(fin2, buf, '\n'))
2410 {
2411 buf = Tools::Trim(buf);
2412 if (buf[0]=='#')
2413 continue;
2414
2415 unsigned int softid, hardid, dummy;
2416
2417 stringstream str(buf);
2418
2419 str >> softid;
2420 str >> dummy;
2421 str >> hardid;
2422
2423 if (softid>=fPixelMapHW.size())
2424 continue;
2425
2426 fPixelMapHW[softid] = hardid;
2427
2428 l++;
2429 }
2430
2431 if (l!=1440)
2432 cerr << "WARNING - Problems reading MasterList-v3.txt" << endl;
2433
2434 // --------------------------------------------------------------------------
2435
2436 ifstream fin3("PatchList.txt");
2437
2438 l = 0;
2439
2440 while (getline(fin3, buf, '\n'))
2441 {
2442 buf = Tools::Trim(buf);
2443 if (buf[0]=='#')
2444 continue;
2445
2446 unsigned int softid, hardid;
2447
2448 stringstream str(buf);
2449
2450 str >> softid;
2451 str >> hardid;
2452
2453 if (softid>=fPatchMapHW.size())
2454 continue;
2455
2456 fPatchMapHW[softid] = hardid-1;
2457
2458 l++;
2459 }
2460
2461 if (l!=160)
2462 cerr << "WARNING - Problems reading PatchList.txt" << endl;
2463
2464 // --------------------------------------------------------------------------
2465#ifdef HAVE_ROOT
2466
2467 fGraphFtmRate.SetLineColor(kBlue);
2468 fGraphFtmRate.SetMarkerColor(kBlue);
2469 fGraphFtmRate.SetMarkerStyle(kFullDotMedium);
2470
2471 for (int i=0; i<160; i++)
2472 {
2473 fGraphPatchRate[i].SetName("PatchRate");
2474 //fGraphPatchRate[i].SetLineColor(kBlue);
2475 //fGraphPatchRate[i].SetMarkerColor(kBlue);
2476 fGraphPatchRate[i].SetMarkerStyle(kFullDotMedium);
2477 }
2478 for (int i=0; i<40; i++)
2479 {
2480 fGraphBoardRate[i].SetName("BoardRate");
2481 //fGraphBoardRate[i].SetLineColor(kBlue);
2482 //fGraphBoardRate[i].SetMarkerColor(kBlue);
2483 fGraphBoardRate[i].SetMarkerStyle(kFullDotMedium);
2484 }
2485 /*
2486 TCanvas *c = fFtmTempCanv->GetCanvas();
2487 c->SetBit(TCanvas::kNoContextMenu);
2488 c->SetBorderMode(0);
2489 c->SetFrameBorderMode(0);
2490 c->SetFillColor(kWhite);
2491 c->SetRightMargin(0.03);
2492 c->SetTopMargin(0.03);
2493 c->cd();
2494 */
2495 //CreateTimeFrame("Temperature / °C");
2496
2497 fGraphFtmTemp[0].SetMarkerStyle(kFullDotSmall);
2498 fGraphFtmTemp[1].SetMarkerStyle(kFullDotSmall);
2499 fGraphFtmTemp[2].SetMarkerStyle(kFullDotSmall);
2500 fGraphFtmTemp[3].SetMarkerStyle(kFullDotSmall);
2501
2502 fGraphFtmTemp[1].SetLineColor(kBlue);
2503 fGraphFtmTemp[2].SetLineColor(kRed);
2504 fGraphFtmTemp[3].SetLineColor(kGreen);
2505
2506 fGraphFtmTemp[1].SetMarkerColor(kBlue);
2507 fGraphFtmTemp[2].SetMarkerColor(kRed);
2508 fGraphFtmTemp[3].SetMarkerColor(kGreen);
2509
2510 //fGraphFtmTemp[0].Draw("LP");
2511 //fGraphFtmTemp[1].Draw("LP");
2512 //fGraphFtmTemp[2].Draw("LP");
2513 //fGraphFtmTemp[3].Draw("LP");
2514
2515 // --------------------------------------------------------------------------
2516
2517 TCanvas *c = fFtmRateCanv->GetCanvas();
2518 //c->SetBit(TCanvas::kNoContextMenu);
2519 c->SetBorderMode(0);
2520 c->SetFrameBorderMode(0);
2521 c->SetFillColor(kWhite);
2522 c->SetRightMargin(0.03);
2523 c->SetTopMargin(0.03);
2524 c->SetGrid();
2525 c->cd();
2526
2527 DrawTimeFrame("Trigger rate [Hz]");
2528
2529 fTriggerCounter0 = -1;
2530
2531 fGraphFtmRate.SetMarkerStyle(kFullDotSmall);
2532 fGraphFtmRate.Draw("LP");
2533
2534 // --------------------------------------------------------------------------
2535
2536 c = fRatesCanv->GetCanvas();
2537 //c->SetBit(TCanvas::kNoContextMenu);
2538 c->SetBorderMode(0);
2539 c->SetFrameBorderMode(0);
2540 c->SetFillColor(kWhite);
2541 c->cd();
2542
2543 Camera *cam = new Camera;
2544 cam->SetBit(kCanDelete);
2545 cam->Draw();
2546
2547 ChoosePixel(*cam, 0);
2548
2549 // --------------------------------------------------------------------------
2550
2551 c = fAdcDataCanv->GetCanvas();
2552 c->SetBit(TCanvas::kNoContextMenu);
2553 c->SetBorderMode(0);
2554 c->SetFrameBorderMode(0);
2555 c->SetFillColor(kWhite);
2556 c->SetGrid();
2557 c->cd();
2558
2559 // Create histogram?
2560
2561 // --------------------------------------------------------------------------
2562
2563// QTimer::singleShot(0, this, SLOT(slot_RootUpdate()));
2564
2565 //widget->setMouseTracking(true);
2566 //widget->EnableSignalEvents(kMouseMoveEvent);
2567
2568 fFtmRateCanv->setMouseTracking(true);
2569 fFtmRateCanv->EnableSignalEvents(kMouseMoveEvent);
2570
2571 fAdcDataCanv->setMouseTracking(true);
2572 fAdcDataCanv->EnableSignalEvents(kMouseMoveEvent);
2573
2574 fRatesCanv->setMouseTracking(true);
2575 fRatesCanv->EnableSignalEvents(kMouseMoveEvent|kMouseReleaseEvent|kMouseDoubleClickEvent);
2576
2577 connect(fRatesCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)),
2578 this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*)));
2579 connect(fFtmRateCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)),
2580 this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*)));
2581 connect(fAdcDataCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)),
2582 this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*)));
2583#endif
2584 }
2585
2586 ~FactGui()
2587 {
2588 UnsubscribeAllServers();
2589 }
2590};
2591
2592#endif
Note: See TracBrowser for help on using the repository browser.