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

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