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

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