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

Last change on this file since 12426 was 12416, checked in by tbretz, 14 years ago
Stop the event update when the fEventStop is checked; enable the Calibrate button in the feedback tab only in its allowed state.
File size: 138.7 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 if (fEventsStop->isChecked())
1581 return;
1582
1583 const float *ptr = d.ptr<float>();
1584
1585 valarray<double> arr1(1440);
1586 valarray<double> arr2(1440);
1587 valarray<double> arr3(1440);
1588 valarray<double> arr4(1440);
1589
1590 for (vector<PixelMapEntry>::const_iterator it=fPixelMap.begin(); it!=fPixelMap.end(); it++)
1591 {
1592 arr1[it->index] = ptr[0*1440+it->hw()];
1593 arr2[it->index] = ptr[1*1440+it->hw()];
1594 arr3[it->index] = ptr[2*1440+it->hw()];
1595 arr4[it->index] = ptr[3*1440+it->hw()];
1596 }
1597
1598 fEventCanv1->SetData(arr1);
1599 fEventCanv2->SetData(arr2);
1600 fEventCanv3->SetData(arr3);
1601 fEventCanv4->SetData(arr4);
1602
1603 fEventCanv1->updateCamera();
1604 fEventCanv2->updateCamera();
1605 fEventCanv3->updateCamera();
1606 fEventCanv4->updateCamera();
1607 }
1608
1609 vector<float> fDrsCalibration;
1610
1611 void handleFadDrsCalibration(const DimData &d)
1612 {
1613 if (d.size()==0)
1614 {
1615 fDrsCalibBaseline->setValue(0);
1616 fDrsCalibGain->setValue(0);
1617 fDrsCalibTrgOffset->setValue(0);
1618 fDrsCalibration.assign(1024*1440*6, 0);
1619 DisplayEventData();
1620 return;
1621 }
1622
1623 if (!CheckSize(d, 1024*1440*6*sizeof(float)+3*sizeof(uint32_t)))
1624 // Do WHAT?
1625 return;
1626
1627 const uint32_t *run = d.ptr<uint32_t>();
1628
1629 fDrsCalibBaseline->setValue(run[0]);
1630 fDrsCalibGain->setValue(run[1]);
1631 fDrsCalibTrgOffset->setValue(run[2]);
1632
1633 const float *dat = d.ptr<float>(sizeof(uint32_t)*3);
1634 fDrsCalibration.assign(dat, dat+1024*1440*6);
1635
1636 DisplayEventData();
1637 }
1638
1639// vector<uint8_t> fFadConnections;
1640
1641 void handleFadConnections(const DimData &d)
1642 {
1643 if (!CheckSize(d, 41))
1644 {
1645 fStatusEventBuilderLabel->setText("Offline");
1646 fStatusEventBuilderLabel->setToolTip("FADs or fadctrl seems to be offline.");
1647 fEvtBldWidget->setEnabled(false);
1648
1649 SetLedColor(fStatusEventBuilderLed, kLedGray, d.time);
1650 return;
1651 }
1652
1653 const uint8_t *ptr = d.ptr<uint8_t>();
1654
1655 for (int i=0; i<40; i++)
1656 {
1657 const uint8_t stat1 = ptr[i]&3;
1658 const uint8_t stat2 = ptr[i]>>3;
1659
1660 if (stat1==0 && stat2==0)
1661 {
1662 SetLedColor(fFadLED[i], kLedGray, d.time);
1663 continue;
1664 }
1665 if (stat1>=2 && stat2==8)
1666 {
1667 SetLedColor(fFadLED[i], stat1==2?kLedGreen:kLedGreenCheck, d.time);
1668 continue;
1669 }
1670
1671 if (stat1==1 && stat2==1)
1672 SetLedColor(fFadLED[i], kLedRed, d.time);
1673 else
1674 SetLedColor(fFadLED[i], kLedOrange, d.time);
1675 }
1676
1677
1678 const bool runs = ptr[40]!=0;
1679
1680 fStatusEventBuilderLabel->setText(runs?"Running":"Not running");
1681 fStatusEventBuilderLabel->setToolTip(runs?"Event builder thread running.":"Event builder thread stopped.");
1682 fEvtBldWidget->setEnabled(runs);
1683
1684 SetLedColor(fStatusEventBuilderLed, runs?kLedGreen:kLedRed, d.time);
1685
1686// fFadConnections.assign(ptr, ptr+40);
1687 }
1688
1689 template<typename T>
1690 void handleFadToolTip(const Time &time, QWidget *w, T *ptr)
1691 {
1692 ostringstream tip;
1693 tip << "<table border='1'><tr><th colspan='11'>" << time.GetAsStr() << " (UTC)</th></tr><tr><th></th>";
1694 for (int b=0; b<10; b++)
1695 tip << "<th>" << b << "</th>";
1696 tip << "</tr>";
1697
1698 for (int c=0; c<4; c++)
1699 {
1700 tip << "<tr><th>" << c << "</th>";
1701 for (int b=0; b<10; b++)
1702 tip << "<td>" << ptr[c*10+b] << "</td>";
1703 tip << "</tr>";
1704 }
1705 tip << "</table>";
1706
1707 w->setToolTip(tip.str().c_str());
1708 }
1709
1710 template<typename T, class S>
1711 void handleFadMinMax(const DimData &d, QPushButton *led, S *wmin, S *wmax=0)
1712 {
1713 if (!CheckSize(d, 42*sizeof(T)))
1714 return;
1715
1716 const T *ptr = d.ptr<T>();
1717 const T min = ptr[40];
1718 const T max = ptr[41];
1719
1720 if (max==0 && min>max)
1721 SetLedColor(led, kLedGray, d.time);
1722 else
1723 SetLedColor(led, min==max?kLedGreen: kLedOrange, d.time);
1724
1725 if (!wmax && max!=min)
1726 wmin->setValue(0);
1727 else
1728 wmin->setValue(min);
1729
1730 if (wmax)
1731 wmax->setValue(max);
1732
1733 handleFadToolTip(d.time, led, ptr);
1734 }
1735
1736 void handleFadFwVersion(const DimData &d)
1737 {
1738 handleFadMinMax<float, QDoubleSpinBox>(d, fFadLedFwVersion, fFadFwVersion);
1739 }
1740
1741 void handleFadRunNumber(const DimData &d)
1742 {
1743 handleFadMinMax<uint32_t, QSpinBox>(d, fFadLedRunNumber, fFadRunNumber);
1744 }
1745
1746 void handleFadPrescaler(const DimData &d)
1747 {
1748 handleFadMinMax<uint16_t, QSpinBox>(d, fFadLedPrescaler, fFadPrescaler);
1749 }
1750
1751 void handleFadDNA(const DimData &d)
1752 {
1753 if (!CheckSize(d, 40*sizeof(uint64_t)))
1754 return;
1755
1756 const uint64_t *ptr = d.ptr<uint64_t>();
1757
1758 ostringstream tip;
1759 tip << "<table width='100%'>";
1760 tip << "<tr><th>Crate</th><td></td><th>Board</th><td></td><th>DNA</th></tr>";
1761
1762 for (int i=0; i<40; i++)
1763 {
1764 tip << dec;
1765 tip << "<tr>";
1766 tip << "<td align='center'>" << i/10 << "</td><td>:</td>";
1767 tip << "<td align='center'>" << i%10 << "</td><td>:</td>";
1768 tip << hex;
1769 tip << "<td>0x" << setfill('0') << setw(16) << ptr[i] << "</td>";
1770 tip << "</tr>";
1771 }
1772 tip << "</table>";
1773
1774 fFadDNA->setText(tip.str().c_str());
1775 }
1776
1777 void SetFadLed(QPushButton *led, const DimData &d, uint16_t bitmask, bool invert=false)
1778 {
1779 if (d.size()==0)
1780 {
1781 SetLedColor(led, kLedGray, d.time);
1782 return;
1783 }
1784
1785 const bool quality = d.ptr<uint16_t>()[0]&bitmask;
1786 const bool value = d.ptr<uint16_t>()[1]&bitmask;
1787 const uint16_t *ptr = d.ptr<uint16_t>()+2;
1788
1789 SetLedColor(led, quality?kLedOrange:(value^invert?kLedGreen:kLedGreenBar), d.time);
1790
1791 ostringstream tip;
1792 tip << "<table border='1'><tr><th colspan='11'>" << d.time.GetAsStr() << " (UTC)</th></tr><tr><th></th>";
1793 for (int b=0; b<10; b++)
1794 tip << "<th>" << b << "</th>";
1795 tip << "</tr>";
1796
1797 /*
1798 tip << "<tr>" << hex;
1799 tip << "<th>" << d.ptr<uint16_t>()[0] << " " << (d.ptr<uint16_t>()[0]&bitmask) << "</th>";
1800 tip << "<th>" << d.ptr<uint16_t>()[1] << " " << (d.ptr<uint16_t>()[1]&bitmask) << "</th>";
1801 tip << "</tr>";
1802 */
1803
1804 for (int c=0; c<4; c++)
1805 {
1806 tip << "<tr><th>" << dec << c << "</th>" << hex;
1807 for (int b=0; b<10; b++)
1808 {
1809 tip << "<td>"
1810 << (ptr[c*10+b]&bitmask)
1811 << "</td>";
1812 }
1813 tip << "</tr>";
1814 }
1815 tip << "</table>";
1816
1817 led->setToolTip(tip.str().c_str());
1818 }
1819
1820 void handleFadStatus(const DimData &d)
1821 {
1822 if (d.size()!=0 && !CheckSize(d, 42*sizeof(uint16_t)))
1823 return;
1824
1825 SetFadLed(fFadLedDrsEnabled, d, FAD::EventHeader::kDenable);
1826 SetFadLed(fFadLedDrsWrite, d, FAD::EventHeader::kDwrite);
1827 SetFadLed(fFadLedDcmLocked, d, FAD::EventHeader::kDcmLocked);
1828 SetFadLed(fFadLedDcmReady, d, FAD::EventHeader::kDcmReady);
1829 SetFadLed(fFadLedSpiSclk, d, FAD::EventHeader::kSpiSclk);
1830 SetFadLed(fFadLedRefClockTooLow, d, FAD::EventHeader::kRefClkTooLow, true);
1831 SetFadLed(fFadLedBusyOn, d, FAD::EventHeader::kBusyOn);
1832 SetFadLed(fFadLedBusyOff, d, FAD::EventHeader::kBusyOff);
1833 SetFadLed(fFadLedTriggerLine, d, FAD::EventHeader::kTriggerLine);
1834 SetFadLed(fFadLedContTrigger, d, FAD::EventHeader::kContTrigger);
1835 SetFadLed(fFadLedSocket, d, FAD::EventHeader::kSock17);
1836 SetFadLed(fFadLedPllLock, d, 0xf000);
1837 }
1838
1839 void handleFadStatistics1(const DimData &d)
1840 {
1841 if (!CheckSize(d, sizeof(GUI_STAT)))
1842 return;
1843
1844 const GUI_STAT &stat = d.ref<GUI_STAT>();
1845
1846 /*
1847 //info about status of the main threads
1848 int32_t readStat ; //read thread
1849 int32_t procStat ; //processing thread(s)
1850 int32_t writStat ; //write thread
1851 */
1852
1853 fFadBufferMax->setValue(stat.totMem/1000000);
1854 fFadBuffer->setMaximum(stat.totMem/100);
1855 fFadBuffer->setValue((stat.maxMem>stat.totMem?stat.totMem:stat.maxMem)/100); // Max mem used in last second
1856
1857 uint32_t sum = 0;
1858 //int32_t min = 0x7fffff;
1859 //int32_t max = 0;
1860
1861 int cnt = 0;
1862 int err = 0;
1863
1864 for (int i=0; i<40; i++)
1865 {
1866 if (stat.numConn[i]!=1)
1867 continue;
1868
1869 cnt++;
1870
1871 sum += stat.rateBytes[i];
1872 err += stat.errConn[i];
1873
1874 //if (stat.rateBytes[i]<min)
1875 // min = stat.rateBytes[i];
1876 //if (stat.rateBytes[i]>max)
1877 // max = stat.rateBytes[i];
1878 }
1879
1880 fFadEvtConn->setValue(cnt);
1881 fFadEvtConnErr->setValue(err);
1882
1883 fFadEvtBufNew->setValue(stat.bufNew); // Incomplete in buffer
1884 fFadEvtBufEvt->setValue(stat.bufEvt); // Complete in buffer
1885 fFadEvtBufMax->setValue(stat.maxEvt); // Complete in buffer
1886 fFadEvtWrite->setValue(stat.evtWrite-stat.evtSkip-stat.evtErr);
1887 fFadEvtSkip->setValue(stat.evtSkip);
1888 fFadEvtErr->setValue(stat.evtErr);
1889
1890 if (stat.deltaT==0)
1891 return;
1892
1893 //fFadEthernetRateMin->setValue(min/stat.deltaT);
1894 //fFadEthernetRateMax->setValue(max/stat.deltaT);
1895 fFadEthernetRateTot->setValue(sum/stat.deltaT);
1896 fFadEthernetRateAvg->setValue(cnt==0 ? 0 : sum/cnt/stat.deltaT);
1897
1898 fFadTransmission->setValue(1000*stat.rateNew/stat.deltaT);
1899 fFadWriteRate->setValue(1000*stat.rateWrite/stat.deltaT);
1900 }
1901
1902 void handleFadStatistics2(const DimData &d)
1903 {
1904 if (!CheckSize(d, sizeof(EVT_STAT)))
1905 return;
1906
1907 //const EVT_STAT &stat = d.ref<EVT_STAT>();
1908
1909 /*
1910 //some info about what happened since start of program (or last 'reset')
1911 uint32_t reset ; //#if increased, reset all counters
1912 uint32_t numRead[MAX_SOCK] ; //how often succesfull read from N sockets per loop
1913
1914 uint64_t gotByte[NBOARDS] ; //#Bytes read per Board
1915 uint32_t gotErr[NBOARDS] ; //#Communication Errors per Board
1916
1917 uint32_t evtGet; //#new Start of Events read
1918 uint32_t evtTot; //#complete Events read
1919
1920 uint32_t evtErr; //#Events with Errors
1921 uint32_t evtSkp; //#Events incomplete (timeout)
1922
1923
1924 uint32_t procTot; //#Events processed
1925 uint32_t procErr; //#Events showed problem in processing
1926 uint32_t procTrg; //#Events accepted by SW trigger
1927 uint32_t procSkp; //#Events rejected by SW trigger
1928
1929 uint32_t feedTot; //#Events used for feedBack system
1930 uint32_t feedErr; //#Events rejected by feedBack
1931
1932 uint32_t wrtTot; //#Events written to disk
1933 uint32_t wrtErr; //#Events with write-error
1934
1935 uint32_t runOpen; //#Runs opened
1936 uint32_t runClose; //#Runs closed
1937 uint32_t runErr; //#Runs with open/close errors
1938
1939
1940 //info about current connection status
1941 uint8_t numConn[NBOARDS] ; //#Sockets succesfully open per board
1942 */
1943 }
1944
1945 // ===================== FTM ============================================
1946
1947 FTM::DimTriggerRates fTriggerRates;
1948
1949 void UpdateTriggerRate(const FTM::DimTriggerRates &sdata)
1950 {
1951#ifdef HAVE_ROOT
1952 TCanvas *c = fFtmRateCanv->GetCanvas();
1953
1954 TH1 *h = (TH1*)c->FindObject("TimeFrame");
1955
1956 if (sdata.fTriggerRate<0)
1957 {
1958 fGraphFtmRate.Set(0);
1959
1960 const double tm = Time().RootTime();
1961
1962 h->SetBins(1, tm, tm+60);
1963 h->GetXaxis()->SetTimeFormat("%M'%S\"");
1964 h->GetXaxis()->SetTitle("Time");
1965
1966 c->Modified();
1967 c->Update();
1968 return;
1969 }
1970
1971 const double t1 = h->GetXaxis()->GetXmax();
1972 const double t0 = h->GetXaxis()->GetXmin();
1973
1974 const double now = t0+sdata.fTimeStamp/1000000.;
1975
1976 h->SetBins(h->GetNbinsX()+1, t0, now+1);
1977 fGraphFtmRate.SetPoint(fGraphFtmRate.GetN(), now, sdata.fTriggerRate);
1978
1979 if (t1-t0>300)
1980 {
1981 h->GetXaxis()->SetTimeFormat("%Hh%M'");
1982 h->GetXaxis()->SetTitle("Time");
1983 }
1984
1985 h->SetMinimum(0);
1986
1987 c->Modified();
1988 c->Update();
1989#endif
1990 }
1991
1992 void UpdateRatesCam(const FTM::DimTriggerRates &sdata)
1993 {
1994 if (fThresholdIdx->value()>=0)
1995 {
1996 const int isw = fThresholdIdx->value();
1997 const int ihw = fPatchMapHW[isw];
1998 fPatchRate->setValue(sdata.fPatchRate[ihw]);
1999 fBoardRate->setValue(sdata.fBoardRate[ihw/4]);
2000 }
2001
2002 const bool b = fBoardRatesEnabled->isChecked();
2003
2004 valarray<double> dat(0., 1440);
2005
2006 // fPatch converts from software id to software patch id
2007 for (int i=0; i<1440; i++)
2008 {
2009 const int ihw = fPixelMap.index(i).hw()/9;
2010 dat[i] = b ? sdata.fBoardRate[ihw/4] : sdata.fPatchRate[ihw];
2011 }
2012
2013 fRatesCanv->SetData(dat);
2014 fRatesCanv->updateCamera();
2015 }
2016
2017 int64_t fTimeStamp0;
2018
2019 void on_fBoardRatesEnabled_toggled(bool)
2020 {
2021 UpdateRatesCam(fTriggerRates);
2022 }
2023
2024 void UpdateRatesGraphs(const FTM::DimTriggerRates &sdata)
2025 {
2026#ifdef HAVE_ROOT
2027 if (fTimeStamp0<0)
2028 {
2029 fTimeStamp0 = sdata.fTimeStamp;
2030 return;
2031 }
2032
2033 TCanvas *c = fFtmRateCanv->GetCanvas();
2034
2035 TH1 *h = (TH1*)c->FindObject("TimeFrame");
2036
2037 const double tdiff = sdata.fTimeStamp-fTimeStamp0;
2038 fTimeStamp0 = sdata.fTimeStamp;
2039
2040 if (tdiff<0)
2041 {
2042 for (int i=0; i<160; i++)
2043 fGraphPatchRate[i].Set(0);
2044 for (int i=0; i<40; i++)
2045 fGraphBoardRate[i].Set(0);
2046
2047 return;
2048 }
2049
2050 //const double t1 = h->GetXaxis()->GetXmax();
2051 const double t0 = h->GetXaxis()->GetXmin();
2052
2053 for (int i=0; i<160; i++)
2054 if (fFtuStatus[i/4]>0)
2055 fGraphPatchRate[i].SetPoint(fGraphPatchRate[i].GetN(),
2056 t0+sdata.fTimeStamp/1000000., sdata.fPatchRate[i]);
2057 for (int i=0; i<40; i++)
2058 if (fFtuStatus[i]>0)
2059 fGraphBoardRate[i].SetPoint(fGraphBoardRate[i].GetN(),
2060 t0+sdata.fTimeStamp/1000000., sdata.fBoardRate[i]);
2061
2062 c->Modified();
2063 c->Update();
2064#endif
2065 }
2066
2067 void handleFtmTriggerRates(const DimData &d)
2068 {
2069 if (!CheckSize(d, sizeof(FTM::DimTriggerRates)))
2070 return;
2071
2072 const FTM::DimTriggerRates &sdata = d.ref<FTM::DimTriggerRates>();
2073
2074 fFtmTime->setText(QString::number(sdata.fTimeStamp/1000000., 'f', 6)+ " s");
2075 fTriggerCounter->setText(QString::number(sdata.fTriggerCounter));
2076
2077 if (sdata.fTimeStamp>0)
2078 fTriggerCounterRate->setValue(1000000.*sdata.fTriggerCounter/sdata.fTimeStamp);
2079 else
2080 fTriggerCounterRate->setValue(0);
2081
2082 // ----------------------------------------------
2083
2084 fOnTime->setText(QString::number(sdata.fOnTimeCounter/1000000., 'f', 6)+" s");
2085
2086 if (sdata.fTimeStamp>0)
2087 fOnTimeRel->setValue(100.*sdata.fOnTimeCounter/sdata.fTimeStamp);
2088 else
2089 fOnTimeRel->setValue(0);
2090
2091 // ----------------------------------------------
2092
2093 UpdateTriggerRate(sdata);
2094 UpdateRatesGraphs(sdata);
2095 UpdateRatesCam(sdata);
2096
2097 fTriggerRates = sdata;
2098 }
2099
2100 void handleFtmCounter(const DimData &d)
2101 {
2102 if (!CheckSize(d, sizeof(uint32_t)*6))
2103 return;
2104
2105 const uint32_t *sdata = d.ptr<uint32_t>();
2106
2107 fFtmCounterH->setValue(sdata[0]);
2108 fFtmCounterS->setValue(sdata[1]);
2109 fFtmCounterD->setValue(sdata[2]);
2110 fFtmCounterF->setValue(sdata[3]);
2111 fFtmCounterE->setValue(sdata[4]);
2112 fFtmCounterR->setValue(sdata[5]);
2113 }
2114
2115 void handleFtmDynamicData(const DimData &d)
2116 {
2117 if (!CheckSize(d, sizeof(FTM::DimDynamicData)))
2118 return;
2119
2120 const FTM::DimDynamicData &sdata = d.ref<FTM::DimDynamicData>();
2121
2122 fFtmTemp0->setValue(sdata.fTempSensor[0]*0.1);
2123 fFtmTemp1->setValue(sdata.fTempSensor[1]*0.1);
2124 fFtmTemp2->setValue(sdata.fTempSensor[2]*0.1);
2125 fFtmTemp3->setValue(sdata.fTempSensor[3]*0.1);
2126
2127 SetLedColor(fClockCondLed, sdata.fState&FTM::kFtmLocked ? kLedGreen : kLedRed, d.time);
2128 }
2129
2130 void DisplayRates()
2131 {
2132#ifdef HAVE_ROOT
2133 TCanvas *c = fFtmRateCanv->GetCanvas();
2134
2135 while (c->FindObject("PatchRate"))
2136 c->GetListOfPrimitives()->Remove(c->FindObject("PatchRate"));
2137
2138 while (c->FindObject("BoardRate"))
2139 c->GetListOfPrimitives()->Remove(c->FindObject("BoardRate"));
2140
2141 c->cd();
2142
2143 if (fRatePatch1->value()>=0)
2144 {
2145 fGraphPatchRate[fRatePatch1->value()].SetLineColor(kRed);
2146 fGraphPatchRate[fRatePatch1->value()].SetMarkerColor(kRed);
2147 fGraphPatchRate[fRatePatch1->value()].Draw("PL");
2148 }
2149 if (fRatePatch2->value()>=0)
2150 {
2151 fGraphPatchRate[fRatePatch2->value()].SetLineColor(kGreen);
2152 fGraphPatchRate[fRatePatch2->value()].SetMarkerColor(kGreen);
2153 fGraphPatchRate[fRatePatch2->value()].Draw("PL");
2154 }
2155 if (fRateBoard1->value()>=0)
2156 {
2157 fGraphBoardRate[fRateBoard1->value()].SetLineColor(kMagenta);
2158 fGraphBoardRate[fRateBoard1->value()].SetMarkerColor(kMagenta);
2159 fGraphBoardRate[fRateBoard1->value()].Draw("PL");
2160 }
2161 if (fRateBoard2->value()>=0)
2162 {
2163 fGraphBoardRate[fRateBoard2->value()].SetLineColor(kCyan);
2164 fGraphBoardRate[fRateBoard2->value()].SetMarkerColor(kCyan);
2165 fGraphBoardRate[fRateBoard2->value()].Draw("PL");
2166 }
2167
2168 c->Modified();
2169 c->Update();
2170#endif
2171 }
2172
2173 FTM::DimStaticData fFtmStaticData;
2174
2175 void SetFtuLed(int idx, int counter, const Time &t)
2176 {
2177 if (counter==0 || counter>3)
2178 counter = 3;
2179
2180 if (counter<0)
2181 counter = 0;
2182
2183 const LedColor_t col[4] = { kLedGray, kLedGreen, kLedOrange, kLedRed };
2184
2185 SetLedColor(fFtuLED[idx], col[counter], t);
2186
2187 fFtuStatus[idx] = counter;
2188 }
2189
2190 void SetFtuStatusLed(const Time &t)
2191 {
2192 const int max = fFtuStatus.max();
2193
2194 switch (max)
2195 {
2196 case 0:
2197 SetLedColor(fStatusFTULed, kLedGray, t);
2198 fStatusFTULabel->setText("All disabled");
2199 fStatusFTULabel->setToolTip("All FTUs are disabled");
2200 break;
2201
2202 case 1:
2203 SetLedColor(fStatusFTULed, kLedGreen, t);
2204 fStatusFTULabel->setToolTip("Communication with FTU is smooth.");
2205 fStatusFTULabel->setText("ok");
2206 break;
2207
2208 case 2:
2209 SetLedColor(fStatusFTULed, kLedOrange, t);
2210 fStatusFTULabel->setText("Warning");
2211 fStatusFTULabel->setToolTip("At least one FTU didn't answer immediately");
2212 break;
2213
2214 case 3:
2215 SetLedColor(fStatusFTULed, kLedRed, t);
2216 fStatusFTULabel->setToolTip("At least one FTU didn't answer!");
2217 fStatusFTULabel->setText("ERROR");
2218 break;
2219 }
2220
2221 const int cnt = count(&fFtuStatus[0], &fFtuStatus[40], 0);
2222 fFtuAllOn->setEnabled(cnt!=0);
2223 fFtuAllOff->setEnabled(cnt!=40);
2224 }
2225
2226 void handleFtmStaticData(const DimData &d)
2227 {
2228 if (!CheckSize(d, sizeof(FTM::DimStaticData)))
2229 return;
2230
2231 const FTM::DimStaticData &sdata = d.ref<FTM::DimStaticData>();
2232
2233 fTriggerInterval->setValue(sdata.fTriggerInterval);
2234 fPhysicsCoincidence->setValue(sdata.fMultiplicityPhysics);
2235 fCalibCoincidence->setValue(sdata.fMultiplicityCalib);
2236 fPhysicsWindow->setValue(sdata.fWindowPhysics);
2237 fCalibWindow->setValue(sdata.fWindowCalib);
2238
2239 fTriggerDelay->setValue(sdata.fDelayTrigger);
2240 fTimeMarkerDelay->setValue(sdata.fDelayTimeMarker);
2241 fDeadTime->setValue(sdata.fDeadTime);
2242
2243 fClockCondR0->setValue(sdata.fClockConditioner[0]);
2244 fClockCondR1->setValue(sdata.fClockConditioner[1]);
2245 fClockCondR8->setValue(sdata.fClockConditioner[2]);
2246 fClockCondR9->setValue(sdata.fClockConditioner[3]);
2247 fClockCondR11->setValue(sdata.fClockConditioner[4]);
2248 fClockCondR13->setValue(sdata.fClockConditioner[5]);
2249 fClockCondR14->setValue(sdata.fClockConditioner[6]);
2250 fClockCondR15->setValue(sdata.fClockConditioner[7]);
2251
2252 const uint32_t R0 = sdata.fClockConditioner[0];
2253 const uint32_t R14 = sdata.fClockConditioner[6];
2254 const uint32_t R15 = sdata.fClockConditioner[7];
2255
2256 const uint32_t Ndiv = (R15&0x1ffff00)<<2;
2257 const uint32_t Rdiv = (R14&0x007ff00)>>8;
2258 const uint32_t Cdiv = (R0 &0x000ff00)>>8;
2259
2260 double freq = 40.*Ndiv/(Rdiv*Cdiv);
2261
2262 fClockCondFreqRes->setValue(freq);
2263
2264 //fClockCondFreq->setEditText("");
2265 fClockCondFreq->setCurrentIndex(0);
2266
2267 fTriggerSeqPed->setValue(sdata.fTriggerSeqPed);
2268 fTriggerSeqLPint->setValue(sdata.fTriggerSeqLPint);
2269 fTriggerSeqLPext->setValue(sdata.fTriggerSeqLPext);
2270
2271 fLpIntIntensity->setValue(sdata.fIntensityLPint);
2272 fLpExtIntensity->setValue(sdata.fIntensityLPext);
2273
2274 fLpIntGroup1->setChecked(sdata.HasLPintG1());
2275 fLpIntGroup2->setChecked(sdata.HasLPintG2());
2276 fLpExtGroup1->setChecked(sdata.HasLPextG1());
2277 fLpExtGroup2->setChecked(sdata.HasLPextG2());
2278
2279 fEnableTrigger->setChecked(sdata.HasTrigger());
2280 fEnableVeto->setChecked(sdata.HasVeto());
2281 fEnableExt1->setChecked(sdata.HasExt1());
2282 fEnableExt2->setChecked(sdata.HasExt2());
2283 fEnableClockCond->setChecked(sdata.HasClockConditioner());
2284
2285 uint16_t multiplicity = sdata.fMultiplicity[0];
2286
2287 for (int i=0; i<40; i++)
2288 {
2289 if (!sdata.IsActive(i))
2290 SetFtuLed(i, -1, d.time);
2291 else
2292 {
2293 if (fFtuStatus[i]==0)
2294 SetFtuLed(i, 1, d.time);
2295 }
2296 fFtuLED[i]->setChecked(false);
2297
2298 if (sdata.fMultiplicity[i]!=multiplicity)
2299 multiplicity = -1;
2300
2301 }
2302 SetFtuStatusLed(d.time);
2303
2304 fNoutof4Val->setValue(multiplicity);
2305
2306 for (vector<PixelMapEntry>::const_iterator it=fPixelMap.begin(); it!=fPixelMap.end(); it++)
2307 fRatesCanv->SetEnable(it->index, sdata.IsEnabled(it->hw()));
2308
2309 const PixelMapEntry &entry = fPixelMap.index(fPixelIdx->value());
2310 fPixelEnable->setChecked(sdata.IsEnabled(entry.hw()));
2311
2312 if (fThresholdIdx->value()>=0)
2313 {
2314 const int isw = fThresholdIdx->value();
2315 const int ihw = fPatchMapHW[isw];
2316 fThresholdVal->setValue(sdata.fThreshold[ihw]);
2317 }
2318
2319 fPrescalingVal->setValue(sdata.fPrescaling[0]);
2320
2321 fFtmStaticData = sdata;
2322 }
2323
2324 void handleFtmPassport(const DimData &d)
2325 {
2326 if (!CheckSize(d, sizeof(FTM::DimPassport)))
2327 return;
2328
2329 const FTM::DimPassport &sdata = d.ref<FTM::DimPassport>();
2330
2331 stringstream str1, str2;
2332 str1 << hex << "0x" << setfill('0') << setw(16) << sdata.fBoardId;
2333 str2 << sdata.fFirmwareId;
2334
2335 fFtmBoardId->setText(str1.str().c_str());
2336 fFtmFirmwareId->setText(str2.str().c_str());
2337 }
2338
2339 void handleFtmFtuList(const DimData &d)
2340 {
2341 if (!CheckSize(d, sizeof(FTM::DimFtuList)))
2342 return;
2343
2344 fFtuPing->setChecked(false);
2345
2346 const FTM::DimFtuList &sdata = d.ref<FTM::DimFtuList>();
2347
2348 stringstream str;
2349 str << "<table width='100%'>" << setfill('0');
2350 str << "<tr><th>Num</th><th></th><th>Addr</th><th></th><th>DNA</th></tr>";
2351 for (int i=0; i<40; i++)
2352 {
2353 str << "<tr>";
2354 str << "<td align='center'>" << dec << i << hex << "</td>";
2355 str << "<td align='center'>:</td>";
2356 str << "<td align='center'>0x" << setw(2) << (int)sdata.fAddr[i] << "</td>";
2357 str << "<td align='center'>:</td>";
2358 str << "<td align='center'>0x" << setw(16) << sdata.fDNA[i] << "</td>";
2359 str << "</tr>";
2360 }
2361 str << "</table>";
2362
2363 fFtuDNA->setText(str.str().c_str());
2364
2365 fFtuAnswersTotal->setValue(sdata.fNumBoards);
2366 fFtuAnswersCrate0->setValue(sdata.fNumBoardsCrate[0]);
2367 fFtuAnswersCrate1->setValue(sdata.fNumBoardsCrate[1]);
2368 fFtuAnswersCrate2->setValue(sdata.fNumBoardsCrate[2]);
2369 fFtuAnswersCrate3->setValue(sdata.fNumBoardsCrate[3]);
2370
2371 for (int i=0; i<40; i++)
2372 SetFtuLed(i, sdata.IsActive(i) ? sdata.fPing[i] : -1, d.time);
2373
2374 SetFtuStatusLed(d.time);
2375 }
2376
2377 void handleFtmError(const DimData &d)
2378 {
2379 if (!CheckSize(d, sizeof(FTM::DimError)))
2380 return;
2381
2382 const FTM::DimError &sdata = d.ref<FTM::DimError>();
2383
2384 SetFtuLed(sdata.fError.fDestAddress, sdata.fError.fNumCalls, d.time);
2385 SetFtuStatusLed(d.time);
2386
2387 // FIXME: Write to special window!
2388 //Out() << "Error:" << endl;
2389 //Out() << sdata.fError << endl;
2390 }
2391
2392 // ========================== FSC =======================================
2393
2394 void SetFscValue(QDoubleSpinBox *box, const DimData &d, int idx, bool enable)
2395 {
2396 //box->setEnabled(enable);
2397 if (!enable)
2398 {
2399 box->setToolTip(d.time.GetAsStr().c_str());
2400 return;
2401 }
2402
2403 ostringstream str;
2404 str << d.time << " -- " << d.get<float>() << "s";
2405
2406 box->setToolTip(str.str().c_str());
2407 box->setValue(d.get<float>(idx*4+4));
2408 }
2409
2410
2411 void handleFscTemp(const DimData &d)
2412 {
2413 const bool enable = d.size()>0 && CheckSize(d, 60*sizeof(float));
2414 if (!enable)
2415 return;
2416
2417 QDoubleSpinBox *boxes[] = {
2418 fTempCam00, fTempCam01,
2419 fTempCam10, fTempCam11, fTempCam12, fTempCam13, fTempCam14,
2420 fTempCam20, fTempCam21, fTempCam22, fTempCam23, fTempCam24, fTempCam25,
2421 fTempCam30, fTempCam31, fTempCam32, fTempCam33, fTempCam34,
2422 fTempCam40, fTempCam41, fTempCam42, fTempCam43, fTempCam44, fTempCam45,
2423 fTempCam50, fTempCam51, fTempCam52, fTempCam53, fTempCam54,
2424 fTempCam60, fTempCam61,
2425 // 0:b/f 1:b/f 2:b/f 3:b/f
2426 fTempCrate0back, fTempCrate0front,
2427 fTempCrate1back, fTempCrate1front,
2428 fTempCrate2back, fTempCrate2front,
2429 fTempCrate3back, fTempCrate3front,
2430 // 0:b/f 1:b/f 2:b/f 3:b/f
2431 fTempPS0back, fTempPS0front,
2432 fTempPS1back, fTempPS1front,
2433 fTempPS2back, fTempPS2front,
2434 fTempPS3back, fTempPS3front,
2435 // AUX PS: FTM t/b; FSC t/b
2436 fTempAuxFTMtop, fTempAuxFTMbottom,
2437 fTempAuxFSCtop, fTempAuxFSCbottom,
2438 // Backpanel: FTM t/b; FSC t/b
2439 fTempBackpanelFTMtop, fTempBackpanelFTMbottom,
2440 fTempBackpanelFSCtop, fTempBackpanelFSCbottom,
2441 // top front/back; bottom front/back
2442 fTempSwitchboxTopFront, fTempSwitchboxTopBack,
2443 fTempSwitchboxBottomFront, fTempSwitchboxBottomBack,
2444 };
2445
2446 for (int i=0; i<59; i++)
2447 SetFscValue(boxes[i], d, i, enable);
2448
2449 if (!enable)
2450 return;
2451
2452 const float *ptr = d.ptr<float>();
2453
2454 double avg = 0;
2455 int num = 0;
2456 for (int i=1; i<32; i++)
2457 if (ptr[i]!=0)
2458 {
2459 avg += ptr[i];
2460 num ++;
2461 }
2462
2463 fTempCamAvg->setValue(num?avg/num:0);
2464 }
2465
2466 void handleFscVolt(const DimData &d)
2467 {
2468 const bool enable = d.size()>0 && CheckSize(d, 31*sizeof(float));
2469 if (!enable)
2470 return;
2471
2472 QDoubleSpinBox *boxes[] = {
2473 fVoltFad00, fVoltFad10, fVoltFad20, fVoltFad30,
2474 fVoltFad01, fVoltFad11, fVoltFad21, fVoltFad31,
2475 fVoltFad02, fVoltFad12, fVoltFad22, fVoltFad32,
2476 fVoltFPA00, fVoltFPA10, fVoltFPA20, fVoltFPA30,
2477 fVoltFPA01, fVoltFPA11, fVoltFPA21, fVoltFPA31,
2478 fVoltFPA02, fVoltFPA12, fVoltFPA22, fVoltFPA32,
2479 fVoltETH0, fVoltETH1,
2480 fVoltFTM0, fVoltFTM1,
2481 fVoltFFC, fVoltFLP,
2482 };
2483
2484 for (int i=0; i<30; i++)
2485 SetFscValue(boxes[i], d, i, enable);
2486 }
2487
2488 void handleFscCurrent(const DimData &d)
2489 {
2490 const bool enable = d.size()>0 && CheckSize(d, 31*sizeof(float));
2491 if (!enable)
2492 return;
2493
2494 QDoubleSpinBox *boxes[] = {
2495 fAmpFad00, fAmpFad10, fAmpFad20, fAmpFad30,
2496 fAmpFad01, fAmpFad11, fAmpFad21, fAmpFad31,
2497 fAmpFad02, fAmpFad12, fAmpFad22, fAmpFad32,
2498 fAmpFPA00, fAmpFPA10, fAmpFPA20, fAmpFPA30,
2499 fAmpFPA01, fAmpFPA11, fAmpFPA21, fAmpFPA31,
2500 fAmpFPA02, fAmpFPA12, fAmpFPA22, fAmpFPA32,
2501 fAmpETH0, fAmpETH1,
2502 fAmpFTM0, fAmpFTM1,
2503 fAmpFFC, fAmpFLP,
2504 };
2505
2506 for (int i=0; i<30; i++)
2507 SetFscValue(boxes[i], d, i, enable);
2508 }
2509
2510 void handleFscHumidity(const DimData &d)
2511 {
2512 const bool enable = d.size()>0 && CheckSize(d, 5*sizeof(float));
2513
2514 SetFscValue(fHumidity1, d, 0, enable);
2515 SetFscValue(fHumidity2, d, 1, enable);
2516 SetFscValue(fHumidity3, d, 2, enable);
2517 SetFscValue(fHumidity4, d, 3, enable);
2518 }
2519
2520 // ========================== Feedback ==================================
2521
2522#ifdef HAVE_ROOT
2523 TGraphErrors fGraphFeedbackDev;
2524 TGraphErrors fGraphFeedbackCmd;
2525
2526 void UpdateFeedback(TQtWidget &rwidget, const Time &time, TGraphErrors &graph, double avg, double rms)
2527 {
2528 TCanvas *c = rwidget.GetCanvas();
2529
2530 TH1 *h = (TH1*)c->FindObject("TimeFrame");
2531
2532 while (graph.GetN()>500)
2533 graph.RemovePoint(0);
2534
2535 const double now = time.RootTime();
2536
2537 while (graph.GetN()>0 && now-graph.GetX()[0]>3600)
2538 graph.RemovePoint(0);
2539
2540 const int n = graph.GetN();
2541
2542 const double xmin = n>0 ? graph.GetX()[0] : now;
2543
2544 h->SetBins(n+1, xmin-1, now+1);
2545 graph.SetPoint(n, now, avg);
2546 graph.SetPointError(n, 0, rms);
2547
2548 h->GetXaxis()->SetTimeFormat(now-xmin>300 ? "%Hh%M'" : "%M'%S\"");
2549
2550 c->Modified();
2551 c->Update();
2552 }
2553#endif
2554
2555 void handleFeedbackDeviation(const DimData &d)
2556 {
2557 if (!CheckSize(d, 2*416*sizeof(float)))
2558 return;
2559
2560 const float *ptr = d.ptr<float>();
2561
2562 valarray<float> dev(1440);
2563 valarray<float> cmd(1440);
2564
2565 double avgdev = 0;
2566 double avgcmd = 0;
2567
2568 double rmsdev = 0;
2569 double rmscmd = 0;
2570
2571 for (int i=0; i<1440; i++)
2572 {
2573 const PixelMapEntry &entry = fPixelMap.index(i);
2574
2575 dev[i] = /*1000*/ptr[entry.hv()];
2576 cmd[i] = 1000*ptr[entry.hv()+416];
2577
2578 avgdev += dev[i];
2579 avgcmd += cmd[i];
2580
2581 rmsdev += dev[i]*dev[i];
2582 rmscmd += cmd[i]*cmd[i];
2583 }
2584
2585 avgdev /= 1440;
2586 avgcmd /= 1440;
2587
2588 rmsdev = sqrt(rmsdev/1440 - avgdev*avgdev);
2589 rmscmd = sqrt(rmscmd/1440 - avgcmd*avgcmd);
2590
2591 fFeedbackDevCam->SetData(dev);
2592 fFeedbackCmdCam->SetData(cmd);
2593
2594 fFeedbackDevCam->updateCamera();
2595 fFeedbackCmdCam->updateCamera();
2596
2597#ifdef HAVE_ROOT
2598 UpdateFeedback(*fFeedbackDev, d.time, fGraphFeedbackDev, avgdev, rmsdev);
2599 UpdateFeedback(*fFeedbackCmd, d.time, fGraphFeedbackCmd, avgcmd, rmscmd);
2600#endif
2601 }
2602
2603 void handleFeedbackReference(const DimData &d)
2604 {
2605 if (!CheckSize(d, 416*sizeof(float)))
2606 return;
2607
2608 const float *ptr = d.ptr<float>();
2609
2610// fFeedbackRefCam->SetData(valarray<float>(ptr, 416));
2611// fFeedbackRefCam->updateCamera();
2612 }
2613
2614 vector<float> fBiasOffsets;
2615
2616 void handleFeedbackCalibration(const DimData &d)
2617 {
2618 if (!CheckSize(d, 2*416*sizeof(float)))
2619 return;
2620
2621 const float *ptr = d.ptr<float>();
2622 fBiasOffsets.assign(ptr, ptr+416);
2623 }
2624
2625 // ======================= Rate Scan ====================================
2626
2627 TGraph fGraphRateScan[201];
2628
2629 void UpdateRateScan(uint32_t th, const float *rates)
2630 {
2631#ifdef HAVE_ROOT
2632 TCanvas *c = fRateScanCanv->GetCanvas();
2633
2634 TH1 *h = (TH1*)c->FindObject("Frame");
2635
2636 if (fGraphRateScan[0].GetN()==0 || th<fGraphRateScan[0].GetX()[fGraphRateScan[0].GetN()-1])
2637 {
2638 h->SetBins(1, th<10 ? 0 : th-10, th+10);
2639 h->SetMinimum(1);
2640 h->SetMaximum(rates[0]*2);
2641
2642 for (int i=0; i<201; i++)
2643 {
2644 fGraphRateScan[i].Set(0);
2645 fGraphRateScan[i].SetPoint(fGraphRateScan[i].GetN(), th, rates[i]);
2646 }
2647
2648 c->SetGrid();
2649 c->SetLogy();
2650
2651 c->Modified();
2652 c->Update();
2653 return;
2654 }
2655
2656 const double dac = h->GetXaxis()->GetXmin();
2657 h->SetBins(h->GetNbinsX()+1, dac, th+10);
2658
2659 for (int i=0; i<201; i++)
2660 fGraphRateScan[i].SetPoint(fGraphRateScan[i].GetN(), th, rates[i]);
2661
2662 c->Modified();
2663 c->Update();
2664#endif
2665 }
2666
2667 void DisplayRateScan()
2668 {
2669#ifdef HAVE_ROOT
2670 TCanvas *c = fRateScanCanv->GetCanvas();
2671
2672 while (c->FindObject("PatchRate"))
2673 c->GetListOfPrimitives()->Remove(c->FindObject("PatchRate"));
2674
2675 while (c->FindObject("BoardRate"))
2676 c->GetListOfPrimitives()->Remove(c->FindObject("BoardRate"));
2677
2678 c->cd();
2679
2680 if (fRateScanPatch1->value()>=0)
2681 {
2682 fGraphRateScan[fRateScanPatch1->value()+41].SetLineColor(kRed);
2683 fGraphRateScan[fRateScanPatch1->value()+41].SetMarkerColor(kRed);
2684 fGraphRateScan[fRateScanPatch1->value()+41].Draw("PL");
2685 }
2686 if (fRateScanPatch2->value()>=0)
2687 {
2688 fGraphRateScan[fRateScanPatch2->value()+41].SetLineColor(kGreen);
2689 fGraphRateScan[fRateScanPatch2->value()+41].SetMarkerColor(kGreen);
2690 fGraphRateScan[fRateScanPatch2->value()+41].Draw("PL");
2691 }
2692 if (fRateScanBoard1->value()>=0)
2693 {
2694 fGraphRateScan[fRateScanBoard1->value()+1].SetLineColor(kMagenta);
2695 fGraphRateScan[fRateScanBoard1->value()+1].SetMarkerColor(kMagenta);
2696 fGraphRateScan[fRateScanBoard1->value()+1].Draw("PL");
2697 }
2698 if (fRateScanBoard2->value()>=0)
2699 {
2700 fGraphRateScan[fRateScanBoard2->value()+1].SetLineColor(kCyan);
2701 fGraphRateScan[fRateScanBoard2->value()+1].SetMarkerColor(kCyan);
2702 fGraphRateScan[fRateScanBoard2->value()+1].Draw("PL");
2703 }
2704
2705 c->Modified();
2706 c->Update();
2707#endif
2708 }
2709
2710 void handleRateScan(const DimData &d)
2711 {
2712 if (!CheckSize(d, 204*sizeof(float)))
2713 return;
2714
2715 UpdateRateScan(d.get<uint32_t>(), d.ptr<float>(12));
2716 }
2717
2718 // ========================== FSC =======================================
2719
2720 vector<int16_t> fVecBiasVolt;
2721 vector<int16_t> fVecBiasCurrent;
2722
2723 void handleBiasVolt(const DimData &d)
2724 {
2725 if (!CheckSize(d, 2*416*sizeof(int16_t)))
2726 return;
2727
2728 const int16_t *ptr = d.ptr<int16_t>();
2729
2730 fVecBiasVolt.assign(ptr, ptr+2*416);
2731
2732 on_fBiasDispRefVolt_stateChanged();
2733 UpdateBiasValues();
2734 }
2735
2736 void handleBiasCurrent(const DimData &d)
2737 {
2738 if (!CheckSize(d, 416*sizeof(int16_t)))
2739 return;
2740
2741 const int16_t *ptr = d.ptr<int16_t>();
2742
2743 fVecBiasCurrent.assign(ptr, ptr+416);
2744
2745 valarray<double> dat(0., 1440);
2746
2747 // fPatch converts from software id to software patch id
2748 for (int i=0; i<1440; i++)
2749 {
2750 const PixelMapEntry &entry = fPixelMap.index(i);
2751
2752 // FIXME: Display Overcurrent
2753 /*
2754 dat[i] = fVecBiasVolt[entry.hv()]*90./4096;
2755 double amp = abs(ptr[entry.hv()]);
2756 if (fBiasOffsets.size()>0)
2757 amp -= fBiasOffsets[entry.hv()];
2758 amp *= 5000./4096;
2759 amp *= 5200 *1e-6;
2760 dat[i] -= amp;
2761 */
2762
2763 dat[i] = abs(ptr[entry.hv()]);
2764 if (fBiasOffsets.size()>0)
2765 dat[i] -= fBiasOffsets[entry.hv()];
2766 dat[i] *= 5000./4096;
2767
2768 if (entry.group()==1)
2769 dat[i] *= 0.92;
2770
2771 fBiasCamA->SetEnable(i, uint16_t(ptr[entry.hv()])!=0x8000);
2772 fBiasCamA->highlightPixel(i, ptr[entry.hv()]<0);
2773 }
2774
2775 fBiasCamA->SetData(dat);
2776 fBiasCamA->updateCamera();
2777
2778 UpdateBiasValues();
2779 }
2780
2781 // ====================== MessageImp ====================================
2782
2783 bool fChatOnline;
2784
2785 void handleStateChanged(const Time &time, const std::string &server,
2786 const State &s)
2787 {
2788 // FIXME: Prefix tooltip with time
2789 if (server=="MCP")
2790 {
2791 // FIXME: Enable FTU page!!!
2792 fStatusMCPLabel->setText(s.name.c_str());
2793 fStatusMCPLabel->setToolTip(s.comment.c_str());
2794
2795 if (s.index<2) // No Dim connection
2796 SetLedColor(fStatusMCPLed, kLedGray, time);
2797 if (s.index==2) // Disconnected
2798 SetLedColor(fStatusMCPLed, kLedRed, time);
2799 if (s.index==3) // Connecting
2800 SetLedColor(fStatusMCPLed, kLedOrange, time);
2801 if (s.index==4) // Connected
2802 SetLedColor(fStatusMCPLed, kLedYellow, time);
2803 if (s.index==5 || s.index==10) // Idle
2804 SetLedColor(fStatusMCPLed, kLedGreen, time);
2805
2806 if (s.index>=7 && s.index<=9)
2807 SetLedColor(fStatusMCPLed, kLedGreenBar, time);
2808
2809 fMcpStartRun->setEnabled(s.index>=5);
2810 fMcpStopRun->setEnabled(s.index>=5);
2811 fMcpReset->setEnabled(s.index>=7 && s.index<=10);
2812 }
2813
2814 if (server=="FTM_CONTROL")
2815 {
2816 // FIXME: Enable FTU page!!!
2817 fStatusFTMLabel->setText(s.name.c_str());
2818 fStatusFTMLabel->setToolTip(s.comment.c_str());
2819
2820 bool enable = false;
2821 const bool configuring =
2822 s.index==FTM::StateMachine::kConfiguring1 ||
2823 s.index==FTM::StateMachine::kConfiguring2 ||
2824 s.index==FTM::StateMachine::kConfigured;
2825
2826 if (s.index<FTM::StateMachine::kDisconnected) // No Dim connection
2827 SetLedColor(fStatusFTMLed, kLedGray, time);
2828 if (s.index==FTM::StateMachine::kDisconnected) // Dim connection / FTM disconnected
2829 SetLedColor(fStatusFTMLed, kLedYellow, time);
2830 if (s.index==FTM::StateMachine::kConnected ||
2831 s.index==FTM::StateMachine::kIdle ||
2832 configuring) // Dim connection / FTM connected
2833 SetLedColor(fStatusFTMLed, kLedGreen, time);
2834 if (s.index==FTM::StateMachine::kTriggerOn) // Dim connection / FTM connected
2835 SetLedColor(fStatusFTMLed, kLedGreenCheck, time);
2836 if (s.index==FTM::StateMachine::kConnected ||
2837 s.index==FTM::StateMachine::kIdle) // Dim connection / FTM connected
2838 enable = true;
2839
2840 fFtmStartRun->setEnabled(!configuring && enable);
2841 fFtmStopRun->setEnabled(!configuring && (enable || s.index==FTM::StateMachine::kTriggerOn));
2842
2843 fTriggerWidget->setEnabled(enable);
2844 fFtuGroupEnable->setEnabled(enable);
2845 fRatesControls->setEnabled(enable);
2846 fFtuWidget->setEnabled(s.index>FTM::StateMachine::kDisconnected);
2847
2848 if (s.index>=FTM::StateMachine::kConnected)
2849 SetFtuStatusLed(time);
2850 else
2851 {
2852 SetLedColor(fStatusFTULed, kLedGray, time);
2853 fStatusFTULabel->setText("Offline");
2854 fStatusFTULabel->setToolTip("FTM is not online.");
2855 }
2856 }
2857
2858 if (server=="FAD_CONTROL")
2859 {
2860 fStatusFADLabel->setText(s.name.c_str());
2861 fStatusFADLabel->setToolTip(s.comment.c_str());
2862
2863 bool enable = false;
2864
2865 if (s.index<FAD::kOffline) // No Dim connection
2866 {
2867 SetLedColor(fStatusFADLed, kLedGray, time);
2868
2869 // Timing problem - sometimes they stay gray :(
2870 //for (int i=0; i<40; i++)
2871 // SetLedColor(fFadLED[i], kLedGray, time);
2872
2873 /*
2874 fStatusEventBuilderLabel->setText("Offline");
2875 fStatusEventBuilderLabel->setToolTip("No connection to fadctrl.");
2876 fEvtBldWidget->setEnabled(false);
2877
2878 SetLedColor(fStatusEventBuilderLed, kLedGray, time);
2879 */
2880 }
2881 if (s.index==FAD::kOffline) // Dim connection / FTM disconnected
2882 SetLedColor(fStatusFADLed, kLedRed, time);
2883 if (s.index==FAD::kDisconnected) // Dim connection / FTM disconnected
2884 SetLedColor(fStatusFADLed, kLedOrange, time);
2885 if (s.index==FAD::kConnecting) // Dim connection / FTM disconnected
2886 {
2887 SetLedColor(fStatusFADLed, kLedYellow, time);
2888 // FIXME FIXME FIXME: The LEDs are not displayed when disabled!
2889 enable = true;
2890 }
2891 if (s.index>=FAD::kConnected) // Dim connection / FTM connected
2892 {
2893 SetLedColor(fStatusFADLed, kLedGreen, time);
2894 enable = true;
2895 }
2896
2897 fFadWidget->setEnabled(enable);
2898
2899 fFadStart->setEnabled(s.index==FAD::kOffline);
2900 fFadStop->setEnabled(s.index>FAD::kOffline);
2901 fFadAbort->setEnabled(s.index>FAD::kOffline);
2902 fFadSoftReset->setEnabled(s.index>FAD::kOffline);
2903 fFadHardReset->setEnabled(s.index>FAD::kOffline);
2904 }
2905
2906 if (server=="FSC_CONTROL")
2907 {
2908 fStatusFSCLabel->setText(s.name.c_str());
2909 fStatusFSCLabel->setToolTip(s.comment.c_str());
2910
2911 bool enable = false;
2912
2913 if (s.index<1) // No Dim connection
2914 SetLedColor(fStatusFSCLed, kLedGray, time);
2915 if (s.index==1) // Dim connection / FTM disconnected
2916 SetLedColor(fStatusFSCLed, kLedRed, time);
2917 if (s.index>=2) // Dim connection / FTM disconnected
2918 {
2919 SetLedColor(fStatusFSCLed, kLedGreen, time);
2920 enable = true;
2921 }
2922
2923 fAuxWidget->setEnabled(enable);
2924 }
2925
2926 if (server=="DRIVE_CONTROL")
2927 {
2928 fStatusDriveLabel->setText(s.name.c_str());
2929 fStatusDriveLabel->setToolTip(s.comment.c_str());
2930
2931 bool enable = false;
2932
2933 if (s.index<1) // No Dim connection
2934 SetLedColor(fStatusDriveLed, kLedGray, time);
2935 if (s.index==1) // Dim connection / No connection to cosy
2936 SetLedColor(fStatusDriveLed, kLedRed, time);
2937 if (s.index==2 || s.index==3) // Not Ready
2938 SetLedColor(fStatusDriveLed, kLedGreenBar, time);
2939 if (s.index==4 || s.index==5) // Connected / Armed
2940 SetLedColor(fStatusDriveLed, kLedGreen, time);
2941 if (s.index==6) // Moving
2942 SetLedColor(fStatusDriveLed, kLedInProgress, time);
2943 if (s.index==7) // Tracking
2944 SetLedColor(fStatusDriveLed, kLedGreenCheck, time);
2945 if (s.index==99) // Error
2946 SetLedColor(fStatusDriveLed, kLedGreenWarn, time);
2947 }
2948
2949 if (server=="BIAS_CONTROL")
2950 {
2951 fStatusBiasLabel->setText(s.name.c_str());
2952 fStatusBiasLabel->setToolTip(s.comment.c_str());
2953
2954 if (s.index<1) // No Dim connection
2955 SetLedColor(fStatusBiasLed, kLedGray, time);
2956 if (s.index==BIAS::kDisconnected) // Dim connection / FTM disconnected
2957 SetLedColor(fStatusBiasLed, kLedRed, time);
2958 if (s.index==BIAS::kConnecting || s.index==BIAS::kInitializing) // Connecting / Initializing
2959 SetLedColor(fStatusBiasLed, kLedOrange, time);
2960 if (s.index==BIAS::kVoltageOff) // At reference
2961 SetLedColor(fStatusBiasLed, kLedGreenBar, time);
2962 if (s.index==BIAS::kNotReferenced) // At reference
2963 SetLedColor(fStatusBiasLed, kLedGreenWarn, time);
2964 if (s.index==BIAS::kRamping) // Ramping
2965 SetLedColor(fStatusBiasLed, kLedInProgress, time);
2966 if (s.index==BIAS::kVoltageOn) // At reference
2967 SetLedColor(fStatusBiasLed, kLedGreenCheck, time);
2968 if (s.index==BIAS::kOverCurrent) // Over current
2969 SetLedColor(fStatusBiasLed, kLedWarnBorder, time);
2970 if (s.index==BIAS::kExpertMode) // ExpertMode
2971 SetLedColor(fStatusBiasLed, kLedWarnTriangleBorder, time);
2972
2973 fBiasWidget->setEnabled(s.index>=3);
2974 }
2975
2976 if (server=="FEEDBACK")
2977 {
2978 fStatusFeedbackLabel->setText(s.name.c_str());
2979 fStatusFeedbackLabel->setToolTip(s.comment.c_str());
2980
2981 if (s.index>6) // Running
2982 SetLedColor(fStatusFeedbackLed, kLedGreenCheck, time);
2983 if (s.index==5 || s.index==6) // Idle
2984 SetLedColor(fStatusFeedbackLed, kLedGreen, time);
2985 if (s.index==4) // Connected
2986 SetLedColor(fStatusFeedbackLed, kLedYellow, time);
2987 if (s.index==3) // Connecting
2988 SetLedColor(fStatusFeedbackLed, kLedOrange, time);
2989 if (s.index<3) // NoDim / Disconnected
2990 SetLedColor(fStatusFeedbackLed, kLedRed, time);
2991 if (s.index<1) // No Dim connection
2992 SetLedColor(fStatusFeedbackLed, kLedGray, time);
2993
2994 fFeedbackWidget->setEnabled(s.index>=3);
2995 fFeedbackCalibrate->setEnabled(s.index==4);
2996 fFeedbackStop->setEnabled(s.index>4);
2997 fFeedbackTempStart->setEnabled(s.index==4);
2998 fFeedbackTempOffset->setEnabled(s.index<=4);
2999 fFeedbackOutputEnable->setEnabled(s.index<=6);
3000 fFeedbackOutputDisable->setEnabled(s.index!=5 && s.index!=6);
3001
3002 fFeedbackFrameLeft->setEnabled(s.index!=5 && s.index!=7);
3003 fFeedbackCanvLeft->setEnabled(s.index!=5 && s.index!=7);
3004 }
3005
3006 if (server=="DATA_LOGGER")
3007 {
3008 fStatusLoggerLabel->setText(s.name.c_str());
3009 fStatusLoggerLabel->setToolTip(s.comment.c_str());
3010
3011 bool enable = true;
3012
3013 if (s.index<30) // Ready/Waiting
3014 SetLedColor(fStatusLoggerLed, kLedYellow, time);
3015 if (s.index==30) // Ready/Waiting
3016 SetLedColor(fStatusLoggerLed, kLedGreen, time);
3017 if (s.index<-1) // Offline
3018 {
3019 SetLedColor(fStatusLoggerLed, kLedGray, time);
3020 enable = false;
3021 }
3022 if (s.index>=0x100) // Error
3023 SetLedColor(fStatusLoggerLed, kLedRed, time);
3024 if (s.index==40) // Logging
3025 SetLedColor(fStatusLoggerLed, kLedGreen, time);
3026
3027 fLoggerWidget->setEnabled(enable);
3028 fLoggerStart->setEnabled(s.index>-1 && s.index<30);
3029 fLoggerStop->setEnabled(s.index>=30);
3030 }
3031
3032 if (server=="CHAT")
3033 {
3034 fStatusChatLabel->setText(s.name.c_str());
3035
3036 fChatOnline = s.index==0;
3037
3038 SetLedColor(fStatusChatLed, fChatOnline ? kLedGreen : kLedGray, time);
3039
3040 fChatSend->setEnabled(fChatOnline);
3041 fChatMessage->setEnabled(fChatOnline);
3042 }
3043
3044 if (server=="SCHEDULER")
3045 {
3046 fStatusSchedulerLabel->setText(s.name.c_str());
3047
3048 SetLedColor(fStatusSchedulerLed, s.index>=0 ? kLedGreen : kLedRed, time);
3049 }
3050 }
3051
3052 void on_fTabWidget_currentChanged(int which)
3053 {
3054 if (fTabWidget->tabText(which)=="Chat")
3055 fTabWidget->setTabIcon(which, QIcon());
3056 }
3057
3058 void handleWrite(const Time &time, const string &text, int qos)
3059 {
3060 stringstream out;
3061
3062 if (text.substr(0, 6)=="CHAT: ")
3063 {
3064 if (qos==MessageImp::kDebug)
3065 return;
3066
3067 out << "<font size='-1' color='navy'>[<B>";
3068 out << time.GetAsStr("%H:%M:%S");
3069 out << "</B>]</FONT> " << text.substr(6);
3070 fChatText->append(out.str().c_str());
3071
3072 if (fTabWidget->tabText(fTabWidget->currentIndex())=="Chat")
3073 return;
3074
3075 static int num = 0;
3076 if (num++<2)
3077 return;
3078
3079 for (int i=0; i<fTabWidget->count(); i++)
3080 if (fTabWidget->tabText(i)=="Chat")
3081 {
3082 fTabWidget->setTabIcon(i, QIcon(":/Resources/icons/warning 3.png"));
3083 break;
3084 }
3085
3086 return;
3087 }
3088
3089
3090 out << "<font style='font-family:monospace' color='";
3091
3092 switch (qos)
3093 {
3094 case kMessage: out << "black"; break;
3095 case kInfo: out << "green"; break;
3096 case kWarn: out << "#FF6600"; break;
3097 case kError: out << "maroon"; break;
3098 case kFatal: out << "maroon"; break;
3099 case kDebug: out << "navy"; break;
3100 default: out << "navy"; break;
3101 }
3102 out << "'>";
3103 out << time.GetAsStr("%H:%M:%S.%f").substr(0,12);
3104 out << " - " << text << "</font>";
3105
3106 fLogText->append(out.str().c_str());
3107
3108 if (qos>=kWarn && qos!=kDebug)
3109 fTextEdit->append(out.str().c_str());
3110 }
3111
3112 void IndicateStateChange(const Time &time, const std::string &server)
3113 {
3114 const State s = GetState(server, GetCurrentState(server));
3115
3116 QApplication::postEvent(this,
3117 new FunctionEvent(boost::bind(&FactGui::handleStateChanged, this, time, server, s)));
3118 }
3119
3120 int Write(const Time &time, const string &txt, int qos)
3121 {
3122 QApplication::postEvent(this,
3123 new FunctionEvent(boost::bind(&FactGui::handleWrite, this, time, txt, qos)));
3124
3125 return 0;
3126 }
3127
3128 // ====================== Dim infoHandler================================
3129
3130 void handleDimService(const string &txt)
3131 {
3132 fDimSvcText->append(txt.c_str());
3133 }
3134
3135 void infoHandlerService(DimInfo &info)
3136 {
3137 const string fmt = string(info.getFormat()).empty() ? "C" : info.getFormat();
3138
3139 stringstream dummy;
3140 const Converter conv(dummy, fmt, false);
3141
3142 const Time tm(info.getTimestamp(), info.getTimestampMillisecs()*1000);
3143
3144 stringstream out;
3145 out << "<font size'-1' color='navy'>[";
3146 out << tm.GetAsStr("%H:%M:%S.%f").substr(0,12);
3147 out << "]</font> <B>" << info.getName() << "</B> - ";
3148
3149 bool iserr = 2;
3150 if (!conv)
3151 {
3152 out << "Compilation of format string '" << fmt << "' failed!";
3153 }
3154 else
3155 {
3156 try
3157 {
3158 const string dat = info.getSize()==0 ? "&lt;empty&gt;" : conv.GetString(info.getData(), info.getSize());
3159 out << dat;
3160 iserr = info.getSize()==0;
3161 }
3162 catch (const runtime_error &e)
3163 {
3164 out << "Conversion to string failed!<pre>" << e.what() << "</pre>";
3165 }
3166 }
3167
3168 // srand(hash<string>()(string(info.getName())));
3169 // int bg = rand()&0xffffff;
3170
3171 int bg = hash<string>()(string(info.getName()));
3172
3173 // allow only light colors
3174 bg = ~(bg&0x1f1f1f)&0xffffff;
3175
3176 if (iserr==2)
3177 bg = 0xffffff;
3178
3179 stringstream bgcol;
3180 bgcol << hex << setfill('0') << setw(6) << bg;
3181
3182 const string col = iserr==0 ? "black" : (iserr==1 ? "#FF6600" : "black");
3183 const string str = "<table width='100%' bgcolor=#"+bgcol.str()+"><tr><td><font color='"+col+"'>"+out.str()+"</font></td></tr></table>";
3184
3185 QApplication::postEvent(this,
3186 new FunctionEvent(boost::bind(&FactGui::handleDimService, this, str)));
3187 }
3188
3189 void CallInfoHandler(void (FactGui::*handler)(const DimData&), const DimData &d)
3190 {
3191 fInHandler = true;
3192 (this->*handler)(d);
3193 fInHandler = false;
3194 }
3195
3196 /*
3197 void CallInfoHandler(const boost::function<void()> &func)
3198 {
3199 // This ensures that newly received values are not sent back to the emitter
3200 // because changing the value emits the valueChanged signal (or similar)
3201 fInHandler = true;
3202 func();
3203 fInHandler = false;
3204 }*/
3205
3206 void PostInfoHandler(void (FactGui::*handler)(const DimData&))
3207 {
3208 //const boost::function<void()> f = boost::bind(handler, this, DimData(getInfo()));
3209
3210 FunctionEvent *evt = new FunctionEvent(boost::bind(&FactGui::CallInfoHandler, this, handler, DimData(getInfo())));
3211 // FunctionEvent *evt = new FunctionEvent(boost::bind(&FactGui::CallInfoHandler, this, f));
3212 // FunctionEvent *evt = new FunctionEvent(boost::bind(handler, this, DimData(getInfo()))));
3213
3214 QApplication::postEvent(this, evt);
3215 }
3216
3217 void infoHandler()
3218 {
3219 // Initialize the time-stamp (what a weird workaround...)
3220 if (getInfo())
3221 getInfo()->getTimestamp();
3222
3223 if (getInfo()==&fDimDNS)
3224 return PostInfoHandler(&FactGui::handleDimDNS);
3225#ifdef DEBUG_DIM
3226 cout << "HandleDimInfo " << getInfo()->getName() << endl;
3227#endif
3228 if (getInfo()==&fDimLoggerStats)
3229 return PostInfoHandler(&FactGui::handleLoggerStats);
3230
3231// if (getInfo()==&fDimFadFiles)
3232// return PostInfoHandler(&FactGui::handleFadFiles);
3233
3234 if (getInfo()==&fDimFadWriteStats)
3235 return PostInfoHandler(&FactGui::handleFadWriteStats);
3236
3237 if (getInfo()==&fDimFadConnections)
3238 return PostInfoHandler(&FactGui::handleFadConnections);
3239
3240 if (getInfo()==&fDimFadFwVersion)
3241 return PostInfoHandler(&FactGui::handleFadFwVersion);
3242
3243 if (getInfo()==&fDimFadRunNumber)
3244 return PostInfoHandler(&FactGui::handleFadRunNumber);
3245
3246 if (getInfo()==&fDimFadDNA)
3247 return PostInfoHandler(&FactGui::handleFadDNA);
3248
3249 if (getInfo()==&fDimFadTemperature)
3250 return PostInfoHandler(&FactGui::handleFadTemperature);
3251
3252 if (getInfo()==&fDimFadRefClock)
3253 return PostInfoHandler(&FactGui::handleFadRefClock);
3254
3255 if (getInfo()==&fDimFadRoi)
3256 return PostInfoHandler(&FactGui::handleFadRoi);
3257
3258 if (getInfo()==&fDimFadDac)
3259 return PostInfoHandler(&FactGui::handleFadDac);
3260
3261 if (getInfo()==&fDimFadDrsCalibration)
3262 return PostInfoHandler(&FactGui::handleFadDrsCalibration);
3263
3264 if (getInfo()==&fDimFadPrescaler)
3265 return PostInfoHandler(&FactGui::handleFadPrescaler);
3266
3267 if (getInfo()==&fDimFadStatus)
3268 return PostInfoHandler(&FactGui::handleFadStatus);
3269
3270 if (getInfo()==&fDimFadStatistics1)
3271 return PostInfoHandler(&FactGui::handleFadStatistics1);
3272
3273 if (getInfo()==&fDimFadStatistics2)
3274 return PostInfoHandler(&FactGui::handleFadStatistics2);
3275
3276 if (getInfo()==&fDimFadEvents)
3277 return PostInfoHandler(&FactGui::handleFadEvents);
3278
3279 if (getInfo()==&fDimFadRuns)
3280 return PostInfoHandler(&FactGui::handleFadRuns);
3281
3282 if (getInfo()==&fDimFadStartRun)
3283 return PostInfoHandler(&FactGui::handleFadStartRun);
3284
3285 if (getInfo()==&fDimFadRawData)
3286 return PostInfoHandler(&FactGui::handleFadRawData);
3287
3288 if (getInfo()==&fDimFadEventData)
3289 return PostInfoHandler(&FactGui::handleFadEventData);
3290
3291/*
3292 if (getInfo()==&fDimFadSetup)
3293 return PostInfoHandler(&FactGui::handleFadSetup);
3294*/
3295 if (getInfo()==&fDimLoggerFilenameNight)
3296 return PostInfoHandler(&FactGui::handleLoggerFilenameNight);
3297
3298 if (getInfo()==&fDimLoggerNumSubs)
3299 return PostInfoHandler(&FactGui::handleLoggerNumSubs);
3300
3301 if (getInfo()==&fDimLoggerFilenameRun)
3302 return PostInfoHandler(&FactGui::handleLoggerFilenameRun);
3303
3304 if (getInfo()==&fDimFtmTriggerRates)
3305 return PostInfoHandler(&FactGui::handleFtmTriggerRates);
3306
3307 if (getInfo()==&fDimFtmCounter)
3308 return PostInfoHandler(&FactGui::handleFtmCounter);
3309
3310 if (getInfo()==&fDimFtmDynamicData)
3311 return PostInfoHandler(&FactGui::handleFtmDynamicData);
3312
3313 if (getInfo()==&fDimFtmPassport)
3314 return PostInfoHandler(&FactGui::handleFtmPassport);
3315
3316 if (getInfo()==&fDimFtmFtuList)
3317 return PostInfoHandler(&FactGui::handleFtmFtuList);
3318
3319 if (getInfo()==&fDimFtmStaticData)
3320 return PostInfoHandler(&FactGui::handleFtmStaticData);
3321
3322 if (getInfo()==&fDimFtmError)
3323 return PostInfoHandler(&FactGui::handleFtmError);
3324
3325 if (getInfo()==&fDimFscTemp)
3326 return PostInfoHandler(&FactGui::handleFscTemp);
3327
3328 if (getInfo()==&fDimFscVolt)
3329 return PostInfoHandler(&FactGui::handleFscVolt);
3330
3331 if (getInfo()==&fDimFscCurrent)
3332 return PostInfoHandler(&FactGui::handleFscCurrent);
3333
3334 if (getInfo()==&fDimFscHumidity)
3335 return PostInfoHandler(&FactGui::handleFscHumidity);
3336
3337 if (getInfo()==&fDimBiasVolt)
3338 return PostInfoHandler(&FactGui::handleBiasVolt);
3339
3340 if (getInfo()==&fDimBiasCurrent)
3341 return PostInfoHandler(&FactGui::handleBiasCurrent);
3342
3343 if (getInfo()==&fDimFeedbackReference)
3344 return PostInfoHandler(&FactGui::handleFeedbackReference);
3345
3346 if (getInfo()==&fDimFeedbackDeviation)
3347 return PostInfoHandler(&FactGui::handleFeedbackDeviation);
3348
3349 if (getInfo()==&fDimFeedbackCalibration)
3350 return PostInfoHandler(&FactGui::handleFeedbackCalibration);
3351
3352 if (getInfo()==&fDimRateScan)
3353 return PostInfoHandler(&FactGui::handleRateScan);
3354
3355// if (getInfo()==&fDimFadFiles)
3356// return PostInfoHandler(&FactGui::handleFadFiles);
3357
3358 for (map<string,DimInfo*>::iterator i=fServices.begin(); i!=fServices.end(); i++)
3359 if (i->second==getInfo())
3360 {
3361 infoHandlerService(*i->second);
3362 return;
3363 }
3364
3365 DimNetwork::infoHandler();
3366 }
3367
3368
3369 // ======================================================================
3370
3371 bool event(QEvent *evt)
3372 {
3373 if (dynamic_cast<FunctionEvent*>(evt))
3374 return static_cast<FunctionEvent*>(evt)->Exec();
3375
3376 if (dynamic_cast<CheckBoxEvent*>(evt))
3377 {
3378 const QStandardItem &item = static_cast<CheckBoxEvent*>(evt)->item;
3379 const QStandardItem *par = item.parent();
3380 if (par)
3381 {
3382 const QString server = par->text();
3383 const QString service = item.text();
3384
3385 const string s = (server+'/'+service).toStdString();
3386
3387 if (item.checkState()==Qt::Checked)
3388 SubscribeService(s);
3389 else
3390 UnsubscribeService(s);
3391 }
3392 }
3393
3394 return MainWindow::event(evt); // unrecognized
3395 }
3396
3397 void on_fDimCmdSend_clicked()
3398 {
3399 const QString server = fDimCmdServers->currentIndex().data().toString();
3400 const QString command = fDimCmdCommands->currentIndex().data().toString();
3401 const QString arguments = fDimCmdLineEdit->displayText();
3402
3403 // FIXME: Sending a command exactly when the info Handler changes
3404 // the list it might lead to confusion.
3405 try
3406 {
3407 SendDimCommand(server.toStdString(), command.toStdString()+" "+arguments.toStdString());
3408 fTextEdit->append("<font color='green'>Command '"+server+'/'+command+"' successfully emitted.</font>");
3409 fDimCmdLineEdit->clear();
3410 }
3411 catch (const runtime_error &e)
3412 {
3413 stringstream txt;
3414 txt << e.what();
3415
3416 string buffer;
3417 while (getline(txt, buffer, '\n'))
3418 fTextEdit->append(("<font color='red'><pre>"+buffer+"</pre></font>").c_str());
3419 }
3420 }
3421
3422#ifdef HAVE_ROOT
3423 void slot_RootEventProcessed(TObject *obj, unsigned int evt, TCanvas *canv)
3424 {
3425 // kMousePressEvent // TCanvas processed QEvent mousePressEvent
3426 // kMouseMoveEvent // TCanvas processed QEvent mouseMoveEvent
3427 // kMouseReleaseEvent // TCanvas processed QEvent mouseReleaseEvent
3428 // kMouseDoubleClickEvent // TCanvas processed QEvent mouseDoubleClickEvent
3429 // kKeyPressEvent // TCanvas processed QEvent keyPressEvent
3430 // kEnterEvent // TCanvas processed QEvent enterEvent
3431 // kLeaveEvent // TCanvas processed QEvent leaveEvent
3432
3433 if (dynamic_cast<TCanvas*>(obj))
3434 return;
3435
3436 TQtWidget *tipped = static_cast<TQtWidget*>(sender());
3437
3438 if (evt==11/*kMouseReleaseEvent*/)
3439 return;
3440
3441 if (evt==61/*kMouseDoubleClickEvent*/)
3442 return;
3443
3444 if (obj)
3445 {
3446 // Find the object which will get picked by the GetObjectInfo
3447 // due to buffer overflows in many root-versions
3448 // in TH1 and TProfile we have to work around and implement
3449 // our own GetObjectInfo which make everything a bit more
3450 // complicated.
3451 canv->cd();
3452#if ROOT_VERSION_CODE > ROOT_VERSION(5,22,00)
3453 const char *objectInfo =
3454 obj->GetObjectInfo(tipped->GetEventX(),tipped->GetEventY());
3455#else
3456 const char *objectInfo = dynamic_cast<TH1*>(obj) ?
3457 "" : obj->GetObjectInfo(tipped->GetEventX(),tipped->GetEventY());
3458#endif
3459
3460 QString tipText;
3461 tipText += obj->GetName();
3462 tipText += " [";
3463 tipText += obj->ClassName();
3464 tipText += "]: ";
3465 tipText += objectInfo;
3466
3467 fStatusBar->showMessage(tipText, 3000);
3468 }
3469
3470 gSystem->DispatchOneEvent(kFALSE);
3471 //gSystem->ProcessEvents();
3472 //QWhatsThis::display(tipText)
3473 }
3474
3475 void slot_RootUpdate()
3476 {
3477 gSystem->DispatchOneEvent(kFALSE);
3478 //gSystem->ProcessEvents();
3479 QTimer::singleShot(10, this, SLOT(slot_RootUpdate()));
3480 }
3481#endif
3482
3483 void ChoosePatchThreshold(Camera &cam, int isw)
3484 {
3485 cam.Reset();
3486
3487 fThresholdIdx->setValue(isw);
3488
3489 const int ihw = isw<0 ? 0 : fPatchMapHW[isw];
3490
3491 fPatchRate->setEnabled(isw>=0);
3492 fThresholdCrate->setEnabled(isw>=0);
3493 fThresholdBoard->setEnabled(isw>=0);
3494 fThresholdPatch->setEnabled(isw>=0);
3495
3496 if (isw<0)
3497 return;
3498
3499 const int patch = ihw%4;
3500 const int board = (ihw/4)%10;
3501 const int crate = (ihw/4)/10;
3502
3503 fInChoosePatchTH = true;
3504
3505 fThresholdCrate->setValue(crate);
3506 fThresholdBoard->setValue(board);
3507 fThresholdPatch->setValue(patch);
3508
3509 fInChoosePatchTH = false;
3510
3511 fThresholdVal->setValue(fFtmStaticData.fThreshold[ihw]);
3512 fPatchRate->setValue(fTriggerRates.fPatchRate[ihw]);
3513 fBoardRate->setValue(fTriggerRates.fBoardRate[ihw/4]);
3514
3515 // Loop over the software idx of all pixels
3516// for (unsigned int i=0; i<1440; i++)
3517// if (fPatchHW[i]==ihw)
3518// cam.SetBold(i);
3519 }
3520
3521 /*
3522 void ChoosePatchBias(Camera &cam, int isw)
3523 {
3524 cam.Reset();
3525
3526 fBiasChannel->setValue(isw);
3527
3528 const int ihw = isw<0 ? 0 : fPatchMapHW[isw];
3529
3530 fBiasCurrent->setEnabled(isw>=0);
3531 fBiasCrate->setEnabled(isw>=0);
3532 fBiasBoard->setEnabled(isw>=0);
3533 fBiasPatch->setEnabled(isw>=0);
3534
3535 if (isw<0)
3536 return;
3537
3538 const int patch = ihw%4;
3539 const int board = (ihw/4)%10;
3540 const int crate = (ihw/4)/10;
3541
3542 fInChoosePatchBias = true;
3543
3544 fBiasCrate->setValue(crate);
3545 fBiasBoard->setValue(board);
3546 fBiasPatch->setValue(patch);
3547
3548 fInChoosePatchBias = false;
3549
3550 if (fVecBias.size()>0)
3551 {
3552 // FIXME: Mapping
3553 fBiasVoltDac->setValue(fVecBias[ihw]);
3554 fBiasVolt->setValue(fVecBias[ihw]*90./4096);
3555 }
3556
3557 fBiasCurrent->setValue(cam.GetData(isw));
3558
3559 // Loop over the software idx of all pixels
3560 for (unsigned int i=0; i<1440; i++)
3561 if (fPatchHW[i]==ihw)
3562 cam.SetBold(i);
3563 }*/
3564
3565 void slot_ChoosePixelThreshold(int isw)
3566 {
3567 fPixelIdx->setValue(isw);
3568
3569 const PixelMapEntry &entry = fPixelMap.index(isw);
3570 fPixelEnable->setChecked(fFtmStaticData.IsEnabled(entry.hw()));
3571 }
3572
3573 void slot_CameraDoubleClick(int isw)
3574 {
3575 fPixelIdx->setValue(isw);
3576
3577 const PixelMapEntry &entry = fPixelMap.index(isw);
3578 Dim::SendCommand("FTM_CONTROL/TOGGLE_PIXEL", uint16_t(entry.hw()));
3579 }
3580
3581 void slot_CameraMouseMove(int isw)
3582 {
3583 const PixelMapEntry &entry = fPixelMap.index(isw);
3584
3585 QString tipText;
3586 tipText += fRatesCanv->GetName();
3587 ostringstream str;
3588 str << setfill('0') <<
3589 " || HW: " << entry.crate() << "|" << entry.board() << "|" << entry.patch() << "|" << entry.pixel() << " (crate|board|patch|pixel)" <<
3590 " || HV: " << entry.hv_board << "|" << setw(2) << entry.hv_channel << " (board|channel)" <<
3591 " || ID: " << isw;
3592
3593
3594 tipText += str.str().c_str();
3595 fStatusBar->showMessage(tipText, 3000);
3596 }
3597
3598 void on_fThresholdIdx_valueChanged(int isw)
3599 {
3600 // fRatesCanv->SetBold(isw);
3601 // fRatesCanv->updateGL();
3602 }
3603
3604 void UpdateThresholdIdx()
3605 {
3606 if (fInChoosePatchTH)
3607 return;
3608
3609 const int crate = fThresholdCrate->value();
3610 const int board = fThresholdBoard->value();
3611 const int patch = fThresholdPatch->value();
3612
3613 const int ihw = patch + board*4 + crate*40;
3614
3615 int isw = 0;
3616 for (; isw<160; isw++)
3617 if (ihw==fPatchMapHW[isw])
3618 break;
3619
3620 on_fThresholdIdx_valueChanged(isw);
3621 }
3622
3623 void on_fPixelIdx_valueChanged(int isw)
3624 {
3625 int ii = 0;
3626 for (; ii<160; ii++)
3627 if (fPixelMap.index(isw).hw()/9==fPatchMapHW[ii])
3628 break;
3629
3630 fRatesCanv->SetWhite(isw);
3631 ChoosePatchThreshold(*fRatesCanv, ii);
3632
3633 const PixelMapEntry &entry = fPixelMap.index(isw);
3634 fPixelEnable->setChecked(fFtmStaticData.IsEnabled(entry.hw()));
3635 }
3636
3637 // ------------------- Bias display ---------------------
3638
3639 void UpdateBiasValues()
3640 {
3641 const int b = fBiasHvBoard->value();
3642 const int c = fBiasHvChannel->value();
3643
3644 const int ihw = b*32+c;
3645
3646 if (fVecBiasVolt.size()>0)
3647 {
3648 fBiasVoltCur->setValue(fVecBiasVolt[ihw]*90./4096);
3649 fBiasVoltRef->setValue(fVecBiasVolt[ihw+416]*90./4096);
3650
3651 SetLedColor(fBiasNominalLed,
3652 fVecBiasVolt[ihw]==fVecBiasVolt[ihw+416]?kLedGreen:kLedRed, Time());
3653 }
3654
3655 if (fVecBiasCurrent.size()>0)
3656 {
3657 double val = abs(fVecBiasCurrent[ihw]);
3658 if (fBiasOffsets.size()>0)
3659 val -= fBiasOffsets[ihw];
3660 val *= 5000/4096;
3661
3662 fBiasCurrent->setValue(val);
3663 SetLedColor(fBiasOverCurrentLed,
3664 fVecBiasCurrent[ihw]<0?kLedRed:kLedGreen, Time());
3665 }
3666
3667 if (fBiasOffsets.size()>0)
3668 fBiasOffset->setValue(fBiasOffsets[ihw]*5000./4096);
3669 fBiasOffset->setEnabled(fBiasOffsets.size()>0);
3670 }
3671
3672 void UpdateBiasCam(const PixelMapEntry &entry)
3673 {
3674 fInChooseBiasCam = true;
3675
3676 fBiasCamCrate->setValue(entry.crate());
3677 fBiasCamBoard->setValue(entry.board());
3678 fBiasCamPatch->setValue(entry.patch());
3679 fBiasCamPixel->setValue(entry.pixel());
3680
3681 fInChooseBiasCam = false;
3682 }
3683
3684 void BiasHvChannelChanged()
3685 {
3686 if (fInChooseBiasHv)
3687 return;
3688
3689 const int b = fBiasHvBoard->value();
3690 const int ch = fBiasHvChannel->value();
3691
3692 // FIXME: Mark corresponding patch in camera
3693 const PixelMapEntry &entry = fPixelMap.hv(b, ch);
3694 fBiasCamV->SetWhite(entry.index);
3695 fBiasCamA->SetWhite(entry.index);
3696 fBiasCamV->updateCamera();
3697 fBiasCamA->updateCamera();
3698
3699 UpdateBiasCam(entry);
3700 UpdateBiasValues();
3701 }
3702
3703 void UpdateBiasHv(const PixelMapEntry &entry)
3704 {
3705 fInChooseBiasHv = true;
3706
3707 fBiasHvBoard->setValue(entry.hv_board);
3708 fBiasHvChannel->setValue(entry.hv_channel);
3709
3710 fInChooseBiasHv = false;
3711 }
3712
3713 void BiasCamChannelChanged()
3714 {
3715 if (fInChooseBiasCam)
3716 return;
3717
3718 const int crate = fBiasCamCrate->value();
3719 const int board = fBiasCamBoard->value();
3720 const int patch = fBiasCamPatch->value();
3721 const int pixel = fBiasCamPixel->value();
3722
3723 // FIXME: Display corresponding patches
3724 const PixelMapEntry &entry = fPixelMap.cbpx(crate, board, patch, pixel);
3725 fBiasCamV->SetWhite(entry.index);
3726 fBiasCamA->SetWhite(entry.index);
3727 fBiasCamV->updateCamera();
3728 fBiasCamA->updateCamera();
3729
3730 UpdateBiasHv(entry);
3731 UpdateBiasValues();
3732 }
3733
3734 void slot_ChooseBiasChannel(int isw)
3735 {
3736 const PixelMapEntry &entry = fPixelMap.index(isw);
3737
3738 UpdateBiasHv(entry);
3739 UpdateBiasCam(entry);
3740 UpdateBiasValues();
3741 }
3742
3743 void on_fBiasDispRefVolt_stateChanged(int = 0)
3744 {
3745 // FIXME: Display patches for which ref==cur
3746
3747 valarray<double> dat(0., 1440);
3748
3749 int offset = 0;
3750 if (!fBiasDispRefVolt->isChecked())
3751 fBiasCamV->setTitle("Applied BIAS voltage");
3752 else
3753 {
3754 fBiasCamV->setTitle("Reference BIAS voltage");
3755 offset = 416;
3756 }
3757
3758 if (fVecBiasVolt.size()>0)
3759 {
3760 for (int i=0; i<1440; i++)
3761 {
3762 const PixelMapEntry &entry = fPixelMap.index(i);
3763 dat[i] = fVecBiasVolt[entry.hv()+offset]*90./4096;
3764
3765 fBiasCamV->highlightPixel(i, fVecBiasVolt[entry.hv()]!=fVecBiasVolt[entry.hv()+416]);
3766 }
3767
3768 fBiasCamV->SetData(dat);
3769 }
3770
3771 fBiasCamV->updateCamera();
3772 }
3773
3774 // ------------------------------------------------------
3775
3776 void on_fPixelEnable_stateChanged(int b)
3777 {
3778 if (fInHandler)
3779 return;
3780
3781 const PixelMapEntry &entry = fPixelMap.index(fPixelIdx->value());
3782
3783 Dim::SendCommand(b==Qt::Unchecked ?
3784 "FTM_CONTROL/DISABLE_PIXEL" : "FTM_CONTROL/ENABLE_PIXEL",
3785 uint16_t(entry.hw()));
3786 }
3787
3788 void on_fPixelDisableOthers_clicked()
3789 {
3790 const PixelMapEntry &entry = fPixelMap.index(fPixelIdx->value());
3791 Dim::SendCommand("FTM_CONTROL/DISABLE_ALL_PIXELS_EXCEPT", uint16_t(entry.hw()));
3792 }
3793
3794 void on_fThresholdDisableOthers_clicked()
3795 {
3796 const int16_t isw = fThresholdIdx->value();
3797 const int16_t ihw = isw<0 ? -1 : fPatchMapHW[isw];
3798 if (ihw<0)
3799 return;
3800
3801 Dim::SendCommand("FTM_CONTROL/DISABLE_ALL_PATCHES_EXCEPT", ihw);
3802 }
3803
3804 void on_fThresholdEnablePatch_clicked()
3805 {
3806 const int16_t isw = fThresholdIdx->value();
3807 const int16_t ihw = isw<0 ? -1 : fPatchMapHW[isw];
3808 if (ihw<0)
3809 return;
3810
3811 Dim::SendCommand("FTM_CONTROL/ENABLE_PATCH", ihw);
3812 }
3813
3814 void on_fThresholdDisablePatch_clicked()
3815 {
3816 const int16_t isw = fThresholdIdx->value();
3817 const int16_t ihw = isw<0 ? -1 : fPatchMapHW[isw];
3818 if (ihw<0)
3819 return;
3820
3821 Dim::SendCommand("FTM_CONTROL/DISABLE_PATCH", ihw);
3822 }
3823
3824 void on_fThresholdVal_valueChanged(int v)
3825 {
3826 fThresholdVolt->setValue(2500./4095*v);
3827
3828 const int32_t isw = fThresholdIdx->value();
3829 const int32_t ihw = isw<0 ? -1 : fPatchMapHW[isw];
3830
3831 const int32_t d[2] = { ihw, v };
3832
3833 if (!fInHandler)
3834 Dim::SendCommand("FTM_CONTROL/SET_THRESHOLD", d);
3835 }
3836
3837 TGraph fGraphFtmTemp[4];
3838 TGraph fGraphFtmRate;
3839 TGraph fGraphPatchRate[160];
3840 TGraph fGraphBoardRate[40];
3841
3842#ifdef HAVE_ROOT
3843 TH1 *DrawTimeFrame(const char *ytitle)
3844 {
3845 const double tm = Time().RootTime();
3846
3847 TH1F *h=new TH1F("TimeFrame", "", 1, tm, tm+60);//Time().RootTime()-1./24/60/60, Time().RootTime());
3848 h->SetDirectory(0);
3849 h->SetBit(kCanDelete);
3850 h->SetStats(kFALSE);
3851// h.SetMinimum(0);
3852// h.SetMaximum(1);
3853 h->SetXTitle("Time");
3854 h->SetYTitle(ytitle);
3855 h->GetXaxis()->CenterTitle();
3856 h->GetYaxis()->CenterTitle();
3857 h->GetXaxis()->SetTimeDisplay(true);
3858 h->GetXaxis()->SetTimeFormat("%Mh%S'");
3859 h->GetXaxis()->SetLabelSize(0.025);
3860 h->GetYaxis()->SetLabelSize(0.025);
3861 h->GetYaxis()->SetTitleOffset(1.2);
3862 // h.GetYaxis()->SetTitleSize(1.2);
3863 h->Draw();
3864
3865 return h;
3866 }
3867#endif
3868
3869 pair<string,string> Split(const string &str) const
3870 {
3871 const size_t p = str.find_first_of('|');
3872 if (p==string::npos)
3873 return make_pair(str, "");
3874
3875 return make_pair(str.substr(0, p), str.substr(p+1));
3876 }
3877
3878public:
3879 FactGui(Configuration &conf) :
3880 fFtuStatus(40),
3881 /*fPixelMapHW(1440),*/ fPatchMapHW(160),
3882 fInChoosePatchTH(false),
3883 fInChooseBiasHv(false), fInChooseBiasCam(false),
3884 fDimDNS("DIS_DNS/VERSION_NUMBER", 1, int(0), this),
3885 //-
3886 fDimLoggerStats ("DATA_LOGGER/STATS", (void*)NULL, 0, this),
3887 fDimLoggerFilenameNight("DATA_LOGGER/FILENAME_NIGHTLY", (void*)NULL, 0, this),
3888 fDimLoggerFilenameRun ("DATA_LOGGER/FILENAME_RUN", (void*)NULL, 0, this),
3889 fDimLoggerNumSubs ("DATA_LOGGER/NUM_SUBS", (void*)NULL, 0, this),
3890 //-
3891 fDimFtmPassport ("FTM_CONTROL/PASSPORT", (void*)NULL, 0, this),
3892 fDimFtmTriggerRates ("FTM_CONTROL/TRIGGER_RATES", (void*)NULL, 0, this),
3893 fDimFtmError ("FTM_CONTROL/ERROR", (void*)NULL, 0, this),
3894 fDimFtmFtuList ("FTM_CONTROL/FTU_LIST", (void*)NULL, 0, this),
3895 fDimFtmStaticData ("FTM_CONTROL/STATIC_DATA", (void*)NULL, 0, this),
3896 fDimFtmDynamicData ("FTM_CONTROL/DYNAMIC_DATA", (void*)NULL, 0, this),
3897 fDimFtmCounter ("FTM_CONTROL/COUNTER", (void*)NULL, 0, this),
3898 //-
3899 fDimFadWriteStats ("FAD_CONTROL/STATS", (void*)NULL, 0, this),
3900 fDimFadStartRun ("FAD_CONTROL/START_RUN", (void*)NULL, 0, this),
3901 fDimFadRuns ("FAD_CONTROL/RUNS", (void*)NULL, 0, this),
3902 fDimFadEvents ("FAD_CONTROL/EVENTS", (void*)NULL, 0, this),
3903 fDimFadRawData ("FAD_CONTROL/RAW_DATA", (void*)NULL, 0, this),
3904 fDimFadEventData ("FAD_CONTROL/EVENT_DATA", (void*)NULL, 0, this),
3905 fDimFadConnections ("FAD_CONTROL/CONNECTIONS", (void*)NULL, 0, this),
3906 fDimFadFwVersion ("FAD_CONTROL/FIRMWARE_VERSION", (void*)NULL, 0, this),
3907 fDimFadRunNumber ("FAD_CONTROL/RUN_NUMBER", (void*)NULL, 0, this),
3908 fDimFadDNA ("FAD_CONTROL/DNA", (void*)NULL, 0, this),
3909 fDimFadTemperature ("FAD_CONTROL/TEMPERATURE", (void*)NULL, 0, this),
3910 fDimFadPrescaler ("FAD_CONTROL/PRESCALER", (void*)NULL, 0, this),
3911 fDimFadRefClock ("FAD_CONTROL/REFERENCE_CLOCK", (void*)NULL, 0, this),
3912 fDimFadRoi ("FAD_CONTROL/REGION_OF_INTEREST", (void*)NULL, 0, this),
3913 fDimFadDac ("FAD_CONTROL/DAC", (void*)NULL, 0, this),
3914 fDimFadDrsCalibration ("FAD_CONTROL/DRS_CALIBRATION", (void*)NULL, 0, this),
3915 fDimFadStatus ("FAD_CONTROL/STATUS", (void*)NULL, 0, this),
3916 fDimFadStatistics1 ("FAD_CONTROL/STATISTICS1", (void*)NULL, 0, this),
3917 fDimFadStatistics2 ("FAD_CONTROL/STATISTICS2", (void*)NULL, 0, this),
3918 //-
3919 fDimFscTemp ("FSC_CONTROL/TEMPERATURE", (void*)NULL, 0, this),
3920 fDimFscVolt ("FSC_CONTROL/VOLTAGE", (void*)NULL, 0, this),
3921 fDimFscCurrent ("FSC_CONTROL/CURRENT", (void*)NULL, 0, this),
3922 fDimFscHumidity ("FSC_CONTROL/HUMIDITY", (void*)NULL, 0, this),
3923 //-
3924 fDimFeedbackDeviation ("FEEDBACK/DEVIATION", (void*)NULL, 0, this),
3925 fDimFeedbackReference ("FEEDBACK/REFERENCE", (void*)NULL, 0, this),
3926 fDimFeedbackCalibration("FEEDBACK/CALIBRATION", (void*)NULL, 0, this),
3927 //-
3928 fDimBiasVolt ("BIAS_CONTROL/VOLTAGE", (void*)NULL, 0, this),
3929 fDimBiasCurrent ("BIAS_CONTROL/CURRENT", (void*)NULL, 0, this),
3930 //-
3931 fDimRateScan ("RATE_SCAN/DATA", (void*)NULL, 0, this),
3932 //-
3933 fEventData(0), fDrsCalibration(1440*1024*6),
3934 fTimeStamp0(0)
3935 {
3936 fClockCondFreq->addItem("--- Hz", QVariant(-1));
3937 fClockCondFreq->addItem("800 MHz", QVariant(800));
3938 fClockCondFreq->addItem("1 GHz", QVariant(1000));
3939 fClockCondFreq->addItem("2 GHz", QVariant(2000));
3940 fClockCondFreq->addItem("3 GHz", QVariant(3000));
3941 fClockCondFreq->addItem("4 GHz", QVariant(4000));
3942 fClockCondFreq->addItem("5 GHz", QVariant(5000));
3943
3944 cout << "-- run counter ---" << endl;
3945 fMcpNumEvents->addItem("unlimited", QVariant(0));
3946 const vector<uint32_t> runcount = conf.Vec<uint32_t>("run-count");
3947 for (vector<uint32_t>::const_iterator it=runcount.begin(); it!=runcount.end(); it++)
3948 {
3949 cout << *it << endl;
3950 ostringstream str;
3951 str << *it;
3952 fMcpNumEvents->addItem(str.str().c_str(), QVariant(*it));
3953 }
3954
3955 cout << "-- run times ---" << endl;
3956 fMcpTime->addItem("unlimited", QVariant(0));
3957 const vector<string> runtime = conf.Vec<string>("run-time");
3958 for (vector<string>::const_iterator it=runtime.begin(); it!=runtime.end(); it++)
3959 {
3960 const pair<string,string> p = Split(*it);
3961 cout << *it << "|" << p.second << "|" << p.first << "|" << endl;
3962 fMcpTime->addItem(p.second.c_str(), QVariant(stoi(p.first)));
3963 }
3964
3965 cout << "-- run types ---" << endl;
3966 const vector<string> runtype = conf.Vec<string>("run-type");
3967 for (vector<string>::const_iterator it=runtype.begin(); it!=runtype.end(); it++)
3968 {
3969 const pair<string,string> p = Split(*it);
3970 cout << *it << "|" << p.second << "|" << p.first << "|" << endl;
3971 fMcpRunType->addItem(p.second.c_str(), QVariant(p.first.c_str()));
3972 }
3973
3974 fTriggerWidget->setEnabled(false);
3975 fFtuWidget->setEnabled(false);
3976 fFtuGroupEnable->setEnabled(false);
3977 fRatesControls->setEnabled(false);
3978 fFadWidget->setEnabled(false);
3979 fEvtBldWidget->setEnabled(false);
3980 fLoggerWidget->setEnabled(false);
3981 fBiasWidget->setEnabled(false);
3982 fAuxWidget->setEnabled(false);
3983
3984 fChatSend->setEnabled(false);
3985 fChatMessage->setEnabled(false);
3986
3987 DimClient::sendCommand("CHAT/MSG", "GUI online.");
3988 // + MessageDimRX
3989
3990 // --------------------------------------------------------------------------
3991
3992 if (!fPixelMap.Read(conf.Get<string>("pixel-map-file")))
3993 {
3994 cerr << "ERROR - Problems reading " << conf.Get<string>("pixel-map-file") << endl;
3995 exit(-1);
3996 }
3997
3998 // --------------------------------------------------------------------------
3999
4000 /*
4001 ifstream fin1("Trigger-Patches.txt");
4002
4003 string buf;
4004
4005 int l = 0;
4006 while (getline(fin1, buf, '\n'))
4007 {
4008 buf = Tools::Trim(buf);
4009 if (buf[0]=='#')
4010 continue;
4011
4012 stringstream str(buf);
4013 for (int i=0; i<9; i++)
4014 {
4015 unsigned int n;
4016 str >> n;
4017
4018 if (n>=fPatchHW.size())
4019 continue;
4020
4021 fPatchHW[n] = l;
4022 }
4023 l++;
4024 }
4025
4026 if (l!=160)
4027 cerr << "WARNING - Problems reading Trigger-Patches.txt" << endl;
4028 */
4029 // --------------------------------------------------------------------------
4030
4031 /*
4032 ifstream fin2("MasterList-v3.txt");
4033
4034 l = 0;
4035
4036 while (getline(fin2, buf, '\n'))
4037 {
4038 buf = Tools::Trim(buf);
4039 if (buf[0]=='#')
4040 continue;
4041
4042 unsigned int softid, hardid, dummy;
4043
4044 stringstream str(buf);
4045
4046 str >> softid;
4047 str >> dummy;
4048 str >> hardid;
4049
4050 if (softid>=fPixelMapHW.size())
4051 continue;
4052
4053 fPixelMapHW[softid] = hardid;
4054
4055 l++;
4056 }
4057
4058 if (l!=1440)
4059 cerr << "WARNING - Problems reading MasterList-v3.txt" << endl;
4060 */
4061 // --------------------------------------------------------------------------
4062
4063 ifstream fin3("PatchList.txt");
4064
4065 string buf;
4066
4067 int l = 0;
4068 while (getline(fin3, buf, '\n'))
4069 {
4070 buf = Tools::Trim(buf);
4071 if (buf[0]=='#')
4072 continue;
4073
4074 unsigned int softid, hardid;
4075
4076 stringstream str(buf);
4077
4078 str >> softid;
4079 str >> hardid;
4080
4081 if (softid>=fPatchMapHW.size())
4082 continue;
4083
4084 fPatchMapHW[softid] = hardid-1;
4085
4086 l++;
4087 }
4088
4089 if (l!=160)
4090 cerr << "WARNING - Problems reading PatchList.txt" << endl;
4091
4092 // --------------------------------------------------------------------------
4093#ifdef HAVE_ROOT
4094
4095 fGraphFeedbackDev.SetLineColor(kBlue);
4096 fGraphFeedbackDev.SetMarkerColor(kBlue);
4097 fGraphFeedbackDev.SetMarkerStyle(kFullDotMedium);
4098
4099 fGraphFeedbackCmd.SetLineColor(kBlue);
4100 fGraphFeedbackCmd.SetMarkerColor(kBlue);
4101 fGraphFeedbackCmd.SetMarkerStyle(kFullDotMedium);
4102
4103 // Evolution of control deviation
4104 // Evolution of command values (bias voltage change)
4105 fGraphFeedbackDev.SetName("ControlDev");
4106 fGraphFeedbackCmd.SetName("CommandVal");
4107
4108 TCanvas *c = fFeedbackDev->GetCanvas();
4109 c->SetBorderMode(0);
4110 c->SetFrameBorderMode(0);
4111 c->SetFillColor(kWhite);
4112 c->SetRightMargin(0.03);
4113 c->SetTopMargin(0.03);
4114 c->SetGrid();
4115 c->cd();
4116
4117 TH1 *hf = DrawTimeFrame("Control deviation [mV] ");
4118 hf->GetXaxis()->SetLabelSize(0.07);
4119 hf->GetYaxis()->SetLabelSize(0.07);
4120 hf->GetYaxis()->SetTitleSize(0.08);
4121 hf->GetYaxis()->SetTitleOffset(0.55);
4122 hf->GetXaxis()->SetTitle("");
4123 hf->GetYaxis()->SetRangeUser(-99, 99);
4124
4125 fGraphFeedbackDev.Draw("LP");
4126
4127 c = fFeedbackCmd->GetCanvas();
4128 c->SetBorderMode(0);
4129 c->SetFrameBorderMode(0);
4130 c->SetFillColor(kWhite);
4131 c->SetRightMargin(0.03);
4132 c->SetTopMargin(0.03);
4133 c->SetGrid();
4134 c->cd();
4135
4136 hf = DrawTimeFrame("Command delta value [mV] ");
4137 hf->GetXaxis()->SetLabelSize(0.07);
4138 hf->GetYaxis()->SetLabelSize(0.07);
4139 hf->GetYaxis()->SetTitleSize(0.08);
4140 hf->GetYaxis()->SetTitleOffset(0.55);
4141 hf->GetXaxis()->SetTitle("");
4142 hf->GetYaxis()->SetRangeUser(-99*10, 99*10);
4143
4144 fGraphFeedbackCmd.Draw("LP");
4145
4146 // --------------------------------------------------------------------------
4147
4148 c = fRateScanCanv->GetCanvas();
4149 //c->SetBit(TCanvas::kNoContextMenu);
4150 c->SetBorderMode(0);
4151 c->SetFrameBorderMode(0);
4152 c->SetFillColor(kWhite);
4153 c->SetRightMargin(0.03);
4154 c->SetTopMargin(0.03);
4155 c->SetGrid();
4156 c->cd();
4157
4158 TH1F *h=new TH1F("Frame", "", 1, 0, 1);
4159 h->SetDirectory(0);
4160 h->SetBit(kCanDelete);
4161 h->SetStats(kFALSE);
4162 h->SetXTitle("Threshold [DAC]");
4163 h->SetYTitle("Rate [Hz]");
4164 h->GetXaxis()->CenterTitle();
4165 h->GetYaxis()->CenterTitle();
4166 h->GetXaxis()->SetLabelSize(0.025);
4167 h->GetYaxis()->SetLabelSize(0.025);
4168 h->GetYaxis()->SetTitleOffset(1.2);
4169 h->Draw();
4170
4171 fGraphRateScan[0].SetName("CameraRate");
4172 for (int i=0; i<40; i++)
4173 {
4174 fGraphRateScan[i+1].SetName("BoardRate");
4175 fGraphRateScan[i+1].SetMarkerStyle(kFullDotMedium);
4176 }
4177 for (int i=0; i<160; i++)
4178 {
4179 fGraphRateScan[i+41].SetName("PatchRate");
4180 fGraphRateScan[i+41].SetMarkerStyle(kFullDotMedium);
4181 }
4182
4183 fGraphRateScan[0].SetLineColor(kBlue);
4184 fGraphRateScan[0].SetMarkerColor(kBlue);
4185 fGraphRateScan[0].SetMarkerStyle(kFullDotSmall);
4186 fGraphRateScan[0].Draw("LP");
4187
4188 // --------------------------------------------------------------------------
4189
4190 c = fFtmRateCanv->GetCanvas();
4191 //c->SetBit(TCanvas::kNoContextMenu);
4192 c->SetBorderMode(0);
4193 c->SetFrameBorderMode(0);
4194 c->SetFillColor(kWhite);
4195 c->SetRightMargin(0.03);
4196 c->SetTopMargin(0.03);
4197 c->SetGrid();
4198 c->cd();
4199
4200 hf = DrawTimeFrame("Trigger rate [Hz]");
4201 hf->GetYaxis()->SetRangeUser(0, 1010);
4202
4203 for (int i=0; i<160; i++)
4204 {
4205 fGraphPatchRate[i].SetName("PatchRate");
4206 //fGraphPatchRate[i].SetLineColor(kBlue);
4207 //fGraphPatchRate[i].SetMarkerColor(kBlue);
4208 fGraphPatchRate[i].SetMarkerStyle(kFullDotMedium);
4209 }
4210 for (int i=0; i<40; i++)
4211 {
4212 fGraphBoardRate[i].SetName("BoardRate");
4213 //fGraphBoardRate[i].SetLineColor(kBlue);
4214 //fGraphBoardRate[i].SetMarkerColor(kBlue);
4215 fGraphBoardRate[i].SetMarkerStyle(kFullDotMedium);
4216 }
4217
4218 fGraphFtmRate.SetLineColor(kBlue);
4219 fGraphFtmRate.SetMarkerColor(kBlue);
4220 fGraphFtmRate.SetMarkerStyle(kFullDotSmall);
4221 fGraphFtmRate.Draw("LP");
4222
4223 /*
4224 TCanvas *c = fFtmTempCanv->GetCanvas();
4225 c->SetBit(TCanvas::kNoContextMenu);
4226 c->SetBorderMode(0);
4227 c->SetFrameBorderMode(0);
4228 c->SetFillColor(kWhite);
4229 c->SetRightMargin(0.03);
4230 c->SetTopMargin(0.03);
4231 c->cd();
4232 */
4233 //CreateTimeFrame("Temperature / �C");
4234
4235 fGraphFtmTemp[0].SetMarkerStyle(kFullDotSmall);
4236 fGraphFtmTemp[1].SetMarkerStyle(kFullDotSmall);
4237 fGraphFtmTemp[2].SetMarkerStyle(kFullDotSmall);
4238 fGraphFtmTemp[3].SetMarkerStyle(kFullDotSmall);
4239
4240 fGraphFtmTemp[1].SetLineColor(kBlue);
4241 fGraphFtmTemp[2].SetLineColor(kRed);
4242 fGraphFtmTemp[3].SetLineColor(kGreen);
4243
4244 fGraphFtmTemp[1].SetMarkerColor(kBlue);
4245 fGraphFtmTemp[2].SetMarkerColor(kRed);
4246 fGraphFtmTemp[3].SetMarkerColor(kGreen);
4247
4248 //fGraphFtmTemp[0].Draw("LP");
4249 //fGraphFtmTemp[1].Draw("LP");
4250 //fGraphFtmTemp[2].Draw("LP");
4251 //fGraphFtmTemp[3].Draw("LP");
4252
4253 // --------------------------------------------------------------------------
4254
4255 c = fAdcDataCanv->GetCanvas();
4256 //c->SetBit(TCanvas::kNoContextMenu);
4257 c->SetBorderMode(0);
4258 c->SetFrameBorderMode(0);
4259 c->SetFillColor(kWhite);
4260 c->SetRightMargin(0.10);
4261 c->SetGrid();
4262 //c->cd();
4263#endif
4264
4265 // --------------------------------------------------------------------------
4266 fFeedbackDevCam->assignPixelMap(fPixelMap);
4267 fFeedbackDevCam->setAutoscaleLowerLimit((fFeedbackDevMin->minimum()+0.5*fFeedbackDevMin->singleStep()));
4268 fFeedbackDevCam->SetMin(fFeedbackDevMin->value());
4269 fFeedbackDevCam->SetMax(fFeedbackDevMax->value());
4270 fFeedbackDevCam->updateCamera();
4271
4272 fFeedbackCmdCam->assignPixelMap(fPixelMap);
4273 fFeedbackCmdCam->setAutoscaleLowerLimit((fFeedbackCmdMin->minimum()+0.5*fFeedbackCmdMin->singleStep()));
4274 fFeedbackCmdCam->SetMin(fFeedbackCmdMin->value());
4275 fFeedbackCmdCam->SetMax(fFeedbackCmdMax->value());
4276 fFeedbackCmdCam->updateCamera();
4277
4278 // --------------------------------------------------------------------------
4279
4280 fBiasCamV->assignPixelMap(fPixelMap);
4281 fBiasCamV->setAutoscaleLowerLimit((fBiasVoltMin->minimum()+0.5*fBiasVoltMin->singleStep()));
4282 fBiasCamV->SetMin(fBiasVoltMin->value());
4283 fBiasCamV->SetMax(fBiasVoltMax->value());
4284 fBiasCamV->updateCamera();
4285
4286 fBiasCamA->assignPixelMap(fPixelMap);
4287 fBiasCamA->setAutoscaleLowerLimit((fBiasCurrentMin->minimum()+0.5*fBiasCurrentMin->singleStep()));
4288 fBiasCamA->SetMin(fBiasCurrentMin->value());
4289 fBiasCamA->SetMax(fBiasCurrentMax->value());
4290 fBiasCamA->updateCamera();
4291
4292 // --------------------------------------------------------------------------
4293
4294 fRatesCanv->assignPixelMap(fPixelMap);
4295 fRatesCanv->setAutoscaleLowerLimit((fRatesMin->minimum()+0.5*fRatesMin->singleStep())*0.001);
4296 fRatesCanv->SetMin(fRatesMin->value());
4297 fRatesCanv->SetMax(fRatesMax->value());
4298 fRatesCanv->updateCamera();
4299 on_fPixelIdx_valueChanged(0);
4300
4301 // --------------------------------------------------------------------------
4302
4303 fRatesCanv->setTitle("Patch rates");
4304 fRatesCanv->setUnits("Hz");
4305
4306 fBiasCamA->setTitle("BIAS current");
4307 fBiasCamA->setUnits("uA");
4308
4309 fBiasCamV->setTitle("Applied BIAS voltage");
4310 fBiasCamV->setUnits("V");
4311
4312 fEventCanv1->setTitle("Average (all slices)");
4313 fEventCanv2->setTitle("RMS (all slices)");
4314 fEventCanv3->setTitle("Maximum (all slices)");
4315 fEventCanv4->setTitle("Position of maximum (all slices)");
4316
4317 fEventCanv1->setUnits("mV");
4318 fEventCanv2->setUnits("mV");
4319 fEventCanv3->setUnits("mV");
4320 fEventCanv4->setUnits("slice");
4321
4322 // --------------------------------------------------------------------------
4323
4324 fFeedbackDevCam->setTitle("Control deviation (Pulser amplitude voltage)");
4325 fFeedbackCmdCam->setTitle("Applied voltage change (BIAS voltage)");
4326
4327 fFeedbackDevCam->setUnits("mV");
4328 fFeedbackCmdCam->setUnits("mV");
4329
4330 // --------------------------------------------------------------------------
4331
4332 QTimer::singleShot(1000, this, SLOT(slot_RootUpdate()));
4333
4334 //widget->setMouseTracking(true);
4335 //widget->EnableSignalEvents(kMouseMoveEvent);
4336
4337 fFtmRateCanv->setMouseTracking(true);
4338 fFtmRateCanv->EnableSignalEvents(kMouseMoveEvent);
4339
4340 fAdcDataCanv->setMouseTracking(true);
4341 fAdcDataCanv->EnableSignalEvents(kMouseMoveEvent);
4342
4343 fRatesCanv->setMouseTracking(true);
4344 fEventCanv1->setMouseTracking(true);
4345 fEventCanv2->setMouseTracking(true);
4346 fEventCanv3->setMouseTracking(true);
4347 fEventCanv4->setMouseTracking(true);
4348
4349 fBiasCamV->setMouseTracking(true);
4350 fBiasCamA->setMouseTracking(true);
4351
4352 fFeedbackDevCam->setMouseTracking(true);
4353 fFeedbackCmdCam->setMouseTracking(true);
4354
4355 fEventCanv1->ShowPixelCursor(true);
4356 fEventCanv2->ShowPixelCursor(true);
4357 fEventCanv3->ShowPixelCursor(true);
4358 fEventCanv4->ShowPixelCursor(true);
4359
4360 fEventCanv1->ShowPatchCursor(true);
4361 fEventCanv2->ShowPatchCursor(true);
4362 fEventCanv3->ShowPatchCursor(true);
4363 fEventCanv4->ShowPatchCursor(true);
4364
4365 fFeedbackDevCam->ShowPixelCursor(true);
4366 fFeedbackCmdCam->ShowPixelCursor(true);
4367
4368 fFeedbackDevCam->ShowPatchCursor(true);
4369 fFeedbackCmdCam->ShowPatchCursor(true);
4370
4371 connect(fRatesCanv, SIGNAL(signalPixelMoveOver(int)),
4372 this, SLOT(slot_CameraMouseMove(int)));
4373 connect(fEventCanv1, SIGNAL(signalPixelMoveOver(int)),
4374 this, SLOT(slot_CameraMouseMove(int)));
4375 connect(fEventCanv2, SIGNAL(signalPixelMoveOver(int)),
4376 this, SLOT(slot_CameraMouseMove(int)));
4377 connect(fEventCanv3, SIGNAL(signalPixelMoveOver(int)),
4378 this, SLOT(slot_CameraMouseMove(int)));
4379 connect(fEventCanv4, SIGNAL(signalPixelMoveOver(int)),
4380 this, SLOT(slot_CameraMouseMove(int)));
4381
4382 connect(fBiasCamV, SIGNAL(signalPixelMoveOver(int)),
4383 this, SLOT(slot_CameraMouseMove(int)));
4384 connect(fBiasCamA, SIGNAL(signalPixelMoveOver(int)),
4385 this, SLOT(slot_CameraMouseMove(int)));
4386
4387 connect(fFeedbackDevCam, SIGNAL(signalPixelMoveOver(int)),
4388 this, SLOT(slot_CameraMouseMove(int)));
4389 connect(fFeedbackCmdCam, SIGNAL(signalPixelMoveOver(int)),
4390 this, SLOT(slot_CameraMouseMove(int)));
4391
4392 connect(fRatesCanv, SIGNAL(signalPixelDoubleClick(int)),
4393 this, SLOT(slot_CameraDoubleClick(int)));
4394 connect(fRatesCanv, SIGNAL(signalCurrentPixel(int)),
4395 this, SLOT(slot_ChoosePixelThreshold(int)));
4396 connect(fBiasCamV, SIGNAL(signalCurrentPixel(int)),
4397 this, SLOT(slot_ChooseBiasChannel(int)));
4398 connect(fBiasCamA, SIGNAL(signalCurrentPixel(int)),
4399 this, SLOT(slot_ChooseBiasChannel(int)));
4400
4401 connect(fFtmRateCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)),
4402 this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*)));
4403 connect(fAdcDataCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)),
4404 this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*)));
4405 }
4406
4407 ~FactGui()
4408 {
4409 // Unsubscribe all services
4410 for (map<string,DimInfo*>::iterator i=fServices.begin();
4411 i!=fServices.end(); i++)
4412 delete i->second;
4413
4414 delete fEventData;
4415 }
4416};
4417
4418#endif
Note: See TracBrowser for help on using the repository browser.