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

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