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

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