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

Last change on this file since 10518 was 10518, checked in by tbretz, 10 years ago
Added latest changes, which includes almost a complete FTM support and implements root-plots.
File size: 50.4 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/Converter.h"
17#include "src/HeadersFTM.h"
18#include "src/DimNetwork.h"
19#include "src/tools.h"
20
21#include "TROOT.h"
22#include "TSystem.h"
23#include "TGraph.h"
24#include "TH1.h"
25#include "TStyle.h"
26#include "TMarker.h"
27#include "TColor.h"
28
29using namespace std;
30 class Camera : public TObject
31 {
32 typedef pair<double,double> Position;
33 typedef vector<Position> Positions;
34 Positions fGeom;
35
36 void CreatePalette()
37 {
38 /*
39 double ss[5] = {0., 0.10, 0.45, 0.75, 1.00};
40 double rr[5] = {0., 0.35, 0.85, 1.00, 1.00};
41 double gg[5] = {0., 0.10, 0.20, 0.73, 1.00};
42 double bb[5] = {0., 0.03, 0.06, 0.00, 1.00};
43 */
44 double ss[5] = {0., 0.25, 0.50, 0.75, 1.00};
45 double rr[5] = {0., 0.00, 0.00, 1.00, 1.00};
46 double gg[5] = {0., 0.00, 1.00, 0.00, 1.00};
47 double bb[5] = {0., 1.00, 0.00, 0.00, 1.00};
48
49 const Int_t nn = 1438;
50
51 Int_t idx = TColor::CreateGradientColorTable(5, ss, rr, gg, bb, nn);
52 for (int i=0; i<nn; i++)
53 fPalette.push_back(idx++);
54 }
55
56 void CreateGeometry()
57 {
58 const double gsSin60 = sqrt(3.)/2;
59
60 const int rings = 23;
61
62 // add the first pixel to the list
63
64 fGeom.push_back(make_pair(0, -0.5));
65
66 for (int ring=1; ring<=rings; ring++)
67 {
68 for (int s=0; s<6; s++)
69 {
70 for (int i=1; i<=ring; i++)
71 {
72 double xx, yy;
73 switch (s)
74 {
75 case 0: // Direction South East
76 xx = (ring+i)*0.5;
77 yy = (-ring+i)*gsSin60;
78 break;
79
80 case 1: // Direction North East
81 xx = ring-i*0.5;
82 yy = i*gsSin60;
83 break;
84
85 case 2: // Direction North
86 xx = ring*0.5-i;
87 yy = ring*gsSin60;
88 break;
89
90 case 3: // Direction North West
91 xx = -(ring+i)*0.5;
92 yy = (ring-i)*gsSin60;
93 break;
94
95 case 4: // Direction South West
96 xx = 0.5*i-ring;
97 yy = -i*gsSin60;
98 break;
99
100 case 5: // Direction South
101 xx = i-ring*0.5;
102 yy = -ring*gsSin60;
103 break;
104 }
105
106 if (xx*xx + yy*yy - xx > 395.75)
107 continue;
108
109 fGeom.push_back(make_pair(yy, xx-0.5));
110 }
111 }
112 }
113 }
114
115 valarray<double> fData;
116 map<int, bool> fBold;
117 map<int, bool> fEnable;
118
119 int fWhite;
120
121public:
122 Camera() : fData(0., 1438), fWhite(-1)
123 {
124 CreatePalette();
125 CreateGeometry();
126
127 for (int i=0; i<1438; i++)
128 fData[i] = i;
129 }
130
131 void Reset() { fBold.clear(); }
132
133 void SetBold(int idx) { fBold[idx]=true; }
134 void SetWhite(int idx) { fWhite=idx; }
135 void SetEnable(int idx, bool b) { fEnable[idx]=b; }
136 void Toggle(int idx) { fEnable[idx]=!fEnable[idx]; }
137
138 const char *GetName() const { return "Camera"; }
139
140 vector<Int_t> fPalette;
141
142 void Paint(const Position &p)
143 {
144 static const Double_t fgCos60 = 0.5; // TMath::Cos(60/TMath::RadToDeg());
145 static const Double_t fgSin60 = sqrt(3.)/2; // TMath::Sin(60/TMath::RadToDeg());
146
147 static const Double_t fgDy[6] = { fgCos60, 0., -fgCos60, -fgCos60, 0., fgCos60 };
148 static const Double_t fgDx[6] = { fgSin60/3, fgSin60*2/3, fgSin60/3, -fgSin60/3, -fgSin60*2/3, -fgSin60/3 };
149
150 //
151 // calculate the positions of the pixel corners
152 //
153 Double_t x[7], y[7];
154 for (Int_t i=0; i<7; i++)
155 {
156 x[i] = p.first + fgDx[i%6];
157 y[i] = p.second + fgDy[i%6];
158 }
159
160 gPad->PaintFillArea(6, x, y);
161 gPad->PaintPolyLine(7, x, y);
162
163 }
164
165 void Paint(Option_t *)
166 {
167 gStyle->SetPalette(fPalette.size(), fPalette.data());
168
169
170 const double r = double(gPad->GetWw())/gPad->GetWh();
171 const double max = 20.5; // 20.5 rings in x and y
172
173 if (r>1)
174 gPad->Range(-r*max, -max, r*max, max);
175 else
176 gPad->Range(-max, -max/r, max, max/r);
177
178
179 const double min = fData.min();
180 const double scale = fData.max()-fData.min();
181
182 TAttFill fill(0, 1001);
183 TAttLine line;
184
185 int cnt=0;
186 for (Positions::iterator p=fGeom.begin(); p!=fGeom.end(); p++, cnt++)
187 {
188 if (fBold[cnt])
189 continue;
190
191
192 const int col = (fData[cnt]-min)/scale*(fPalette.size()-1);
193
194 if (fEnable[cnt])
195 fill.SetFillColor(gStyle->GetColorPalette(col));
196 else
197 fill.SetFillColor(kWhite);
198
199 fill.Modify();
200
201 Paint(*p);
202 }
203
204 line.SetLineWidth(2);
205 line.Modify();
206
207 cnt = 0;
208 for (Positions::iterator p=fGeom.begin(); p!=fGeom.end(); p++, cnt++)
209 {
210 if (!fBold[cnt])
211 continue;
212
213 const int col = (fData[cnt]-min)/scale*(fPalette.size()-1);
214
215 if (fEnable[cnt])
216 fill.SetFillColor(gStyle->GetColorPalette(col));
217 else
218 fill.SetFillColor(kWhite);
219 fill.Modify();
220
221 Paint(*p);
222 }
223
224 TMarker m(0,0,kStar);
225 m.DrawMarker(0, 0);
226
227 if (fWhite<0)
228 return;
229
230 const Position &p = fGeom[fWhite];
231
232 line.SetLineColor(kWhite);
233 line.Modify();
234
235 const int col = (fData[fWhite]-min)/scale*(fPalette.size()-1);
236
237 if (fEnable[fWhite])
238 fill.SetFillColor(gStyle->GetColorPalette(col));
239 else
240 fill.SetFillColor(kWhite);
241 fill.Modify();
242
243 Paint(p);
244 }
245
246 int GetIdx(float px, float py) const
247 {
248 static const double sqrt3 = sqrt(3);
249
250 int idx = 0;
251 for (Positions::const_iterator p=fGeom.begin(); p!=fGeom.end(); p++, idx++)
252 {
253 const Double_t dy = py - p->second;
254 if (fabs(dy)>0.5)
255 continue;
256
257 const Double_t dx = px - p->first;
258
259 if (TMath::Abs(dy + dx*sqrt3) > 1)
260 continue;
261
262 if (TMath::Abs(dy - dx*sqrt3) > 1)
263 continue;
264
265 return idx;
266 }
267 return -1;
268 }
269
270 char* GetObjectInfo(Int_t px, Int_t py) const
271 {
272 static stringstream stream;
273 static string str;
274
275 const float x = gPad->PadtoX(gPad->AbsPixeltoX(px));
276 const float y = gPad->PadtoY(gPad->AbsPixeltoY(py));
277
278 const int idx = GetIdx(x, y);
279
280 stream.seekp(0);
281 if (idx>=0)
282 stream << "Pixel=" << idx << " Data=" << fData[idx] << '\0';
283
284 str = stream.str();
285 return const_cast<char*>(str.c_str());
286 }
287
288 Int_t DistancetoPrimitive(Int_t px, Int_t py)
289 {
290 const float x = gPad->PadtoX(gPad->AbsPixeltoX(px));
291 const float y = gPad->PadtoY(gPad->AbsPixeltoY(py));
292
293 return GetIdx(x, y)>=0 ? 0 : 99999;
294 }
295
296 void SetData(const valarray<double> &data)
297 {
298 fData = data;
299 }
300
301
302 };
303
304
305class FactGui : public MainWindow, public DimNetwork
306{
307private:
308 class FunctionEvent : public QEvent
309 {
310 public:
311 boost::function<void(const QEvent &)> fFunction;
312
313 FunctionEvent(const boost::function<void(const QEvent &)> &f)
314 : QEvent((QEvent::Type)QEvent::registerEventType()),
315 fFunction(f) { }
316
317 bool Exec() { fFunction(*this); return true; }
318 };
319
320 DimStampedInfo fDimDNS;
321
322 DimStampedInfo fDimLoggerStats;
323 DimStampedInfo fDimLoggerFilenameNight;
324 DimStampedInfo fDimLoggerFilenameRun;
325 DimStampedInfo fDimLoggerNumSubs;
326
327 DimStampedInfo fDimFtmPassport;
328 DimStampedInfo fDimFtmTriggerCounter;
329 DimStampedInfo fDimFtmError;
330 DimStampedInfo fDimFtmFtuList;
331 DimStampedInfo fDimFtmStaticData;
332 DimStampedInfo fDimFtmDynamicData;
333
334 vector<DimInfo*> fDim;
335 map<string, DimInfo*> fServices;
336
337 // ===================== Services and Commands ==========================
338
339 QStandardItem *AddServiceItem(const std::string &server, const std::string &service, bool iscmd)
340 {
341 QListView *servers = iscmd ? fDimCmdServers : fDimSvcServers;
342 QListView *services = iscmd ? fDimCmdCommands : fDimSvcServices;
343 QListView *description = iscmd ? fDimCmdDescription : fDimSvcDescription;
344
345 QStandardItemModel *m = dynamic_cast<QStandardItemModel*>(servers->model());
346 if (!m)
347 {
348 m = new QStandardItemModel(this);
349 servers->setModel(m);
350 services->setModel(m);
351 description->setModel(m);
352 }
353
354 QList<QStandardItem*> l = m->findItems(server.c_str());
355
356 if (l.size()>1)
357 {
358 cout << "hae" << endl;
359 return 0;
360 }
361
362 QStandardItem *col = l.size()==0 ? NULL : l[0];
363
364 if (!col)
365 {
366 col = new QStandardItem(server.c_str());
367 m->appendRow(col);
368
369 if (!services->rootIndex().isValid())
370 {
371 services->setRootIndex(col->index());
372 servers->setCurrentIndex(col->index());
373 }
374 }
375
376 QStandardItem *item = 0;
377 for (int i=0; i<col->rowCount(); i++)
378 {
379 QStandardItem *coli = col->child(i);
380 if (coli->text().toStdString()==service)
381 return coli;
382 }
383
384 item = new QStandardItem(service.c_str());
385 col->appendRow(item);
386
387 if (!description->rootIndex().isValid())
388 {
389 description->setRootIndex(item->index());
390 services->setCurrentIndex(item->index());
391 }
392
393 if (!iscmd)
394 item->setCheckable(true);
395
396 return item;
397 }
398
399 void AddDescription(QStandardItem *item, const vector<Description> &vec)
400 {
401 if (!item)
402 return;
403 if (vec.size()==0)
404 return;
405
406 item->setToolTip(vec[0].comment.c_str());
407
408 const string str = Description::GetHtmlDescription(vec);
409
410 QStandardItem *desc = new QStandardItem(str.c_str());
411 desc->setSelectable(false);
412 item->setChild(0, 0, desc);
413 }
414
415 void AddServer(const std::string &s)
416 {
417 DimNetwork::AddServer(s);
418
419 QApplication::postEvent(this,
420 new FunctionEvent(boost::bind(&FactGui::handleAddServer, this, s)));
421 }
422
423 void RemoveServer(const std::string &s)
424 {
425 UnsubscribeServer(s);
426
427 DimNetwork::RemoveServer(s);
428
429 QApplication::postEvent(this,
430 new FunctionEvent(boost::bind(&FactGui::handleRemoveServer, this, s)));
431 }
432
433 void RemoveAllServers()
434 {
435 UnsubscribeAllServers();
436
437 vector<string> v = GetServerList();
438 for (vector<string>::iterator i=v.begin(); i<v.end(); i++)
439 QApplication::postEvent(this,
440 new FunctionEvent(boost::bind(&FactGui::handleStateOffline, this, *i)));
441
442 DimNetwork::RemoveAllServers();
443
444 QApplication::postEvent(this,
445 new FunctionEvent(boost::bind(&FactGui::handleRemoveAllServers, this)));
446 }
447
448 void AddService(const std::string &server, const std::string &service, const std::string &fmt, bool iscmd)
449 {
450 QApplication::postEvent(this,
451 new FunctionEvent(boost::bind(&FactGui::handleAddService, this, server, service, fmt, iscmd)));
452 }
453
454 void RemoveService(const std::string &server, const std::string &service, bool iscmd)
455 {
456 if (fServices.find(server+'/'+service)!=fServices.end())
457 UnsubscribeService(server+'/'+service);
458
459 QApplication::postEvent(this,
460 new FunctionEvent(boost::bind(&FactGui::handleRemoveService, this, server, service, iscmd)));
461 }
462
463 void RemoveAllServices(const std::string &server)
464 {
465 UnsubscribeServer(server);
466
467 QApplication::postEvent(this,
468 new FunctionEvent(boost::bind(&FactGui::handleRemoveAllServices, this, server)));
469 }
470
471 void AddDescription(const std::string &server, const std::string &service, const vector<Description> &vec)
472 {
473 QApplication::postEvent(this,
474 new FunctionEvent(boost::bind(&FactGui::handleAddDescription, this, server, service, vec)));
475 }
476
477 // ======================================================================
478
479 void handleAddServer(const std::string &server)
480 {
481 const State s = GetState(server, GetCurrentState(server));
482 handleStateChanged(Time(), server, s);
483 }
484
485 void handleRemoveServer(const string &server)
486 {
487 handleStateOffline(server);
488 handleRemoveAllServices(server);
489 }
490
491 void handleRemoveAllServers()
492 {
493 QStandardItemModel *m = 0;
494 if ((m=dynamic_cast<QStandardItemModel*>(fDimCmdServers->model())))
495 m->removeRows(0, m->rowCount());
496
497 if ((m = dynamic_cast<QStandardItemModel*>(fDimSvcServers->model())))
498 m->removeRows(0, m->rowCount());
499 }
500
501 void handleAddService(const std::string &server, const std::string &service, const std::string &/*fmt*/, bool iscmd)
502 {
503 QStandardItem *item = AddServiceItem(server, service, iscmd);
504 const vector<Description> v = GetDescription(server, service);
505 AddDescription(item, v);
506 }
507
508 void handleRemoveService(const std::string &server, const std::string &service, bool iscmd)
509 {
510 QListView *servers = iscmd ? fDimCmdServers : fDimSvcServers;
511
512 QStandardItemModel *m = dynamic_cast<QStandardItemModel*>(servers->model());
513 if (!m)
514 return;
515
516 QList<QStandardItem*> l = m->findItems(server.c_str());
517 if (l.size()!=1)
518 return;
519
520 for (int i=0; i<l[0]->rowCount(); i++)
521 {
522 QStandardItem *row = l[0]->child(i);
523 if (row->text().toStdString()==service)
524 {
525 l[0]->removeRow(row->index().row());
526 return;
527 }
528 }
529 }
530
531 void handleRemoveAllServices(const std::string &server)
532 {
533 QStandardItemModel *m = 0;
534 if ((m=dynamic_cast<QStandardItemModel*>(fDimCmdServers->model())))
535 {
536 QList<QStandardItem*> l = m->findItems(server.c_str());
537 if (l.size()==1)
538 m->removeRow(l[0]->index().row());
539 }
540
541 if ((m = dynamic_cast<QStandardItemModel*>(fDimSvcServers->model())))
542 {
543 QList<QStandardItem*> l = m->findItems(server.c_str());
544 if (l.size()==1)
545 m->removeRow(l[0]->index().row());
546 }
547 }
548
549 void handleAddDescription(const std::string &server, const std::string &service, const vector<Description> &vec)
550 {
551 const bool iscmd = IsCommand(server, service)==true;
552
553 QStandardItem *item = AddServiceItem(server, service, iscmd);
554 AddDescription(item, vec);
555 }
556
557 // ======================================================================
558
559 void SubscribeService(const string &service)
560 {
561 if (fServices.find(service)!=fServices.end())
562 {
563 cout << "ERROR - We are already subscribed to " << service << endl;
564 return;
565 }
566
567 fServices[service] = new DimStampedInfo(service.c_str(), (void*)NULL, 0, this);
568 }
569
570 void UnsubscribeService(const string &service)
571 {
572 const map<string,DimInfo*>::iterator i=fServices.find(service);
573
574 if (i==fServices.end())
575 {
576 cout << "ERROR - We are not subscribed to " << service << endl;
577 return;
578 }
579
580 delete i->second;
581
582 fServices.erase(i);
583 }
584
585 void UnsubscribeServer(const string &server)
586 {
587 for (map<string,DimInfo*>::iterator i=fServices.begin();
588 i!=fServices.end(); i++)
589 if (i->first.substr(0, server.length()+1)==server+'/')
590 {
591 delete i->second;
592 fServices.erase(i);
593 }
594 }
595
596 void UnsubscribeAllServers()
597 {
598 for (map<string,DimInfo*>::iterator i=fServices.begin();
599 i!=fServices.end(); i++)
600 delete i->second;
601
602 fServices.clear();
603 }
604
605 // ======================================================================
606
607 struct DimData
608 {
609 Time time;
610 int qos;
611 string name;
612 string format;
613 vector<char> data;
614
615 DimInfo *info; // this is ONLY for a fast check of the type of the DimData!!
616
617 DimData(DimInfo *inf) :
618 time(inf->getTimestamp(), inf->getTimestampMillisecs()*1000),
619 qos(inf->getQuality()),
620 name(inf->getName()),
621 format(inf->getFormat()),
622 data(inf->getString(), inf->getString()+inf->getSize()),
623 info(inf)
624 {
625 }
626
627 template<typename T>
628 T get() const { return *reinterpret_cast<const T*>(data.data()); }
629
630 vector<char> vec(int b) const { return vector<char>(data.begin()+b, data.end()); }
631 string str(unsigned int b) const { return b>=data.size()?string():string(data.data()+b, data.size()-b); }
632 const char *c_str() const { return (char*)data.data(); }
633
634 vector<boost::any> any() const
635 {
636 const Converter conv(format);
637 conv.Print();
638 return conv.GetAny(data.data(), data.size());
639 }
640 int size() const { return data.size(); }
641 const void *ptr() const { return data.data(); }
642 };
643
644 // ======================= DNS ==========================================
645
646 void handleDimDNS(int version)
647 {
648 ostringstream str;
649 str << "V" << version/100 << 'r' << version%100;
650
651 if (version==0)
652 fStatusDNSLed->setIcon(QIcon(":/Resources/icons/red circle 1.png"));
653 else
654 fStatusDNSLed->setIcon(QIcon(":/Resources/icons/green circle 1.png"));
655
656 fStatusDNSLabel->setText(version==0?"Offline":str.str().c_str());
657 fStatusDNSLabel->setToolTip(version==0?"No connection to DIM DNS.":"Connection to DIM DNS established.");
658 }
659
660
661 // ======================= Logger =======================================
662
663 void handleLoggerStats(const DimData &d)
664 {
665 const bool connected = d.size()!=0;
666
667 fLoggerET->setEnabled(connected);
668 fLoggerRate->setEnabled(connected);
669 fLoggerWritten->setEnabled(connected);
670 fLoggerFreeSpace->setEnabled(connected);
671 fLoggerSpaceLeft->setEnabled(connected);
672
673 if (!connected)
674 return;
675
676 const vector<boost::any> any = d.any();
677
678 const size_t rate = boost::any_cast<int>(any[2]);
679 const size_t space = boost::any_cast<long long>(any[1]);
680 const size_t written = boost::any_cast<long long>(any[0]);
681
682 fLoggerFreeSpace->setSuffix(" MB");
683 fLoggerFreeSpace->setDecimals(0);
684 fLoggerFreeSpace->setValue(space*1e-6);
685
686 if (space> 1000000) // > 1GB
687 {
688 fLoggerFreeSpace->setSuffix(" GB");
689 fLoggerFreeSpace->setDecimals(2);
690 fLoggerFreeSpace->setValue(space*1e-9);
691 }
692 if (space>= 3000000) // >= 3GB
693 {
694 fLoggerFreeSpace->setSuffix(" GB");
695 fLoggerFreeSpace->setDecimals(1);
696 fLoggerFreeSpace->setValue(space*1e-9);
697 }
698 if (space>=100000000) // >= 100GB
699 {
700 fLoggerFreeSpace->setSuffix(" GB");
701 fLoggerFreeSpace->setDecimals(0);
702 fLoggerFreeSpace->setValue(space*1e-9);
703 }
704
705 fLoggerET->setTime(QTime().addSecs(rate>0?space/rate:0));
706 fLoggerRate->setValue(rate*1e-3); // kB/s
707 fLoggerWritten->setValue(written*1e-6);
708
709 fLoggerRate->setSuffix(" kB/s");
710 fLoggerRate->setDecimals(2);
711 fLoggerRate->setValue(rate*1e-3);
712 if (rate> 2000) // > 2kB/s
713 {
714 fLoggerRate->setSuffix(" kB/s");
715 fLoggerRate->setDecimals(1);
716 fLoggerRate->setValue(rate*1e-3);
717 }
718 if (rate>=100000) // >100kB/s
719 {
720 fLoggerRate->setSuffix(" kB/s");
721 fLoggerRate->setDecimals(0);
722 fLoggerRate->setValue(rate*1e-3);
723 }
724 if (rate>=1000000) // >100kB/s
725 {
726 fLoggerRate->setSuffix(" MB/s");
727 fLoggerRate->setDecimals(2);
728 fLoggerRate->setValue(rate*1e-6);
729 }
730 if (rate>=10000000) // >1MB/s
731 {
732 fLoggerRate->setSuffix(" MB/s");
733 fLoggerRate->setDecimals(1);
734 fLoggerRate->setValue(rate*1e-6);
735 }
736 if (rate>=100000000) // >10MB/s
737 {
738 fLoggerRate->setSuffix(" MB/s");
739 fLoggerRate->setDecimals(0);
740 fLoggerRate->setValue(rate*1e-6);
741 }
742
743 if (space/10000000>static_cast<size_t>(fLoggerSpaceLeft->maximum()))
744 fLoggerSpaceLeft->setValue(fLoggerSpaceLeft->maximum()); // MB
745 else
746 fLoggerSpaceLeft->setValue(space/10000000); // MB
747 }
748
749 void handleLoggerFilenameNight(const DimData &d)
750 {
751 const bool connected = d.size()!=0;
752
753 fLoggerFilenameNight->setEnabled(connected);
754 if (connected)
755 fLoggerFilenameNight->setText(d.c_str());
756
757 if (d.qos&1)
758 fLoggerLedLog->setIcon(QIcon(":/Resources/icons/gray circle 1.png"));
759 else
760 fLoggerLedLog->setIcon(QIcon(":/Resources/icons/green circle 1.png"));
761
762 if (d.qos&2)
763 fLoggerLedRep->setIcon(QIcon(":/Resources/icons/gray circle 1.png"));
764 else
765 fLoggerLedRep->setIcon(QIcon(":/Resources/icons/green circle 1.png"));
766
767 if (d.qos&4)
768 fLoggerLedFits->setIcon(QIcon(":/Resources/icons/gray circle 1.png"));
769 else
770 fLoggerLedFits->setIcon(QIcon(":/Resources/icons/green circle 1.png"));
771 }
772
773 void handleLoggerFilenameRun(const DimData &d)
774 {
775 const bool connected = d.size()!=0;
776
777 fLoggerFilenameRun->setEnabled(connected);
778 if (connected)
779 fLoggerFilenameRun->setText(d.c_str());
780
781 if (d.qos&1)
782 fLoggerLedLog->setIcon(QIcon(":/Resources/icons/gray circle 1.png"));
783 else
784 fLoggerLedLog->setIcon(QIcon(":/Resources/icons/green circle 1.png"));
785
786 if (d.qos&2)
787 fLoggerLedRep->setIcon(QIcon(":/Resources/icons/gray circle 1.png"));
788 else
789 fLoggerLedRep->setIcon(QIcon(":/Resources/icons/green circle 1.png"));
790
791 if (d.qos&4)
792 fLoggerLedFits->setIcon(QIcon(":/Resources/icons/gray circle 1.png"));
793 else
794 fLoggerLedFits->setIcon(QIcon(":/Resources/icons/green circle 1.png"));
795 }
796
797 void handleLoggerNumSubs(const DimData &d)
798 {
799 const bool connected = d.size()!=0;
800
801 fLoggerSubscriptions->setEnabled(connected);
802 fLoggerOpenFiles->setEnabled(connected);
803 if (!connected)
804 return;
805
806 const vector<boost::any> any = d.any();
807
808 fLoggerSubscriptions->setValue(boost::any_cast<int>(any[0]));
809 fLoggerOpenFiles->setValue(boost::any_cast<int>(any[1]));
810 }
811
812 // ===================== FTM ============================================
813
814 void handleFtmTriggerCounter(const DimData &d)
815 {
816 if (d.size()==0)
817 return;
818
819 if (d.size()!=sizeof(FTM::DimTriggerCounter))
820 {
821 cout << "Size mismatch: " << d.size() << " " << sizeof(FTM::DimTriggerCounter) << endl;
822 return;
823 }
824
825 const FTM::DimTriggerCounter &sdata = *reinterpret_cast<const FTM::DimTriggerCounter*>(d.ptr());
826
827 fFtmTime->setText(QString::number(sdata.fTimeStamp));
828 fTriggerCounter->setText(QString::number(sdata.fTriggerCounter));
829 }
830
831 void handleFtmDynamicData(const DimData &d)
832 {
833 if (d.size()==0)
834 return;
835
836 if (d.size()!=sizeof(FTM::DimDynamicData))
837 {
838 cout << "Size mismatch: " << d.size() << " " << sizeof(FTM::DimDynamicData) << endl;
839 return;
840 }
841
842 const FTM::DimDynamicData &sdata = *reinterpret_cast<const FTM::DimDynamicData*>(d.ptr());
843
844 fFtmTime->setText(QString::number(sdata.fTimeStamp));
845 fOnTime->setText(QString::number(sdata.fOnTimeCounter));
846
847 fFtmTemp0->setValue(sdata.fTempSensor[0]*0.1);
848 fFtmTemp1->setValue(sdata.fTempSensor[1]*0.1);
849 fFtmTemp2->setValue(sdata.fTempSensor[2]*0.1);
850 fFtmTemp3->setValue(sdata.fTempSensor[3]*0.1);
851
852
853 // ----------------------------------------------
854
855 TCanvas *c = fFtmTempCanv->GetCanvas();
856
857 static int cntr = 0;
858 double_t tm = cntr++;//Time().RootTime();
859
860 TH1 *h = (TH1*)c->FindObject("MyFrame");
861 h->FindBin(tm);
862
863 fGraphFtmTemp[0].SetPoint(fGraphFtmTemp[0].GetN(), tm, sdata.fTempSensor[0]*0.1);
864 fGraphFtmTemp[1].SetPoint(fGraphFtmTemp[1].GetN(), tm, sdata.fTempSensor[1]*0.1);
865 fGraphFtmTemp[2].SetPoint(fGraphFtmTemp[2].GetN(), tm, sdata.fTempSensor[2]*0.1);
866 fGraphFtmTemp[3].SetPoint(fGraphFtmTemp[3].GetN(), tm, sdata.fTempSensor[3]*0.1);
867
868 c->Modified();
869 c->Update();
870
871 // ----------------------------------------------
872
873 valarray<double> dat(0., 1438);
874
875 for (int i=0; i<1438; i++)
876 dat[i] = sdata.fRatePatch[fPatch[i]];
877
878 c = fRatesCanv->GetCanvas();
879 Camera *cam = (Camera*)c->FindObject("Camera");
880
881 cam->SetData(dat);
882
883 c->Modified();
884 c->Update();
885 }
886
887 FTM::DimStaticData fFtmStaticData;
888
889 void handleFtmStaticData(const DimData &d)
890 {
891 if (d.size()==0)
892 return;
893
894 if (d.size()!=sizeof(FTM::DimStaticData))
895 {
896 cout << "Size mismatch: " << d.size() << " " << sizeof(FTM::DimStaticData) << endl;
897 return;
898 }
899
900 const FTM::DimStaticData &sdata = *reinterpret_cast<const FTM::DimStaticData*>(d.ptr());
901
902 fTriggerInterval->setValue(sdata.fTriggerInterval);
903 fPhysicsCoincidence->setValue(sdata.fCoincidencePhysics);
904 fCalibCoincidence->setValue(sdata.fCoincidenceCalib);
905 fPhysicsWindow->setValue(sdata.fWindowPhysics);
906 fCalibWindow->setValue(sdata.fWindowCalib);
907
908 fTriggerDelay->setValue(sdata.fDelayTrigger);
909 fTimeMarkerDelay->setValue(sdata.fDelayTimeMarker);
910 fDeadTime->setValue(sdata.fDeadTime);
911
912 fClockCondR0->setValue(sdata.fClockConditioner[0]);
913 fClockCondR1->setValue(sdata.fClockConditioner[1]);
914 fClockCondR8->setValue(sdata.fClockConditioner[2]);
915 fClockCondR9->setValue(sdata.fClockConditioner[3]);
916 fClockCondR11->setValue(sdata.fClockConditioner[4]);
917 fClockCondR13->setValue(sdata.fClockConditioner[5]);
918 fClockCondR14->setValue(sdata.fClockConditioner[6]);
919 fClockCondR15->setValue(sdata.fClockConditioner[7]);
920
921 fTriggerSeqPed->setValue(sdata.fTriggerSeqPed);
922 fTriggerSeqLP1->setValue(sdata.fTriggerSeqLP1);
923 fTriggerSeqLP2->setValue(sdata.fTriggerSeqLP2);
924
925 fEnableTrigger->setChecked(sdata.HasTrigger());
926 fEnableLP1->setChecked(sdata.HasLP1());
927 fEnableLP2->setChecked(sdata.HasLP2());
928 fEnableVeto->setChecked(sdata.HasVeto());
929 fEnablePedestal->setChecked(sdata.HasPedestal());
930 fEnableExt1->setChecked(sdata.HasExt1());
931 fEnableExt2->setChecked(sdata.HasExt2());
932 fEnableTimeMarker->setChecked(sdata.HasTimeMarker());
933
934 cout << hex << sdata.fActiveFTU << dec << endl;
935
936 for (int i=0; i<64; i++)
937 std::cout << (sdata.fActiveFTU&(1<<i) ? 1 : 0);
938 std::cout << std::endl;
939
940 for (int i=0; i<40; i++)
941 if (!sdata.IsActive(i))
942 fFtuLED[i]->setIcon(QIcon(":/Resources/icons/gray circle 1.png"));
943 else
944 fFtuLED[i]->setIcon(QIcon(":/Resources/icons/green circle 1.png"));
945
946 Camera *cam = (Camera*)fRatesCanv->GetCanvas()->FindObject("Camera");
947 for (int i=0; i<1438; i++)
948 cam->SetEnable(i, sdata.IsEnabled(i));
949
950 const int patch1 = fThresholdIdx->value();
951 fThresholdVal->setValue(sdata.fThreshold[patch1<0?0:patch1]);
952
953 fPrescalingVal->setValue(sdata.fPrescaling[0]);
954
955 fFtmStaticData = sdata;
956 }
957
958 void handleFtmPassport(const DimData &d)
959 {
960 if (d.size()==0)
961 return;
962
963 if (d.size()!=sizeof(FTM::DimPassport))
964 {
965 cout << "Size mismatch: " << d.size() << " " << sizeof(FTM::DimPassport) << endl;
966 return;
967 }
968
969 const FTM::DimPassport &sdata = *reinterpret_cast<const FTM::DimPassport*>(d.ptr());
970
971 stringstream str1, str2;
972 str1 << hex << "0x" << setfill('0') << setw(16) << sdata.fBoardId;
973 str2 << sdata.fFirmwareId;
974
975 fFtmBoardId->setText(str1.str().c_str());
976 fFtmFirmwareId->setText(str2.str().c_str());
977 }
978
979 void handleFtmFtuList(const DimData &d)
980 {
981 if (d.size()==0)
982 return;
983
984 if (d.size()!=sizeof(FTM::DimFtuList))
985 {
986 cout << "Size mismatch: " << d.size() << " " << sizeof(FTM::DimFtuList) << endl;
987 return;
988 }
989
990 const FTM::DimFtuList &sdata = *reinterpret_cast<const FTM::DimFtuList*>(d.ptr());
991
992 stringstream str;
993 str << "<table width='100%'>" << setfill('0');
994 str << "<tr><th>Num</th><th></th><th>Addr</th><th></th><th>DNA</th></tr>";
995 for (int i=0; i<40; i++)
996 {
997 str << "<tr>";
998 str << "<td align='center'>" << dec << i << hex << "</td>";
999 str << "<td align='center'>:</td>";
1000 str << "<td align='center'>0x" << setw(2) << (int)sdata.fAddr[i] << "</td>";
1001 str << "<td align='center'>:</td>";
1002 str << "<td align='center'>0x" << setw(16) << sdata.fDNA[i] << "</td>";
1003 str << "</tr>";
1004 }
1005 str << "</table>";
1006
1007 fFtuDNA->setText(str.str().c_str());
1008
1009 fFtuAnswersTotal->setValue(sdata.fNumBoards);
1010 fFtuAnswersCrate0->setValue(sdata.fNumBoardsCrate[0]);
1011 fFtuAnswersCrate1->setValue(sdata.fNumBoardsCrate[1]);
1012 fFtuAnswersCrate2->setValue(sdata.fNumBoardsCrate[2]);
1013 fFtuAnswersCrate3->setValue(sdata.fNumBoardsCrate[3]);
1014
1015 cout << "FtuList received: fActiveFTU not handled yet." << endl;
1016
1017 for (int i=0; i<40; i++)
1018 {
1019 if (sdata.IsActive(i))
1020 {
1021 if (sdata.fPing[i]>0)
1022 fFtuLED[i]->setIcon(QIcon(":/Resources/icons/red circle 1.png"));
1023 else
1024 fFtuLED[i]->setIcon(QIcon(":/Resources/icons/green circle 1.png"));
1025 //if (sdata.fCRC[i]>0)
1026 // fFtuLED[i]->setIcon(QIcon(":/Resources/icons/warning 1.png"));
1027 }
1028 else
1029 fFtuLED[i]->setIcon(QIcon(":/Resources/icons/gray circle 1.png"));
1030 }
1031 }
1032
1033 void handleFtmError(const DimData &d)
1034 {
1035 if (d.size()==0)
1036 return;
1037 const Converter conv(d.format);
1038 cout << "Error:" << endl;
1039 cout << conv.GetString(&d.data[0], d.size()) << endl;
1040 }
1041
1042 // ====================== MessageImp ====================================
1043
1044 bool fChatOnline;
1045
1046 void handleStateChanged(const Time &/*time*/, const std::string &server,
1047 const State &s)
1048 {
1049 // FIXME: Prefix tooltip with time
1050 if (server=="FTM_CONTROL")
1051 {
1052 fStatusFTMLabel->setText(s.name.c_str());
1053 fStatusFTMLabel->setToolTip(s.comment.c_str());
1054
1055 bool enable = false;
1056
1057 if (s.index<FTM::kDisconnected) // No Dim connection
1058 fStatusFTMLed->setIcon(QIcon(":/Resources/icons/gray circle 1.png"));
1059 if (s.index==FTM::kDisconnected) // Dim connection / FTM disconnected
1060 fStatusFTMLed->setIcon(QIcon(":/Resources/icons/yellow circle 1.png"));
1061 if (s.index==FTM::kConnected || s.index==FTM::kIdle) // Dim connection / FTM connected
1062 {
1063 fStatusFTMLed->setIcon(QIcon(":/Resources/icons/green circle 1.png"));
1064 enable = true;
1065 }
1066
1067 fTriggerWidget->setEnabled(enable);
1068 fFtuWidget->setEnabled(enable);
1069 fRatesWidget->setEnabled(enable);
1070 }
1071
1072 if (server=="FAD_CONTROL")
1073 {
1074 fStatusFADLabel->setText(s.name.c_str());
1075 fStatusFADLabel->setToolTip(s.comment.c_str());
1076
1077 if (s.index<FTM::kDisconnected) // No Dim connection
1078 fStatusFADLed->setIcon(QIcon(":/Resources/icons/gray circle 1.png"));
1079 if (s.index==FTM::kDisconnected) // Dim connection / FTM disconnected
1080 fStatusFADLed->setIcon(QIcon(":/Resources/icons/yellow circle 1.png"));
1081 if (s.index==FTM::kConnected) // Dim connection / FTM connected
1082 fStatusFADLed->setIcon(QIcon(":/Resources/icons/green circle 1.png"));
1083 }
1084
1085 if (server=="DATA_LOGGER")
1086 {
1087 fStatusLoggerLabel->setText(s.name.c_str());
1088 fStatusLoggerLabel->setToolTip(s.comment.c_str());
1089
1090 bool enable = true;
1091
1092 if (s.index<=30) // Ready/Waiting
1093 fStatusLoggerLed->setIcon(QIcon(":/Resources/icons/yellow circle 1.png"));
1094 if (s.index<-1) // Offline
1095 {
1096 fStatusLoggerLed->setIcon(QIcon(":/Resources/icons/gray circle 1.png"));
1097 enable = false;
1098 }
1099 if (s.index>=0x100) // Error
1100 fStatusLoggerLed->setIcon(QIcon(":/Resources/icons/red circle 1.png"));
1101 if (s.index==40) // Logging
1102 fStatusLoggerLed->setIcon(QIcon(":/Resources/icons/green circle 1.png"));
1103
1104 cout << "enable " << s.index << " " << enable << endl;
1105 fLoggerWidget->setEnabled(enable);
1106 }
1107
1108 if (server=="CHAT")
1109 {
1110 fStatusChatLabel->setText(s.name.c_str());
1111
1112 fChatOnline = s.index;
1113
1114 if (fChatOnline) // Dim connection / FTM connected
1115 fStatusChatLed->setIcon(QIcon(":/Resources/icons/green circle 1.png"));
1116 else
1117 fStatusChatLed->setIcon(QIcon(":/Resources/icons/gray circle 1.png"));
1118 }
1119 }
1120
1121 void handleStateOffline(const string &server)
1122 {
1123 handleStateChanged(Time(), server, State(-2, "Offline", "No connection via DIM."));
1124 }
1125
1126 void on_fTabWidget_currentChanged(int which)
1127 {
1128 if (fTabWidget->tabText(which)=="Chat")
1129 fTabWidget->setTabIcon(which, QIcon());
1130 }
1131
1132 void handleWrite(const Time &time, const string &text, int qos)
1133 {
1134 stringstream out;
1135
1136 if (text.substr(0, 6)=="CHAT: ")
1137 {
1138 out << "<font size='-1' color='navy'>[<B>";
1139 out << Time::fmt("%H:%M:%S") << time << "</B>]</FONT> ";
1140 out << text.substr(6);
1141 fChatText->append(out.str().c_str());
1142
1143 if (fTabWidget->tabText(fTabWidget->currentIndex())=="Chat")
1144 return;
1145
1146 static int num = 0;
1147 if (num++<2)
1148 return;
1149
1150 for (int i=0; i<fTabWidget->count(); i++)
1151 if (fTabWidget->tabText(i)=="Chat")
1152 {
1153 fTabWidget->setTabIcon(i, QIcon(":/Resources/icons/warning 3.png"));
1154 break;
1155 }
1156
1157 return;
1158 }
1159
1160
1161 out << "<font color='";
1162
1163 switch (qos)
1164 {
1165 case kMessage: out << "black"; break;
1166 case kInfo: out << "green"; break;
1167 case kWarn: out << "#FF6600"; break;
1168 case kError: out << "maroon"; break;
1169 case kFatal: out << "maroon"; break;
1170 case kDebug: out << "navy"; break;
1171 default: out << "navy"; break;
1172 }
1173 out << "'>" << time.GetAsStr() << " - " << text << "</font>";
1174
1175 fLogText->append(out.str().c_str());
1176
1177 if (qos>=kWarn)
1178 fTextEdit->append(out.str().c_str());
1179 }
1180
1181 void IndicateStateChange(const Time &time, const std::string &server)
1182 {
1183 const State s = GetState(server, GetCurrentState(server));
1184
1185 QApplication::postEvent(this,
1186 new FunctionEvent(boost::bind(&FactGui::handleStateChanged, this, time, server, s)));
1187 }
1188
1189 int Write(const Time &time, const string &txt, int qos)
1190 {
1191 QApplication::postEvent(this,
1192 new FunctionEvent(boost::bind(&FactGui::handleWrite, this, time, txt, qos)));
1193
1194 return 0;
1195 }
1196
1197 // ====================== Dim infoHandler================================
1198
1199 void handleDimInfo(const DimData &d)
1200 {
1201 if (d.info==&fDimDNS)
1202 return handleDimDNS(d.get<unsigned int>());
1203
1204 cout << "HandleDimInfo " << d.name << endl;
1205
1206 if (d.info==&fDimLoggerStats)
1207 return handleLoggerStats(d);
1208
1209 if (d.info==&fDimLoggerFilenameNight)
1210 return handleLoggerFilenameNight(d);
1211
1212 if (d.info==&fDimLoggerNumSubs)
1213 return handleLoggerNumSubs(d);
1214
1215 if (d.info==&fDimLoggerFilenameRun)
1216 return handleLoggerFilenameRun(d);
1217
1218 if (d.info==&fDimFtmTriggerCounter)
1219 return handleFtmTriggerCounter(d);
1220
1221 if (d.info==&fDimFtmDynamicData)
1222 return handleFtmDynamicData(d);
1223
1224 if (d.info==&fDimFtmPassport)
1225 return handleFtmPassport(d);
1226
1227 if (d.info==&fDimFtmFtuList)
1228 return handleFtmFtuList(d);
1229
1230 if (d.info==&fDimFtmStaticData)
1231 return handleFtmStaticData(d);
1232
1233 if (d.info==&fDimFtmError)
1234 return handleFtmError(d);
1235 }
1236
1237 void handleDimService(const string &txt)
1238 {
1239 fDimSvcText->append(txt.c_str());
1240 }
1241
1242
1243 void infoHandlerService(DimInfo &info)
1244 {
1245 const string fmt = string(info.getFormat()).empty() ? "C" : info.getFormat();
1246
1247 stringstream dummy;
1248 const Converter conv(dummy, fmt, false);
1249
1250 const Time tm(info.getTimestamp(), info.getTimestampMillisecs()*1000);
1251
1252 stringstream out;
1253 out << "<font size'-1' color='navy'>[" << Time::fmt("%H:%M:%S.%f") << tm << "]</font> <B>" << info.getName() << "</B> - ";
1254
1255 bool iserr = true;
1256 if (!conv)
1257 {
1258 out << "Compilation of format string '" << fmt << "' failed!";
1259 }
1260 else
1261 {
1262 try
1263 {
1264 const string dat = conv.GetString(info.getData(), info.getSize());
1265 out << dat;
1266 iserr = false;
1267 }
1268 catch (const runtime_error &e)
1269 {
1270 out << "Conversion to string failed!<pre>" << e.what() << "</pre>";
1271 }
1272 }
1273
1274 // srand(hash<string>()(string(info.getName())));
1275 // int bg = rand()&0xffffff;
1276
1277 int bg = hash<string>()(string(info.getName()));
1278
1279 // allow only light colors
1280 bg = ~(bg&0x1f1f1f)&0xffffff;
1281
1282 if (iserr)
1283 bg = 0xffffff;
1284
1285 stringstream bgcol;
1286 bgcol << hex << setfill('0') << setw(6) << bg;
1287
1288 const string col = iserr ? "red" : "black";
1289 const string str = "<table width='100%' bgcolor=#"+bgcol.str()+"><tr><td><font color='"+col+"'>"+out.str()+"</font></td></tr></table>";
1290
1291 QApplication::postEvent(this,
1292 new FunctionEvent(boost::bind(&FactGui::handleDimService, this, str)));
1293 }
1294
1295 void infoHandler()
1296 {
1297 // Initialize the time-stamp (what a weird workaround...)
1298 getInfo()->getTimestamp();
1299
1300 if (std::find(fDim.begin(), fDim.end(), getInfo())!=fDim.end())
1301 {
1302 QApplication::postEvent(this,
1303 new FunctionEvent(boost::bind(&FactGui::handleDimInfo, this, DimData(getInfo()))));
1304 return;
1305 }
1306
1307 for (map<string,DimInfo*>::iterator i=fServices.begin(); i!=fServices.end(); i++)
1308 if (i->second==getInfo())
1309 {
1310 infoHandlerService(*i->second);
1311 return;
1312 }
1313
1314 DimNetwork::infoHandler();
1315 }
1316
1317
1318 // ======================================================================
1319
1320 bool event(QEvent *evt)
1321 {
1322 if (dynamic_cast<FunctionEvent*>(evt))
1323 return static_cast<FunctionEvent*>(evt)->Exec();
1324
1325 if (dynamic_cast<CheckBoxEvent*>(evt))
1326 {
1327 const QStandardItem &item = static_cast<CheckBoxEvent*>(evt)->item;
1328 const QStandardItem *par = item.parent();
1329 if (par)
1330 {
1331 const QString server = par->text();
1332 const QString service = item.text();
1333
1334 const string s = (server+'/'+service).toStdString();
1335
1336 if (item.checkState()==Qt::Checked)
1337 SubscribeService(s);
1338 else
1339 UnsubscribeService(s);
1340 }
1341 }
1342
1343 return MainWindow::event(evt); // unrecognized
1344 }
1345
1346 void on_fDimCmdSend_clicked()
1347 {
1348 const QString server = fDimCmdServers->currentIndex().data().toString();
1349 const QString command = fDimCmdCommands->currentIndex().data().toString();
1350 const QString arguments = fDimCmdLineEdit->displayText();
1351
1352 // FIXME: Sending a command exactly when the info Handler changes
1353 // the list it might lead to confusion.
1354 try
1355 {
1356 SendDimCommand(server.toStdString(), command.toStdString()+" "+arguments.toStdString());
1357 fTextEdit->append("<font color='green'>Command '"+server+'/'+command+"' successfully emitted.</font>");
1358 fDimCmdLineEdit->clear();
1359 }
1360 catch (const runtime_error &e)
1361 {
1362 stringstream txt;
1363 txt << e.what();
1364
1365 string buffer;
1366 while (getline(txt, buffer, '\n'))
1367 fTextEdit->append(("<font color='red'><pre>"+buffer+"</pre></font>").c_str());
1368 }
1369 }
1370 void ChoosePatch(Camera &cam, int idx)
1371 {
1372 cam.Reset();
1373
1374 fThresholdIdx->setValue(idx);
1375 fThresholdVal->setValue(fFtmStaticData.fThreshold[idx<0?0:idx]);
1376
1377 if (idx<0)
1378 return;
1379
1380 for (unsigned int i=0; i<fPatch.size(); i++)
1381 if (fPatch[i]==idx)
1382 cam.SetBold(i);
1383 }
1384
1385 void ChoosePixel(Camera &cam, int idx)
1386 {
1387 cam.SetWhite(idx);
1388 ChoosePatch(cam, fPatch[idx]);
1389 }
1390
1391 void slot_RootEventProcessed(TObject *obj, unsigned int evt, TCanvas *)
1392 {
1393 // kMousePressEvent // TCanvas processed QEvent mousePressEvent
1394 // kMouseMoveEvent // TCanvas processed QEvent mouseMoveEvent
1395 // kMouseReleaseEvent // TCanvas processed QEvent mouseReleaseEvent
1396 // kMouseDoubleClickEvent // TCanvas processed QEvent mouseDoubleClickEvent
1397 // kKeyPressEvent // TCanvas processed QEvent keyPressEvent
1398 // kEnterEvent // TCanvas processed QEvent enterEvent
1399 // kLeaveEvent // TCanvas processed QEvent leaveEvent
1400
1401 if (dynamic_cast<TCanvas*>(obj))
1402 return;
1403
1404 TQtWidget *tipped = static_cast<TQtWidget*>(sender());
1405
1406 if (evt==11/*kMouseReleaseEvent*/)
1407 {
1408 if (dynamic_cast<Camera*>(obj))
1409 {
1410 const float xx = gPad->PadtoX(gPad->AbsPixeltoX(tipped->GetEventX()));
1411 const float yy = gPad->PadtoY(gPad->AbsPixeltoY(tipped->GetEventY()));
1412
1413 Camera *cam = static_cast<Camera*>(obj);
1414 const int idx = cam->GetIdx(xx, yy);
1415
1416 ChoosePixel(*cam, idx);
1417 }
1418 return;
1419 }
1420
1421 if (evt==61/*kMouseDoubleClickEvent*/)
1422 {
1423 if (dynamic_cast<Camera*>(obj))
1424 {
1425 const float xx = gPad->PadtoX(gPad->AbsPixeltoX(tipped->GetEventX()));
1426 const float yy = gPad->PadtoY(gPad->AbsPixeltoY(tipped->GetEventY()));
1427
1428 Camera *cam = static_cast<Camera*>(obj);
1429 const int idx = cam->GetIdx(xx, yy);
1430
1431 cam->Toggle(idx);
1432 }
1433 return;
1434 }
1435
1436 // Find the object which will get picked by the GetObjectInfo
1437 // due to buffer overflows in many root-versions
1438 // in TH1 and TProfile we have to work around and implement
1439 // our own GetObjectInfo which make everything a bit more
1440 // complicated.
1441#if ROOT_VERSION_CODE > ROOT_VERSION(5,22,00)
1442 const char *objectInfo =
1443 obj->GetObjectInfo(tipped->GetEventX(),tipped->GetEventY());
1444#else
1445 const char *objectInfo = dynamic_cast<TH1*>(obj) ?
1446 "" : obj->GetObjectInfo(tipped->GetEventX(),tipped->GetEventY());
1447#endif
1448
1449 QString tipText;
1450 tipText += obj->GetName();
1451 tipText += " [";
1452 tipText += obj->ClassName();
1453 tipText += "]: ";
1454 tipText += objectInfo;
1455
1456 if (dynamic_cast<Camera*>(obj))
1457 {
1458 const float xx = gPad->PadtoX(gPad->AbsPixeltoX(tipped->GetEventX()));
1459 const float yy = gPad->PadtoY(gPad->AbsPixeltoY(tipped->GetEventY()));
1460
1461 Camera *cam = static_cast<Camera*>(obj);
1462 int idx = fPatch[cam->GetIdx(xx, yy)];
1463
1464 tipText+=" Patch=";
1465 tipText+=QString::number(idx);
1466 }
1467
1468
1469 fStatusBar->showMessage(tipText, 3000);
1470
1471 gSystem->ProcessEvents();
1472 //QWhatsThis::display(tipText)
1473 }
1474
1475 void slot_RootUpdate()
1476 {
1477 gSystem->ProcessEvents();
1478 QTimer::singleShot(100, this, SLOT(slot_RootUpdate()));
1479 }
1480 void on_fThresholdIdx_valueChanged(int idx)
1481 {
1482 Camera *cam = (Camera*)fRatesCanv->GetCanvas()->FindObject("Camera");
1483 ChoosePatch(*cam, idx);
1484 }
1485
1486 TGraph fGraphFtmTemp[4];
1487
1488 map<int, int> fPatch;
1489
1490public:
1491 FactGui() :
1492 fDimDNS("DIS_DNS/VERSION_NUMBER", 1, int(0), this),
1493
1494 fDimLoggerStats ("DATA_LOGGER/STATS", (void*)NULL, 0, this),
1495 fDimLoggerFilenameNight("DATA_LOGGER/FILENAME_NIGHT", const_cast<char*>(""), 0, this),
1496 fDimLoggerFilenameRun ("DATA_LOGGER/FILENAME_RUN", const_cast<char*>(""), 0, this),
1497 fDimLoggerNumSubs ("DATA_LOGGER/NUM_SUBS", const_cast<char*>(""), 0, this),
1498
1499 fDimFtmPassport ("FTM_CONTROL/PASSPORT", (void*)NULL, 0, this),
1500 fDimFtmTriggerCounter("FTM_CONTROL/TRIGGER_COUNTER", (void*)NULL, 0, this),
1501 fDimFtmError ("FTM_CONTROL/ERROR", (void*)NULL, 0, this),
1502 fDimFtmFtuList ("FTM_CONTROL/FTU_LIST", (void*)NULL, 0, this),
1503 fDimFtmStaticData ("FTM_CONTROL/STATIC_DATA", (void*)NULL, 0, this),
1504 fDimFtmDynamicData ("FTM_CONTROL/DYNAMIC_DATA", (void*)NULL, 0, this)
1505
1506
1507 {
1508 DimClient::sendCommand("CHAT/MSG", "GUI online.");
1509 // + MessageDimRX
1510
1511 fDim.push_back(&fDimFtmDynamicData);
1512 fDim.push_back(&fDimFtmTriggerCounter);
1513 fDim.push_back(&fDimFtmStaticData);
1514 fDim.push_back(&fDimFtmFtuList);
1515 fDim.push_back(&fDimFtmPassport);
1516 fDim.push_back(&fDimFtmError);
1517 fDim.push_back(&fDimLoggerStats);
1518 fDim.push_back(&fDimLoggerFilenameNight);
1519 fDim.push_back(&fDimLoggerFilenameRun);
1520 fDim.push_back(&fDimLoggerNumSubs);
1521 fDim.push_back(&fDimDNS);
1522
1523 fTriggerWidget->setEnabled(false);
1524 fFtuWidget->setEnabled(false);
1525 fRatesWidget->setEnabled(false);
1526 fLoggerWidget->setEnabled(false);
1527
1528 // --------------------------------------------------------------------------
1529
1530 ifstream fin("fact-trigger-all.txt");
1531
1532 int l = 0;
1533
1534 string buf;
1535 while (getline(fin, buf, '\n'))
1536 {
1537 buf = Tools::Trim(buf);
1538 if (buf[0]=='#')
1539 continue;
1540
1541 stringstream str(buf);
1542 for (int i=0; i<9; i++)
1543 {
1544 int n;
1545 str >> n;
1546
1547 fPatch[n] = l;
1548 }
1549 l++;
1550 }
1551
1552 // --------------------------------------------------------------------------
1553
1554 TCanvas *c = fFtmTempCanv->GetCanvas();
1555 c->SetBit(TCanvas::kNoContextMenu);
1556 c->SetBorderMode(0);
1557 c->SetFrameBorderMode(0);
1558 c->SetFillColor(kWhite);
1559 c->SetRightMargin(0.03);
1560 c->SetTopMargin(0.03);
1561 c->cd();
1562
1563 TH1F h("MyFrame", "", 1000, 0, 1);//Time().RootTime()-1./24/60/60, Time().RootTime());
1564 h.SetDirectory(0);
1565 h.SetBit(TH1::kCanRebin);
1566 h.SetStats(kFALSE);
1567 h.SetMinimum(-20);
1568 h.SetMaximum(100);
1569 h.SetXTitle("Time");
1570 h.SetYTitle("Temperature / °C");
1571 h.GetXaxis()->CenterTitle();
1572 h.GetYaxis()->CenterTitle();
1573// h.GetXaxis()->SetTitleSize(1.2);
1574// h.GetYaxis()->SetTitleSize(1.2);
1575 h.DrawCopy();
1576
1577 fGraphFtmTemp[0].SetMarkerStyle(kFullDotSmall);
1578 fGraphFtmTemp[1].SetMarkerStyle(kFullDotSmall);
1579 fGraphFtmTemp[2].SetMarkerStyle(kFullDotSmall);
1580 fGraphFtmTemp[3].SetMarkerStyle(kFullDotSmall);
1581
1582 fGraphFtmTemp[1].SetLineColor(kBlue);
1583 fGraphFtmTemp[2].SetLineColor(kRed);
1584 fGraphFtmTemp[3].SetLineColor(kGreen);
1585
1586 fGraphFtmTemp[1].SetMarkerColor(kBlue);
1587 fGraphFtmTemp[2].SetMarkerColor(kRed);
1588 fGraphFtmTemp[3].SetMarkerColor(kGreen);
1589
1590 fGraphFtmTemp[0].Draw("LP");
1591 fGraphFtmTemp[1].Draw("LP");
1592 fGraphFtmTemp[2].Draw("LP");
1593 fGraphFtmTemp[3].Draw("LP");
1594
1595 // --------------------------------------------------------------------------
1596
1597 c = fRatesCanv->GetCanvas();
1598 c->SetBit(TCanvas::kNoContextMenu);
1599 c->SetBorderMode(0);
1600 c->SetFrameBorderMode(0);
1601 c->SetFillColor(kWhite);
1602 c->cd();
1603
1604 Camera *cam = new Camera;
1605 cam->SetBit(kCanDelete);
1606 cam->Draw();
1607
1608 ChoosePixel(*cam, 1);
1609
1610 QTimer::singleShot(100, this, SLOT(slot_RootUpdate()));
1611
1612 //widget->setMouseTracking(true);
1613 //widget->EnableSignalEvents(kMouseMoveEvent);
1614
1615 fFtmTempCanv->setMouseTracking(true);
1616 fFtmTempCanv->EnableSignalEvents(kMouseMoveEvent);
1617
1618 fRatesCanv->setMouseTracking(true);
1619 fRatesCanv->EnableSignalEvents(kMouseMoveEvent|kMouseReleaseEvent|kMouseDoubleClickEvent);
1620
1621 connect(fRatesCanv, SIGNAL( RootEventProcessed(TObject *, unsigned int, TCanvas *)),
1622 this, SLOT (slot_RootEventProcessed(TObject *, unsigned int, TCanvas *)));
1623 connect(fFtmTempCanv, SIGNAL( RootEventProcessed(TObject *, unsigned int, TCanvas *)),
1624 this, SLOT (slot_RootEventProcessed(TObject *, unsigned int, TCanvas *)));
1625 }
1626 ~FactGui()
1627 {
1628 UnsubscribeAllServers();
1629 }
1630};
1631
1632#endif
Note: See TracBrowser for help on using the repository browser.