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

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