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

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