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

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