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

Last change on this file since 11692 was 11692, checked in by tbretz, 13 years ago
Added trigger number to GUI.
File size: 95.8 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 =
1172 fAdcChannel->value() +
1173 fAdcChip->value() * 9+
1174 fAdcBoard->value() * 36+
1175 fAdcCrate->value() *360;
1176
1177 ostringstream str;
1178 str << "EventNum = " << fEventData->EventNum;
1179 str << "TriggerNum = " << fEventData->TriggerNum;
1180 str << " Trigger type = " << fEventData->TriggerType;
1181 str << " Board time = " << fEventData->BoardTime[fAdcBoard->value()+fAdcCrate->value()*10];
1182 str << " (" << Time(fEventData->PCTime, fEventData->PCUsec) << ")";
1183 h->SetTitle(str.str().c_str());
1184 str.str("");
1185 str << "ADC Pipeline (start cell: " << fEventData->StartPix[p] << ")";
1186 h->SetXTitle(str.str().c_str());
1187
1188 // str.str("");
1189 // str << "Crate=" << crate << " Board=" << board << " Channel=" << channel << " [" << d.time() << "]" << endl;
1190 // hist->SetTitle(str.str().c_str());
1191
1192 for (int i=0; i<fEventData->Roi; i++)
1193 h->SetBinContent(i+1, reinterpret_cast<float*>(fEventData->Adc_Data)[p*fEventData->Roi+i]);
1194
1195 if (fAdcDynamicScale->isChecked())
1196 {
1197 h->SetMinimum(-1111);
1198 h->SetMaximum(-1111);
1199 }
1200 if (fAdcManualScale->isChecked())
1201 {
1202 if (h->GetMinimumStored()==-1111)
1203 h->SetMinimum(-1026);
1204 if (h->GetMaximumStored()==-1111)
1205 h->SetMaximum(1025);
1206 }
1207 if (fAdcAutoScale->isChecked())
1208 {
1209 const double min = h->GetMinimumStored();
1210 const double max = h->GetMaximumStored();
1211
1212 h->SetMinimum();
1213 h->SetMaximum();
1214
1215 h->SetMinimum(h->GetMinimum()<min || min==-1111 ? h->GetMinimum() : min);
1216 h->SetMaximum(h->GetMaximum()>max || max==-1111 ? h->GetMaximum() : max);
1217 }
1218
1219 c->Modified();
1220 c->Update();
1221#endif
1222 }
1223
1224 void handleFadEventData(const DimData &d)
1225 {
1226 if (d.size()==0)
1227 return;
1228
1229 if (fAdcStop->isChecked())
1230 return;
1231
1232 const EVENT &dat = d.ref<EVENT>();
1233
1234 if (d.size()<sizeof(EVENT))
1235 {
1236 cout << "Size mismatch in " << d.name << ": Found=" << d.size() << " Expected>=" << sizeof(EVENT) << endl;
1237 return;
1238 }
1239
1240 if (d.size()!=sizeof(EVENT)+dat.Roi*4*1440)
1241 {
1242 cout << "Size mismatch in " << d.name << ": Found=" << d.size() << " Expected=" << dat.Roi*4*1440+sizeof(EVENT) << " [roi=" << dat.Roi << "]" << endl;
1243 return;
1244 }
1245
1246 delete fEventData;
1247 fEventData = reinterpret_cast<EVENT*>(new char[d.size()]);
1248 memcpy(fEventData, d.ptr<void>(), d.size());
1249
1250 DisplayEventData();
1251 }
1252
1253// vector<uint8_t> fFadConnections;
1254
1255 void handleFadConnections(const DimData &d)
1256 {
1257 if (!CheckSize(d, 41))
1258 {
1259 fStatusEventBuilderLabel->setText("Offline");
1260 fStatusEventBuilderLabel->setToolTip("FADs or fadctrl seems to be offline.");
1261 fEvtBldWidget->setEnabled(false);
1262
1263 SetLedColor(fStatusEventBuilderLed, kLedGray, d.time);
1264 return;
1265 }
1266
1267 const uint8_t *ptr = d.ptr<uint8_t>();
1268
1269 for (int i=0; i<40; i++)
1270 {
1271 const uint8_t stat1 = ptr[i]&3;
1272 const uint8_t stat2 = ptr[i]>>3;
1273
1274 if (stat1==0 && stat2==0)
1275 {
1276 SetLedColor(fFadLED[i], kLedGray, d.time);
1277 continue;
1278 }
1279 if (stat1==2 && stat2==8)
1280 {
1281 SetLedColor(fFadLED[i], kLedGreen, d.time);
1282 continue;
1283 }
1284
1285 if (stat1==1 && stat2==1)
1286 SetLedColor(fFadLED[i], kLedRed, d.time);
1287 else
1288 SetLedColor(fFadLED[i], kLedOrange, d.time);
1289 }
1290
1291
1292 const bool runs = ptr[40]!=0;
1293
1294 fStatusEventBuilderLabel->setText(runs?"Running":"Not running");
1295 fStatusEventBuilderLabel->setToolTip(runs?"Event builder thread running.":"Event builder thread stopped.");
1296 fEvtBldWidget->setEnabled(runs);
1297
1298 SetLedColor(fStatusEventBuilderLed, runs?kLedGreen:kLedRed, d.time);
1299
1300// fFadConnections.assign(ptr, ptr+40);
1301 }
1302
1303 template<typename T>
1304 void handleFadToolTip(const Time &time, QWidget *w, T *ptr)
1305 {
1306 ostringstream tip;
1307 tip << "<table border='1'><tr><th colspan='11'>" << time.GetAsStr() << " (UTC)</th></tr><tr><th></th>";
1308 for (int b=0; b<10; b++)
1309 tip << "<th>" << b << "</th>";
1310 tip << "</tr>";
1311
1312 for (int c=0; c<4; c++)
1313 {
1314 tip << "<tr><th>" << c << "</th>";
1315 for (int b=0; b<10; b++)
1316 tip << "<td>" << ptr[c*10+b] << "</td>";
1317 tip << "</tr>";
1318 }
1319 tip << "</table>";
1320
1321 w->setToolTip(tip.str().c_str());
1322 }
1323
1324 template<typename T, class S>
1325 void handleFadMinMax(const DimData &d, QPushButton *led, S *wmin, S *wmax=0)
1326 {
1327 if (!CheckSize(d, 42*sizeof(T)))
1328 return;
1329
1330 const T *ptr = d.ptr<T>();
1331 const T min = ptr[40];
1332 const T max = ptr[41];
1333
1334 if (max==0 && min>max)
1335 SetLedColor(led, kLedGray, d.time);
1336 else
1337 SetLedColor(led, min==max?kLedGreen: kLedOrange, d.time);
1338
1339 if (!wmax && max!=min)
1340 wmin->setValue(0);
1341 else
1342 wmin->setValue(min);
1343
1344 if (wmax)
1345 wmax->setValue(max);
1346
1347 handleFadToolTip(d.time, led, ptr);
1348 }
1349
1350 void handleFadFwVersion(const DimData &d)
1351 {
1352 handleFadMinMax<float, QDoubleSpinBox>(d, fFadLedFwVersion, fFadFwVersion);
1353 }
1354
1355 void handleFadRunNumber(const DimData &d)
1356 {
1357 handleFadMinMax<uint32_t, QSpinBox>(d, fFadLedRunNumber, fFadRunNumber);
1358 }
1359
1360 void handleFadPrescaler(const DimData &d)
1361 {
1362 handleFadMinMax<uint16_t, QSpinBox>(d, fFadLedPrescaler, fFadPrescaler);
1363 }
1364
1365 void handleFadDNA(const DimData &d)
1366 {
1367 if (!CheckSize(d, 40*sizeof(uint64_t)))
1368 return;
1369
1370 const uint64_t *ptr = d.ptr<uint64_t>();
1371
1372 ostringstream tip;
1373 tip << "<table width='100%'>";
1374 tip << "<tr><th>Crate</th><td></td><th>Board</th><td></td><th>DNA</th></tr>";
1375
1376 for (int i=0; i<40; i++)
1377 {
1378 tip << dec;
1379 tip << "<tr>";
1380 tip << "<td align='center'>" << i/10 << "</td><td>:</td>";
1381 tip << "<td align='center'>" << i%10 << "</td><td>:</td>";
1382 tip << hex;
1383 tip << "<td>0x" << setfill('0') << setw(16) << ptr[i] << "</td>";
1384 tip << "</tr>";
1385 }
1386 tip << "</table>";
1387
1388 fFadDNA->setText(tip.str().c_str());
1389 }
1390
1391 void SetFadLed(QPushButton *led, const DimData &d, uint16_t bitmask, bool invert=false)
1392 {
1393 if (d.size()==0)
1394 {
1395 SetLedColor(led, kLedGray, d.time);
1396 return;
1397 }
1398
1399 const bool quality = d.ptr<uint16_t>()[0]&bitmask;
1400 const bool value = d.ptr<uint16_t>()[1]&bitmask;
1401 const uint16_t *ptr = d.ptr<uint16_t>()+2;
1402
1403 SetLedColor(led, quality?kLedOrange:(value^invert?kLedGreen:kLedRed), d.time);
1404
1405 ostringstream tip;
1406 tip << "<table border='1'><tr><th colspan='11'>" << d.time.GetAsStr() << " (UTC)</th></tr><tr><th></th>";
1407 for (int b=0; b<10; b++)
1408 tip << "<th>" << b << "</th>";
1409 tip << "</tr>";
1410
1411 /*
1412 tip << "<tr>" << hex;
1413 tip << "<th>" << d.ptr<uint16_t>()[0] << " " << (d.ptr<uint16_t>()[0]&bitmask) << "</th>";
1414 tip << "<th>" << d.ptr<uint16_t>()[1] << " " << (d.ptr<uint16_t>()[1]&bitmask) << "</th>";
1415 tip << "</tr>";
1416 */
1417
1418 for (int c=0; c<4; c++)
1419 {
1420 tip << "<tr><th>" << dec << c << "</th>" << hex;
1421 for (int b=0; b<10; b++)
1422 {
1423 tip << "<td>"
1424 << (ptr[c*10+b]&bitmask)
1425 << "</td>";
1426 }
1427 tip << "</tr>";
1428 }
1429 tip << "</table>";
1430
1431 led->setToolTip(tip.str().c_str());
1432 }
1433
1434 void handleFadStatus(const DimData &d)
1435 {
1436 if (d.size()!=0 && !CheckSize(d, 42*sizeof(uint16_t)))
1437 return;
1438
1439 SetFadLed(fFadLedDrsEnabled, d, FAD::EventHeader::kDenable);
1440 SetFadLed(fFadLedDrsWrite, d, FAD::EventHeader::kDwrite);
1441 SetFadLed(fFadLedDcmLocked, d, FAD::EventHeader::kDcmLocked);
1442 SetFadLed(fFadLedDcmReady, d, FAD::EventHeader::kDcmReady);
1443 SetFadLed(fFadLedSpiSclk, d, FAD::EventHeader::kSpiSclk);
1444 SetFadLed(fFadLedRefClockTooLow, d, FAD::EventHeader::kRefClkTooLow, true);
1445 SetFadLed(fFadLedBusyOn, d, FAD::EventHeader::kBusyOn);
1446 SetFadLed(fFadLedBusyOff, d, FAD::EventHeader::kBusyOff);
1447 SetFadLed(fFadLedTriggerLine, d, FAD::EventHeader::kTriggerLine);
1448 SetFadLed(fFadLedContTrigger, d, FAD::EventHeader::kContTrigger);
1449 SetFadLed(fFadLedSocket, d, FAD::EventHeader::kSock17);
1450 SetFadLed(fFadLedPllLock, d, 0xf000);
1451 }
1452
1453 void handleFadStatistics1(const DimData &d)
1454 {
1455 if (!CheckSize(d, sizeof(GUI_STAT)))
1456 return;
1457
1458 const GUI_STAT &stat = d.ref<GUI_STAT>();
1459
1460 /*
1461 //info about status of the main threads
1462 int32_t readStat ; //read thread
1463 int32_t procStat ; //processing thread(s)
1464 int32_t writStat ; //write thread
1465 */
1466
1467 fFadBufferMax->setValue(stat.totMem/1000000);
1468 fFadBuffer->setMaximum(stat.totMem/100);
1469 fFadBuffer->setValue((stat.maxMem>stat.totMem?stat.totMem:stat.maxMem)/100); // Max mem used in last second
1470
1471 uint32_t sum = 0;
1472 int32_t min = 0x7fffff;
1473 int32_t max = 0;
1474
1475 int cnt = 0;
1476 int err = 0;
1477
1478 for (int i=0; i<40; i++)
1479 {
1480 if (stat.numConn[i]!=7)
1481 continue;
1482
1483 cnt++;
1484
1485 sum += stat.rateBytes[i];
1486 err += stat.errConn[i];
1487
1488 if (stat.rateBytes[i]<min)
1489 min = stat.rateBytes[i];
1490 if (stat.rateBytes[i]>max)
1491 max = stat.rateBytes[i];
1492 }
1493
1494 fFadEvtConn->setValue(cnt);
1495 fFadEvtConnErr->setValue(err);
1496
1497 fFadEvtBufNew->setValue(stat.bufNew); // Incomplete in buffer
1498 fFadEvtBufEvt->setValue(stat.bufEvt); // Complete in buffer
1499 fFadEvtBufMax->setValue(stat.maxEvt); // Complete in buffer
1500 fFadEvtWrite->setValue(stat.evtWrite-stat.evtSkip-stat.evtErr);
1501 fFadEvtSkip->setValue(stat.evtSkip);
1502 fFadEvtErr->setValue(stat.evtErr);
1503
1504 if (stat.deltaT==0)
1505 return;
1506
1507 fFadEthernetRateMin->setValue(min/stat.deltaT);
1508 fFadEthernetRateMax->setValue(max/stat.deltaT);
1509 fFadEthernetRateTot->setValue(sum/stat.deltaT);
1510 fFadEthernetRateAvg->setValue(cnt==0 ? 0 : sum/cnt/stat.deltaT);
1511 fFadEvtRateNew->setValue(1000*stat.rateNew/stat.deltaT);
1512 fFadEvtRateWrite->setValue(1000*stat.rateWrite/stat.deltaT);
1513 }
1514
1515 void handleFadStatistics2(const DimData &d)
1516 {
1517 if (!CheckSize(d, sizeof(EVT_STAT)))
1518 return;
1519
1520 //const EVT_STAT &stat = d.ref<EVT_STAT>();
1521
1522 /*
1523 //some info about what happened since start of program (or last 'reset')
1524 uint32_t reset ; //#if increased, reset all counters
1525 uint32_t numRead[MAX_SOCK] ; //how often succesfull read from N sockets per loop
1526
1527 uint64_t gotByte[NBOARDS] ; //#Bytes read per Board
1528 uint32_t gotErr[NBOARDS] ; //#Communication Errors per Board
1529
1530 uint32_t evtGet; //#new Start of Events read
1531 uint32_t evtTot; //#complete Events read
1532
1533 uint32_t evtErr; //#Events with Errors
1534 uint32_t evtSkp; //#Events incomplete (timeout)
1535
1536
1537 uint32_t procTot; //#Events processed
1538 uint32_t procErr; //#Events showed problem in processing
1539 uint32_t procTrg; //#Events accepted by SW trigger
1540 uint32_t procSkp; //#Events rejected by SW trigger
1541
1542 uint32_t feedTot; //#Events used for feedBack system
1543 uint32_t feedErr; //#Events rejected by feedBack
1544
1545 uint32_t wrtTot; //#Events written to disk
1546 uint32_t wrtErr; //#Events with write-error
1547
1548 uint32_t runOpen; //#Runs opened
1549 uint32_t runClose; //#Runs closed
1550 uint32_t runErr; //#Runs with open/close errors
1551
1552
1553 //info about current connection status
1554 uint8_t numConn[NBOARDS] ; //#Sockets succesfully open per board
1555 */
1556 }
1557
1558 // ===================== FTM ============================================
1559
1560 double fTimeStamp1;
1561
1562 void handleFtmTriggerCounter(const DimData &d)
1563 {
1564 if (!CheckSize(d, sizeof(FTM::DimTriggerCounter)))
1565 return;
1566
1567 const FTM::DimTriggerCounter &sdata = d.ref<FTM::DimTriggerCounter>();
1568
1569 fFtmTime->setText(QString::number(sdata.fTimeStamp/1000000., 'f', 6)+ " s");
1570 fTriggerCounter->setText(QString::number(sdata.fTriggerCounter));
1571
1572 if (sdata.fTimeStamp>0)
1573 fTriggerCounterRate->setValue(1000000.*sdata.fTriggerCounter/sdata.fTimeStamp);
1574 else
1575 fTriggerCounterRate->setValue(0);
1576
1577
1578 // ----------------------------------------------
1579#ifdef HAVE_ROOT
1580
1581 if (fTriggerCounter0<0)
1582 {
1583 fTriggerCounter0 = sdata.fTriggerCounter;
1584 fTimeStamp1 = sdata.fTimeStamp;
1585 return;
1586 }
1587
1588 TCanvas *c = fFtmRateCanv->GetCanvas();
1589
1590 TH1 *h = (TH1*)c->FindObject("TimeFrame");
1591
1592 const double rate = sdata.fTriggerCounter-fTriggerCounter0;
1593 const double tdiff = sdata.fTimeStamp -fTimeStamp1;
1594
1595 fTriggerCounter0 = sdata.fTriggerCounter;
1596 fTimeStamp1 = sdata.fTimeStamp;
1597
1598 if (rate<0 && tdiff<=0)
1599 {
1600 fGraphFtmRate.Set(0);
1601
1602 const double tm = Time().RootTime();
1603
1604 h->SetBins(1, tm, tm+60);
1605 h->GetXaxis()->SetTimeFormat("%M'%S\"");
1606 h->GetXaxis()->SetTitle("Time");
1607
1608 c->Modified();
1609 c->Update();
1610 return;
1611 }
1612
1613 if (rate<0)
1614 return;
1615
1616// const double avgrate = sdata.fTimeStamp>0 ? double(sdata.fTriggerCounter)/sdata.fTimeStamp*1000000 : 1;
1617
1618 const double t1 = h->GetXaxis()->GetXmax();
1619 const double t0 = h->GetXaxis()->GetXmin();
1620
1621 h->SetBins(h->GetNbinsX()+1, t0, t0+sdata.fTimeStamp/1000000.+1);
1622 fGraphFtmRate.SetPoint(fGraphFtmRate.GetN(),
1623 t0+sdata.fTimeStamp/1000000., 1000000*rate/tdiff);
1624
1625 if (t1-t0>60)
1626 {
1627 h->GetXaxis()->SetTimeFormat("%Hh%M'");
1628 h->GetXaxis()->SetTitle("Time");
1629 }
1630
1631 h->SetMinimum(0);
1632// h->SetMaximum(2*avgrate);
1633
1634 c->Modified();
1635 c->Update();
1636#endif
1637 // ----------------------------------------------
1638 }
1639
1640 void handleFtmCounter(const DimData &d)
1641 {
1642 if (!CheckSize(d, sizeof(uint32_t)*6))
1643 return;
1644
1645 const uint32_t *sdata = d.ptr<uint32_t>();
1646
1647 fFtmCounterH->setValue(sdata[0]);
1648 fFtmCounterS->setValue(sdata[1]);
1649 fFtmCounterD->setValue(sdata[2]);
1650 fFtmCounterF->setValue(sdata[3]);
1651 fFtmCounterE->setValue(sdata[4]);
1652 fFtmCounterR->setValue(sdata[5]);
1653 }
1654
1655 int64_t fTriggerCounter0;
1656 int64_t fTimeStamp0;
1657
1658 void handleFtmDynamicData(const DimData &d)
1659 {
1660 if (!CheckSize(d, sizeof(FTM::DimDynamicData)))
1661 return;
1662
1663 const FTM::DimDynamicData &sdata = d.ref<FTM::DimDynamicData>();
1664
1665 fOnTime->setText(QString::number(sdata.fOnTimeCounter/1000000., 'f', 6)+" s");
1666
1667 if (sdata.fTimeStamp>0)
1668 fOnTimeRel->setValue(100.*sdata.fOnTimeCounter/sdata.fTimeStamp);
1669 else
1670 fOnTimeRel->setValue(0);
1671
1672 fFtmTemp0->setValue(sdata.fTempSensor[0]*0.1);
1673 fFtmTemp1->setValue(sdata.fTempSensor[1]*0.1);
1674 fFtmTemp2->setValue(sdata.fTempSensor[2]*0.1);
1675 fFtmTemp3->setValue(sdata.fTempSensor[3]*0.1);
1676
1677 SetLedColor(fClockCondLed, sdata.fState&FTM::kFtmLocked ? kLedGreen : kLedRed, d.time);
1678
1679#ifdef HAVE_ROOT
1680
1681 // ----------------------------------------------
1682
1683 if (fTimeStamp0<0)
1684 {
1685 fTimeStamp0 = sdata.fTimeStamp;
1686 return;
1687 }
1688
1689 TCanvas *c = fFtmRateCanv->GetCanvas();
1690
1691 TH1 *h = (TH1*)c->FindObject("TimeFrame");
1692
1693 const double tdiff = sdata.fTimeStamp-fTimeStamp0;
1694 fTimeStamp0 = sdata.fTimeStamp;
1695
1696 if (tdiff<0)
1697 {
1698 for (int i=0; i<160; i++)
1699 fGraphPatchRate[i].Set(0);
1700 for (int i=0; i<40; i++)
1701 fGraphBoardRate[i].Set(0);
1702
1703 return;
1704 }
1705
1706 //const double t1 = h->GetXaxis()->GetXmax();
1707 const double t0 = h->GetXaxis()->GetXmin();
1708
1709 for (int i=0; i<160; i++)
1710 fGraphPatchRate[i].SetPoint(fGraphPatchRate[i].GetN(),
1711 t0+sdata.fTimeStamp/1000000., float(sdata.fRatePatch[i])*2/fFtmStaticData.fPrescaling[i]);
1712 for (int i=0; i<40; i++)
1713 fGraphBoardRate[i].SetPoint(fGraphBoardRate[i].GetN(),
1714 t0+sdata.fTimeStamp/1000000., float(sdata.fRateBoard[i])*2/fFtmStaticData.fPrescaling[i]);
1715
1716 c->Modified();
1717 c->Update();
1718
1719 //fGraphFtmRate.ComputeRange(x[0], x[1], x[2], x[3]);
1720
1721 // ----------------------------------------------
1722
1723 if (fThresholdIdx->value()>=0)
1724 {
1725 const int isw = fThresholdIdx->value();
1726 const int ihw = fPatchMapHW[isw];
1727 fPatchRate->setValue(sdata.fRatePatch[ihw]);
1728 }
1729
1730 valarray<double> dat(0., 1440);
1731
1732 // fPatch converts from software id to software patch id
1733 for (int i=0; i<1440; i++)
1734 {
1735 const int ihw = fPatchHW[i];
1736// const int isw = fPatch[i];
1737// const int ihw = fPatchMapHW[isw];
1738 dat[i] = sdata.fRatePatch[ihw];
1739 }
1740
1741 c = fRatesCanv->GetCanvas();
1742 Camera *cam = (Camera*)c->FindObject("Camera");
1743
1744 cam->SetData(dat);
1745
1746 c->Modified();
1747 c->Update();
1748
1749 // ----------------------------------------------
1750#endif
1751 }
1752
1753 void DisplayRates()
1754 {
1755#ifdef HAVE_ROOT
1756 TCanvas *c = fFtmRateCanv->GetCanvas();
1757
1758 while (c->FindObject("PatchRate"))
1759 c->GetListOfPrimitives()->Remove(c->FindObject("PatchRate"));
1760
1761 while (c->FindObject("BoardRate"))
1762 c->GetListOfPrimitives()->Remove(c->FindObject("BoardRate"));
1763
1764 c->cd();
1765
1766 if (fRatePatch1->value()>=0)
1767 {
1768 fGraphPatchRate[fRatePatch1->value()].SetLineColor(kRed);
1769 fGraphPatchRate[fRatePatch1->value()].SetMarkerColor(kRed);
1770 fGraphPatchRate[fRatePatch1->value()].Draw("PL");
1771 }
1772 if (fRatePatch2->value()>=0)
1773 {
1774 fGraphPatchRate[fRatePatch2->value()].SetLineColor(kGreen);
1775 fGraphPatchRate[fRatePatch2->value()].SetMarkerColor(kGreen);
1776 fGraphPatchRate[fRatePatch2->value()].Draw("PL");
1777 }
1778 if (fRateBoard1->value()>=0)
1779 {
1780 fGraphBoardRate[fRateBoard1->value()].SetLineColor(kMagenta);
1781 fGraphBoardRate[fRateBoard1->value()].SetMarkerColor(kMagenta);
1782 fGraphBoardRate[fRateBoard1->value()].Draw("PL");
1783 }
1784 if (fRateBoard2->value()>=0)
1785 {
1786 fGraphBoardRate[fRateBoard2->value()].SetLineColor(kCyan);
1787 fGraphBoardRate[fRateBoard2->value()].SetMarkerColor(kCyan);
1788 fGraphBoardRate[fRateBoard2->value()].Draw("PL");
1789 }
1790#endif
1791 }
1792
1793 void on_fRatePatch1_valueChanged(int)
1794 {
1795 DisplayRates();
1796 }
1797
1798 void on_fRatePatch2_valueChanged(int)
1799 {
1800 DisplayRates();
1801 }
1802
1803 void on_fRateBoard1_valueChanged(int)
1804 {
1805 DisplayRates();
1806 }
1807
1808 void on_fRateBoard2_valueChanged(int)
1809 {
1810 DisplayRates();
1811 }
1812
1813 FTM::DimStaticData fFtmStaticData;
1814
1815 void SetFtuLed(int idx, int counter, const Time &t)
1816 {
1817 if (counter==0 || counter>3)
1818 counter = 3;
1819
1820 if (counter<0)
1821 counter = 0;
1822
1823 const LedColor_t col[4] = { kLedGray, kLedGreen, kLedOrange, kLedRed };
1824
1825 SetLedColor(fFtuLED[idx], col[counter], t);
1826
1827 fFtuStatus[idx] = counter;
1828 }
1829
1830 void SetFtuStatusLed(const Time &t)
1831 {
1832 const int max = fFtuStatus.max();
1833
1834 switch (max)
1835 {
1836 case 0:
1837 SetLedColor(fStatusFTULed, kLedGray, t);
1838 fStatusFTULabel->setText("All disabled");
1839 fStatusFTULabel->setToolTip("All FTUs are disabled");
1840 break;
1841
1842 case 1:
1843 SetLedColor(fStatusFTULed, kLedGreen, t);
1844 fStatusFTULabel->setToolTip("Communication with FTU is smooth.");
1845 fStatusFTULabel->setText("ok");
1846 break;
1847
1848 case 2:
1849 SetLedColor(fStatusFTULed, kLedOrange, t);
1850 fStatusFTULabel->setText("Warning");
1851 fStatusFTULabel->setToolTip("At least one FTU didn't answer immediately");
1852 break;
1853
1854 case 3:
1855 SetLedColor(fStatusFTULed, kLedRed, t);
1856 fStatusFTULabel->setToolTip("At least one FTU didn't answer!");
1857 fStatusFTULabel->setText("ERROR");
1858 break;
1859 }
1860
1861 const int cnt = count(&fFtuStatus[0], &fFtuStatus[40], 0);
1862 fFtuAllOn->setEnabled(cnt!=0);
1863 fFtuAllOff->setEnabled(cnt!=40);
1864 }
1865
1866 void handleFtmStaticData(const DimData &d)
1867 {
1868 if (!CheckSize(d, sizeof(FTM::DimStaticData)))
1869 return;
1870
1871 const FTM::DimStaticData &sdata = d.ref<FTM::DimStaticData>();
1872
1873 fTriggerInterval->setValue(sdata.fTriggerInterval);
1874 fPhysicsCoincidence->setValue(sdata.fMultiplicityPhysics);
1875 fCalibCoincidence->setValue(sdata.fMultiplicityCalib);
1876 fPhysicsWindow->setValue(sdata.fWindowPhysics);
1877 fCalibWindow->setValue(sdata.fWindowCalib);
1878
1879 fTriggerDelay->setValue(sdata.fDelayTrigger);
1880 fTimeMarkerDelay->setValue(sdata.fDelayTimeMarker);
1881 fDeadTime->setValue(sdata.fDeadTime);
1882
1883 fClockCondR0->setValue(sdata.fClockConditioner[0]);
1884 fClockCondR1->setValue(sdata.fClockConditioner[1]);
1885 fClockCondR8->setValue(sdata.fClockConditioner[2]);
1886 fClockCondR9->setValue(sdata.fClockConditioner[3]);
1887 fClockCondR11->setValue(sdata.fClockConditioner[4]);
1888 fClockCondR13->setValue(sdata.fClockConditioner[5]);
1889 fClockCondR14->setValue(sdata.fClockConditioner[6]);
1890 fClockCondR15->setValue(sdata.fClockConditioner[7]);
1891
1892 const uint32_t R0 = sdata.fClockConditioner[0];
1893 const uint32_t R14 = sdata.fClockConditioner[6];
1894 const uint32_t R15 = sdata.fClockConditioner[7];
1895
1896 const uint32_t Ndiv = (R15&0x1ffff00)<<2;
1897 const uint32_t Rdiv = (R14&0x007ff00)>>8;
1898 const uint32_t Cdiv = (R0 &0x000ff00)>>8;
1899
1900 double freq = 40.*Ndiv/(Rdiv*Cdiv);
1901
1902 fClockCondFreqRes->setValue(freq);
1903
1904 //fClockCondFreq->setEditText("");
1905 fClockCondFreq->setCurrentIndex(0);
1906
1907 fTriggerSeqPed->setValue(sdata.fTriggerSeqPed);
1908 fTriggerSeqLPint->setValue(sdata.fTriggerSeqLPint);
1909 fTriggerSeqLPext->setValue(sdata.fTriggerSeqLPext);
1910
1911 fEnableTrigger->setChecked(sdata.HasTrigger());
1912 fEnableVeto->setChecked(sdata.HasVeto());
1913 fEnableExt1->setChecked(sdata.HasExt1());
1914 fEnableExt2->setChecked(sdata.HasExt2());
1915 fEnableClockCond->setChecked(sdata.HasClockConditioner());
1916
1917 for (int i=0; i<40; i++)
1918 {
1919 if (!sdata.IsActive(i))
1920 SetFtuLed(i, -1, d.time);
1921 else
1922 {
1923 if (fFtuStatus[i]==0)
1924 SetFtuLed(i, 1, d.time);
1925 }
1926 fFtuLED[i]->setChecked(false);
1927 }
1928 SetFtuStatusLed(d.time);
1929
1930#ifdef HAVE_ROOT
1931 Camera *cam = (Camera*)fRatesCanv->GetCanvas()->FindObject("Camera");
1932 for (int isw=0; isw<1440; isw++)
1933 {
1934 const int ihw = fPixelMapHW[isw];
1935 cam->SetEnable(isw, sdata.IsEnabled(ihw));
1936 }
1937
1938 fRatesCanv->GetCanvas()->Modified();
1939 fRatesCanv->GetCanvas()->Update();
1940#endif
1941
1942 {
1943 const int isw = fPixelIdx->value();
1944 const int ihw = fPixelMapHW[isw];
1945 const bool on = sdata.IsEnabled(ihw);
1946 fPixelEnable->setChecked(on);
1947 }
1948
1949 if (fThresholdIdx->value()>=0)
1950 {
1951 const int isw = fThresholdIdx->value();
1952 const int ihw = fPatchMapHW[isw];
1953 fThresholdVal->setValue(sdata.fThreshold[ihw]);
1954 }
1955
1956 fPrescalingVal->setValue(sdata.fPrescaling[0]);
1957
1958 fFtmStaticData = sdata;
1959 }
1960
1961 void handleFtmPassport(const DimData &d)
1962 {
1963 if (!CheckSize(d, sizeof(FTM::DimPassport)))
1964 return;
1965
1966 const FTM::DimPassport &sdata = d.ref<FTM::DimPassport>();
1967
1968 stringstream str1, str2;
1969 str1 << hex << "0x" << setfill('0') << setw(16) << sdata.fBoardId;
1970 str2 << sdata.fFirmwareId;
1971
1972 fFtmBoardId->setText(str1.str().c_str());
1973 fFtmFirmwareId->setText(str2.str().c_str());
1974 }
1975
1976 void handleFtmFtuList(const DimData &d)
1977 {
1978 if (!CheckSize(d, sizeof(FTM::DimFtuList)))
1979 return;
1980
1981 fFtuPing->setChecked(false);
1982
1983 const FTM::DimFtuList &sdata = d.ref<FTM::DimFtuList>();
1984
1985 stringstream str;
1986 str << "<table width='100%'>" << setfill('0');
1987 str << "<tr><th>Num</th><th></th><th>Addr</th><th></th><th>DNA</th></tr>";
1988 for (int i=0; i<40; i++)
1989 {
1990 str << "<tr>";
1991 str << "<td align='center'>" << dec << i << hex << "</td>";
1992 str << "<td align='center'>:</td>";
1993 str << "<td align='center'>0x" << setw(2) << (int)sdata.fAddr[i] << "</td>";
1994 str << "<td align='center'>:</td>";
1995 str << "<td align='center'>0x" << setw(16) << sdata.fDNA[i] << "</td>";
1996 str << "</tr>";
1997 }
1998 str << "</table>";
1999
2000 fFtuDNA->setText(str.str().c_str());
2001
2002 fFtuAnswersTotal->setValue(sdata.fNumBoards);
2003 fFtuAnswersCrate0->setValue(sdata.fNumBoardsCrate[0]);
2004 fFtuAnswersCrate1->setValue(sdata.fNumBoardsCrate[1]);
2005 fFtuAnswersCrate2->setValue(sdata.fNumBoardsCrate[2]);
2006 fFtuAnswersCrate3->setValue(sdata.fNumBoardsCrate[3]);
2007
2008 for (int i=0; i<40; i++)
2009 SetFtuLed(i, sdata.IsActive(i) ? sdata.fPing[i] : -1, d.time);
2010
2011 SetFtuStatusLed(d.time);
2012 }
2013
2014 void handleFtmError(const DimData &d)
2015 {
2016 if (!CheckSize(d, sizeof(FTM::DimError)))
2017 return;
2018
2019 const FTM::DimError &sdata = d.ref<FTM::DimError>();
2020
2021 SetFtuLed(sdata.fError.fDestAddress, sdata.fError.fNumCalls, d.time);
2022 SetFtuStatusLed(d.time);
2023
2024 // FIXME: Write to special window!
2025 //Out() << "Error:" << endl;
2026 //Out() << sdata.fError << endl;
2027 }
2028
2029 // ====================== MessageImp ====================================
2030
2031 bool fChatOnline;
2032
2033 void handleStateChanged(const Time &time, const std::string &server,
2034 const State &s)
2035 {
2036 // FIXME: Prefix tooltip with time
2037 if (server=="FTM_CONTROL")
2038 {
2039 // FIXME: Enable FTU page!!!
2040 fStatusFTMLabel->setText(s.name.c_str());
2041 fStatusFTMLabel->setToolTip(s.comment.c_str());
2042
2043 bool enable = false;
2044
2045 if (s.index<FTM::StateMachine::kDisconnected) // No Dim connection
2046 SetLedColor(fStatusFTMLed, kLedGray, time);
2047 if (s.index==FTM::StateMachine::kDisconnected) // Dim connection / FTM disconnected
2048 SetLedColor(fStatusFTMLed, kLedYellow, time);
2049 if (s.index==FTM::StateMachine::kConnected ||
2050 s.index==FTM::StateMachine::kIdle ||
2051 s.index==FTM::StateMachine::kConfiguring1 ||
2052 s.index==FTM::StateMachine::kConfiguring2 ||
2053 s.index==FTM::StateMachine::kConfigured ||
2054 s.index==FTM::StateMachine::kTakingData) // Dim connection / FTM connected
2055 SetLedColor(fStatusFTMLed, kLedGreen, time);
2056
2057 if (s.index==FTM::StateMachine::kConnected ||
2058 s.index==FTM::StateMachine::kIdle) // Dim connection / FTM connected
2059 enable = true;
2060
2061 fTriggerWidget->setEnabled(enable);
2062 fFtuGroupEnable->setEnabled(enable);
2063 fRatesControls->setEnabled(enable);
2064 fFtuWidget->setEnabled(s.index>FTM::StateMachine::kDisconnected);
2065
2066 if (s.index>=FTM::StateMachine::kConnected)
2067 SetFtuStatusLed(time);
2068 else
2069 {
2070 SetLedColor(fStatusFTULed, kLedGray, time);
2071 fStatusFTULabel->setText("Offline");
2072 fStatusFTULabel->setToolTip("FTM is not online.");
2073 }
2074 }
2075
2076 if (server=="FAD_CONTROL")
2077 {
2078 fStatusFADLabel->setText(s.name.c_str());
2079 fStatusFADLabel->setToolTip(s.comment.c_str());
2080
2081 bool enable = false;
2082
2083 if (s.index<FAD::kOffline) // No Dim connection
2084 {
2085 SetLedColor(fStatusFADLed, kLedGray, time);
2086
2087 // Timing problem - sometimes they stay gray :(
2088 //for (int i=0; i<40; i++)
2089 // SetLedColor(fFadLED[i], kLedGray, time);
2090
2091 /*
2092 fStatusEventBuilderLabel->setText("Offline");
2093 fStatusEventBuilderLabel->setToolTip("No connection to fadctrl.");
2094 fEvtBldWidget->setEnabled(false);
2095
2096 SetLedColor(fStatusEventBuilderLed, kLedGray, time);
2097 */
2098 }
2099 if (s.index==FAD::kOffline) // Dim connection / FTM disconnected
2100 SetLedColor(fStatusFADLed, kLedRed, time);
2101 if (s.index==FAD::kDisconnected) // Dim connection / FTM disconnected
2102 SetLedColor(fStatusFADLed, kLedOrange, time);
2103 if (s.index==FAD::kConnecting) // Dim connection / FTM disconnected
2104 {
2105 SetLedColor(fStatusFADLed, kLedYellow, time);
2106 // FIXME FIXME FIXME: The LEDs are not displayed when disabled!
2107 enable = true;
2108 }
2109 if (s.index>=FAD::kConnected) // Dim connection / FTM connected
2110 {
2111 SetLedColor(fStatusFADLed, kLedGreen, time);
2112 enable = true;
2113 }
2114
2115 fFadWidget->setEnabled(enable);
2116 }
2117
2118 if (server=="FSC_CONTROL")
2119 {
2120 fStatusFSCLabel->setText(s.name.c_str());
2121 fStatusFSCLabel->setToolTip(s.comment.c_str());
2122
2123 bool enable = false;
2124
2125 if (s.index<1) // No Dim connection
2126 SetLedColor(fStatusFSCLed, kLedGray, time);
2127 if (s.index==1) // Dim connection / FTM disconnected
2128 SetLedColor(fStatusFSCLed, kLedRed, time);
2129 if (s.index>=2) // Dim connection / FTM disconnected
2130 {
2131 SetLedColor(fStatusFSCLed, kLedGreen, time);
2132 enable = true;
2133 }
2134
2135 //fFscWidget->setEnabled(enable);
2136 }
2137
2138 if (server=="DATA_LOGGER")
2139 {
2140 fStatusLoggerLabel->setText(s.name.c_str());
2141 fStatusLoggerLabel->setToolTip(s.comment.c_str());
2142
2143 bool enable = true;
2144
2145 if (s.index<=30) // Ready/Waiting
2146 SetLedColor(fStatusLoggerLed, kLedYellow, time);
2147 if (s.index<-1) // Offline
2148 {
2149 SetLedColor(fStatusLoggerLed, kLedGray, time);
2150 enable = false;
2151 }
2152 if (s.index>=0x100) // Error
2153 SetLedColor(fStatusLoggerLed, kLedRed, time);
2154 if (s.index==40) // Logging
2155 SetLedColor(fStatusLoggerLed, kLedGreen, time);
2156
2157 fLoggerWidget->setEnabled(enable);
2158 }
2159
2160 if (server=="CHAT")
2161 {
2162 fStatusChatLabel->setText(s.name.c_str());
2163
2164 fChatOnline = s.index==0;
2165
2166 SetLedColor(fStatusChatLed, fChatOnline ? kLedGreen : kLedGray, time);
2167
2168 fChatSend->setEnabled(fChatOnline);
2169 fChatMessage->setEnabled(fChatOnline);
2170 }
2171
2172 if (server=="SCHEDULER")
2173 {
2174 fStatusSchedulerLabel->setText(s.name.c_str());
2175
2176 SetLedColor(fStatusSchedulerLed, s.index>=0 ? kLedGreen : kLedRed, time);
2177 }
2178 }
2179
2180 void on_fTabWidget_currentChanged(int which)
2181 {
2182 if (fTabWidget->tabText(which)=="Chat")
2183 fTabWidget->setTabIcon(which, QIcon());
2184 }
2185
2186 void handleWrite(const Time &time, const string &text, int qos)
2187 {
2188 stringstream out;
2189
2190 if (text.substr(0, 6)=="CHAT: ")
2191 {
2192 if (qos==MessageImp::kDebug)
2193 return;
2194
2195 out << "<font size='-1' color='navy'>[<B>";
2196 out << time.GetAsStr("%H:%M:%S");
2197 out << "</B>]</FONT> " << text.substr(6);
2198 fChatText->append(out.str().c_str());
2199
2200 if (fTabWidget->tabText(fTabWidget->currentIndex())=="Chat")
2201 return;
2202
2203 static int num = 0;
2204 if (num++<2)
2205 return;
2206
2207 for (int i=0; i<fTabWidget->count(); i++)
2208 if (fTabWidget->tabText(i)=="Chat")
2209 {
2210 fTabWidget->setTabIcon(i, QIcon(":/Resources/icons/warning 3.png"));
2211 break;
2212 }
2213
2214 return;
2215 }
2216
2217
2218 out << "<font style='font-family:monospace' color='";
2219
2220 switch (qos)
2221 {
2222 case kMessage: out << "black"; break;
2223 case kInfo: out << "green"; break;
2224 case kWarn: out << "#FF6600"; break;
2225 case kError: out << "maroon"; break;
2226 case kFatal: out << "maroon"; break;
2227 case kDebug: out << "navy"; break;
2228 default: out << "navy"; break;
2229 }
2230 out << "'>";
2231 out << time.GetAsStr("%H:%M:%S.%f").substr(0,12);
2232 out << " - " << text << "</font>";
2233
2234 fLogText->append(out.str().c_str());
2235
2236 if (qos>=kWarn && qos!=kDebug)
2237 fTextEdit->append(out.str().c_str());
2238 }
2239
2240 void IndicateStateChange(const Time &time, const std::string &server)
2241 {
2242 const State s = GetState(server, GetCurrentState(server));
2243
2244 QApplication::postEvent(this,
2245 new FunctionEvent(boost::bind(&FactGui::handleStateChanged, this, time, server, s)));
2246 }
2247
2248 int Write(const Time &time, const string &txt, int qos)
2249 {
2250 QApplication::postEvent(this,
2251 new FunctionEvent(boost::bind(&FactGui::handleWrite, this, time, txt, qos)));
2252
2253 return 0;
2254 }
2255
2256 // ====================== Dim infoHandler================================
2257
2258 void handleDimService(const string &txt)
2259 {
2260 fDimSvcText->append(txt.c_str());
2261 }
2262
2263 void infoHandlerService(DimInfo &info)
2264 {
2265 const string fmt = string(info.getFormat()).empty() ? "C" : info.getFormat();
2266
2267 stringstream dummy;
2268 const Converter conv(dummy, fmt, false);
2269
2270 const Time tm(info.getTimestamp(), info.getTimestampMillisecs()*1000);
2271
2272 stringstream out;
2273 out << "<font size'-1' color='navy'>[";
2274 out << tm.GetAsStr("%H:%M:%S.%f").substr(0,12);
2275 out << "]</font> <B>" << info.getName() << "</B> - ";
2276
2277 bool iserr = true;
2278 if (!conv)
2279 {
2280 out << "Compilation of format string '" << fmt << "' failed!";
2281 }
2282 else
2283 {
2284 try
2285 {
2286 const string dat = conv.GetString(info.getData(), info.getSize());
2287 out << dat;
2288 iserr = false;
2289 }
2290 catch (const runtime_error &e)
2291 {
2292 out << "Conversion to string failed!<pre>" << e.what() << "</pre>";
2293 }
2294 }
2295
2296 // srand(hash<string>()(string(info.getName())));
2297 // int bg = rand()&0xffffff;
2298
2299 int bg = hash<string>()(string(info.getName()));
2300
2301 // allow only light colors
2302 bg = ~(bg&0x1f1f1f)&0xffffff;
2303
2304 if (iserr)
2305 bg = 0xffffff;
2306
2307 stringstream bgcol;
2308 bgcol << hex << setfill('0') << setw(6) << bg;
2309
2310 const string col = iserr ? "red" : "black";
2311 const string str = "<table width='100%' bgcolor=#"+bgcol.str()+"><tr><td><font color='"+col+"'>"+out.str()+"</font></td></tr></table>";
2312
2313 QApplication::postEvent(this,
2314 new FunctionEvent(boost::bind(&FactGui::handleDimService, this, str)));
2315 }
2316
2317 void CallInfoHandler(void (FactGui::*handler)(const DimData&), const DimData &d)
2318 {
2319 fInHandler = true;
2320 (this->*handler)(d);
2321 fInHandler = false;
2322 }
2323
2324 /*
2325 void CallInfoHandler(const boost::function<void()> &func)
2326 {
2327 // This ensures that newly received values are not sent back to the emitter
2328 // because changing the value emits the valueChanged signal (or similar)
2329 fInHandler = true;
2330 func();
2331 fInHandler = false;
2332 }*/
2333
2334 void PostInfoHandler(void (FactGui::*handler)(const DimData&))
2335 {
2336 //const boost::function<void()> f = boost::bind(handler, this, DimData(getInfo()));
2337
2338 FunctionEvent *evt = new FunctionEvent(boost::bind(&FactGui::CallInfoHandler, this, handler, DimData(getInfo())));
2339 // FunctionEvent *evt = new FunctionEvent(boost::bind(&FactGui::CallInfoHandler, this, f));
2340 // FunctionEvent *evt = new FunctionEvent(boost::bind(handler, this, DimData(getInfo()))));
2341
2342 QApplication::postEvent(this, evt);
2343 }
2344
2345 void infoHandler()
2346 {
2347 // Initialize the time-stamp (what a weird workaround...)
2348 if (getInfo())
2349 getInfo()->getTimestamp();
2350
2351 if (getInfo()==&fDimDNS)
2352 return PostInfoHandler(&FactGui::handleDimDNS);
2353#ifdef DEBUG_DIM
2354 cout << "HandleDimInfo " << getInfo()->getName() << endl;
2355#endif
2356 if (getInfo()==&fDimLoggerStats)
2357 return PostInfoHandler(&FactGui::handleLoggerStats);
2358
2359// if (getInfo()==&fDimFadFiles)
2360// return PostInfoHandler(&FactGui::handleFadFiles);
2361
2362 if (getInfo()==&fDimFadWriteStats)
2363 return PostInfoHandler(&FactGui::handleFadWriteStats);
2364
2365 if (getInfo()==&fDimFadConnections)
2366 return PostInfoHandler(&FactGui::handleFadConnections);
2367
2368 if (getInfo()==&fDimFadFwVersion)
2369 return PostInfoHandler(&FactGui::handleFadFwVersion);
2370
2371 if (getInfo()==&fDimFadRunNumber)
2372 return PostInfoHandler(&FactGui::handleFadRunNumber);
2373
2374 if (getInfo()==&fDimFadDNA)
2375 return PostInfoHandler(&FactGui::handleFadDNA);
2376
2377 if (getInfo()==&fDimFadTemperature)
2378 return PostInfoHandler(&FactGui::handleFadTemperature);
2379
2380 if (getInfo()==&fDimFadRefClock)
2381 return PostInfoHandler(&FactGui::handleFadRefClock);
2382
2383 if (getInfo()==&fDimFadRoi)
2384 return PostInfoHandler(&FactGui::handleFadRoi);
2385
2386 if (getInfo()==&fDimFadDac)
2387 return PostInfoHandler(&FactGui::handleFadDac);
2388
2389 if (getInfo()==&fDimFadPrescaler)
2390 return PostInfoHandler(&FactGui::handleFadPrescaler);
2391
2392 if (getInfo()==&fDimFadStatus)
2393 return PostInfoHandler(&FactGui::handleFadStatus);
2394
2395 if (getInfo()==&fDimFadStatistics1)
2396 return PostInfoHandler(&FactGui::handleFadStatistics1);
2397
2398 if (getInfo()==&fDimFadStatistics2)
2399 return PostInfoHandler(&FactGui::handleFadStatistics2);
2400
2401 if (getInfo()==&fDimFadEvents)
2402 return PostInfoHandler(&FactGui::handleFadEvents);
2403
2404 if (getInfo()==&fDimFadRuns)
2405 return PostInfoHandler(&FactGui::handleFadRuns);
2406
2407 if (getInfo()==&fDimFadEventData)
2408 return PostInfoHandler(&FactGui::handleFadEventData);
2409
2410/*
2411 if (getInfo()==&fDimFadSetup)
2412 return PostInfoHandler(&FactGui::handleFadSetup);
2413*/
2414 if (getInfo()==&fDimLoggerFilenameNight)
2415 return PostInfoHandler(&FactGui::handleLoggerFilenameNight);
2416
2417 if (getInfo()==&fDimLoggerNumSubs)
2418 return PostInfoHandler(&FactGui::handleLoggerNumSubs);
2419
2420 if (getInfo()==&fDimLoggerFilenameRun)
2421 return PostInfoHandler(&FactGui::handleLoggerFilenameRun);
2422
2423 if (getInfo()==&fDimFtmTriggerCounter)
2424 return PostInfoHandler(&FactGui::handleFtmTriggerCounter);
2425
2426 if (getInfo()==&fDimFtmCounter)
2427 return PostInfoHandler(&FactGui::handleFtmCounter);
2428
2429 if (getInfo()==&fDimFtmDynamicData)
2430 return PostInfoHandler(&FactGui::handleFtmDynamicData);
2431
2432 if (getInfo()==&fDimFtmPassport)
2433 return PostInfoHandler(&FactGui::handleFtmPassport);
2434
2435 if (getInfo()==&fDimFtmFtuList)
2436 return PostInfoHandler(&FactGui::handleFtmFtuList);
2437
2438 if (getInfo()==&fDimFtmStaticData)
2439 return PostInfoHandler(&FactGui::handleFtmStaticData);
2440
2441 if (getInfo()==&fDimFtmError)
2442 return PostInfoHandler(&FactGui::handleFtmError);
2443
2444// if (getInfo()==&fDimFadFiles)
2445// return PostInfoHandler(&FactGui::handleFadFiles);
2446
2447 for (map<string,DimInfo*>::iterator i=fServices.begin(); i!=fServices.end(); i++)
2448 if (i->second==getInfo())
2449 {
2450 infoHandlerService(*i->second);
2451 return;
2452 }
2453
2454 DimNetwork::infoHandler();
2455 }
2456
2457
2458 // ======================================================================
2459
2460 bool event(QEvent *evt)
2461 {
2462 if (dynamic_cast<FunctionEvent*>(evt))
2463 return static_cast<FunctionEvent*>(evt)->Exec();
2464
2465 if (dynamic_cast<CheckBoxEvent*>(evt))
2466 {
2467 const QStandardItem &item = static_cast<CheckBoxEvent*>(evt)->item;
2468 const QStandardItem *par = item.parent();
2469 if (par)
2470 {
2471 const QString server = par->text();
2472 const QString service = item.text();
2473
2474 const string s = (server+'/'+service).toStdString();
2475
2476 if (item.checkState()==Qt::Checked)
2477 SubscribeService(s);
2478 else
2479 UnsubscribeService(s);
2480 }
2481 }
2482
2483 return MainWindow::event(evt); // unrecognized
2484 }
2485
2486 void on_fDimCmdSend_clicked()
2487 {
2488 const QString server = fDimCmdServers->currentIndex().data().toString();
2489 const QString command = fDimCmdCommands->currentIndex().data().toString();
2490 const QString arguments = fDimCmdLineEdit->displayText();
2491
2492 // FIXME: Sending a command exactly when the info Handler changes
2493 // the list it might lead to confusion.
2494 try
2495 {
2496 SendDimCommand(server.toStdString(), command.toStdString()+" "+arguments.toStdString());
2497 fTextEdit->append("<font color='green'>Command '"+server+'/'+command+"' successfully emitted.</font>");
2498 fDimCmdLineEdit->clear();
2499 }
2500 catch (const runtime_error &e)
2501 {
2502 stringstream txt;
2503 txt << e.what();
2504
2505 string buffer;
2506 while (getline(txt, buffer, '\n'))
2507 fTextEdit->append(("<font color='red'><pre>"+buffer+"</pre></font>").c_str());
2508 }
2509 }
2510
2511#ifdef HAVE_ROOT
2512 void slot_RootEventProcessed(TObject *obj, unsigned int evt, TCanvas *canv)
2513 {
2514 // kMousePressEvent // TCanvas processed QEvent mousePressEvent
2515 // kMouseMoveEvent // TCanvas processed QEvent mouseMoveEvent
2516 // kMouseReleaseEvent // TCanvas processed QEvent mouseReleaseEvent
2517 // kMouseDoubleClickEvent // TCanvas processed QEvent mouseDoubleClickEvent
2518 // kKeyPressEvent // TCanvas processed QEvent keyPressEvent
2519 // kEnterEvent // TCanvas processed QEvent enterEvent
2520 // kLeaveEvent // TCanvas processed QEvent leaveEvent
2521 if (dynamic_cast<TCanvas*>(obj))
2522 return;
2523
2524 TQtWidget *tipped = static_cast<TQtWidget*>(sender());
2525
2526 if (evt==11/*kMouseReleaseEvent*/)
2527 {
2528 if (dynamic_cast<Camera*>(obj))
2529 {
2530 const float xx = canv->AbsPixeltoX(tipped->GetEventX());
2531 const float yy = canv->AbsPixeltoY(tipped->GetEventY());
2532
2533 Camera *cam = static_cast<Camera*>(obj);
2534 const int isw = cam->GetIdx(xx, yy);
2535
2536 fPixelIdx->setValue(isw);
2537 ChoosePixel(*cam, isw);
2538 }
2539 return;
2540 }
2541
2542 if (evt==61/*kMouseDoubleClickEvent*/)
2543 {
2544 if (dynamic_cast<Camera*>(obj) && fRatesControls->isEnabled())
2545 {
2546 const float xx = canv->AbsPixeltoX(tipped->GetEventX());
2547 const float yy = canv->AbsPixeltoY(tipped->GetEventY());
2548
2549 Camera *cam = static_cast<Camera*>(obj);
2550 const int isw = cam->GetIdx(xx, yy);
2551
2552 ChoosePixel(*cam, isw);
2553
2554 fPixelIdx->setValue(isw);
2555
2556 const uint16_t ihw = fPixelMapHW[isw];
2557
2558 Dim::SendCommand("FTM_CONTROL/TOGGLE_PIXEL", ihw);
2559 }
2560
2561 if (dynamic_cast<TAxis*>(obj))
2562 static_cast<TAxis*>(obj)->UnZoom();
2563
2564 return;
2565 }
2566
2567 // Find the object which will get picked by the GetObjectInfo
2568 // due to buffer overflows in many root-versions
2569 // in TH1 and TProfile we have to work around and implement
2570 // our own GetObjectInfo which make everything a bit more
2571 // complicated.
2572 canv->cd();
2573#if ROOT_VERSION_CODE > ROOT_VERSION(5,22,00)
2574 const char *objectInfo =
2575 obj->GetObjectInfo(tipped->GetEventX(),tipped->GetEventY());
2576#else
2577 const char *objectInfo = dynamic_cast<TH1*>(obj) ?
2578 "" : obj->GetObjectInfo(tipped->GetEventX(),tipped->GetEventY());
2579#endif
2580
2581 QString tipText;
2582 tipText += obj->GetName();
2583 tipText += " [";
2584 tipText += obj->ClassName();
2585 tipText += "]: ";
2586 tipText += objectInfo;
2587
2588 if (dynamic_cast<Camera*>(obj))
2589 {
2590 const float xx = canv->AbsPixeltoX(tipped->GetEventX());
2591 const float yy = canv->AbsPixeltoY(tipped->GetEventY());
2592
2593 Camera *cam = static_cast<Camera*>(obj);
2594
2595 const int isw = cam->GetIdx(xx, yy);
2596 const int ihw = fPixelMapHW[isw];
2597
2598 const int idx = fPatchHW[isw];
2599
2600 int ii = 0;
2601 for (; ii<160; ii++)
2602 if (idx==fPatchMapHW[ii])
2603 break;
2604
2605
2606 const int patch = ihw%4;
2607 const int board = (ihw/4)%10;
2608 const int crate = (ihw/4)/10;
2609
2610 ostringstream str;
2611 str << " (hw=" << ihw << ") Patch=" << ii << " (hw=" << fPatchMapHW[idx] << "; Crate=" << crate << " Board=" << board << " Patch=" << patch << ")";
2612
2613 tipText += str.str().c_str();
2614 }
2615
2616
2617 fStatusBar->showMessage(tipText, 3000);
2618
2619 gSystem->ProcessEvents();
2620 //QWhatsThis::display(tipText)
2621 }
2622
2623 void slot_RootUpdate()
2624 {
2625 gSystem->ProcessEvents();
2626 QTimer::singleShot(0, this, SLOT(slot_RootUpdate()));
2627 }
2628
2629 void ChoosePatch(Camera &cam, int isw)
2630 {
2631 cam.Reset();
2632
2633 fThresholdIdx->setValue(isw);
2634
2635 const int ihw = isw<0 ? 0 : fPatchMapHW[isw];
2636
2637 fPatchRate->setEnabled(isw>=0);
2638 fThresholdCrate->setEnabled(isw>=0);
2639 fThresholdBoard->setEnabled(isw>=0);
2640 fThresholdPatch->setEnabled(isw>=0);
2641
2642 if (isw<0)
2643 return;
2644
2645 const int patch = ihw%4;
2646 const int board = (ihw/4)%10;
2647 const int crate = (ihw/4)/10;
2648
2649 fInChoosePatch = true;
2650
2651 fThresholdCrate->setValue(crate);
2652 fThresholdBoard->setValue(board);
2653 fThresholdPatch->setValue(patch);
2654
2655 fInChoosePatch = false;
2656
2657 fThresholdVal->setValue(fFtmStaticData.fThreshold[ihw]);
2658 fPatchRate->setValue(cam.GetData(isw));
2659
2660 // Loop over the software idx of all pixels
2661 for (unsigned int i=0; i<1440; i++)
2662 if (fPatchHW[i]==ihw)
2663 cam.SetBold(i);
2664 }
2665
2666 void ChoosePixel(Camera &cam, int isw)
2667 {
2668 const int ihw = fPixelMapHW[isw];
2669
2670 int ii = 0;
2671 for (; ii<160; ii++)
2672 if (fPatchHW[isw]==fPatchMapHW[ii])
2673 break;
2674
2675 cam.SetWhite(isw);
2676 ChoosePatch(cam, ii);
2677
2678 const bool on = fFtmStaticData.IsEnabled(ihw);
2679 fPixelEnable->setChecked(on);
2680 }
2681
2682 void UpdatePatch(int isw)
2683 {
2684 Camera *cam = (Camera*)fRatesCanv->GetCanvas()->FindObject("Camera");
2685 ChoosePatch(*cam, isw);
2686 }
2687
2688 void on_fThresholdIdx_valueChanged(int isw)
2689 {
2690 UpdatePatch(isw);
2691
2692 fRatesCanv->GetCanvas()->Modified();
2693 fRatesCanv->GetCanvas()->Update();
2694 }
2695
2696 void UpdateThresholdIdx()
2697 {
2698 if (fInChoosePatch)
2699 return;
2700
2701 const int crate = fThresholdCrate->value();
2702 const int board = fThresholdBoard->value();
2703 const int patch = fThresholdPatch->value();
2704
2705 const int ihw = patch + board*4 + crate*40;
2706
2707 int isw = 0;
2708 for (; isw<160; isw++)
2709 if (ihw==fPatchMapHW[isw])
2710 break;
2711
2712 UpdatePatch(isw);
2713 }
2714
2715 void on_fThresholdPatch_valueChanged(int)
2716 {
2717 UpdateThresholdIdx();
2718 }
2719 void on_fThresholdBoard_valueChanged(int)
2720 {
2721 UpdateThresholdIdx();
2722 }
2723 void on_fThresholdCrate_valueChanged(int)
2724 {
2725 UpdateThresholdIdx();
2726 }
2727
2728 void on_fPixelIdx_valueChanged(int isw)
2729 {
2730 Camera *cam = (Camera*)fRatesCanv->GetCanvas()->FindObject("Camera");
2731 ChoosePixel(*cam, isw);
2732
2733 fRatesCanv->GetCanvas()->Modified();
2734 fRatesCanv->GetCanvas()->Update();
2735 }
2736
2737 void on_fRatesMin_valueChanged(int min)
2738 {
2739 Camera *cam = (Camera*)fRatesCanv->GetCanvas()->FindObject("Camera");
2740 cam->SetMin(min);
2741
2742 fRatesCanv->GetCanvas()->Modified();
2743 fRatesCanv->GetCanvas()->Update();
2744 }
2745
2746 void on_fRatesMax_valueChanged(int max)
2747 {
2748 Camera *cam = (Camera*)fRatesCanv->GetCanvas()->FindObject("Camera");
2749 cam->SetMax(max);
2750
2751 fRatesCanv->GetCanvas()->Modified();
2752 fRatesCanv->GetCanvas()->Update();
2753 }
2754
2755#endif
2756
2757 void on_fPixelEnable_stateChanged(int b)
2758 {
2759 if (fInHandler)
2760 return;
2761
2762 const uint16_t isw = fPixelIdx->value();
2763 const uint16_t ihw = fPixelMapHW[isw];
2764
2765 Dim::SendCommand(b==Qt::Unchecked ?
2766 "FTM_CONTROL/DISABLE_PIXEL" : "FTM_CONTROL/ENABLE_PIXEL",
2767 ihw);
2768 }
2769
2770 void on_fPixelDisableOthers_clicked()
2771 {
2772 const uint16_t isw = fPixelIdx->value();
2773 const uint16_t ihw = fPixelMapHW[isw];
2774
2775 Dim::SendCommand("FTM_CONTROL/DISABLE_ALL_PIXELS_EXCEPT", ihw);
2776 }
2777
2778 void on_fThresholdDisableOthers_clicked()
2779 {
2780 const int16_t isw = fThresholdIdx->value();
2781 const int16_t ihw = isw<0 ? -1 : fPatchMapHW[isw];
2782
2783 Dim::SendCommand("FTM_CONTROL/DISABLE_ALL_PATCHES_EXCEPT", ihw);
2784 }
2785
2786 void on_fThresholdVal_valueChanged(int v)
2787 {
2788 fThresholdVolt->setValue(2500./4095*v);
2789
2790 const int32_t isw = fThresholdIdx->value();
2791 const int32_t ihw = isw<0 ? -1 : fPatchMapHW[isw];
2792
2793 const int32_t d[2] = { ihw, v };
2794
2795 if (!fInHandler)
2796 Dim::SendCommand("FTM_CONTROL/SET_THRESHOLD", d);
2797 }
2798
2799 TGraph fGraphFtmTemp[4];
2800 TGraph fGraphFtmRate;
2801 TGraph fGraphPatchRate[160];
2802 TGraph fGraphBoardRate[40];
2803
2804#ifdef HAVE_ROOT
2805 TH1 *DrawTimeFrame(const char *ytitle)
2806 {
2807 const double tm = Time().RootTime();
2808
2809 TH1F h("TimeFrame", "", 1, tm, tm+60);//Time().RootTime()-1./24/60/60, Time().RootTime());
2810 h.SetDirectory(0);
2811// h.SetBit(TH1::kCanRebin);
2812 h.SetStats(kFALSE);
2813// h.SetMinimum(0);
2814// h.SetMaximum(1);
2815 h.SetXTitle("Time");
2816 h.SetYTitle(ytitle);
2817 h.GetXaxis()->CenterTitle();
2818 h.GetYaxis()->CenterTitle();
2819 h.GetXaxis()->SetTimeDisplay(true);
2820 h.GetXaxis()->SetTimeFormat("%Mh%S'");
2821 h.GetXaxis()->SetLabelSize(0.025);
2822 h.GetYaxis()->SetLabelSize(0.025);
2823 h.GetYaxis()->SetTitleOffset(1.2);
2824 // h.GetYaxis()->SetTitleSize(1.2);
2825
2826 TH1 *cpy = h.DrawCopy();
2827 cpy->SetDirectory(0);
2828 return cpy;
2829 }
2830#endif
2831
2832public:
2833 FactGui() :
2834 fFtuStatus(40),
2835 fPixelMapHW(1440), fPatchMapHW(160), fPatchHW(1440),
2836 fInChoosePatch(false),
2837 fDimDNS("DIS_DNS/VERSION_NUMBER", 1, int(0), this),
2838 //-
2839 fDimLoggerStats ("DATA_LOGGER/STATS", (void*)NULL, 0, this),
2840 fDimLoggerFilenameNight("DATA_LOGGER/FILENAME_NIGHTLY", (void*)NULL, 0, this),
2841 fDimLoggerFilenameRun ("DATA_LOGGER/FILENAME_RUN", (void*)NULL, 0, this),
2842 fDimLoggerNumSubs ("DATA_LOGGER/NUM_SUBS", (void*)NULL, 0, this),
2843 //-
2844 fDimFtmPassport ("FTM_CONTROL/PASSPORT", (void*)NULL, 0, this),
2845 fDimFtmTriggerCounter ("FTM_CONTROL/TRIGGER_COUNTER", (void*)NULL, 0, this),
2846 fDimFtmError ("FTM_CONTROL/ERROR", (void*)NULL, 0, this),
2847 fDimFtmFtuList ("FTM_CONTROL/FTU_LIST", (void*)NULL, 0, this),
2848 fDimFtmStaticData ("FTM_CONTROL/STATIC_DATA", (void*)NULL, 0, this),
2849 fDimFtmDynamicData ("FTM_CONTROL/DYNAMIC_DATA", (void*)NULL, 0, this),
2850 fDimFtmCounter ("FTM_CONTROL/COUNTER", (void*)NULL, 0, this),
2851 //-
2852 fDimFadWriteStats ("FAD_CONTROL/STATS", (void*)NULL, 0, this),
2853 fDimFadRuns ("FAD_CONTROL/RUNS", (void*)NULL, 0, this),
2854 fDimFadEvents ("FAD_CONTROL/EVENTS", (void*)NULL, 0, this),
2855 fDimFadEventData ("FAD_CONTROL/EVENT_DATA", (void*)NULL, 0, this),
2856 fDimFadConnections ("FAD_CONTROL/CONNECTIONS", (void*)NULL, 0, this),
2857 fDimFadFwVersion ("FAD_CONTROL/FIRMWARE_VERSION", (void*)NULL, 0, this),
2858 fDimFadRunNumber ("FAD_CONTROL/RUN_NUMBER", (void*)NULL, 0, this),
2859 fDimFadDNA ("FAD_CONTROL/DNA", (void*)NULL, 0, this),
2860 fDimFadTemperature ("FAD_CONTROL/TEMPERATURE", (void*)NULL, 0, this),
2861 fDimFadPrescaler ("FAD_CONTROL/PRESCALER", (void*)NULL, 0, this),
2862 fDimFadRefClock ("FAD_CONTROL/REFERENCE_CLOCK", (void*)NULL, 0, this),
2863 fDimFadRoi ("FAD_CONTROL/REGION_OF_INTEREST", (void*)NULL, 0, this),
2864 fDimFadDac ("FAD_CONTROL/DAC", (void*)NULL, 0, this),
2865 fDimFadStatus ("FAD_CONTROL/STATUS", (void*)NULL, 0, this),
2866 fDimFadStatistics1 ("FAD_CONTROL/STATISTICS1", (void*)NULL, 0, this),
2867 fDimFadStatistics2 ("FAD_CONTROL/STATISTICS2", (void*)NULL, 0, this),
2868 //-
2869 fEventData(0),
2870 fTimeStamp1(0),
2871 fTriggerCounter0(0),
2872 fTimeStamp0(0)
2873
2874 {
2875 fClockCondFreq->addItem("--- Hz", QVariant(-1));
2876 fClockCondFreq->addItem("800 MHz", QVariant(800));
2877 fClockCondFreq->addItem("1 GHz", QVariant(1000));
2878 fClockCondFreq->addItem("2 GHz", QVariant(2000));
2879 fClockCondFreq->addItem("3 GHz", QVariant(3000));
2880 fClockCondFreq->addItem("4 GHz", QVariant(4000));
2881 fClockCondFreq->addItem("5 GHz", QVariant(5000));
2882
2883 fMcpNumEvents->addItem("unlimited", QVariant(0));
2884 fMcpNumEvents->addItem("100", QVariant(100));
2885 fMcpNumEvents->addItem("300", QVariant(300));
2886 fMcpNumEvents->addItem("1000", QVariant(1000));
2887 fMcpNumEvents->addItem("3000", QVariant(3000));
2888 fMcpNumEvents->addItem("10000", QVariant(10000));
2889 fMcpNumEvents->addItem("30000", QVariant(30000));
2890
2891 fMcpTime->addItem("unlimited", QVariant(0));
2892 fMcpTime->addItem("00:30", QVariant(30));
2893 fMcpTime->addItem("01:00", QVariant(60));
2894 fMcpTime->addItem("02:30", QVariant(150));
2895 fMcpTime->addItem("05:00", QVariant(300));
2896 fMcpTime->addItem("10:00", QVariant(600));
2897 fMcpTime->addItem("15:00", QVariant(900));
2898 fMcpTime->addItem("20:00", QVariant(1200));
2899 fMcpTime->addItem("30:00", QVariant(1800));
2900 fMcpTime->addItem("60:00", QVariant(3600));
2901
2902 fMcpRunType->addItem("Data", QVariant("data"));
2903 fMcpRunType->addItem("Pedestal", QVariant("pedestal"));
2904 fMcpRunType->addItem("DRS Calib", QVariant("drs-calib"));
2905
2906 fTriggerWidget->setEnabled(false);
2907 fFtuWidget->setEnabled(false);
2908 fFtuGroupEnable->setEnabled(false);
2909 fRatesControls->setEnabled(false);
2910 fFadWidget->setEnabled(false);
2911 fEvtBldWidget->setEnabled(false);
2912 fLoggerWidget->setEnabled(false);
2913
2914 fChatSend->setEnabled(false);
2915 fChatMessage->setEnabled(false);
2916
2917 DimClient::sendCommand("CHAT/MSG", "GUI online.");
2918 // + MessageDimRX
2919
2920 // --------------------------------------------------------------------------
2921
2922 ifstream fin1("Trigger-Patches.txt");
2923
2924 int l = 0;
2925
2926 string buf;
2927 while (getline(fin1, buf, '\n'))
2928 {
2929 buf = Tools::Trim(buf);
2930 if (buf[0]=='#')
2931 continue;
2932
2933 stringstream str(buf);
2934 for (int i=0; i<9; i++)
2935 {
2936 unsigned int n;
2937 str >> n;
2938
2939 if (n>=fPatchHW.size())
2940 continue;
2941
2942 fPatchHW[n] = l;
2943 }
2944 l++;
2945 }
2946
2947 if (l!=160)
2948 cerr << "WARNING - Problems reading Trigger-Patches.txt" << endl;
2949
2950 // --------------------------------------------------------------------------
2951
2952 ifstream fin2("MasterList-v3.txt");
2953
2954 l = 0;
2955
2956 while (getline(fin2, buf, '\n'))
2957 {
2958 buf = Tools::Trim(buf);
2959 if (buf[0]=='#')
2960 continue;
2961
2962 unsigned int softid, hardid, dummy;
2963
2964 stringstream str(buf);
2965
2966 str >> softid;
2967 str >> dummy;
2968 str >> hardid;
2969
2970 if (softid>=fPixelMapHW.size())
2971 continue;
2972
2973 fPixelMapHW[softid] = hardid;
2974
2975 l++;
2976 }
2977
2978 if (l!=1440)
2979 cerr << "WARNING - Problems reading MasterList-v3.txt" << endl;
2980
2981 // --------------------------------------------------------------------------
2982
2983 ifstream fin3("PatchList.txt");
2984
2985 l = 0;
2986
2987 while (getline(fin3, buf, '\n'))
2988 {
2989 buf = Tools::Trim(buf);
2990 if (buf[0]=='#')
2991 continue;
2992
2993 unsigned int softid, hardid;
2994
2995 stringstream str(buf);
2996
2997 str >> softid;
2998 str >> hardid;
2999
3000 if (softid>=fPatchMapHW.size())
3001 continue;
3002
3003 fPatchMapHW[softid] = hardid-1;
3004
3005 l++;
3006 }
3007
3008 if (l!=160)
3009 cerr << "WARNING - Problems reading PatchList.txt" << endl;
3010
3011 // --------------------------------------------------------------------------
3012#ifdef HAVE_ROOT
3013
3014 fGraphFtmRate.SetLineColor(kBlue);
3015 fGraphFtmRate.SetMarkerColor(kBlue);
3016 fGraphFtmRate.SetMarkerStyle(kFullDotMedium);
3017
3018 for (int i=0; i<160; i++)
3019 {
3020 fGraphPatchRate[i].SetName("PatchRate");
3021 //fGraphPatchRate[i].SetLineColor(kBlue);
3022 //fGraphPatchRate[i].SetMarkerColor(kBlue);
3023 fGraphPatchRate[i].SetMarkerStyle(kFullDotMedium);
3024 }
3025 for (int i=0; i<40; i++)
3026 {
3027 fGraphBoardRate[i].SetName("BoardRate");
3028 //fGraphBoardRate[i].SetLineColor(kBlue);
3029 //fGraphBoardRate[i].SetMarkerColor(kBlue);
3030 fGraphBoardRate[i].SetMarkerStyle(kFullDotMedium);
3031 }
3032 /*
3033 TCanvas *c = fFtmTempCanv->GetCanvas();
3034 c->SetBit(TCanvas::kNoContextMenu);
3035 c->SetBorderMode(0);
3036 c->SetFrameBorderMode(0);
3037 c->SetFillColor(kWhite);
3038 c->SetRightMargin(0.03);
3039 c->SetTopMargin(0.03);
3040 c->cd();
3041 */
3042 //CreateTimeFrame("Temperature / °C");
3043
3044 fGraphFtmTemp[0].SetMarkerStyle(kFullDotSmall);
3045 fGraphFtmTemp[1].SetMarkerStyle(kFullDotSmall);
3046 fGraphFtmTemp[2].SetMarkerStyle(kFullDotSmall);
3047 fGraphFtmTemp[3].SetMarkerStyle(kFullDotSmall);
3048
3049 fGraphFtmTemp[1].SetLineColor(kBlue);
3050 fGraphFtmTemp[2].SetLineColor(kRed);
3051 fGraphFtmTemp[3].SetLineColor(kGreen);
3052
3053 fGraphFtmTemp[1].SetMarkerColor(kBlue);
3054 fGraphFtmTemp[2].SetMarkerColor(kRed);
3055 fGraphFtmTemp[3].SetMarkerColor(kGreen);
3056
3057 //fGraphFtmTemp[0].Draw("LP");
3058 //fGraphFtmTemp[1].Draw("LP");
3059 //fGraphFtmTemp[2].Draw("LP");
3060 //fGraphFtmTemp[3].Draw("LP");
3061
3062 // --------------------------------------------------------------------------
3063
3064 TCanvas *c = fFtmRateCanv->GetCanvas();
3065 //c->SetBit(TCanvas::kNoContextMenu);
3066 c->SetBorderMode(0);
3067 c->SetFrameBorderMode(0);
3068 c->SetFillColor(kWhite);
3069 c->SetRightMargin(0.03);
3070 c->SetTopMargin(0.03);
3071 c->SetGrid();
3072 c->cd();
3073
3074 TH1 *hf = DrawTimeFrame("Trigger rate [Hz]");
3075 hf->GetYaxis()->SetRangeUser(0, 1010);
3076
3077 fTriggerCounter0 = -1;
3078
3079 fGraphFtmRate.SetMarkerStyle(kFullDotSmall);
3080 fGraphFtmRate.Draw("LP");
3081
3082 // --------------------------------------------------------------------------
3083
3084 c = fRatesCanv->GetCanvas();
3085 //c->SetBit(TCanvas::kNoContextMenu);
3086 c->SetBorderMode(0);
3087 c->SetFrameBorderMode(0);
3088 c->SetFillColor(kWhite);
3089 c->cd();
3090
3091 Camera *cam = new Camera;
3092 cam->SetBit(kCanDelete);
3093 cam->SetMin(fRatesMin->value());
3094 cam->SetMax(fRatesMax->value());
3095 cam->Draw();
3096
3097 ChoosePixel(*cam, 0);
3098
3099 // --------------------------------------------------------------------------
3100
3101 c = fAdcDataCanv->GetCanvas();
3102 //c->SetBit(TCanvas::kNoContextMenu);
3103 c->SetBorderMode(0);
3104 c->SetFrameBorderMode(0);
3105 c->SetFillColor(kWhite);
3106 c->SetGrid();
3107 c->cd();
3108
3109 // Create histogram?
3110
3111 // --------------------------------------------------------------------------
3112
3113// QTimer::singleShot(0, this, SLOT(slot_RootUpdate()));
3114
3115 //widget->setMouseTracking(true);
3116 //widget->EnableSignalEvents(kMouseMoveEvent);
3117
3118 fFtmRateCanv->setMouseTracking(true);
3119 fFtmRateCanv->EnableSignalEvents(kMouseMoveEvent);
3120
3121 fAdcDataCanv->setMouseTracking(true);
3122 fAdcDataCanv->EnableSignalEvents(kMouseMoveEvent);
3123
3124 fRatesCanv->setMouseTracking(true);
3125 fRatesCanv->EnableSignalEvents(kMouseMoveEvent|kMouseReleaseEvent|kMouseDoubleClickEvent);
3126
3127 connect(fRatesCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)),
3128 this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*)));
3129 connect(fFtmRateCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)),
3130 this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*)));
3131 connect(fAdcDataCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)),
3132 this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*)));
3133#endif
3134 }
3135
3136 ~FactGui()
3137 {
3138 // Unsubscribe all services
3139 for (map<string,DimInfo*>::iterator i=fServices.begin();
3140 i!=fServices.end(); i++)
3141 delete i->second;
3142
3143 delete fEventData;
3144 }
3145};
3146
3147#endif
Note: See TracBrowser for help on using the repository browser.