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

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