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

Last change on this file since 13052 was 13010, checked in by tbretz, 13 years ago
Fixed the size of the received magic weather reports.
File size: 146.4 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 const float *ptr = d.ptr<float>();
2651
2652 valarray<float> dev(1440);
2653 valarray<float> cmd(1440);
2654
2655 double avgdev = 0;
2656 double avgcmd = 0;
2657
2658 double rmsdev = 0;
2659 double rmscmd = 0;
2660
2661 for (int i=0; i<1440; i++)
2662 {
2663 const PixelMapEntry &entry = fPixelMap.index(i);
2664
2665 dev[i] = /*1000*/ptr[entry.hv()];
2666 cmd[i] = 1000*ptr[entry.hv()+416];
2667
2668 avgdev += dev[i];
2669 avgcmd += cmd[i];
2670
2671 rmsdev += dev[i]*dev[i];
2672 rmscmd += cmd[i]*cmd[i];
2673 }
2674
2675 avgdev /= 1440;
2676 avgcmd /= 1440;
2677
2678 rmsdev = sqrt(rmsdev/1440 - avgdev*avgdev);
2679 rmscmd = sqrt(rmscmd/1440 - avgcmd*avgcmd);
2680
2681 fFeedbackDevCam->SetData(dev);
2682 fFeedbackCmdCam->SetData(cmd);
2683
2684 fFeedbackDevCam->updateCamera();
2685 fFeedbackCmdCam->updateCamera();
2686
2687#ifdef HAVE_ROOT
2688 UpdateFeedback(*fFeedbackDev, d.time, fGraphFeedbackDev, avgdev, rmsdev);
2689 UpdateFeedback(*fFeedbackCmd, d.time, fGraphFeedbackCmd, avgcmd, rmscmd);
2690#endif
2691 }
2692
2693 void handleFeedbackReference(const DimData &d)
2694 {
2695 if (!CheckSize(d, 416*sizeof(float)))
2696 return;
2697
2698 const float *ptr = d.ptr<float>();
2699
2700// fFeedbackRefCam->SetData(valarray<float>(ptr, 416));
2701// fFeedbackRefCam->updateCamera();
2702 }
2703
2704 vector<float> fBiasOffsets;
2705
2706 void handleFeedbackCalibration(const DimData &d)
2707 {
2708 if (!CheckSize(d, 2*416*sizeof(float)))
2709 return;
2710
2711 const float *ptr = d.ptr<float>();
2712 fBiasOffsets.assign(ptr, ptr+416);
2713 }
2714
2715 // ======================= Rate Scan ====================================
2716
2717 TGraph fGraphRateScan[201];
2718
2719 void UpdateRateScan(uint32_t th, const float *rates)
2720 {
2721#ifdef HAVE_ROOT
2722 TCanvas *c = fRateScanCanv->GetCanvas();
2723
2724 TH1 *h = (TH1*)c->FindObject("Frame");
2725
2726 if (fGraphRateScan[0].GetN()==0 || th<fGraphRateScan[0].GetX()[fGraphRateScan[0].GetN()-1])
2727 {
2728 h->SetBins(1, th<10 ? 0 : th-10, th+10);
2729 h->SetMinimum(1);
2730 h->SetMaximum(rates[0]*2);
2731
2732 for (int i=0; i<201; i++)
2733 {
2734 fGraphRateScan[i].Set(0);
2735 fGraphRateScan[i].SetPoint(fGraphRateScan[i].GetN(), th, rates[i]);
2736 }
2737
2738 c->SetGrid();
2739 c->SetLogy();
2740
2741 c->Modified();
2742 c->Update();
2743 return;
2744 }
2745
2746 const double dac = h->GetXaxis()->GetXmin();
2747 h->SetBins(h->GetNbinsX()+1, dac, th+10);
2748
2749 for (int i=0; i<201; i++)
2750 fGraphRateScan[i].SetPoint(fGraphRateScan[i].GetN(), th, rates[i]);
2751
2752 c->Modified();
2753 c->Update();
2754#endif
2755 }
2756
2757 void DisplayRateScan()
2758 {
2759#ifdef HAVE_ROOT
2760 TCanvas *c = fRateScanCanv->GetCanvas();
2761
2762 while (c->FindObject("PatchRate"))
2763 c->GetListOfPrimitives()->Remove(c->FindObject("PatchRate"));
2764
2765 while (c->FindObject("BoardRate"))
2766 c->GetListOfPrimitives()->Remove(c->FindObject("BoardRate"));
2767
2768 c->cd();
2769
2770 if (fRateScanPatch1->value()>=0)
2771 {
2772 fGraphRateScan[fRateScanPatch1->value()+41].SetLineColor(kRed);
2773 fGraphRateScan[fRateScanPatch1->value()+41].SetMarkerColor(kRed);
2774 fGraphRateScan[fRateScanPatch1->value()+41].Draw("PL");
2775 }
2776 if (fRateScanPatch2->value()>=0)
2777 {
2778 fGraphRateScan[fRateScanPatch2->value()+41].SetLineColor(kGreen);
2779 fGraphRateScan[fRateScanPatch2->value()+41].SetMarkerColor(kGreen);
2780 fGraphRateScan[fRateScanPatch2->value()+41].Draw("PL");
2781 }
2782 if (fRateScanBoard1->value()>=0)
2783 {
2784 fGraphRateScan[fRateScanBoard1->value()+1].SetLineColor(kMagenta);
2785 fGraphRateScan[fRateScanBoard1->value()+1].SetMarkerColor(kMagenta);
2786 fGraphRateScan[fRateScanBoard1->value()+1].Draw("PL");
2787 }
2788 if (fRateScanBoard2->value()>=0)
2789 {
2790 fGraphRateScan[fRateScanBoard2->value()+1].SetLineColor(kCyan);
2791 fGraphRateScan[fRateScanBoard2->value()+1].SetMarkerColor(kCyan);
2792 fGraphRateScan[fRateScanBoard2->value()+1].Draw("PL");
2793 }
2794
2795 c->Modified();
2796 c->Update();
2797#endif
2798 }
2799
2800 void handleRateScan(const DimData &d)
2801 {
2802 if (!CheckSize(d, 206*sizeof(float)))
2803 return;
2804
2805 UpdateRateScan(d.get<uint32_t>(8), d.ptr<float>(20));
2806 }
2807
2808 // ===================== MAGIC Weather ==================================
2809
2810 void handleMagicWeather(const DimData &d)
2811 {
2812 if (!CheckSize(d, 7*sizeof(float)+sizeof(uint16_t)))
2813 return;
2814
2815 const float *ptr = d.ptr<float>(2);
2816
2817 fMagicTemp->setValue(ptr[0]);
2818 fMagicDew->setValue(ptr[1]);
2819 fMagicHum->setValue(ptr[2]);
2820 fMagicPressure->setValue(ptr[3]);
2821 fMagicWind->setValue(ptr[4]);
2822 fMagicGusts->setValue(ptr[5]);
2823 fMagicWindDir->setValue(ptr[6]);
2824 }
2825
2826 // ========================== FSC =======================================
2827
2828 vector<int16_t> fVecBiasVolt;
2829 vector<int16_t> fVecBiasCurrent;
2830
2831 void handleBiasVolt(const DimData &d)
2832 {
2833 if (!CheckSize(d, 2*416*sizeof(int16_t)))
2834 return;
2835
2836 const int16_t *ptr = d.ptr<int16_t>();
2837
2838 fVecBiasVolt.assign(ptr, ptr+2*416);
2839
2840 on_fBiasDispRefVolt_stateChanged();
2841 UpdateBiasValues();
2842 }
2843
2844 void handleBiasCurrent(const DimData &d)
2845 {
2846 if (!CheckSize(d, 416*sizeof(int16_t)))
2847 return;
2848
2849 const int16_t *ptr = d.ptr<int16_t>();
2850
2851 fVecBiasCurrent.assign(ptr, ptr+416);
2852
2853 valarray<double> dat(0., 1440);
2854
2855 // fPatch converts from software id to software patch id
2856 for (int i=0; i<1440; i++)
2857 {
2858 const PixelMapEntry &entry = fPixelMap.index(i);
2859
2860 // FIXME: Display Overcurrent
2861 /*
2862 dat[i] = fVecBiasVolt[entry.hv()]*90./4096;
2863 double amp = abs(ptr[entry.hv()]);
2864 if (fBiasOffsets.size()>0)
2865 amp -= fBiasOffsets[entry.hv()];
2866 amp *= 5000./4096;
2867 amp *= 5200 *1e-6;
2868 dat[i] -= amp;
2869 */
2870
2871 dat[i] = abs(ptr[entry.hv()]);
2872 if (fBiasOffsets.size()>0)
2873 dat[i] -= fBiasOffsets[entry.hv()];
2874 dat[i] *= 5000./4096;
2875
2876 dat[i] /= entry.group()==0 ? 4 : 5;
2877
2878 fBiasCamA->SetEnable(i, uint16_t(ptr[entry.hv()])!=0x8000);
2879 fBiasCamA->highlightPixel(i, ptr[entry.hv()]<0);
2880 }
2881
2882 fBiasCamA->SetData(dat);
2883 fBiasCamA->updateCamera();
2884
2885 UpdateBiasValues();
2886 }
2887
2888 // ====================== MessageImp ====================================
2889
2890 bool fChatOnline;
2891
2892 void handleStateChanged(const Time &time, const std::string &server,
2893 const State &s)
2894 {
2895 // FIXME: Prefix tooltip with time
2896 if (server=="MCP")
2897 {
2898 // FIXME: Enable FTU page!!!
2899 fStatusMCPLabel->setText(s.name.c_str());
2900 fStatusMCPLabel->setToolTip(s.comment.c_str());
2901
2902 if (s.index<2) // No Dim connection
2903 SetLedColor(fStatusMCPLed, kLedGray, time);
2904 if (s.index==2) // Disconnected
2905 SetLedColor(fStatusMCPLed, kLedRed, time);
2906 if (s.index==3) // Connecting
2907 SetLedColor(fStatusMCPLed, kLedOrange, time);
2908 if (s.index==4) // Connected
2909 SetLedColor(fStatusMCPLed, kLedYellow, time);
2910 if (s.index==5 || s.index==10) // Idle
2911 SetLedColor(fStatusMCPLed, kLedGreen, time);
2912
2913 if (s.index>=7 && s.index<=9)
2914 SetLedColor(fStatusMCPLed, kLedGreenBar, time);
2915
2916 fMcpStartRun->setEnabled(s.index>=5);
2917 fMcpStopRun->setEnabled(s.index>=5);
2918 fMcpReset->setEnabled(s.index==5||(s.index>=7 && s.index<=10));
2919 }
2920
2921 if (server=="FTM_CONTROL")
2922 {
2923 // FIXME: Enable FTU page!!!
2924 fStatusFTMLabel->setText(s.name.c_str());
2925 fStatusFTMLabel->setToolTip(s.comment.c_str());
2926
2927 bool enable = false;
2928 const bool configuring =
2929 s.index==FTM::StateMachine::kConfiguring1 ||
2930 s.index==FTM::StateMachine::kConfiguring2 ||
2931 s.index==FTM::StateMachine::kConfigured;
2932
2933 if (s.index<FTM::StateMachine::kDisconnected) // No Dim connection
2934 SetLedColor(fStatusFTMLed, kLedGray, time);
2935 if (s.index==FTM::StateMachine::kDisconnected) // Dim connection / FTM disconnected
2936 SetLedColor(fStatusFTMLed, kLedYellow, time);
2937 if (s.index==FTM::StateMachine::kConnected ||
2938 s.index==FTM::StateMachine::kIdle ||
2939 configuring) // Dim connection / FTM connected
2940 SetLedColor(fStatusFTMLed, kLedGreen, time);
2941 if (s.index==FTM::StateMachine::kTriggerOn) // Dim connection / FTM connected
2942 SetLedColor(fStatusFTMLed, kLedGreenCheck, time);
2943 if (s.index==FTM::StateMachine::kConnected ||
2944 s.index==FTM::StateMachine::kIdle) // Dim connection / FTM connected
2945 enable = true;
2946
2947 fFtmStartRun->setEnabled(!configuring && enable);
2948 fFtmStopRun->setEnabled(!configuring && (enable || s.index==FTM::StateMachine::kTriggerOn));
2949
2950 fTriggerWidget->setEnabled(enable);
2951 fFtuGroupEnable->setEnabled(enable);
2952 fRatesControls->setEnabled(enable);
2953 fFtuWidget->setEnabled(s.index>FTM::StateMachine::kDisconnected);
2954
2955 if (s.index>=FTM::StateMachine::kConnected)
2956 SetFtuStatusLed(time);
2957 else
2958 {
2959 SetLedColor(fStatusFTULed, kLedGray, time);
2960 fStatusFTULabel->setText("Offline");
2961 fStatusFTULabel->setToolTip("FTM is not online.");
2962 }
2963 }
2964
2965 if (server=="FAD_CONTROL")
2966 {
2967 fStatusFADLabel->setText(s.name.c_str());
2968 fStatusFADLabel->setToolTip(s.comment.c_str());
2969
2970 bool enable = false;
2971
2972 if (s.index<FAD::kOffline) // No Dim connection
2973 {
2974 SetLedColor(fStatusFADLed, kLedGray, time);
2975
2976 // Timing problem - sometimes they stay gray :(
2977 //for (int i=0; i<40; i++)
2978 // SetLedColor(fFadLED[i], kLedGray, time);
2979
2980 /*
2981 fStatusEventBuilderLabel->setText("Offline");
2982 fStatusEventBuilderLabel->setToolTip("No connection to fadctrl.");
2983 fEvtBldWidget->setEnabled(false);
2984
2985 SetLedColor(fStatusEventBuilderLed, kLedGray, time);
2986 */
2987 }
2988 if (s.index==FAD::kOffline) // Dim connection / FTM disconnected
2989 SetLedColor(fStatusFADLed, kLedRed, time);
2990 if (s.index==FAD::kDisconnected) // Dim connection / FTM disconnected
2991 SetLedColor(fStatusFADLed, kLedOrange, time);
2992 if (s.index==FAD::kConnecting) // Dim connection / FTM disconnected
2993 {
2994 SetLedColor(fStatusFADLed, kLedYellow, time);
2995 // FIXME FIXME FIXME: The LEDs are not displayed when disabled!
2996 enable = true;
2997 }
2998 if (s.index>=FAD::kConnected) // Dim connection / FTM connected
2999 {
3000 SetLedColor(fStatusFADLed, kLedGreen, time);
3001 enable = true;
3002 }
3003
3004 fFadWidget->setEnabled(enable);
3005
3006 fFadStart->setEnabled(s.index==FAD::kOffline);
3007 fFadStop->setEnabled(s.index>FAD::kOffline);
3008 fFadAbort->setEnabled(s.index>FAD::kOffline);
3009 fFadSoftReset->setEnabled(s.index>FAD::kOffline);
3010 fFadHardReset->setEnabled(s.index>FAD::kOffline);
3011 }
3012
3013 if (server=="FSC_CONTROL")
3014 {
3015 fStatusFSCLabel->setText(s.name.c_str());
3016 fStatusFSCLabel->setToolTip(s.comment.c_str());
3017
3018 bool enable = false;
3019
3020 if (s.index<1) // No Dim connection
3021 SetLedColor(fStatusFSCLed, kLedGray, time);
3022 if (s.index==1) // Dim connection / FTM disconnected
3023 SetLedColor(fStatusFSCLed, kLedRed, time);
3024 if (s.index>=2) // Dim connection / FTM disconnected
3025 {
3026 SetLedColor(fStatusFSCLed, kLedGreen, time);
3027 enable = true;
3028 }
3029
3030 fAuxWidget->setEnabled(enable);
3031 }
3032
3033 if (server=="DRIVE_CONTROL")
3034 {
3035 fStatusDriveLabel->setText(s.name.c_str());
3036 fStatusDriveLabel->setToolTip(s.comment.c_str());
3037
3038 if (s.index<1) // No Dim connection
3039 SetLedColor(fStatusDriveLed, kLedGray, time);
3040 if (s.index==1) // Dim connection / No connection to cosy
3041 SetLedColor(fStatusDriveLed, kLedRed, time);
3042 if (s.index==2 || s.index==3) // Not Ready
3043 SetLedColor(fStatusDriveLed, kLedGreenBar, time);
3044 if (s.index==4 || s.index==5) // Connected / Armed
3045 SetLedColor(fStatusDriveLed, kLedGreen, time);
3046 if (s.index==6) // Moving
3047 SetLedColor(fStatusDriveLed, kLedInProgress, time);
3048 if (s.index==7) // Tracking
3049 SetLedColor(fStatusDriveLed, kLedGreenCheck, time);
3050 if (s.index==99) // Error
3051 SetLedColor(fStatusDriveLed, kLedGreenWarn, time);
3052 }
3053
3054 if (server=="BIAS_CONTROL")
3055 {
3056 fStatusBiasLabel->setText(s.name.c_str());
3057 fStatusBiasLabel->setToolTip(s.comment.c_str());
3058
3059 if (s.index<1) // No Dim connection
3060 SetLedColor(fStatusBiasLed, kLedGray, time);
3061 if (s.index==BIAS::kDisconnected) // Dim connection / FTM disconnected
3062 SetLedColor(fStatusBiasLed, kLedRed, time);
3063 if (s.index==BIAS::kConnecting || s.index==BIAS::kInitializing) // Connecting / Initializing
3064 SetLedColor(fStatusBiasLed, kLedOrange, time);
3065 if (s.index==BIAS::kVoltageOff) // At reference
3066 SetLedColor(fStatusBiasLed, kLedGreenBar, time);
3067 if (s.index==BIAS::kNotReferenced) // At reference
3068 SetLedColor(fStatusBiasLed, kLedGreenWarn, time);
3069 if (s.index==BIAS::kRamping) // Ramping
3070 SetLedColor(fStatusBiasLed, kLedInProgress, time);
3071 if (s.index==BIAS::kVoltageOn) // At reference
3072 SetLedColor(fStatusBiasLed, kLedGreenCheck, time);
3073 if (s.index==BIAS::kOverCurrent) // Over current
3074 SetLedColor(fStatusBiasLed, kLedWarnBorder, time);
3075 if (s.index==BIAS::kExpertMode) // ExpertMode
3076 SetLedColor(fStatusBiasLed, kLedWarnTriangleBorder, time);
3077
3078 fBiasWidget->setEnabled(s.index>=3);
3079 }
3080
3081 if (server=="FEEDBACK")
3082 {
3083 fStatusFeedbackLabel->setText(s.name.c_str());
3084 fStatusFeedbackLabel->setToolTip(s.comment.c_str());
3085
3086 if (s.index>8) // Running
3087 SetLedColor(fStatusFeedbackLed, kLedGreenCheck, time);
3088 if (s.index==7 || s.index==8) // Idle
3089 SetLedColor(fStatusFeedbackLed, kLedGreen, time);
3090 if (s.index>=4 && s.index<=6) // Connected
3091 SetLedColor(fStatusFeedbackLed, kLedYellow, time);
3092 if (s.index==3) // Connecting
3093 SetLedColor(fStatusFeedbackLed, kLedOrange, time);
3094 if (s.index<3) // NoDim / Disconnected
3095 SetLedColor(fStatusFeedbackLed, kLedRed, time);
3096 if (s.index<1) // No Dim connection
3097 SetLedColor(fStatusFeedbackLed, kLedGray, time);
3098
3099 fFeedbackWidget->setEnabled(s.index>=3);
3100 fFeedbackCalibrate->setEnabled(s.index==4 || s.index==6);
3101 fFeedbackStop->setEnabled(s.index>4);
3102 fFeedbackTempStart->setEnabled(s.index==4 || s.index==5);
3103 fFeedbackTempOffset->setEnabled(s.index<=6);
3104 fFeedbackOutputEnable->setEnabled(s.index<=8);
3105 fFeedbackOutputDisable->setEnabled(s.index!=7 && s.index!=8);
3106
3107 fFeedbackFrameLeft->setEnabled(s.index!=7 && s.index!=9);
3108 fFeedbackCanvLeft->setEnabled(s.index!=7 && s.index!=9);
3109 }
3110
3111 if (server=="RATE_CONTROL")
3112 {
3113 fStatusRateControlLabel->setText(s.name.c_str());
3114 fStatusRateControlLabel->setToolTip(s.comment.c_str());
3115
3116 if (s.index==7) // InProgress
3117 SetLedColor(fStatusRateControlLed, kLedGreenCheck, time);
3118 if (s.index==6) // GlobalThresholdSet
3119 SetLedColor(fStatusRateControlLed, kLedGreen, time);
3120 if (s.index==5) // SettingGlobalThreshold
3121 SetLedColor(fStatusRateControlLed, kLedInProgress, time);
3122 if (s.index==4) // Connected
3123 SetLedColor(fStatusRateControlLed, kLedGreenBar, time);
3124 if (s.index==3) // Connecting
3125 SetLedColor(fStatusRateControlLed, kLedOrange, time);
3126 if (s.index<3) // NoDim / Disconnected
3127 SetLedColor(fStatusRateControlLed, kLedRed, time);
3128 if (s.index<1) // No Dim connection
3129 SetLedColor(fStatusRateControlLed, kLedGray, time);
3130 }
3131
3132 if (server=="DATA_LOGGER")
3133 {
3134 fStatusLoggerLabel->setText(s.name.c_str());
3135 fStatusLoggerLabel->setToolTip(s.comment.c_str());
3136
3137 bool enable = true;
3138
3139 if (s.index<30) // Ready/Waiting
3140 SetLedColor(fStatusLoggerLed, kLedYellow, time);
3141 if (s.index==30) // Ready/Waiting
3142 SetLedColor(fStatusLoggerLed, kLedGreen, time);
3143 if (s.index<-1) // Offline
3144 {
3145 SetLedColor(fStatusLoggerLed, kLedGray, time);
3146 enable = false;
3147 }
3148 if (s.index>=0x100) // Error
3149 SetLedColor(fStatusLoggerLed, kLedRed, time);
3150 if (s.index==40) // Logging
3151 SetLedColor(fStatusLoggerLed, kLedGreen, time);
3152
3153 fLoggerWidget->setEnabled(enable);
3154 fLoggerStart->setEnabled(s.index>-1 && s.index<30);
3155 fLoggerStop->setEnabled(s.index>=30);
3156 }
3157
3158 if (server=="CHAT")
3159 {
3160 fStatusChatLabel->setText(s.name.c_str());
3161
3162 fChatOnline = s.index==0;
3163
3164 SetLedColor(fStatusChatLed, fChatOnline ? kLedGreen : kLedGray, time);
3165
3166 fChatSend->setEnabled(fChatOnline);
3167 fChatMessage->setEnabled(fChatOnline);
3168 }
3169
3170 if (server=="RATESCAN")
3171 fRateScanControls->setEnabled(s.index>=4);
3172
3173 if (server=="SCHEDULER")
3174 {
3175 fStatusSchedulerLabel->setText(s.name.c_str());
3176
3177 SetLedColor(fStatusSchedulerLed, s.index>=0 ? kLedGreen : kLedRed, time);
3178 }
3179 }
3180
3181 void on_fTabWidget_currentChanged(int which)
3182 {
3183 if (fTabWidget->tabText(which)=="Chat")
3184 fTabWidget->setTabIcon(which, QIcon());
3185 }
3186
3187 void handleWrite(const Time &time, const string &text, int qos)
3188 {
3189 stringstream out;
3190
3191 if (text.substr(0, 6)=="CHAT: ")
3192 {
3193 if (qos==MessageImp::kDebug)
3194 return;
3195
3196 out << "<font size='-1' color='navy'>[<B>";
3197 out << time.GetAsStr("%H:%M:%S");
3198 out << "</B>]</FONT> " << text.substr(6);
3199 fChatText->append(out.str().c_str());
3200
3201 if (fTabWidget->tabText(fTabWidget->currentIndex())=="Chat")
3202 return;
3203
3204 static int num = 0;
3205 if (num++<2)
3206 return;
3207
3208 for (int i=0; i<fTabWidget->count(); i++)
3209 if (fTabWidget->tabText(i)=="Chat")
3210 {
3211 fTabWidget->setTabIcon(i, QIcon(":/Resources/icons/warning 3.png"));
3212 break;
3213 }
3214
3215 return;
3216 }
3217
3218
3219 out << "<font style='font-family:monospace' color='";
3220
3221 switch (qos)
3222 {
3223 case kMessage: out << "black"; break;
3224 case kInfo: out << "green"; break;
3225 case kWarn: out << "#FF6600"; break;
3226 case kError: out << "maroon"; break;
3227 case kFatal: out << "maroon"; break;
3228 case kDebug: out << "navy"; break;
3229 default: out << "navy"; break;
3230 }
3231 out << "'>";
3232 out << time.GetAsStr("%H:%M:%S.%f").substr(0,12);
3233 out << " - " << text << "</font>";
3234
3235 fLogText->append(out.str().c_str());
3236
3237 if (qos>=kWarn && qos!=kDebug)
3238 fTextEdit->append(out.str().c_str());
3239 }
3240
3241 void IndicateStateChange(const Time &time, const std::string &server)
3242 {
3243 const State s = GetState(server, GetCurrentState(server));
3244
3245 QApplication::postEvent(this,
3246 new FunctionEvent(boost::bind(&FactGui::handleStateChanged, this, time, server, s)));
3247 }
3248
3249 int Write(const Time &time, const string &txt, int qos)
3250 {
3251 QApplication::postEvent(this,
3252 new FunctionEvent(boost::bind(&FactGui::handleWrite, this, time, txt, qos)));
3253
3254 return 0;
3255 }
3256
3257 // ====================== Dim infoHandler================================
3258
3259 void handleDimService(const string &txt)
3260 {
3261 fDimSvcText->append(txt.c_str());
3262 }
3263
3264 void infoHandlerService(DimInfo &info)
3265 {
3266 const string fmt = string(info.getFormat()).empty() ? "C" : info.getFormat();
3267
3268 stringstream dummy;
3269 const Converter conv(dummy, fmt, false);
3270
3271 const Time tm(info.getTimestamp(), info.getTimestampMillisecs()*1000);
3272
3273 stringstream out;
3274 out << "<font size'-1' color='navy'>[";
3275 out << tm.GetAsStr("%H:%M:%S.%f").substr(0,12);
3276 out << "]</font> <B>" << info.getName() << "</B> - ";
3277
3278 bool iserr = 2;
3279 if (!conv)
3280 {
3281 out << "Compilation of format string '" << fmt << "' failed!";
3282 }
3283 else
3284 {
3285 try
3286 {
3287 const string dat = info.getSize()==0 ? "&lt;empty&gt;" : conv.GetString(info.getData(), info.getSize());
3288 out << dat;
3289 iserr = info.getSize()==0;
3290 }
3291 catch (const runtime_error &e)
3292 {
3293 out << "Conversion to string failed!<pre>" << e.what() << "</pre>";
3294 }
3295 }
3296
3297 // srand(hash<string>()(string(info.getName())));
3298 // int bg = rand()&0xffffff;
3299
3300 int bg = hash<string>()(string(info.getName()));
3301
3302 // allow only light colors
3303 bg = ~(bg&0x1f1f1f)&0xffffff;
3304
3305 if (iserr==2)
3306 bg = 0xffffff;
3307
3308 stringstream bgcol;
3309 bgcol << hex << setfill('0') << setw(6) << bg;
3310
3311 const string col = iserr==0 ? "black" : (iserr==1 ? "#FF6600" : "black");
3312 const string str = "<table width='100%' bgcolor=#"+bgcol.str()+"><tr><td><font color='"+col+"'>"+out.str()+"</font></td></tr></table>";
3313
3314 QApplication::postEvent(this,
3315 new FunctionEvent(boost::bind(&FactGui::handleDimService, this, str)));
3316 }
3317
3318 void CallInfoHandler(void (FactGui::*handler)(const DimData&), const DimData &d)
3319 {
3320 fInHandler = true;
3321 (this->*handler)(d);
3322 fInHandler = false;
3323 }
3324
3325 /*
3326 void CallInfoHandler(const boost::function<void()> &func)
3327 {
3328 // This ensures that newly received values are not sent back to the emitter
3329 // because changing the value emits the valueChanged signal (or similar)
3330 fInHandler = true;
3331 func();
3332 fInHandler = false;
3333 }*/
3334
3335 void PostInfoHandler(void (FactGui::*handler)(const DimData&))
3336 {
3337 //const boost::function<void()> f = boost::bind(handler, this, DimData(getInfo()));
3338
3339 FunctionEvent *evt = new FunctionEvent(boost::bind(&FactGui::CallInfoHandler, this, handler, DimData(getInfo())));
3340 // FunctionEvent *evt = new FunctionEvent(boost::bind(&FactGui::CallInfoHandler, this, f));
3341 // FunctionEvent *evt = new FunctionEvent(boost::bind(handler, this, DimData(getInfo()))));
3342
3343 QApplication::postEvent(this, evt);
3344 }
3345
3346 void infoHandler()
3347 {
3348 // Initialize the time-stamp (what a weird workaround...)
3349 if (getInfo())
3350 getInfo()->getTimestamp();
3351
3352 if (getInfo()==&fDimDNS)
3353 return PostInfoHandler(&FactGui::handleDimDNS);
3354#ifdef DEBUG_DIM
3355 cout << "HandleDimInfo " << getInfo()->getName() << endl;
3356#endif
3357 if (getInfo()==&fDimLoggerStats)
3358 return PostInfoHandler(&FactGui::handleLoggerStats);
3359
3360// if (getInfo()==&fDimFadFiles)
3361// return PostInfoHandler(&FactGui::handleFadFiles);
3362
3363 if (getInfo()==&fDimFadWriteStats)
3364 return PostInfoHandler(&FactGui::handleFadWriteStats);
3365
3366 if (getInfo()==&fDimFadConnections)
3367 return PostInfoHandler(&FactGui::handleFadConnections);
3368
3369 if (getInfo()==&fDimFadFwVersion)
3370 return PostInfoHandler(&FactGui::handleFadFwVersion);
3371
3372 if (getInfo()==&fDimFadRunNumber)
3373 return PostInfoHandler(&FactGui::handleFadRunNumber);
3374
3375 if (getInfo()==&fDimFadDNA)
3376 return PostInfoHandler(&FactGui::handleFadDNA);
3377
3378 if (getInfo()==&fDimFadTemperature)
3379 return PostInfoHandler(&FactGui::handleFadTemperature);
3380
3381 if (getInfo()==&fDimFadRefClock)
3382 return PostInfoHandler(&FactGui::handleFadRefClock);
3383
3384 if (getInfo()==&fDimFadRoi)
3385 return PostInfoHandler(&FactGui::handleFadRoi);
3386
3387 if (getInfo()==&fDimFadDac)
3388 return PostInfoHandler(&FactGui::handleFadDac);
3389
3390 if (getInfo()==&fDimFadDrsCalibration)
3391 return PostInfoHandler(&FactGui::handleFadDrsCalibration);
3392
3393 if (getInfo()==&fDimFadPrescaler)
3394 return PostInfoHandler(&FactGui::handleFadPrescaler);
3395
3396 if (getInfo()==&fDimFadStatus)
3397 return PostInfoHandler(&FactGui::handleFadStatus);
3398
3399 if (getInfo()==&fDimFadStatistics1)
3400 return PostInfoHandler(&FactGui::handleFadStatistics1);
3401
3402 if (getInfo()==&fDimFadStatistics2)
3403 return PostInfoHandler(&FactGui::handleFadStatistics2);
3404
3405 if (getInfo()==&fDimFadFileFormat)
3406 return PostInfoHandler(&FactGui::handleFadFileFormat);
3407
3408 if (getInfo()==&fDimFadEvents)
3409 return PostInfoHandler(&FactGui::handleFadEvents);
3410
3411 if (getInfo()==&fDimFadRuns)
3412 return PostInfoHandler(&FactGui::handleFadRuns);
3413
3414 if (getInfo()==&fDimFadStartRun)
3415 return PostInfoHandler(&FactGui::handleFadStartRun);
3416
3417 if (getInfo()==&fDimFadRawData)
3418 return PostInfoHandler(&FactGui::handleFadRawData);
3419
3420 if (getInfo()==&fDimFadEventData)
3421 return PostInfoHandler(&FactGui::handleFadEventData);
3422
3423/*
3424 if (getInfo()==&fDimFadSetup)
3425 return PostInfoHandler(&FactGui::handleFadSetup);
3426*/
3427 if (getInfo()==&fDimLoggerFilenameNight)
3428 return PostInfoHandler(&FactGui::handleLoggerFilenameNight);
3429
3430 if (getInfo()==&fDimLoggerNumSubs)
3431 return PostInfoHandler(&FactGui::handleLoggerNumSubs);
3432
3433 if (getInfo()==&fDimLoggerFilenameRun)
3434 return PostInfoHandler(&FactGui::handleLoggerFilenameRun);
3435
3436 if (getInfo()==&fDimFtmTriggerRates)
3437 return PostInfoHandler(&FactGui::handleFtmTriggerRates);
3438
3439 if (getInfo()==&fDimFtmCounter)
3440 return PostInfoHandler(&FactGui::handleFtmCounter);
3441
3442 if (getInfo()==&fDimFtmDynamicData)
3443 return PostInfoHandler(&FactGui::handleFtmDynamicData);
3444
3445 if (getInfo()==&fDimFtmPassport)
3446 return PostInfoHandler(&FactGui::handleFtmPassport);
3447
3448 if (getInfo()==&fDimFtmFtuList)
3449 return PostInfoHandler(&FactGui::handleFtmFtuList);
3450
3451 if (getInfo()==&fDimFtmStaticData)
3452 return PostInfoHandler(&FactGui::handleFtmStaticData);
3453
3454 if (getInfo()==&fDimFtmError)
3455 return PostInfoHandler(&FactGui::handleFtmError);
3456
3457 if (getInfo()==&fDimFscTemp)
3458 return PostInfoHandler(&FactGui::handleFscTemp);
3459
3460 if (getInfo()==&fDimFscVolt)
3461 return PostInfoHandler(&FactGui::handleFscVolt);
3462
3463 if (getInfo()==&fDimFscCurrent)
3464 return PostInfoHandler(&FactGui::handleFscCurrent);
3465
3466 if (getInfo()==&fDimFscHumidity)
3467 return PostInfoHandler(&FactGui::handleFscHumidity);
3468
3469 if (getInfo()==&fDimBiasVolt)
3470 return PostInfoHandler(&FactGui::handleBiasVolt);
3471
3472 if (getInfo()==&fDimBiasCurrent)
3473 return PostInfoHandler(&FactGui::handleBiasCurrent);
3474
3475 if (getInfo()==&fDimFeedbackReference)
3476 return PostInfoHandler(&FactGui::handleFeedbackReference);
3477
3478 if (getInfo()==&fDimFeedbackDeviation)
3479 return PostInfoHandler(&FactGui::handleFeedbackDeviation);
3480
3481 if (getInfo()==&fDimFeedbackCalibration)
3482 return PostInfoHandler(&FactGui::handleFeedbackCalibration);
3483
3484 if (getInfo()==&fDimRateScan)
3485 return PostInfoHandler(&FactGui::handleRateScan);
3486
3487 if (getInfo()==&fDimMagicWeather)
3488 return PostInfoHandler(&FactGui::handleMagicWeather);
3489
3490// if (getInfo()==&fDimFadFiles)
3491// return PostInfoHandler(&FactGui::handleFadFiles);
3492
3493 for (map<string,DimInfo*>::iterator i=fServices.begin(); i!=fServices.end(); i++)
3494 if (i->second==getInfo())
3495 {
3496 infoHandlerService(*i->second);
3497 return;
3498 }
3499
3500 DimNetwork::infoHandler();
3501 }
3502
3503
3504 // ======================================================================
3505
3506 bool event(QEvent *evt)
3507 {
3508 if (dynamic_cast<FunctionEvent*>(evt))
3509 return static_cast<FunctionEvent*>(evt)->Exec();
3510
3511 if (dynamic_cast<CheckBoxEvent*>(evt))
3512 {
3513 const QStandardItem &item = static_cast<CheckBoxEvent*>(evt)->item;
3514 const QStandardItem *par = item.parent();
3515 if (par)
3516 {
3517 const QString server = par->text();
3518 const QString service = item.text();
3519
3520 const string s = (server+'/'+service).toStdString();
3521
3522 if (item.checkState()==Qt::Checked)
3523 SubscribeService(s);
3524 else
3525 UnsubscribeService(s);
3526 }
3527 }
3528
3529 return MainWindow::event(evt); // unrecognized
3530 }
3531
3532 void on_fDimCmdSend_clicked()
3533 {
3534 const QString server = fDimCmdServers->currentIndex().data().toString();
3535 const QString command = fDimCmdCommands->currentIndex().data().toString();
3536 const QString arguments = fDimCmdLineEdit->displayText();
3537
3538 // FIXME: Sending a command exactly when the info Handler changes
3539 // the list it might lead to confusion.
3540 try
3541 {
3542 SendDimCommand(server.toStdString(), command.toStdString()+" "+arguments.toStdString());
3543 fTextEdit->append("<font color='green'>Command '"+server+'/'+command+"' successfully emitted.</font>");
3544 fDimCmdLineEdit->clear();
3545 }
3546 catch (const runtime_error &e)
3547 {
3548 stringstream txt;
3549 txt << e.what();
3550
3551 string buffer;
3552 while (getline(txt, buffer, '\n'))
3553 fTextEdit->append(("<font color='red'><pre>"+buffer+"</pre></font>").c_str());
3554 }
3555 }
3556
3557#ifdef HAVE_ROOT
3558 void slot_RootEventProcessed(TObject *obj, unsigned int evt, TCanvas *canv)
3559 {
3560 // kMousePressEvent // TCanvas processed QEvent mousePressEvent
3561 // kMouseMoveEvent // TCanvas processed QEvent mouseMoveEvent
3562 // kMouseReleaseEvent // TCanvas processed QEvent mouseReleaseEvent
3563 // kMouseDoubleClickEvent // TCanvas processed QEvent mouseDoubleClickEvent
3564 // kKeyPressEvent // TCanvas processed QEvent keyPressEvent
3565 // kEnterEvent // TCanvas processed QEvent enterEvent
3566 // kLeaveEvent // TCanvas processed QEvent leaveEvent
3567
3568 if (dynamic_cast<TCanvas*>(obj))
3569 return;
3570
3571 TQtWidget *tipped = static_cast<TQtWidget*>(sender());
3572
3573 if (evt==11/*kMouseReleaseEvent*/)
3574 return;
3575
3576 if (evt==61/*kMouseDoubleClickEvent*/)
3577 return;
3578
3579 if (obj)
3580 {
3581 // Find the object which will get picked by the GetObjectInfo
3582 // due to buffer overflows in many root-versions
3583 // in TH1 and TProfile we have to work around and implement
3584 // our own GetObjectInfo which make everything a bit more
3585 // complicated.
3586 canv->cd();
3587#if ROOT_VERSION_CODE > ROOT_VERSION(5,22,00)
3588 const char *objectInfo =
3589 obj->GetObjectInfo(tipped->GetEventX(),tipped->GetEventY());
3590#else
3591 const char *objectInfo = dynamic_cast<TH1*>(obj) ?
3592 "" : obj->GetObjectInfo(tipped->GetEventX(),tipped->GetEventY());
3593#endif
3594
3595 QString tipText;
3596 tipText += obj->GetName();
3597 tipText += " [";
3598 tipText += obj->ClassName();
3599 tipText += "]: ";
3600 tipText += objectInfo;
3601
3602 fStatusBar->showMessage(tipText, 3000);
3603 }
3604
3605 gSystem->DispatchOneEvent(kFALSE);
3606 //gSystem->ProcessEvents();
3607 //QWhatsThis::display(tipText)
3608 }
3609
3610 void slot_RootUpdate()
3611 {
3612 gSystem->DispatchOneEvent(kFALSE);
3613 //gSystem->ProcessEvents();
3614 QTimer::singleShot(10, this, SLOT(slot_RootUpdate()));
3615 }
3616#endif
3617
3618 void ChoosePatchThreshold(Camera &cam, int isw)
3619 {
3620 cam.Reset();
3621
3622 fThresholdIdx->setValue(isw);
3623
3624 const int ihw = isw<0 ? 0 : fPatchMapHW[isw];
3625
3626 fPatchRate->setEnabled(isw>=0);
3627 fThresholdCrate->setEnabled(isw>=0);
3628 fThresholdBoard->setEnabled(isw>=0);
3629 fThresholdPatch->setEnabled(isw>=0);
3630
3631 if (isw<0)
3632 return;
3633
3634 const int patch = ihw%4;
3635 const int board = (ihw/4)%10;
3636 const int crate = (ihw/4)/10;
3637
3638 fInChoosePatchTH = true;
3639
3640 fThresholdCrate->setValue(crate);
3641 fThresholdBoard->setValue(board);
3642 fThresholdPatch->setValue(patch);
3643
3644 fInChoosePatchTH = false;
3645
3646 fThresholdVal->setValue(fFtmStaticData.fThreshold[ihw]);
3647 fPatchRate->setValue(fTriggerRates.fPatchRate[ihw]);
3648 fBoardRate->setValue(fTriggerRates.fBoardRate[ihw/4]);
3649
3650 // Loop over the software idx of all pixels
3651// for (unsigned int i=0; i<1440; i++)
3652// if (fPatchHW[i]==ihw)
3653// cam.SetBold(i);
3654 }
3655
3656 /*
3657 void ChoosePatchBias(Camera &cam, int isw)
3658 {
3659 cam.Reset();
3660
3661 fBiasChannel->setValue(isw);
3662
3663 const int ihw = isw<0 ? 0 : fPatchMapHW[isw];
3664
3665 fBiasCurrent->setEnabled(isw>=0);
3666 fBiasCrate->setEnabled(isw>=0);
3667 fBiasBoard->setEnabled(isw>=0);
3668 fBiasPatch->setEnabled(isw>=0);
3669
3670 if (isw<0)
3671 return;
3672
3673 const int patch = ihw%4;
3674 const int board = (ihw/4)%10;
3675 const int crate = (ihw/4)/10;
3676
3677 fInChoosePatchBias = true;
3678
3679 fBiasCrate->setValue(crate);
3680 fBiasBoard->setValue(board);
3681 fBiasPatch->setValue(patch);
3682
3683 fInChoosePatchBias = false;
3684
3685 if (fVecBias.size()>0)
3686 {
3687 // FIXME: Mapping
3688 fBiasVoltDac->setValue(fVecBias[ihw]);
3689 fBiasVolt->setValue(fVecBias[ihw]*90./4096);
3690 }
3691
3692 fBiasCurrent->setValue(cam.GetData(isw));
3693
3694 // Loop over the software idx of all pixels
3695 for (unsigned int i=0; i<1440; i++)
3696 if (fPatchHW[i]==ihw)
3697 cam.SetBold(i);
3698 }*/
3699
3700 void slot_ChoosePixelThreshold(int isw)
3701 {
3702 fPixelIdx->setValue(isw);
3703
3704 const PixelMapEntry &entry = fPixelMap.index(isw);
3705 fPixelEnable->setChecked(fFtmStaticData.IsEnabled(entry.hw()));
3706 }
3707
3708 void slot_CameraDoubleClick(int isw)
3709 {
3710 fPixelIdx->setValue(isw);
3711
3712 const PixelMapEntry &entry = fPixelMap.index(isw);
3713 Dim::SendCommand("FTM_CONTROL/TOGGLE_PIXEL", uint16_t(entry.hw()));
3714 }
3715
3716 void slot_CameraMouseMove(int isw)
3717 {
3718 const PixelMapEntry &entry = fPixelMap.index(isw);
3719
3720 QString tipText;
3721 tipText += fRatesCanv->GetName();
3722 ostringstream str;
3723 str << setfill('0') <<
3724 " || HW: " << entry.crate() << "|" << entry.board() << "|" << entry.patch() << "|" << entry.pixel() << " (crate|board|patch|pixel)" <<
3725 " || HV: " << entry.hv_board << "|" << setw(2) << entry.hv_channel << " (board|channel)" <<
3726 " || ID: " << isw;
3727
3728
3729 tipText += str.str().c_str();
3730 fStatusBar->showMessage(tipText, 3000);
3731 }
3732
3733 /*
3734 void on_fThresholdIdx_valueChanged(int isw)
3735 {
3736 // fRatesCanv->SetBold(isw);
3737 // fRatesCanv->updateGL();
3738 }*/
3739
3740 /*
3741 void UpdateThresholdIdx()
3742 {
3743 if (fInChoosePatchTH)
3744 return;
3745
3746 const int crate = fThresholdCrate->value();
3747 const int board = fThresholdBoard->value();
3748 const int patch = fThresholdPatch->value();
3749
3750 const int ihw = patch + board*4 + crate*40;
3751
3752 int isw = 0;
3753 for (; isw<160; isw++)
3754 if (ihw==fPatchMapHW[isw])
3755 break;
3756
3757 on_fThresholdIdx_valueChanged(isw);
3758 }*/
3759
3760 void on_fPixelIdx_valueChanged(int isw)
3761 {
3762 int ii = 0;
3763 for (; ii<160; ii++)
3764 if (fPixelMap.index(isw).hw()/9==fPatchMapHW[ii])
3765 break;
3766
3767 fRatesCanv->SetWhite(isw);
3768 ChoosePatchThreshold(*fRatesCanv, ii);
3769
3770 const PixelMapEntry &entry = fPixelMap.index(isw);
3771 fPixelEnable->setChecked(fFtmStaticData.IsEnabled(entry.hw()));
3772 }
3773
3774 // ------------------- Bias display ---------------------
3775
3776 void UpdateBiasValues()
3777 {
3778 const int b = fBiasHvBoard->value();
3779 const int c = fBiasHvChannel->value();
3780
3781 const int ihw = b*32+c;
3782
3783 if (fVecBiasVolt.size()>0)
3784 {
3785 fBiasVoltCur->setValue(fVecBiasVolt[ihw]*90./4096);
3786 fBiasVoltRef->setValue(fVecBiasVolt[ihw+416]*90./4096);
3787
3788 SetLedColor(fBiasNominalLed,
3789 fVecBiasVolt[ihw]==fVecBiasVolt[ihw+416]?kLedGreen:kLedRed, Time());
3790 }
3791
3792 if (fVecBiasCurrent.size()>0)
3793 {
3794 double val = abs(fVecBiasCurrent[ihw]);
3795 if (fBiasOffsets.size()>0)
3796 val -= fBiasOffsets[ihw];
3797 val *= 5000/4096;
3798
3799 fBiasCurrent->setValue(val);
3800 SetLedColor(fBiasOverCurrentLed,
3801 fVecBiasCurrent[ihw]<0?kLedRed:kLedGreen, Time());
3802 }
3803
3804 if (fBiasOffsets.size()>0)
3805 fBiasOffset->setValue(fBiasOffsets[ihw]*5000./4096);
3806 fBiasOffset->setEnabled(fBiasOffsets.size()>0);
3807 }
3808
3809 void UpdateBiasCam(const PixelMapEntry &entry)
3810 {
3811 fInChooseBiasCam = true;
3812
3813 fBiasCamCrate->setValue(entry.crate());
3814 fBiasCamBoard->setValue(entry.board());
3815 fBiasCamPatch->setValue(entry.patch());
3816 fBiasCamPixel->setValue(entry.pixel());
3817
3818 fInChooseBiasCam = false;
3819 }
3820
3821 void BiasHvChannelChanged()
3822 {
3823 if (fInChooseBiasHv)
3824 return;
3825
3826 const int b = fBiasHvBoard->value();
3827 const int ch = fBiasHvChannel->value();
3828
3829 // FIXME: Mark corresponding patch in camera
3830 const PixelMapEntry &entry = fPixelMap.hv(b, ch);
3831 fBiasCamV->SetWhite(entry.index);
3832 fBiasCamA->SetWhite(entry.index);
3833 fBiasCamV->updateCamera();
3834 fBiasCamA->updateCamera();
3835
3836 UpdateBiasCam(entry);
3837 UpdateBiasValues();
3838 }
3839
3840 void UpdateBiasHv(const PixelMapEntry &entry)
3841 {
3842 fInChooseBiasHv = true;
3843
3844 fBiasHvBoard->setValue(entry.hv_board);
3845 fBiasHvChannel->setValue(entry.hv_channel);
3846
3847 fInChooseBiasHv = false;
3848 }
3849
3850 void BiasCamChannelChanged()
3851 {
3852 if (fInChooseBiasCam)
3853 return;
3854
3855 const int crate = fBiasCamCrate->value();
3856 const int board = fBiasCamBoard->value();
3857 const int patch = fBiasCamPatch->value();
3858 const int pixel = fBiasCamPixel->value();
3859
3860 // FIXME: Display corresponding patches
3861 const PixelMapEntry &entry = fPixelMap.cbpx(crate, board, patch, pixel);
3862 fBiasCamV->SetWhite(entry.index);
3863 fBiasCamA->SetWhite(entry.index);
3864 fBiasCamV->updateCamera();
3865 fBiasCamA->updateCamera();
3866
3867 UpdateBiasHv(entry);
3868 UpdateBiasValues();
3869 }
3870
3871 void slot_ChooseBiasChannel(int isw)
3872 {
3873 const PixelMapEntry &entry = fPixelMap.index(isw);
3874
3875 UpdateBiasHv(entry);
3876 UpdateBiasCam(entry);
3877 UpdateBiasValues();
3878 }
3879
3880 void on_fBiasDispRefVolt_stateChanged(int = 0)
3881 {
3882 // FIXME: Display patches for which ref==cur
3883
3884 valarray<double> dat(0., 1440);
3885
3886 int offset = 0;
3887 if (!fBiasDispRefVolt->isChecked())
3888 fBiasCamV->setTitle("Applied BIAS voltage");
3889 else
3890 {
3891 fBiasCamV->setTitle("Reference BIAS voltage");
3892 offset = 416;
3893 }
3894
3895 if (fVecBiasVolt.size()>0)
3896 {
3897 for (int i=0; i<1440; i++)
3898 {
3899 const PixelMapEntry &entry = fPixelMap.index(i);
3900 dat[i] = fVecBiasVolt[entry.hv()+offset]*90./4096;
3901
3902 fBiasCamV->highlightPixel(i, fVecBiasVolt[entry.hv()]!=fVecBiasVolt[entry.hv()+416]);
3903 }
3904
3905 fBiasCamV->SetData(dat);
3906 }
3907
3908 fBiasCamV->updateCamera();
3909 }
3910
3911 // ------------------------------------------------------
3912
3913 void on_fPixelEnable_stateChanged(int b)
3914 {
3915 if (fInHandler)
3916 return;
3917
3918 const PixelMapEntry &entry = fPixelMap.index(fPixelIdx->value());
3919
3920 Dim::SendCommand(b==Qt::Unchecked ?
3921 "FTM_CONTROL/DISABLE_PIXEL" : "FTM_CONTROL/ENABLE_PIXEL",
3922 uint16_t(entry.hw()));
3923 }
3924
3925 void on_fPixelDisableOthers_clicked()
3926 {
3927 const PixelMapEntry &entry = fPixelMap.index(fPixelIdx->value());
3928 Dim::SendCommand("FTM_CONTROL/DISABLE_ALL_PIXELS_EXCEPT", uint16_t(entry.hw()));
3929 }
3930
3931 void on_fThresholdDisableOthers_clicked()
3932 {
3933 const int16_t isw = fThresholdIdx->value();
3934 const int16_t ihw = isw<0 ? -1 : fPatchMapHW[isw];
3935 if (ihw<0)
3936 return;
3937
3938 Dim::SendCommand("FTM_CONTROL/DISABLE_ALL_PATCHES_EXCEPT", ihw);
3939 }
3940
3941 void on_fThresholdEnablePatch_clicked()
3942 {
3943 const int16_t isw = fThresholdIdx->value();
3944 const int16_t ihw = isw<0 ? -1 : fPatchMapHW[isw];
3945 if (ihw<0)
3946 return;
3947
3948 Dim::SendCommand("FTM_CONTROL/ENABLE_PATCH", ihw);
3949 }
3950
3951 void on_fThresholdDisablePatch_clicked()
3952 {
3953 const int16_t isw = fThresholdIdx->value();
3954 const int16_t ihw = isw<0 ? -1 : fPatchMapHW[isw];
3955 if (ihw<0)
3956 return;
3957
3958 Dim::SendCommand("FTM_CONTROL/DISABLE_PATCH", ihw);
3959 }
3960
3961 void on_fThresholdVal_valueChanged(int v)
3962 {
3963 fThresholdVolt->setValue(2500./4095*v);
3964
3965 const int32_t isw = fThresholdIdx->value();
3966 const int32_t ihw = isw<0 ? -1 : fPatchMapHW[isw];
3967
3968 const int32_t d[2] = { ihw, v };
3969
3970 if (!fInHandler)
3971 Dim::SendCommand("FTM_CONTROL/SET_THRESHOLD", d);
3972 }
3973
3974 TGraph fGraphFtmTemp[4];
3975 TGraph fGraphFtmRate;
3976 TGraph fGraphPatchRate[160];
3977 TGraph fGraphBoardRate[40];
3978
3979#ifdef HAVE_ROOT
3980 TH1 *DrawTimeFrame(const char *ytitle)
3981 {
3982 const double tm = Time().RootTime();
3983
3984 TH1F *h=new TH1F("TimeFrame", "", 1, tm, tm+60);//Time().RootTime()-1./24/60/60, Time().RootTime());
3985 h->SetDirectory(0);
3986 h->SetBit(kCanDelete);
3987 h->SetStats(kFALSE);
3988// h.SetMinimum(0);
3989// h.SetMaximum(1);
3990 h->SetXTitle("Time");
3991 h->SetYTitle(ytitle);
3992 h->GetXaxis()->CenterTitle();
3993 h->GetYaxis()->CenterTitle();
3994 h->GetXaxis()->SetTimeDisplay(true);
3995 h->GetXaxis()->SetTimeFormat("%Mh%S'");
3996 h->GetXaxis()->SetLabelSize(0.025);
3997 h->GetYaxis()->SetLabelSize(0.025);
3998 h->GetYaxis()->SetTitleOffset(1.2);
3999 // h.GetYaxis()->SetTitleSize(1.2);
4000 h->Draw();
4001
4002 return h;
4003 }
4004#endif
4005
4006 pair<string,string> Split(const string &str) const
4007 {
4008 const size_t p = str.find_first_of('|');
4009 if (p==string::npos)
4010 return make_pair(str, "");
4011
4012 return make_pair(str.substr(0, p), str.substr(p+1));
4013 }
4014
4015public:
4016 FactGui(Configuration &conf) :
4017 fFtuStatus(40),
4018 /*fPixelMapHW(1440),*/ fPatchMapHW(160),
4019 fInChoosePatchTH(false),
4020 fInChooseBiasHv(false), fInChooseBiasCam(false),
4021 fDimDNS("DIS_DNS/VERSION_NUMBER", 1, int(0), this),
4022 //-
4023 fDimLoggerStats ("DATA_LOGGER/STATS", (void*)NULL, 0, this),
4024 fDimLoggerFilenameNight("DATA_LOGGER/FILENAME_NIGHTLY", (void*)NULL, 0, this),
4025 fDimLoggerFilenameRun ("DATA_LOGGER/FILENAME_RUN", (void*)NULL, 0, this),
4026 fDimLoggerNumSubs ("DATA_LOGGER/NUM_SUBS", (void*)NULL, 0, this),
4027 //-
4028 fDimFtmPassport ("FTM_CONTROL/PASSPORT", (void*)NULL, 0, this),
4029 fDimFtmTriggerRates ("FTM_CONTROL/TRIGGER_RATES", (void*)NULL, 0, this),
4030 fDimFtmError ("FTM_CONTROL/ERROR", (void*)NULL, 0, this),
4031 fDimFtmFtuList ("FTM_CONTROL/FTU_LIST", (void*)NULL, 0, this),
4032 fDimFtmStaticData ("FTM_CONTROL/STATIC_DATA", (void*)NULL, 0, this),
4033 fDimFtmDynamicData ("FTM_CONTROL/DYNAMIC_DATA", (void*)NULL, 0, this),
4034 fDimFtmCounter ("FTM_CONTROL/COUNTER", (void*)NULL, 0, this),
4035 //-
4036 fDimFadWriteStats ("FAD_CONTROL/STATS", (void*)NULL, 0, this),
4037 fDimFadStartRun ("FAD_CONTROL/START_RUN", (void*)NULL, 0, this),
4038 fDimFadRuns ("FAD_CONTROL/RUNS", (void*)NULL, 0, this),
4039 fDimFadEvents ("FAD_CONTROL/EVENTS", (void*)NULL, 0, this),
4040 fDimFadRawData ("FAD_CONTROL/RAW_DATA", (void*)NULL, 0, this),
4041 fDimFadEventData ("FAD_CONTROL/EVENT_DATA", (void*)NULL, 0, this),
4042 fDimFadConnections ("FAD_CONTROL/CONNECTIONS", (void*)NULL, 0, this),
4043 fDimFadFwVersion ("FAD_CONTROL/FIRMWARE_VERSION", (void*)NULL, 0, this),
4044 fDimFadRunNumber ("FAD_CONTROL/RUN_NUMBER", (void*)NULL, 0, this),
4045 fDimFadDNA ("FAD_CONTROL/DNA", (void*)NULL, 0, this),
4046 fDimFadTemperature ("FAD_CONTROL/TEMPERATURE", (void*)NULL, 0, this),
4047 fDimFadPrescaler ("FAD_CONTROL/PRESCALER", (void*)NULL, 0, this),
4048 fDimFadRefClock ("FAD_CONTROL/REFERENCE_CLOCK", (void*)NULL, 0, this),
4049 fDimFadRoi ("FAD_CONTROL/REGION_OF_INTEREST", (void*)NULL, 0, this),
4050 fDimFadDac ("FAD_CONTROL/DAC", (void*)NULL, 0, this),
4051 fDimFadDrsCalibration ("FAD_CONTROL/DRS_CALIBRATION", (void*)NULL, 0, this),
4052 fDimFadStatus ("FAD_CONTROL/STATUS", (void*)NULL, 0, this),
4053 fDimFadStatistics1 ("FAD_CONTROL/STATISTICS1", (void*)NULL, 0, this),
4054 fDimFadStatistics2 ("FAD_CONTROL/STATISTICS2", (void*)NULL, 0, this),
4055 fDimFadFileFormat ("FAD_CONTROL/FILE_FORMAT", (void*)NULL, 0, this),
4056 //-
4057 fDimFscTemp ("FSC_CONTROL/TEMPERATURE", (void*)NULL, 0, this),
4058 fDimFscVolt ("FSC_CONTROL/VOLTAGE", (void*)NULL, 0, this),
4059 fDimFscCurrent ("FSC_CONTROL/CURRENT", (void*)NULL, 0, this),
4060 fDimFscHumidity ("FSC_CONTROL/HUMIDITY", (void*)NULL, 0, this),
4061 //-
4062 fDimFeedbackDeviation ("FEEDBACK/DEVIATION", (void*)NULL, 0, this),
4063 fDimFeedbackReference ("FEEDBACK/REFERENCE", (void*)NULL, 0, this),
4064 fDimFeedbackCalibration("FEEDBACK/CALIBRATION", (void*)NULL, 0, this),
4065 //-
4066 fDimBiasVolt ("BIAS_CONTROL/VOLTAGE", (void*)NULL, 0, this),
4067 fDimBiasCurrent ("BIAS_CONTROL/CURRENT", (void*)NULL, 0, this),
4068 //-
4069 fDimRateScan ("RATE_SCAN/DATA", (void*)NULL, 0, this),
4070 //-
4071 fDimMagicWeather ("MAGIC_WEATHER/DATA", (void*)NULL, 0, this),
4072 //-
4073 fDimVersion(0),
4074 fFreeSpaceLogger(UINT64_MAX), fFreeSpaceData(UINT64_MAX),
4075 fEventData(0),
4076 fDrsCalibration(1440*1024*6+160*1024*2),
4077 fTimeStamp0(0)
4078 {
4079 fClockCondFreq->addItem("--- Hz", QVariant(-1));
4080 fClockCondFreq->addItem("800 MHz", QVariant(800));
4081 fClockCondFreq->addItem("1 GHz", QVariant(1000));
4082 fClockCondFreq->addItem("2 GHz", QVariant(2000));
4083 fClockCondFreq->addItem("3 GHz", QVariant(3000));
4084 fClockCondFreq->addItem("4 GHz", QVariant(4000));
4085 fClockCondFreq->addItem("5 GHz", QVariant(5000));
4086
4087 cout << "-- run counter ---" << endl;
4088 fMcpNumEvents->addItem("unlimited", QVariant(0));
4089 const vector<uint32_t> runcount = conf.Vec<uint32_t>("run-count");
4090 for (vector<uint32_t>::const_iterator it=runcount.begin(); it!=runcount.end(); it++)
4091 {
4092 cout << *it << endl;
4093 ostringstream str;
4094 str << *it;
4095 fMcpNumEvents->addItem(str.str().c_str(), QVariant(*it));
4096 }
4097
4098 cout << "-- run times ---" << endl;
4099 fMcpTime->addItem("unlimited", QVariant(0));
4100 const vector<string> runtime = conf.Vec<string>("run-time");
4101 for (vector<string>::const_iterator it=runtime.begin(); it!=runtime.end(); it++)
4102 {
4103 const pair<string,string> p = Split(*it);
4104 cout << *it << "|" << p.second << "|" << p.first << "|" << endl;
4105 fMcpTime->addItem(p.second.c_str(), QVariant(stoi(p.first)));
4106 }
4107
4108 cout << "-- run types ---" << endl;
4109 const vector<string> runtype = conf.Vec<string>("run-type");
4110 for (vector<string>::const_iterator it=runtype.begin(); it!=runtype.end(); it++)
4111 {
4112 const pair<string,string> p = Split(*it);
4113 cout << *it << "|" << p.second << "|" << p.first << "|" << endl;
4114 fMcpRunType->addItem(p.second.c_str(), QVariant(p.first.c_str()));
4115 }
4116
4117 fTriggerWidget->setEnabled(false);
4118 fFtuWidget->setEnabled(false);
4119 fFtuGroupEnable->setEnabled(false);
4120 fRatesControls->setEnabled(false);
4121 fFadWidget->setEnabled(false);
4122 fGroupEthernet->setEnabled(false);
4123 fGroupOutput->setEnabled(false);
4124 fLoggerWidget->setEnabled(false);
4125 fBiasWidget->setEnabled(false);
4126 fAuxWidget->setEnabled(false);
4127
4128 fChatSend->setEnabled(false);
4129 fChatMessage->setEnabled(false);
4130
4131 DimClient::sendCommand("CHAT/MSG", "GUI online.");
4132 // + MessageDimRX
4133
4134 // --------------------------------------------------------------------------
4135
4136 if (!fPixelMap.Read(conf.Get<string>("pixel-map-file")))
4137 {
4138 cerr << "ERROR - Problems reading " << conf.Get<string>("pixel-map-file") << endl;
4139 exit(-1);
4140 }
4141
4142 // --------------------------------------------------------------------------
4143
4144 /*
4145 ifstream fin1("Trigger-Patches.txt");
4146
4147 string buf;
4148
4149 int l = 0;
4150 while (getline(fin1, buf, '\n'))
4151 {
4152 buf = Tools::Trim(buf);
4153 if (buf[0]=='#')
4154 continue;
4155
4156 stringstream str(buf);
4157 for (int i=0; i<9; i++)
4158 {
4159 unsigned int n;
4160 str >> n;
4161
4162 if (n>=fPatchHW.size())
4163 continue;
4164
4165 fPatchHW[n] = l;
4166 }
4167 l++;
4168 }
4169
4170 if (l!=160)
4171 cerr << "WARNING - Problems reading Trigger-Patches.txt" << endl;
4172 */
4173 // --------------------------------------------------------------------------
4174
4175 /*
4176 ifstream fin2("MasterList-v3.txt");
4177
4178 l = 0;
4179
4180 while (getline(fin2, buf, '\n'))
4181 {
4182 buf = Tools::Trim(buf);
4183 if (buf[0]=='#')
4184 continue;
4185
4186 unsigned int softid, hardid, dummy;
4187
4188 stringstream str(buf);
4189
4190 str >> softid;
4191 str >> dummy;
4192 str >> hardid;
4193
4194 if (softid>=fPixelMapHW.size())
4195 continue;
4196
4197 fPixelMapHW[softid] = hardid;
4198
4199 l++;
4200 }
4201
4202 if (l!=1440)
4203 cerr << "WARNING - Problems reading MasterList-v3.txt" << endl;
4204 */
4205 // --------------------------------------------------------------------------
4206
4207 ifstream fin3("PatchList.txt");
4208
4209 string buf;
4210
4211 int l = 0;
4212 while (getline(fin3, buf, '\n'))
4213 {
4214 buf = Tools::Trim(buf);
4215 if (buf[0]=='#')
4216 continue;
4217
4218 unsigned int softid, hardid;
4219
4220 stringstream str(buf);
4221
4222 str >> softid;
4223 str >> hardid;
4224
4225 if (softid>=fPatchMapHW.size())
4226 continue;
4227
4228 fPatchMapHW[softid] = hardid-1;
4229
4230 l++;
4231 }
4232
4233 if (l!=160)
4234 cerr << "WARNING - Problems reading PatchList.txt" << endl;
4235
4236 // --------------------------------------------------------------------------
4237
4238 fCommentsWidget->setEnabled(false);
4239
4240 static const boost::regex expr("(([[:word:].-]+)(:(.+))?@)?([[:word:].-]+)(:([[:digit:]]+))?(/([[:word:].-]+))");
4241
4242 const string database = conf.Get<string>("CommentDB");
4243
4244 if (!database.empty())
4245 {
4246 boost::smatch what;
4247 if (!boost::regex_match(database, what, expr, boost::match_extra))
4248 throw runtime_error("Couldn't parse '"+database+"'.");
4249
4250 if (what.size()!=10)
4251 throw runtime_error("Error parsing '"+database+"'.");
4252
4253 const string user = what[2];
4254 const string passwd = what[4];
4255 const string server = what[5];
4256 const string db = what[9];
4257 const int port = atoi(string(what[7]).c_str());
4258
4259 QSqlDatabase qdb = QSqlDatabase::addDatabase("QMYSQL");
4260 qdb.setHostName(server.c_str());
4261 qdb.setDatabaseName(db.c_str());
4262 qdb.setUserName(user.c_str());
4263 qdb.setPassword(passwd.c_str());
4264 qdb.setPort(port);
4265 qdb.setConnectOptions("CLIENT_SSL=1;MYSQL_OPT_RECONNECT=1");
4266 if (qdb.open())
4267 {
4268 QSqlTableModel *model = new QSqlTableModel(fTableComments, qdb);
4269 model->setTable("runcomments");
4270 model->setEditStrategy(QSqlTableModel::OnManualSubmit);
4271
4272 const bool ok2 = model->select();
4273
4274 if (ok2)
4275 {
4276 fTableComments->setModel(model);
4277 fTableComments->resizeColumnsToContents();
4278 fTableComments->resizeRowsToContents();
4279
4280 connect(fCommentSubmit, SIGNAL(clicked()), model, SLOT(submitAll()));
4281 connect(fCommentRevert, SIGNAL(clicked()), model, SLOT(revertAll()));
4282 connect(fCommentUpdateLayout, SIGNAL(clicked()), fTableComments, SLOT(resizeColumnsToContents()));
4283 connect(fCommentUpdateLayout, SIGNAL(clicked()), fTableComments, SLOT(resizeRowsToContents()));
4284
4285 fCommentsWidget->setEnabled(true);
4286 }
4287 else
4288 cout << "\n==> ERROR: Select on table failed.\n" << endl;
4289 }
4290 else
4291 cout << "\n==> ERROR: Connection to database failed:\n "
4292 << qdb.lastError().text().toStdString() << endl << endl;
4293 }
4294
4295 // --------------------------------------------------------------------------
4296#ifdef HAVE_ROOT
4297
4298 fGraphFeedbackDev.SetLineColor(kBlue);
4299 fGraphFeedbackDev.SetMarkerColor(kBlue);
4300 fGraphFeedbackDev.SetMarkerStyle(kFullDotMedium);
4301
4302 fGraphFeedbackCmd.SetLineColor(kBlue);
4303 fGraphFeedbackCmd.SetMarkerColor(kBlue);
4304 fGraphFeedbackCmd.SetMarkerStyle(kFullDotMedium);
4305
4306 // Evolution of control deviation
4307 // Evolution of command values (bias voltage change)
4308 fGraphFeedbackDev.SetName("ControlDev");
4309 fGraphFeedbackCmd.SetName("CommandVal");
4310
4311 TCanvas *c = fFeedbackDev->GetCanvas();
4312 c->SetBorderMode(0);
4313 c->SetFrameBorderMode(0);
4314 c->SetFillColor(kWhite);
4315 c->SetRightMargin(0.03);
4316 c->SetTopMargin(0.03);
4317 c->SetGrid();
4318 c->cd();
4319
4320 TH1 *hf = DrawTimeFrame("Control deviation [mV] ");
4321 hf->GetXaxis()->SetLabelSize(0.07);
4322 hf->GetYaxis()->SetLabelSize(0.07);
4323 hf->GetYaxis()->SetTitleSize(0.08);
4324 hf->GetYaxis()->SetTitleOffset(0.55);
4325 hf->GetXaxis()->SetTitle("");
4326 hf->GetYaxis()->SetRangeUser(-99, 99);
4327
4328 fGraphFeedbackDev.Draw("LP");
4329
4330 c = fFeedbackCmd->GetCanvas();
4331 c->SetBorderMode(0);
4332 c->SetFrameBorderMode(0);
4333 c->SetFillColor(kWhite);
4334 c->SetRightMargin(0.03);
4335 c->SetTopMargin(0.03);
4336 c->SetGrid();
4337 c->cd();
4338
4339 hf = DrawTimeFrame("Command delta value [mV] ");
4340 hf->GetXaxis()->SetLabelSize(0.07);
4341 hf->GetYaxis()->SetLabelSize(0.07);
4342 hf->GetYaxis()->SetTitleSize(0.08);
4343 hf->GetYaxis()->SetTitleOffset(0.55);
4344 hf->GetXaxis()->SetTitle("");
4345 hf->GetYaxis()->SetRangeUser(-99*10, 99*10);
4346
4347 fGraphFeedbackCmd.Draw("LP");
4348
4349 // --------------------------------------------------------------------------
4350
4351 c = fRateScanCanv->GetCanvas();
4352 //c->SetBit(TCanvas::kNoContextMenu);
4353 c->SetBorderMode(0);
4354 c->SetFrameBorderMode(0);
4355 c->SetFillColor(kWhite);
4356 c->SetRightMargin(0.03);
4357 c->SetTopMargin(0.03);
4358 c->SetGrid();
4359 c->cd();
4360
4361 TH1F *h=new TH1F("Frame", "", 1, 0, 1);
4362 h->SetDirectory(0);
4363 h->SetBit(kCanDelete);
4364 h->SetStats(kFALSE);
4365 h->SetXTitle("Threshold [DAC]");
4366 h->SetYTitle("Rate [Hz]");
4367 h->GetXaxis()->CenterTitle();
4368 h->GetYaxis()->CenterTitle();
4369 h->GetXaxis()->SetLabelSize(0.025);
4370 h->GetYaxis()->SetLabelSize(0.025);
4371 h->GetYaxis()->SetTitleOffset(1.2);
4372 h->Draw();
4373
4374 fGraphRateScan[0].SetName("CameraRate");
4375 for (int i=0; i<40; i++)
4376 {
4377 fGraphRateScan[i+1].SetName("BoardRate");
4378 fGraphRateScan[i+1].SetMarkerStyle(kFullDotMedium);
4379 }
4380 for (int i=0; i<160; i++)
4381 {
4382 fGraphRateScan[i+41].SetName("PatchRate");
4383 fGraphRateScan[i+41].SetMarkerStyle(kFullDotMedium);
4384 }
4385
4386 fGraphRateScan[0].SetLineColor(kBlue);
4387 fGraphRateScan[0].SetMarkerColor(kBlue);
4388 fGraphRateScan[0].SetMarkerStyle(kFullDotSmall);
4389 fGraphRateScan[0].Draw("LP");
4390
4391 // --------------------------------------------------------------------------
4392
4393 c = fFtmRateCanv->GetCanvas();
4394 //c->SetBit(TCanvas::kNoContextMenu);
4395 c->SetBorderMode(0);
4396 c->SetFrameBorderMode(0);
4397 c->SetFillColor(kWhite);
4398 c->SetRightMargin(0.03);
4399 c->SetTopMargin(0.03);
4400 c->SetGrid();
4401 c->cd();
4402
4403 hf = DrawTimeFrame("Trigger rate [Hz]");
4404 hf->GetYaxis()->SetRangeUser(0, 1010);
4405
4406 for (int i=0; i<160; i++)
4407 {
4408 fGraphPatchRate[i].SetName("PatchRate");
4409 //fGraphPatchRate[i].SetLineColor(kBlue);
4410 //fGraphPatchRate[i].SetMarkerColor(kBlue);
4411 fGraphPatchRate[i].SetMarkerStyle(kFullDotMedium);
4412 }
4413 for (int i=0; i<40; i++)
4414 {
4415 fGraphBoardRate[i].SetName("BoardRate");
4416 //fGraphBoardRate[i].SetLineColor(kBlue);
4417 //fGraphBoardRate[i].SetMarkerColor(kBlue);
4418 fGraphBoardRate[i].SetMarkerStyle(kFullDotMedium);
4419 }
4420
4421 fGraphFtmRate.SetLineColor(kBlue);
4422 fGraphFtmRate.SetMarkerColor(kBlue);
4423 fGraphFtmRate.SetMarkerStyle(kFullDotSmall);
4424 fGraphFtmRate.Draw("LP");
4425
4426 /*
4427 TCanvas *c = fFtmTempCanv->GetCanvas();
4428 c->SetBit(TCanvas::kNoContextMenu);
4429 c->SetBorderMode(0);
4430 c->SetFrameBorderMode(0);
4431 c->SetFillColor(kWhite);
4432 c->SetRightMargin(0.03);
4433 c->SetTopMargin(0.03);
4434 c->cd();
4435 */
4436 //CreateTimeFrame("Temperature / �C");
4437
4438 fGraphFtmTemp[0].SetMarkerStyle(kFullDotSmall);
4439 fGraphFtmTemp[1].SetMarkerStyle(kFullDotSmall);
4440 fGraphFtmTemp[2].SetMarkerStyle(kFullDotSmall);
4441 fGraphFtmTemp[3].SetMarkerStyle(kFullDotSmall);
4442
4443 fGraphFtmTemp[1].SetLineColor(kBlue);
4444 fGraphFtmTemp[2].SetLineColor(kRed);
4445 fGraphFtmTemp[3].SetLineColor(kGreen);
4446
4447 fGraphFtmTemp[1].SetMarkerColor(kBlue);
4448 fGraphFtmTemp[2].SetMarkerColor(kRed);
4449 fGraphFtmTemp[3].SetMarkerColor(kGreen);
4450
4451 //fGraphFtmTemp[0].Draw("LP");
4452 //fGraphFtmTemp[1].Draw("LP");
4453 //fGraphFtmTemp[2].Draw("LP");
4454 //fGraphFtmTemp[3].Draw("LP");
4455
4456 // --------------------------------------------------------------------------
4457
4458 c = fAdcDataCanv->GetCanvas();
4459 //c->SetBit(TCanvas::kNoContextMenu);
4460 c->SetBorderMode(0);
4461 c->SetFrameBorderMode(0);
4462 c->SetFillColor(kWhite);
4463 c->SetRightMargin(0.10);
4464 c->SetGrid();
4465 //c->cd();
4466#endif
4467
4468 // --------------------------------------------------------------------------
4469 fFeedbackDevCam->assignPixelMap(fPixelMap);
4470 fFeedbackDevCam->setAutoscaleLowerLimit((fFeedbackDevMin->minimum()+0.5*fFeedbackDevMin->singleStep()));
4471 fFeedbackDevCam->SetMin(fFeedbackDevMin->value());
4472 fFeedbackDevCam->SetMax(fFeedbackDevMax->value());
4473 fFeedbackDevCam->updateCamera();
4474
4475 fFeedbackCmdCam->assignPixelMap(fPixelMap);
4476 fFeedbackCmdCam->setAutoscaleLowerLimit((fFeedbackCmdMin->minimum()+0.5*fFeedbackCmdMin->singleStep()));
4477 fFeedbackCmdCam->SetMin(fFeedbackCmdMin->value());
4478 fFeedbackCmdCam->SetMax(fFeedbackCmdMax->value());
4479 fFeedbackCmdCam->updateCamera();
4480
4481 // --------------------------------------------------------------------------
4482
4483 fBiasCamV->assignPixelMap(fPixelMap);
4484 fBiasCamV->setAutoscaleLowerLimit((fBiasVoltMin->minimum()+0.5*fBiasVoltMin->singleStep()));
4485 fBiasCamV->SetMin(fBiasVoltMin->value());
4486 fBiasCamV->SetMax(fBiasVoltMax->value());
4487 fBiasCamV->updateCamera();
4488
4489 fBiasCamA->assignPixelMap(fPixelMap);
4490 fBiasCamA->setAutoscaleLowerLimit((fBiasCurrentMin->minimum()+0.5*fBiasCurrentMin->singleStep()));
4491 fBiasCamA->SetMin(fBiasCurrentMin->value());
4492 fBiasCamA->SetMax(fBiasCurrentMax->value());
4493 fBiasCamA->updateCamera();
4494
4495 // --------------------------------------------------------------------------
4496
4497 fRatesCanv->assignPixelMap(fPixelMap);
4498 fRatesCanv->setAutoscaleLowerLimit((fRatesMin->minimum()+0.5*fRatesMin->singleStep())*0.001);
4499 fRatesCanv->SetMin(fRatesMin->value());
4500 fRatesCanv->SetMax(fRatesMax->value());
4501 fRatesCanv->updateCamera();
4502 on_fPixelIdx_valueChanged(0);
4503
4504 // --------------------------------------------------------------------------
4505
4506 fRatesCanv->setTitle("Patch rates");
4507 fRatesCanv->setUnits("Hz");
4508
4509 fBiasCamA->setTitle("BIAS current");
4510 fBiasCamA->setUnits("uA");
4511
4512 fBiasCamV->setTitle("Applied BIAS voltage");
4513 fBiasCamV->setUnits("V");
4514
4515 fEventCanv1->setTitle("Average (all slices)");
4516 fEventCanv2->setTitle("RMS (all slices)");
4517 fEventCanv3->setTitle("Maximum (all slices)");
4518 fEventCanv4->setTitle("Position of maximum (all slices)");
4519
4520 fEventCanv1->setUnits("mV");
4521 fEventCanv2->setUnits("mV");
4522 fEventCanv3->setUnits("mV");
4523 fEventCanv4->setUnits("slice");
4524
4525 // --------------------------------------------------------------------------
4526
4527 fFeedbackDevCam->setTitle("Control deviation (Pulser amplitude voltage)");
4528 fFeedbackCmdCam->setTitle("Applied voltage change (BIAS voltage)");
4529
4530 fFeedbackDevCam->setUnits("mV");
4531 fFeedbackCmdCam->setUnits("mV");
4532
4533 // --------------------------------------------------------------------------
4534
4535 QTimer::singleShot(1000, this, SLOT(slot_RootUpdate()));
4536
4537 //widget->setMouseTracking(true);
4538 //widget->EnableSignalEvents(kMouseMoveEvent);
4539
4540 fFtmRateCanv->setMouseTracking(true);
4541 fFtmRateCanv->EnableSignalEvents(kMouseMoveEvent);
4542
4543 fAdcDataCanv->setMouseTracking(true);
4544 fAdcDataCanv->EnableSignalEvents(kMouseMoveEvent);
4545
4546 fRatesCanv->setMouseTracking(true);
4547 fEventCanv1->setMouseTracking(true);
4548 fEventCanv2->setMouseTracking(true);
4549 fEventCanv3->setMouseTracking(true);
4550 fEventCanv4->setMouseTracking(true);
4551
4552 fBiasCamV->setMouseTracking(true);
4553 fBiasCamA->setMouseTracking(true);
4554
4555 fFeedbackDevCam->setMouseTracking(true);
4556 fFeedbackCmdCam->setMouseTracking(true);
4557
4558 fEventCanv1->ShowPixelCursor(true);
4559 fEventCanv2->ShowPixelCursor(true);
4560 fEventCanv3->ShowPixelCursor(true);
4561 fEventCanv4->ShowPixelCursor(true);
4562
4563 fEventCanv1->ShowPatchCursor(true);
4564 fEventCanv2->ShowPatchCursor(true);
4565 fEventCanv3->ShowPatchCursor(true);
4566 fEventCanv4->ShowPatchCursor(true);
4567
4568 fFeedbackDevCam->ShowPixelCursor(true);
4569 fFeedbackCmdCam->ShowPixelCursor(true);
4570
4571 fFeedbackDevCam->ShowPatchCursor(true);
4572 fFeedbackCmdCam->ShowPatchCursor(true);
4573
4574 connect(fRatesCanv, SIGNAL(signalPixelMoveOver(int)),
4575 this, SLOT(slot_CameraMouseMove(int)));
4576 connect(fEventCanv1, SIGNAL(signalPixelMoveOver(int)),
4577 this, SLOT(slot_CameraMouseMove(int)));
4578 connect(fEventCanv2, SIGNAL(signalPixelMoveOver(int)),
4579 this, SLOT(slot_CameraMouseMove(int)));
4580 connect(fEventCanv3, SIGNAL(signalPixelMoveOver(int)),
4581 this, SLOT(slot_CameraMouseMove(int)));
4582 connect(fEventCanv4, SIGNAL(signalPixelMoveOver(int)),
4583 this, SLOT(slot_CameraMouseMove(int)));
4584
4585 connect(fBiasCamV, SIGNAL(signalPixelMoveOver(int)),
4586 this, SLOT(slot_CameraMouseMove(int)));
4587 connect(fBiasCamA, SIGNAL(signalPixelMoveOver(int)),
4588 this, SLOT(slot_CameraMouseMove(int)));
4589
4590 connect(fFeedbackDevCam, SIGNAL(signalPixelMoveOver(int)),
4591 this, SLOT(slot_CameraMouseMove(int)));
4592 connect(fFeedbackCmdCam, SIGNAL(signalPixelMoveOver(int)),
4593 this, SLOT(slot_CameraMouseMove(int)));
4594
4595 connect(fRatesCanv, SIGNAL(signalPixelDoubleClick(int)),
4596 this, SLOT(slot_CameraDoubleClick(int)));
4597 connect(fRatesCanv, SIGNAL(signalCurrentPixel(int)),
4598 this, SLOT(slot_ChoosePixelThreshold(int)));
4599 connect(fBiasCamV, SIGNAL(signalCurrentPixel(int)),
4600 this, SLOT(slot_ChooseBiasChannel(int)));
4601 connect(fBiasCamA, SIGNAL(signalCurrentPixel(int)),
4602 this, SLOT(slot_ChooseBiasChannel(int)));
4603
4604 connect(fFtmRateCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)),
4605 this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*)));
4606 connect(fAdcDataCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)),
4607 this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*)));
4608 }
4609
4610 ~FactGui()
4611 {
4612 // Unsubscribe all services
4613 for (map<string,DimInfo*>::iterator i=fServices.begin();
4614 i!=fServices.end(); i++)
4615 delete i->second;
4616
4617 delete fEventData;
4618 }
4619};
4620
4621#endif
Note: See TracBrowser for help on using the repository browser.