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

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