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

Last change on this file since 11989 was 11988, checked in by tbretz, 14 years ago
Display average front plate temperature.
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=0; i<31; 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//ETIENNE MESS HERE
3216// Camera *cam = (Camera*)fRatesCanv->GetCanvas()->FindObject("Camera");
3217// ChoosePatchTH(*cam, isw);
3218 }
3219
3220 void UpdateThresholdIdx()
3221 {
3222 if (fInChoosePatchTH)
3223 return;
3224
3225 const int crate = fThresholdCrate->value();
3226 const int board = fThresholdBoard->value();
3227 const int patch = fThresholdPatch->value();
3228
3229 const int ihw = patch + board*4 + crate*40;
3230
3231 int isw = 0;
3232 for (; isw<160; isw++)
3233 if (ihw==fPatchMapHW[isw])
3234 break;
3235
3236 on_fThresholdIdx_valueChanged(isw);
3237 }
3238
3239 void on_fPixelIdx_valueChanged(int isw)
3240 {
3241 int ii = 0;
3242 for (; ii<160; ii++)
3243 if (fPatchHW[isw]==fPatchMapHW[ii])
3244 break;
3245
3246 fRatesCanv->SetWhite(isw);
3247 ChoosePatchThreshold(*fRatesCanv, ii);
3248
3249 const PixelMapEntry &entry = fPixelMap.index(isw);
3250 fPixelEnable->setChecked(fFtmStaticData.IsEnabled(entry.hw()));
3251 }
3252
3253 // ------------------- Bias display ---------------------
3254
3255 void UpdateBiasValues()
3256 {
3257 const int b = fBiasHvBoard->value();
3258 const int c = fBiasHvChannel->value();
3259
3260 const int ihw = b*32+c;
3261
3262 if (fVecBiasVolt.size()>0)
3263 {
3264 fBiasVoltCur->setValue(fVecBiasVolt[ihw]*90./4096);
3265 fBiasVoltRef->setValue(fVecBiasVolt[ihw+416]*90./4096);
3266
3267 SetLedColor(fBiasNominalLed,
3268 fVecBiasVolt[ihw]==fVecBiasVolt[ihw+416]?kLedGreen:kLedRed, Time());
3269 }
3270
3271 if (fVecBiasCurrent.size()>0)
3272 {
3273 fBiasCurrent->setValue(abs(fVecBiasCurrent[ihw])*5000./4096);
3274 SetLedColor(fBiasOverCurrentLed,
3275 fVecBiasCurrent[ihw]<0?kLedRed:kLedGreen, Time());
3276 }
3277 }
3278
3279 void UpdateBiasCam(const PixelMapEntry &entry)
3280 {
3281 fInChooseBiasCam = true;
3282
3283 fBiasCamCrate->setValue(entry.crate());
3284 fBiasCamBoard->setValue(entry.board());
3285 fBiasCamPatch->setValue(entry.patch());
3286 fBiasCamPixel->setValue(entry.pixel());
3287
3288 fInChooseBiasCam = false;
3289 }
3290
3291 void BiasHvChannelChanged()
3292 {
3293 if (fInChooseBiasHv)
3294 return;
3295
3296 const int b = fBiasHvBoard->value();
3297 const int ch = fBiasHvChannel->value();
3298
3299 // FIXME: Mark corresponding patch in camera
3300 const PixelMapEntry &entry = fPixelMap.hv(b, ch);
3301 fBiasCamV->SetWhite(entry.index);
3302 fBiasCamA->SetWhite(entry.index);
3303 fBiasCamV->updateGL();
3304 fBiasCamA->updateGL();
3305
3306 UpdateBiasCam(entry);
3307 UpdateBiasValues();
3308 }
3309
3310 void UpdateBiasHv(const PixelMapEntry &entry)
3311 {
3312 fInChooseBiasHv = true;
3313
3314 fBiasHvBoard->setValue(entry.hv_board);
3315 fBiasHvChannel->setValue(entry.hv_channel);
3316
3317 fInChooseBiasHv = false;
3318 }
3319
3320 void BiasCamChannelChanged()
3321 {
3322 if (fInChooseBiasCam)
3323 return;
3324
3325 const int crate = fBiasCamCrate->value();
3326 const int board = fBiasCamBoard->value();
3327 const int patch = fBiasCamPatch->value();
3328 const int pixel = fBiasCamPixel->value();
3329
3330 // FIXME: Display corresponding patches
3331 const PixelMapEntry &entry = fPixelMap.cbpx(crate, board, patch, pixel);
3332 fBiasCamV->SetWhite(entry.index);
3333 fBiasCamA->SetWhite(entry.index);
3334 fBiasCamV->updateGL();
3335 fBiasCamA->updateGL();
3336
3337 UpdateBiasHv(entry);
3338 UpdateBiasValues();
3339 }
3340
3341 void slot_ChooseBiasChannel(int isw)
3342 {
3343 const PixelMapEntry &entry = fPixelMap.index(isw);
3344
3345 UpdateBiasHv(entry);
3346 UpdateBiasCam(entry);
3347 UpdateBiasValues();
3348 }
3349
3350 void on_fBiasDispRefVolt_stateChanged(int = 0)
3351 {
3352 // FIXME: Display patches for which ref==cur
3353
3354 valarray<double> dat(0., 1440);
3355
3356 int offset = 0;
3357 if (!fBiasDispRefVolt->isChecked())
3358 fBiasCamV->setTitle("Applied BIAS voltage");
3359 else
3360 {
3361 fBiasCamV->setTitle("Reference BIAS voltage");
3362 offset = 416;
3363 }
3364
3365 if (fVecBiasVolt.size()>0)
3366 {
3367 for (int i=0; i<1440; i++)
3368 {
3369 const PixelMapEntry &entry = fPixelMap.index(i);
3370 dat[i] = fVecBiasVolt[entry.hv()+offset]*90./4096;
3371
3372 fBiasCamV->highlightPixel(i, fVecBiasVolt[entry.hv()]==fVecBiasVolt[entry.hv()+416]);
3373 }
3374
3375 fBiasCamV->SetData(dat);
3376 }
3377
3378 fBiasCamV->updateGL();
3379 }
3380
3381 // ------------------------------------------------------
3382
3383 void on_fPixelEnable_stateChanged(int b)
3384 {
3385 if (fInHandler)
3386 return;
3387
3388 const PixelMapEntry &entry = fPixelMap.index(fPixelIdx->value());
3389
3390 Dim::SendCommand(b==Qt::Unchecked ?
3391 "FTM_CONTROL/DISABLE_PIXEL" : "FTM_CONTROL/ENABLE_PIXEL",
3392 uint16_t(entry.hw()));
3393 }
3394
3395 void on_fPixelDisableOthers_clicked()
3396 {
3397 const PixelMapEntry &entry = fPixelMap.index(fPixelIdx->value());
3398
3399 Dim::SendCommand("FTM_CONTROL/DISABLE_ALL_PIXELS_EXCEPT", uint16_t(entry.hw()));
3400 }
3401
3402 void on_fThresholdDisableOthers_clicked()
3403 {
3404 const int16_t isw = fThresholdIdx->value();
3405 const int16_t ihw = isw<0 ? -1 : fPatchMapHW[isw];
3406
3407 Dim::SendCommand("FTM_CONTROL/DISABLE_ALL_PATCHES_EXCEPT", ihw);
3408 }
3409
3410 void on_fThresholdVal_valueChanged(int v)
3411 {
3412 fThresholdVolt->setValue(2500./4095*v);
3413
3414 const int32_t isw = fThresholdIdx->value();
3415 const int32_t ihw = isw<0 ? -1 : fPatchMapHW[isw];
3416
3417 const int32_t d[2] = { ihw, v };
3418
3419 if (!fInHandler)
3420 Dim::SendCommand("FTM_CONTROL/SET_THRESHOLD", d);
3421 }
3422
3423 TGraph fGraphFtmTemp[4];
3424 TGraph fGraphFtmRate;
3425 TGraph fGraphPatchRate[160];
3426 TGraph fGraphBoardRate[40];
3427
3428#ifdef HAVE_ROOT
3429 TH1 *DrawTimeFrame(const char *ytitle)
3430 {
3431 const double tm = Time().RootTime();
3432
3433 TH1F *h=new TH1F("TimeFrame", "", 1, tm, tm+60);//Time().RootTime()-1./24/60/60, Time().RootTime());
3434 h->SetDirectory(0);
3435 h->SetBit(kCanDelete);
3436 h->SetStats(kFALSE);
3437// h.SetMinimum(0);
3438// h.SetMaximum(1);
3439 h->SetXTitle("Time");
3440 h->SetYTitle(ytitle);
3441 h->GetXaxis()->CenterTitle();
3442 h->GetYaxis()->CenterTitle();
3443 h->GetXaxis()->SetTimeDisplay(true);
3444 h->GetXaxis()->SetTimeFormat("%Mh%S'");
3445 h->GetXaxis()->SetLabelSize(0.025);
3446 h->GetYaxis()->SetLabelSize(0.025);
3447 h->GetYaxis()->SetTitleOffset(1.2);
3448 // h.GetYaxis()->SetTitleSize(1.2);
3449 h->Draw();
3450
3451 return h;
3452 }
3453#endif
3454
3455 pair<string,string> Split(const string &str) const
3456 {
3457 const size_t p = str.find_first_of('|');
3458 if (p==string::npos)
3459 return make_pair(str, "");
3460
3461 return make_pair(str.substr(0, p), str.substr(p+1));
3462 }
3463
3464public:
3465 FactGui(Configuration &conf) :
3466 fFtuStatus(40),
3467 /*fPixelMapHW(1440),*/ fPatchMapHW(160), fPatchHW(1440),
3468 fInChoosePatchTH(false),
3469 fInChooseBiasHv(false), fInChooseBiasCam(false),
3470 fDimDNS("DIS_DNS/VERSION_NUMBER", 1, int(0), this),
3471 //-
3472 fDimLoggerStats ("DATA_LOGGER/STATS", (void*)NULL, 0, this),
3473 fDimLoggerFilenameNight("DATA_LOGGER/FILENAME_NIGHTLY", (void*)NULL, 0, this),
3474 fDimLoggerFilenameRun ("DATA_LOGGER/FILENAME_RUN", (void*)NULL, 0, this),
3475 fDimLoggerNumSubs ("DATA_LOGGER/NUM_SUBS", (void*)NULL, 0, this),
3476 //-
3477 fDimFtmPassport ("FTM_CONTROL/PASSPORT", (void*)NULL, 0, this),
3478 fDimFtmTriggerRates ("FTM_CONTROL/TRIGGER_RATES", (void*)NULL, 0, this),
3479 fDimFtmError ("FTM_CONTROL/ERROR", (void*)NULL, 0, this),
3480 fDimFtmFtuList ("FTM_CONTROL/FTU_LIST", (void*)NULL, 0, this),
3481 fDimFtmStaticData ("FTM_CONTROL/STATIC_DATA", (void*)NULL, 0, this),
3482 fDimFtmDynamicData ("FTM_CONTROL/DYNAMIC_DATA", (void*)NULL, 0, this),
3483 fDimFtmCounter ("FTM_CONTROL/COUNTER", (void*)NULL, 0, this),
3484 //-
3485 fDimFadWriteStats ("FAD_CONTROL/STATS", (void*)NULL, 0, this),
3486 fDimFadStartRun ("FAD_CONTROL/START_RUN", (void*)NULL, 0, this),
3487 fDimFadRuns ("FAD_CONTROL/RUNS", (void*)NULL, 0, this),
3488 fDimFadEvents ("FAD_CONTROL/EVENTS", (void*)NULL, 0, this),
3489 fDimFadRawData ("FAD_CONTROL/RAW_DATA", (void*)NULL, 0, this),
3490 fDimFadEventData ("FAD_CONTROL/EVENT_DATA", (void*)NULL, 0, this),
3491 fDimFadConnections ("FAD_CONTROL/CONNECTIONS", (void*)NULL, 0, this),
3492 fDimFadFwVersion ("FAD_CONTROL/FIRMWARE_VERSION", (void*)NULL, 0, this),
3493 fDimFadRunNumber ("FAD_CONTROL/RUN_NUMBER", (void*)NULL, 0, this),
3494 fDimFadDNA ("FAD_CONTROL/DNA", (void*)NULL, 0, this),
3495 fDimFadTemperature ("FAD_CONTROL/TEMPERATURE", (void*)NULL, 0, this),
3496 fDimFadPrescaler ("FAD_CONTROL/PRESCALER", (void*)NULL, 0, this),
3497 fDimFadRefClock ("FAD_CONTROL/REFERENCE_CLOCK", (void*)NULL, 0, this),
3498 fDimFadRoi ("FAD_CONTROL/REGION_OF_INTEREST", (void*)NULL, 0, this),
3499 fDimFadDac ("FAD_CONTROL/DAC", (void*)NULL, 0, this),
3500 fDimFadDrsCalibration ("FAD_CONTROL/DRS_CALIBRATION", (void*)NULL, 0, this),
3501 fDimFadStatus ("FAD_CONTROL/STATUS", (void*)NULL, 0, this),
3502 fDimFadStatistics1 ("FAD_CONTROL/STATISTICS1", (void*)NULL, 0, this),
3503 fDimFadStatistics2 ("FAD_CONTROL/STATISTICS2", (void*)NULL, 0, this),
3504 //-
3505 fDimFscTemp ("FSC_CONTROL/TEMPERATURE", (void*)NULL, 0, this),
3506 fDimFscVolt ("FSC_CONTROL/VOLTAGE", (void*)NULL, 0, this),
3507 fDimFscCurrent ("FSC_CONTROL/CURRENT", (void*)NULL, 0, this),
3508 fDimFscHumidity ("FSC_CONTROL/HUMIDITY", (void*)NULL, 0, this),
3509 //-
3510 fDimBiasVolt ("BIAS_CONTROL/VOLTAGE", (void*)NULL, 0, this),
3511 fDimBiasCurrent ("BIAS_CONTROL/CURRENT", (void*)NULL, 0, this),
3512 //-
3513 fEventData(0), fDrsCalibration(1440*1024*6),
3514 fTimeStamp0(0)
3515 {
3516 fClockCondFreq->addItem("--- Hz", QVariant(-1));
3517 fClockCondFreq->addItem("800 MHz", QVariant(800));
3518 fClockCondFreq->addItem("1 GHz", QVariant(1000));
3519 fClockCondFreq->addItem("2 GHz", QVariant(2000));
3520 fClockCondFreq->addItem("3 GHz", QVariant(3000));
3521 fClockCondFreq->addItem("4 GHz", QVariant(4000));
3522 fClockCondFreq->addItem("5 GHz", QVariant(5000));
3523
3524 cout << "-- run counter ---" << endl;
3525 fMcpNumEvents->addItem("unlimited", QVariant(0));
3526 const vector<uint32_t> runcount = conf.Vec<uint32_t>("run-count");
3527 for (vector<uint32_t>::const_iterator it=runcount.begin(); it!=runcount.end(); it++)
3528 {
3529 cout << *it << endl;
3530 ostringstream str;
3531 str << *it;
3532 fMcpNumEvents->addItem(str.str().c_str(), QVariant(*it));
3533 }
3534
3535 cout << "-- run times ---" << endl;
3536 fMcpTime->addItem("unlimited", QVariant(0));
3537 const vector<string> runtime = conf.Vec<string>("run-time");
3538 for (vector<string>::const_iterator it=runtime.begin(); it!=runtime.end(); it++)
3539 {
3540 const pair<string,string> p = Split(*it);
3541 cout << *it << "|" << p.second << "|" << p.first << "|" << endl;
3542 fMcpTime->addItem(p.second.c_str(), QVariant(stoi(p.first)));
3543 }
3544
3545 cout << "-- run types ---" << endl;
3546 const vector<string> runtype = conf.Vec<string>("run-type");
3547 for (vector<string>::const_iterator it=runtype.begin(); it!=runtype.end(); it++)
3548 {
3549 const pair<string,string> p = Split(*it);
3550 cout << *it << "|" << p.second << "|" << p.first << "|" << endl;
3551 fMcpRunType->addItem(p.second.c_str(), QVariant(p.first.c_str()));
3552 }
3553
3554 fTriggerWidget->setEnabled(false);
3555 fFtuWidget->setEnabled(false);
3556 fFtuGroupEnable->setEnabled(false);
3557 fRatesControls->setEnabled(false);
3558 fFadWidget->setEnabled(false);
3559 fEvtBldWidget->setEnabled(false);
3560 fLoggerWidget->setEnabled(false);
3561 fBiasWidget->setEnabled(false);
3562
3563 fChatSend->setEnabled(false);
3564 fChatMessage->setEnabled(false);
3565
3566 DimClient::sendCommand("CHAT/MSG", "GUI online.");
3567 // + MessageDimRX
3568
3569 // --------------------------------------------------------------------------
3570
3571 if (!fPixelMap.Read("FACTmapV5.txt"))
3572 {
3573 cerr << "ERROR - Problems reading FACTmapV5.txt" << endl;
3574 exit(-1);
3575 }
3576
3577/*
3578 ifstream fin0("FACTmapV5.txt");
3579
3580 int l = 0;
3581
3582 string buf;
3583 while (getline(fin0, buf, '\n'))
3584 {
3585 if (l>1439)
3586 break;
3587
3588 buf = Tools::Trim(buf);
3589 if (buf[0]=='#')
3590 continue;
3591
3592 stringstream str(buf);
3593
3594 int idummy;
3595 float fdummy;
3596
3597 PixelMapEntry entry;
3598
3599 str >> entry.index;
3600 str >> entry.cbpx;
3601 str >> idummy;
3602 str >> idummy;
3603 str >> entry.gapd;
3604 str >> fdummy;
3605 str >> entry.hv_board;
3606 str >> entry.hv_channel;
3607 str >> fdummy;
3608 str >> fdummy;
3609 str >> fdummy;
3610
3611 fPixelMap[l++] = entry;
3612 }
3613
3614 if (l!=1440)
3615 {
3616 cerr << "ERROR - Problems reading FACTmapV5.txt" << endl;
3617 exit(-1);
3618 }
3619 */
3620 // --------------------------------------------------------------------------
3621
3622 ifstream fin1("Trigger-Patches.txt");
3623
3624 string buf;
3625
3626 int l = 0;
3627 while (getline(fin1, buf, '\n'))
3628 {
3629 buf = Tools::Trim(buf);
3630 if (buf[0]=='#')
3631 continue;
3632
3633 stringstream str(buf);
3634 for (int i=0; i<9; i++)
3635 {
3636 unsigned int n;
3637 str >> n;
3638
3639 if (n>=fPatchHW.size())
3640 continue;
3641
3642 fPatchHW[n] = l;
3643 }
3644 l++;
3645 }
3646
3647 if (l!=160)
3648 cerr << "WARNING - Problems reading Trigger-Patches.txt" << endl;
3649
3650 // --------------------------------------------------------------------------
3651
3652 /*
3653 ifstream fin2("MasterList-v3.txt");
3654
3655 l = 0;
3656
3657 while (getline(fin2, buf, '\n'))
3658 {
3659 buf = Tools::Trim(buf);
3660 if (buf[0]=='#')
3661 continue;
3662
3663 unsigned int softid, hardid, dummy;
3664
3665 stringstream str(buf);
3666
3667 str >> softid;
3668 str >> dummy;
3669 str >> hardid;
3670
3671 if (softid>=fPixelMapHW.size())
3672 continue;
3673
3674 fPixelMapHW[softid] = hardid;
3675
3676 l++;
3677 }
3678
3679 if (l!=1440)
3680 cerr << "WARNING - Problems reading MasterList-v3.txt" << endl;
3681 */
3682 // --------------------------------------------------------------------------
3683
3684 ifstream fin3("PatchList.txt");
3685
3686 l = 0;
3687
3688 while (getline(fin3, buf, '\n'))
3689 {
3690 buf = Tools::Trim(buf);
3691 if (buf[0]=='#')
3692 continue;
3693
3694 unsigned int softid, hardid;
3695
3696 stringstream str(buf);
3697
3698 str >> softid;
3699 str >> hardid;
3700
3701 if (softid>=fPatchMapHW.size())
3702 continue;
3703
3704 fPatchMapHW[softid] = hardid-1;
3705
3706 l++;
3707 }
3708
3709 if (l!=160)
3710 cerr << "WARNING - Problems reading PatchList.txt" << endl;
3711
3712 // --------------------------------------------------------------------------
3713#ifdef HAVE_ROOT
3714
3715 fGraphFtmRate.SetLineColor(kBlue);
3716 fGraphFtmRate.SetMarkerColor(kBlue);
3717 fGraphFtmRate.SetMarkerStyle(kFullDotMedium);
3718
3719 for (int i=0; i<160; i++)
3720 {
3721 fGraphPatchRate[i].SetName("PatchRate");
3722 //fGraphPatchRate[i].SetLineColor(kBlue);
3723 //fGraphPatchRate[i].SetMarkerColor(kBlue);
3724 fGraphPatchRate[i].SetMarkerStyle(kFullDotMedium);
3725 }
3726 for (int i=0; i<40; i++)
3727 {
3728 fGraphBoardRate[i].SetName("BoardRate");
3729 //fGraphBoardRate[i].SetLineColor(kBlue);
3730 //fGraphBoardRate[i].SetMarkerColor(kBlue);
3731 fGraphBoardRate[i].SetMarkerStyle(kFullDotMedium);
3732 }
3733 /*
3734 TCanvas *c = fFtmTempCanv->GetCanvas();
3735 c->SetBit(TCanvas::kNoContextMenu);
3736 c->SetBorderMode(0);
3737 c->SetFrameBorderMode(0);
3738 c->SetFillColor(kWhite);
3739 c->SetRightMargin(0.03);
3740 c->SetTopMargin(0.03);
3741 c->cd();
3742 */
3743 //CreateTimeFrame("Temperature / �C");
3744
3745 fGraphFtmTemp[0].SetMarkerStyle(kFullDotSmall);
3746 fGraphFtmTemp[1].SetMarkerStyle(kFullDotSmall);
3747 fGraphFtmTemp[2].SetMarkerStyle(kFullDotSmall);
3748 fGraphFtmTemp[3].SetMarkerStyle(kFullDotSmall);
3749
3750 fGraphFtmTemp[1].SetLineColor(kBlue);
3751 fGraphFtmTemp[2].SetLineColor(kRed);
3752 fGraphFtmTemp[3].SetLineColor(kGreen);
3753
3754 fGraphFtmTemp[1].SetMarkerColor(kBlue);
3755 fGraphFtmTemp[2].SetMarkerColor(kRed);
3756 fGraphFtmTemp[3].SetMarkerColor(kGreen);
3757
3758 //fGraphFtmTemp[0].Draw("LP");
3759 //fGraphFtmTemp[1].Draw("LP");
3760 //fGraphFtmTemp[2].Draw("LP");
3761 //fGraphFtmTemp[3].Draw("LP");
3762
3763 // --------------------------------------------------------------------------
3764
3765 TCanvas *c = fFtmRateCanv->GetCanvas();
3766 //c->SetBit(TCanvas::kNoContextMenu);
3767 c->SetBorderMode(0);
3768 c->SetFrameBorderMode(0);
3769 c->SetFillColor(kWhite);
3770 c->SetRightMargin(0.03);
3771 c->SetTopMargin(0.03);
3772 c->SetGrid();
3773 c->cd();
3774
3775 TH1 *hf = DrawTimeFrame("Trigger rate [Hz]");
3776 hf->GetYaxis()->SetRangeUser(0, 1010);
3777
3778 fGraphFtmRate.SetMarkerStyle(kFullDotSmall);
3779 fGraphFtmRate.Draw("LP");
3780
3781 // --------------------------------------------------------------------------
3782
3783 fBiasCamV->SetMin(fBiasVoltMin->value());
3784 fBiasCamV->SetMax(fBiasVoltMax->value());
3785 fBiasCamV->updateGL();
3786
3787 fBiasCamA->SetMin(fBiasCurrentMin->value());
3788 fBiasCamA->SetMax(fBiasCurrentMax->value());
3789 fBiasCamA->updateGL();
3790
3791 // --------------------------------------------------------------------------
3792
3793 fRatesCanv->SetMin(fRatesMin->value());
3794 fRatesCanv->SetMax(fRatesMax->value());
3795 fRatesCanv->updateGL();
3796 on_fPixelIdx_valueChanged(0);
3797
3798 // --------------------------------------------------------------------------
3799
3800 c = fAdcDataCanv->GetCanvas();
3801 //c->SetBit(TCanvas::kNoContextMenu);
3802 c->SetBorderMode(0);
3803 c->SetFrameBorderMode(0);
3804 c->SetFillColor(kWhite);
3805 c->SetRightMargin(0.10);
3806 c->SetGrid();
3807 c->cd();
3808
3809 // Create histogram?
3810
3811 // --------------------------------------------------------------------------
3812
3813 fRatesCanv->setTitle("Patch rates");
3814 fRatesCanv->setUnits("Hz");
3815
3816 fBiasCamA->setTitle("BIAS current");
3817 fBiasCamA->setUnits("uA");
3818
3819 fBiasCamV->setTitle("Applied BIAS voltage");
3820 fBiasCamV->setUnits("V");
3821
3822 fEventCanv1->setTitle("Average (all slices)");
3823 fEventCanv2->setTitle("RMS (all slices)");
3824 fEventCanv3->setTitle("Maximum (all slices)");
3825 fEventCanv4->setTitle("Position of maximum (all slices)");
3826
3827 fEventCanv1->setUnits("mV");
3828 fEventCanv2->setUnits("mV");
3829 fEventCanv3->setUnits("mV");
3830 fEventCanv4->setUnits("slice");
3831
3832 // --------------------------------------------------------------------------
3833
3834 QTimer::singleShot(1000, this, SLOT(slot_RootUpdate()));
3835
3836 //widget->setMouseTracking(true);
3837 //widget->EnableSignalEvents(kMouseMoveEvent);
3838
3839 fFtmRateCanv->setMouseTracking(true);
3840 fFtmRateCanv->EnableSignalEvents(kMouseMoveEvent);
3841
3842 fAdcDataCanv->setMouseTracking(true);
3843 fAdcDataCanv->EnableSignalEvents(kMouseMoveEvent);
3844
3845 fRatesCanv->setMouseTracking(true);
3846
3847 connect(fRatesCanv, SIGNAL(signalPixelMoveOver(int)),
3848 this, SLOT(slot_CameraMouseMove(int)));
3849 connect(fEventCanv1, SIGNAL(signalCurrentPixel(int)),
3850 this, SLOT(slot_CameraMouseMove(int)));
3851 connect(fEventCanv2, SIGNAL(signalCurrentPixel(int)),
3852 this, SLOT(slot_CameraMouseMove(int)));
3853 connect(fEventCanv3, SIGNAL(signalCurrentPixel(int)),
3854 this, SLOT(slot_CameraMouseMove(int)));
3855 connect(fEventCanv4, SIGNAL(signalCurrentPixel(int)),
3856 this, SLOT(slot_CameraMouseMove(int)));
3857
3858 connect(fRatesCanv, SIGNAL(signalPixelDoubleClick(int)),
3859 this, SLOT(slot_CameraDoubleClick(int)));
3860 connect(fRatesCanv, SIGNAL(signalCurrentPixel(int)),
3861 this, SLOT(slot_ChoosePixelThreshold(int)));
3862 connect(fBiasCamV, SIGNAL(signalCurrentPixel(int)),
3863 this, SLOT(slot_ChooseBiasChannel(int)));
3864 connect(fBiasCamA, SIGNAL(signalCurrentPixel(int)),
3865 this, SLOT(slot_ChooseBiasChannel(int)));
3866 connect(fFtmRateCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)),
3867 this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*)));
3868 connect(fAdcDataCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)),
3869 this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*)));
3870#endif
3871 }
3872
3873 ~FactGui()
3874 {
3875 // Unsubscribe all services
3876 for (map<string,DimInfo*>::iterator i=fServices.begin();
3877 i!=fServices.end(); i++)
3878 delete i->second;
3879
3880 delete fEventData;
3881 }
3882};
3883
3884#endif
Note: See TracBrowser for help on using the repository browser.