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

Last change on this file since 11111 was 11108, checked in by tbretz, 14 years ago
Fixed display of board and patch rate.
File size: 72.4 KB
Line 
1#ifndef FACT_FactGui
2#define FACT_FactGui
3
4#include "MainWindow.h"
5
6#include <iomanip>
7#include <valarray>
8
9#include <boost/bind.hpp>
10
11#include <QTimer>
12#include <QStandardItemModel>
13
14#include "CheckBoxDelegate.h"
15
16#include "src/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/1000000., float(sdata.fRatePatch[i])*2/fFtmStaticData.fPrescaling[i]);
1174 for (int i=0; i<40; i++)
1175 fGraphBoardRate[i].SetPoint(fGraphBoardRate[i].GetN(),
1176 t0+sdata.fTimeStamp/1000000., float(sdata.fRateBoard[i])*2/fFtmStaticData.fPrescaling[i]);
1177
1178 c->Modified();
1179 c->Update();
1180
1181 //fGraphFtmRate.ComputeRange(x[0], x[1], x[2], x[3]);
1182
1183 // ----------------------------------------------
1184
1185 if (fThresholdIdx->value()>=0)
1186 {
1187 const int isw = fThresholdIdx->value();
1188 const int ihw = fPatchMapHW[isw];
1189 fPatchRate->setValue(sdata.fRatePatch[ihw]);
1190 }
1191
1192 valarray<double> dat(0., 1440);
1193
1194 // fPatch converts from software id to software patch id
1195 for (int i=0; i<1440; i++)
1196 {
1197 const int ihw = fPatchHW[i];
1198// const int isw = fPatch[i];
1199// const int ihw = fPatchMapHW[isw];
1200 dat[i] = sdata.fRatePatch[ihw];
1201 }
1202
1203 c = fRatesCanv->GetCanvas();
1204 Camera *cam = (Camera*)c->FindObject("Camera");
1205
1206 cam->SetData(dat);
1207
1208 c->Modified();
1209 c->Update();
1210
1211 // ----------------------------------------------
1212#endif
1213 }
1214
1215 void DisplayRates()
1216 {
1217#ifdef HAVE_ROOT
1218 TCanvas *c = fFtmRateCanv->GetCanvas();
1219
1220 while (c->FindObject("PatchRate"))
1221 c->GetListOfPrimitives()->Remove(c->FindObject("PatchRate"));
1222
1223 while (c->FindObject("BoardRate"))
1224 c->GetListOfPrimitives()->Remove(c->FindObject("BoardRate"));
1225
1226 c->cd();
1227
1228 if (fRatePatch1->value()>=0)
1229 {
1230 fGraphPatchRate[fRatePatch1->value()].SetLineColor(kRed);
1231 fGraphPatchRate[fRatePatch1->value()].SetMarkerColor(kRed);
1232 fGraphPatchRate[fRatePatch1->value()].Draw("PL");
1233 }
1234 if (fRatePatch2->value()>=0)
1235 {
1236 fGraphPatchRate[fRatePatch2->value()].SetLineColor(kGreen);
1237 fGraphPatchRate[fRatePatch2->value()].SetMarkerColor(kGreen);
1238 fGraphPatchRate[fRatePatch2->value()].Draw("PL");
1239 }
1240 if (fRateBoard1->value()>=0)
1241 {
1242 fGraphBoardRate[fRateBoard1->value()].SetLineColor(kMagenta);
1243 fGraphBoardRate[fRateBoard1->value()].SetMarkerColor(kMagenta);
1244 fGraphBoardRate[fRateBoard1->value()].Draw("PL");
1245 }
1246 if (fRateBoard2->value()>=0)
1247 {
1248 fGraphBoardRate[fRateBoard2->value()].SetLineColor(kCyan);
1249 fGraphBoardRate[fRateBoard2->value()].SetMarkerColor(kCyan);
1250 fGraphBoardRate[fRateBoard2->value()].Draw("PL");
1251 }
1252#endif
1253 }
1254
1255 void on_fRatePatch1_valueChanged(int)
1256 {
1257 DisplayRates();
1258 }
1259
1260 void on_fRatePatch2_valueChanged(int)
1261 {
1262 DisplayRates();
1263 }
1264
1265 void on_fRateBoard1_valueChanged(int)
1266 {
1267 DisplayRates();
1268 }
1269
1270 void on_fRateBoard2_valueChanged(int)
1271 {
1272 DisplayRates();
1273 }
1274
1275 FTM::DimStaticData fFtmStaticData;
1276
1277 void SetFtuLed(int idx, int counter, const Time &t)
1278 {
1279 if (counter==0 || counter>3)
1280 counter = 3;
1281
1282 if (counter<0)
1283 counter = 0;
1284
1285 const LedColor_t col[4] = { kLedGray, kLedGreen, kLedOrange, kLedRed };
1286
1287 SetLedColor(fFtuLED[idx], col[counter], t);
1288
1289 fFtuStatus[idx] = counter;
1290 }
1291
1292 void SetFtuStatusLed(const Time &t)
1293 {
1294 const int max = fFtuStatus.max();
1295
1296 switch (max)
1297 {
1298 case 0:
1299 SetLedColor(fStatusFTULed, kLedGray, t);
1300 fStatusFTULabel->setText("All disabled");
1301 fStatusFTULabel->setToolTip("All FTUs are disabled");
1302 break;
1303
1304 case 1:
1305 SetLedColor(fStatusFTULed, kLedGreen, t);
1306 fStatusFTULabel->setToolTip("Communication with FTU is smooth.");
1307 fStatusFTULabel->setText("ok");
1308 break;
1309
1310 case 2:
1311 SetLedColor(fStatusFTULed, kLedOrange, t);
1312 fStatusFTULabel->setText("Warning");
1313 fStatusFTULabel->setToolTip("At least one FTU didn't answer immediately");
1314 break;
1315
1316 case 3:
1317 SetLedColor(fStatusFTULed, kLedRed, t);
1318 fStatusFTULabel->setToolTip("At least one FTU didn't answer!");
1319 fStatusFTULabel->setText("ERROR");
1320 break;
1321 }
1322
1323 const int cnt = count(&fFtuStatus[0], &fFtuStatus[40], 0);
1324 fFtuAllOn->setEnabled(cnt!=0);
1325 fFtuAllOff->setEnabled(cnt!=40);
1326 }
1327
1328 void handleFtmStaticData(const DimData &d)
1329 {
1330 if (!CheckSize(d, sizeof(FTM::DimStaticData)))
1331 return;
1332
1333 const FTM::DimStaticData &sdata = d.ref<FTM::DimStaticData>();
1334
1335 fTriggerInterval->setValue(sdata.fTriggerInterval);
1336 fPhysicsCoincidence->setValue(sdata.fMultiplicityPhysics);
1337 fCalibCoincidence->setValue(sdata.fMultiplicityCalib);
1338 fPhysicsWindow->setValue(sdata.fWindowPhysics);
1339 fCalibWindow->setValue(sdata.fWindowCalib);
1340
1341 fTriggerDelay->setValue(sdata.fDelayTrigger);
1342 fTimeMarkerDelay->setValue(sdata.fDelayTimeMarker);
1343 fDeadTime->setValue(sdata.fDeadTime);
1344
1345 fClockCondR0->setValue(sdata.fClockConditioner[0]);
1346 fClockCondR1->setValue(sdata.fClockConditioner[1]);
1347 fClockCondR8->setValue(sdata.fClockConditioner[2]);
1348 fClockCondR9->setValue(sdata.fClockConditioner[3]);
1349 fClockCondR11->setValue(sdata.fClockConditioner[4]);
1350 fClockCondR13->setValue(sdata.fClockConditioner[5]);
1351 fClockCondR14->setValue(sdata.fClockConditioner[6]);
1352 fClockCondR15->setValue(sdata.fClockConditioner[7]);
1353
1354 //fClockCondFreq->setEditText("");
1355 fClockCondFreq->setCurrentIndex(0);
1356
1357 fTriggerSeqPed->setValue(sdata.fTriggerSeqPed);
1358 fTriggerSeqLPint->setValue(sdata.fTriggerSeqLPint);
1359 fTriggerSeqLPext->setValue(sdata.fTriggerSeqLPext);
1360
1361 fEnableTrigger->setChecked(sdata.HasTrigger());
1362 fEnableVeto->setChecked(sdata.HasVeto());
1363 fEnableExt1->setChecked(sdata.HasExt1());
1364 fEnableExt2->setChecked(sdata.HasExt2());
1365 fEnableClockCond->setChecked(sdata.HasClockConditioner());
1366
1367 for (int i=0; i<40; i++)
1368 {
1369 if (!sdata.IsActive(i))
1370 SetFtuLed(i, -1, d.time);
1371 else
1372 {
1373 if (fFtuStatus[i]==0)
1374 SetFtuLed(i, 1, d.time);
1375 }
1376 fFtuLED[i]->setChecked(false);
1377 }
1378 SetFtuStatusLed(d.time);
1379
1380#ifdef HAVE_ROOT
1381 Camera *cam = (Camera*)fRatesCanv->GetCanvas()->FindObject("Camera");
1382 for (int isw=0; isw<1440; isw++)
1383 {
1384 const int ihw = fPixelMapHW[isw];
1385 cam->SetEnable(isw, sdata.IsEnabled(ihw));
1386 }
1387
1388 fRatesCanv->GetCanvas()->Modified();
1389 fRatesCanv->GetCanvas()->Update();
1390#endif
1391
1392 {
1393 const int isw = fPixelIdx->value();
1394 const int ihw = fPixelMapHW[isw];
1395 const bool on = sdata.IsEnabled(ihw);
1396 fPixelEnable->setChecked(on);
1397 }
1398
1399 if (fThresholdIdx->value()>=0)
1400 {
1401 const int isw = fThresholdIdx->value();
1402 const int ihw = fPatchMapHW[isw];
1403 fThresholdVal->setValue(sdata.fThreshold[ihw]);
1404 }
1405
1406 fPrescalingVal->setValue(sdata.fPrescaling[0]);
1407
1408 fFtmStaticData = sdata;
1409 }
1410
1411 void handleFtmPassport(const DimData &d)
1412 {
1413 if (!CheckSize(d, sizeof(FTM::DimPassport)))
1414 return;
1415
1416 const FTM::DimPassport &sdata = d.ref<FTM::DimPassport>();
1417
1418 stringstream str1, str2;
1419 str1 << hex << "0x" << setfill('0') << setw(16) << sdata.fBoardId;
1420 str2 << sdata.fFirmwareId;
1421
1422 fFtmBoardId->setText(str1.str().c_str());
1423 fFtmFirmwareId->setText(str2.str().c_str());
1424 }
1425
1426 void handleFtmFtuList(const DimData &d)
1427 {
1428 if (!CheckSize(d, sizeof(FTM::DimFtuList)))
1429 return;
1430
1431 fFtuPing->setChecked(false);
1432
1433 const FTM::DimFtuList &sdata = d.ref<FTM::DimFtuList>();
1434
1435 stringstream str;
1436 str << "<table width='100%'>" << setfill('0');
1437 str << "<tr><th>Num</th><th></th><th>Addr</th><th></th><th>DNA</th></tr>";
1438 for (int i=0; i<40; i++)
1439 {
1440 str << "<tr>";
1441 str << "<td align='center'>" << dec << i << hex << "</td>";
1442 str << "<td align='center'>:</td>";
1443 str << "<td align='center'>0x" << setw(2) << (int)sdata.fAddr[i] << "</td>";
1444 str << "<td align='center'>:</td>";
1445 str << "<td align='center'>0x" << setw(16) << sdata.fDNA[i] << "</td>";
1446 str << "</tr>";
1447 }
1448 str << "</table>";
1449
1450 fFtuDNA->setText(str.str().c_str());
1451
1452 fFtuAnswersTotal->setValue(sdata.fNumBoards);
1453 fFtuAnswersCrate0->setValue(sdata.fNumBoardsCrate[0]);
1454 fFtuAnswersCrate1->setValue(sdata.fNumBoardsCrate[1]);
1455 fFtuAnswersCrate2->setValue(sdata.fNumBoardsCrate[2]);
1456 fFtuAnswersCrate3->setValue(sdata.fNumBoardsCrate[3]);
1457
1458 for (int i=0; i<40; i++)
1459 SetFtuLed(i, sdata.IsActive(i) ? sdata.fPing[i] : -1, d.time);
1460
1461 SetFtuStatusLed(d.time);
1462 }
1463
1464 void handleFtmError(const DimData &d)
1465 {
1466 if (!CheckSize(d, sizeof(FTM::DimError)))
1467 return;
1468
1469 const FTM::DimError &sdata = d.ref<FTM::DimError>();
1470
1471 SetFtuLed(sdata.fError.fDestAddress , sdata.fError.fNumCalls, d.time);
1472 SetFtuStatusLed(d.time);
1473
1474 // FIXME: Write to special window!
1475 //Out() << "Error:" << endl;
1476 //Out() << sdata.fError << endl;
1477 }
1478
1479 // ====================== MessageImp ====================================
1480
1481 bool fChatOnline;
1482
1483 void handleStateChanged(const Time &time, const std::string &server,
1484 const State &s)
1485 {
1486 // FIXME: Prefix tooltip with time
1487 if (server=="FTM_CONTROL")
1488 {
1489 // FIXME: Enable FTU page!!!
1490 fStatusFTMLabel->setText(s.name.c_str());
1491 fStatusFTMLabel->setToolTip(s.comment.c_str());
1492
1493 bool enable = false;
1494
1495 if (s.index<FTM::kDisconnected) // No Dim connection
1496 SetLedColor(fStatusFTMLed, kLedGray, time);
1497 if (s.index==FTM::kDisconnected) // Dim connection / FTM disconnected
1498 SetLedColor(fStatusFTMLed, kLedYellow, time);
1499 if (s.index==FTM::kConnected || s.index==FTM::kIdle || s.index==FTM::kTakingData) // Dim connection / FTM connected
1500 SetLedColor(fStatusFTMLed, kLedGreen, time);
1501
1502 if (s.index==FTM::kConnected || s.index==FTM::kIdle) // Dim connection / FTM connected
1503 enable = true;
1504
1505 fTriggerWidget->setEnabled(enable);
1506 fFtuWidget->setEnabled(enable);
1507 fRatesWidget->setEnabled(enable);
1508
1509 if (!enable)
1510 {
1511 SetLedColor(fStatusFTULed, kLedGray, time);
1512 fStatusFTULabel->setText("Offline");
1513 fStatusFTULabel->setToolTip("FTM is not online.");
1514 }
1515 }
1516
1517 if (server=="FAD_CONTROL")
1518 {
1519 fStatusFADLabel->setText(s.name.c_str());
1520 fStatusFADLabel->setToolTip(s.comment.c_str());
1521
1522 bool enable = false;
1523
1524 if (s.index<FAD::kDisconnected) // No Dim connection
1525 SetLedColor(fStatusFADLed, kLedGray, time);
1526 if (s.index==FAD::kOffline) // Dim connection / FTM disconnected
1527 SetLedColor(fStatusFADLed, kLedRed, time);
1528 if (s.index==FAD::kDisconnected) // Dim connection / FTM disconnected
1529 SetLedColor(fStatusFADLed, kLedOrange, time);
1530 if (s.index==FAD::kConnecting) // Dim connection / FTM disconnected
1531 {
1532 SetLedColor(fStatusFADLed, kLedYellow, time);
1533 // FIXME FIXME FIXME: The LEDs are not displayed when disabled!
1534 enable = true;
1535 }
1536 if (s.index>=FAD::kConnected) // Dim connection / FTM connected
1537 {
1538 SetLedColor(fStatusFADLed, kLedGreen, time);
1539 enable = true;
1540 }
1541
1542 fFadWidget->setEnabled(enable);
1543 }
1544
1545 if (server=="DATA_LOGGER")
1546 {
1547 fStatusLoggerLabel->setText(s.name.c_str());
1548 fStatusLoggerLabel->setToolTip(s.comment.c_str());
1549
1550 bool enable = true;
1551
1552 if (s.index<=30) // Ready/Waiting
1553 SetLedColor(fStatusLoggerLed, kLedYellow, time);
1554 if (s.index<-1) // Offline
1555 {
1556 SetLedColor(fStatusLoggerLed, kLedGray, time);
1557 enable = false;
1558 }
1559 if (s.index>=0x100) // Error
1560 SetLedColor(fStatusLoggerLed, kLedRed, time);
1561 if (s.index==40) // Logging
1562 SetLedColor(fStatusLoggerLed, kLedGreen, time);
1563
1564 fLoggerWidget->setEnabled(enable);
1565 }
1566
1567 if (server=="CHAT")
1568 {
1569 fStatusChatLabel->setText(s.name.c_str());
1570
1571 fChatOnline = s.index==0;
1572
1573 SetLedColor(fStatusChatLed, fChatOnline ? kLedGreen : kLedGray, time);
1574
1575 fChatSend->setEnabled(fChatOnline);
1576 fChatMessage->setEnabled(fChatOnline);
1577 }
1578
1579 if (server=="SCHEDULER")
1580 {
1581 fStatusSchedulerLabel->setText(s.name.c_str());
1582
1583 SetLedColor(fStatusSchedulerLed, s.index>=0 ? kLedGreen : kLedRed, time);
1584 }
1585 }
1586
1587 void handleStateOffline(const string &server)
1588 {
1589 handleStateChanged(Time(), server, State(-2, "Offline", "No connection via DIM."));
1590 }
1591
1592 void on_fTabWidget_currentChanged(int which)
1593 {
1594 if (fTabWidget->tabText(which)=="Chat")
1595 fTabWidget->setTabIcon(which, QIcon());
1596 }
1597
1598 void handleWrite(const Time &time, const string &text, int qos)
1599 {
1600 stringstream out;
1601
1602 if (text.substr(0, 6)=="CHAT: ")
1603 {
1604 if (qos==MessageImp::kDebug)
1605 return;
1606
1607 out << "<font size='-1' color='navy'>[<B>";
1608 out << Time::fmt("%H:%M:%S") << time << "</B>]</FONT> ";
1609 out << text.substr(6);
1610 fChatText->append(out.str().c_str());
1611
1612 if (fTabWidget->tabText(fTabWidget->currentIndex())=="Chat")
1613 return;
1614
1615 static int num = 0;
1616 if (num++<2)
1617 return;
1618
1619 for (int i=0; i<fTabWidget->count(); i++)
1620 if (fTabWidget->tabText(i)=="Chat")
1621 {
1622 fTabWidget->setTabIcon(i, QIcon(":/Resources/icons/warning 3.png"));
1623 break;
1624 }
1625
1626 return;
1627 }
1628
1629
1630 out << "<font style='font-family:monospace' color='";
1631
1632 switch (qos)
1633 {
1634 case kMessage: out << "black"; break;
1635 case kInfo: out << "green"; break;
1636 case kWarn: out << "#FF6600"; break;
1637 case kError: out << "maroon"; break;
1638 case kFatal: out << "maroon"; break;
1639 case kDebug: out << "navy"; break;
1640 default: out << "navy"; break;
1641 }
1642 out << "'>" << time.GetAsStr() << " - " << text << "</font>";
1643
1644 fLogText->append(out.str().c_str());
1645
1646 if (qos>=kWarn)
1647 fTextEdit->append(out.str().c_str());
1648 }
1649
1650 void IndicateStateChange(const Time &time, const std::string &server)
1651 {
1652 const State s = GetState(server, GetCurrentState(server));
1653
1654 QApplication::postEvent(this,
1655 new FunctionEvent(boost::bind(&FactGui::handleStateChanged, this, time, server, s)));
1656 }
1657
1658 int Write(const Time &time, const string &txt, int qos)
1659 {
1660 QApplication::postEvent(this,
1661 new FunctionEvent(boost::bind(&FactGui::handleWrite, this, time, txt, qos)));
1662
1663 return 0;
1664 }
1665
1666 // ====================== Dim infoHandler================================
1667
1668 void handleDimService(const string &txt)
1669 {
1670 fDimSvcText->append(txt.c_str());
1671 }
1672
1673 void infoHandlerService(DimInfo &info)
1674 {
1675 const string fmt = string(info.getFormat()).empty() ? "C" : info.getFormat();
1676
1677 stringstream dummy;
1678 const Converter conv(dummy, fmt, false);
1679
1680 const Time tm(info.getTimestamp(), info.getTimestampMillisecs()*1000);
1681
1682 stringstream out;
1683 out << "<font size'-1' color='navy'>[" << Time::fmt("%H:%M:%S.%f") << tm << "]</font> <B>" << info.getName() << "</B> - ";
1684
1685 bool iserr = true;
1686 if (!conv)
1687 {
1688 out << "Compilation of format string '" << fmt << "' failed!";
1689 }
1690 else
1691 {
1692 try
1693 {
1694 const string dat = conv.GetString(info.getData(), info.getSize());
1695 out << dat;
1696 iserr = false;
1697 }
1698 catch (const runtime_error &e)
1699 {
1700 out << "Conversion to string failed!<pre>" << e.what() << "</pre>";
1701 }
1702 }
1703
1704 // srand(hash<string>()(string(info.getName())));
1705 // int bg = rand()&0xffffff;
1706
1707 int bg = hash<string>()(string(info.getName()));
1708
1709 // allow only light colors
1710 bg = ~(bg&0x1f1f1f)&0xffffff;
1711
1712 if (iserr)
1713 bg = 0xffffff;
1714
1715 stringstream bgcol;
1716 bgcol << hex << setfill('0') << setw(6) << bg;
1717
1718 const string col = iserr ? "red" : "black";
1719 const string str = "<table width='100%' bgcolor=#"+bgcol.str()+"><tr><td><font color='"+col+"'>"+out.str()+"</font></td></tr></table>";
1720
1721 QApplication::postEvent(this,
1722 new FunctionEvent(boost::bind(&FactGui::handleDimService, this, str)));
1723 }
1724
1725 void CallInfoHandler(void (FactGui::*handler)(const DimData&), const DimData &d)
1726 {
1727 fInHandler = true;
1728 (this->*handler)(d);
1729 fInHandler = false;
1730 }
1731
1732 /*
1733 void CallInfoHandler(const boost::function<void()> &func)
1734 {
1735 // This ensures that newly received values are not sent back to the emitter
1736 // because changing the value emits the valueChanged signal (or similar)
1737 fInHandler = true;
1738 func();
1739 fInHandler = false;
1740 }*/
1741
1742 void PostInfoHandler(void (FactGui::*handler)(const DimData&))
1743 {
1744 //const boost::function<void()> f = boost::bind(handler, this, DimData(getInfo()));
1745
1746 FunctionEvent *evt = new FunctionEvent(boost::bind(&FactGui::CallInfoHandler, this, handler, DimData(getInfo())));
1747 // FunctionEvent *evt = new FunctionEvent(boost::bind(&FactGui::CallInfoHandler, this, f));
1748 // FunctionEvent *evt = new FunctionEvent(boost::bind(handler, this, DimData(getInfo()))));
1749
1750 QApplication::postEvent(this, evt);
1751 }
1752
1753 void infoHandler()
1754 {
1755 // Initialize the time-stamp (what a weird workaround...)
1756 if (getInfo())
1757 getInfo()->getTimestamp();
1758
1759 if (getInfo()==&fDimDNS)
1760 return PostInfoHandler(&FactGui::handleDimDNS);
1761#ifdef DEBUG_DIM
1762 cout << "HandleDimInfo " << getInfo()->getName() << endl;
1763#endif
1764 if (getInfo()==&fDimLoggerStats)
1765 return PostInfoHandler(&FactGui::handleLoggerStats);
1766
1767 if (getInfo()==&fDimFadFiles)
1768 return PostInfoHandler(&FactGui::handleFadFiles);
1769
1770 if (getInfo()==&fDimFadConnections)
1771 return PostInfoHandler(&FactGui::handleFadConnections);
1772
1773 if (getInfo()==&fDimFadEvents)
1774 return PostInfoHandler(&FactGui::handleFadEvents);
1775
1776 if (getInfo()==&fDimFadRuns)
1777 return PostInfoHandler(&FactGui::handleFadRuns);
1778
1779 if (getInfo()==&fDimFadCurrentEvent)
1780 return PostInfoHandler(&FactGui::handleFadCurrentEvent);
1781
1782/*
1783 if (getInfo()==&fDimFadSetup)
1784 return PostInfoHandler(&FactGui::handleFadSetup);
1785*/
1786 if (getInfo()==&fDimLoggerFilenameNight)
1787 return PostInfoHandler(&FactGui::handleLoggerFilenameNight);
1788
1789 if (getInfo()==&fDimLoggerNumSubs)
1790 return PostInfoHandler(&FactGui::handleLoggerNumSubs);
1791
1792 if (getInfo()==&fDimLoggerFilenameRun)
1793 return PostInfoHandler(&FactGui::handleLoggerFilenameRun);
1794
1795 if (getInfo()==&fDimFtmTriggerCounter)
1796 return PostInfoHandler(&FactGui::handleFtmTriggerCounter);
1797
1798 if (getInfo()==&fDimFtmCounter)
1799 return PostInfoHandler(&FactGui::handleFtmCounter);
1800
1801 if (getInfo()==&fDimFtmDynamicData)
1802 return PostInfoHandler(&FactGui::handleFtmDynamicData);
1803
1804 if (getInfo()==&fDimFtmPassport)
1805 return PostInfoHandler(&FactGui::handleFtmPassport);
1806
1807 if (getInfo()==&fDimFtmFtuList)
1808 return PostInfoHandler(&FactGui::handleFtmFtuList);
1809
1810 if (getInfo()==&fDimFtmStaticData)
1811 return PostInfoHandler(&FactGui::handleFtmStaticData);
1812
1813 if (getInfo()==&fDimFtmError)
1814 return PostInfoHandler(&FactGui::handleFtmError);
1815
1816 if (getInfo()==&fDimFadFiles)
1817 return PostInfoHandler(&FactGui::handleFadFiles);
1818
1819 for (map<string,DimInfo*>::iterator i=fServices.begin(); i!=fServices.end(); i++)
1820 if (i->second==getInfo())
1821 {
1822 infoHandlerService(*i->second);
1823 return;
1824 }
1825
1826 DimNetwork::infoHandler();
1827 }
1828
1829
1830 // ======================================================================
1831
1832 bool event(QEvent *evt)
1833 {
1834 if (dynamic_cast<FunctionEvent*>(evt))
1835 return static_cast<FunctionEvent*>(evt)->Exec();
1836
1837 if (dynamic_cast<CheckBoxEvent*>(evt))
1838 {
1839 const QStandardItem &item = static_cast<CheckBoxEvent*>(evt)->item;
1840 const QStandardItem *par = item.parent();
1841 if (par)
1842 {
1843 const QString server = par->text();
1844 const QString service = item.text();
1845
1846 const string s = (server+'/'+service).toStdString();
1847
1848 if (item.checkState()==Qt::Checked)
1849 SubscribeService(s);
1850 else
1851 UnsubscribeService(s);
1852 }
1853 }
1854
1855 return MainWindow::event(evt); // unrecognized
1856 }
1857
1858 void on_fDimCmdSend_clicked()
1859 {
1860 const QString server = fDimCmdServers->currentIndex().data().toString();
1861 const QString command = fDimCmdCommands->currentIndex().data().toString();
1862 const QString arguments = fDimCmdLineEdit->displayText();
1863
1864 // FIXME: Sending a command exactly when the info Handler changes
1865 // the list it might lead to confusion.
1866 try
1867 {
1868 SendDimCommand(server.toStdString(), command.toStdString()+" "+arguments.toStdString());
1869 fTextEdit->append("<font color='green'>Command '"+server+'/'+command+"' successfully emitted.</font>");
1870 fDimCmdLineEdit->clear();
1871 }
1872 catch (const runtime_error &e)
1873 {
1874 stringstream txt;
1875 txt << e.what();
1876
1877 string buffer;
1878 while (getline(txt, buffer, '\n'))
1879 fTextEdit->append(("<font color='red'><pre>"+buffer+"</pre></font>").c_str());
1880 }
1881 }
1882
1883#ifdef HAVE_ROOT
1884 void slot_RootEventProcessed(TObject *obj, unsigned int evt, TCanvas *canv)
1885 {
1886 // kMousePressEvent // TCanvas processed QEvent mousePressEvent
1887 // kMouseMoveEvent // TCanvas processed QEvent mouseMoveEvent
1888 // kMouseReleaseEvent // TCanvas processed QEvent mouseReleaseEvent
1889 // kMouseDoubleClickEvent // TCanvas processed QEvent mouseDoubleClickEvent
1890 // kKeyPressEvent // TCanvas processed QEvent keyPressEvent
1891 // kEnterEvent // TCanvas processed QEvent enterEvent
1892 // kLeaveEvent // TCanvas processed QEvent leaveEvent
1893 if (dynamic_cast<TCanvas*>(obj))
1894 return;
1895
1896 TQtWidget *tipped = static_cast<TQtWidget*>(sender());
1897
1898 if (evt==11/*kMouseReleaseEvent*/)
1899 {
1900 if (dynamic_cast<Camera*>(obj))
1901 {
1902 const float xx = canv->AbsPixeltoX(tipped->GetEventX());
1903 const float yy = canv->AbsPixeltoY(tipped->GetEventY());
1904
1905 Camera *cam = static_cast<Camera*>(obj);
1906 const int isw = cam->GetIdx(xx, yy);
1907
1908 fPixelIdx->setValue(isw);
1909 ChoosePixel(*cam, isw);
1910 }
1911 return;
1912 }
1913
1914 if (evt==61/*kMouseDoubleClickEvent*/)
1915 {
1916 if (dynamic_cast<Camera*>(obj))
1917 {
1918 const float xx = canv->AbsPixeltoX(tipped->GetEventX());
1919 const float yy = canv->AbsPixeltoY(tipped->GetEventY());
1920
1921 Camera *cam = static_cast<Camera*>(obj);
1922 const int isw = cam->GetIdx(xx, yy);
1923
1924 ChoosePixel(*cam, isw);
1925
1926 fPixelIdx->setValue(isw);
1927
1928 const uint16_t ihw = fPixelMapHW[isw];
1929
1930 Dim::SendCommand("FTM_CONTROL/TOGGLE_PIXEL", ihw);
1931 }
1932
1933 if (dynamic_cast<TAxis*>(obj))
1934 static_cast<TAxis*>(obj)->UnZoom();
1935
1936 return;
1937 }
1938
1939 // Find the object which will get picked by the GetObjectInfo
1940 // due to buffer overflows in many root-versions
1941 // in TH1 and TProfile we have to work around and implement
1942 // our own GetObjectInfo which make everything a bit more
1943 // complicated.
1944 canv->cd();
1945#if ROOT_VERSION_CODE > ROOT_VERSION(5,22,00)
1946 const char *objectInfo =
1947 obj->GetObjectInfo(tipped->GetEventX(),tipped->GetEventY());
1948#else
1949 const char *objectInfo = dynamic_cast<TH1*>(obj) ?
1950 "" : obj->GetObjectInfo(tipped->GetEventX(),tipped->GetEventY());
1951#endif
1952
1953 QString tipText;
1954 tipText += obj->GetName();
1955 tipText += " [";
1956 tipText += obj->ClassName();
1957 tipText += "]: ";
1958 tipText += objectInfo;
1959
1960 if (dynamic_cast<Camera*>(obj))
1961 {
1962 const float xx = canv->AbsPixeltoX(tipped->GetEventX());
1963 const float yy = canv->AbsPixeltoY(tipped->GetEventY());
1964
1965 Camera *cam = static_cast<Camera*>(obj);
1966
1967 const int isw = cam->GetIdx(xx, yy);
1968 const int ihw = fPixelMapHW[isw];
1969
1970 const int idx = fPatchHW[isw];
1971
1972 int ii = 0;
1973 for (; ii<160; ii++)
1974 if (idx==fPatchMapHW[ii])
1975 break;
1976
1977
1978 const int patch = ihw%4;
1979 const int board = (ihw/4)%10;
1980 const int crate = (ihw/4)/10;
1981
1982 ostringstream str;
1983 str << " (hw=" << ihw << ") Patch=" << ii << " (hw=" << fPatchMapHW[idx] << "; Crate=" << crate << " Board=" << board << " Patch=" << patch << ")";
1984
1985 tipText += str.str().c_str();
1986 }
1987
1988
1989 fStatusBar->showMessage(tipText, 3000);
1990
1991 gSystem->ProcessEvents();
1992 //QWhatsThis::display(tipText)
1993 }
1994
1995 void slot_RootUpdate()
1996 {
1997 gSystem->ProcessEvents();
1998 QTimer::singleShot(0, this, SLOT(slot_RootUpdate()));
1999 }
2000
2001 void ChoosePatch(Camera &cam, int isw)
2002 {
2003 cam.Reset();
2004
2005 fThresholdIdx->setValue(isw);
2006
2007 const int ihw = isw<0 ? 0 : fPatchMapHW[isw];
2008
2009 fPatchRate->setEnabled(isw>=0);
2010 fThresholdCrate->setEnabled(isw>=0);
2011 fThresholdBoard->setEnabled(isw>=0);
2012 fThresholdPatch->setEnabled(isw>=0);
2013
2014 if (isw<0)
2015 return;
2016
2017 const int patch = ihw%4;
2018 const int board = (ihw/4)%10;
2019 const int crate = (ihw/4)/10;
2020
2021 fInChoosePatch = true;
2022
2023 fThresholdCrate->setValue(crate);
2024 fThresholdBoard->setValue(board);
2025 fThresholdPatch->setValue(patch);
2026
2027 fInChoosePatch = false;
2028
2029 fThresholdVal->setValue(fFtmStaticData.fThreshold[ihw]);
2030 fPatchRate->setValue(cam.GetData(isw));
2031
2032 // Loop over the software idx of all pixels
2033 for (unsigned int i=0; i<1440; i++)
2034 if (fPatchHW[i]==ihw)
2035 cam.SetBold(i);
2036 }
2037
2038 void ChoosePixel(Camera &cam, int isw)
2039 {
2040 const int ihw = fPixelMapHW[isw];
2041
2042 int ii = 0;
2043 for (; ii<160; ii++)
2044 if (fPatchHW[isw]==fPatchMapHW[ii])
2045 break;
2046
2047 cam.SetWhite(isw);
2048 ChoosePatch(cam, ii);
2049
2050 const bool on = fFtmStaticData.IsEnabled(ihw);
2051 fPixelEnable->setChecked(on);
2052 }
2053
2054 void UpdatePatch(int isw)
2055 {
2056 Camera *cam = (Camera*)fRatesCanv->GetCanvas()->FindObject("Camera");
2057 ChoosePatch(*cam, isw);
2058 }
2059
2060 void on_fThresholdIdx_valueChanged(int isw)
2061 {
2062 UpdatePatch(isw);
2063
2064 fRatesCanv->GetCanvas()->Modified();
2065 fRatesCanv->GetCanvas()->Update();
2066 }
2067
2068 void UpdateThresholdIdx()
2069 {
2070 if (fInChoosePatch)
2071 return;
2072
2073 const int crate = fThresholdCrate->value();
2074 const int board = fThresholdBoard->value();
2075 const int patch = fThresholdPatch->value();
2076
2077 const int ihw = patch + board*4 + crate*40;
2078
2079 int isw = 0;
2080 for (; isw<160; isw++)
2081 if (ihw==fPatchMapHW[isw])
2082 break;
2083
2084 UpdatePatch(isw);
2085 }
2086
2087 void on_fThresholdPatch_valueChanged(int)
2088 {
2089 UpdateThresholdIdx();
2090 }
2091 void on_fThresholdBoard_valueChanged(int)
2092 {
2093 UpdateThresholdIdx();
2094 }
2095 void on_fThresholdCrate_valueChanged(int)
2096 {
2097 UpdateThresholdIdx();
2098 }
2099
2100 void on_fPixelIdx_valueChanged(int isw)
2101 {
2102 Camera *cam = (Camera*)fRatesCanv->GetCanvas()->FindObject("Camera");
2103 ChoosePixel(*cam, isw);
2104
2105 fRatesCanv->GetCanvas()->Modified();
2106 fRatesCanv->GetCanvas()->Update();
2107 }
2108#endif
2109
2110 void on_fPixelEnable_stateChanged(int b)
2111 {
2112 if (fInHandler)
2113 return;
2114
2115 const uint16_t isw = fPixelIdx->value();
2116 const uint16_t ihw = fPixelMapHW[isw];
2117
2118 Dim::SendCommand(b==Qt::Unchecked ?
2119 "FTM_CONTROL/DISABLE_PIXEL" : "FTM_CONTROL/ENABLE_PIXEL",
2120 ihw);
2121 }
2122
2123 void on_fPixelDisableOthers_clicked()
2124 {
2125 const uint16_t isw = fPixelIdx->value();
2126 const uint16_t ihw = fPixelMapHW[isw];
2127
2128 Dim::SendCommand("FTM_CONTROL/DISABLE_ALL_PIXELS_EXCEPT", ihw);
2129 }
2130
2131 void on_fThresholdDisableOthers_clicked()
2132 {
2133 const uint16_t isw = fThresholdIdx->value();
2134 const uint16_t ihw = fPatchMapHW[isw];
2135
2136 Dim::SendCommand("FTM_CONTROL/DISABLE_ALL_PATCHES_EXCEPT", ihw);
2137 }
2138
2139 void on_fThresholdVal_valueChanged(int v)
2140 {
2141 fThresholdVolt->setValue(2500./4095*v);
2142
2143 const int32_t isw = fThresholdIdx->value();
2144 const int32_t ihw = fPatchMapHW[isw];
2145
2146 const int32_t d[2] = { ihw, v };
2147
2148 if (!fInHandler)
2149 Dim::SendCommand("FTM_CONTROL/SET_THRESHOLD", d);
2150 }
2151
2152 TGraph fGraphFtmTemp[4];
2153 TGraph fGraphFtmRate;
2154 TGraph fGraphPatchRate[160];
2155 TGraph fGraphBoardRate[40];
2156
2157#ifdef HAVE_ROOT
2158 void DrawTimeFrame(const char *ytitle)
2159 {
2160 const double tm = Time().RootTime();
2161
2162 TH1F h("TimeFrame", "", 1, tm, tm+60);//Time().RootTime()-1./24/60/60, Time().RootTime());
2163 h.SetDirectory(0);
2164// h.SetBit(TH1::kCanRebin);
2165 h.SetStats(kFALSE);
2166// h.SetMinimum(0);
2167// h.SetMaximum(1);
2168 h.SetXTitle("Time");
2169 h.SetYTitle(ytitle);
2170 h.GetXaxis()->CenterTitle();
2171 h.GetYaxis()->CenterTitle();
2172 h.GetXaxis()->SetTimeDisplay(true);
2173 h.GetXaxis()->SetTimeFormat("%Mh%S'");
2174 h.GetXaxis()->SetLabelSize(0.025);
2175 h.GetYaxis()->SetLabelSize(0.025);
2176 h.GetYaxis()->SetTitleOffset(1.2);
2177// h.GetYaxis()->SetTitleSize(1.2);
2178 h.DrawCopy()->SetDirectory(0);
2179 }
2180#endif
2181
2182public:
2183 FactGui() :
2184 fFtuStatus(40),
2185 fPixelMapHW(1440), fPatchMapHW(160), fPatchHW(1440),
2186 fInChoosePatch(false),
2187 fDimDNS("DIS_DNS/VERSION_NUMBER", 1, int(0), this),
2188
2189 fDimLoggerStats ("DATA_LOGGER/STATS", (void*)NULL, 0, this),
2190 fDimLoggerFilenameNight("DATA_LOGGER/FILENAME_NIGHTLY", const_cast<char*>(""), 0, this),
2191 fDimLoggerFilenameRun ("DATA_LOGGER/FILENAME_RUN", const_cast<char*>(""), 0, this),
2192 fDimLoggerNumSubs ("DATA_LOGGER/NUM_SUBS", const_cast<char*>(""), 0, this),
2193
2194 fDimFtmPassport ("FTM_CONTROL/PASSPORT", (void*)NULL, 0, this),
2195 fDimFtmTriggerCounter("FTM_CONTROL/TRIGGER_COUNTER", (void*)NULL, 0, this),
2196 fDimFtmError ("FTM_CONTROL/ERROR", (void*)NULL, 0, this),
2197 fDimFtmFtuList ("FTM_CONTROL/FTU_LIST", (void*)NULL, 0, this),
2198 fDimFtmStaticData ("FTM_CONTROL/STATIC_DATA", (void*)NULL, 0, this),
2199 fDimFtmDynamicData ("FTM_CONTROL/DYNAMIC_DATA", (void*)NULL, 0, this),
2200 fDimFtmCounter ("FTM_CONTROL/COUNTER", (void*)NULL, 0, this),
2201 fDimFadFiles ("FAD_CONTROL/FILES", (void*)NULL, 0, this),
2202 fDimFadRuns ("FAD_CONTROL/RUNS", (void*)NULL, 0, this),
2203 fDimFadEvents ("FAD_CONTROL/EVENTS", (void*)NULL, 0, this),
2204 fDimFadCurrentEvent ("FAD_CONTROL/CURRENT_EVENT", (void*)NULL, 0, this),
2205 fDimFadConnections ("FAD_CONTROL/CONNECTIONS", (void*)NULL, 0, this)
2206 {
2207 fClockCondFreq->addItem("-/-", QVariant(-1));
2208 fClockCondFreq->addItem("700 MHz", QVariant(700));
2209 fClockCondFreq->addItem("1 GHz", QVariant(1000));
2210 fClockCondFreq->addItem("2 GHz", QVariant(2000));
2211 fClockCondFreq->addItem("2 GHz (*)", QVariant(2001));
2212 fClockCondFreq->addItem("3 GHz", QVariant(3000));
2213 fClockCondFreq->addItem("4 GHz", QVariant(4000));
2214 fClockCondFreq->addItem("5 GHz", QVariant(5000));
2215
2216 fTriggerWidget->setEnabled(false);
2217 fFtuWidget->setEnabled(false);
2218 fRatesWidget->setEnabled(false);
2219// fFadWidget->setEnabled(false);
2220 fLoggerWidget->setEnabled(false);
2221
2222 fChatSend->setEnabled(false);
2223 fChatMessage->setEnabled(false);
2224
2225 DimClient::sendCommand("CHAT/MSG", "GUI online.");
2226 // + MessageDimRX
2227
2228 // --------------------------------------------------------------------------
2229
2230 ifstream fin1("Trigger-Patches.txt");
2231
2232 int l = 0;
2233
2234 string buf;
2235 while (getline(fin1, buf, '\n'))
2236 {
2237 buf = Tools::Trim(buf);
2238 if (buf[0]=='#')
2239 continue;
2240
2241 stringstream str(buf);
2242 for (int i=0; i<9; i++)
2243 {
2244 unsigned int n;
2245 str >> n;
2246
2247 if (n>=fPatchHW.size())
2248 continue;
2249
2250 fPatchHW[n] = l;
2251 }
2252 l++;
2253 }
2254
2255 if (l!=160)
2256 cerr << "WARNING - Problems reading Trigger-Patches.txt" << endl;
2257
2258 // --------------------------------------------------------------------------
2259
2260 ifstream fin2("MasterList-v3.txt");
2261
2262 l = 0;
2263
2264 while (getline(fin2, buf, '\n'))
2265 {
2266 buf = Tools::Trim(buf);
2267 if (buf[0]=='#')
2268 continue;
2269
2270 unsigned int softid, hardid, dummy;
2271
2272 stringstream str(buf);
2273
2274 str >> softid;
2275 str >> dummy;
2276 str >> hardid;
2277
2278 if (softid>=fPixelMapHW.size())
2279 continue;
2280
2281 fPixelMapHW[softid] = hardid;
2282
2283 l++;
2284 }
2285
2286 if (l!=1440)
2287 cerr << "WARNING - Problems reading MasterList-v3.txt" << endl;
2288
2289 // --------------------------------------------------------------------------
2290
2291 ifstream fin3("PatchList.txt");
2292
2293 l = 0;
2294
2295 while (getline(fin3, buf, '\n'))
2296 {
2297 buf = Tools::Trim(buf);
2298 if (buf[0]=='#')
2299 continue;
2300
2301 unsigned int softid, hardid;
2302
2303 stringstream str(buf);
2304
2305 str >> softid;
2306 str >> hardid;
2307
2308 if (softid>=fPatchMapHW.size())
2309 continue;
2310
2311 fPatchMapHW[softid] = hardid-1;
2312
2313 l++;
2314 }
2315
2316 if (l!=160)
2317 cerr << "WARNING - Problems reading PatchList.txt" << endl;
2318
2319 // --------------------------------------------------------------------------
2320#ifdef HAVE_ROOT
2321
2322 fGraphFtmRate.SetLineColor(kBlue);
2323 fGraphFtmRate.SetMarkerColor(kBlue);
2324 fGraphFtmRate.SetMarkerStyle(kFullDotMedium);
2325
2326 for (int i=0; i<160; i++)
2327 {
2328 fGraphPatchRate[i].SetName("PatchRate");
2329 //fGraphPatchRate[i].SetLineColor(kBlue);
2330 //fGraphPatchRate[i].SetMarkerColor(kBlue);
2331 fGraphPatchRate[i].SetMarkerStyle(kFullDotMedium);
2332 }
2333 for (int i=0; i<40; i++)
2334 {
2335 fGraphBoardRate[i].SetName("BoardRate");
2336 //fGraphBoardRate[i].SetLineColor(kBlue);
2337 //fGraphBoardRate[i].SetMarkerColor(kBlue);
2338 fGraphBoardRate[i].SetMarkerStyle(kFullDotMedium);
2339 }
2340 /*
2341 TCanvas *c = fFtmTempCanv->GetCanvas();
2342 c->SetBit(TCanvas::kNoContextMenu);
2343 c->SetBorderMode(0);
2344 c->SetFrameBorderMode(0);
2345 c->SetFillColor(kWhite);
2346 c->SetRightMargin(0.03);
2347 c->SetTopMargin(0.03);
2348 c->cd();
2349 */
2350 //CreateTimeFrame("Temperature / °C");
2351
2352 fGraphFtmTemp[0].SetMarkerStyle(kFullDotSmall);
2353 fGraphFtmTemp[1].SetMarkerStyle(kFullDotSmall);
2354 fGraphFtmTemp[2].SetMarkerStyle(kFullDotSmall);
2355 fGraphFtmTemp[3].SetMarkerStyle(kFullDotSmall);
2356
2357 fGraphFtmTemp[1].SetLineColor(kBlue);
2358 fGraphFtmTemp[2].SetLineColor(kRed);
2359 fGraphFtmTemp[3].SetLineColor(kGreen);
2360
2361 fGraphFtmTemp[1].SetMarkerColor(kBlue);
2362 fGraphFtmTemp[2].SetMarkerColor(kRed);
2363 fGraphFtmTemp[3].SetMarkerColor(kGreen);
2364
2365 //fGraphFtmTemp[0].Draw("LP");
2366 //fGraphFtmTemp[1].Draw("LP");
2367 //fGraphFtmTemp[2].Draw("LP");
2368 //fGraphFtmTemp[3].Draw("LP");
2369
2370 // --------------------------------------------------------------------------
2371
2372 TCanvas *c = fFtmRateCanv->GetCanvas();
2373 //c->SetBit(TCanvas::kNoContextMenu);
2374 c->SetBorderMode(0);
2375 c->SetFrameBorderMode(0);
2376 c->SetFillColor(kWhite);
2377 c->SetRightMargin(0.03);
2378 c->SetTopMargin(0.03);
2379 c->SetGrid();
2380 c->cd();
2381
2382 DrawTimeFrame("Trigger rate [Hz]");
2383
2384 fTriggerCounter0 = -1;
2385
2386 fGraphFtmRate.SetMarkerStyle(kFullDotSmall);
2387 fGraphFtmRate.Draw("LP");
2388
2389 // --------------------------------------------------------------------------
2390
2391 c = fRatesCanv->GetCanvas();
2392 //c->SetBit(TCanvas::kNoContextMenu);
2393 c->SetBorderMode(0);
2394 c->SetFrameBorderMode(0);
2395 c->SetFillColor(kWhite);
2396 c->cd();
2397
2398 Camera *cam = new Camera;
2399 cam->SetBit(kCanDelete);
2400 cam->Draw();
2401
2402 ChoosePixel(*cam, 0);
2403
2404 // --------------------------------------------------------------------------
2405
2406 c = fAdcDataCanv->GetCanvas();
2407 c->SetBit(TCanvas::kNoContextMenu);
2408 c->SetBorderMode(0);
2409 c->SetFrameBorderMode(0);
2410 c->SetFillColor(kWhite);
2411 c->SetGrid();
2412 c->cd();
2413
2414 // Create histogram?
2415
2416 // --------------------------------------------------------------------------
2417
2418// QTimer::singleShot(0, this, SLOT(slot_RootUpdate()));
2419
2420 //widget->setMouseTracking(true);
2421 //widget->EnableSignalEvents(kMouseMoveEvent);
2422
2423 fFtmRateCanv->setMouseTracking(true);
2424 fFtmRateCanv->EnableSignalEvents(kMouseMoveEvent);
2425
2426 fAdcDataCanv->setMouseTracking(true);
2427 fAdcDataCanv->EnableSignalEvents(kMouseMoveEvent);
2428
2429 fRatesCanv->setMouseTracking(true);
2430 fRatesCanv->EnableSignalEvents(kMouseMoveEvent|kMouseReleaseEvent|kMouseDoubleClickEvent);
2431
2432 connect(fRatesCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)),
2433 this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*)));
2434 connect(fFtmRateCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)),
2435 this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*)));
2436 connect(fAdcDataCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)),
2437 this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*)));
2438#endif
2439 }
2440
2441 ~FactGui()
2442 {
2443 UnsubscribeAllServers();
2444 }
2445};
2446
2447#endif
Note: See TracBrowser for help on using the repository browser.