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

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