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

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