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

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