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

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