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

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