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

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