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

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