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

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