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

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