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

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