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

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