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

Last change on this file since 11709 was 11709, checked in by tbretz, 13 years ago
Display the received light-pulser settings.
File size: 99.6 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 fLpIntIntensity->setValue(sdata.fIntensityLPint);
2023 fLpExtIntensity->setValue(sdata.fIntensityLPext);
2024
2025 fLpIntGroup1->setChecked(sdata.HasLPintG1());
2026 fLpIntGroup2->setChecked(sdata.HasLPintG2());
2027 fLpExtGroup1->setChecked(sdata.HasLPextG1());
2028 fLpExtGroup2->setChecked(sdata.HasLPextG2());
2029
2030 fEnableTrigger->setChecked(sdata.HasTrigger());
2031 fEnableVeto->setChecked(sdata.HasVeto());
2032 fEnableExt1->setChecked(sdata.HasExt1());
2033 fEnableExt2->setChecked(sdata.HasExt2());
2034 fEnableClockCond->setChecked(sdata.HasClockConditioner());
2035
2036 for (int i=0; i<40; i++)
2037 {
2038 if (!sdata.IsActive(i))
2039 SetFtuLed(i, -1, d.time);
2040 else
2041 {
2042 if (fFtuStatus[i]==0)
2043 SetFtuLed(i, 1, d.time);
2044 }
2045 fFtuLED[i]->setChecked(false);
2046 }
2047 SetFtuStatusLed(d.time);
2048
2049#ifdef HAVE_ROOT
2050 Camera *cam = (Camera*)fRatesCanv->GetCanvas()->FindObject("Camera");
2051 for (int isw=0; isw<1440; isw++)
2052 {
2053 const int ihw = fPixelMapHW[isw];
2054 cam->SetEnable(isw, sdata.IsEnabled(ihw));
2055 }
2056
2057 fRatesCanv->GetCanvas()->Modified();
2058 fRatesCanv->GetCanvas()->Update();
2059#endif
2060
2061 {
2062 const int isw = fPixelIdx->value();
2063 const int ihw = fPixelMapHW[isw];
2064 const bool on = sdata.IsEnabled(ihw);
2065 fPixelEnable->setChecked(on);
2066 }
2067
2068 if (fThresholdIdx->value()>=0)
2069 {
2070 const int isw = fThresholdIdx->value();
2071 const int ihw = fPatchMapHW[isw];
2072 fThresholdVal->setValue(sdata.fThreshold[ihw]);
2073 }
2074
2075 fPrescalingVal->setValue(sdata.fPrescaling[0]);
2076
2077 fFtmStaticData = sdata;
2078 }
2079
2080 void handleFtmPassport(const DimData &d)
2081 {
2082 if (!CheckSize(d, sizeof(FTM::DimPassport)))
2083 return;
2084
2085 const FTM::DimPassport &sdata = d.ref<FTM::DimPassport>();
2086
2087 stringstream str1, str2;
2088 str1 << hex << "0x" << setfill('0') << setw(16) << sdata.fBoardId;
2089 str2 << sdata.fFirmwareId;
2090
2091 fFtmBoardId->setText(str1.str().c_str());
2092 fFtmFirmwareId->setText(str2.str().c_str());
2093 }
2094
2095 void handleFtmFtuList(const DimData &d)
2096 {
2097 if (!CheckSize(d, sizeof(FTM::DimFtuList)))
2098 return;
2099
2100 fFtuPing->setChecked(false);
2101
2102 const FTM::DimFtuList &sdata = d.ref<FTM::DimFtuList>();
2103
2104 stringstream str;
2105 str << "<table width='100%'>" << setfill('0');
2106 str << "<tr><th>Num</th><th></th><th>Addr</th><th></th><th>DNA</th></tr>";
2107 for (int i=0; i<40; i++)
2108 {
2109 str << "<tr>";
2110 str << "<td align='center'>" << dec << i << hex << "</td>";
2111 str << "<td align='center'>:</td>";
2112 str << "<td align='center'>0x" << setw(2) << (int)sdata.fAddr[i] << "</td>";
2113 str << "<td align='center'>:</td>";
2114 str << "<td align='center'>0x" << setw(16) << sdata.fDNA[i] << "</td>";
2115 str << "</tr>";
2116 }
2117 str << "</table>";
2118
2119 fFtuDNA->setText(str.str().c_str());
2120
2121 fFtuAnswersTotal->setValue(sdata.fNumBoards);
2122 fFtuAnswersCrate0->setValue(sdata.fNumBoardsCrate[0]);
2123 fFtuAnswersCrate1->setValue(sdata.fNumBoardsCrate[1]);
2124 fFtuAnswersCrate2->setValue(sdata.fNumBoardsCrate[2]);
2125 fFtuAnswersCrate3->setValue(sdata.fNumBoardsCrate[3]);
2126
2127 for (int i=0; i<40; i++)
2128 SetFtuLed(i, sdata.IsActive(i) ? sdata.fPing[i] : -1, d.time);
2129
2130 SetFtuStatusLed(d.time);
2131 }
2132
2133 void handleFtmError(const DimData &d)
2134 {
2135 if (!CheckSize(d, sizeof(FTM::DimError)))
2136 return;
2137
2138 const FTM::DimError &sdata = d.ref<FTM::DimError>();
2139
2140 SetFtuLed(sdata.fError.fDestAddress, sdata.fError.fNumCalls, d.time);
2141 SetFtuStatusLed(d.time);
2142
2143 // FIXME: Write to special window!
2144 //Out() << "Error:" << endl;
2145 //Out() << sdata.fError << endl;
2146 }
2147
2148 // ====================== MessageImp ====================================
2149
2150 bool fChatOnline;
2151
2152 void handleStateChanged(const Time &time, const std::string &server,
2153 const State &s)
2154 {
2155 // FIXME: Prefix tooltip with time
2156 if (server=="FTM_CONTROL")
2157 {
2158 // FIXME: Enable FTU page!!!
2159 fStatusFTMLabel->setText(s.name.c_str());
2160 fStatusFTMLabel->setToolTip(s.comment.c_str());
2161
2162 bool enable = false;
2163
2164 if (s.index<FTM::StateMachine::kDisconnected) // No Dim connection
2165 SetLedColor(fStatusFTMLed, kLedGray, time);
2166 if (s.index==FTM::StateMachine::kDisconnected) // Dim connection / FTM disconnected
2167 SetLedColor(fStatusFTMLed, kLedYellow, time);
2168 if (s.index==FTM::StateMachine::kConnected ||
2169 s.index==FTM::StateMachine::kIdle ||
2170 s.index==FTM::StateMachine::kConfiguring1 ||
2171 s.index==FTM::StateMachine::kConfiguring2 ||
2172 s.index==FTM::StateMachine::kConfigured ||
2173 s.index==FTM::StateMachine::kTakingData) // Dim connection / FTM connected
2174 SetLedColor(fStatusFTMLed, kLedGreen, time);
2175
2176 if (s.index==FTM::StateMachine::kConnected ||
2177 s.index==FTM::StateMachine::kIdle) // Dim connection / FTM connected
2178 enable = true;
2179
2180 fTriggerWidget->setEnabled(enable);
2181 fFtuGroupEnable->setEnabled(enable);
2182 fRatesControls->setEnabled(enable);
2183 fFtuWidget->setEnabled(s.index>FTM::StateMachine::kDisconnected);
2184
2185 if (s.index>=FTM::StateMachine::kConnected)
2186 SetFtuStatusLed(time);
2187 else
2188 {
2189 SetLedColor(fStatusFTULed, kLedGray, time);
2190 fStatusFTULabel->setText("Offline");
2191 fStatusFTULabel->setToolTip("FTM is not online.");
2192 }
2193 }
2194
2195 if (server=="FAD_CONTROL")
2196 {
2197 fStatusFADLabel->setText(s.name.c_str());
2198 fStatusFADLabel->setToolTip(s.comment.c_str());
2199
2200 bool enable = false;
2201
2202 if (s.index<FAD::kOffline) // No Dim connection
2203 {
2204 SetLedColor(fStatusFADLed, kLedGray, time);
2205
2206 // Timing problem - sometimes they stay gray :(
2207 //for (int i=0; i<40; i++)
2208 // SetLedColor(fFadLED[i], kLedGray, time);
2209
2210 /*
2211 fStatusEventBuilderLabel->setText("Offline");
2212 fStatusEventBuilderLabel->setToolTip("No connection to fadctrl.");
2213 fEvtBldWidget->setEnabled(false);
2214
2215 SetLedColor(fStatusEventBuilderLed, kLedGray, time);
2216 */
2217 }
2218 if (s.index==FAD::kOffline) // Dim connection / FTM disconnected
2219 SetLedColor(fStatusFADLed, kLedRed, time);
2220 if (s.index==FAD::kDisconnected) // Dim connection / FTM disconnected
2221 SetLedColor(fStatusFADLed, kLedOrange, time);
2222 if (s.index==FAD::kConnecting) // Dim connection / FTM disconnected
2223 {
2224 SetLedColor(fStatusFADLed, kLedYellow, time);
2225 // FIXME FIXME FIXME: The LEDs are not displayed when disabled!
2226 enable = true;
2227 }
2228 if (s.index>=FAD::kConnected) // Dim connection / FTM connected
2229 {
2230 SetLedColor(fStatusFADLed, kLedGreen, time);
2231 enable = true;
2232 }
2233
2234 fFadWidget->setEnabled(enable);
2235 }
2236
2237 if (server=="FSC_CONTROL")
2238 {
2239 fStatusFSCLabel->setText(s.name.c_str());
2240 fStatusFSCLabel->setToolTip(s.comment.c_str());
2241
2242 bool enable = false;
2243
2244 if (s.index<1) // No Dim connection
2245 SetLedColor(fStatusFSCLed, kLedGray, time);
2246 if (s.index==1) // Dim connection / FTM disconnected
2247 SetLedColor(fStatusFSCLed, kLedRed, time);
2248 if (s.index>=2) // Dim connection / FTM disconnected
2249 {
2250 SetLedColor(fStatusFSCLed, kLedGreen, time);
2251 enable = true;
2252 }
2253
2254 //fFscWidget->setEnabled(enable);
2255 }
2256
2257 if (server=="DATA_LOGGER")
2258 {
2259 fStatusLoggerLabel->setText(s.name.c_str());
2260 fStatusLoggerLabel->setToolTip(s.comment.c_str());
2261
2262 bool enable = true;
2263
2264 if (s.index<=30) // Ready/Waiting
2265 SetLedColor(fStatusLoggerLed, kLedYellow, time);
2266 if (s.index<-1) // Offline
2267 {
2268 SetLedColor(fStatusLoggerLed, kLedGray, time);
2269 enable = false;
2270 }
2271 if (s.index>=0x100) // Error
2272 SetLedColor(fStatusLoggerLed, kLedRed, time);
2273 if (s.index==40) // Logging
2274 SetLedColor(fStatusLoggerLed, kLedGreen, time);
2275
2276 fLoggerWidget->setEnabled(enable);
2277 }
2278
2279 if (server=="CHAT")
2280 {
2281 fStatusChatLabel->setText(s.name.c_str());
2282
2283 fChatOnline = s.index==0;
2284
2285 SetLedColor(fStatusChatLed, fChatOnline ? kLedGreen : kLedGray, time);
2286
2287 fChatSend->setEnabled(fChatOnline);
2288 fChatMessage->setEnabled(fChatOnline);
2289 }
2290
2291 if (server=="SCHEDULER")
2292 {
2293 fStatusSchedulerLabel->setText(s.name.c_str());
2294
2295 SetLedColor(fStatusSchedulerLed, s.index>=0 ? kLedGreen : kLedRed, time);
2296 }
2297 }
2298
2299 void on_fTabWidget_currentChanged(int which)
2300 {
2301 if (fTabWidget->tabText(which)=="Chat")
2302 fTabWidget->setTabIcon(which, QIcon());
2303 }
2304
2305 void handleWrite(const Time &time, const string &text, int qos)
2306 {
2307 stringstream out;
2308
2309 if (text.substr(0, 6)=="CHAT: ")
2310 {
2311 if (qos==MessageImp::kDebug)
2312 return;
2313
2314 out << "<font size='-1' color='navy'>[<B>";
2315 out << time.GetAsStr("%H:%M:%S");
2316 out << "</B>]</FONT> " << text.substr(6);
2317 fChatText->append(out.str().c_str());
2318
2319 if (fTabWidget->tabText(fTabWidget->currentIndex())=="Chat")
2320 return;
2321
2322 static int num = 0;
2323 if (num++<2)
2324 return;
2325
2326 for (int i=0; i<fTabWidget->count(); i++)
2327 if (fTabWidget->tabText(i)=="Chat")
2328 {
2329 fTabWidget->setTabIcon(i, QIcon(":/Resources/icons/warning 3.png"));
2330 break;
2331 }
2332
2333 return;
2334 }
2335
2336
2337 out << "<font style='font-family:monospace' color='";
2338
2339 switch (qos)
2340 {
2341 case kMessage: out << "black"; break;
2342 case kInfo: out << "green"; break;
2343 case kWarn: out << "#FF6600"; break;
2344 case kError: out << "maroon"; break;
2345 case kFatal: out << "maroon"; break;
2346 case kDebug: out << "navy"; break;
2347 default: out << "navy"; break;
2348 }
2349 out << "'>";
2350 out << time.GetAsStr("%H:%M:%S.%f").substr(0,12);
2351 out << " - " << text << "</font>";
2352
2353 fLogText->append(out.str().c_str());
2354
2355 if (qos>=kWarn && qos!=kDebug)
2356 fTextEdit->append(out.str().c_str());
2357 }
2358
2359 void IndicateStateChange(const Time &time, const std::string &server)
2360 {
2361 const State s = GetState(server, GetCurrentState(server));
2362
2363 QApplication::postEvent(this,
2364 new FunctionEvent(boost::bind(&FactGui::handleStateChanged, this, time, server, s)));
2365 }
2366
2367 int Write(const Time &time, const string &txt, int qos)
2368 {
2369 QApplication::postEvent(this,
2370 new FunctionEvent(boost::bind(&FactGui::handleWrite, this, time, txt, qos)));
2371
2372 return 0;
2373 }
2374
2375 // ====================== Dim infoHandler================================
2376
2377 void handleDimService(const string &txt)
2378 {
2379 fDimSvcText->append(txt.c_str());
2380 }
2381
2382 void infoHandlerService(DimInfo &info)
2383 {
2384 const string fmt = string(info.getFormat()).empty() ? "C" : info.getFormat();
2385
2386 stringstream dummy;
2387 const Converter conv(dummy, fmt, false);
2388
2389 const Time tm(info.getTimestamp(), info.getTimestampMillisecs()*1000);
2390
2391 stringstream out;
2392 out << "<font size'-1' color='navy'>[";
2393 out << tm.GetAsStr("%H:%M:%S.%f").substr(0,12);
2394 out << "]</font> <B>" << info.getName() << "</B> - ";
2395
2396 bool iserr = true;
2397 if (!conv)
2398 {
2399 out << "Compilation of format string '" << fmt << "' failed!";
2400 }
2401 else
2402 {
2403 try
2404 {
2405 const string dat = conv.GetString(info.getData(), info.getSize());
2406 out << dat;
2407 iserr = false;
2408 }
2409 catch (const runtime_error &e)
2410 {
2411 out << "Conversion to string failed!<pre>" << e.what() << "</pre>";
2412 }
2413 }
2414
2415 // srand(hash<string>()(string(info.getName())));
2416 // int bg = rand()&0xffffff;
2417
2418 int bg = hash<string>()(string(info.getName()));
2419
2420 // allow only light colors
2421 bg = ~(bg&0x1f1f1f)&0xffffff;
2422
2423 if (iserr)
2424 bg = 0xffffff;
2425
2426 stringstream bgcol;
2427 bgcol << hex << setfill('0') << setw(6) << bg;
2428
2429 const string col = iserr ? "red" : "black";
2430 const string str = "<table width='100%' bgcolor=#"+bgcol.str()+"><tr><td><font color='"+col+"'>"+out.str()+"</font></td></tr></table>";
2431
2432 QApplication::postEvent(this,
2433 new FunctionEvent(boost::bind(&FactGui::handleDimService, this, str)));
2434 }
2435
2436 void CallInfoHandler(void (FactGui::*handler)(const DimData&), const DimData &d)
2437 {
2438 fInHandler = true;
2439 (this->*handler)(d);
2440 fInHandler = false;
2441 }
2442
2443 /*
2444 void CallInfoHandler(const boost::function<void()> &func)
2445 {
2446 // This ensures that newly received values are not sent back to the emitter
2447 // because changing the value emits the valueChanged signal (or similar)
2448 fInHandler = true;
2449 func();
2450 fInHandler = false;
2451 }*/
2452
2453 void PostInfoHandler(void (FactGui::*handler)(const DimData&))
2454 {
2455 //const boost::function<void()> f = boost::bind(handler, this, DimData(getInfo()));
2456
2457 FunctionEvent *evt = new FunctionEvent(boost::bind(&FactGui::CallInfoHandler, this, handler, DimData(getInfo())));
2458 // FunctionEvent *evt = new FunctionEvent(boost::bind(&FactGui::CallInfoHandler, this, f));
2459 // FunctionEvent *evt = new FunctionEvent(boost::bind(handler, this, DimData(getInfo()))));
2460
2461 QApplication::postEvent(this, evt);
2462 }
2463
2464 void infoHandler()
2465 {
2466 // Initialize the time-stamp (what a weird workaround...)
2467 if (getInfo())
2468 getInfo()->getTimestamp();
2469
2470 if (getInfo()==&fDimDNS)
2471 return PostInfoHandler(&FactGui::handleDimDNS);
2472#ifdef DEBUG_DIM
2473 cout << "HandleDimInfo " << getInfo()->getName() << endl;
2474#endif
2475 if (getInfo()==&fDimLoggerStats)
2476 return PostInfoHandler(&FactGui::handleLoggerStats);
2477
2478// if (getInfo()==&fDimFadFiles)
2479// return PostInfoHandler(&FactGui::handleFadFiles);
2480
2481 if (getInfo()==&fDimFadWriteStats)
2482 return PostInfoHandler(&FactGui::handleFadWriteStats);
2483
2484 if (getInfo()==&fDimFadConnections)
2485 return PostInfoHandler(&FactGui::handleFadConnections);
2486
2487 if (getInfo()==&fDimFadFwVersion)
2488 return PostInfoHandler(&FactGui::handleFadFwVersion);
2489
2490 if (getInfo()==&fDimFadRunNumber)
2491 return PostInfoHandler(&FactGui::handleFadRunNumber);
2492
2493 if (getInfo()==&fDimFadDNA)
2494 return PostInfoHandler(&FactGui::handleFadDNA);
2495
2496 if (getInfo()==&fDimFadTemperature)
2497 return PostInfoHandler(&FactGui::handleFadTemperature);
2498
2499 if (getInfo()==&fDimFadRefClock)
2500 return PostInfoHandler(&FactGui::handleFadRefClock);
2501
2502 if (getInfo()==&fDimFadRoi)
2503 return PostInfoHandler(&FactGui::handleFadRoi);
2504
2505 if (getInfo()==&fDimFadDac)
2506 return PostInfoHandler(&FactGui::handleFadDac);
2507
2508 if (getInfo()==&fDimFadDrsCalibration)
2509 return PostInfoHandler(&FactGui::handleFadDrsCalibration);
2510
2511 if (getInfo()==&fDimFadPrescaler)
2512 return PostInfoHandler(&FactGui::handleFadPrescaler);
2513
2514 if (getInfo()==&fDimFadStatus)
2515 return PostInfoHandler(&FactGui::handleFadStatus);
2516
2517 if (getInfo()==&fDimFadStatistics1)
2518 return PostInfoHandler(&FactGui::handleFadStatistics1);
2519
2520 if (getInfo()==&fDimFadStatistics2)
2521 return PostInfoHandler(&FactGui::handleFadStatistics2);
2522
2523 if (getInfo()==&fDimFadEvents)
2524 return PostInfoHandler(&FactGui::handleFadEvents);
2525
2526 if (getInfo()==&fDimFadRuns)
2527 return PostInfoHandler(&FactGui::handleFadRuns);
2528
2529 if (getInfo()==&fDimFadEventData)
2530 return PostInfoHandler(&FactGui::handleFadEventData);
2531
2532/*
2533 if (getInfo()==&fDimFadSetup)
2534 return PostInfoHandler(&FactGui::handleFadSetup);
2535*/
2536 if (getInfo()==&fDimLoggerFilenameNight)
2537 return PostInfoHandler(&FactGui::handleLoggerFilenameNight);
2538
2539 if (getInfo()==&fDimLoggerNumSubs)
2540 return PostInfoHandler(&FactGui::handleLoggerNumSubs);
2541
2542 if (getInfo()==&fDimLoggerFilenameRun)
2543 return PostInfoHandler(&FactGui::handleLoggerFilenameRun);
2544
2545 if (getInfo()==&fDimFtmTriggerCounter)
2546 return PostInfoHandler(&FactGui::handleFtmTriggerCounter);
2547
2548 if (getInfo()==&fDimFtmCounter)
2549 return PostInfoHandler(&FactGui::handleFtmCounter);
2550
2551 if (getInfo()==&fDimFtmDynamicData)
2552 return PostInfoHandler(&FactGui::handleFtmDynamicData);
2553
2554 if (getInfo()==&fDimFtmPassport)
2555 return PostInfoHandler(&FactGui::handleFtmPassport);
2556
2557 if (getInfo()==&fDimFtmFtuList)
2558 return PostInfoHandler(&FactGui::handleFtmFtuList);
2559
2560 if (getInfo()==&fDimFtmStaticData)
2561 return PostInfoHandler(&FactGui::handleFtmStaticData);
2562
2563 if (getInfo()==&fDimFtmError)
2564 return PostInfoHandler(&FactGui::handleFtmError);
2565
2566// if (getInfo()==&fDimFadFiles)
2567// return PostInfoHandler(&FactGui::handleFadFiles);
2568
2569 for (map<string,DimInfo*>::iterator i=fServices.begin(); i!=fServices.end(); i++)
2570 if (i->second==getInfo())
2571 {
2572 infoHandlerService(*i->second);
2573 return;
2574 }
2575
2576 DimNetwork::infoHandler();
2577 }
2578
2579
2580 // ======================================================================
2581
2582 bool event(QEvent *evt)
2583 {
2584 if (dynamic_cast<FunctionEvent*>(evt))
2585 return static_cast<FunctionEvent*>(evt)->Exec();
2586
2587 if (dynamic_cast<CheckBoxEvent*>(evt))
2588 {
2589 const QStandardItem &item = static_cast<CheckBoxEvent*>(evt)->item;
2590 const QStandardItem *par = item.parent();
2591 if (par)
2592 {
2593 const QString server = par->text();
2594 const QString service = item.text();
2595
2596 const string s = (server+'/'+service).toStdString();
2597
2598 if (item.checkState()==Qt::Checked)
2599 SubscribeService(s);
2600 else
2601 UnsubscribeService(s);
2602 }
2603 }
2604
2605 return MainWindow::event(evt); // unrecognized
2606 }
2607
2608 void on_fDimCmdSend_clicked()
2609 {
2610 const QString server = fDimCmdServers->currentIndex().data().toString();
2611 const QString command = fDimCmdCommands->currentIndex().data().toString();
2612 const QString arguments = fDimCmdLineEdit->displayText();
2613
2614 // FIXME: Sending a command exactly when the info Handler changes
2615 // the list it might lead to confusion.
2616 try
2617 {
2618 SendDimCommand(server.toStdString(), command.toStdString()+" "+arguments.toStdString());
2619 fTextEdit->append("<font color='green'>Command '"+server+'/'+command+"' successfully emitted.</font>");
2620 fDimCmdLineEdit->clear();
2621 }
2622 catch (const runtime_error &e)
2623 {
2624 stringstream txt;
2625 txt << e.what();
2626
2627 string buffer;
2628 while (getline(txt, buffer, '\n'))
2629 fTextEdit->append(("<font color='red'><pre>"+buffer+"</pre></font>").c_str());
2630 }
2631 }
2632
2633#ifdef HAVE_ROOT
2634 void slot_RootEventProcessed(TObject *obj, unsigned int evt, TCanvas *canv)
2635 {
2636 // kMousePressEvent // TCanvas processed QEvent mousePressEvent
2637 // kMouseMoveEvent // TCanvas processed QEvent mouseMoveEvent
2638 // kMouseReleaseEvent // TCanvas processed QEvent mouseReleaseEvent
2639 // kMouseDoubleClickEvent // TCanvas processed QEvent mouseDoubleClickEvent
2640 // kKeyPressEvent // TCanvas processed QEvent keyPressEvent
2641 // kEnterEvent // TCanvas processed QEvent enterEvent
2642 // kLeaveEvent // TCanvas processed QEvent leaveEvent
2643 if (dynamic_cast<TCanvas*>(obj))
2644 return;
2645
2646 TQtWidget *tipped = static_cast<TQtWidget*>(sender());
2647
2648 if (evt==11/*kMouseReleaseEvent*/)
2649 {
2650 if (dynamic_cast<Camera*>(obj))
2651 {
2652 const float xx = canv->AbsPixeltoX(tipped->GetEventX());
2653 const float yy = canv->AbsPixeltoY(tipped->GetEventY());
2654
2655 Camera *cam = static_cast<Camera*>(obj);
2656 const int isw = cam->GetIdx(xx, yy);
2657
2658 fPixelIdx->setValue(isw);
2659 ChoosePixel(*cam, isw);
2660 }
2661 return;
2662 }
2663
2664 if (evt==61/*kMouseDoubleClickEvent*/)
2665 {
2666 if (dynamic_cast<Camera*>(obj) && fRatesControls->isEnabled())
2667 {
2668 const float xx = canv->AbsPixeltoX(tipped->GetEventX());
2669 const float yy = canv->AbsPixeltoY(tipped->GetEventY());
2670
2671 Camera *cam = static_cast<Camera*>(obj);
2672 const int isw = cam->GetIdx(xx, yy);
2673
2674 ChoosePixel(*cam, isw);
2675
2676 fPixelIdx->setValue(isw);
2677
2678 const uint16_t ihw = fPixelMapHW[isw];
2679
2680 Dim::SendCommand("FTM_CONTROL/TOGGLE_PIXEL", ihw);
2681 }
2682
2683 if (dynamic_cast<TAxis*>(obj))
2684 static_cast<TAxis*>(obj)->UnZoom();
2685
2686 return;
2687 }
2688
2689 // Find the object which will get picked by the GetObjectInfo
2690 // due to buffer overflows in many root-versions
2691 // in TH1 and TProfile we have to work around and implement
2692 // our own GetObjectInfo which make everything a bit more
2693 // complicated.
2694 canv->cd();
2695#if ROOT_VERSION_CODE > ROOT_VERSION(5,22,00)
2696 const char *objectInfo =
2697 obj->GetObjectInfo(tipped->GetEventX(),tipped->GetEventY());
2698#else
2699 const char *objectInfo = dynamic_cast<TH1*>(obj) ?
2700 "" : obj->GetObjectInfo(tipped->GetEventX(),tipped->GetEventY());
2701#endif
2702
2703 QString tipText;
2704 tipText += obj->GetName();
2705 tipText += " [";
2706 tipText += obj->ClassName();
2707 tipText += "]: ";
2708 tipText += objectInfo;
2709
2710 if (dynamic_cast<Camera*>(obj))
2711 {
2712 const float xx = canv->AbsPixeltoX(tipped->GetEventX());
2713 const float yy = canv->AbsPixeltoY(tipped->GetEventY());
2714
2715 Camera *cam = static_cast<Camera*>(obj);
2716
2717 const int isw = cam->GetIdx(xx, yy);
2718 const int ihw = fPixelMapHW[isw];
2719
2720 const int idx = fPatchHW[isw];
2721
2722 int ii = 0;
2723 for (; ii<160; ii++)
2724 if (idx==fPatchMapHW[ii])
2725 break;
2726
2727
2728 const int patch = ihw%4;
2729 const int board = (ihw/4)%10;
2730 const int crate = (ihw/4)/10;
2731
2732 ostringstream str;
2733 str << " (hw=" << ihw << ") Patch=" << ii << " (hw=" << fPatchMapHW[idx] << "; Crate=" << crate << " Board=" << board << " Patch=" << patch << ")";
2734
2735 tipText += str.str().c_str();
2736 }
2737
2738
2739 fStatusBar->showMessage(tipText, 3000);
2740
2741 gSystem->ProcessEvents();
2742 //QWhatsThis::display(tipText)
2743 }
2744
2745 void slot_RootUpdate()
2746 {
2747 gSystem->ProcessEvents();
2748 QTimer::singleShot(0, this, SLOT(slot_RootUpdate()));
2749 }
2750
2751 void ChoosePatch(Camera &cam, int isw)
2752 {
2753 cam.Reset();
2754
2755 fThresholdIdx->setValue(isw);
2756
2757 const int ihw = isw<0 ? 0 : fPatchMapHW[isw];
2758
2759 fPatchRate->setEnabled(isw>=0);
2760 fThresholdCrate->setEnabled(isw>=0);
2761 fThresholdBoard->setEnabled(isw>=0);
2762 fThresholdPatch->setEnabled(isw>=0);
2763
2764 if (isw<0)
2765 return;
2766
2767 const int patch = ihw%4;
2768 const int board = (ihw/4)%10;
2769 const int crate = (ihw/4)/10;
2770
2771 fInChoosePatch = true;
2772
2773 fThresholdCrate->setValue(crate);
2774 fThresholdBoard->setValue(board);
2775 fThresholdPatch->setValue(patch);
2776
2777 fInChoosePatch = false;
2778
2779 fThresholdVal->setValue(fFtmStaticData.fThreshold[ihw]);
2780 fPatchRate->setValue(cam.GetData(isw));
2781
2782 // Loop over the software idx of all pixels
2783 for (unsigned int i=0; i<1440; i++)
2784 if (fPatchHW[i]==ihw)
2785 cam.SetBold(i);
2786 }
2787
2788 void ChoosePixel(Camera &cam, int isw)
2789 {
2790 const int ihw = fPixelMapHW[isw];
2791
2792 int ii = 0;
2793 for (; ii<160; ii++)
2794 if (fPatchHW[isw]==fPatchMapHW[ii])
2795 break;
2796
2797 cam.SetWhite(isw);
2798 ChoosePatch(cam, ii);
2799
2800 const bool on = fFtmStaticData.IsEnabled(ihw);
2801 fPixelEnable->setChecked(on);
2802 }
2803
2804 void UpdatePatch(int isw)
2805 {
2806 Camera *cam = (Camera*)fRatesCanv->GetCanvas()->FindObject("Camera");
2807 ChoosePatch(*cam, isw);
2808 }
2809
2810 void on_fThresholdIdx_valueChanged(int isw)
2811 {
2812 UpdatePatch(isw);
2813
2814 fRatesCanv->GetCanvas()->Modified();
2815 fRatesCanv->GetCanvas()->Update();
2816 }
2817
2818 void UpdateThresholdIdx()
2819 {
2820 if (fInChoosePatch)
2821 return;
2822
2823 const int crate = fThresholdCrate->value();
2824 const int board = fThresholdBoard->value();
2825 const int patch = fThresholdPatch->value();
2826
2827 const int ihw = patch + board*4 + crate*40;
2828
2829 int isw = 0;
2830 for (; isw<160; isw++)
2831 if (ihw==fPatchMapHW[isw])
2832 break;
2833
2834 UpdatePatch(isw);
2835 }
2836
2837 void on_fThresholdPatch_valueChanged(int)
2838 {
2839 UpdateThresholdIdx();
2840 }
2841 void on_fThresholdBoard_valueChanged(int)
2842 {
2843 UpdateThresholdIdx();
2844 }
2845 void on_fThresholdCrate_valueChanged(int)
2846 {
2847 UpdateThresholdIdx();
2848 }
2849
2850 void on_fPixelIdx_valueChanged(int isw)
2851 {
2852 Camera *cam = (Camera*)fRatesCanv->GetCanvas()->FindObject("Camera");
2853 ChoosePixel(*cam, isw);
2854
2855 fRatesCanv->GetCanvas()->Modified();
2856 fRatesCanv->GetCanvas()->Update();
2857 }
2858
2859 void on_fRatesMin_valueChanged(int min)
2860 {
2861 Camera *cam = (Camera*)fRatesCanv->GetCanvas()->FindObject("Camera");
2862 cam->SetMin(min);
2863
2864 fRatesCanv->GetCanvas()->Modified();
2865 fRatesCanv->GetCanvas()->Update();
2866 }
2867
2868 void on_fRatesMax_valueChanged(int max)
2869 {
2870 Camera *cam = (Camera*)fRatesCanv->GetCanvas()->FindObject("Camera");
2871 cam->SetMax(max);
2872
2873 fRatesCanv->GetCanvas()->Modified();
2874 fRatesCanv->GetCanvas()->Update();
2875 }
2876
2877#endif
2878
2879 void on_fPixelEnable_stateChanged(int b)
2880 {
2881 if (fInHandler)
2882 return;
2883
2884 const uint16_t isw = fPixelIdx->value();
2885 const uint16_t ihw = fPixelMapHW[isw];
2886
2887 Dim::SendCommand(b==Qt::Unchecked ?
2888 "FTM_CONTROL/DISABLE_PIXEL" : "FTM_CONTROL/ENABLE_PIXEL",
2889 ihw);
2890 }
2891
2892 void on_fPixelDisableOthers_clicked()
2893 {
2894 const uint16_t isw = fPixelIdx->value();
2895 const uint16_t ihw = fPixelMapHW[isw];
2896
2897 Dim::SendCommand("FTM_CONTROL/DISABLE_ALL_PIXELS_EXCEPT", ihw);
2898 }
2899
2900 void on_fThresholdDisableOthers_clicked()
2901 {
2902 const int16_t isw = fThresholdIdx->value();
2903 const int16_t ihw = isw<0 ? -1 : fPatchMapHW[isw];
2904
2905 Dim::SendCommand("FTM_CONTROL/DISABLE_ALL_PATCHES_EXCEPT", ihw);
2906 }
2907
2908 void on_fThresholdVal_valueChanged(int v)
2909 {
2910 fThresholdVolt->setValue(2500./4095*v);
2911
2912 const int32_t isw = fThresholdIdx->value();
2913 const int32_t ihw = isw<0 ? -1 : fPatchMapHW[isw];
2914
2915 const int32_t d[2] = { ihw, v };
2916
2917 if (!fInHandler)
2918 Dim::SendCommand("FTM_CONTROL/SET_THRESHOLD", d);
2919 }
2920
2921 TGraph fGraphFtmTemp[4];
2922 TGraph fGraphFtmRate;
2923 TGraph fGraphPatchRate[160];
2924 TGraph fGraphBoardRate[40];
2925
2926#ifdef HAVE_ROOT
2927 TH1 *DrawTimeFrame(const char *ytitle)
2928 {
2929 const double tm = Time().RootTime();
2930
2931 TH1F *h=new TH1F("TimeFrame", "", 1, tm, tm+60);//Time().RootTime()-1./24/60/60, Time().RootTime());
2932 h->SetDirectory(0);
2933 h->SetBit(kCanDelete);
2934 h->SetStats(kFALSE);
2935// h.SetMinimum(0);
2936// h.SetMaximum(1);
2937 h->SetXTitle("Time");
2938 h->SetYTitle(ytitle);
2939 h->GetXaxis()->CenterTitle();
2940 h->GetYaxis()->CenterTitle();
2941 h->GetXaxis()->SetTimeDisplay(true);
2942 h->GetXaxis()->SetTimeFormat("%Mh%S'");
2943 h->GetXaxis()->SetLabelSize(0.025);
2944 h->GetYaxis()->SetLabelSize(0.025);
2945 h->GetYaxis()->SetTitleOffset(1.2);
2946 // h.GetYaxis()->SetTitleSize(1.2);
2947 h->Draw();
2948
2949 return h;
2950 }
2951#endif
2952
2953public:
2954 FactGui() :
2955 fFtuStatus(40),
2956 fPixelMapHW(1440), fPatchMapHW(160), fPatchHW(1440),
2957 fInChoosePatch(false),
2958 fDimDNS("DIS_DNS/VERSION_NUMBER", 1, int(0), this),
2959 //-
2960 fDimLoggerStats ("DATA_LOGGER/STATS", (void*)NULL, 0, this),
2961 fDimLoggerFilenameNight("DATA_LOGGER/FILENAME_NIGHTLY", (void*)NULL, 0, this),
2962 fDimLoggerFilenameRun ("DATA_LOGGER/FILENAME_RUN", (void*)NULL, 0, this),
2963 fDimLoggerNumSubs ("DATA_LOGGER/NUM_SUBS", (void*)NULL, 0, this),
2964 //-
2965 fDimFtmPassport ("FTM_CONTROL/PASSPORT", (void*)NULL, 0, this),
2966 fDimFtmTriggerCounter ("FTM_CONTROL/TRIGGER_COUNTER", (void*)NULL, 0, this),
2967 fDimFtmError ("FTM_CONTROL/ERROR", (void*)NULL, 0, this),
2968 fDimFtmFtuList ("FTM_CONTROL/FTU_LIST", (void*)NULL, 0, this),
2969 fDimFtmStaticData ("FTM_CONTROL/STATIC_DATA", (void*)NULL, 0, this),
2970 fDimFtmDynamicData ("FTM_CONTROL/DYNAMIC_DATA", (void*)NULL, 0, this),
2971 fDimFtmCounter ("FTM_CONTROL/COUNTER", (void*)NULL, 0, this),
2972 //-
2973 fDimFadWriteStats ("FAD_CONTROL/STATS", (void*)NULL, 0, this),
2974 fDimFadRuns ("FAD_CONTROL/RUNS", (void*)NULL, 0, this),
2975 fDimFadEvents ("FAD_CONTROL/EVENTS", (void*)NULL, 0, this),
2976 fDimFadEventData ("FAD_CONTROL/EVENT_DATA", (void*)NULL, 0, this),
2977 fDimFadConnections ("FAD_CONTROL/CONNECTIONS", (void*)NULL, 0, this),
2978 fDimFadFwVersion ("FAD_CONTROL/FIRMWARE_VERSION", (void*)NULL, 0, this),
2979 fDimFadRunNumber ("FAD_CONTROL/RUN_NUMBER", (void*)NULL, 0, this),
2980 fDimFadDNA ("FAD_CONTROL/DNA", (void*)NULL, 0, this),
2981 fDimFadTemperature ("FAD_CONTROL/TEMPERATURE", (void*)NULL, 0, this),
2982 fDimFadPrescaler ("FAD_CONTROL/PRESCALER", (void*)NULL, 0, this),
2983 fDimFadRefClock ("FAD_CONTROL/REFERENCE_CLOCK", (void*)NULL, 0, this),
2984 fDimFadRoi ("FAD_CONTROL/REGION_OF_INTEREST", (void*)NULL, 0, this),
2985 fDimFadDac ("FAD_CONTROL/DAC", (void*)NULL, 0, this),
2986 fDimFadDrsCalibration ("FAD_CONTROL/DRS_CALIBRATION", (void*)NULL, 0, this),
2987 fDimFadStatus ("FAD_CONTROL/STATUS", (void*)NULL, 0, this),
2988 fDimFadStatistics1 ("FAD_CONTROL/STATISTICS1", (void*)NULL, 0, this),
2989 fDimFadStatistics2 ("FAD_CONTROL/STATISTICS2", (void*)NULL, 0, this),
2990 //-
2991 fEventData(0), fDrsCalibration(1440*1024*6),
2992 fTimeStamp1(0),
2993 fTriggerCounter0(0),
2994 fTimeStamp0(0)
2995
2996 {
2997 fClockCondFreq->addItem("--- Hz", QVariant(-1));
2998 fClockCondFreq->addItem("800 MHz", QVariant(800));
2999 fClockCondFreq->addItem("1 GHz", QVariant(1000));
3000 fClockCondFreq->addItem("2 GHz", QVariant(2000));
3001 fClockCondFreq->addItem("3 GHz", QVariant(3000));
3002 fClockCondFreq->addItem("4 GHz", QVariant(4000));
3003 fClockCondFreq->addItem("5 GHz", QVariant(5000));
3004
3005 fMcpNumEvents->addItem("unlimited", QVariant(0));
3006 fMcpNumEvents->addItem("100", QVariant(100));
3007 fMcpNumEvents->addItem("300", QVariant(300));
3008 fMcpNumEvents->addItem("1000", QVariant(1000));
3009 fMcpNumEvents->addItem("3000", QVariant(3000));
3010 fMcpNumEvents->addItem("10000", QVariant(10000));
3011 fMcpNumEvents->addItem("30000", QVariant(30000));
3012
3013 fMcpTime->addItem("unlimited", QVariant(0));
3014 fMcpTime->addItem("00:30", QVariant(30));
3015 fMcpTime->addItem("01:00", QVariant(60));
3016 fMcpTime->addItem("02:30", QVariant(150));
3017 fMcpTime->addItem("05:00", QVariant(300));
3018 fMcpTime->addItem("10:00", QVariant(600));
3019 fMcpTime->addItem("15:00", QVariant(900));
3020 fMcpTime->addItem("20:00", QVariant(1200));
3021 fMcpTime->addItem("30:00", QVariant(1800));
3022 fMcpTime->addItem("60:00", QVariant(3600));
3023
3024 fMcpRunType->addItem("Data", QVariant("data"));
3025 fMcpRunType->addItem("Pedestal", QVariant("pedestal"));
3026 fMcpRunType->addItem("DRS Calib", QVariant("drs-calib"));
3027
3028 fTriggerWidget->setEnabled(false);
3029 fFtuWidget->setEnabled(false);
3030 fFtuGroupEnable->setEnabled(false);
3031 fRatesControls->setEnabled(false);
3032 fFadWidget->setEnabled(false);
3033 fEvtBldWidget->setEnabled(false);
3034 fLoggerWidget->setEnabled(false);
3035
3036 fChatSend->setEnabled(false);
3037 fChatMessage->setEnabled(false);
3038
3039 DimClient::sendCommand("CHAT/MSG", "GUI online.");
3040 // + MessageDimRX
3041
3042 // --------------------------------------------------------------------------
3043
3044 ifstream fin1("Trigger-Patches.txt");
3045
3046 int l = 0;
3047
3048 string buf;
3049 while (getline(fin1, buf, '\n'))
3050 {
3051 buf = Tools::Trim(buf);
3052 if (buf[0]=='#')
3053 continue;
3054
3055 stringstream str(buf);
3056 for (int i=0; i<9; i++)
3057 {
3058 unsigned int n;
3059 str >> n;
3060
3061 if (n>=fPatchHW.size())
3062 continue;
3063
3064 fPatchHW[n] = l;
3065 }
3066 l++;
3067 }
3068
3069 if (l!=160)
3070 cerr << "WARNING - Problems reading Trigger-Patches.txt" << endl;
3071
3072 // --------------------------------------------------------------------------
3073
3074 ifstream fin2("MasterList-v3.txt");
3075
3076 l = 0;
3077
3078 while (getline(fin2, buf, '\n'))
3079 {
3080 buf = Tools::Trim(buf);
3081 if (buf[0]=='#')
3082 continue;
3083
3084 unsigned int softid, hardid, dummy;
3085
3086 stringstream str(buf);
3087
3088 str >> softid;
3089 str >> dummy;
3090 str >> hardid;
3091
3092 if (softid>=fPixelMapHW.size())
3093 continue;
3094
3095 fPixelMapHW[softid] = hardid;
3096
3097 l++;
3098 }
3099
3100 if (l!=1440)
3101 cerr << "WARNING - Problems reading MasterList-v3.txt" << endl;
3102
3103 // --------------------------------------------------------------------------
3104
3105 ifstream fin3("PatchList.txt");
3106
3107 l = 0;
3108
3109 while (getline(fin3, buf, '\n'))
3110 {
3111 buf = Tools::Trim(buf);
3112 if (buf[0]=='#')
3113 continue;
3114
3115 unsigned int softid, hardid;
3116
3117 stringstream str(buf);
3118
3119 str >> softid;
3120 str >> hardid;
3121
3122 if (softid>=fPatchMapHW.size())
3123 continue;
3124
3125 fPatchMapHW[softid] = hardid-1;
3126
3127 l++;
3128 }
3129
3130 if (l!=160)
3131 cerr << "WARNING - Problems reading PatchList.txt" << endl;
3132
3133 // --------------------------------------------------------------------------
3134#ifdef HAVE_ROOT
3135
3136 fGraphFtmRate.SetLineColor(kBlue);
3137 fGraphFtmRate.SetMarkerColor(kBlue);
3138 fGraphFtmRate.SetMarkerStyle(kFullDotMedium);
3139
3140 for (int i=0; i<160; i++)
3141 {
3142 fGraphPatchRate[i].SetName("PatchRate");
3143 //fGraphPatchRate[i].SetLineColor(kBlue);
3144 //fGraphPatchRate[i].SetMarkerColor(kBlue);
3145 fGraphPatchRate[i].SetMarkerStyle(kFullDotMedium);
3146 }
3147 for (int i=0; i<40; i++)
3148 {
3149 fGraphBoardRate[i].SetName("BoardRate");
3150 //fGraphBoardRate[i].SetLineColor(kBlue);
3151 //fGraphBoardRate[i].SetMarkerColor(kBlue);
3152 fGraphBoardRate[i].SetMarkerStyle(kFullDotMedium);
3153 }
3154 /*
3155 TCanvas *c = fFtmTempCanv->GetCanvas();
3156 c->SetBit(TCanvas::kNoContextMenu);
3157 c->SetBorderMode(0);
3158 c->SetFrameBorderMode(0);
3159 c->SetFillColor(kWhite);
3160 c->SetRightMargin(0.03);
3161 c->SetTopMargin(0.03);
3162 c->cd();
3163 */
3164 //CreateTimeFrame("Temperature / °C");
3165
3166 fGraphFtmTemp[0].SetMarkerStyle(kFullDotSmall);
3167 fGraphFtmTemp[1].SetMarkerStyle(kFullDotSmall);
3168 fGraphFtmTemp[2].SetMarkerStyle(kFullDotSmall);
3169 fGraphFtmTemp[3].SetMarkerStyle(kFullDotSmall);
3170
3171 fGraphFtmTemp[1].SetLineColor(kBlue);
3172 fGraphFtmTemp[2].SetLineColor(kRed);
3173 fGraphFtmTemp[3].SetLineColor(kGreen);
3174
3175 fGraphFtmTemp[1].SetMarkerColor(kBlue);
3176 fGraphFtmTemp[2].SetMarkerColor(kRed);
3177 fGraphFtmTemp[3].SetMarkerColor(kGreen);
3178
3179 //fGraphFtmTemp[0].Draw("LP");
3180 //fGraphFtmTemp[1].Draw("LP");
3181 //fGraphFtmTemp[2].Draw("LP");
3182 //fGraphFtmTemp[3].Draw("LP");
3183
3184 // --------------------------------------------------------------------------
3185
3186 TCanvas *c = fFtmRateCanv->GetCanvas();
3187 //c->SetBit(TCanvas::kNoContextMenu);
3188 c->SetBorderMode(0);
3189 c->SetFrameBorderMode(0);
3190 c->SetFillColor(kWhite);
3191 c->SetRightMargin(0.03);
3192 c->SetTopMargin(0.03);
3193 c->SetGrid();
3194 c->cd();
3195
3196 TH1 *hf = DrawTimeFrame("Trigger rate [Hz]");
3197 hf->GetYaxis()->SetRangeUser(0, 1010);
3198
3199 fTriggerCounter0 = -1;
3200
3201 fGraphFtmRate.SetMarkerStyle(kFullDotSmall);
3202 fGraphFtmRate.Draw("LP");
3203
3204 // --------------------------------------------------------------------------
3205
3206 c = fRatesCanv->GetCanvas();
3207 //c->SetBit(TCanvas::kNoContextMenu);
3208 c->SetBorderMode(0);
3209 c->SetFrameBorderMode(0);
3210 c->SetFillColor(kWhite);
3211 c->cd();
3212
3213 Camera *cam = new Camera;
3214 cam->SetBit(kCanDelete);
3215 cam->SetMin(fRatesMin->value());
3216 cam->SetMax(fRatesMax->value());
3217 cam->Draw();
3218
3219 ChoosePixel(*cam, 0);
3220
3221 // --------------------------------------------------------------------------
3222
3223 c = fAdcDataCanv->GetCanvas();
3224 //c->SetBit(TCanvas::kNoContextMenu);
3225 c->SetBorderMode(0);
3226 c->SetFrameBorderMode(0);
3227 c->SetFillColor(kWhite);
3228 c->SetGrid();
3229 c->cd();
3230
3231 // Create histogram?
3232
3233 // --------------------------------------------------------------------------
3234
3235// QTimer::singleShot(0, this, SLOT(slot_RootUpdate()));
3236
3237 //widget->setMouseTracking(true);
3238 //widget->EnableSignalEvents(kMouseMoveEvent);
3239
3240 fFtmRateCanv->setMouseTracking(true);
3241 fFtmRateCanv->EnableSignalEvents(kMouseMoveEvent);
3242
3243 fAdcDataCanv->setMouseTracking(true);
3244 fAdcDataCanv->EnableSignalEvents(kMouseMoveEvent);
3245
3246 fRatesCanv->setMouseTracking(true);
3247 fRatesCanv->EnableSignalEvents(kMouseMoveEvent|kMouseReleaseEvent|kMouseDoubleClickEvent);
3248
3249 connect(fRatesCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)),
3250 this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*)));
3251 connect(fFtmRateCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)),
3252 this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*)));
3253 connect(fAdcDataCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)),
3254 this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*)));
3255#endif
3256 }
3257
3258 ~FactGui()
3259 {
3260 // Unsubscribe all services
3261 for (map<string,DimInfo*>::iterator i=fServices.begin();
3262 i!=fServices.end(); i++)
3263 delete i->second;
3264
3265 delete fEventData;
3266 }
3267};
3268
3269#endif
Note: See TracBrowser for help on using the repository browser.