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

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