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

Last change on this file since 11967 was 11967, checked in by tbretz, 14 years ago
Added BIAS states, added kLedInProgress, moved PixelMap to new file
File size: 119.8 KB
Line 
1#ifndef FACT_FactGui
2#define FACT_FactGui
3
4#include "MainWindow.h"
5
6#include <iomanip>
7#include <valarray>
8
9#include <boost/bind.hpp>
10
11#include <QTimer>
12#include <QStandardItemModel>
13
14#include "CheckBoxDelegate.h"
15
16#include "src/Dim.h"
17#include "src/Converter.h"
18#include "src/Configuration.h"
19#include "src/HeadersFTM.h"
20#include "src/HeadersFAD.h"
21#include "src/HeadersBIAS.h"
22#include "src/DimNetwork.h"
23#include "src/tools.h"
24#include "src/FAD.h"
25#include "src/PixelMap.h"
26
27
28#include "TROOT.h"
29#include "TSystem.h"
30#include "TGraph.h"
31#include "TH2.h"
32#include "TBox.h"
33#include "TStyle.h"
34#include "TMarker.h"
35#include "TColor.h"
36
37#include "QCameraWidget.h"
38
39using namespace std;
40
41// #########################################################################
42
43/*
44class Camera : public TObject
45{
46 typedef pair<double,double> Position;
47 typedef vector<Position> Positions;
48
49 Positions fGeom;
50
51 void CreatePalette()
52 {
53
54 double ss[5] = {0.00, 0.25, 0.50, 0.75, 1.00};
55 double rr[5] = {0.15, 0.00, 0.00, 1.00, 0.85};
56 double gg[5] = {0.15, 0.00, 1.00, 0.00, 0.85};
57 double bb[5] = {0.15, 1.00, 0.00, 0.00, 0.85};
58
59 const Int_t nn = 1440;
60
61 Int_t idx = TColor::CreateGradientColorTable(5, ss, rr, gg, bb, nn);
62 for (int i=0; i<nn; i++)
63 fPalette.push_back(idx++);
64 }
65
66 void CreateGeometry()
67 {
68 const double gsSin60 = sqrt(3.)/2;
69
70 const int rings = 23;
71
72 // add the first pixel to the list
73
74 fGeom.push_back(make_pair(0, -0.5));
75
76 for (int ring=1; ring<=rings; ring++)
77 {
78 for (int s=0; s<6; s++)
79 {
80 for (int i=1; i<=ring; i++)
81 {
82 double xx, yy;
83 switch (s)
84 {
85 case 0: // Direction South East
86 xx = (ring+i)*0.5;
87 yy = (-ring+i)*gsSin60;
88 break;
89
90 case 1: // Direction North East
91 xx = ring-i*0.5;
92 yy = i*gsSin60;
93 break;
94
95 case 2: // Direction North
96 xx = ring*0.5-i;
97 yy = ring*gsSin60;
98 break;
99
100 case 3: // Direction North West
101 xx = -(ring+i)*0.5;
102 yy = (ring-i)*gsSin60;
103 break;
104
105 case 4: // Direction South West
106 xx = 0.5*i-ring;
107 yy = -i*gsSin60;
108 break;
109
110 case 5: // Direction South
111 xx = i-ring*0.5;
112 yy = -ring*gsSin60;
113 break;
114 }
115
116 if (xx*xx + yy*yy - xx > 395.75)
117 continue;
118
119 fGeom.push_back(make_pair(yy, xx-0.5));
120 }
121 }
122 }
123 }
124
125 valarray<double> fData;
126 vector<bool> fBold;
127 vector<bool> fEnable;
128
129 int fWhite;
130
131 int64_t fMin;
132 int64_t fMax;
133
134public:
135 Camera() : fData(1440), fBold(1440), fEnable(1440), fWhite(-1), fMin(-1), fMax(-1)
136 {
137 CreatePalette();
138 CreateGeometry();
139
140 for (int i=0; i<1440; i++)
141 {
142 fData[i] = i;
143 fBold[i]=false;
144 fEnable[i]=true;
145 }
146 }
147
148 void Reset() { fBold.assign(1440, false); }
149
150 void SetBold(int idx) { fBold[idx]=true; }
151 void SetWhite(int idx) { fWhite=idx; }
152 void SetEnable(int idx, bool b) { fEnable[idx]=b; }
153 void Toggle(int idx) { fEnable[idx]=!fEnable[idx]; }
154 double GetData(int idx) const { return fData[idx]; }
155 void SetMin(int64_t min) { fMin=min; }
156 void SetMax(int64_t max) { fMax=max; }
157
158 const char *GetName() const { return "Camera"; }
159
160 vector<Int_t> fPalette;
161
162 void Paint(const Position &p)
163 {
164 static const Double_t fgCos60 = 0.5; // TMath::Cos(60/TMath::RadToDeg());
165 static const Double_t fgSin60 = sqrt(3.)/2; // TMath::Sin(60/TMath::RadToDeg());
166
167 static const Double_t fgDy[6] = { fgCos60, 0., -fgCos60, -fgCos60, 0., fgCos60 };
168 static const Double_t fgDx[6] = { fgSin60/3, fgSin60*2/3, fgSin60/3, -fgSin60/3, -fgSin60*2/3, -fgSin60/3 };
169
170 //
171 // calculate the positions of the pixel corners
172 //
173 static Double_t x[7], y[7];
174 for (Int_t i=0; i<7; i++)
175 {
176 x[i] = p.first + fgDx[i%6];
177 y[i] = p.second + fgDy[i%6];
178 }
179
180 gPad->PaintFillArea(6, x, y);
181 gPad->PaintPolyLine(7, x, y);
182 }
183
184 int GetCol(double dmin, double val, double dmax, bool enable)
185 {
186 if (!enable)
187 return kWhite;
188
189 if (val<dmin)
190 return kBlue+4;//kBlack;
191
192 if (val>dmax)
193 return kRed+4;//kWhite;
194
195 const double min = dmin;
196 const double scale = dmax==dmin ? 1 : dmax-dmin;
197
198 const int col = (val-min)/scale*(fPalette.size()-1);
199
200 return gStyle->GetColorPalette(col);
201 }
202
203 void Paint(Option_t *)
204 {
205 gStyle->SetPalette(fPalette.size(), fPalette.data());
206
207 const double r = double(gPad->GetWw())/gPad->GetWh();
208 const double max = 20.5; // 20.5 rings in x and y
209
210 if (r>1)
211 gPad->Range(-r*max, -max, r*max, max);
212 else
213 gPad->Range(-max, -max/r, max, max/r);
214
215 Double_t x1, x2, y1, y2;
216 gPad->GetRange(x1, x2, y1, y2);
217
218 double dmin = fData[0];
219 double dmax = fData[0];
220
221 for (unsigned int i=0; i<fData.size(); i++)
222 {
223 if (!fEnable[i])
224 continue;
225
226 if (fData[i]>dmax)
227 dmax = fData[i];
228 if (fData[i]<dmin)
229 dmin = fData[i];
230 }
231
232 if (fMin>=0)
233 dmin = fMin;
234 if (fMax>=0)
235 dmax = fMax;
236
237// const double min = dmin;
238// const double scale = dmax==dmin ? 1 : dmax-dmin;
239
240 TAttFill fill(0, 1001);
241 TAttLine line;
242
243 int cnt=0;
244 for (Positions::iterator p=fGeom.begin(); p!=fGeom.end(); p++, cnt++)
245 {
246 if (fBold[cnt])
247 continue;
248
249 const int col = GetCol(dmin, fData[cnt], dmax, fEnable[cnt]);
250
251 fill.SetFillColor(col);
252 fill.Modify();
253
254 Paint(*p);
255 }
256
257 line.SetLineWidth(2);
258 line.Modify();
259
260 cnt = 0;
261 for (Positions::iterator p=fGeom.begin(); p!=fGeom.end(); p++, cnt++)
262 {
263 if (!fBold[cnt])
264 continue;
265
266 const int col = GetCol(dmin, fData[cnt], dmax, fEnable[cnt]);
267
268 fill.SetFillColor(col);
269 fill.Modify();
270
271 Paint(*p);
272 }
273
274 TMarker m(0,0,kStar);
275 m.DrawMarker(0, 0);
276
277 if (fWhite<0)
278 return;
279
280 const Position &p = fGeom[fWhite];
281
282 line.SetLineColor(kWhite);
283 line.Modify();
284
285 const int col = GetCol(dmin, fData[fWhite], dmax, fEnable[fWhite]);
286
287 fill.SetFillColor(col);
288 fill.Modify();
289
290 Paint(p);
291 }
292
293 int GetIdx(float px, float py) const
294 {
295 static const double sqrt3 = sqrt(3);
296
297 int idx = 0;
298 for (Positions::const_iterator p=fGeom.begin(); p!=fGeom.end(); p++, idx++)
299 {
300 const Double_t dy = py - p->second;
301 if (fabs(dy)>0.5)
302 continue;
303
304 const Double_t dx = px - p->first;
305
306 if (TMath::Abs(dy + dx*sqrt3) > 1)
307 continue;
308
309 if (TMath::Abs(dy - dx*sqrt3) > 1)
310 continue;
311
312 return idx;
313 }
314 return -1;
315 }
316
317 char *GetObjectInfo(Int_t px, Int_t py) const
318 {
319 static stringstream stream;
320 static string str;
321
322 const float x = gPad->AbsPixeltoX(px);
323 const float y = gPad->AbsPixeltoY(py);
324
325 const int idx = GetIdx(x, y);
326
327 stream.seekp(0);
328 if (idx>=0)
329 {
330 stream << "Pixel=" << idx << " Data=" << fData[idx] << '\0';
331 }
332
333 str = stream.str();
334 return const_cast<char*>(str.c_str());
335 }
336
337 Int_t DistancetoPrimitive(Int_t px, Int_t py)
338 {
339 const float x = gPad->AbsPixeltoX(px);
340 const float y = gPad->AbsPixeltoY(py);
341
342 return GetIdx(x, y)>=0 ? 0 : 99999;
343 }
344
345 void SetData(const valarray<double> &data)
346 {
347 fData = data;
348 }
349
350 void SetData(const float *data)
351 {
352 for (int i=0; i<1440; i++)
353 fData[i] = data[i];
354 }
355};
356*/
357// #########################################################################
358
359class FactGui : public MainWindow, public DimNetwork
360{
361private:
362 class FunctionEvent : public QEvent
363 {
364 public:
365 boost::function<void(const QEvent &)> fFunction;
366
367 FunctionEvent(const boost::function<void(const QEvent &)> &f)
368 : QEvent((QEvent::Type)QEvent::registerEventType()),
369 fFunction(f) { }
370
371 bool Exec() { fFunction(*this); return true; }
372 };
373
374 valarray<int8_t> fFtuStatus;
375
376 PixelMap fPixelMap;
377
378 //vector<int> fPixelMapHW; // Software -> Hardware
379 vector<int> fPatchMapHW; // Software -> Hardware
380 vector<int> fPatchHW; // Maps the software(!) pixel id to the hardware(!) patch id
381
382 bool fInChoosePatchTH; // FIXME. Find a better solution
383 bool fInChooseBiasHv; // FIXME. Find a better solution
384 bool fInChooseBiasCam; // FIXME. Find a better solution
385
386 DimStampedInfo fDimDNS;
387
388 DimStampedInfo fDimLoggerStats;
389 DimStampedInfo fDimLoggerFilenameNight;
390 DimStampedInfo fDimLoggerFilenameRun;
391 DimStampedInfo fDimLoggerNumSubs;
392
393 DimStampedInfo fDimFtmPassport;
394 DimStampedInfo fDimFtmTriggerRates;
395 DimStampedInfo fDimFtmError;
396 DimStampedInfo fDimFtmFtuList;
397 DimStampedInfo fDimFtmStaticData;
398 DimStampedInfo fDimFtmDynamicData;
399 DimStampedInfo fDimFtmCounter;
400
401 DimStampedInfo fDimFadWriteStats;
402 DimStampedInfo fDimFadStartRun;
403 DimStampedInfo fDimFadRuns;
404 DimStampedInfo fDimFadEvents;
405 DimStampedInfo fDimFadRawData;
406 DimStampedInfo fDimFadEventData;
407 DimStampedInfo fDimFadConnections;
408 DimStampedInfo fDimFadFwVersion;
409 DimStampedInfo fDimFadRunNumber;
410 DimStampedInfo fDimFadDNA;
411 DimStampedInfo fDimFadTemperature;
412 DimStampedInfo fDimFadPrescaler;
413 DimStampedInfo fDimFadRefClock;
414 DimStampedInfo fDimFadRoi;
415 DimStampedInfo fDimFadDac;
416 DimStampedInfo fDimFadDrsCalibration;
417 DimStampedInfo fDimFadStatus;
418 DimStampedInfo fDimFadStatistics1;
419 DimStampedInfo fDimFadStatistics2;
420
421 DimStampedInfo fDimFscTemp;
422 DimStampedInfo fDimFscVolt;
423 DimStampedInfo fDimFscCurrent;
424 DimStampedInfo fDimFscHumidity;
425
426 DimStampedInfo fDimBiasVolt;
427 DimStampedInfo fDimBiasCurrent;
428
429 map<string, DimInfo*> fServices;
430
431 // ========================== LED Colors ================================
432
433 enum LedColor_t
434 {
435 kLedRed,
436 kLedGreen,
437 kLedYellow,
438 kLedOrange,
439 kLedGray,
440 kLedWarnBorder,
441 kLedWarn,
442 kLedWarnTriangleBorder,
443 kLedWarnTriangle,
444 kLedInProgress,
445 };
446
447 void SetLedColor(QPushButton *button, LedColor_t col, const Time &t)
448 {
449 switch (col)
450 {
451 case kLedRed:
452 button->setIcon(QIcon(":/Resources/icons/red circle 1.png"));
453 break;
454
455 case kLedGreen:
456 button->setIcon(QIcon(":/Resources/icons/green circle 1.png"));
457 break;
458
459 case kLedYellow:
460 button->setIcon(QIcon(":/Resources/icons/yellow circle 1.png"));
461 break;
462
463 case kLedOrange:
464 button->setIcon(QIcon(":/Resources/icons/orange circle 1.png"));
465 break;
466
467 case kLedGray:
468 button->setIcon(QIcon(":/Resources/icons/gray circle 1.png"));
469 break;
470
471 case kLedWarnBorder:
472 button->setIcon(QIcon(":/Resources/icons/warning 1.png"));
473 break;
474
475 case kLedWarn:
476 button->setIcon(QIcon(":/Resources/icons/warning 2.png"));
477 break;
478
479 case kLedWarnTriangle:
480 button->setIcon(QIcon(":/Resources/icons/warning 3.png"));
481 break;
482
483 case kLedWarnTriangleBorder:
484 button->setIcon(QIcon(":/Resources/icons/warning 4.png"));
485 break;
486
487 case kLedInProgress:
488 button->setIcon(QIcon(":/Resources/icons/in progress.png"));
489 break;
490
491 }
492
493 //button->setToolTip("Last change: "+QDateTime::currentDateTimeUtc().toString()+" UTC");
494 button->setToolTip(("Last change: "+t.GetAsStr()+" (UTC)").c_str());
495 }
496
497 // ===================== Services and Commands ==========================
498
499 QStandardItem *AddServiceItem(const std::string &server, const std::string &service, bool iscmd)
500 {
501 QListView *servers = iscmd ? fDimCmdServers : fDimSvcServers;
502 QListView *services = iscmd ? fDimCmdCommands : fDimSvcServices;
503 QListView *description = iscmd ? fDimCmdDescription : fDimSvcDescription;
504
505 QStandardItemModel *m = dynamic_cast<QStandardItemModel*>(servers->model());
506 if (!m)
507 {
508 m = new QStandardItemModel(this);
509 servers->setModel(m);
510 services->setModel(m);
511 description->setModel(m);
512 }
513
514 QList<QStandardItem*> l = m->findItems(server.c_str());
515
516 if (l.size()>1)
517 {
518 cout << "hae" << endl;
519 return 0;
520 }
521
522 QStandardItem *col = l.size()==0 ? NULL : l[0];
523
524 if (!col)
525 {
526 col = new QStandardItem(server.c_str());
527 m->appendRow(col);
528
529 if (!services->rootIndex().isValid())
530 {
531 services->setRootIndex(col->index());
532 servers->setCurrentIndex(col->index());
533 }
534 }
535
536 QStandardItem *item = 0;
537 for (int i=0; i<col->rowCount(); i++)
538 {
539 QStandardItem *coli = col->child(i);
540 if (coli->text().toStdString()==service)
541 return coli;
542 }
543
544 item = new QStandardItem(service.c_str());
545 col->appendRow(item);
546 col->sortChildren(0);
547
548 if (!description->rootIndex().isValid())
549 {
550 description->setRootIndex(item->index());
551 services->setCurrentIndex(item->index());
552 }
553
554 if (!iscmd)
555 item->setCheckable(true);
556
557 return item;
558 }
559
560 void AddDescription(QStandardItem *item, const vector<Description> &vec)
561 {
562 if (!item)
563 return;
564 if (vec.size()==0)
565 return;
566
567 item->setToolTip(vec[0].comment.c_str());
568
569 const string str = Description::GetHtmlDescription(vec);
570
571 QStandardItem *desc = new QStandardItem(str.c_str());
572 desc->setSelectable(false);
573 item->setChild(0, 0, desc);
574 }
575
576 void AddServer(const std::string &s)
577 {
578 DimNetwork::AddServer(s);
579
580 QApplication::postEvent(this,
581 new FunctionEvent(boost::bind(&FactGui::handleAddServer, this, s)));
582 }
583
584 void AddService(const std::string &server, const std::string &service, const std::string &fmt, bool iscmd)
585 {
586 QApplication::postEvent(this,
587 new FunctionEvent(boost::bind(&FactGui::handleAddService, this, server, service, fmt, iscmd)));
588 }
589
590 void RemoveService(std::string server, std::string service, bool iscmd)
591 {
592 UnsubscribeService(server+'/'+service, true);
593
594 QApplication::postEvent(this,
595 new FunctionEvent(boost::bind(&FactGui::handleRemoveService, this, server, service, iscmd)));
596 }
597
598 void RemoveAllServices(const std::string &server)
599 {
600 UnsubscribeAllServices(server);
601
602 QApplication::postEvent(this,
603 new FunctionEvent(boost::bind(&FactGui::handleRemoveAllServices, this, server)));
604 }
605
606 void AddDescription(const std::string &server, const std::string &service, const vector<Description> &vec)
607 {
608 QApplication::postEvent(this,
609 new FunctionEvent(boost::bind(&FactGui::handleAddDescription, this, server, service, vec)));
610 }
611
612 // ======================================================================
613
614 void handleAddServer(const std::string &server)
615 {
616 const State s = GetState(server, GetCurrentState(server));
617 handleStateChanged(Time(), server, s);
618 }
619
620 void handleAddService(const std::string &server, const std::string &service, const std::string &/*fmt*/, bool iscmd)
621 {
622 QStandardItem *item = AddServiceItem(server, service, iscmd);
623 const vector<Description> v = GetDescription(server, service);
624 AddDescription(item, v);
625 }
626
627 void handleRemoveService(const std::string &server, const std::string &service, bool iscmd)
628 {
629 QListView *servers = iscmd ? fDimCmdServers : fDimSvcServers;
630
631 QStandardItemModel *m = dynamic_cast<QStandardItemModel*>(servers->model());
632 if (!m)
633 return;
634
635 QList<QStandardItem*> l = m->findItems(server.c_str());
636 if (l.size()!=1)
637 return;
638
639 for (int i=0; i<l[0]->rowCount(); i++)
640 {
641 QStandardItem *row = l[0]->child(i);
642 if (row->text().toStdString()==service)
643 {
644 l[0]->removeRow(row->index().row());
645 return;
646 }
647 }
648 }
649
650 void handleRemoveAllServices(const std::string &server)
651 {
652 handleStateChanged(Time(), server, State(-2, "Offline", "No connection via DIM."));
653
654 QStandardItemModel *m = 0;
655 if ((m=dynamic_cast<QStandardItemModel*>(fDimCmdServers->model())))
656 {
657 QList<QStandardItem*> l = m->findItems(server.c_str());
658 if (l.size()==1)
659 m->removeRow(l[0]->index().row());
660 }
661
662 if ((m = dynamic_cast<QStandardItemModel*>(fDimSvcServers->model())))
663 {
664 QList<QStandardItem*> l = m->findItems(server.c_str());
665 if (l.size()==1)
666 m->removeRow(l[0]->index().row());
667 }
668 }
669
670 void handleAddDescription(const std::string &server, const std::string &service, const vector<Description> &vec)
671 {
672 const bool iscmd = IsCommand(server, service)==true;
673
674 QStandardItem *item = AddServiceItem(server, service, iscmd);
675 AddDescription(item, vec);
676 }
677
678 // ======================================================================
679
680 void SubscribeService(const string &service)
681 {
682 if (fServices.find(service)!=fServices.end())
683 {
684 cerr << "ERROR - We are already subscribed to " << service << endl;
685 return;
686 }
687
688 fServices[service] = new DimStampedInfo(service.c_str(), (void*)NULL, 0, this);
689 }
690
691 void UnsubscribeService(const string &service, bool allow_unsubscribed=false)
692 {
693 const map<string,DimInfo*>::iterator i=fServices.find(service);
694
695 if (i==fServices.end())
696 {
697 if (!allow_unsubscribed)
698 cerr << "ERROR - We are not subscribed to " << service << endl;
699 return;
700 }
701
702 delete i->second;
703
704 fServices.erase(i);
705 }
706
707 void UnsubscribeAllServices(const string &server)
708 {
709 for (map<string,DimInfo*>::iterator i=fServices.begin();
710 i!=fServices.end(); i++)
711 if (i->first.substr(0, server.length()+1)==server+'/')
712 {
713 delete i->second;
714 fServices.erase(i);
715 }
716 }
717
718 // ======================================================================
719
720 struct DimData
721 {
722 const int qos;
723 const string name;
724 const string format;
725 const vector<char> data;
726 const Time time;
727
728 Time extract(DimInfo *inf) const
729 {
730 // Must be called in exactly this order!
731 const int tsec = inf->getTimestamp();
732 const int tms = inf->getTimestampMillisecs();
733
734 return Time(tsec, tms*1000);
735 }
736
737// DimInfo *info; // this is ONLY for a fast check of the type of the DimData!!
738
739 DimData(DimInfo *inf) :
740 qos(inf->getQuality()),
741 name(inf->getName()),
742 format(inf->getFormat()),
743 data(inf->getString(), inf->getString()+inf->getSize()),
744 time(extract(inf))/*,
745 info(inf)*/
746 {
747 }
748
749 template<typename T>
750 T get(uint32_t offset=0) const { return *reinterpret_cast<const T*>(data.data()+offset); }
751
752 template<typename T>
753 const T *ptr(uint32_t offset=0) const { return reinterpret_cast<const T*>(data.data()+offset); }
754
755 template<typename T>
756 const T &ref(uint32_t offset=0) const { return *reinterpret_cast<const T*>(data.data()+offset); }
757
758// vector<char> vec(int b) const { return vector<char>(data.begin()+b, data.end()); }
759// string str(unsigned int b) const { return b>=data.size()?string():string(data.data()+b, data.size()-b); }
760 const char *c_str() const { return (char*)data.data(); }
761/*
762 vector<boost::any> any() const
763 {
764 const Converter conv(format);
765 conv.Print();
766 return conv.GetAny(data.data(), data.size());
767 }*/
768 size_t size() const { return data.size(); }
769 };
770
771 // ======================= DNS ==========================================
772
773 void handleDimDNS(const DimData &d)
774 {
775 const int version = d.size()!=4 ? 0 : d.get<uint32_t>();
776
777 ostringstream str;
778 str << "V" << version/100 << 'r' << version%100;
779
780 ostringstream dns;
781 dns << (version==0?"No connection":"Connection");
782 dns << " to DIM DNS (" << getenv("DIM_DNS_NODE") << ")";
783 dns << (version==0?".":" established.");
784
785 fStatusDNSLabel->setText(version==0?"Offline":str.str().c_str());
786 fStatusDNSLabel->setToolTip(dns.str().c_str());
787
788 SetLedColor(fStatusDNSLed, version==0 ? kLedRed : kLedGreen, Time());
789 }
790
791
792 // ======================= Logger =======================================
793
794 void handleLoggerStats(const DimData &d)
795 {
796 const bool connected = d.size()!=0;
797
798 fLoggerET->setEnabled(connected);
799 fLoggerRate->setEnabled(connected);
800 fLoggerWritten->setEnabled(connected);
801 fLoggerFreeSpace->setEnabled(connected);
802 fLoggerSpaceLeft->setEnabled(connected);
803
804 if (!connected)
805 return;
806
807 const uint64_t *vals = d.ptr<uint64_t>();
808
809 const size_t space = vals[0];
810 const size_t written = vals[1];
811 const size_t rate = float(vals[2])/vals[3];
812
813 fLoggerFreeSpace->setSuffix(" MB");
814 fLoggerFreeSpace->setDecimals(0);
815 fLoggerFreeSpace->setValue(space*1e-6);
816
817 if (space> 1000000) // > 1GB
818 {
819 fLoggerFreeSpace->setSuffix(" GB");
820 fLoggerFreeSpace->setDecimals(2);
821 fLoggerFreeSpace->setValue(space*1e-9);
822 }
823 if (space>= 3000000) // >= 3GB
824 {
825 fLoggerFreeSpace->setSuffix(" GB");
826 fLoggerFreeSpace->setDecimals(1);
827 fLoggerFreeSpace->setValue(space*1e-9);
828 }
829 if (space>=100000000) // >= 100GB
830 {
831 fLoggerFreeSpace->setSuffix(" GB");
832 fLoggerFreeSpace->setDecimals(0);
833 fLoggerFreeSpace->setValue(space*1e-9);
834 }
835
836 fLoggerET->setTime(QTime().addSecs(rate>0?space/rate:0));
837 fLoggerRate->setValue(rate*1e-3); // kB/s
838 fLoggerWritten->setValue(written*1e-6);
839
840 fLoggerRate->setSuffix(" kB/s");
841 fLoggerRate->setDecimals(2);
842 fLoggerRate->setValue(rate);
843 if (rate> 2) // > 2kB/s
844 {
845 fLoggerRate->setSuffix(" kB/s");
846 fLoggerRate->setDecimals(1);
847 fLoggerRate->setValue(rate);
848 }
849 if (rate>=100) // >100kB/s
850 {
851 fLoggerRate->setSuffix(" kB/s");
852 fLoggerRate->setDecimals(0);
853 fLoggerRate->setValue(rate);
854 }
855 if (rate>=1000) // >100kB/s
856 {
857 fLoggerRate->setSuffix(" MB/s");
858 fLoggerRate->setDecimals(2);
859 fLoggerRate->setValue(rate*1e-3);
860 }
861 if (rate>=10000) // >1MB/s
862 {
863 fLoggerRate->setSuffix(" MB/s");
864 fLoggerRate->setDecimals(1);
865 fLoggerRate->setValue(rate*1e-3);
866 }
867 if (rate>=100000) // >10MB/s
868 {
869 fLoggerRate->setSuffix(" MB/s");
870 fLoggerRate->setDecimals(0);
871 fLoggerRate->setValue(rate*1e-3);
872 }
873
874 if (space/1000000>static_cast<size_t>(fLoggerSpaceLeft->maximum()))
875 fLoggerSpaceLeft->setValue(fLoggerSpaceLeft->maximum()); // GB
876 else
877 fLoggerSpaceLeft->setValue(space/1000000); // MB
878 }
879
880 void handleLoggerFilenameNight(const DimData &d)
881 {
882 const bool connected = d.size()!=0;
883
884 fLoggerFilenameNight->setEnabled(connected);
885 if (!connected)
886 return;
887
888 fLoggerFilenameNight->setText(d.c_str()+4);
889
890 const uint32_t files = d.get<uint32_t>();
891
892 SetLedColor(fLoggerLedLog, files&1 ? kLedGreen : kLedGray, d.time);
893 SetLedColor(fLoggerLedRep, files&2 ? kLedGreen : kLedGray, d.time);
894 SetLedColor(fLoggerLedFits, files&4 ? kLedGreen : kLedGray, d.time);
895 }
896
897 void handleLoggerFilenameRun(const DimData &d)
898 {
899 const bool connected = d.size()!=0;
900
901 fLoggerFilenameRun->setEnabled(connected);
902 if (!connected)
903 return;
904
905 fLoggerFilenameRun->setText(d.c_str()+4);
906
907 const uint32_t files = d.get<uint32_t>();
908
909 SetLedColor(fLoggerLedLog, files&1 ? kLedGreen : kLedGray, d.time);
910 SetLedColor(fLoggerLedRep, files&2 ? kLedGreen : kLedGray, d.time);
911 SetLedColor(fLoggerLedFits, files&4 ? kLedGreen : kLedGray, d.time);
912 }
913
914 void handleLoggerNumSubs(const DimData &d)
915 {
916 const bool connected = d.size()!=0;
917
918 fLoggerSubscriptions->setEnabled(connected);
919 fLoggerOpenFiles->setEnabled(connected);
920 if (!connected)
921 return;
922
923 const uint32_t *vals = d.ptr<uint32_t>();
924
925 fLoggerSubscriptions->setValue(vals[0]);
926 fLoggerOpenFiles->setValue(vals[1]);
927 }
928
929
930 // ===================== All ============================================
931
932 bool CheckSize(const DimData &d, size_t sz, bool print=true) const
933 {
934 if (d.size()==0)
935 return false;
936
937 if (d.size()!=sz)
938 {
939 if (print)
940 cerr << "Size mismatch in " << d.name << ": Found=" << d.size() << " Expected=" << sz << endl;
941 return false;
942 }
943
944 return true;
945 }
946
947 // ===================== FAD ============================================
948
949 void handleFadWriteStats(const DimData &d)
950 {
951 const bool connected = d.size()!=0;
952
953 fEvtBuilderET->setEnabled(connected);
954 fEvtBuilderRate->setEnabled(connected);
955 fEvtBuilderWritten->setEnabled(connected);
956 fEvtBuilderFreeSpace->setEnabled(connected);
957 fEvtBuilderSpaceLeft->setEnabled(connected);
958
959 if (!connected)
960 return;
961
962 const uint64_t *vals = d.ptr<uint64_t>();
963
964 const size_t space = vals[0];
965 const size_t written = vals[1];
966 const size_t rate = float(vals[2])/vals[3];
967
968 fEvtBuilderFreeSpace->setSuffix(" MB");
969 fEvtBuilderFreeSpace->setDecimals(0);
970 fEvtBuilderFreeSpace->setValue(space*1e-6);
971
972 if (space> 1000000) // > 1GB
973 {
974 fEvtBuilderFreeSpace->setSuffix(" GB");
975 fEvtBuilderFreeSpace->setDecimals(2);
976 fEvtBuilderFreeSpace->setValue(space*1e-9);
977 }
978 if (space>= 3000000) // >= 3GB
979 {
980 fEvtBuilderFreeSpace->setSuffix(" GB");
981 fEvtBuilderFreeSpace->setDecimals(1);
982 fEvtBuilderFreeSpace->setValue(space*1e-9);
983 }
984 if (space>=100000000) // >= 100GB
985 {
986 fEvtBuilderFreeSpace->setSuffix(" GB");
987 fEvtBuilderFreeSpace->setDecimals(0);
988 fEvtBuilderFreeSpace->setValue(space*1e-9);
989 }
990
991 fEvtBuilderET->setTime(QTime().addSecs(rate>0?space/rate:0));
992 fEvtBuilderRate->setValue(rate*1e-3); // kB/s
993 fEvtBuilderWritten->setValue(written*1e-6);
994
995 fEvtBuilderRate->setSuffix(" kB/s");
996 fEvtBuilderRate->setDecimals(2);
997 fEvtBuilderRate->setValue(rate);
998 if (rate> 2) // > 2kB/s
999 {
1000 fEvtBuilderRate->setSuffix(" kB/s");
1001 fEvtBuilderRate->setDecimals(1);
1002 fEvtBuilderRate->setValue(rate);
1003 }
1004 if (rate>=100) // >100kB/s
1005 {
1006 fEvtBuilderRate->setSuffix(" kB/s");
1007 fEvtBuilderRate->setDecimals(0);
1008 fEvtBuilderRate->setValue(rate);
1009 }
1010 if (rate>=1000) // >100kB/s
1011 {
1012 fEvtBuilderRate->setSuffix(" MB/s");
1013 fEvtBuilderRate->setDecimals(2);
1014 fEvtBuilderRate->setValue(rate*1e-3);
1015 }
1016 if (rate>=10000) // >1MB/s
1017 {
1018 fEvtBuilderRate->setSuffix(" MB/s");
1019 fEvtBuilderRate->setDecimals(1);
1020 fEvtBuilderRate->setValue(rate*1e-3);
1021 }
1022 if (rate>=100000) // >10MB/s
1023 {
1024 fEvtBuilderRate->setSuffix(" MB/s");
1025 fEvtBuilderRate->setDecimals(0);
1026 fEvtBuilderRate->setValue(rate*1e-3);
1027 }
1028
1029 if (space/1000000>static_cast<size_t>(fEvtBuilderSpaceLeft->maximum()))
1030 fEvtBuilderSpaceLeft->setValue(fEvtBuilderSpaceLeft->maximum()); // GB
1031 else
1032 fEvtBuilderSpaceLeft->setValue(space/1000000); // MB
1033 }
1034
1035 void handleFadRuns(const DimData &d)
1036 {
1037 if (d.size()==0)
1038 return;
1039
1040 if (d.size()<20)
1041 {
1042 cerr << "Size mismatch in " << d.name << ": Found=" << d.size() << " Expected>=20" << endl;
1043 return;
1044 }
1045
1046 const uint32_t *ptr = d.ptr<uint32_t>();
1047
1048 fEvtBldOpenFiles->setValue(ptr[0]);
1049 fEvtBldOpenStreams->setValue(ptr[0]);
1050 fEvtBldRunNumberMin->setValue(ptr[1]);
1051 fEvtBldRunNumberMax->setValue(ptr[2]);
1052 fEvtBldLastOpened->setValue(ptr[3]);
1053 fEvtBldLastClosed->setValue(ptr[4]);
1054
1055 if (d.size()>=20)
1056 fEvtBldFilename->setText(d.ptr<char>(20));
1057
1058 if (ptr[0]==0)
1059 fEvtBldFilename->setText("");
1060 }
1061
1062 void handleFadStartRun(const DimData &d)
1063 {
1064 if (!CheckSize(d, 16))
1065 return;
1066
1067 const int64_t *runs = d.ptr<int64_t>();
1068
1069 fFadRunNoCur->setValue(runs[0]);
1070 fFadRunNoNext->setValue(runs[1]);
1071 fFadRunNoCur->setEnabled(runs[0]>=0);
1072 }
1073
1074 void handleFadEvents(const DimData &d)
1075 {
1076 if (!CheckSize(d, 16))
1077 return;
1078
1079 const uint32_t *ptr = d.ptr<uint32_t>();
1080
1081 fEvtsSuccessCurRun->setValue(ptr[0]);
1082 fEvtsSuccessTotal->setValue(ptr[1]);
1083 fEvtBldEventId->setValue(ptr[2]);
1084 fFadEvtCounter->setValue(ptr[2]);
1085 fEvtBldTriggerId->setValue(ptr[3]);
1086 }
1087
1088 void handleFadTemperature(const DimData &d)
1089 {
1090 if (d.size()==0)
1091 {
1092 fFadTempMin->setEnabled(false);
1093 fFadTempMax->setEnabled(false);
1094 SetLedColor(fFadLedTemp, kLedGray, d.time);
1095 return;
1096 }
1097
1098 if (!CheckSize(d, 82*sizeof(float)))
1099 return;
1100
1101 const float *ptr = d.ptr<float>();
1102
1103 fFadTempMin->setEnabled(true);
1104 fFadTempMax->setEnabled(true);
1105
1106 fFadTempMin->setValue(ptr[0]);
1107 fFadTempMax->setValue(ptr[41]);
1108
1109 handleFadToolTip(d.time, fFadTempMin, ptr+1);
1110 handleFadToolTip(d.time, fFadTempMax, ptr+42);
1111 }
1112
1113 void handleFadRefClock(const DimData &d)
1114 {
1115 if (d.size()==0)
1116 {
1117 fFadRefClockMin->setEnabled(false);
1118 fFadRefClockMax->setEnabled(false);
1119 SetLedColor(fFadLedRefClock, kLedGray, d.time);
1120 return;
1121 }
1122
1123 if (!CheckSize(d, 42*sizeof(uint32_t)))
1124 return;
1125
1126 const uint32_t *ptr = d.ptr<uint32_t>();
1127
1128 fFadRefClockMin->setEnabled(true);
1129 fFadRefClockMax->setEnabled(true);
1130
1131 fFadRefClockMin->setValue(ptr[40]*2.048);
1132 fFadRefClockMax->setValue(ptr[41]*2.048);
1133
1134 const int64_t diff = int64_t(ptr[41]) - int64_t(ptr[40]);
1135
1136 SetLedColor(fFadLedRefClock, abs(diff)>3?kLedRed:kLedGreen, d.time);
1137
1138 handleFadToolTip(d.time, fFadLedRefClock, ptr);
1139 }
1140
1141 void handleFadRoi(const DimData &d)
1142 {
1143 if (d.size()==0)
1144 {
1145 fFadRoi->setEnabled(false);
1146 fFadRoiCh9->setEnabled(false);
1147 SetLedColor(fFadLedRoi, kLedGray, d.time);
1148 return;
1149 }
1150
1151 if (!CheckSize(d, 2*sizeof(uint16_t)))
1152 return;
1153
1154 const uint16_t *ptr = d.ptr<uint16_t>();
1155
1156 fFadRoi->setEnabled(true);
1157 fFadRoiCh9->setEnabled(true);
1158
1159 fFadRoi->setValue(ptr[0]);
1160 fFadRoiCh9->setValue(ptr[1]);
1161
1162 SetLedColor(fFadLedRoi, kLedGray, d.time);
1163 }
1164
1165 void handleDac(QPushButton *led, QSpinBox *box, const DimData &d, int idx)
1166 {
1167 if (d.size()==0)
1168 {
1169 box->setEnabled(false);
1170 SetLedColor(led, kLedGray, d.time);
1171 return;
1172 }
1173
1174 const uint16_t *ptr = d.ptr<uint16_t>()+idx*42;
1175
1176 box->setEnabled(true);
1177 box->setValue(ptr[40]==ptr[41]?ptr[40]:0);
1178
1179 SetLedColor(led, ptr[40]==ptr[41]?kLedGreen:kLedOrange, d.time);
1180 handleFadToolTip(d.time, led, ptr);
1181 }
1182
1183 void handleFadDac(const DimData &d)
1184 {
1185 if (!CheckSize(d, 8*42*sizeof(uint16_t)) && !d.size()==0)
1186 return;
1187
1188 handleDac(fFadLedDac0, fFadDac0, d, 0);
1189 handleDac(fFadLedDac1, fFadDac1, d, 1);
1190 handleDac(fFadLedDac2, fFadDac2, d, 2);
1191 handleDac(fFadLedDac3, fFadDac3, d, 3);
1192 handleDac(fFadLedDac4, fFadDac4, d, 4);
1193 handleDac(fFadLedDac5, fFadDac5, d, 5);
1194 handleDac(fFadLedDac6, fFadDac6, d, 6);
1195 handleDac(fFadLedDac7, fFadDac7, d, 7);
1196 }
1197
1198 EVENT *fEventData;
1199
1200 void DrawHorizontal(TH1 *hf, double xmax, TH1 &h, double scale)
1201 {
1202 for (Int_t i=1;i<=h.GetNbinsX();i++)
1203 {
1204 if (h.GetBinContent(i)<0.5 || h.GetBinContent(i)>h.GetEntries()-0.5)
1205 continue;
1206
1207 TBox * box=new TBox(xmax, h.GetBinLowEdge(i),
1208 xmax+h.GetBinContent(i)*scale,
1209 h.GetBinLowEdge(i+1));
1210
1211 box->SetFillStyle(0);
1212 box->SetLineColor(h.GetLineColor());
1213 box->SetLineStyle(kSolid);
1214 box->SetBit(kCannotPick|kNoContextMenu);
1215 //box->Draw();
1216
1217 hf->GetListOfFunctions()->Add(box);
1218 }
1219 }
1220
1221 void DisplayEventData()
1222 {
1223 if (!fEventData)
1224 return;
1225
1226#ifdef HAVE_ROOT
1227 TCanvas *c = fAdcDataCanv->GetCanvas();
1228
1229 TH1 *hf = dynamic_cast<TH1*>(c->FindObject("Frame"));
1230 TH1 *h = dynamic_cast<TH1*>(c->FindObject("EventData"));
1231 TH1 *d0 = dynamic_cast<TH1*>(c->FindObject("DrsCalib0"));
1232 TH1 *d1 = dynamic_cast<TH1*>(c->FindObject("DrsCalib1"));
1233 TH1 *d2 = dynamic_cast<TH1*>(c->FindObject("DrsCalib2"));
1234
1235 const int roi = fAdcPhysical->isChecked() ? 1024 : (fEventData->Roi>0 ? fEventData->Roi : 1);
1236
1237 if ((hf && hf->GetNbinsX()!=roi) ||
1238 (dynamic_cast<TH2*>(h) && !fAdcPersistent->isChecked()) ||
1239 (!dynamic_cast<TH2*>(h) && fAdcPersistent->isChecked()))
1240 {
1241 delete hf;
1242 delete h;
1243 delete d0;
1244 delete d1;
1245 delete d2;
1246 d0 = 0;
1247 d1 = 0;
1248 d2 = 0;
1249 hf = 0;
1250 }
1251
1252 c->cd();
1253
1254 if (!hf)
1255 {
1256 hf = new TH1F("Frame", "", roi, -0.5, roi-0.5);
1257 hf->SetDirectory(0);
1258 hf->SetBit(kCanDelete);
1259 hf->SetStats(kFALSE);
1260 hf->SetYTitle("Voltage [mV]");
1261 hf->GetXaxis()->CenterTitle();
1262 hf->GetYaxis()->CenterTitle();
1263 hf->SetMinimum(-1250);
1264 hf->SetMaximum(2150);
1265
1266 if (!fAdcPersistent->isChecked())
1267 h = new TH1F("EventData", "", roi, -0.5, roi-0.5);
1268 else
1269 {
1270 h = new TH2F("EventData", "", roi, -0.5, roi-0.5, 6751, -2350.5*2000/4096, 4400.5*2000/4096);
1271 h->SetContour(50);
1272 gStyle->SetPalette(1, 0);
1273 }
1274
1275 h->SetDirectory(0);
1276 h->SetBit(kCanDelete);
1277 h->SetMarkerStyle(kFullDotMedium);
1278 h->SetMarkerColor(kBlue);
1279
1280 hf->Draw("");
1281
1282 if (dynamic_cast<TH2*>(h))
1283 h->Draw("col same");
1284 }
1285
1286 if (d0 && !(fDrsCalibBaselineOn->isChecked() && fDrsCalibBaseline->value()>0))
1287 {
1288 delete d0;
1289 d0 = 0;
1290 }
1291 if (d1 && !(fDrsCalibGainOn->isChecked() && fDrsCalibGain->value()>0))
1292 {
1293 delete d1;
1294 d1 = 0;
1295 }
1296 if (d2 && !(fDrsCalibTrgOffsetOn->isChecked() && fDrsCalibTrgOffset->value()>0))
1297 {
1298 delete d2;
1299 d2 = 0;
1300 }
1301
1302 if (!d0 && fDrsCalibBaselineOn->isChecked() && fDrsCalibBaseline->value()>0)
1303 {
1304 d0 = new TH1F("DrsCalib0", "", roi, -0.5, roi-0.5);
1305 d0->SetDirectory(0);
1306 d0->SetBit(kCanDelete);
1307 d0->SetMarkerStyle(kFullDotSmall);
1308 d0->SetMarkerColor(kRed);
1309 d0->SetLineColor(kRed);
1310 d0->Draw("PEX0same");
1311 }
1312
1313 if (!d1 && fDrsCalibGainOn->isChecked() && fDrsCalibGain->value()>0)
1314 {
1315 d1 = new TH1F("DrsCalib1", "", roi, -0.5, roi-0.5);
1316 d1->SetDirectory(0);
1317 d1->SetBit(kCanDelete);
1318 d1->SetMarkerStyle(kFullDotSmall);
1319 d1->SetMarkerColor(kMagenta);
1320 d1->SetLineColor(kMagenta);
1321 d1->Draw("PEX0same");
1322 }
1323
1324 if (!d2 && fDrsCalibTrgOffsetOn->isChecked() && fDrsCalibTrgOffset->value()>0)
1325 {
1326 d2 = new TH1F("DrsCalib2", "", roi, -0.5, roi-0.5);
1327 d2->SetDirectory(0);
1328 d2->SetBit(kCanDelete);
1329 d2->SetMarkerStyle(kFullDotSmall);
1330 d2->SetMarkerColor(kGreen);
1331 d2->SetLineColor(kGreen);
1332 d2->Draw("PEX0same");
1333 }
1334
1335 if (!dynamic_cast<TH2*>(h) && !c->GetListOfPrimitives()->FindObject(h))
1336 h->Draw("PLsame");
1337
1338 // -----------------------------------------------------------
1339
1340 const uint32_t p =
1341 fAdcChannel->value() +
1342 fAdcChip->value() * 9+
1343 fAdcBoard->value() * 36+
1344 fAdcCrate->value() *360;
1345
1346 ostringstream str;
1347 str << "CBPX = " << fAdcCrate->value() << '|' << fAdcBoard->value() << '|' << fAdcChip->value() << '|' << fAdcChannel->value() << " (" << p << ")";
1348 str << " EventNum = " << fEventData->EventNum;
1349 str << " TriggerNum = " << fEventData->TriggerNum;
1350 str << " TriggerType = " << fEventData->TriggerType;
1351 str << " BoardTime = " << fEventData->BoardTime[fAdcBoard->value()+fAdcCrate->value()*10];
1352 str << " (" << Time(fEventData->PCTime, fEventData->PCUsec) << ")";
1353 hf->SetTitle(str.str().c_str());
1354 str.str("");
1355 str << "ADC Pipeline (start cell: " << fEventData->StartPix[p] << ")";
1356 hf->SetXTitle(str.str().c_str());
1357
1358 // -----------------------------------------------------------
1359
1360 const int16_t start = fEventData->StartPix[p];
1361
1362 fDrsCalibBaseline->setEnabled(fDrsCalibBaseline->value()>0);
1363 fDrsCalibGain->setEnabled(fDrsCalibGain->value()>0);
1364 fDrsCalibTrgOffset->setEnabled(fDrsCalibTrgOffset->value()>0);
1365
1366 if (d0)//fDrsCalibBaseline->value()==0 || start<0)
1367 d0->Reset();
1368 if (d1)//fDrsCalibGain->value()==0 || start<0)
1369 d1->Reset();
1370 if (d2)//fDrsCalibTrgOffset->value()==0 || start<0)
1371 d2->Reset();
1372
1373 if (!dynamic_cast<TH2*>(h))
1374 h->Reset();
1375 if (d0)
1376 d0->SetEntries(0);
1377 if (d1)
1378 d1->SetEntries(0);
1379 if (d2)
1380 d2->SetEntries(0);
1381
1382 for (int i=0; i<fEventData->Roi; i++)
1383 {
1384 // FIXME: physcial: i -> (i+start)%1024
1385 // FIXME: logical: i -> i
1386
1387 const int ii = fAdcPhysical->isChecked() ? (i+start)%1024 : i;
1388
1389 //if (dynamic_cast<TH2*>(h))
1390 h->Fill(ii, reinterpret_cast<float*>(fEventData->Adc_Data)[p*fEventData->Roi+i]);
1391 //else
1392 // h->SetBinContent(i+1, reinterpret_cast<float*>(fEventData->Adc_Data)[p*fEventData->Roi+i]);
1393 if (start<0)
1394 continue;
1395
1396 if (d0)
1397 {
1398 d0->SetBinContent(ii+1, fDrsCalibration[1440*1024*0 + p*1024+(start+i)%1024]);
1399 d0->SetBinError(ii+1, fDrsCalibration[1440*1024*1 + p*1024+(start+i)%1024]);
1400
1401 }
1402 if (d1)
1403 {
1404 d1->SetBinContent(ii+1, fDrsCalibration[1440*1024*2 + p*1024+(start+i)%1024]);
1405 d1->SetBinError(ii+1, fDrsCalibration[1440*1024*3 + p*1024+(start+i)%1024]);
1406 }
1407 if (d2)
1408 {
1409 d2->SetBinContent(ii+1, fDrsCalibration[1440*1024*4 + p*1024 + i]);
1410 d2->SetBinError(ii+1, fDrsCalibration[1440*1024*5 + p*1024 + i]);
1411 }
1412 }
1413
1414 // -----------------------------------------------------------
1415 if (fAdcDynamicScale->isEnabled() && fAdcDynamicScale->isChecked())
1416 {
1417 h->SetMinimum();
1418 h->SetMaximum();
1419
1420 hf->SetMinimum(h->GetMinimum());
1421 hf->SetMaximum(h->GetMaximum());
1422 }
1423 if (fAdcManualScale->isEnabled() && fAdcManualScale->isChecked())
1424 {
1425 if (h->GetMinimumStored()==-1111)
1426 {
1427 h->SetMinimum(-1150);//-1026);
1428 hf->SetMinimum(-1150);//-1026);
1429 }
1430 if (h->GetMaximumStored()==-1111)
1431 {
1432 h->SetMaximum(2150);//1025);
1433 hf->SetMaximum(2150);//1025);
1434 }
1435 }
1436
1437 if (fAdcAutoScale->isEnabled() && fAdcAutoScale->isChecked())
1438 {
1439 h->SetMinimum();
1440 h->SetMaximum();
1441
1442 if (h->GetMinimum()<hf->GetMinimum())
1443 hf->SetMinimum(h->GetMinimum());
1444 if (h->GetMaximum()>hf->GetMaximum())
1445 hf->SetMaximum(h->GetMaximum());
1446 }
1447
1448 if (dynamic_cast<TH2*>(h))
1449 {
1450 h->SetMinimum();
1451 h->SetMaximum();
1452 }
1453
1454 // -----------------------------------------------------------
1455
1456 const int imin = ceil(hf->GetMinimum());
1457 const int imax = floor(hf->GetMaximum());
1458
1459 TH1S hd("", "", imax-imin+1, imin-0.5, imax+0.5);
1460 hd.SetDirectory(0);
1461 TH1S h0("", "", imax-imin+1, imin-0.5, imax+0.5);
1462 h0.SetDirectory(0);
1463 TH1S h1("", "", imax-imin+1, imin-0.5, imax+0.5);
1464 h1.SetDirectory(0);
1465 TH1S h2("", "", imax-imin+1, imin-0.5, imax+0.5);
1466 h2.SetDirectory(0);
1467 hd.SetLineColor(h->GetLineColor());
1468 if (d0)
1469 h0.SetLineColor(d0->GetLineColor());
1470 if (d1)
1471 h1.SetLineColor(d1->GetLineColor());
1472 if (d2)
1473 h2.SetLineColor(d2->GetLineColor());
1474
1475 for (int i=0; i<fEventData->Roi; i++)
1476 {
1477 if (!dynamic_cast<TH2*>(h))
1478 hd.Fill(h->GetBinContent(i+1));
1479 if (d0)
1480 h0.Fill(d0->GetBinContent(i+1));
1481 if (d1)
1482 h1.Fill(d1->GetBinContent(i+1));
1483 if (d2)
1484 h2.Fill(d2->GetBinContent(i+1));
1485 }
1486
1487 double mm = hd.GetMaximum(hd.GetEntries());
1488 if (h0.GetMaximum(h0.GetEntries())>mm)
1489 mm = h0.GetMaximum();
1490 if (h1.GetMaximum(h1.GetEntries())>mm)
1491 mm = h1.GetMaximum();
1492 if (h2.GetMaximum(h2.GetEntries())>mm)
1493 mm = h2.GetMaximum();
1494
1495 TIter Next(hf->GetListOfFunctions());
1496 TObject *obj = 0;
1497 while ((obj=Next()))
1498 if (dynamic_cast<TBox*>(obj))
1499 delete hf->GetListOfFunctions()->Remove(obj);
1500
1501 const double l = h->GetBinLowEdge(h->GetXaxis()->GetLast()+1);
1502 const double m = c->GetX2();
1503
1504 const double scale = 0.9*(m-l)/mm;
1505
1506 c->cd();
1507
1508 DrawHorizontal(hf, l, h2, scale);
1509 DrawHorizontal(hf, l, h1, scale);
1510 DrawHorizontal(hf, l, h0, scale);
1511 DrawHorizontal(hf, l, hd, scale);
1512
1513 // -----------------------------------------------------------
1514
1515 c->Modified();
1516 c->Update();
1517#endif
1518 }
1519
1520 void handleFadRawData(const DimData &d)
1521 {
1522 if (d.size()==0)
1523 return;
1524
1525 if (fAdcStop->isChecked())
1526 return;
1527
1528 const EVENT &dat = d.ref<EVENT>();
1529
1530 if (d.size()<sizeof(EVENT))
1531 {
1532 cerr << "Size mismatch in " << d.name << ": Found=" << d.size() << " Expected>=" << sizeof(EVENT) << endl;
1533 return;
1534 }
1535
1536 if (d.size()!=sizeof(EVENT)+dat.Roi*4*1440)
1537 {
1538 cerr << "Size mismatch in " << d.name << ": Found=" << d.size() << " Expected=" << dat.Roi*4*1440+sizeof(EVENT) << " [roi=" << dat.Roi << "]" << endl;
1539 return;
1540 }
1541
1542 delete fEventData;
1543 fEventData = reinterpret_cast<EVENT*>(new char[d.size()]);
1544 memcpy(fEventData, d.ptr<void>(), d.size());
1545
1546 DisplayEventData();
1547 }
1548
1549 void handleFadEventData(const DimData &d)
1550 {
1551 if (!CheckSize(d, 4*1440*sizeof(float)))
1552 return;
1553
1554 const float *ptr = d.ptr<float>();
1555
1556 valarray<double> arr1(1440);
1557 valarray<double> arr2(1440);
1558 valarray<double> arr3(1440);
1559 valarray<double> arr4(1440);
1560
1561 for (vector<PixelMapEntry>::const_iterator it=fPixelMap.begin(); it!=fPixelMap.end(); it++)
1562 {
1563 arr1[it->index] = ptr[0*1440+it->hw()];
1564 arr2[it->index] = ptr[1*1440+it->hw()];
1565 arr3[it->index] = ptr[2*1440+it->hw()];
1566 arr4[it->index] = ptr[3*1440+it->hw()];
1567 }
1568
1569 fEventCanv1->SetData(arr1);
1570 fEventCanv2->SetData(arr2);
1571 fEventCanv3->SetData(arr3);
1572 fEventCanv4->SetData(arr4);
1573 }
1574
1575 vector<float> fDrsCalibration;
1576
1577 void handleFadDrsCalibration(const DimData &d)
1578 {
1579 if (d.size()==0)
1580 {
1581 fDrsCalibBaseline->setValue(0);
1582 fDrsCalibGain->setValue(0);
1583 fDrsCalibTrgOffset->setValue(0);
1584 fDrsCalibration.assign(1024*1440*6, 0);
1585 DisplayEventData();
1586 return;
1587 }
1588
1589 if (!CheckSize(d, 1024*1440*6*sizeof(float)+3*sizeof(uint32_t)))
1590 // Do WHAT?
1591 return;
1592
1593 const uint32_t *run = d.ptr<uint32_t>();
1594
1595 fDrsCalibBaseline->setValue(run[0]);
1596 fDrsCalibGain->setValue(run[1]);
1597 fDrsCalibTrgOffset->setValue(run[2]);
1598
1599 const float *dat = d.ptr<float>(sizeof(uint32_t)*3);
1600 fDrsCalibration.assign(dat, dat+1024*1440*6);
1601
1602 DisplayEventData();
1603 }
1604
1605// vector<uint8_t> fFadConnections;
1606
1607 void handleFadConnections(const DimData &d)
1608 {
1609 if (!CheckSize(d, 41))
1610 {
1611 fStatusEventBuilderLabel->setText("Offline");
1612 fStatusEventBuilderLabel->setToolTip("FADs or fadctrl seems to be offline.");
1613 fEvtBldWidget->setEnabled(false);
1614
1615 SetLedColor(fStatusEventBuilderLed, kLedGray, d.time);
1616 return;
1617 }
1618
1619 const uint8_t *ptr = d.ptr<uint8_t>();
1620
1621 for (int i=0; i<40; i++)
1622 {
1623 const uint8_t stat1 = ptr[i]&3;
1624 const uint8_t stat2 = ptr[i]>>3;
1625
1626 if (stat1==0 && stat2==0)
1627 {
1628 SetLedColor(fFadLED[i], kLedGray, d.time);
1629 continue;
1630 }
1631 if (stat1==2 && stat2==8)
1632 {
1633 SetLedColor(fFadLED[i], kLedGreen, d.time);
1634 continue;
1635 }
1636
1637 if (stat1==1 && stat2==1)
1638 SetLedColor(fFadLED[i], kLedRed, d.time);
1639 else
1640 SetLedColor(fFadLED[i], kLedOrange, d.time);
1641 }
1642
1643
1644 const bool runs = ptr[40]!=0;
1645
1646 fStatusEventBuilderLabel->setText(runs?"Running":"Not running");
1647 fStatusEventBuilderLabel->setToolTip(runs?"Event builder thread running.":"Event builder thread stopped.");
1648 fEvtBldWidget->setEnabled(runs);
1649
1650 SetLedColor(fStatusEventBuilderLed, runs?kLedGreen:kLedRed, d.time);
1651
1652// fFadConnections.assign(ptr, ptr+40);
1653 }
1654
1655 template<typename T>
1656 void handleFadToolTip(const Time &time, QWidget *w, T *ptr)
1657 {
1658 ostringstream tip;
1659 tip << "<table border='1'><tr><th colspan='11'>" << time.GetAsStr() << " (UTC)</th></tr><tr><th></th>";
1660 for (int b=0; b<10; b++)
1661 tip << "<th>" << b << "</th>";
1662 tip << "</tr>";
1663
1664 for (int c=0; c<4; c++)
1665 {
1666 tip << "<tr><th>" << c << "</th>";
1667 for (int b=0; b<10; b++)
1668 tip << "<td>" << ptr[c*10+b] << "</td>";
1669 tip << "</tr>";
1670 }
1671 tip << "</table>";
1672
1673 w->setToolTip(tip.str().c_str());
1674 }
1675
1676 template<typename T, class S>
1677 void handleFadMinMax(const DimData &d, QPushButton *led, S *wmin, S *wmax=0)
1678 {
1679 if (!CheckSize(d, 42*sizeof(T)))
1680 return;
1681
1682 const T *ptr = d.ptr<T>();
1683 const T min = ptr[40];
1684 const T max = ptr[41];
1685
1686 if (max==0 && min>max)
1687 SetLedColor(led, kLedGray, d.time);
1688 else
1689 SetLedColor(led, min==max?kLedGreen: kLedOrange, d.time);
1690
1691 if (!wmax && max!=min)
1692 wmin->setValue(0);
1693 else
1694 wmin->setValue(min);
1695
1696 if (wmax)
1697 wmax->setValue(max);
1698
1699 handleFadToolTip(d.time, led, ptr);
1700 }
1701
1702 void handleFadFwVersion(const DimData &d)
1703 {
1704 handleFadMinMax<float, QDoubleSpinBox>(d, fFadLedFwVersion, fFadFwVersion);
1705 }
1706
1707 void handleFadRunNumber(const DimData &d)
1708 {
1709 handleFadMinMax<uint32_t, QSpinBox>(d, fFadLedRunNumber, fFadRunNumber);
1710 }
1711
1712 void handleFadPrescaler(const DimData &d)
1713 {
1714 handleFadMinMax<uint16_t, QSpinBox>(d, fFadLedPrescaler, fFadPrescaler);
1715 }
1716
1717 void handleFadDNA(const DimData &d)
1718 {
1719 if (!CheckSize(d, 40*sizeof(uint64_t)))
1720 return;
1721
1722 const uint64_t *ptr = d.ptr<uint64_t>();
1723
1724 ostringstream tip;
1725 tip << "<table width='100%'>";
1726 tip << "<tr><th>Crate</th><td></td><th>Board</th><td></td><th>DNA</th></tr>";
1727
1728 for (int i=0; i<40; i++)
1729 {
1730 tip << dec;
1731 tip << "<tr>";
1732 tip << "<td align='center'>" << i/10 << "</td><td>:</td>";
1733 tip << "<td align='center'>" << i%10 << "</td><td>:</td>";
1734 tip << hex;
1735 tip << "<td>0x" << setfill('0') << setw(16) << ptr[i] << "</td>";
1736 tip << "</tr>";
1737 }
1738 tip << "</table>";
1739
1740 fFadDNA->setText(tip.str().c_str());
1741 }
1742
1743 void SetFadLed(QPushButton *led, const DimData &d, uint16_t bitmask, bool invert=false)
1744 {
1745 if (d.size()==0)
1746 {
1747 SetLedColor(led, kLedGray, d.time);
1748 return;
1749 }
1750
1751 const bool quality = d.ptr<uint16_t>()[0]&bitmask;
1752 const bool value = d.ptr<uint16_t>()[1]&bitmask;
1753 const uint16_t *ptr = d.ptr<uint16_t>()+2;
1754
1755 SetLedColor(led, quality?kLedOrange:(value^invert?kLedGreen:kLedRed), d.time);
1756
1757 ostringstream tip;
1758 tip << "<table border='1'><tr><th colspan='11'>" << d.time.GetAsStr() << " (UTC)</th></tr><tr><th></th>";
1759 for (int b=0; b<10; b++)
1760 tip << "<th>" << b << "</th>";
1761 tip << "</tr>";
1762
1763 /*
1764 tip << "<tr>" << hex;
1765 tip << "<th>" << d.ptr<uint16_t>()[0] << " " << (d.ptr<uint16_t>()[0]&bitmask) << "</th>";
1766 tip << "<th>" << d.ptr<uint16_t>()[1] << " " << (d.ptr<uint16_t>()[1]&bitmask) << "</th>";
1767 tip << "</tr>";
1768 */
1769
1770 for (int c=0; c<4; c++)
1771 {
1772 tip << "<tr><th>" << dec << c << "</th>" << hex;
1773 for (int b=0; b<10; b++)
1774 {
1775 tip << "<td>"
1776 << (ptr[c*10+b]&bitmask)
1777 << "</td>";
1778 }
1779 tip << "</tr>";
1780 }
1781 tip << "</table>";
1782
1783 led->setToolTip(tip.str().c_str());
1784 }
1785
1786 void handleFadStatus(const DimData &d)
1787 {
1788 if (d.size()!=0 && !CheckSize(d, 42*sizeof(uint16_t)))
1789 return;
1790
1791 SetFadLed(fFadLedDrsEnabled, d, FAD::EventHeader::kDenable);
1792 SetFadLed(fFadLedDrsWrite, d, FAD::EventHeader::kDwrite);
1793 SetFadLed(fFadLedDcmLocked, d, FAD::EventHeader::kDcmLocked);
1794 SetFadLed(fFadLedDcmReady, d, FAD::EventHeader::kDcmReady);
1795 SetFadLed(fFadLedSpiSclk, d, FAD::EventHeader::kSpiSclk);
1796 SetFadLed(fFadLedRefClockTooLow, d, FAD::EventHeader::kRefClkTooLow, true);
1797 SetFadLed(fFadLedBusyOn, d, FAD::EventHeader::kBusyOn);
1798 SetFadLed(fFadLedBusyOff, d, FAD::EventHeader::kBusyOff);
1799 SetFadLed(fFadLedTriggerLine, d, FAD::EventHeader::kTriggerLine);
1800 SetFadLed(fFadLedContTrigger, d, FAD::EventHeader::kContTrigger);
1801 SetFadLed(fFadLedSocket, d, FAD::EventHeader::kSock17);
1802 SetFadLed(fFadLedPllLock, d, 0xf000);
1803 }
1804
1805 void handleFadStatistics1(const DimData &d)
1806 {
1807 if (!CheckSize(d, sizeof(GUI_STAT)))
1808 return;
1809
1810 const GUI_STAT &stat = d.ref<GUI_STAT>();
1811
1812 /*
1813 //info about status of the main threads
1814 int32_t readStat ; //read thread
1815 int32_t procStat ; //processing thread(s)
1816 int32_t writStat ; //write thread
1817 */
1818
1819 fFadBufferMax->setValue(stat.totMem/1000000);
1820 fFadBuffer->setMaximum(stat.totMem/100);
1821 fFadBuffer->setValue((stat.maxMem>stat.totMem?stat.totMem:stat.maxMem)/100); // Max mem used in last second
1822
1823 uint32_t sum = 0;
1824 int32_t min = 0x7fffff;
1825 int32_t max = 0;
1826
1827 int cnt = 0;
1828 int err = 0;
1829
1830 for (int i=0; i<40; i++)
1831 {
1832 if (stat.numConn[i]!=7)
1833 continue;
1834
1835 cnt++;
1836
1837 sum += stat.rateBytes[i];
1838 err += stat.errConn[i];
1839
1840 if (stat.rateBytes[i]<min)
1841 min = stat.rateBytes[i];
1842 if (stat.rateBytes[i]>max)
1843 max = stat.rateBytes[i];
1844 }
1845
1846 fFadEvtConn->setValue(cnt);
1847 fFadEvtConnErr->setValue(err);
1848
1849 fFadEvtBufNew->setValue(stat.bufNew); // Incomplete in buffer
1850 fFadEvtBufEvt->setValue(stat.bufEvt); // Complete in buffer
1851 fFadEvtBufMax->setValue(stat.maxEvt); // Complete in buffer
1852 fFadEvtWrite->setValue(stat.evtWrite-stat.evtSkip-stat.evtErr);
1853 fFadEvtSkip->setValue(stat.evtSkip);
1854 fFadEvtErr->setValue(stat.evtErr);
1855
1856 if (stat.deltaT==0)
1857 return;
1858
1859 fFadEthernetRateMin->setValue(min/stat.deltaT);
1860 fFadEthernetRateMax->setValue(max/stat.deltaT);
1861 fFadEthernetRateTot->setValue(sum/stat.deltaT);
1862 fFadEthernetRateAvg->setValue(cnt==0 ? 0 : sum/cnt/stat.deltaT);
1863 fFadEvtRateNew->setValue(1000*stat.rateNew/stat.deltaT);
1864 fFadEvtRateWrite->setValue(1000*stat.rateWrite/stat.deltaT);
1865
1866 fFadTransmission->setValue(fFadEvtRateNew->value());
1867 fFadEthernet->setValue(fFadEthernetRateTot->value());
1868 fFadWriteRate->setValue(fFadEvtRateWrite->value());
1869 }
1870
1871 void handleFadStatistics2(const DimData &d)
1872 {
1873 if (!CheckSize(d, sizeof(EVT_STAT)))
1874 return;
1875
1876 //const EVT_STAT &stat = d.ref<EVT_STAT>();
1877
1878 /*
1879 //some info about what happened since start of program (or last 'reset')
1880 uint32_t reset ; //#if increased, reset all counters
1881 uint32_t numRead[MAX_SOCK] ; //how often succesfull read from N sockets per loop
1882
1883 uint64_t gotByte[NBOARDS] ; //#Bytes read per Board
1884 uint32_t gotErr[NBOARDS] ; //#Communication Errors per Board
1885
1886 uint32_t evtGet; //#new Start of Events read
1887 uint32_t evtTot; //#complete Events read
1888
1889 uint32_t evtErr; //#Events with Errors
1890 uint32_t evtSkp; //#Events incomplete (timeout)
1891
1892
1893 uint32_t procTot; //#Events processed
1894 uint32_t procErr; //#Events showed problem in processing
1895 uint32_t procTrg; //#Events accepted by SW trigger
1896 uint32_t procSkp; //#Events rejected by SW trigger
1897
1898 uint32_t feedTot; //#Events used for feedBack system
1899 uint32_t feedErr; //#Events rejected by feedBack
1900
1901 uint32_t wrtTot; //#Events written to disk
1902 uint32_t wrtErr; //#Events with write-error
1903
1904 uint32_t runOpen; //#Runs opened
1905 uint32_t runClose; //#Runs closed
1906 uint32_t runErr; //#Runs with open/close errors
1907
1908
1909 //info about current connection status
1910 uint8_t numConn[NBOARDS] ; //#Sockets succesfully open per board
1911 */
1912 }
1913
1914 // ===================== FTM ============================================
1915
1916 void UpdateTriggerRate(const FTM::DimTriggerRates &sdata)
1917 {
1918#ifdef HAVE_ROOT
1919 TCanvas *c = fFtmRateCanv->GetCanvas();
1920
1921 TH1 *h = (TH1*)c->FindObject("TimeFrame");
1922
1923 if (sdata.fTriggerRate<0)
1924 {
1925 fGraphFtmRate.Set(0);
1926
1927 const double tm = Time().RootTime();
1928
1929 h->SetBins(1, tm, tm+60);
1930 h->GetXaxis()->SetTimeFormat("%M'%S\"");
1931 h->GetXaxis()->SetTitle("Time");
1932
1933 c->Modified();
1934 c->Update();
1935 return;
1936 }
1937
1938 const double t1 = h->GetXaxis()->GetXmax();
1939 const double t0 = h->GetXaxis()->GetXmin();
1940
1941 const double now = t0+sdata.fTimeStamp/1000000.;
1942
1943 h->SetBins(h->GetNbinsX()+1, t0, now+1);
1944 fGraphFtmRate.SetPoint(fGraphFtmRate.GetN(), now, sdata.fTriggerRate);
1945
1946 if (t1-t0>60)
1947 {
1948 h->GetXaxis()->SetTimeFormat("%Hh%M'");
1949 h->GetXaxis()->SetTitle("Time");
1950 }
1951
1952 h->SetMinimum(0);
1953
1954 c->Modified();
1955 c->Update();
1956#endif
1957 }
1958
1959 void UpdateRatesCam(const FTM::DimTriggerRates &sdata)
1960 {
1961 if (fThresholdIdx->value()>=0)
1962 {
1963 const int isw = fThresholdIdx->value();
1964 const int ihw = fPatchMapHW[isw];
1965 fPatchRate->setValue(sdata.fPatchRate[ihw]);
1966 }
1967
1968 valarray<double> dat(0., 1440);
1969
1970 // fPatch converts from software id to software patch id
1971 for (int i=0; i<1440; i++)
1972 {
1973 const int ihw = fPatchHW[i];
1974// const int isw = fPatch[i];
1975// const int ihw = fPatchMapHW[isw];
1976 dat[i] = sdata.fPatchRate[ihw];
1977
1978 fRatesCanv->SetEnable(ihw, fFtuStatus[ihw/4]);
1979 }
1980
1981 fRatesCanv->SetData(dat);
1982 }
1983
1984 int64_t fTimeStamp0;
1985
1986 void UpdateRatesGraphs(const FTM::DimTriggerRates &sdata)
1987 {
1988#ifdef HAVE_ROOT
1989 if (fTimeStamp0<0)
1990 {
1991 fTimeStamp0 = sdata.fTimeStamp;
1992 return;
1993 }
1994
1995 TCanvas *c = fFtmRateCanv->GetCanvas();
1996
1997 TH1 *h = (TH1*)c->FindObject("TimeFrame");
1998
1999 const double tdiff = sdata.fTimeStamp-fTimeStamp0;
2000 fTimeStamp0 = sdata.fTimeStamp;
2001
2002 if (tdiff<0)
2003 {
2004 for (int i=0; i<160; i++)
2005 fGraphPatchRate[i].Set(0);
2006 for (int i=0; i<40; i++)
2007 fGraphBoardRate[i].Set(0);
2008
2009 return;
2010 }
2011
2012 //const double t1 = h->GetXaxis()->GetXmax();
2013 const double t0 = h->GetXaxis()->GetXmin();
2014
2015 for (int i=0; i<160; i++)
2016 if (fFtuStatus[i/4]>0)
2017 fGraphPatchRate[i].SetPoint(fGraphPatchRate[i].GetN(),
2018 t0+sdata.fTimeStamp/1000000., sdata.fPatchRate[i]);
2019 for (int i=0; i<40; i++)
2020 if (fFtuStatus[i]>0)
2021 fGraphBoardRate[i].SetPoint(fGraphBoardRate[i].GetN(),
2022 t0+sdata.fTimeStamp/1000000., sdata.fBoardRate[i]);
2023
2024 c->Modified();
2025 c->Update();
2026#endif
2027 }
2028
2029 void handleFtmTriggerRates(const DimData &d)
2030 {
2031 if (!CheckSize(d, sizeof(FTM::DimTriggerRates)))
2032 return;
2033
2034 const FTM::DimTriggerRates &sdata = d.ref<FTM::DimTriggerRates>();
2035
2036 fFtmTime->setText(QString::number(sdata.fTimeStamp/1000000., 'f', 6)+ " s");
2037 fTriggerCounter->setText(QString::number(sdata.fTriggerCounter));
2038
2039 if (sdata.fTimeStamp>0)
2040 fTriggerCounterRate->setValue(1000000.*sdata.fTriggerCounter/sdata.fTimeStamp);
2041 else
2042 fTriggerCounterRate->setValue(0);
2043
2044 // ----------------------------------------------
2045
2046 fOnTime->setText(QString::number(sdata.fOnTimeCounter/1000000., 'f', 6)+" s");
2047
2048 if (sdata.fTimeStamp>0)
2049 fOnTimeRel->setValue(100.*sdata.fOnTimeCounter/sdata.fTimeStamp);
2050 else
2051 fOnTimeRel->setValue(0);
2052
2053 // ----------------------------------------------
2054
2055 UpdateTriggerRate(sdata);
2056 UpdateRatesGraphs(sdata);
2057 UpdateRatesCam(sdata);
2058 }
2059
2060 void handleFtmCounter(const DimData &d)
2061 {
2062 if (!CheckSize(d, sizeof(uint32_t)*6))
2063 return;
2064
2065 const uint32_t *sdata = d.ptr<uint32_t>();
2066
2067 fFtmCounterH->setValue(sdata[0]);
2068 fFtmCounterS->setValue(sdata[1]);
2069 fFtmCounterD->setValue(sdata[2]);
2070 fFtmCounterF->setValue(sdata[3]);
2071 fFtmCounterE->setValue(sdata[4]);
2072 fFtmCounterR->setValue(sdata[5]);
2073 }
2074
2075 void handleFtmDynamicData(const DimData &d)
2076 {
2077 if (!CheckSize(d, sizeof(FTM::DimDynamicData)))
2078 return;
2079
2080 const FTM::DimDynamicData &sdata = d.ref<FTM::DimDynamicData>();
2081
2082 fFtmTemp0->setValue(sdata.fTempSensor[0]*0.1);
2083 fFtmTemp1->setValue(sdata.fTempSensor[1]*0.1);
2084 fFtmTemp2->setValue(sdata.fTempSensor[2]*0.1);
2085 fFtmTemp3->setValue(sdata.fTempSensor[3]*0.1);
2086
2087 SetLedColor(fClockCondLed, sdata.fState&FTM::kFtmLocked ? kLedGreen : kLedRed, d.time);
2088 }
2089
2090 void DisplayRates()
2091 {
2092#ifdef HAVE_ROOT
2093 TCanvas *c = fFtmRateCanv->GetCanvas();
2094
2095 while (c->FindObject("PatchRate"))
2096 c->GetListOfPrimitives()->Remove(c->FindObject("PatchRate"));
2097
2098 while (c->FindObject("BoardRate"))
2099 c->GetListOfPrimitives()->Remove(c->FindObject("BoardRate"));
2100
2101 c->cd();
2102
2103 if (fRatePatch1->value()>=0)
2104 {
2105 fGraphPatchRate[fRatePatch1->value()].SetLineColor(kRed);
2106 fGraphPatchRate[fRatePatch1->value()].SetMarkerColor(kRed);
2107 fGraphPatchRate[fRatePatch1->value()].Draw("PL");
2108 }
2109 if (fRatePatch2->value()>=0)
2110 {
2111 fGraphPatchRate[fRatePatch2->value()].SetLineColor(kGreen);
2112 fGraphPatchRate[fRatePatch2->value()].SetMarkerColor(kGreen);
2113 fGraphPatchRate[fRatePatch2->value()].Draw("PL");
2114 }
2115 if (fRateBoard1->value()>=0)
2116 {
2117 fGraphBoardRate[fRateBoard1->value()].SetLineColor(kMagenta);
2118 fGraphBoardRate[fRateBoard1->value()].SetMarkerColor(kMagenta);
2119 fGraphBoardRate[fRateBoard1->value()].Draw("PL");
2120 }
2121 if (fRateBoard2->value()>=0)
2122 {
2123 fGraphBoardRate[fRateBoard2->value()].SetLineColor(kCyan);
2124 fGraphBoardRate[fRateBoard2->value()].SetMarkerColor(kCyan);
2125 fGraphBoardRate[fRateBoard2->value()].Draw("PL");
2126 }
2127#endif
2128 }
2129
2130 FTM::DimStaticData fFtmStaticData;
2131
2132 void SetFtuLed(int idx, int counter, const Time &t)
2133 {
2134 if (counter==0 || counter>3)
2135 counter = 3;
2136
2137 if (counter<0)
2138 counter = 0;
2139
2140 const LedColor_t col[4] = { kLedGray, kLedGreen, kLedOrange, kLedRed };
2141
2142 SetLedColor(fFtuLED[idx], col[counter], t);
2143
2144 fFtuStatus[idx] = counter;
2145 }
2146
2147 void SetFtuStatusLed(const Time &t)
2148 {
2149 const int max = fFtuStatus.max();
2150
2151 switch (max)
2152 {
2153 case 0:
2154 SetLedColor(fStatusFTULed, kLedGray, t);
2155 fStatusFTULabel->setText("All disabled");
2156 fStatusFTULabel->setToolTip("All FTUs are disabled");
2157 break;
2158
2159 case 1:
2160 SetLedColor(fStatusFTULed, kLedGreen, t);
2161 fStatusFTULabel->setToolTip("Communication with FTU is smooth.");
2162 fStatusFTULabel->setText("ok");
2163 break;
2164
2165 case 2:
2166 SetLedColor(fStatusFTULed, kLedOrange, t);
2167 fStatusFTULabel->setText("Warning");
2168 fStatusFTULabel->setToolTip("At least one FTU didn't answer immediately");
2169 break;
2170
2171 case 3:
2172 SetLedColor(fStatusFTULed, kLedRed, t);
2173 fStatusFTULabel->setToolTip("At least one FTU didn't answer!");
2174 fStatusFTULabel->setText("ERROR");
2175 break;
2176 }
2177
2178 const int cnt = count(&fFtuStatus[0], &fFtuStatus[40], 0);
2179 fFtuAllOn->setEnabled(cnt!=0);
2180 fFtuAllOff->setEnabled(cnt!=40);
2181 }
2182
2183 void handleFtmStaticData(const DimData &d)
2184 {
2185 if (!CheckSize(d, sizeof(FTM::DimStaticData)))
2186 return;
2187
2188 const FTM::DimStaticData &sdata = d.ref<FTM::DimStaticData>();
2189
2190 fTriggerInterval->setValue(sdata.fTriggerInterval);
2191 fPhysicsCoincidence->setValue(sdata.fMultiplicityPhysics);
2192 fCalibCoincidence->setValue(sdata.fMultiplicityCalib);
2193 fPhysicsWindow->setValue(sdata.fWindowPhysics);
2194 fCalibWindow->setValue(sdata.fWindowCalib);
2195
2196 fTriggerDelay->setValue(sdata.fDelayTrigger);
2197 fTimeMarkerDelay->setValue(sdata.fDelayTimeMarker);
2198 fDeadTime->setValue(sdata.fDeadTime);
2199
2200 fClockCondR0->setValue(sdata.fClockConditioner[0]);
2201 fClockCondR1->setValue(sdata.fClockConditioner[1]);
2202 fClockCondR8->setValue(sdata.fClockConditioner[2]);
2203 fClockCondR9->setValue(sdata.fClockConditioner[3]);
2204 fClockCondR11->setValue(sdata.fClockConditioner[4]);
2205 fClockCondR13->setValue(sdata.fClockConditioner[5]);
2206 fClockCondR14->setValue(sdata.fClockConditioner[6]);
2207 fClockCondR15->setValue(sdata.fClockConditioner[7]);
2208
2209 const uint32_t R0 = sdata.fClockConditioner[0];
2210 const uint32_t R14 = sdata.fClockConditioner[6];
2211 const uint32_t R15 = sdata.fClockConditioner[7];
2212
2213 const uint32_t Ndiv = (R15&0x1ffff00)<<2;
2214 const uint32_t Rdiv = (R14&0x007ff00)>>8;
2215 const uint32_t Cdiv = (R0 &0x000ff00)>>8;
2216
2217 double freq = 40.*Ndiv/(Rdiv*Cdiv);
2218
2219 fClockCondFreqRes->setValue(freq);
2220
2221 //fClockCondFreq->setEditText("");
2222 fClockCondFreq->setCurrentIndex(0);
2223
2224 fTriggerSeqPed->setValue(sdata.fTriggerSeqPed);
2225 fTriggerSeqLPint->setValue(sdata.fTriggerSeqLPint);
2226 fTriggerSeqLPext->setValue(sdata.fTriggerSeqLPext);
2227
2228 fLpIntIntensity->setValue(sdata.fIntensityLPint);
2229 fLpExtIntensity->setValue(sdata.fIntensityLPext);
2230
2231 fLpIntGroup1->setChecked(sdata.HasLPintG1());
2232 fLpIntGroup2->setChecked(sdata.HasLPintG2());
2233 fLpExtGroup1->setChecked(sdata.HasLPextG1());
2234 fLpExtGroup2->setChecked(sdata.HasLPextG2());
2235
2236 fEnableTrigger->setChecked(sdata.HasTrigger());
2237 fEnableVeto->setChecked(sdata.HasVeto());
2238 fEnableExt1->setChecked(sdata.HasExt1());
2239 fEnableExt2->setChecked(sdata.HasExt2());
2240 fEnableClockCond->setChecked(sdata.HasClockConditioner());
2241
2242 for (int i=0; i<40; i++)
2243 {
2244 if (!sdata.IsActive(i))
2245 SetFtuLed(i, -1, d.time);
2246 else
2247 {
2248 if (fFtuStatus[i]==0)
2249 SetFtuLed(i, 1, d.time);
2250 }
2251 fFtuLED[i]->setChecked(false);
2252 }
2253 SetFtuStatusLed(d.time);
2254
2255 for (vector<PixelMapEntry>::const_iterator it=fPixelMap.begin(); it!=fPixelMap.end(); it++)
2256 fRatesCanv->SetEnable(it->index, sdata.IsEnabled(it->hw()));
2257
2258 const PixelMapEntry &entry = fPixelMap.index(fPixelIdx->value());
2259 fPixelEnable->setChecked(sdata.IsEnabled(entry.index));
2260
2261 if (fThresholdIdx->value()>=0)
2262 {
2263 const int isw = fThresholdIdx->value();
2264 const int ihw = fPatchMapHW[isw];
2265 fThresholdVal->setValue(sdata.fThreshold[ihw]);
2266 }
2267
2268 fPrescalingVal->setValue(sdata.fPrescaling[0]);
2269
2270 fFtmStaticData = sdata;
2271 }
2272
2273 void handleFtmPassport(const DimData &d)
2274 {
2275 if (!CheckSize(d, sizeof(FTM::DimPassport)))
2276 return;
2277
2278 const FTM::DimPassport &sdata = d.ref<FTM::DimPassport>();
2279
2280 stringstream str1, str2;
2281 str1 << hex << "0x" << setfill('0') << setw(16) << sdata.fBoardId;
2282 str2 << sdata.fFirmwareId;
2283
2284 fFtmBoardId->setText(str1.str().c_str());
2285 fFtmFirmwareId->setText(str2.str().c_str());
2286 }
2287
2288 void handleFtmFtuList(const DimData &d)
2289 {
2290 if (!CheckSize(d, sizeof(FTM::DimFtuList)))
2291 return;
2292
2293 fFtuPing->setChecked(false);
2294
2295 const FTM::DimFtuList &sdata = d.ref<FTM::DimFtuList>();
2296
2297 stringstream str;
2298 str << "<table width='100%'>" << setfill('0');
2299 str << "<tr><th>Num</th><th></th><th>Addr</th><th></th><th>DNA</th></tr>";
2300 for (int i=0; i<40; i++)
2301 {
2302 str << "<tr>";
2303 str << "<td align='center'>" << dec << i << hex << "</td>";
2304 str << "<td align='center'>:</td>";
2305 str << "<td align='center'>0x" << setw(2) << (int)sdata.fAddr[i] << "</td>";
2306 str << "<td align='center'>:</td>";
2307 str << "<td align='center'>0x" << setw(16) << sdata.fDNA[i] << "</td>";
2308 str << "</tr>";
2309 }
2310 str << "</table>";
2311
2312 fFtuDNA->setText(str.str().c_str());
2313
2314 fFtuAnswersTotal->setValue(sdata.fNumBoards);
2315 fFtuAnswersCrate0->setValue(sdata.fNumBoardsCrate[0]);
2316 fFtuAnswersCrate1->setValue(sdata.fNumBoardsCrate[1]);
2317 fFtuAnswersCrate2->setValue(sdata.fNumBoardsCrate[2]);
2318 fFtuAnswersCrate3->setValue(sdata.fNumBoardsCrate[3]);
2319
2320 for (int i=0; i<40; i++)
2321 SetFtuLed(i, sdata.IsActive(i) ? sdata.fPing[i] : -1, d.time);
2322
2323 SetFtuStatusLed(d.time);
2324 }
2325
2326 void handleFtmError(const DimData &d)
2327 {
2328 if (!CheckSize(d, sizeof(FTM::DimError)))
2329 return;
2330
2331 const FTM::DimError &sdata = d.ref<FTM::DimError>();
2332
2333 SetFtuLed(sdata.fError.fDestAddress, sdata.fError.fNumCalls, d.time);
2334 SetFtuStatusLed(d.time);
2335
2336 // FIXME: Write to special window!
2337 //Out() << "Error:" << endl;
2338 //Out() << sdata.fError << endl;
2339 }
2340
2341 // ========================== FSC =======================================
2342
2343 void SetFscValue(QDoubleSpinBox *box, const DimData &d, int idx, bool enable)
2344 {
2345 box->setEnabled(enable);
2346 if (!enable)
2347 {
2348 box->setToolTip(d.time.GetAsStr().c_str());
2349 return;
2350 }
2351
2352 ostringstream str;
2353 str << d.time << " -- " << d.get<float>() << "s";
2354
2355 box->setToolTip(str.str().c_str());
2356 box->setValue(d.get<float>(idx*4+4));
2357 }
2358
2359
2360 void handleFscTemp(const DimData &d)
2361 {
2362 const bool enable = d.size()>0 && CheckSize(d, 60*sizeof(float));
2363
2364 QDoubleSpinBox *boxes[] = {
2365 fTempCam00, fTempCam01,
2366 fTempCam10, fTempCam11, fTempCam12, fTempCam13, fTempCam14,
2367 fTempCam20, fTempCam21, fTempCam22, fTempCam23, fTempCam24, fTempCam25,
2368 fTempCam30, fTempCam31, fTempCam32, fTempCam33, fTempCam34,
2369 fTempCam40, fTempCam41, fTempCam42, fTempCam43, fTempCam44, fTempCam45,
2370 fTempCam50, fTempCam51, fTempCam52, fTempCam53, fTempCam54,
2371 fTempCam60, fTempCam61,
2372 fTempCrate00, fTempCrate01, fTempCrate10, fTempCrate11,
2373 fTempCrate20, fTempCrate21, fTempCrate30, fTempCrate31,
2374 fTempPS00, fTempPS01, fTempPS10, fTempPS11,
2375 fTempPS20, fTempPS21, fTempPS30, fTempPS31,
2376 fTempAux0a, fTempAux0b, fTempAux1a, fTempAux1b,
2377 fTempBackpanel0a, fTempBackpanel0b, fTempBackpanel1a, fTempBackpanel1b,
2378 fTempSwitchbox0a, fTempSwitchbox0b, fTempSwitchbox1a, fTempSwitchbox1b,
2379 };
2380
2381 for (int i=0; i<59; i++)
2382 SetFscValue(boxes[i], d, i, enable);
2383 }
2384
2385 void handleFscVolt(const DimData &d)
2386 {
2387 const bool enable = d.size()>0 && CheckSize(d, 31*sizeof(float));
2388
2389 QDoubleSpinBox *boxes[] = {
2390 fVoltFad00, fVoltFad10, fVoltFad20, fVoltFad30,
2391 fVoltFad01, fVoltFad11, fVoltFad21, fVoltFad31,
2392 fVoltFad02, fVoltFad12, fVoltFad22, fVoltFad32,
2393 fVoltFPA00, fVoltFPA10, fVoltFPA20, fVoltFPA30,
2394 fVoltFPA01, fVoltFPA11, fVoltFPA21, fVoltFPA31,
2395 fVoltFPA02, fVoltFPA12, fVoltFPA22, fVoltFPA32,
2396 fVoltETH0, fVoltETH1,
2397 fVoltFTM0, fVoltFTM1,
2398 fVoltFFC, fVoltFLP,
2399 };
2400
2401 for (int i=0; i<30; i++)
2402 SetFscValue(boxes[i], d, i, enable);
2403 }
2404
2405 void handleFscCurrent(const DimData &d)
2406 {
2407 const bool enable = d.size()>0 && CheckSize(d, 31*sizeof(float));
2408
2409 QDoubleSpinBox *boxes[] = {
2410 fAmpFad00, fAmpFad10, fAmpFad20, fAmpFad30,
2411 fAmpFad01, fAmpFad11, fAmpFad21, fAmpFad31,
2412 fAmpFad02, fAmpFad12, fAmpFad22, fAmpFad32,
2413 fAmpFPA00, fAmpFPA10, fAmpFPA20, fAmpFPA30,
2414 fAmpFPA01, fAmpFPA11, fAmpFPA21, fAmpFPA31,
2415 fAmpFPA02, fAmpFPA12, fAmpFPA22, fAmpFPA32,
2416 fAmpETH0, fAmpETH1,
2417 fAmpFTM0, fAmpFTM1,
2418 fAmpFFC, fAmpFLP,
2419 };
2420
2421 for (int i=0; i<30; i++)
2422 SetFscValue(boxes[i], d, i, enable);
2423 }
2424
2425 void handleFscHumidity(const DimData &d)
2426 {
2427 const bool enable = d.size()>0 && CheckSize(d, 5*sizeof(float));
2428
2429 SetFscValue(fHumidity1, d, 0, enable);
2430 SetFscValue(fHumidity2, d, 1, enable);
2431 SetFscValue(fHumidity3, d, 2, enable);
2432 SetFscValue(fHumidity4, d, 3, enable);
2433 }
2434
2435 // ========================== FSC =======================================
2436
2437 vector<int16_t> fVecBiasVolt;
2438 vector<int16_t> fVecBiasCurrent;
2439
2440 void handleBiasVolt(const DimData &d)
2441 {
2442 if (!CheckSize(d, 2*416*sizeof(int16_t)))
2443 return;
2444
2445 const int16_t *ptr = d.ptr<int16_t>();
2446
2447 fVecBiasVolt.assign(ptr, ptr+2*416);
2448
2449 on_fBiasDispRefVolt_stateChanged();
2450 UpdateBiasValues();
2451 }
2452
2453 void handleBiasCurrent(const DimData &d)
2454 {
2455 if (!CheckSize(d, 416*sizeof(int16_t)))
2456 return;
2457
2458 const int16_t *ptr = d.ptr<int16_t>();
2459
2460 fVecBiasCurrent.assign(ptr, ptr+416);
2461
2462 valarray<double> dat(0., 1440);
2463
2464 // fPatch converts from software id to software patch id
2465 for (int i=0; i<1440; i++)
2466 {
2467 const PixelMapEntry &entry = fPixelMap.index(i);
2468
2469 // FIXME: Display Overcurrent
2470 dat[i] = abs(ptr[entry.hv()])*5000./4096;
2471
2472 fBiasCamA->SetEnable(i, uint16_t(ptr[entry.hv()])!=0x8000);
2473 fBiasCamA->highlightPixel(i, ptr[entry.hv()]<0);
2474 }
2475
2476 fBiasCamA->SetData(dat);
2477 fBiasCamA->updateGL();
2478
2479 UpdateBiasValues();
2480 }
2481
2482 // ====================== MessageImp ====================================
2483
2484 bool fChatOnline;
2485
2486 void handleStateChanged(const Time &time, const std::string &server,
2487 const State &s)
2488 {
2489 // FIXME: Prefix tooltip with time
2490 if (server=="FTM_CONTROL")
2491 {
2492 // FIXME: Enable FTU page!!!
2493 fStatusFTMLabel->setText(s.name.c_str());
2494 fStatusFTMLabel->setToolTip(s.comment.c_str());
2495
2496 bool enable = false;
2497
2498 if (s.index<FTM::StateMachine::kDisconnected) // No Dim connection
2499 SetLedColor(fStatusFTMLed, kLedGray, time);
2500 if (s.index==FTM::StateMachine::kDisconnected) // Dim connection / FTM disconnected
2501 SetLedColor(fStatusFTMLed, kLedYellow, time);
2502 if (s.index==FTM::StateMachine::kConnected ||
2503 s.index==FTM::StateMachine::kIdle ||
2504 s.index==FTM::StateMachine::kConfiguring1 ||
2505 s.index==FTM::StateMachine::kConfiguring2 ||
2506 s.index==FTM::StateMachine::kConfigured ||
2507 s.index==FTM::StateMachine::kTakingData) // Dim connection / FTM connected
2508 SetLedColor(fStatusFTMLed, kLedGreen, time);
2509
2510 if (s.index==FTM::StateMachine::kConnected ||
2511 s.index==FTM::StateMachine::kIdle) // Dim connection / FTM connected
2512 enable = true;
2513
2514 fTriggerWidget->setEnabled(enable);
2515 fFtuGroupEnable->setEnabled(enable);
2516 fRatesControls->setEnabled(enable);
2517 fFtuWidget->setEnabled(s.index>FTM::StateMachine::kDisconnected);
2518
2519 if (s.index>=FTM::StateMachine::kConnected)
2520 SetFtuStatusLed(time);
2521 else
2522 {
2523 SetLedColor(fStatusFTULed, kLedGray, time);
2524 fStatusFTULabel->setText("Offline");
2525 fStatusFTULabel->setToolTip("FTM is not online.");
2526 }
2527 }
2528
2529 if (server=="FAD_CONTROL")
2530 {
2531 fStatusFADLabel->setText(s.name.c_str());
2532 fStatusFADLabel->setToolTip(s.comment.c_str());
2533
2534 bool enable = false;
2535
2536 if (s.index<FAD::kOffline) // No Dim connection
2537 {
2538 SetLedColor(fStatusFADLed, kLedGray, time);
2539
2540 // Timing problem - sometimes they stay gray :(
2541 //for (int i=0; i<40; i++)
2542 // SetLedColor(fFadLED[i], kLedGray, time);
2543
2544 /*
2545 fStatusEventBuilderLabel->setText("Offline");
2546 fStatusEventBuilderLabel->setToolTip("No connection to fadctrl.");
2547 fEvtBldWidget->setEnabled(false);
2548
2549 SetLedColor(fStatusEventBuilderLed, kLedGray, time);
2550 */
2551 }
2552 if (s.index==FAD::kOffline) // Dim connection / FTM disconnected
2553 SetLedColor(fStatusFADLed, kLedRed, time);
2554 if (s.index==FAD::kDisconnected) // Dim connection / FTM disconnected
2555 SetLedColor(fStatusFADLed, kLedOrange, time);
2556 if (s.index==FAD::kConnecting) // Dim connection / FTM disconnected
2557 {
2558 SetLedColor(fStatusFADLed, kLedYellow, time);
2559 // FIXME FIXME FIXME: The LEDs are not displayed when disabled!
2560 enable = true;
2561 }
2562 if (s.index>=FAD::kConnected) // Dim connection / FTM connected
2563 {
2564 SetLedColor(fStatusFADLed, kLedGreen, time);
2565 enable = true;
2566 }
2567
2568 fFadWidget->setEnabled(enable);
2569 }
2570
2571 if (server=="FSC_CONTROL")
2572 {
2573 fStatusFSCLabel->setText(s.name.c_str());
2574 fStatusFSCLabel->setToolTip(s.comment.c_str());
2575
2576 bool enable = false;
2577
2578 if (s.index<1) // No Dim connection
2579 SetLedColor(fStatusFSCLed, kLedGray, time);
2580 if (s.index==1) // Dim connection / FTM disconnected
2581 SetLedColor(fStatusFSCLed, kLedRed, time);
2582 if (s.index>=2) // Dim connection / FTM disconnected
2583 {
2584 SetLedColor(fStatusFSCLed, kLedGreen, time);
2585 enable = true;
2586 }
2587
2588 fAuxWidget->setEnabled(enable);
2589 }
2590
2591 if (server=="BIAS_CONTROL")
2592 {
2593 fStatusBiasLabel->setText(s.name.c_str());
2594 fStatusBiasLabel->setToolTip(s.comment.c_str());
2595
2596 if (s.index<1) // No Dim connection
2597 SetLedColor(fStatusBiasLed, kLedGray, time);
2598 if (s.index==BIAS::kDisconnected) // Dim connection / FTM disconnected
2599 SetLedColor(fStatusBiasLed, kLedRed, time);
2600 if (s.index==BIAS::kConnecting || s.index==BIAS::kInitializing) // Connecting / Initializing
2601 SetLedColor(fStatusBiasLed, kLedOrange, time);
2602 if (s.index==BIAS::kConnected) // Connected
2603 SetLedColor(fStatusBiasLed, kLedYellow, time);
2604 if (s.index==BIAS::kRamping) // Ramping
2605 SetLedColor(fStatusBiasLed, kLedInProgress, time);
2606 if (s.index==BIAS::kOverCurrent) // Over current
2607 SetLedColor(fStatusBiasLed, kLedWarnBorder, time);
2608 if (s.index==BIAS::kAtReference) // At reference
2609 SetLedColor(fStatusBiasLed, kLedGreen, time);
2610 if (s.index==BIAS::kExpertMode) // ExpertMode
2611 SetLedColor(fStatusBiasLed, kLedWarnTriangleBorder, time);
2612
2613 fBiasWidget->setEnabled(s.index>=3);
2614 }
2615
2616 if (server=="DATA_LOGGER")
2617 {
2618 fStatusLoggerLabel->setText(s.name.c_str());
2619 fStatusLoggerLabel->setToolTip(s.comment.c_str());
2620
2621 bool enable = true;
2622
2623 if (s.index<=30) // Ready/Waiting
2624 SetLedColor(fStatusLoggerLed, kLedYellow, time);
2625 if (s.index<-1) // Offline
2626 {
2627 SetLedColor(fStatusLoggerLed, kLedGray, time);
2628 enable = false;
2629 }
2630 if (s.index>=0x100) // Error
2631 SetLedColor(fStatusLoggerLed, kLedRed, time);
2632 if (s.index==40) // Logging
2633 SetLedColor(fStatusLoggerLed, kLedGreen, time);
2634
2635 fLoggerWidget->setEnabled(enable);
2636 }
2637
2638 if (server=="CHAT")
2639 {
2640 fStatusChatLabel->setText(s.name.c_str());
2641
2642 fChatOnline = s.index==0;
2643
2644 SetLedColor(fStatusChatLed, fChatOnline ? kLedGreen : kLedGray, time);
2645
2646 fChatSend->setEnabled(fChatOnline);
2647 fChatMessage->setEnabled(fChatOnline);
2648 }
2649
2650 if (server=="SCHEDULER")
2651 {
2652 fStatusSchedulerLabel->setText(s.name.c_str());
2653
2654 SetLedColor(fStatusSchedulerLed, s.index>=0 ? kLedGreen : kLedRed, time);
2655 }
2656 }
2657
2658 void on_fTabWidget_currentChanged(int which)
2659 {
2660 if (fTabWidget->tabText(which)=="Chat")
2661 fTabWidget->setTabIcon(which, QIcon());
2662 }
2663
2664 void handleWrite(const Time &time, const string &text, int qos)
2665 {
2666 stringstream out;
2667
2668 if (text.substr(0, 6)=="CHAT: ")
2669 {
2670 if (qos==MessageImp::kDebug)
2671 return;
2672
2673 out << "<font size='-1' color='navy'>[<B>";
2674 out << time.GetAsStr("%H:%M:%S");
2675 out << "</B>]</FONT> " << text.substr(6);
2676 fChatText->append(out.str().c_str());
2677
2678 if (fTabWidget->tabText(fTabWidget->currentIndex())=="Chat")
2679 return;
2680
2681 static int num = 0;
2682 if (num++<2)
2683 return;
2684
2685 for (int i=0; i<fTabWidget->count(); i++)
2686 if (fTabWidget->tabText(i)=="Chat")
2687 {
2688 fTabWidget->setTabIcon(i, QIcon(":/Resources/icons/warning 3.png"));
2689 break;
2690 }
2691
2692 return;
2693 }
2694
2695
2696 out << "<font style='font-family:monospace' color='";
2697
2698 switch (qos)
2699 {
2700 case kMessage: out << "black"; break;
2701 case kInfo: out << "green"; break;
2702 case kWarn: out << "#FF6600"; break;
2703 case kError: out << "maroon"; break;
2704 case kFatal: out << "maroon"; break;
2705 case kDebug: out << "navy"; break;
2706 default: out << "navy"; break;
2707 }
2708 out << "'>";
2709 out << time.GetAsStr("%H:%M:%S.%f").substr(0,12);
2710 out << " - " << text << "</font>";
2711
2712 fLogText->append(out.str().c_str());
2713
2714 if (qos>=kWarn && qos!=kDebug)
2715 fTextEdit->append(out.str().c_str());
2716 }
2717
2718 void IndicateStateChange(const Time &time, const std::string &server)
2719 {
2720 const State s = GetState(server, GetCurrentState(server));
2721
2722 QApplication::postEvent(this,
2723 new FunctionEvent(boost::bind(&FactGui::handleStateChanged, this, time, server, s)));
2724 }
2725
2726 int Write(const Time &time, const string &txt, int qos)
2727 {
2728 QApplication::postEvent(this,
2729 new FunctionEvent(boost::bind(&FactGui::handleWrite, this, time, txt, qos)));
2730
2731 return 0;
2732 }
2733
2734 // ====================== Dim infoHandler================================
2735
2736 void handleDimService(const string &txt)
2737 {
2738 fDimSvcText->append(txt.c_str());
2739 }
2740
2741 void infoHandlerService(DimInfo &info)
2742 {
2743 const string fmt = string(info.getFormat()).empty() ? "C" : info.getFormat();
2744
2745 stringstream dummy;
2746 const Converter conv(dummy, fmt, false);
2747
2748 const Time tm(info.getTimestamp(), info.getTimestampMillisecs()*1000);
2749
2750 stringstream out;
2751 out << "<font size'-1' color='navy'>[";
2752 out << tm.GetAsStr("%H:%M:%S.%f").substr(0,12);
2753 out << "]</font> <B>" << info.getName() << "</B> - ";
2754
2755 bool iserr = true;
2756 if (!conv)
2757 {
2758 out << "Compilation of format string '" << fmt << "' failed!";
2759 }
2760 else
2761 {
2762 try
2763 {
2764 const string dat = conv.GetString(info.getData(), info.getSize());
2765 out << dat;
2766 iserr = false;
2767 }
2768 catch (const runtime_error &e)
2769 {
2770 out << "Conversion to string failed!<pre>" << e.what() << "</pre>";
2771 }
2772 }
2773
2774 // srand(hash<string>()(string(info.getName())));
2775 // int bg = rand()&0xffffff;
2776
2777 int bg = hash<string>()(string(info.getName()));
2778
2779 // allow only light colors
2780 bg = ~(bg&0x1f1f1f)&0xffffff;
2781
2782 if (iserr)
2783 bg = 0xffffff;
2784
2785 stringstream bgcol;
2786 bgcol << hex << setfill('0') << setw(6) << bg;
2787
2788 const string col = iserr ? "red" : "black";
2789 const string str = "<table width='100%' bgcolor=#"+bgcol.str()+"><tr><td><font color='"+col+"'>"+out.str()+"</font></td></tr></table>";
2790
2791 QApplication::postEvent(this,
2792 new FunctionEvent(boost::bind(&FactGui::handleDimService, this, str)));
2793 }
2794
2795 void CallInfoHandler(void (FactGui::*handler)(const DimData&), const DimData &d)
2796 {
2797 fInHandler = true;
2798 (this->*handler)(d);
2799 fInHandler = false;
2800 }
2801
2802 /*
2803 void CallInfoHandler(const boost::function<void()> &func)
2804 {
2805 // This ensures that newly received values are not sent back to the emitter
2806 // because changing the value emits the valueChanged signal (or similar)
2807 fInHandler = true;
2808 func();
2809 fInHandler = false;
2810 }*/
2811
2812 void PostInfoHandler(void (FactGui::*handler)(const DimData&))
2813 {
2814 //const boost::function<void()> f = boost::bind(handler, this, DimData(getInfo()));
2815
2816 FunctionEvent *evt = new FunctionEvent(boost::bind(&FactGui::CallInfoHandler, this, handler, DimData(getInfo())));
2817 // FunctionEvent *evt = new FunctionEvent(boost::bind(&FactGui::CallInfoHandler, this, f));
2818 // FunctionEvent *evt = new FunctionEvent(boost::bind(handler, this, DimData(getInfo()))));
2819
2820 QApplication::postEvent(this, evt);
2821 }
2822
2823 void infoHandler()
2824 {
2825 // Initialize the time-stamp (what a weird workaround...)
2826 if (getInfo())
2827 getInfo()->getTimestamp();
2828
2829 if (getInfo()==&fDimDNS)
2830 return PostInfoHandler(&FactGui::handleDimDNS);
2831#ifdef DEBUG_DIM
2832 cout << "HandleDimInfo " << getInfo()->getName() << endl;
2833#endif
2834 if (getInfo()==&fDimLoggerStats)
2835 return PostInfoHandler(&FactGui::handleLoggerStats);
2836
2837// if (getInfo()==&fDimFadFiles)
2838// return PostInfoHandler(&FactGui::handleFadFiles);
2839
2840 if (getInfo()==&fDimFadWriteStats)
2841 return PostInfoHandler(&FactGui::handleFadWriteStats);
2842
2843 if (getInfo()==&fDimFadConnections)
2844 return PostInfoHandler(&FactGui::handleFadConnections);
2845
2846 if (getInfo()==&fDimFadFwVersion)
2847 return PostInfoHandler(&FactGui::handleFadFwVersion);
2848
2849 if (getInfo()==&fDimFadRunNumber)
2850 return PostInfoHandler(&FactGui::handleFadRunNumber);
2851
2852 if (getInfo()==&fDimFadDNA)
2853 return PostInfoHandler(&FactGui::handleFadDNA);
2854
2855 if (getInfo()==&fDimFadTemperature)
2856 return PostInfoHandler(&FactGui::handleFadTemperature);
2857
2858 if (getInfo()==&fDimFadRefClock)
2859 return PostInfoHandler(&FactGui::handleFadRefClock);
2860
2861 if (getInfo()==&fDimFadRoi)
2862 return PostInfoHandler(&FactGui::handleFadRoi);
2863
2864 if (getInfo()==&fDimFadDac)
2865 return PostInfoHandler(&FactGui::handleFadDac);
2866
2867 if (getInfo()==&fDimFadDrsCalibration)
2868 return PostInfoHandler(&FactGui::handleFadDrsCalibration);
2869
2870 if (getInfo()==&fDimFadPrescaler)
2871 return PostInfoHandler(&FactGui::handleFadPrescaler);
2872
2873 if (getInfo()==&fDimFadStatus)
2874 return PostInfoHandler(&FactGui::handleFadStatus);
2875
2876 if (getInfo()==&fDimFadStatistics1)
2877 return PostInfoHandler(&FactGui::handleFadStatistics1);
2878
2879 if (getInfo()==&fDimFadStatistics2)
2880 return PostInfoHandler(&FactGui::handleFadStatistics2);
2881
2882 if (getInfo()==&fDimFadEvents)
2883 return PostInfoHandler(&FactGui::handleFadEvents);
2884
2885 if (getInfo()==&fDimFadRuns)
2886 return PostInfoHandler(&FactGui::handleFadRuns);
2887
2888 if (getInfo()==&fDimFadStartRun)
2889 return PostInfoHandler(&FactGui::handleFadStartRun);
2890
2891 if (getInfo()==&fDimFadRawData)
2892 return PostInfoHandler(&FactGui::handleFadRawData);
2893
2894 if (getInfo()==&fDimFadEventData)
2895 return PostInfoHandler(&FactGui::handleFadEventData);
2896
2897/*
2898 if (getInfo()==&fDimFadSetup)
2899 return PostInfoHandler(&FactGui::handleFadSetup);
2900*/
2901 if (getInfo()==&fDimLoggerFilenameNight)
2902 return PostInfoHandler(&FactGui::handleLoggerFilenameNight);
2903
2904 if (getInfo()==&fDimLoggerNumSubs)
2905 return PostInfoHandler(&FactGui::handleLoggerNumSubs);
2906
2907 if (getInfo()==&fDimLoggerFilenameRun)
2908 return PostInfoHandler(&FactGui::handleLoggerFilenameRun);
2909
2910 if (getInfo()==&fDimFtmTriggerRates)
2911 return PostInfoHandler(&FactGui::handleFtmTriggerRates);
2912
2913 if (getInfo()==&fDimFtmCounter)
2914 return PostInfoHandler(&FactGui::handleFtmCounter);
2915
2916 if (getInfo()==&fDimFtmDynamicData)
2917 return PostInfoHandler(&FactGui::handleFtmDynamicData);
2918
2919 if (getInfo()==&fDimFtmPassport)
2920 return PostInfoHandler(&FactGui::handleFtmPassport);
2921
2922 if (getInfo()==&fDimFtmFtuList)
2923 return PostInfoHandler(&FactGui::handleFtmFtuList);
2924
2925 if (getInfo()==&fDimFtmStaticData)
2926 return PostInfoHandler(&FactGui::handleFtmStaticData);
2927
2928 if (getInfo()==&fDimFtmError)
2929 return PostInfoHandler(&FactGui::handleFtmError);
2930
2931 if (getInfo()==&fDimFscTemp)
2932 return PostInfoHandler(&FactGui::handleFscTemp);
2933
2934 if (getInfo()==&fDimFscVolt)
2935 return PostInfoHandler(&FactGui::handleFscVolt);
2936
2937 if (getInfo()==&fDimFscCurrent)
2938 return PostInfoHandler(&FactGui::handleFscCurrent);
2939
2940 if (getInfo()==&fDimFscHumidity)
2941 return PostInfoHandler(&FactGui::handleFscHumidity);
2942
2943 if (getInfo()==&fDimBiasVolt)
2944 return PostInfoHandler(&FactGui::handleBiasVolt);
2945
2946 if (getInfo()==&fDimBiasCurrent)
2947 return PostInfoHandler(&FactGui::handleBiasCurrent);
2948
2949// if (getInfo()==&fDimFadFiles)
2950// return PostInfoHandler(&FactGui::handleFadFiles);
2951
2952 for (map<string,DimInfo*>::iterator i=fServices.begin(); i!=fServices.end(); i++)
2953 if (i->second==getInfo())
2954 {
2955 infoHandlerService(*i->second);
2956 return;
2957 }
2958
2959 DimNetwork::infoHandler();
2960 }
2961
2962
2963 // ======================================================================
2964
2965 bool event(QEvent *evt)
2966 {
2967 if (dynamic_cast<FunctionEvent*>(evt))
2968 return static_cast<FunctionEvent*>(evt)->Exec();
2969
2970 if (dynamic_cast<CheckBoxEvent*>(evt))
2971 {
2972 const QStandardItem &item = static_cast<CheckBoxEvent*>(evt)->item;
2973 const QStandardItem *par = item.parent();
2974 if (par)
2975 {
2976 const QString server = par->text();
2977 const QString service = item.text();
2978
2979 const string s = (server+'/'+service).toStdString();
2980
2981 if (item.checkState()==Qt::Checked)
2982 SubscribeService(s);
2983 else
2984 UnsubscribeService(s);
2985 }
2986 }
2987
2988 return MainWindow::event(evt); // unrecognized
2989 }
2990
2991 void on_fDimCmdSend_clicked()
2992 {
2993 const QString server = fDimCmdServers->currentIndex().data().toString();
2994 const QString command = fDimCmdCommands->currentIndex().data().toString();
2995 const QString arguments = fDimCmdLineEdit->displayText();
2996
2997 // FIXME: Sending a command exactly when the info Handler changes
2998 // the list it might lead to confusion.
2999 try
3000 {
3001 SendDimCommand(server.toStdString(), command.toStdString()+" "+arguments.toStdString());
3002 fTextEdit->append("<font color='green'>Command '"+server+'/'+command+"' successfully emitted.</font>");
3003 fDimCmdLineEdit->clear();
3004 }
3005 catch (const runtime_error &e)
3006 {
3007 stringstream txt;
3008 txt << e.what();
3009
3010 string buffer;
3011 while (getline(txt, buffer, '\n'))
3012 fTextEdit->append(("<font color='red'><pre>"+buffer+"</pre></font>").c_str());
3013 }
3014 }
3015
3016#ifdef HAVE_ROOT
3017 void slot_RootEventProcessed(TObject *obj, unsigned int evt, TCanvas *canv)
3018 {
3019 // kMousePressEvent // TCanvas processed QEvent mousePressEvent
3020 // kMouseMoveEvent // TCanvas processed QEvent mouseMoveEvent
3021 // kMouseReleaseEvent // TCanvas processed QEvent mouseReleaseEvent
3022 // kMouseDoubleClickEvent // TCanvas processed QEvent mouseDoubleClickEvent
3023 // kKeyPressEvent // TCanvas processed QEvent keyPressEvent
3024 // kEnterEvent // TCanvas processed QEvent enterEvent
3025 // kLeaveEvent // TCanvas processed QEvent leaveEvent
3026
3027 if (dynamic_cast<TCanvas*>(obj))
3028 return;
3029
3030 TQtWidget *tipped = static_cast<TQtWidget*>(sender());
3031
3032 if (evt==11/*kMouseReleaseEvent*/)
3033 return;
3034
3035 if (evt==61/*kMouseDoubleClickEvent*/)
3036 return;
3037
3038 if (obj)
3039 {
3040 // Find the object which will get picked by the GetObjectInfo
3041 // due to buffer overflows in many root-versions
3042 // in TH1 and TProfile we have to work around and implement
3043 // our own GetObjectInfo which make everything a bit more
3044 // complicated.
3045 canv->cd();
3046#if ROOT_VERSION_CODE > ROOT_VERSION(5,22,00)
3047 const char *objectInfo =
3048 obj->GetObjectInfo(tipped->GetEventX(),tipped->GetEventY());
3049#else
3050 const char *objectInfo = dynamic_cast<TH1*>(obj) ?
3051 "" : obj->GetObjectInfo(tipped->GetEventX(),tipped->GetEventY());
3052#endif
3053
3054 QString tipText;
3055 tipText += obj->GetName();
3056 tipText += " [";
3057 tipText += obj->ClassName();
3058 tipText += "]: ";
3059 tipText += objectInfo;
3060
3061 fStatusBar->showMessage(tipText, 3000);
3062 }
3063
3064 gSystem->DispatchOneEvent(kFALSE);
3065 //gSystem->ProcessEvents();
3066 //QWhatsThis::display(tipText)
3067 }
3068
3069 void slot_RootUpdate()
3070 {
3071 gSystem->DispatchOneEvent(kFALSE);
3072 //gSystem->ProcessEvents();
3073 QTimer::singleShot(10, this, SLOT(slot_RootUpdate()));
3074 }
3075#endif
3076
3077 void ChoosePatchThreshold(Camera &cam, int isw)
3078 {
3079 cam.Reset();
3080
3081 fThresholdIdx->setValue(isw);
3082
3083 const int ihw = isw<0 ? 0 : fPatchMapHW[isw];
3084
3085 fPatchRate->setEnabled(isw>=0);
3086 fThresholdCrate->setEnabled(isw>=0);
3087 fThresholdBoard->setEnabled(isw>=0);
3088 fThresholdPatch->setEnabled(isw>=0);
3089
3090 if (isw<0)
3091 return;
3092
3093 const int patch = ihw%4;
3094 const int board = (ihw/4)%10;
3095 const int crate = (ihw/4)/10;
3096
3097 fInChoosePatchTH = true;
3098
3099 fThresholdCrate->setValue(crate);
3100 fThresholdBoard->setValue(board);
3101 fThresholdPatch->setValue(patch);
3102
3103 fInChoosePatchTH = false;
3104
3105 fThresholdVal->setValue(fFtmStaticData.fThreshold[ihw]);
3106 fPatchRate->setValue(cam.GetData(isw));
3107
3108 // Loop over the software idx of all pixels
3109// for (unsigned int i=0; i<1440; i++)
3110// if (fPatchHW[i]==ihw)
3111// cam.SetBold(i);
3112 }
3113
3114 /*
3115 void ChoosePatchBias(Camera &cam, int isw)
3116 {
3117 cam.Reset();
3118
3119 fBiasChannel->setValue(isw);
3120
3121 const int ihw = isw<0 ? 0 : fPatchMapHW[isw];
3122
3123 fBiasCurrent->setEnabled(isw>=0);
3124 fBiasCrate->setEnabled(isw>=0);
3125 fBiasBoard->setEnabled(isw>=0);
3126 fBiasPatch->setEnabled(isw>=0);
3127
3128 if (isw<0)
3129 return;
3130
3131 const int patch = ihw%4;
3132 const int board = (ihw/4)%10;
3133 const int crate = (ihw/4)/10;
3134
3135 fInChoosePatchBias = true;
3136
3137 fBiasCrate->setValue(crate);
3138 fBiasBoard->setValue(board);
3139 fBiasPatch->setValue(patch);
3140
3141 fInChoosePatchBias = false;
3142
3143 if (fVecBias.size()>0)
3144 {
3145 // FIXME: Mapping
3146 fBiasVoltDac->setValue(fVecBias[ihw]);
3147 fBiasVolt->setValue(fVecBias[ihw]*90./4096);
3148 }
3149
3150 fBiasCurrent->setValue(cam.GetData(isw));
3151
3152 // Loop over the software idx of all pixels
3153 for (unsigned int i=0; i<1440; i++)
3154 if (fPatchHW[i]==ihw)
3155 cam.SetBold(i);
3156 }*/
3157
3158 void slot_ChoosePixelThreshold(int isw)
3159 {
3160 fPixelIdx->setValue(isw);
3161
3162 const PixelMapEntry &entry = fPixelMap.index(isw);
3163 fPixelEnable->setChecked(fFtmStaticData.IsEnabled(entry.hw()));
3164 }
3165
3166 void slot_CameraDoubleClick(int isw)
3167 {
3168 fPixelIdx->setValue(isw);
3169
3170 const PixelMapEntry &entry = fPixelMap.index(isw);
3171 Dim::SendCommand("FTM_CONTROL/TOGGLE_PIXEL", uint16_t(entry.hw()));
3172 }
3173
3174 void slot_CameraMouseMove(int isw)
3175 {
3176 const PixelMapEntry &entry = fPixelMap.index(isw);
3177
3178 const int ihw = entry.hw();
3179
3180 const int idx = fPatchHW[isw];
3181 int ii = 0;
3182 for (; ii<160;ii++)
3183 if (idx ==fPatchMapHW[ii])
3184 break;
3185
3186 const int patch = idx%4;
3187 const int board = (idx/4)%10;
3188 const int crate = (idx/4)/10;
3189 QString tipText;
3190 tipText += fRatesCanv->GetName();
3191 ostringstream str;
3192 str << " || Pixel=" << isw << " (hw=" << ihw << ") || Patch=" << ii << " (hw=" << fPatchMapHW[idx] << "; Crate=" << crate << " Board=" << board << " Patch=" << patch << ")";
3193 tipText += str.str().c_str();
3194 fStatusBar->showMessage(tipText, 3000);
3195 }
3196
3197 void on_fThresholdIdx_valueChanged(int isw)
3198 {
3199//ETIENNE MESS HERE
3200// Camera *cam = (Camera*)fRatesCanv->GetCanvas()->FindObject("Camera");
3201// ChoosePatchTH(*cam, isw);
3202 }
3203
3204 void UpdateThresholdIdx()
3205 {
3206 if (fInChoosePatchTH)
3207 return;
3208
3209 const int crate = fThresholdCrate->value();
3210 const int board = fThresholdBoard->value();
3211 const int patch = fThresholdPatch->value();
3212
3213 const int ihw = patch + board*4 + crate*40;
3214
3215 int isw = 0;
3216 for (; isw<160; isw++)
3217 if (ihw==fPatchMapHW[isw])
3218 break;
3219
3220 on_fThresholdIdx_valueChanged(isw);
3221 }
3222
3223 void on_fPixelIdx_valueChanged(int isw)
3224 {
3225 int ii = 0;
3226 for (; ii<160; ii++)
3227 if (fPatchHW[isw]==fPatchMapHW[ii])
3228 break;
3229
3230 fRatesCanv->SetWhite(isw);
3231 ChoosePatchThreshold(*fRatesCanv, ii);
3232
3233 const PixelMapEntry &entry = fPixelMap.index(isw);
3234 fPixelEnable->setChecked(fFtmStaticData.IsEnabled(entry.hw()));
3235 }
3236
3237 // ------------------- Bias display ---------------------
3238
3239 void UpdateBiasValues()
3240 {
3241 const int b = fBiasHvBoard->value();
3242 const int c = fBiasHvChannel->value();
3243
3244 const int ihw = b*32+c;
3245
3246 if (fVecBiasVolt.size()>0)
3247 {
3248 fBiasVoltCur->setValue(fVecBiasVolt[ihw]*90./4096);
3249 fBiasVoltRef->setValue(fVecBiasVolt[ihw+416]*90./4096);
3250
3251 SetLedColor(fBiasNominalLed,
3252 fVecBiasVolt[ihw]==fVecBiasVolt[ihw+416]?kLedGreen:kLedRed, Time());
3253 }
3254
3255 if (fVecBiasCurrent.size()>0)
3256 {
3257 fBiasCurrent->setValue(abs(fVecBiasCurrent[ihw])*5000./4096);
3258 SetLedColor(fBiasOverCurrentLed,
3259 fVecBiasCurrent[ihw]<0?kLedRed:kLedGreen, Time());
3260 }
3261 }
3262
3263 void UpdateBiasCam(const PixelMapEntry &entry)
3264 {
3265 fInChooseBiasCam = true;
3266
3267 fBiasCamCrate->setValue(entry.crate());
3268 fBiasCamBoard->setValue(entry.board());
3269 fBiasCamPatch->setValue(entry.patch());
3270 fBiasCamPixel->setValue(entry.pixel());
3271
3272 fInChooseBiasCam = false;
3273 }
3274
3275 void BiasHvChannelChanged()
3276 {
3277 if (fInChooseBiasHv)
3278 return;
3279
3280 const int b = fBiasHvBoard->value();
3281 const int ch = fBiasHvChannel->value();
3282
3283 // FIXME: Mark corresponding patch in camera
3284 const PixelMapEntry &entry = fPixelMap.hv(b, ch);
3285 fBiasCamV->SetWhite(entry.index);
3286 fBiasCamA->SetWhite(entry.index);
3287 fBiasCamV->updateGL();
3288 fBiasCamA->updateGL();
3289
3290 UpdateBiasCam(entry);
3291 UpdateBiasValues();
3292 }
3293
3294 void UpdateBiasHv(const PixelMapEntry &entry)
3295 {
3296 fInChooseBiasHv = true;
3297
3298 fBiasHvBoard->setValue(entry.hv_board);
3299 fBiasHvChannel->setValue(entry.hv_channel);
3300
3301 fInChooseBiasHv = false;
3302 }
3303
3304 void BiasCamChannelChanged()
3305 {
3306 if (fInChooseBiasCam)
3307 return;
3308
3309 const int crate = fBiasCamCrate->value();
3310 const int board = fBiasCamBoard->value();
3311 const int patch = fBiasCamPatch->value();
3312 const int pixel = fBiasCamPixel->value();
3313
3314 // FIXME: Display corresponding patches
3315 const PixelMapEntry &entry = fPixelMap.cbpx(crate, board, patch, pixel);
3316 fBiasCamV->SetWhite(entry.index);
3317 fBiasCamA->SetWhite(entry.index);
3318 fBiasCamV->updateGL();
3319 fBiasCamA->updateGL();
3320
3321 UpdateBiasHv(entry);
3322 UpdateBiasValues();
3323 }
3324
3325 void slot_ChooseBiasChannel(int isw)
3326 {
3327 const PixelMapEntry &entry = fPixelMap.index(isw);
3328
3329 UpdateBiasHv(entry);
3330 UpdateBiasCam(entry);
3331 UpdateBiasValues();
3332 }
3333
3334 void on_fBiasDispRefVolt_stateChanged(int = 0)
3335 {
3336 // FIXME: Display patches for which ref==cur
3337
3338 valarray<double> dat(0., 1440);
3339
3340 int offset = 0;
3341 if (!fBiasDispRefVolt->isChecked())
3342 fBiasCamV->setTitle("Applied BIAS voltage");
3343 else
3344 {
3345 fBiasCamV->setTitle("Reference BIAS voltage");
3346 offset = 416;
3347 }
3348
3349 if (fVecBiasVolt.size()>0)
3350 {
3351 for (int i=0; i<1440; i++)
3352 {
3353 const PixelMapEntry &entry = fPixelMap.index(i);
3354 dat[i] = fVecBiasVolt[entry.hv()+offset]*90./4096;
3355
3356 fBiasCamV->highlightPixel(i, fVecBiasVolt[entry.hv()]==fVecBiasVolt[entry.hv()+416]);
3357 }
3358
3359 fBiasCamV->SetData(dat);
3360 }
3361
3362 fBiasCamV->updateGL();
3363 }
3364
3365 // ------------------------------------------------------
3366
3367 void on_fPixelEnable_stateChanged(int b)
3368 {
3369 if (fInHandler)
3370 return;
3371
3372 const PixelMapEntry &entry = fPixelMap.index(fPixelIdx->value());
3373
3374 Dim::SendCommand(b==Qt::Unchecked ?
3375 "FTM_CONTROL/DISABLE_PIXEL" : "FTM_CONTROL/ENABLE_PIXEL",
3376 uint16_t(entry.hw()));
3377 }
3378
3379 void on_fPixelDisableOthers_clicked()
3380 {
3381 const PixelMapEntry &entry = fPixelMap.index(fPixelIdx->value());
3382
3383 Dim::SendCommand("FTM_CONTROL/DISABLE_ALL_PIXELS_EXCEPT", uint16_t(entry.hw()));
3384 }
3385
3386 void on_fThresholdDisableOthers_clicked()
3387 {
3388 const int16_t isw = fThresholdIdx->value();
3389 const int16_t ihw = isw<0 ? -1 : fPatchMapHW[isw];
3390
3391 Dim::SendCommand("FTM_CONTROL/DISABLE_ALL_PATCHES_EXCEPT", ihw);
3392 }
3393
3394 void on_fThresholdVal_valueChanged(int v)
3395 {
3396 fThresholdVolt->setValue(2500./4095*v);
3397
3398 const int32_t isw = fThresholdIdx->value();
3399 const int32_t ihw = isw<0 ? -1 : fPatchMapHW[isw];
3400
3401 const int32_t d[2] = { ihw, v };
3402
3403 if (!fInHandler)
3404 Dim::SendCommand("FTM_CONTROL/SET_THRESHOLD", d);
3405 }
3406
3407 TGraph fGraphFtmTemp[4];
3408 TGraph fGraphFtmRate;
3409 TGraph fGraphPatchRate[160];
3410 TGraph fGraphBoardRate[40];
3411
3412#ifdef HAVE_ROOT
3413 TH1 *DrawTimeFrame(const char *ytitle)
3414 {
3415 const double tm = Time().RootTime();
3416
3417 TH1F *h=new TH1F("TimeFrame", "", 1, tm, tm+60);//Time().RootTime()-1./24/60/60, Time().RootTime());
3418 h->SetDirectory(0);
3419 h->SetBit(kCanDelete);
3420 h->SetStats(kFALSE);
3421// h.SetMinimum(0);
3422// h.SetMaximum(1);
3423 h->SetXTitle("Time");
3424 h->SetYTitle(ytitle);
3425 h->GetXaxis()->CenterTitle();
3426 h->GetYaxis()->CenterTitle();
3427 h->GetXaxis()->SetTimeDisplay(true);
3428 h->GetXaxis()->SetTimeFormat("%Mh%S'");
3429 h->GetXaxis()->SetLabelSize(0.025);
3430 h->GetYaxis()->SetLabelSize(0.025);
3431 h->GetYaxis()->SetTitleOffset(1.2);
3432 // h.GetYaxis()->SetTitleSize(1.2);
3433 h->Draw();
3434
3435 return h;
3436 }
3437#endif
3438
3439 pair<string,string> Split(const string &str) const
3440 {
3441 const size_t p = str.find_first_of('|');
3442 if (p==string::npos)
3443 return make_pair(str, "");
3444
3445 return make_pair(str.substr(0, p), str.substr(p+1));
3446 }
3447
3448public:
3449 FactGui(Configuration &conf) :
3450 fFtuStatus(40),
3451 /*fPixelMapHW(1440),*/ fPatchMapHW(160), fPatchHW(1440),
3452 fInChoosePatchTH(false),
3453 fInChooseBiasHv(false), fInChooseBiasCam(false),
3454 fDimDNS("DIS_DNS/VERSION_NUMBER", 1, int(0), this),
3455 //-
3456 fDimLoggerStats ("DATA_LOGGER/STATS", (void*)NULL, 0, this),
3457 fDimLoggerFilenameNight("DATA_LOGGER/FILENAME_NIGHTLY", (void*)NULL, 0, this),
3458 fDimLoggerFilenameRun ("DATA_LOGGER/FILENAME_RUN", (void*)NULL, 0, this),
3459 fDimLoggerNumSubs ("DATA_LOGGER/NUM_SUBS", (void*)NULL, 0, this),
3460 //-
3461 fDimFtmPassport ("FTM_CONTROL/PASSPORT", (void*)NULL, 0, this),
3462 fDimFtmTriggerRates ("FTM_CONTROL/TRIGGER_RATES", (void*)NULL, 0, this),
3463 fDimFtmError ("FTM_CONTROL/ERROR", (void*)NULL, 0, this),
3464 fDimFtmFtuList ("FTM_CONTROL/FTU_LIST", (void*)NULL, 0, this),
3465 fDimFtmStaticData ("FTM_CONTROL/STATIC_DATA", (void*)NULL, 0, this),
3466 fDimFtmDynamicData ("FTM_CONTROL/DYNAMIC_DATA", (void*)NULL, 0, this),
3467 fDimFtmCounter ("FTM_CONTROL/COUNTER", (void*)NULL, 0, this),
3468 //-
3469 fDimFadWriteStats ("FAD_CONTROL/STATS", (void*)NULL, 0, this),
3470 fDimFadStartRun ("FAD_CONTROL/START_RUN", (void*)NULL, 0, this),
3471 fDimFadRuns ("FAD_CONTROL/RUNS", (void*)NULL, 0, this),
3472 fDimFadEvents ("FAD_CONTROL/EVENTS", (void*)NULL, 0, this),
3473 fDimFadRawData ("FAD_CONTROL/RAW_DATA", (void*)NULL, 0, this),
3474 fDimFadEventData ("FAD_CONTROL/EVENT_DATA", (void*)NULL, 0, this),
3475 fDimFadConnections ("FAD_CONTROL/CONNECTIONS", (void*)NULL, 0, this),
3476 fDimFadFwVersion ("FAD_CONTROL/FIRMWARE_VERSION", (void*)NULL, 0, this),
3477 fDimFadRunNumber ("FAD_CONTROL/RUN_NUMBER", (void*)NULL, 0, this),
3478 fDimFadDNA ("FAD_CONTROL/DNA", (void*)NULL, 0, this),
3479 fDimFadTemperature ("FAD_CONTROL/TEMPERATURE", (void*)NULL, 0, this),
3480 fDimFadPrescaler ("FAD_CONTROL/PRESCALER", (void*)NULL, 0, this),
3481 fDimFadRefClock ("FAD_CONTROL/REFERENCE_CLOCK", (void*)NULL, 0, this),
3482 fDimFadRoi ("FAD_CONTROL/REGION_OF_INTEREST", (void*)NULL, 0, this),
3483 fDimFadDac ("FAD_CONTROL/DAC", (void*)NULL, 0, this),
3484 fDimFadDrsCalibration ("FAD_CONTROL/DRS_CALIBRATION", (void*)NULL, 0, this),
3485 fDimFadStatus ("FAD_CONTROL/STATUS", (void*)NULL, 0, this),
3486 fDimFadStatistics1 ("FAD_CONTROL/STATISTICS1", (void*)NULL, 0, this),
3487 fDimFadStatistics2 ("FAD_CONTROL/STATISTICS2", (void*)NULL, 0, this),
3488 //-
3489 fDimFscTemp ("FSC_CONTROL/TEMPERATURE", (void*)NULL, 0, this),
3490 fDimFscVolt ("FSC_CONTROL/VOLTAGE", (void*)NULL, 0, this),
3491 fDimFscCurrent ("FSC_CONTROL/CURRENT", (void*)NULL, 0, this),
3492 fDimFscHumidity ("FSC_CONTROL/HUMIDITY", (void*)NULL, 0, this),
3493 //-
3494 fDimBiasVolt ("BIAS_CONTROL/VOLTAGE", (void*)NULL, 0, this),
3495 fDimBiasCurrent ("BIAS_CONTROL/CURRENT", (void*)NULL, 0, this),
3496 //-
3497 fEventData(0), fDrsCalibration(1440*1024*6),
3498 fTimeStamp0(0)
3499 {
3500 fClockCondFreq->addItem("--- Hz", QVariant(-1));
3501 fClockCondFreq->addItem("800 MHz", QVariant(800));
3502 fClockCondFreq->addItem("1 GHz", QVariant(1000));
3503 fClockCondFreq->addItem("2 GHz", QVariant(2000));
3504 fClockCondFreq->addItem("3 GHz", QVariant(3000));
3505 fClockCondFreq->addItem("4 GHz", QVariant(4000));
3506 fClockCondFreq->addItem("5 GHz", QVariant(5000));
3507
3508 cout << "-- run counter ---" << endl;
3509 fMcpNumEvents->addItem("unlimited", QVariant(0));
3510 const vector<uint32_t> runcount = conf.Vec<uint32_t>("run-count");
3511 for (vector<uint32_t>::const_iterator it=runcount.begin(); it!=runcount.end(); it++)
3512 {
3513 cout << *it << endl;
3514 ostringstream str;
3515 str << *it;
3516 fMcpNumEvents->addItem(str.str().c_str(), QVariant(*it));
3517 }
3518
3519 cout << "-- run times ---" << endl;
3520 fMcpTime->addItem("unlimited", QVariant(0));
3521 const vector<string> runtime = conf.Vec<string>("run-time");
3522 for (vector<string>::const_iterator it=runtime.begin(); it!=runtime.end(); it++)
3523 {
3524 const pair<string,string> p = Split(*it);
3525 cout << *it << "|" << p.second << "|" << p.first << "|" << endl;
3526 fMcpTime->addItem(p.second.c_str(), QVariant(stoi(p.first)));
3527 }
3528
3529 cout << "-- run types ---" << endl;
3530 const vector<string> runtype = conf.Vec<string>("run-type");
3531 for (vector<string>::const_iterator it=runtype.begin(); it!=runtype.end(); it++)
3532 {
3533 const pair<string,string> p = Split(*it);
3534 cout << *it << "|" << p.second << "|" << p.first << "|" << endl;
3535 fMcpRunType->addItem(p.second.c_str(), QVariant(p.first.c_str()));
3536 }
3537
3538 fTriggerWidget->setEnabled(false);
3539 fFtuWidget->setEnabled(false);
3540 fFtuGroupEnable->setEnabled(false);
3541 fRatesControls->setEnabled(false);
3542 fFadWidget->setEnabled(false);
3543 fEvtBldWidget->setEnabled(false);
3544 fLoggerWidget->setEnabled(false);
3545 fBiasWidget->setEnabled(false);
3546
3547 fChatSend->setEnabled(false);
3548 fChatMessage->setEnabled(false);
3549
3550 DimClient::sendCommand("CHAT/MSG", "GUI online.");
3551 // + MessageDimRX
3552
3553 // --------------------------------------------------------------------------
3554
3555 if (!fPixelMap.Read("FACTmapV5.txt"))
3556 {
3557 cerr << "ERROR - Problems reading FACTmapV5.txt" << endl;
3558 exit(-1);
3559 }
3560
3561/*
3562 ifstream fin0("FACTmapV5.txt");
3563
3564 int l = 0;
3565
3566 string buf;
3567 while (getline(fin0, buf, '\n'))
3568 {
3569 if (l>1439)
3570 break;
3571
3572 buf = Tools::Trim(buf);
3573 if (buf[0]=='#')
3574 continue;
3575
3576 stringstream str(buf);
3577
3578 int idummy;
3579 float fdummy;
3580
3581 PixelMapEntry entry;
3582
3583 str >> entry.index;
3584 str >> entry.cbpx;
3585 str >> idummy;
3586 str >> idummy;
3587 str >> entry.gapd;
3588 str >> fdummy;
3589 str >> entry.hv_board;
3590 str >> entry.hv_channel;
3591 str >> fdummy;
3592 str >> fdummy;
3593 str >> fdummy;
3594
3595 fPixelMap[l++] = entry;
3596 }
3597
3598 if (l!=1440)
3599 {
3600 cerr << "ERROR - Problems reading FACTmapV5.txt" << endl;
3601 exit(-1);
3602 }
3603 */
3604 // --------------------------------------------------------------------------
3605
3606 ifstream fin1("Trigger-Patches.txt");
3607
3608 string buf;
3609
3610 int l = 0;
3611 while (getline(fin1, buf, '\n'))
3612 {
3613 buf = Tools::Trim(buf);
3614 if (buf[0]=='#')
3615 continue;
3616
3617 stringstream str(buf);
3618 for (int i=0; i<9; i++)
3619 {
3620 unsigned int n;
3621 str >> n;
3622
3623 if (n>=fPatchHW.size())
3624 continue;
3625
3626 fPatchHW[n] = l;
3627 }
3628 l++;
3629 }
3630
3631 if (l!=160)
3632 cerr << "WARNING - Problems reading Trigger-Patches.txt" << endl;
3633
3634 // --------------------------------------------------------------------------
3635
3636 /*
3637 ifstream fin2("MasterList-v3.txt");
3638
3639 l = 0;
3640
3641 while (getline(fin2, buf, '\n'))
3642 {
3643 buf = Tools::Trim(buf);
3644 if (buf[0]=='#')
3645 continue;
3646
3647 unsigned int softid, hardid, dummy;
3648
3649 stringstream str(buf);
3650
3651 str >> softid;
3652 str >> dummy;
3653 str >> hardid;
3654
3655 if (softid>=fPixelMapHW.size())
3656 continue;
3657
3658 fPixelMapHW[softid] = hardid;
3659
3660 l++;
3661 }
3662
3663 if (l!=1440)
3664 cerr << "WARNING - Problems reading MasterList-v3.txt" << endl;
3665 */
3666 // --------------------------------------------------------------------------
3667
3668 ifstream fin3("PatchList.txt");
3669
3670 l = 0;
3671
3672 while (getline(fin3, buf, '\n'))
3673 {
3674 buf = Tools::Trim(buf);
3675 if (buf[0]=='#')
3676 continue;
3677
3678 unsigned int softid, hardid;
3679
3680 stringstream str(buf);
3681
3682 str >> softid;
3683 str >> hardid;
3684
3685 if (softid>=fPatchMapHW.size())
3686 continue;
3687
3688 fPatchMapHW[softid] = hardid-1;
3689
3690 l++;
3691 }
3692
3693 if (l!=160)
3694 cerr << "WARNING - Problems reading PatchList.txt" << endl;
3695
3696 // --------------------------------------------------------------------------
3697#ifdef HAVE_ROOT
3698
3699 fGraphFtmRate.SetLineColor(kBlue);
3700 fGraphFtmRate.SetMarkerColor(kBlue);
3701 fGraphFtmRate.SetMarkerStyle(kFullDotMedium);
3702
3703 for (int i=0; i<160; i++)
3704 {
3705 fGraphPatchRate[i].SetName("PatchRate");
3706 //fGraphPatchRate[i].SetLineColor(kBlue);
3707 //fGraphPatchRate[i].SetMarkerColor(kBlue);
3708 fGraphPatchRate[i].SetMarkerStyle(kFullDotMedium);
3709 }
3710 for (int i=0; i<40; i++)
3711 {
3712 fGraphBoardRate[i].SetName("BoardRate");
3713 //fGraphBoardRate[i].SetLineColor(kBlue);
3714 //fGraphBoardRate[i].SetMarkerColor(kBlue);
3715 fGraphBoardRate[i].SetMarkerStyle(kFullDotMedium);
3716 }
3717 /*
3718 TCanvas *c = fFtmTempCanv->GetCanvas();
3719 c->SetBit(TCanvas::kNoContextMenu);
3720 c->SetBorderMode(0);
3721 c->SetFrameBorderMode(0);
3722 c->SetFillColor(kWhite);
3723 c->SetRightMargin(0.03);
3724 c->SetTopMargin(0.03);
3725 c->cd();
3726 */
3727 //CreateTimeFrame("Temperature / �C");
3728
3729 fGraphFtmTemp[0].SetMarkerStyle(kFullDotSmall);
3730 fGraphFtmTemp[1].SetMarkerStyle(kFullDotSmall);
3731 fGraphFtmTemp[2].SetMarkerStyle(kFullDotSmall);
3732 fGraphFtmTemp[3].SetMarkerStyle(kFullDotSmall);
3733
3734 fGraphFtmTemp[1].SetLineColor(kBlue);
3735 fGraphFtmTemp[2].SetLineColor(kRed);
3736 fGraphFtmTemp[3].SetLineColor(kGreen);
3737
3738 fGraphFtmTemp[1].SetMarkerColor(kBlue);
3739 fGraphFtmTemp[2].SetMarkerColor(kRed);
3740 fGraphFtmTemp[3].SetMarkerColor(kGreen);
3741
3742 //fGraphFtmTemp[0].Draw("LP");
3743 //fGraphFtmTemp[1].Draw("LP");
3744 //fGraphFtmTemp[2].Draw("LP");
3745 //fGraphFtmTemp[3].Draw("LP");
3746
3747 // --------------------------------------------------------------------------
3748
3749 TCanvas *c = fFtmRateCanv->GetCanvas();
3750 //c->SetBit(TCanvas::kNoContextMenu);
3751 c->SetBorderMode(0);
3752 c->SetFrameBorderMode(0);
3753 c->SetFillColor(kWhite);
3754 c->SetRightMargin(0.03);
3755 c->SetTopMargin(0.03);
3756 c->SetGrid();
3757 c->cd();
3758
3759 TH1 *hf = DrawTimeFrame("Trigger rate [Hz]");
3760 hf->GetYaxis()->SetRangeUser(0, 1010);
3761
3762 fGraphFtmRate.SetMarkerStyle(kFullDotSmall);
3763 fGraphFtmRate.Draw("LP");
3764
3765 // --------------------------------------------------------------------------
3766
3767 fBiasCamV->SetMin(fBiasVoltMin->value());
3768 fBiasCamV->SetMax(fBiasVoltMax->value());
3769 fBiasCamV->updateGL();
3770
3771 fBiasCamA->SetMin(fBiasCurrentMin->value());
3772 fBiasCamA->SetMax(fBiasCurrentMax->value());
3773 fBiasCamA->updateGL();
3774
3775 // --------------------------------------------------------------------------
3776
3777 fRatesCanv->SetMin(fRatesMin->value());
3778 fRatesCanv->SetMax(fRatesMax->value());
3779 fRatesCanv->updateGL();
3780 on_fPixelIdx_valueChanged(0);
3781
3782 // --------------------------------------------------------------------------
3783
3784 c = fAdcDataCanv->GetCanvas();
3785 //c->SetBit(TCanvas::kNoContextMenu);
3786 c->SetBorderMode(0);
3787 c->SetFrameBorderMode(0);
3788 c->SetFillColor(kWhite);
3789 c->SetRightMargin(0.10);
3790 c->SetGrid();
3791 c->cd();
3792
3793 // Create histogram?
3794
3795 // --------------------------------------------------------------------------
3796
3797 fRatesCanv->setTitle("Patch rates");
3798 fRatesCanv->setUnits("Hz");
3799
3800 fBiasCamA->setTitle("BIAS current");
3801 fBiasCamA->setUnits("uA");
3802
3803 fBiasCamV->setTitle("Applied BIAS voltage");
3804 fBiasCamV->setUnits("V");
3805
3806 fEventCanv1->setTitle("Average (all slices)");
3807 fEventCanv2->setTitle("RMS (all slices)");
3808 fEventCanv3->setTitle("Maximum (all slices)");
3809 fEventCanv4->setTitle("Position of maximum (all slices)");
3810
3811 fEventCanv1->setUnits("mV");
3812 fEventCanv2->setUnits("mV");
3813 fEventCanv3->setUnits("mV");
3814 fEventCanv4->setUnits("slice");
3815
3816 // --------------------------------------------------------------------------
3817
3818 QTimer::singleShot(1000, this, SLOT(slot_RootUpdate()));
3819
3820 //widget->setMouseTracking(true);
3821 //widget->EnableSignalEvents(kMouseMoveEvent);
3822
3823 fFtmRateCanv->setMouseTracking(true);
3824 fFtmRateCanv->EnableSignalEvents(kMouseMoveEvent);
3825
3826 fAdcDataCanv->setMouseTracking(true);
3827 fAdcDataCanv->EnableSignalEvents(kMouseMoveEvent);
3828
3829 fRatesCanv->setMouseTracking(true);
3830
3831 connect(fRatesCanv, SIGNAL(signalPixelMoveOver(int)),
3832 this, SLOT(slot_CameraMouseMove(int)));
3833 connect(fEventCanv1, SIGNAL(signalCurrentPixel(int)),
3834 this, SLOT(slot_CameraMouseMove(int)));
3835 connect(fEventCanv2, SIGNAL(signalCurrentPixel(int)),
3836 this, SLOT(slot_CameraMouseMove(int)));
3837 connect(fEventCanv3, SIGNAL(signalCurrentPixel(int)),
3838 this, SLOT(slot_CameraMouseMove(int)));
3839 connect(fEventCanv4, SIGNAL(signalCurrentPixel(int)),
3840 this, SLOT(slot_CameraMouseMove(int)));
3841
3842 connect(fRatesCanv, SIGNAL(signalPixelDoubleClick(int)),
3843 this, SLOT(slot_CameraDoubleClick(int)));
3844 connect(fRatesCanv, SIGNAL(signalCurrentPixel(int)),
3845 this, SLOT(slot_ChoosePixelThreshold(int)));
3846 connect(fBiasCamV, SIGNAL(signalCurrentPixel(int)),
3847 this, SLOT(slot_ChooseBiasChannel(int)));
3848 connect(fBiasCamA, SIGNAL(signalCurrentPixel(int)),
3849 this, SLOT(slot_ChooseBiasChannel(int)));
3850 connect(fFtmRateCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)),
3851 this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*)));
3852 connect(fAdcDataCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)),
3853 this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*)));
3854#endif
3855 }
3856
3857 ~FactGui()
3858 {
3859 // Unsubscribe all services
3860 for (map<string,DimInfo*>::iterator i=fServices.begin();
3861 i!=fServices.end(); i++)
3862 delete i->second;
3863
3864 delete fEventData;
3865 }
3866};
3867
3868#endif
Note: See TracBrowser for help on using the repository browser.