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

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