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

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