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

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