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

Last change on this file since 11854 was 11854, checked in by tbretz, 14 years ago
Added the Bias control to the GUI; consequently, updated the rate display functions -- to be unified.
File size: 113.2 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
11#include <QTimer>
12#include <QStandardItemModel>
13
14#include "CheckBoxDelegate.h"
15
16#include "src/Dim.h"
17#include "src/Converter.h"
18#include "src/Configuration.h"
19#include "src/HeadersFTM.h"
20#include "src/HeadersFAD.h"
21#include "src/DimNetwork.h"
22#include "src/tools.h"
23#include "src/FAD.h"
24
25
26#include "TROOT.h"
27#include "TSystem.h"
28#include "TGraph.h"
29#include "TH2.h"
30#include "TBox.h"
31#include "TStyle.h"
32#include "TMarker.h"
33#include "TColor.h"
34
35#include "QCameraWidget.h"
36
37using namespace std;
38
39// #########################################################################
40
41/*
42class Camera : public TObject
43{
44 typedef pair<double,double> Position;
45 typedef vector<Position> Positions;
46
47 Positions fGeom;
48
49 void CreatePalette()
50 {
51
52 double ss[5] = {0.00, 0.25, 0.50, 0.75, 1.00};
53 double rr[5] = {0.15, 0.00, 0.00, 1.00, 0.85};
54 double gg[5] = {0.15, 0.00, 1.00, 0.00, 0.85};
55 double bb[5] = {0.15, 1.00, 0.00, 0.00, 0.85};
56
57 const Int_t nn = 1440;
58
59 Int_t idx = TColor::CreateGradientColorTable(5, ss, rr, gg, bb, nn);
60 for (int i=0; i<nn; i++)
61 fPalette.push_back(idx++);
62 }
63
64 void CreateGeometry()
65 {
66 const double gsSin60 = sqrt(3.)/2;
67
68 const int rings = 23;
69
70 // add the first pixel to the list
71
72 fGeom.push_back(make_pair(0, -0.5));
73
74 for (int ring=1; ring<=rings; ring++)
75 {
76 for (int s=0; s<6; s++)
77 {
78 for (int i=1; i<=ring; i++)
79 {
80 double xx, yy;
81 switch (s)
82 {
83 case 0: // Direction South East
84 xx = (ring+i)*0.5;
85 yy = (-ring+i)*gsSin60;
86 break;
87
88 case 1: // Direction North East
89 xx = ring-i*0.5;
90 yy = i*gsSin60;
91 break;
92
93 case 2: // Direction North
94 xx = ring*0.5-i;
95 yy = ring*gsSin60;
96 break;
97
98 case 3: // Direction North West
99 xx = -(ring+i)*0.5;
100 yy = (ring-i)*gsSin60;
101 break;
102
103 case 4: // Direction South West
104 xx = 0.5*i-ring;
105 yy = -i*gsSin60;
106 break;
107
108 case 5: // Direction South
109 xx = i-ring*0.5;
110 yy = -ring*gsSin60;
111 break;
112 }
113
114 if (xx*xx + yy*yy - xx > 395.75)
115 continue;
116
117 fGeom.push_back(make_pair(yy, xx-0.5));
118 }
119 }
120 }
121 }
122
123 valarray<double> fData;
124 vector<bool> fBold;
125 vector<bool> fEnable;
126
127 int fWhite;
128
129 int64_t fMin;
130 int64_t fMax;
131
132public:
133 Camera() : fData(1440), fBold(1440), fEnable(1440), fWhite(-1), fMin(-1), fMax(-1)
134 {
135 CreatePalette();
136 CreateGeometry();
137
138 for (int i=0; i<1440; i++)
139 {
140 fData[i] = i;
141 fBold[i]=false;
142 fEnable[i]=true;
143 }
144 }
145
146 void Reset() { fBold.assign(1440, false); }
147
148 void SetBold(int idx) { fBold[idx]=true; }
149 void SetWhite(int idx) { fWhite=idx; }
150 void SetEnable(int idx, bool b) { fEnable[idx]=b; }
151 void Toggle(int idx) { fEnable[idx]=!fEnable[idx]; }
152 double GetData(int idx) const { return fData[idx]; }
153 void SetMin(int64_t min) { fMin=min; }
154 void SetMax(int64_t max) { fMax=max; }
155
156 const char *GetName() const { return "Camera"; }
157
158 vector<Int_t> fPalette;
159
160 void Paint(const Position &p)
161 {
162 static const Double_t fgCos60 = 0.5; // TMath::Cos(60/TMath::RadToDeg());
163 static const Double_t fgSin60 = sqrt(3.)/2; // TMath::Sin(60/TMath::RadToDeg());
164
165 static const Double_t fgDy[6] = { fgCos60, 0., -fgCos60, -fgCos60, 0., fgCos60 };
166 static const Double_t fgDx[6] = { fgSin60/3, fgSin60*2/3, fgSin60/3, -fgSin60/3, -fgSin60*2/3, -fgSin60/3 };
167
168 //
169 // calculate the positions of the pixel corners
170 //
171 static Double_t x[7], y[7];
172 for (Int_t i=0; i<7; i++)
173 {
174 x[i] = p.first + fgDx[i%6];
175 y[i] = p.second + fgDy[i%6];
176 }
177
178 gPad->PaintFillArea(6, x, y);
179 gPad->PaintPolyLine(7, x, y);
180 }
181
182 int GetCol(double dmin, double val, double dmax, bool enable)
183 {
184 if (!enable)
185 return kWhite;
186
187 if (val<dmin)
188 return kBlue+4;//kBlack;
189
190 if (val>dmax)
191 return kRed+4;//kWhite;
192
193 const double min = dmin;
194 const double scale = dmax==dmin ? 1 : dmax-dmin;
195
196 const int col = (val-min)/scale*(fPalette.size()-1);
197
198 return gStyle->GetColorPalette(col);
199 }
200
201 void Paint(Option_t *)
202 {
203 gStyle->SetPalette(fPalette.size(), fPalette.data());
204
205 const double r = double(gPad->GetWw())/gPad->GetWh();
206 const double max = 20.5; // 20.5 rings in x and y
207
208 if (r>1)
209 gPad->Range(-r*max, -max, r*max, max);
210 else
211 gPad->Range(-max, -max/r, max, max/r);
212
213 Double_t x1, x2, y1, y2;
214 gPad->GetRange(x1, x2, y1, y2);
215
216 double dmin = fData[0];
217 double dmax = fData[0];
218
219 for (unsigned int i=0; i<fData.size(); i++)
220 {
221 if (!fEnable[i])
222 continue;
223
224 if (fData[i]>dmax)
225 dmax = fData[i];
226 if (fData[i]<dmin)
227 dmin = fData[i];
228 }
229
230 if (fMin>=0)
231 dmin = fMin;
232 if (fMax>=0)
233 dmax = fMax;
234
235// const double min = dmin;
236// const double scale = dmax==dmin ? 1 : dmax-dmin;
237
238 TAttFill fill(0, 1001);
239 TAttLine line;
240
241 int cnt=0;
242 for (Positions::iterator p=fGeom.begin(); p!=fGeom.end(); p++, cnt++)
243 {
244 if (fBold[cnt])
245 continue;
246
247 const int col = GetCol(dmin, fData[cnt], dmax, fEnable[cnt]);
248
249 fill.SetFillColor(col);
250 fill.Modify();
251
252 Paint(*p);
253 }
254
255 line.SetLineWidth(2);
256 line.Modify();
257
258 cnt = 0;
259 for (Positions::iterator p=fGeom.begin(); p!=fGeom.end(); p++, cnt++)
260 {
261 if (!fBold[cnt])
262 continue;
263
264 const int col = GetCol(dmin, fData[cnt], dmax, fEnable[cnt]);
265
266 fill.SetFillColor(col);
267 fill.Modify();
268
269 Paint(*p);
270 }
271
272 TMarker m(0,0,kStar);
273 m.DrawMarker(0, 0);
274
275 if (fWhite<0)
276 return;
277
278 const Position &p = fGeom[fWhite];
279
280 line.SetLineColor(kWhite);
281 line.Modify();
282
283 const int col = GetCol(dmin, fData[fWhite], dmax, fEnable[fWhite]);
284
285 fill.SetFillColor(col);
286 fill.Modify();
287
288 Paint(p);
289 }
290
291 int GetIdx(float px, float py) const
292 {
293 static const double sqrt3 = sqrt(3);
294
295 int idx = 0;
296 for (Positions::const_iterator p=fGeom.begin(); p!=fGeom.end(); p++, idx++)
297 {
298 const Double_t dy = py - p->second;
299 if (fabs(dy)>0.5)
300 continue;
301
302 const Double_t dx = px - p->first;
303
304 if (TMath::Abs(dy + dx*sqrt3) > 1)
305 continue;
306
307 if (TMath::Abs(dy - dx*sqrt3) > 1)
308 continue;
309
310 return idx;
311 }
312 return -1;
313 }
314
315 char *GetObjectInfo(Int_t px, Int_t py) const
316 {
317 static stringstream stream;
318 static string str;
319
320 const float x = gPad->AbsPixeltoX(px);
321 const float y = gPad->AbsPixeltoY(py);
322
323 const int idx = GetIdx(x, y);
324
325 stream.seekp(0);
326 if (idx>=0)
327 {
328 stream << "Pixel=" << idx << " Data=" << fData[idx] << '\0';
329 }
330
331 str = stream.str();
332 return const_cast<char*>(str.c_str());
333 }
334
335 Int_t DistancetoPrimitive(Int_t px, Int_t py)
336 {
337 const float x = gPad->AbsPixeltoX(px);
338 const float y = gPad->AbsPixeltoY(py);
339
340 return GetIdx(x, y)>=0 ? 0 : 99999;
341 }
342
343 void SetData(const valarray<double> &data)
344 {
345 fData = data;
346 }
347
348 void SetData(const float *data)
349 {
350 for (int i=0; i<1440; i++)
351 fData[i] = data[i];
352 }
353};
354*/
355// #########################################################################
356
357
358class FactGui : public MainWindow, public DimNetwork
359{
360private:
361 class FunctionEvent : public QEvent
362 {
363 public:
364 boost::function<void(const QEvent &)> fFunction;
365
366 FunctionEvent(const boost::function<void(const QEvent &)> &f)
367 : QEvent((QEvent::Type)QEvent::registerEventType()),
368 fFunction(f) { }
369
370 bool Exec() { fFunction(*this); return true; }
371 };
372
373 valarray<int8_t> fFtuStatus;
374
375 vector<int> fPixelMapHW; // Software -> Hardware
376 vector<int> fPatchMapHW; // Software -> Hardware
377 vector<int> fPatchHW; // Maps the software(!) pixel id to the hardware(!) patch id
378
379 bool fInChoosePatchTH; // FIXME. Find a better solution
380 bool fInChoosePatchBias; // FIXME. Find a better solution
381
382 DimStampedInfo fDimDNS;
383
384 DimStampedInfo fDimLoggerStats;
385 DimStampedInfo fDimLoggerFilenameNight;
386 DimStampedInfo fDimLoggerFilenameRun;
387 DimStampedInfo fDimLoggerNumSubs;
388
389 DimStampedInfo fDimFtmPassport;
390 DimStampedInfo fDimFtmTriggerRates;
391 DimStampedInfo fDimFtmError;
392 DimStampedInfo fDimFtmFtuList;
393 DimStampedInfo fDimFtmStaticData;
394 DimStampedInfo fDimFtmDynamicData;
395 DimStampedInfo fDimFtmCounter;
396
397 DimStampedInfo fDimFadWriteStats;
398 DimStampedInfo fDimFadStartRun;
399 DimStampedInfo fDimFadRuns;
400 DimStampedInfo fDimFadEvents;
401 DimStampedInfo fDimFadRawData;
402 DimStampedInfo fDimFadEventData;
403 DimStampedInfo fDimFadConnections;
404 DimStampedInfo fDimFadFwVersion;
405 DimStampedInfo fDimFadRunNumber;
406 DimStampedInfo fDimFadDNA;
407 DimStampedInfo fDimFadTemperature;
408 DimStampedInfo fDimFadPrescaler;
409 DimStampedInfo fDimFadRefClock;
410 DimStampedInfo fDimFadRoi;
411 DimStampedInfo fDimFadDac;
412 DimStampedInfo fDimFadDrsCalibration;
413 DimStampedInfo fDimFadStatus;
414 DimStampedInfo fDimFadStatistics1;
415 DimStampedInfo fDimFadStatistics2;
416
417 DimStampedInfo fDimFscTemp;
418 DimStampedInfo fDimFscVolt;
419 DimStampedInfo fDimFscCurrent;
420 DimStampedInfo fDimFscHumidity;
421
422 //DimStampedInfo fDimBiasVolt;
423 DimStampedInfo fDimBiasCurrent;
424
425 map<string, DimInfo*> fServices;
426
427 // ========================== LED Colors ================================
428
429 enum LedColor_t
430 {
431 kLedRed,
432 kLedGreen,
433 kLedYellow,
434 kLedOrange,
435 kLedGray
436 };
437
438 void SetLedColor(QPushButton *button, LedColor_t col, const Time &t)
439 {
440 switch (col)
441 {
442 case kLedRed:
443 button->setIcon(QIcon(":/Resources/icons/red circle 1.png"));
444 break;
445
446 case kLedGreen:
447 button->setIcon(QIcon(":/Resources/icons/green circle 1.png"));
448 break;
449
450 case kLedYellow:
451 button->setIcon(QIcon(":/Resources/icons/yellow circle 1.png"));
452 break;
453
454 case kLedOrange:
455 button->setIcon(QIcon(":/Resources/icons/orange circle 1.png"));
456 break;
457
458 case kLedGray:
459 button->setIcon(QIcon(":/Resources/icons/gray circle 1.png"));
460 break;
461 }
462
463 //button->setToolTip("Last change: "+QDateTime::currentDateTimeUtc().toString()+" UTC");
464 button->setToolTip(("Last change: "+t.GetAsStr()+" (UTC)").c_str());
465 }
466
467 // ===================== Services and Commands ==========================
468
469 QStandardItem *AddServiceItem(const std::string &server, const std::string &service, bool iscmd)
470 {
471 QListView *servers = iscmd ? fDimCmdServers : fDimSvcServers;
472 QListView *services = iscmd ? fDimCmdCommands : fDimSvcServices;
473 QListView *description = iscmd ? fDimCmdDescription : fDimSvcDescription;
474
475 QStandardItemModel *m = dynamic_cast<QStandardItemModel*>(servers->model());
476 if (!m)
477 {
478 m = new QStandardItemModel(this);
479 servers->setModel(m);
480 services->setModel(m);
481 description->setModel(m);
482 }
483
484 QList<QStandardItem*> l = m->findItems(server.c_str());
485
486 if (l.size()>1)
487 {
488 cout << "hae" << endl;
489 return 0;
490 }
491
492 QStandardItem *col = l.size()==0 ? NULL : l[0];
493
494 if (!col)
495 {
496 col = new QStandardItem(server.c_str());
497 m->appendRow(col);
498
499 if (!services->rootIndex().isValid())
500 {
501 services->setRootIndex(col->index());
502 servers->setCurrentIndex(col->index());
503 }
504 }
505
506 QStandardItem *item = 0;
507 for (int i=0; i<col->rowCount(); i++)
508 {
509 QStandardItem *coli = col->child(i);
510 if (coli->text().toStdString()==service)
511 return coli;
512 }
513
514 item = new QStandardItem(service.c_str());
515 col->appendRow(item);
516 col->sortChildren(0);
517
518 if (!description->rootIndex().isValid())
519 {
520 description->setRootIndex(item->index());
521 services->setCurrentIndex(item->index());
522 }
523
524 if (!iscmd)
525 item->setCheckable(true);
526
527 return item;
528 }
529
530 void AddDescription(QStandardItem *item, const vector<Description> &vec)
531 {
532 if (!item)
533 return;
534 if (vec.size()==0)
535 return;
536
537 item->setToolTip(vec[0].comment.c_str());
538
539 const string str = Description::GetHtmlDescription(vec);
540
541 QStandardItem *desc = new QStandardItem(str.c_str());
542 desc->setSelectable(false);
543 item->setChild(0, 0, desc);
544 }
545
546 void AddServer(const std::string &s)
547 {
548 DimNetwork::AddServer(s);
549
550 QApplication::postEvent(this,
551 new FunctionEvent(boost::bind(&FactGui::handleAddServer, this, s)));
552 }
553
554 void AddService(const std::string &server, const std::string &service, const std::string &fmt, bool iscmd)
555 {
556 QApplication::postEvent(this,
557 new FunctionEvent(boost::bind(&FactGui::handleAddService, this, server, service, fmt, iscmd)));
558 }
559
560 void RemoveService(std::string server, std::string service, bool iscmd)
561 {
562 UnsubscribeService(server+'/'+service, true);
563
564 QApplication::postEvent(this,
565 new FunctionEvent(boost::bind(&FactGui::handleRemoveService, this, server, service, iscmd)));
566 }
567
568 void RemoveAllServices(const std::string &server)
569 {
570 UnsubscribeAllServices(server);
571
572 QApplication::postEvent(this,
573 new FunctionEvent(boost::bind(&FactGui::handleRemoveAllServices, this, server)));
574 }
575
576 void AddDescription(const std::string &server, const std::string &service, const vector<Description> &vec)
577 {
578 QApplication::postEvent(this,
579 new FunctionEvent(boost::bind(&FactGui::handleAddDescription, this, server, service, vec)));
580 }
581
582 // ======================================================================
583
584 void handleAddServer(const std::string &server)
585 {
586 const State s = GetState(server, GetCurrentState(server));
587 handleStateChanged(Time(), server, s);
588 }
589
590 void handleAddService(const std::string &server, const std::string &service, const std::string &/*fmt*/, bool iscmd)
591 {
592 QStandardItem *item = AddServiceItem(server, service, iscmd);
593 const vector<Description> v = GetDescription(server, service);
594 AddDescription(item, v);
595 }
596
597 void handleRemoveService(const std::string &server, const std::string &service, bool iscmd)
598 {
599 QListView *servers = iscmd ? fDimCmdServers : fDimSvcServers;
600
601 QStandardItemModel *m = dynamic_cast<QStandardItemModel*>(servers->model());
602 if (!m)
603 return;
604
605 QList<QStandardItem*> l = m->findItems(server.c_str());
606 if (l.size()!=1)
607 return;
608
609 for (int i=0; i<l[0]->rowCount(); i++)
610 {
611 QStandardItem *row = l[0]->child(i);
612 if (row->text().toStdString()==service)
613 {
614 l[0]->removeRow(row->index().row());
615 return;
616 }
617 }
618 }
619
620 void handleRemoveAllServices(const std::string &server)
621 {
622 handleStateChanged(Time(), server, State(-2, "Offline", "No connection via DIM."));
623
624 QStandardItemModel *m = 0;
625 if ((m=dynamic_cast<QStandardItemModel*>(fDimCmdServers->model())))
626 {
627 QList<QStandardItem*> l = m->findItems(server.c_str());
628 if (l.size()==1)
629 m->removeRow(l[0]->index().row());
630 }
631
632 if ((m = dynamic_cast<QStandardItemModel*>(fDimSvcServers->model())))
633 {
634 QList<QStandardItem*> l = m->findItems(server.c_str());
635 if (l.size()==1)
636 m->removeRow(l[0]->index().row());
637 }
638 }
639
640 void handleAddDescription(const std::string &server, const std::string &service, const vector<Description> &vec)
641 {
642 const bool iscmd = IsCommand(server, service)==true;
643
644 QStandardItem *item = AddServiceItem(server, service, iscmd);
645 AddDescription(item, vec);
646 }
647
648 // ======================================================================
649
650 void SubscribeService(const string &service)
651 {
652 if (fServices.find(service)!=fServices.end())
653 {
654 cout << "ERROR - We are already subscribed to " << service << endl;
655 return;
656 }
657
658 fServices[service] = new DimStampedInfo(service.c_str(), (void*)NULL, 0, this);
659 }
660
661 void UnsubscribeService(const string &service, bool allow_unsubscribed=false)
662 {
663 const map<string,DimInfo*>::iterator i=fServices.find(service);
664
665 if (i==fServices.end())
666 {
667 if (!allow_unsubscribed)
668 cout << "ERROR - We are not subscribed to " << service << endl;
669 return;
670 }
671
672 delete i->second;
673
674 fServices.erase(i);
675 }
676
677 void UnsubscribeAllServices(const string &server)
678 {
679 for (map<string,DimInfo*>::iterator i=fServices.begin();
680 i!=fServices.end(); i++)
681 if (i->first.substr(0, server.length()+1)==server+'/')
682 {
683 delete i->second;
684 fServices.erase(i);
685 }
686 }
687
688 // ======================================================================
689
690 struct DimData
691 {
692 const int qos;
693 const string name;
694 const string format;
695 const vector<char> data;
696 const Time time;
697
698 Time extract(DimInfo *inf) const
699 {
700 // Must be called in exactly this order!
701 const int tsec = inf->getTimestamp();
702 const int tms = inf->getTimestampMillisecs();
703
704 return Time(tsec, tms*1000);
705 }
706
707// DimInfo *info; // this is ONLY for a fast check of the type of the DimData!!
708
709 DimData(DimInfo *inf) :
710 qos(inf->getQuality()),
711 name(inf->getName()),
712 format(inf->getFormat()),
713 data(inf->getString(), inf->getString()+inf->getSize()),
714 time(extract(inf))/*,
715 info(inf)*/
716 {
717 }
718
719 template<typename T>
720 T get(uint32_t offset=0) const { return *reinterpret_cast<const T*>(data.data()+offset); }
721
722 template<typename T>
723 const T *ptr(uint32_t offset=0) const { return reinterpret_cast<const T*>(data.data()+offset); }
724
725 template<typename T>
726 const T &ref(uint32_t offset=0) const { return *reinterpret_cast<const T*>(data.data()+offset); }
727
728// vector<char> vec(int b) const { return vector<char>(data.begin()+b, data.end()); }
729// string str(unsigned int b) const { return b>=data.size()?string():string(data.data()+b, data.size()-b); }
730 const char *c_str() const { return (char*)data.data(); }
731/*
732 vector<boost::any> any() const
733 {
734 const Converter conv(format);
735 conv.Print();
736 return conv.GetAny(data.data(), data.size());
737 }*/
738 size_t size() const { return data.size(); }
739 };
740
741 // ======================= DNS ==========================================
742
743 void handleDimDNS(const DimData &d)
744 {
745 const int version = d.size()!=4 ? 0 : d.get<uint32_t>();
746
747 ostringstream str;
748 str << "V" << version/100 << 'r' << version%100;
749
750 ostringstream dns;
751 dns << (version==0?"No connection":"Connection");
752 dns << " to DIM DNS (" << getenv("DIM_DNS_NODE") << ")";
753 dns << (version==0?".":" established.");
754
755 fStatusDNSLabel->setText(version==0?"Offline":str.str().c_str());
756 fStatusDNSLabel->setToolTip(dns.str().c_str());
757
758 SetLedColor(fStatusDNSLed, version==0 ? kLedRed : kLedGreen, Time());
759 }
760
761
762 // ======================= Logger =======================================
763
764 void handleLoggerStats(const DimData &d)
765 {
766 const bool connected = d.size()!=0;
767
768 fLoggerET->setEnabled(connected);
769 fLoggerRate->setEnabled(connected);
770 fLoggerWritten->setEnabled(connected);
771 fLoggerFreeSpace->setEnabled(connected);
772 fLoggerSpaceLeft->setEnabled(connected);
773
774 if (!connected)
775 return;
776
777 const uint64_t *vals = d.ptr<uint64_t>();
778
779 const size_t space = vals[0];
780 const size_t written = vals[1];
781 const size_t rate = float(vals[2])/vals[3];
782
783 fLoggerFreeSpace->setSuffix(" MB");
784 fLoggerFreeSpace->setDecimals(0);
785 fLoggerFreeSpace->setValue(space*1e-6);
786
787 if (space> 1000000) // > 1GB
788 {
789 fLoggerFreeSpace->setSuffix(" GB");
790 fLoggerFreeSpace->setDecimals(2);
791 fLoggerFreeSpace->setValue(space*1e-9);
792 }
793 if (space>= 3000000) // >= 3GB
794 {
795 fLoggerFreeSpace->setSuffix(" GB");
796 fLoggerFreeSpace->setDecimals(1);
797 fLoggerFreeSpace->setValue(space*1e-9);
798 }
799 if (space>=100000000) // >= 100GB
800 {
801 fLoggerFreeSpace->setSuffix(" GB");
802 fLoggerFreeSpace->setDecimals(0);
803 fLoggerFreeSpace->setValue(space*1e-9);
804 }
805
806 fLoggerET->setTime(QTime().addSecs(rate>0?space/rate:0));
807 fLoggerRate->setValue(rate*1e-3); // kB/s
808 fLoggerWritten->setValue(written*1e-6);
809
810 fLoggerRate->setSuffix(" kB/s");
811 fLoggerRate->setDecimals(2);
812 fLoggerRate->setValue(rate);
813 if (rate> 2) // > 2kB/s
814 {
815 fLoggerRate->setSuffix(" kB/s");
816 fLoggerRate->setDecimals(1);
817 fLoggerRate->setValue(rate);
818 }
819 if (rate>=100) // >100kB/s
820 {
821 fLoggerRate->setSuffix(" kB/s");
822 fLoggerRate->setDecimals(0);
823 fLoggerRate->setValue(rate);
824 }
825 if (rate>=1000) // >100kB/s
826 {
827 fLoggerRate->setSuffix(" MB/s");
828 fLoggerRate->setDecimals(2);
829 fLoggerRate->setValue(rate*1e-3);
830 }
831 if (rate>=10000) // >1MB/s
832 {
833 fLoggerRate->setSuffix(" MB/s");
834 fLoggerRate->setDecimals(1);
835 fLoggerRate->setValue(rate*1e-3);
836 }
837 if (rate>=100000) // >10MB/s
838 {
839 fLoggerRate->setSuffix(" MB/s");
840 fLoggerRate->setDecimals(0);
841 fLoggerRate->setValue(rate*1e-3);
842 }
843
844 if (space/1000000>static_cast<size_t>(fLoggerSpaceLeft->maximum()))
845 fLoggerSpaceLeft->setValue(fLoggerSpaceLeft->maximum()); // GB
846 else
847 fLoggerSpaceLeft->setValue(space/1000000); // MB
848 }
849
850 void handleLoggerFilenameNight(const DimData &d)
851 {
852 const bool connected = d.size()!=0;
853
854 fLoggerFilenameNight->setEnabled(connected);
855 if (!connected)
856 return;
857
858 fLoggerFilenameNight->setText(d.c_str()+4);
859
860 const uint32_t files = d.get<uint32_t>();
861
862 SetLedColor(fLoggerLedLog, files&1 ? kLedGreen : kLedGray, d.time);
863 SetLedColor(fLoggerLedRep, files&2 ? kLedGreen : kLedGray, d.time);
864 SetLedColor(fLoggerLedFits, files&4 ? kLedGreen : kLedGray, d.time);
865 }
866
867 void handleLoggerFilenameRun(const DimData &d)
868 {
869 const bool connected = d.size()!=0;
870
871 fLoggerFilenameRun->setEnabled(connected);
872 if (!connected)
873 return;
874
875 fLoggerFilenameRun->setText(d.c_str()+4);
876
877 const uint32_t files = d.get<uint32_t>();
878
879 SetLedColor(fLoggerLedLog, files&1 ? kLedGreen : kLedGray, d.time);
880 SetLedColor(fLoggerLedRep, files&2 ? kLedGreen : kLedGray, d.time);
881 SetLedColor(fLoggerLedFits, files&4 ? kLedGreen : kLedGray, d.time);
882 }
883
884 void handleLoggerNumSubs(const DimData &d)
885 {
886 const bool connected = d.size()!=0;
887
888 fLoggerSubscriptions->setEnabled(connected);
889 fLoggerOpenFiles->setEnabled(connected);
890 if (!connected)
891 return;
892
893 const uint32_t *vals = d.ptr<uint32_t>();
894
895 fLoggerSubscriptions->setValue(vals[0]);
896 fLoggerOpenFiles->setValue(vals[1]);
897 }
898
899
900 // ===================== All ============================================
901
902 bool CheckSize(const DimData &d, size_t sz, bool print=true) const
903 {
904 if (d.size()==0)
905 return false;
906
907 if (d.size()!=sz)
908 {
909 if (print)
910 cout << "Size mismatch in " << d.name << ": Found=" << d.size() << " Expected=" << sz << endl;
911 return false;
912 }
913
914 return true;
915 }
916
917 // ===================== FAD ============================================
918
919 void handleFadWriteStats(const DimData &d)
920 {
921 const bool connected = d.size()!=0;
922
923 fEvtBuilderET->setEnabled(connected);
924 fEvtBuilderRate->setEnabled(connected);
925 fEvtBuilderWritten->setEnabled(connected);
926 fEvtBuilderFreeSpace->setEnabled(connected);
927 fEvtBuilderSpaceLeft->setEnabled(connected);
928
929 if (!connected)
930 return;
931
932 const uint64_t *vals = d.ptr<uint64_t>();
933
934 const size_t space = vals[0];
935 const size_t written = vals[1];
936 const size_t rate = float(vals[2])/vals[3];
937
938 fEvtBuilderFreeSpace->setSuffix(" MB");
939 fEvtBuilderFreeSpace->setDecimals(0);
940 fEvtBuilderFreeSpace->setValue(space*1e-6);
941
942 if (space> 1000000) // > 1GB
943 {
944 fEvtBuilderFreeSpace->setSuffix(" GB");
945 fEvtBuilderFreeSpace->setDecimals(2);
946 fEvtBuilderFreeSpace->setValue(space*1e-9);
947 }
948 if (space>= 3000000) // >= 3GB
949 {
950 fEvtBuilderFreeSpace->setSuffix(" GB");
951 fEvtBuilderFreeSpace->setDecimals(1);
952 fEvtBuilderFreeSpace->setValue(space*1e-9);
953 }
954 if (space>=100000000) // >= 100GB
955 {
956 fEvtBuilderFreeSpace->setSuffix(" GB");
957 fEvtBuilderFreeSpace->setDecimals(0);
958 fEvtBuilderFreeSpace->setValue(space*1e-9);
959 }
960
961 fEvtBuilderET->setTime(QTime().addSecs(rate>0?space/rate:0));
962 fEvtBuilderRate->setValue(rate*1e-3); // kB/s
963 fEvtBuilderWritten->setValue(written*1e-6);
964
965 fEvtBuilderRate->setSuffix(" kB/s");
966 fEvtBuilderRate->setDecimals(2);
967 fEvtBuilderRate->setValue(rate);
968 if (rate> 2) // > 2kB/s
969 {
970 fEvtBuilderRate->setSuffix(" kB/s");
971 fEvtBuilderRate->setDecimals(1);
972 fEvtBuilderRate->setValue(rate);
973 }
974 if (rate>=100) // >100kB/s
975 {
976 fEvtBuilderRate->setSuffix(" kB/s");
977 fEvtBuilderRate->setDecimals(0);
978 fEvtBuilderRate->setValue(rate);
979 }
980 if (rate>=1000) // >100kB/s
981 {
982 fEvtBuilderRate->setSuffix(" MB/s");
983 fEvtBuilderRate->setDecimals(2);
984 fEvtBuilderRate->setValue(rate*1e-3);
985 }
986 if (rate>=10000) // >1MB/s
987 {
988 fEvtBuilderRate->setSuffix(" MB/s");
989 fEvtBuilderRate->setDecimals(1);
990 fEvtBuilderRate->setValue(rate*1e-3);
991 }
992 if (rate>=100000) // >10MB/s
993 {
994 fEvtBuilderRate->setSuffix(" MB/s");
995 fEvtBuilderRate->setDecimals(0);
996 fEvtBuilderRate->setValue(rate*1e-3);
997 }
998
999 if (space/1000000>static_cast<size_t>(fEvtBuilderSpaceLeft->maximum()))
1000 fEvtBuilderSpaceLeft->setValue(fEvtBuilderSpaceLeft->maximum()); // GB
1001 else
1002 fEvtBuilderSpaceLeft->setValue(space/1000000); // MB
1003 }
1004
1005 void handleFadRuns(const DimData &d)
1006 {
1007 if (d.size()==0)
1008 return;
1009
1010 if (d.size()<20)
1011 {
1012 cout << "Size mismatch in " << d.name << ": Found=" << d.size() << " Expected>=20" << endl;
1013 return;
1014 }
1015
1016 const uint32_t *ptr = d.ptr<uint32_t>();
1017
1018 fEvtBldOpenFiles->setValue(ptr[0]);
1019 fEvtBldOpenStreams->setValue(ptr[0]);
1020 fEvtBldRunNumberMin->setValue(ptr[1]);
1021 fEvtBldRunNumberMax->setValue(ptr[2]);
1022 fEvtBldLastOpened->setValue(ptr[3]);
1023 fEvtBldLastClosed->setValue(ptr[4]);
1024
1025 if (d.size()>=20)
1026 fEvtBldFilename->setText(d.ptr<char>(20));
1027
1028 if (ptr[0]==0)
1029 fEvtBldFilename->setText("");
1030 }
1031
1032 void handleFadStartRun(const DimData &d)
1033 {
1034 if (!CheckSize(d, 16))
1035 return;
1036
1037 const int64_t *runs = d.ptr<int64_t>();
1038
1039 fFadRunNoCur->setValue(runs[0]);
1040 fFadRunNoNext->setValue(runs[1]);
1041 fFadRunNoCur->setEnabled(runs[0]>=0);
1042 }
1043
1044 void handleFadEvents(const DimData &d)
1045 {
1046 if (!CheckSize(d, 16))
1047 return;
1048
1049 const uint32_t *ptr = d.ptr<uint32_t>();
1050
1051 fEvtsSuccessCurRun->setValue(ptr[0]);
1052 fEvtsSuccessTotal->setValue(ptr[1]);
1053 fEvtBldEventId->setValue(ptr[2]);
1054 fFadEvtCounter->setValue(ptr[2]);
1055 fEvtBldTriggerId->setValue(ptr[3]);
1056 }
1057
1058 void handleFadTemperature(const DimData &d)
1059 {
1060 if (d.size()==0)
1061 {
1062 fFadTempMin->setEnabled(false);
1063 fFadTempMax->setEnabled(false);
1064 SetLedColor(fFadLedTemp, kLedGray, d.time);
1065 return;
1066 }
1067
1068 if (!CheckSize(d, 82*sizeof(float)))
1069 return;
1070
1071 const float *ptr = d.ptr<float>();
1072
1073 fFadTempMin->setEnabled(true);
1074 fFadTempMax->setEnabled(true);
1075
1076 fFadTempMin->setValue(ptr[0]);
1077 fFadTempMax->setValue(ptr[41]);
1078
1079 handleFadToolTip(d.time, fFadTempMin, ptr+1);
1080 handleFadToolTip(d.time, fFadTempMax, ptr+42);
1081 }
1082
1083 void handleFadRefClock(const DimData &d)
1084 {
1085 if (d.size()==0)
1086 {
1087 fFadRefClockMin->setEnabled(false);
1088 fFadRefClockMax->setEnabled(false);
1089 SetLedColor(fFadLedRefClock, kLedGray, d.time);
1090 return;
1091 }
1092
1093 if (!CheckSize(d, 42*sizeof(uint32_t)))
1094 return;
1095
1096 const uint32_t *ptr = d.ptr<uint32_t>();
1097
1098 fFadRefClockMin->setEnabled(true);
1099 fFadRefClockMax->setEnabled(true);
1100
1101 fFadRefClockMin->setValue(ptr[40]*2.048);
1102 fFadRefClockMax->setValue(ptr[41]*2.048);
1103
1104 const int64_t diff = int64_t(ptr[41]) - int64_t(ptr[40]);
1105
1106 SetLedColor(fFadLedRefClock, abs(diff)>3?kLedRed:kLedGreen, d.time);
1107
1108 handleFadToolTip(d.time, fFadLedRefClock, ptr);
1109 }
1110
1111 void handleFadRoi(const DimData &d)
1112 {
1113 if (d.size()==0)
1114 {
1115 fFadRoi->setEnabled(false);
1116 fFadRoiCh9->setEnabled(false);
1117 SetLedColor(fFadLedRoi, kLedGray, d.time);
1118 return;
1119 }
1120
1121 if (!CheckSize(d, 2*sizeof(uint16_t)))
1122 return;
1123
1124 const uint16_t *ptr = d.ptr<uint16_t>();
1125
1126 fFadRoi->setEnabled(true);
1127 fFadRoiCh9->setEnabled(true);
1128
1129 fFadRoi->setValue(ptr[0]);
1130 fFadRoiCh9->setValue(ptr[1]);
1131
1132 SetLedColor(fFadLedRoi, kLedGray, d.time);
1133 }
1134
1135 void handleDac(QPushButton *led, QSpinBox *box, const DimData &d, int idx)
1136 {
1137 if (d.size()==0)
1138 {
1139 box->setEnabled(false);
1140 SetLedColor(led, kLedGray, d.time);
1141 return;
1142 }
1143
1144 const uint16_t *ptr = d.ptr<uint16_t>()+idx*42;
1145
1146 box->setEnabled(true);
1147 box->setValue(ptr[40]==ptr[41]?ptr[40]:0);
1148
1149 SetLedColor(led, ptr[40]==ptr[41]?kLedGreen:kLedOrange, d.time);
1150 handleFadToolTip(d.time, led, ptr);
1151 }
1152
1153 void handleFadDac(const DimData &d)
1154 {
1155 if (!CheckSize(d, 8*42*sizeof(uint16_t)) && !d.size()==0)
1156 return;
1157
1158 handleDac(fFadLedDac0, fFadDac0, d, 0);
1159 handleDac(fFadLedDac1, fFadDac1, d, 1);
1160 handleDac(fFadLedDac2, fFadDac2, d, 2);
1161 handleDac(fFadLedDac3, fFadDac3, d, 3);
1162 handleDac(fFadLedDac4, fFadDac4, d, 4);
1163 handleDac(fFadLedDac5, fFadDac5, d, 5);
1164 handleDac(fFadLedDac6, fFadDac6, d, 6);
1165 handleDac(fFadLedDac7, fFadDac7, d, 7);
1166 }
1167
1168 EVENT *fEventData;
1169
1170 void DrawHorizontal(TH1 *hf, double xmax, TH1 &h, double scale)
1171 {
1172 for (Int_t i=1;i<=h.GetNbinsX();i++)
1173 {
1174 if (h.GetBinContent(i)<0.5 || h.GetBinContent(i)>h.GetEntries()-0.5)
1175 continue;
1176
1177 TBox * box=new TBox(xmax, h.GetBinLowEdge(i),
1178 xmax+h.GetBinContent(i)*scale,
1179 h.GetBinLowEdge(i+1));
1180
1181 box->SetFillStyle(0);
1182 box->SetLineColor(h.GetLineColor());
1183 box->SetLineStyle(kSolid);
1184 box->SetBit(kCannotPick|kNoContextMenu);
1185 //box->Draw();
1186
1187 hf->GetListOfFunctions()->Add(box);
1188 }
1189 }
1190
1191 void DisplayEventData()
1192 {
1193 if (!fEventData)
1194 return;
1195
1196#ifdef HAVE_ROOT
1197 TCanvas *c = fAdcDataCanv->GetCanvas();
1198
1199 TH1 *hf = dynamic_cast<TH1*>(c->FindObject("Frame"));
1200 TH1 *h = dynamic_cast<TH1*>(c->FindObject("EventData"));
1201 TH1 *d0 = dynamic_cast<TH1*>(c->FindObject("DrsCalib0"));
1202 TH1 *d1 = dynamic_cast<TH1*>(c->FindObject("DrsCalib1"));
1203 TH1 *d2 = dynamic_cast<TH1*>(c->FindObject("DrsCalib2"));
1204
1205 if ((hf && hf->GetNbinsX()!=fEventData->Roi) ||
1206 (dynamic_cast<TH2*>(h) && !fAdcPersistent->isChecked()) ||
1207 (!dynamic_cast<TH2*>(h) && fAdcPersistent->isChecked()))
1208 {
1209 delete hf;
1210 delete h;
1211 delete d0;
1212 delete d1;
1213 delete d2;
1214 d0 = 0;
1215 d1 = 0;
1216 d2 = 0;
1217 hf = 0;
1218 }
1219 const int roi = fEventData->Roi>0 ? fEventData->Roi : 1;
1220
1221 c->cd();
1222
1223 if (!hf)
1224 {
1225 hf = new TH1F("Frame", "", roi, -0.5, roi-0.5);
1226 hf->SetDirectory(0);
1227 hf->SetBit(kCanDelete);
1228 hf->SetStats(kFALSE);
1229 hf->SetYTitle("Voltage [mV]");
1230 hf->GetXaxis()->CenterTitle();
1231 hf->GetYaxis()->CenterTitle();
1232 hf->SetMinimum(-1250);
1233 hf->SetMaximum(2150);
1234
1235 if (!fAdcPersistent->isChecked())
1236 h = new TH1F("EventData", "", roi, -0.5, roi-0.5);
1237 else
1238 {
1239 h = new TH2F("EventData", "", roi, -0.5, roi-0.5, 3301, -1150.5, 2150.5);
1240 h->SetContour(50);
1241 gStyle->SetPalette(1, 0);
1242 }
1243
1244 h->SetDirectory(0);
1245 h->SetBit(kCanDelete);
1246 h->SetMarkerStyle(kFullDotMedium);
1247 h->SetMarkerColor(kBlue);
1248
1249 hf->Draw("");
1250
1251 if (dynamic_cast<TH2*>(h))
1252 h->Draw("col same");
1253 }
1254
1255 if (d0 && !(fDrsCalibBaselineOn->isChecked() && fDrsCalibBaseline->value()>0))
1256 {
1257 delete d0;
1258 d0 = 0;
1259 }
1260 if (d1 && !(fDrsCalibGainOn->isChecked() && fDrsCalibGain->value()>0))
1261 {
1262 delete d1;
1263 d1 = 0;
1264 }
1265 if (d2 && !(fDrsCalibTrgOffsetOn->isChecked() && fDrsCalibTrgOffset->value()>0))
1266 {
1267 delete d2;
1268 d2 = 0;
1269 }
1270
1271 if (!d0 && fDrsCalibBaselineOn->isChecked() && fDrsCalibBaseline->value()>0)
1272 {
1273 d0 = new TH1F("DrsCalib0", "", roi, -0.5, roi-0.5);
1274 d0->SetDirectory(0);
1275 d0->SetBit(kCanDelete);
1276 d0->SetMarkerStyle(kFullDotSmall);
1277 d0->SetMarkerColor(kRed);
1278 d0->SetLineColor(kRed);
1279 d0->Draw("PEX0same");
1280 }
1281
1282 if (!d1 && fDrsCalibGainOn->isChecked() && fDrsCalibGain->value()>0)
1283 {
1284 d1 = new TH1F("DrsCalib1", "", roi, -0.5, roi-0.5);
1285 d1->SetDirectory(0);
1286 d1->SetBit(kCanDelete);
1287 d1->SetMarkerStyle(kFullDotSmall);
1288 d1->SetMarkerColor(kMagenta);
1289 d1->SetLineColor(kMagenta);
1290 d1->Draw("PEX0same");
1291 }
1292
1293 if (!d2 && fDrsCalibTrgOffsetOn->isChecked() && fDrsCalibTrgOffset->value()>0)
1294 {
1295 d2 = new TH1F("DrsCalib2", "", roi, -0.5, roi-0.5);
1296 d2->SetDirectory(0);
1297 d2->SetBit(kCanDelete);
1298 d2->SetMarkerStyle(kFullDotSmall);
1299 d2->SetMarkerColor(kGreen);
1300 d2->SetLineColor(kGreen);
1301 d2->Draw("PEX0same");
1302 }
1303
1304 if (!dynamic_cast<TH2*>(h) && !c->GetListOfPrimitives()->FindObject(h))
1305 h->Draw("PLsame");
1306
1307 // -----------------------------------------------------------
1308
1309 const uint32_t p =
1310 fAdcChannel->value() +
1311 fAdcChip->value() * 9+
1312 fAdcBoard->value() * 36+
1313 fAdcCrate->value() *360;
1314
1315 ostringstream str;
1316 str << "EventNum = " << fEventData->EventNum;
1317 str << " TriggerNum = " << fEventData->TriggerNum;
1318 str << " TriggerType = " << fEventData->TriggerType;
1319 str << " BoardTime = " << fEventData->BoardTime[fAdcBoard->value()+fAdcCrate->value()*10];
1320 str << " (" << Time(fEventData->PCTime, fEventData->PCUsec) << ")";
1321 hf->SetTitle(str.str().c_str());
1322 str.str("");
1323 str << "ADC Pipeline (start cell: " << fEventData->StartPix[p] << ")";
1324 hf->SetXTitle(str.str().c_str());
1325
1326 // -----------------------------------------------------------
1327
1328 const int16_t start = fEventData->StartPix[p];
1329
1330 fDrsCalibBaseline->setEnabled(fDrsCalibBaseline->value()>0);
1331 fDrsCalibGain->setEnabled(fDrsCalibGain->value()>0);
1332 fDrsCalibTrgOffset->setEnabled(fDrsCalibTrgOffset->value()>0);
1333
1334 if (d0)//fDrsCalibBaseline->value()==0 || start<0)
1335 d0->Reset();
1336 if (d1)//fDrsCalibGain->value()==0 || start<0)
1337 d1->Reset();
1338 if (d2)//fDrsCalibTrgOffset->value()==0 || start<0)
1339 d2->Reset();
1340
1341 if (!dynamic_cast<TH2*>(h))
1342 h->Reset();
1343 if (d0)
1344 d0->SetEntries(0);
1345 if (d1)
1346 d1->SetEntries(0);
1347 if (d2)
1348 d2->SetEntries(0);
1349
1350 for (int i=0; i<fEventData->Roi; i++)
1351 {
1352 //if (dynamic_cast<TH2*>(h))
1353 h->Fill(i, reinterpret_cast<float*>(fEventData->Adc_Data)[p*fEventData->Roi+i]);
1354 //else
1355 // h->SetBinContent(i+1, reinterpret_cast<float*>(fEventData->Adc_Data)[p*fEventData->Roi+i]);
1356 if (start<0)
1357 continue;
1358
1359 if (d0)
1360 {
1361 d0->SetBinContent(i+1, fDrsCalibration[1440*1024*0 + p*1024+(start+i)%1024]);
1362 d0->SetBinError(i+1, fDrsCalibration[1440*1024*1 + p*1024+(start+i)%1024]);
1363
1364 }
1365 if (d1)
1366 {
1367 d1->SetBinContent(i+1, fDrsCalibration[1440*1024*2 + p*1024+(start+i)%1024]);
1368 d1->SetBinError(i+1, fDrsCalibration[1440*1024*3 + p*1024+(start+i)%1024]);
1369 }
1370 if (d2)
1371 {
1372 d2->SetBinContent(i+1, fDrsCalibration[1440*1024*4 + p*1024 + i]);
1373 d2->SetBinError(i+1, fDrsCalibration[1440*1024*5 + p*1024 + i]);
1374 }
1375 }
1376
1377 // -----------------------------------------------------------
1378 if (fAdcDynamicScale->isEnabled() && fAdcDynamicScale->isChecked())
1379 {
1380 h->SetMinimum();
1381 h->SetMaximum();
1382
1383 hf->SetMinimum(h->GetMinimum());
1384 hf->SetMaximum(h->GetMaximum());
1385 }
1386 if (fAdcManualScale->isEnabled() && fAdcManualScale->isChecked())
1387 {
1388 if (h->GetMinimumStored()==-1111)
1389 {
1390 h->SetMinimum(-1150);//-1026);
1391 hf->SetMinimum(-1150);//-1026);
1392 }
1393 if (h->GetMaximumStored()==-1111)
1394 {
1395 h->SetMaximum(2150);//1025);
1396 hf->SetMaximum(2150);//1025);
1397 }
1398 }
1399
1400 if (fAdcAutoScale->isEnabled() && fAdcAutoScale->isChecked())
1401 {
1402 h->SetMinimum();
1403 h->SetMaximum();
1404
1405 if (h->GetMinimum()<hf->GetMinimum())
1406 hf->SetMinimum(h->GetMinimum());
1407 if (h->GetMaximum()>hf->GetMaximum())
1408 hf->SetMaximum(h->GetMaximum());
1409 }
1410
1411 if (dynamic_cast<TH2*>(h))
1412 {
1413 h->SetMinimum();
1414 h->SetMaximum();
1415 }
1416
1417 // -----------------------------------------------------------
1418
1419 const int imin = ceil(hf->GetMinimum());
1420 const int imax = floor(hf->GetMaximum());
1421
1422 TH1S hd("", "", imax-imin+1, imin-0.5, imax+0.5);
1423 hd.SetDirectory(0);
1424 TH1S h0("", "", imax-imin+1, imin-0.5, imax+0.5);
1425 h0.SetDirectory(0);
1426 TH1S h1("", "", imax-imin+1, imin-0.5, imax+0.5);
1427 h1.SetDirectory(0);
1428 TH1S h2("", "", imax-imin+1, imin-0.5, imax+0.5);
1429 h2.SetDirectory(0);
1430 hd.SetLineColor(h->GetLineColor());
1431 if (d0)
1432 h0.SetLineColor(d0->GetLineColor());
1433 if (d1)
1434 h1.SetLineColor(d1->GetLineColor());
1435 if (d2)
1436 h2.SetLineColor(d2->GetLineColor());
1437
1438 for (int i=0; i<fEventData->Roi; i++)
1439 {
1440 if (!dynamic_cast<TH2*>(h))
1441 hd.Fill(h->GetBinContent(i+1));
1442 if (d0)
1443 h0.Fill(d0->GetBinContent(i+1));
1444 if (d1)
1445 h1.Fill(d1->GetBinContent(i+1));
1446 if (d2)
1447 h2.Fill(d2->GetBinContent(i+1));
1448 }
1449
1450 double mm = hd.GetMaximum(hd.GetEntries());
1451 if (h0.GetMaximum(h0.GetEntries())>mm)
1452 mm = h0.GetMaximum();
1453 if (h1.GetMaximum(h1.GetEntries())>mm)
1454 mm = h1.GetMaximum();
1455 if (h2.GetMaximum(h2.GetEntries())>mm)
1456 mm = h2.GetMaximum();
1457
1458 TIter Next(hf->GetListOfFunctions());
1459 TObject *obj = 0;
1460 while ((obj=Next()))
1461 if (dynamic_cast<TBox*>(obj))
1462 delete hf->GetListOfFunctions()->Remove(obj);
1463
1464 const double l = h->GetBinLowEdge(h->GetXaxis()->GetLast()+1);
1465 const double m = c->GetX2();
1466
1467 const double scale = 0.9*(m-l)/mm;
1468
1469 c->cd();
1470
1471 DrawHorizontal(hf, l, h2, scale);
1472 DrawHorizontal(hf, l, h1, scale);
1473 DrawHorizontal(hf, l, h0, scale);
1474 DrawHorizontal(hf, l, hd, scale);
1475
1476 // -----------------------------------------------------------
1477
1478 c->Modified();
1479 c->Update();
1480#endif
1481 }
1482
1483 void handleFadRawData(const DimData &d)
1484 {
1485 if (d.size()==0)
1486 return;
1487
1488 if (fAdcStop->isChecked())
1489 return;
1490
1491 const EVENT &dat = d.ref<EVENT>();
1492
1493 if (d.size()<sizeof(EVENT))
1494 {
1495 cout << "Size mismatch in " << d.name << ": Found=" << d.size() << " Expected>=" << sizeof(EVENT) << endl;
1496 return;
1497 }
1498
1499 if (d.size()!=sizeof(EVENT)+dat.Roi*4*1440)
1500 {
1501 cout << "Size mismatch in " << d.name << ": Found=" << d.size() << " Expected=" << dat.Roi*4*1440+sizeof(EVENT) << " [roi=" << dat.Roi << "]" << endl;
1502 return;
1503 }
1504
1505 delete fEventData;
1506 fEventData = reinterpret_cast<EVENT*>(new char[d.size()]);
1507 memcpy(fEventData, d.ptr<void>(), d.size());
1508
1509 DisplayEventData();
1510 }
1511
1512 void handleFadEventData(const DimData &d)
1513 {
1514 if (!CheckSize(d, 4*1440*sizeof(float)))
1515 return;
1516
1517// static int cnt=0;
1518// if (cnt++%10>0)
1519// return;
1520
1521 const float *ptr = d.ptr<float>();
1522
1523// TCanvas *c = fEventCanv->GetCanvas();
1524 Camera *cam1 = fEventCanv1;//(Camera*)c->GetPad(1)->FindObject("Camera");
1525 Camera *cam2 = fEventCanv2;//(Camera*)c->GetPad(2)->FindObject("Camera");
1526 Camera *cam3 = fEventCanv3;//(Camera*)c->GetPad(3)->FindObject("Camera");
1527 Camera *cam4 = fEventCanv4;//(Camera*)c->GetPad(4)->FindObject("Camera");
1528
1529 valarray<double> arr1(1440);
1530 valarray<double> arr2(1440);
1531 valarray<double> arr3(1440);
1532 valarray<double> arr4(1440);
1533
1534 for (int i=0; i<1440; i++)
1535 {
1536 arr1[i] = ptr[0*1440+fPixelMapHW[i]];
1537 arr2[i] = ptr[1*1440+fPixelMapHW[i]];
1538 arr3[i] = ptr[2*1440+fPixelMapHW[i]];
1539 arr4[i] = ptr[3*1440+fPixelMapHW[i]];
1540 }
1541
1542 cam1->SetData(arr1);
1543 cam2->SetData(arr2);
1544 cam3->SetData(arr3);
1545 cam4->SetData(arr4);
1546
1547// c->GetPad(1)->Modified();
1548// c->GetPad(2)->Modified();
1549// c->GetPad(3)->Modified();
1550// c->GetPad(4)->Modified();
1551
1552// c->Update();
1553 }
1554
1555 vector<float> fDrsCalibration;
1556
1557 void handleFadDrsCalibration(const DimData &d)
1558 {
1559 if (d.size()==0)
1560 {
1561 fDrsCalibBaseline->setValue(0);
1562 fDrsCalibGain->setValue(0);
1563 fDrsCalibTrgOffset->setValue(0);
1564 fDrsCalibration.assign(1024*1440*6, 0);
1565 DisplayEventData();
1566 return;
1567 }
1568
1569 if (!CheckSize(d, 1024*1440*6*sizeof(float)+3*sizeof(uint32_t)))
1570 // Do WHAT?
1571 return;
1572
1573 const uint32_t *run = d.ptr<uint32_t>();
1574
1575 fDrsCalibBaseline->setValue(run[0]);
1576 fDrsCalibGain->setValue(run[1]);
1577 fDrsCalibTrgOffset->setValue(run[2]);
1578
1579 const float *dat = d.ptr<float>(sizeof(uint32_t)*3);
1580 fDrsCalibration.assign(dat, dat+1024*1440*6);
1581
1582 DisplayEventData();
1583 }
1584
1585// vector<uint8_t> fFadConnections;
1586
1587 void handleFadConnections(const DimData &d)
1588 {
1589 if (!CheckSize(d, 41))
1590 {
1591 fStatusEventBuilderLabel->setText("Offline");
1592 fStatusEventBuilderLabel->setToolTip("FADs or fadctrl seems to be offline.");
1593 fEvtBldWidget->setEnabled(false);
1594
1595 SetLedColor(fStatusEventBuilderLed, kLedGray, d.time);
1596 return;
1597 }
1598
1599 const uint8_t *ptr = d.ptr<uint8_t>();
1600
1601 for (int i=0; i<40; i++)
1602 {
1603 const uint8_t stat1 = ptr[i]&3;
1604 const uint8_t stat2 = ptr[i]>>3;
1605
1606 if (stat1==0 && stat2==0)
1607 {
1608 SetLedColor(fFadLED[i], kLedGray, d.time);
1609 continue;
1610 }
1611 if (stat1==2 && stat2==8)
1612 {
1613 SetLedColor(fFadLED[i], kLedGreen, d.time);
1614 continue;
1615 }
1616
1617 if (stat1==1 && stat2==1)
1618 SetLedColor(fFadLED[i], kLedRed, d.time);
1619 else
1620 SetLedColor(fFadLED[i], kLedOrange, d.time);
1621 }
1622
1623
1624 const bool runs = ptr[40]!=0;
1625
1626 fStatusEventBuilderLabel->setText(runs?"Running":"Not running");
1627 fStatusEventBuilderLabel->setToolTip(runs?"Event builder thread running.":"Event builder thread stopped.");
1628 fEvtBldWidget->setEnabled(runs);
1629
1630 SetLedColor(fStatusEventBuilderLed, runs?kLedGreen:kLedRed, d.time);
1631
1632// fFadConnections.assign(ptr, ptr+40);
1633 }
1634
1635 template<typename T>
1636 void handleFadToolTip(const Time &time, QWidget *w, T *ptr)
1637 {
1638 ostringstream tip;
1639 tip << "<table border='1'><tr><th colspan='11'>" << time.GetAsStr() << " (UTC)</th></tr><tr><th></th>";
1640 for (int b=0; b<10; b++)
1641 tip << "<th>" << b << "</th>";
1642 tip << "</tr>";
1643
1644 for (int c=0; c<4; c++)
1645 {
1646 tip << "<tr><th>" << c << "</th>";
1647 for (int b=0; b<10; b++)
1648 tip << "<td>" << ptr[c*10+b] << "</td>";
1649 tip << "</tr>";
1650 }
1651 tip << "</table>";
1652
1653 w->setToolTip(tip.str().c_str());
1654 }
1655
1656 template<typename T, class S>
1657 void handleFadMinMax(const DimData &d, QPushButton *led, S *wmin, S *wmax=0)
1658 {
1659 if (!CheckSize(d, 42*sizeof(T)))
1660 return;
1661
1662 const T *ptr = d.ptr<T>();
1663 const T min = ptr[40];
1664 const T max = ptr[41];
1665
1666 if (max==0 && min>max)
1667 SetLedColor(led, kLedGray, d.time);
1668 else
1669 SetLedColor(led, min==max?kLedGreen: kLedOrange, d.time);
1670
1671 if (!wmax && max!=min)
1672 wmin->setValue(0);
1673 else
1674 wmin->setValue(min);
1675
1676 if (wmax)
1677 wmax->setValue(max);
1678
1679 handleFadToolTip(d.time, led, ptr);
1680 }
1681
1682 void handleFadFwVersion(const DimData &d)
1683 {
1684 handleFadMinMax<float, QDoubleSpinBox>(d, fFadLedFwVersion, fFadFwVersion);
1685 }
1686
1687 void handleFadRunNumber(const DimData &d)
1688 {
1689 handleFadMinMax<uint32_t, QSpinBox>(d, fFadLedRunNumber, fFadRunNumber);
1690 }
1691
1692 void handleFadPrescaler(const DimData &d)
1693 {
1694 handleFadMinMax<uint16_t, QSpinBox>(d, fFadLedPrescaler, fFadPrescaler);
1695 }
1696
1697 void handleFadDNA(const DimData &d)
1698 {
1699 if (!CheckSize(d, 40*sizeof(uint64_t)))
1700 return;
1701
1702 const uint64_t *ptr = d.ptr<uint64_t>();
1703
1704 ostringstream tip;
1705 tip << "<table width='100%'>";
1706 tip << "<tr><th>Crate</th><td></td><th>Board</th><td></td><th>DNA</th></tr>";
1707
1708 for (int i=0; i<40; i++)
1709 {
1710 tip << dec;
1711 tip << "<tr>";
1712 tip << "<td align='center'>" << i/10 << "</td><td>:</td>";
1713 tip << "<td align='center'>" << i%10 << "</td><td>:</td>";
1714 tip << hex;
1715 tip << "<td>0x" << setfill('0') << setw(16) << ptr[i] << "</td>";
1716 tip << "</tr>";
1717 }
1718 tip << "</table>";
1719
1720 fFadDNA->setText(tip.str().c_str());
1721 }
1722
1723 void SetFadLed(QPushButton *led, const DimData &d, uint16_t bitmask, bool invert=false)
1724 {
1725 if (d.size()==0)
1726 {
1727 SetLedColor(led, kLedGray, d.time);
1728 return;
1729 }
1730
1731 const bool quality = d.ptr<uint16_t>()[0]&bitmask;
1732 const bool value = d.ptr<uint16_t>()[1]&bitmask;
1733 const uint16_t *ptr = d.ptr<uint16_t>()+2;
1734
1735 SetLedColor(led, quality?kLedOrange:(value^invert?kLedGreen:kLedRed), d.time);
1736
1737 ostringstream tip;
1738 tip << "<table border='1'><tr><th colspan='11'>" << d.time.GetAsStr() << " (UTC)</th></tr><tr><th></th>";
1739 for (int b=0; b<10; b++)
1740 tip << "<th>" << b << "</th>";
1741 tip << "</tr>";
1742
1743 /*
1744 tip << "<tr>" << hex;
1745 tip << "<th>" << d.ptr<uint16_t>()[0] << " " << (d.ptr<uint16_t>()[0]&bitmask) << "</th>";
1746 tip << "<th>" << d.ptr<uint16_t>()[1] << " " << (d.ptr<uint16_t>()[1]&bitmask) << "</th>";
1747 tip << "</tr>";
1748 */
1749
1750 for (int c=0; c<4; c++)
1751 {
1752 tip << "<tr><th>" << dec << c << "</th>" << hex;
1753 for (int b=0; b<10; b++)
1754 {
1755 tip << "<td>"
1756 << (ptr[c*10+b]&bitmask)
1757 << "</td>";
1758 }
1759 tip << "</tr>";
1760 }
1761 tip << "</table>";
1762
1763 led->setToolTip(tip.str().c_str());
1764 }
1765
1766 void handleFadStatus(const DimData &d)
1767 {
1768 if (d.size()!=0 && !CheckSize(d, 42*sizeof(uint16_t)))
1769 return;
1770
1771 SetFadLed(fFadLedDrsEnabled, d, FAD::EventHeader::kDenable);
1772 SetFadLed(fFadLedDrsWrite, d, FAD::EventHeader::kDwrite);
1773 SetFadLed(fFadLedDcmLocked, d, FAD::EventHeader::kDcmLocked);
1774 SetFadLed(fFadLedDcmReady, d, FAD::EventHeader::kDcmReady);
1775 SetFadLed(fFadLedSpiSclk, d, FAD::EventHeader::kSpiSclk);
1776 SetFadLed(fFadLedRefClockTooLow, d, FAD::EventHeader::kRefClkTooLow, true);
1777 SetFadLed(fFadLedBusyOn, d, FAD::EventHeader::kBusyOn);
1778 SetFadLed(fFadLedBusyOff, d, FAD::EventHeader::kBusyOff);
1779 SetFadLed(fFadLedTriggerLine, d, FAD::EventHeader::kTriggerLine);
1780 SetFadLed(fFadLedContTrigger, d, FAD::EventHeader::kContTrigger);
1781 SetFadLed(fFadLedSocket, d, FAD::EventHeader::kSock17);
1782 SetFadLed(fFadLedPllLock, d, 0xf000);
1783 }
1784
1785 void handleFadStatistics1(const DimData &d)
1786 {
1787 if (!CheckSize(d, sizeof(GUI_STAT)))
1788 return;
1789
1790 const GUI_STAT &stat = d.ref<GUI_STAT>();
1791
1792 /*
1793 //info about status of the main threads
1794 int32_t readStat ; //read thread
1795 int32_t procStat ; //processing thread(s)
1796 int32_t writStat ; //write thread
1797 */
1798
1799 fFadBufferMax->setValue(stat.totMem/1000000);
1800 fFadBuffer->setMaximum(stat.totMem/100);
1801 fFadBuffer->setValue((stat.maxMem>stat.totMem?stat.totMem:stat.maxMem)/100); // Max mem used in last second
1802
1803 uint32_t sum = 0;
1804 int32_t min = 0x7fffff;
1805 int32_t max = 0;
1806
1807 int cnt = 0;
1808 int err = 0;
1809
1810 for (int i=0; i<40; i++)
1811 {
1812 if (stat.numConn[i]!=7)
1813 continue;
1814
1815 cnt++;
1816
1817 sum += stat.rateBytes[i];
1818 err += stat.errConn[i];
1819
1820 if (stat.rateBytes[i]<min)
1821 min = stat.rateBytes[i];
1822 if (stat.rateBytes[i]>max)
1823 max = stat.rateBytes[i];
1824 }
1825
1826 fFadEvtConn->setValue(cnt);
1827 fFadEvtConnErr->setValue(err);
1828
1829 fFadEvtBufNew->setValue(stat.bufNew); // Incomplete in buffer
1830 fFadEvtBufEvt->setValue(stat.bufEvt); // Complete in buffer
1831 fFadEvtBufMax->setValue(stat.maxEvt); // Complete in buffer
1832 fFadEvtWrite->setValue(stat.evtWrite-stat.evtSkip-stat.evtErr);
1833 fFadEvtSkip->setValue(stat.evtSkip);
1834 fFadEvtErr->setValue(stat.evtErr);
1835
1836 if (stat.deltaT==0)
1837 return;
1838
1839 fFadEthernetRateMin->setValue(min/stat.deltaT);
1840 fFadEthernetRateMax->setValue(max/stat.deltaT);
1841 fFadEthernetRateTot->setValue(sum/stat.deltaT);
1842 fFadEthernetRateAvg->setValue(cnt==0 ? 0 : sum/cnt/stat.deltaT);
1843 fFadEvtRateNew->setValue(1000*stat.rateNew/stat.deltaT);
1844 fFadEvtRateWrite->setValue(1000*stat.rateWrite/stat.deltaT);
1845
1846 fFadTransmission->setValue(fFadEvtRateNew->value());
1847 fFadEthernet->setValue(fFadEthernetRateTot->value());
1848 fFadWriteRate->setValue(fFadEvtRateWrite->value());
1849 }
1850
1851 void handleFadStatistics2(const DimData &d)
1852 {
1853 if (!CheckSize(d, sizeof(EVT_STAT)))
1854 return;
1855
1856 //const EVT_STAT &stat = d.ref<EVT_STAT>();
1857
1858 /*
1859 //some info about what happened since start of program (or last 'reset')
1860 uint32_t reset ; //#if increased, reset all counters
1861 uint32_t numRead[MAX_SOCK] ; //how often succesfull read from N sockets per loop
1862
1863 uint64_t gotByte[NBOARDS] ; //#Bytes read per Board
1864 uint32_t gotErr[NBOARDS] ; //#Communication Errors per Board
1865
1866 uint32_t evtGet; //#new Start of Events read
1867 uint32_t evtTot; //#complete Events read
1868
1869 uint32_t evtErr; //#Events with Errors
1870 uint32_t evtSkp; //#Events incomplete (timeout)
1871
1872
1873 uint32_t procTot; //#Events processed
1874 uint32_t procErr; //#Events showed problem in processing
1875 uint32_t procTrg; //#Events accepted by SW trigger
1876 uint32_t procSkp; //#Events rejected by SW trigger
1877
1878 uint32_t feedTot; //#Events used for feedBack system
1879 uint32_t feedErr; //#Events rejected by feedBack
1880
1881 uint32_t wrtTot; //#Events written to disk
1882 uint32_t wrtErr; //#Events with write-error
1883
1884 uint32_t runOpen; //#Runs opened
1885 uint32_t runClose; //#Runs closed
1886 uint32_t runErr; //#Runs with open/close errors
1887
1888
1889 //info about current connection status
1890 uint8_t numConn[NBOARDS] ; //#Sockets succesfully open per board
1891 */
1892 }
1893
1894 // ===================== FTM ============================================
1895
1896 void UpdateTriggerRate(const FTM::DimTriggerRates &sdata)
1897 {
1898#ifdef HAVE_ROOT
1899 TCanvas *c = fFtmRateCanv->GetCanvas();
1900
1901 TH1 *h = (TH1*)c->FindObject("TimeFrame");
1902
1903 if (sdata.fTriggerRate<0)
1904 {
1905 fGraphFtmRate.Set(0);
1906
1907 const double tm = Time().RootTime();
1908
1909 h->SetBins(1, tm, tm+60);
1910 h->GetXaxis()->SetTimeFormat("%M'%S\"");
1911 h->GetXaxis()->SetTitle("Time");
1912
1913 c->Modified();
1914 c->Update();
1915 return;
1916 }
1917
1918 const double t1 = h->GetXaxis()->GetXmax();
1919 const double t0 = h->GetXaxis()->GetXmin();
1920
1921 const double now = t0+sdata.fTimeStamp/1000000.;
1922
1923 h->SetBins(h->GetNbinsX()+1, t0, now+1);
1924 fGraphFtmRate.SetPoint(fGraphFtmRate.GetN(), now, sdata.fTriggerRate);
1925
1926 if (t1-t0>60)
1927 {
1928 h->GetXaxis()->SetTimeFormat("%Hh%M'");
1929 h->GetXaxis()->SetTitle("Time");
1930 }
1931
1932 h->SetMinimum(0);
1933
1934 c->Modified();
1935 c->Update();
1936#endif
1937 }
1938
1939 void UpdateRatesCam(const FTM::DimTriggerRates &sdata)
1940 {
1941#ifdef HAVE_ROOT
1942 if (fThresholdIdx->value()>=0)
1943 {
1944 const int isw = fThresholdIdx->value();
1945 const int ihw = fPatchMapHW[isw];
1946 fPatchRate->setValue(sdata.fPatchRate[ihw]);
1947 }
1948
1949 valarray<double> dat(0., 1440);
1950
1951 // fPatch converts from software id to software patch id
1952 for (int i=0; i<1440; i++)
1953 {
1954 const int ihw = fPatchHW[i];
1955// const int isw = fPatch[i];
1956// const int ihw = fPatchMapHW[isw];
1957 dat[i] = sdata.fPatchRate[ihw];
1958
1959 fRatesCanv->SetEnable(ihw, fFtuStatus[ihw/4]);
1960 }
1961
1962// TCanvas *c = fRatesCanv->GetCanvas();
1963// Camera *cam = (Camera*)c->FindObject("Camera");
1964
1965 fRatesCanv->SetData(dat);
1966
1967// c->Modified();
1968// c->Update();
1969#endif
1970 }
1971
1972 int64_t fTimeStamp0;
1973
1974 void UpdateRatesGraphs(const FTM::DimTriggerRates &sdata)
1975 {
1976#ifdef HAVE_ROOT
1977 if (fTimeStamp0<0)
1978 {
1979 fTimeStamp0 = sdata.fTimeStamp;
1980 return;
1981 }
1982
1983 TCanvas *c = fFtmRateCanv->GetCanvas();
1984
1985 TH1 *h = (TH1*)c->FindObject("TimeFrame");
1986
1987 const double tdiff = sdata.fTimeStamp-fTimeStamp0;
1988 fTimeStamp0 = sdata.fTimeStamp;
1989
1990 if (tdiff<0)
1991 {
1992 for (int i=0; i<160; i++)
1993 fGraphPatchRate[i].Set(0);
1994 for (int i=0; i<40; i++)
1995 fGraphBoardRate[i].Set(0);
1996
1997 return;
1998 }
1999
2000 //const double t1 = h->GetXaxis()->GetXmax();
2001 const double t0 = h->GetXaxis()->GetXmin();
2002
2003 for (int i=0; i<160; i++)
2004 if (fFtuStatus[i/4]>0)
2005 fGraphPatchRate[i].SetPoint(fGraphPatchRate[i].GetN(),
2006 t0+sdata.fTimeStamp/1000000., sdata.fPatchRate[i]);
2007 for (int i=0; i<40; i++)
2008 if (fFtuStatus[i]>0)
2009 fGraphBoardRate[i].SetPoint(fGraphBoardRate[i].GetN(),
2010 t0+sdata.fTimeStamp/1000000., sdata.fBoardRate[i]);
2011
2012 c->Modified();
2013 c->Update();
2014#endif
2015 }
2016
2017 void handleFtmTriggerRates(const DimData &d)
2018 {
2019 if (!CheckSize(d, sizeof(FTM::DimTriggerRates)))
2020 return;
2021
2022 const FTM::DimTriggerRates &sdata = d.ref<FTM::DimTriggerRates>();
2023
2024 fFtmTime->setText(QString::number(sdata.fTimeStamp/1000000., 'f', 6)+ " s");
2025 fTriggerCounter->setText(QString::number(sdata.fTriggerCounter));
2026
2027 if (sdata.fTimeStamp>0)
2028 fTriggerCounterRate->setValue(1000000.*sdata.fTriggerCounter/sdata.fTimeStamp);
2029 else
2030 fTriggerCounterRate->setValue(0);
2031
2032 // ----------------------------------------------
2033
2034 fOnTime->setText(QString::number(sdata.fOnTimeCounter/1000000., 'f', 6)+" s");
2035
2036 if (sdata.fTimeStamp>0)
2037 fOnTimeRel->setValue(100.*sdata.fOnTimeCounter/sdata.fTimeStamp);
2038 else
2039 fOnTimeRel->setValue(0);
2040
2041 // ----------------------------------------------
2042
2043 UpdateTriggerRate(sdata);
2044 UpdateRatesGraphs(sdata);
2045 UpdateRatesCam(sdata);
2046 }
2047
2048 void handleFtmCounter(const DimData &d)
2049 {
2050 if (!CheckSize(d, sizeof(uint32_t)*6))
2051 return;
2052
2053 const uint32_t *sdata = d.ptr<uint32_t>();
2054
2055 fFtmCounterH->setValue(sdata[0]);
2056 fFtmCounterS->setValue(sdata[1]);
2057 fFtmCounterD->setValue(sdata[2]);
2058 fFtmCounterF->setValue(sdata[3]);
2059 fFtmCounterE->setValue(sdata[4]);
2060 fFtmCounterR->setValue(sdata[5]);
2061 }
2062
2063 void handleFtmDynamicData(const DimData &d)
2064 {
2065 if (!CheckSize(d, sizeof(FTM::DimDynamicData)))
2066 return;
2067
2068 const FTM::DimDynamicData &sdata = d.ref<FTM::DimDynamicData>();
2069
2070 fFtmTemp0->setValue(sdata.fTempSensor[0]*0.1);
2071 fFtmTemp1->setValue(sdata.fTempSensor[1]*0.1);
2072 fFtmTemp2->setValue(sdata.fTempSensor[2]*0.1);
2073 fFtmTemp3->setValue(sdata.fTempSensor[3]*0.1);
2074
2075 SetLedColor(fClockCondLed, sdata.fState&FTM::kFtmLocked ? kLedGreen : kLedRed, d.time);
2076 }
2077
2078 void DisplayRates()
2079 {
2080#ifdef HAVE_ROOT
2081 TCanvas *c = fFtmRateCanv->GetCanvas();
2082
2083 while (c->FindObject("PatchRate"))
2084 c->GetListOfPrimitives()->Remove(c->FindObject("PatchRate"));
2085
2086 while (c->FindObject("BoardRate"))
2087 c->GetListOfPrimitives()->Remove(c->FindObject("BoardRate"));
2088
2089 c->cd();
2090
2091 if (fRatePatch1->value()>=0)
2092 {
2093 fGraphPatchRate[fRatePatch1->value()].SetLineColor(kRed);
2094 fGraphPatchRate[fRatePatch1->value()].SetMarkerColor(kRed);
2095 fGraphPatchRate[fRatePatch1->value()].Draw("PL");
2096 }
2097 if (fRatePatch2->value()>=0)
2098 {
2099 fGraphPatchRate[fRatePatch2->value()].SetLineColor(kGreen);
2100 fGraphPatchRate[fRatePatch2->value()].SetMarkerColor(kGreen);
2101 fGraphPatchRate[fRatePatch2->value()].Draw("PL");
2102 }
2103 if (fRateBoard1->value()>=0)
2104 {
2105 fGraphBoardRate[fRateBoard1->value()].SetLineColor(kMagenta);
2106 fGraphBoardRate[fRateBoard1->value()].SetMarkerColor(kMagenta);
2107 fGraphBoardRate[fRateBoard1->value()].Draw("PL");
2108 }
2109 if (fRateBoard2->value()>=0)
2110 {
2111 fGraphBoardRate[fRateBoard2->value()].SetLineColor(kCyan);
2112 fGraphBoardRate[fRateBoard2->value()].SetMarkerColor(kCyan);
2113 fGraphBoardRate[fRateBoard2->value()].Draw("PL");
2114 }
2115#endif
2116 }
2117
2118 void on_fRatePatch1_valueChanged(int)
2119 {
2120 DisplayRates();
2121 }
2122
2123 void on_fRatePatch2_valueChanged(int)
2124 {
2125 DisplayRates();
2126 }
2127
2128 void on_fRateBoard1_valueChanged(int)
2129 {
2130 DisplayRates();
2131 }
2132
2133 void on_fRateBoard2_valueChanged(int)
2134 {
2135 DisplayRates();
2136 }
2137
2138 FTM::DimStaticData fFtmStaticData;
2139
2140 void SetFtuLed(int idx, int counter, const Time &t)
2141 {
2142 if (counter==0 || counter>3)
2143 counter = 3;
2144
2145 if (counter<0)
2146 counter = 0;
2147
2148 const LedColor_t col[4] = { kLedGray, kLedGreen, kLedOrange, kLedRed };
2149
2150 SetLedColor(fFtuLED[idx], col[counter], t);
2151
2152 fFtuStatus[idx] = counter;
2153 }
2154
2155 void SetFtuStatusLed(const Time &t)
2156 {
2157 const int max = fFtuStatus.max();
2158
2159 switch (max)
2160 {
2161 case 0:
2162 SetLedColor(fStatusFTULed, kLedGray, t);
2163 fStatusFTULabel->setText("All disabled");
2164 fStatusFTULabel->setToolTip("All FTUs are disabled");
2165 break;
2166
2167 case 1:
2168 SetLedColor(fStatusFTULed, kLedGreen, t);
2169 fStatusFTULabel->setToolTip("Communication with FTU is smooth.");
2170 fStatusFTULabel->setText("ok");
2171 break;
2172
2173 case 2:
2174 SetLedColor(fStatusFTULed, kLedOrange, t);
2175 fStatusFTULabel->setText("Warning");
2176 fStatusFTULabel->setToolTip("At least one FTU didn't answer immediately");
2177 break;
2178
2179 case 3:
2180 SetLedColor(fStatusFTULed, kLedRed, t);
2181 fStatusFTULabel->setToolTip("At least one FTU didn't answer!");
2182 fStatusFTULabel->setText("ERROR");
2183 break;
2184 }
2185
2186 const int cnt = count(&fFtuStatus[0], &fFtuStatus[40], 0);
2187 fFtuAllOn->setEnabled(cnt!=0);
2188 fFtuAllOff->setEnabled(cnt!=40);
2189 }
2190
2191 void handleFtmStaticData(const DimData &d)
2192 {
2193 if (!CheckSize(d, sizeof(FTM::DimStaticData)))
2194 return;
2195
2196 const FTM::DimStaticData &sdata = d.ref<FTM::DimStaticData>();
2197
2198 fTriggerInterval->setValue(sdata.fTriggerInterval);
2199 fPhysicsCoincidence->setValue(sdata.fMultiplicityPhysics);
2200 fCalibCoincidence->setValue(sdata.fMultiplicityCalib);
2201 fPhysicsWindow->setValue(sdata.fWindowPhysics);
2202 fCalibWindow->setValue(sdata.fWindowCalib);
2203
2204 fTriggerDelay->setValue(sdata.fDelayTrigger);
2205 fTimeMarkerDelay->setValue(sdata.fDelayTimeMarker);
2206 fDeadTime->setValue(sdata.fDeadTime);
2207
2208 fClockCondR0->setValue(sdata.fClockConditioner[0]);
2209 fClockCondR1->setValue(sdata.fClockConditioner[1]);
2210 fClockCondR8->setValue(sdata.fClockConditioner[2]);
2211 fClockCondR9->setValue(sdata.fClockConditioner[3]);
2212 fClockCondR11->setValue(sdata.fClockConditioner[4]);
2213 fClockCondR13->setValue(sdata.fClockConditioner[5]);
2214 fClockCondR14->setValue(sdata.fClockConditioner[6]);
2215 fClockCondR15->setValue(sdata.fClockConditioner[7]);
2216
2217 const uint32_t R0 = sdata.fClockConditioner[0];
2218 const uint32_t R14 = sdata.fClockConditioner[6];
2219 const uint32_t R15 = sdata.fClockConditioner[7];
2220
2221 const uint32_t Ndiv = (R15&0x1ffff00)<<2;
2222 const uint32_t Rdiv = (R14&0x007ff00)>>8;
2223 const uint32_t Cdiv = (R0 &0x000ff00)>>8;
2224
2225 double freq = 40.*Ndiv/(Rdiv*Cdiv);
2226
2227 fClockCondFreqRes->setValue(freq);
2228
2229 //fClockCondFreq->setEditText("");
2230 fClockCondFreq->setCurrentIndex(0);
2231
2232 fTriggerSeqPed->setValue(sdata.fTriggerSeqPed);
2233 fTriggerSeqLPint->setValue(sdata.fTriggerSeqLPint);
2234 fTriggerSeqLPext->setValue(sdata.fTriggerSeqLPext);
2235
2236 fLpIntIntensity->setValue(sdata.fIntensityLPint);
2237 fLpExtIntensity->setValue(sdata.fIntensityLPext);
2238
2239 fLpIntGroup1->setChecked(sdata.HasLPintG1());
2240 fLpIntGroup2->setChecked(sdata.HasLPintG2());
2241 fLpExtGroup1->setChecked(sdata.HasLPextG1());
2242 fLpExtGroup2->setChecked(sdata.HasLPextG2());
2243
2244 fEnableTrigger->setChecked(sdata.HasTrigger());
2245 fEnableVeto->setChecked(sdata.HasVeto());
2246 fEnableExt1->setChecked(sdata.HasExt1());
2247 fEnableExt2->setChecked(sdata.HasExt2());
2248 fEnableClockCond->setChecked(sdata.HasClockConditioner());
2249
2250 for (int i=0; i<40; i++)
2251 {
2252 if (!sdata.IsActive(i))
2253 SetFtuLed(i, -1, d.time);
2254 else
2255 {
2256 if (fFtuStatus[i]==0)
2257 SetFtuLed(i, 1, d.time);
2258 }
2259 fFtuLED[i]->setChecked(false);
2260 }
2261 SetFtuStatusLed(d.time);
2262
2263
2264
2265 for (int isw=0; isw<1440; isw++)
2266 {
2267 const int ihw = fPixelMapHW[isw];
2268 fRatesCanv->SetEnable(isw, sdata.IsEnabled(ihw));
2269 }
2270
2271 {
2272 const int isw = fPixelIdx->value();
2273 const int ihw = fPixelMapHW[isw];
2274 const bool on = sdata.IsEnabled(ihw);
2275 fPixelEnable->setChecked(on);
2276 }
2277
2278 if (fThresholdIdx->value()>=0)
2279 {
2280 const int isw = fThresholdIdx->value();
2281 const int ihw = fPatchMapHW[isw];
2282 fThresholdVal->setValue(sdata.fThreshold[ihw]);
2283 }
2284
2285 fPrescalingVal->setValue(sdata.fPrescaling[0]);
2286
2287 fFtmStaticData = sdata;
2288 }
2289
2290 void handleFtmPassport(const DimData &d)
2291 {
2292 if (!CheckSize(d, sizeof(FTM::DimPassport)))
2293 return;
2294
2295 const FTM::DimPassport &sdata = d.ref<FTM::DimPassport>();
2296
2297 stringstream str1, str2;
2298 str1 << hex << "0x" << setfill('0') << setw(16) << sdata.fBoardId;
2299 str2 << sdata.fFirmwareId;
2300
2301 fFtmBoardId->setText(str1.str().c_str());
2302 fFtmFirmwareId->setText(str2.str().c_str());
2303 }
2304
2305 void handleFtmFtuList(const DimData &d)
2306 {
2307 if (!CheckSize(d, sizeof(FTM::DimFtuList)))
2308 return;
2309
2310 fFtuPing->setChecked(false);
2311
2312 const FTM::DimFtuList &sdata = d.ref<FTM::DimFtuList>();
2313
2314 stringstream str;
2315 str << "<table width='100%'>" << setfill('0');
2316 str << "<tr><th>Num</th><th></th><th>Addr</th><th></th><th>DNA</th></tr>";
2317 for (int i=0; i<40; i++)
2318 {
2319 str << "<tr>";
2320 str << "<td align='center'>" << dec << i << hex << "</td>";
2321 str << "<td align='center'>:</td>";
2322 str << "<td align='center'>0x" << setw(2) << (int)sdata.fAddr[i] << "</td>";
2323 str << "<td align='center'>:</td>";
2324 str << "<td align='center'>0x" << setw(16) << sdata.fDNA[i] << "</td>";
2325 str << "</tr>";
2326 }
2327 str << "</table>";
2328
2329 fFtuDNA->setText(str.str().c_str());
2330
2331 fFtuAnswersTotal->setValue(sdata.fNumBoards);
2332 fFtuAnswersCrate0->setValue(sdata.fNumBoardsCrate[0]);
2333 fFtuAnswersCrate1->setValue(sdata.fNumBoardsCrate[1]);
2334 fFtuAnswersCrate2->setValue(sdata.fNumBoardsCrate[2]);
2335 fFtuAnswersCrate3->setValue(sdata.fNumBoardsCrate[3]);
2336
2337 for (int i=0; i<40; i++)
2338 SetFtuLed(i, sdata.IsActive(i) ? sdata.fPing[i] : -1, d.time);
2339
2340 SetFtuStatusLed(d.time);
2341 }
2342
2343 void handleFtmError(const DimData &d)
2344 {
2345 if (!CheckSize(d, sizeof(FTM::DimError)))
2346 return;
2347
2348 const FTM::DimError &sdata = d.ref<FTM::DimError>();
2349
2350 SetFtuLed(sdata.fError.fDestAddress, sdata.fError.fNumCalls, d.time);
2351 SetFtuStatusLed(d.time);
2352
2353 // FIXME: Write to special window!
2354 //Out() << "Error:" << endl;
2355 //Out() << sdata.fError << endl;
2356 }
2357
2358 // ========================== FSC =======================================
2359
2360 void SetFscValue(QDoubleSpinBox *box, const DimData &d, int idx, bool enable)
2361 {
2362 box->setEnabled(enable);
2363 if (!enable)
2364 {
2365 box->setToolTip(d.time.GetAsStr().c_str());
2366 return;
2367 }
2368
2369 ostringstream str;
2370 str << d.time << " -- " << d.get<float>() << "s";
2371
2372 box->setToolTip(str.str().c_str());
2373 box->setValue(d.get<float>(idx*4+4));
2374 }
2375
2376
2377 void handleFscTemp(const DimData &d)
2378 {
2379 const bool enable = d.size()>0 && CheckSize(d, 60*sizeof(float));
2380
2381 QDoubleSpinBox *boxes[] = {
2382 fTempCam00, fTempCam01,
2383 fTempCam10, fTempCam11, fTempCam12, fTempCam13, fTempCam14,
2384 fTempCam20, fTempCam21, fTempCam22, fTempCam23, fTempCam24, fTempCam25,
2385 fTempCam30, fTempCam31, fTempCam32, fTempCam33, fTempCam34,
2386 fTempCam40, fTempCam41, fTempCam42, fTempCam43, fTempCam44, fTempCam45,
2387 fTempCam50, fTempCam51, fTempCam52, fTempCam53, fTempCam54,
2388 fTempCam60, fTempCam61,
2389 fTempCrate00, fTempCrate01, fTempCrate10, fTempCrate11,
2390 fTempCrate20, fTempCrate21, fTempCrate30, fTempCrate31,
2391 fTempPS00, fTempPS01, fTempPS10, fTempPS11,
2392 fTempPS20, fTempPS21, fTempPS30, fTempPS31,
2393 fTempAux0a, fTempAux0b, fTempAux1a, fTempAux1b,
2394 fTempBackpanel0a, fTempBackpanel0b, fTempBackpanel1a, fTempBackpanel1b,
2395 fTempSwitchbox0a, fTempSwitchbox0b, fTempSwitchbox1a, fTempSwitchbox1b,
2396 };
2397
2398 for (int i=0; i<59; i++)
2399 SetFscValue(boxes[i], d, i, enable);
2400 }
2401
2402 void handleFscVolt(const DimData &d)
2403 {
2404 const bool enable = d.size()>0 && CheckSize(d, 31*sizeof(float));
2405
2406 QDoubleSpinBox *boxes[] = {
2407 fVoltFad00, fVoltFad10, fVoltFad20, fVoltFad30,
2408 fVoltFad01, fVoltFad11, fVoltFad21, fVoltFad31,
2409 fVoltFad02, fVoltFad12, fVoltFad22, fVoltFad32,
2410 fVoltFPA00, fVoltFPA10, fVoltFPA20, fVoltFPA30,
2411 fVoltFPA01, fVoltFPA11, fVoltFPA21, fVoltFPA31,
2412 fVoltFPA02, fVoltFPA12, fVoltFPA22, fVoltFPA32,
2413 fVoltETH0, fVoltETH1,
2414 fVoltFTM0, fVoltFTM1,
2415 fVoltFFC, fVoltFLP,
2416 };
2417
2418 for (int i=0; i<30; i++)
2419 SetFscValue(boxes[i], d, i, enable);
2420 }
2421
2422 void handleFscCurrent(const DimData &d)
2423 {
2424 const bool enable = d.size()>0 && CheckSize(d, 31*sizeof(float));
2425
2426 QDoubleSpinBox *boxes[] = {
2427 fAmpFad00, fAmpFad10, fAmpFad20, fAmpFad30,
2428 fAmpFad01, fAmpFad11, fAmpFad21, fAmpFad31,
2429 fAmpFad02, fAmpFad12, fAmpFad22, fAmpFad32,
2430 fAmpFPA00, fAmpFPA10, fAmpFPA20, fAmpFPA30,
2431 fAmpFPA01, fAmpFPA11, fAmpFPA21, fAmpFPA31,
2432 fAmpFPA02, fAmpFPA12, fAmpFPA22, fAmpFPA32,
2433 fAmpETH0, fAmpETH1,
2434 fAmpFTM0, fAmpFTM1,
2435 fAmpFFC, fAmpFLP,
2436 };
2437
2438 for (int i=0; i<30; i++)
2439 SetFscValue(boxes[i], d, i, enable);
2440 }
2441
2442 void handleFscHumidity(const DimData &d)
2443 {
2444 const bool enable = d.size()>0 && CheckSize(d, 5*sizeof(float));
2445
2446 SetFscValue(fHumidity1, d, 0, enable);
2447 SetFscValue(fHumidity2, d, 1, enable);
2448 SetFscValue(fHumidity3, d, 2, enable);
2449 SetFscValue(fHumidity4, d, 3, enable);
2450 }
2451
2452 // ========================== FSC =======================================
2453
2454 vector<int16_t> fVecBias;
2455
2456 void handleBiasVolt(const DimData &d)
2457 {
2458 if (!CheckSize(d, 416*sizeof(int16_t)))
2459 return;
2460
2461 const int16_t *ptr = d.ptr<int16_t>();
2462
2463 fVecBias.assign(ptr, ptr+416);
2464 // FIXME: Update displayed value
2465 }
2466
2467 void handleBiasCurrent(const DimData &d)
2468 {
2469 if (!CheckSize(d, 416*sizeof(int16_t)))
2470 return;
2471
2472 const int16_t *ptr = d.ptr<int16_t>();
2473
2474 valarray<double> dat(0., 1440);
2475
2476 // fPatch converts from software id to software patch id
2477 for (int i=0; i<1440; i++)
2478 {
2479 const int ihw = fPatchHW[i];
2480
2481 // FIXME: Display Overcurrent
2482 dat[i] = abs(ptr[ihw])*5000./4096;
2483
2484 fBiasCam->SetEnable(i, uint16_t(ptr[ihw])!=0x8000);
2485 }
2486
2487 fBiasCam->SetData(dat);
2488 }
2489
2490 // ====================== MessageImp ====================================
2491
2492 bool fChatOnline;
2493
2494 void handleStateChanged(const Time &time, const std::string &server,
2495 const State &s)
2496 {
2497 // FIXME: Prefix tooltip with time
2498 if (server=="FTM_CONTROL")
2499 {
2500 // FIXME: Enable FTU page!!!
2501 fStatusFTMLabel->setText(s.name.c_str());
2502 fStatusFTMLabel->setToolTip(s.comment.c_str());
2503
2504 bool enable = false;
2505
2506 if (s.index<FTM::StateMachine::kDisconnected) // No Dim connection
2507 SetLedColor(fStatusFTMLed, kLedGray, time);
2508 if (s.index==FTM::StateMachine::kDisconnected) // Dim connection / FTM disconnected
2509 SetLedColor(fStatusFTMLed, kLedYellow, time);
2510 if (s.index==FTM::StateMachine::kConnected ||
2511 s.index==FTM::StateMachine::kIdle ||
2512 s.index==FTM::StateMachine::kConfiguring1 ||
2513 s.index==FTM::StateMachine::kConfiguring2 ||
2514 s.index==FTM::StateMachine::kConfigured ||
2515 s.index==FTM::StateMachine::kTakingData) // Dim connection / FTM connected
2516 SetLedColor(fStatusFTMLed, kLedGreen, time);
2517
2518 if (s.index==FTM::StateMachine::kConnected ||
2519 s.index==FTM::StateMachine::kIdle) // Dim connection / FTM connected
2520 enable = true;
2521
2522 fTriggerWidget->setEnabled(enable);
2523 fFtuGroupEnable->setEnabled(enable);
2524 fRatesControls->setEnabled(enable);
2525 fFtuWidget->setEnabled(s.index>FTM::StateMachine::kDisconnected);
2526
2527 if (s.index>=FTM::StateMachine::kConnected)
2528 SetFtuStatusLed(time);
2529 else
2530 {
2531 SetLedColor(fStatusFTULed, kLedGray, time);
2532 fStatusFTULabel->setText("Offline");
2533 fStatusFTULabel->setToolTip("FTM is not online.");
2534 }
2535 }
2536
2537 if (server=="FAD_CONTROL")
2538 {
2539 fStatusFADLabel->setText(s.name.c_str());
2540 fStatusFADLabel->setToolTip(s.comment.c_str());
2541
2542 bool enable = false;
2543
2544 if (s.index<FAD::kOffline) // No Dim connection
2545 {
2546 SetLedColor(fStatusFADLed, kLedGray, time);
2547
2548 // Timing problem - sometimes they stay gray :(
2549 //for (int i=0; i<40; i++)
2550 // SetLedColor(fFadLED[i], kLedGray, time);
2551
2552 /*
2553 fStatusEventBuilderLabel->setText("Offline");
2554 fStatusEventBuilderLabel->setToolTip("No connection to fadctrl.");
2555 fEvtBldWidget->setEnabled(false);
2556
2557 SetLedColor(fStatusEventBuilderLed, kLedGray, time);
2558 */
2559 }
2560 if (s.index==FAD::kOffline) // Dim connection / FTM disconnected
2561 SetLedColor(fStatusFADLed, kLedRed, time);
2562 if (s.index==FAD::kDisconnected) // Dim connection / FTM disconnected
2563 SetLedColor(fStatusFADLed, kLedOrange, time);
2564 if (s.index==FAD::kConnecting) // Dim connection / FTM disconnected
2565 {
2566 SetLedColor(fStatusFADLed, kLedYellow, time);
2567 // FIXME FIXME FIXME: The LEDs are not displayed when disabled!
2568 enable = true;
2569 }
2570 if (s.index>=FAD::kConnected) // Dim connection / FTM connected
2571 {
2572 SetLedColor(fStatusFADLed, kLedGreen, time);
2573 enable = true;
2574 }
2575
2576 fFadWidget->setEnabled(enable);
2577 }
2578
2579 if (server=="FSC_CONTROL")
2580 {
2581 fStatusFSCLabel->setText(s.name.c_str());
2582 fStatusFSCLabel->setToolTip(s.comment.c_str());
2583
2584 bool enable = false;
2585
2586 if (s.index<1) // No Dim connection
2587 SetLedColor(fStatusFSCLed, kLedGray, time);
2588 if (s.index==1) // Dim connection / FTM disconnected
2589 SetLedColor(fStatusFSCLed, kLedRed, time);
2590 if (s.index>=2) // Dim connection / FTM disconnected
2591 {
2592 SetLedColor(fStatusFSCLed, kLedGreen, time);
2593 enable = true;
2594 }
2595
2596 //fFscWidget->setEnabled(enable);
2597 }
2598
2599 if (server=="DATA_LOGGER")
2600 {
2601 fStatusLoggerLabel->setText(s.name.c_str());
2602 fStatusLoggerLabel->setToolTip(s.comment.c_str());
2603
2604 bool enable = true;
2605
2606 if (s.index<=30) // Ready/Waiting
2607 SetLedColor(fStatusLoggerLed, kLedYellow, time);
2608 if (s.index<-1) // Offline
2609 {
2610 SetLedColor(fStatusLoggerLed, kLedGray, time);
2611 enable = false;
2612 }
2613 if (s.index>=0x100) // Error
2614 SetLedColor(fStatusLoggerLed, kLedRed, time);
2615 if (s.index==40) // Logging
2616 SetLedColor(fStatusLoggerLed, kLedGreen, time);
2617
2618 fLoggerWidget->setEnabled(enable);
2619 }
2620
2621 if (server=="CHAT")
2622 {
2623 fStatusChatLabel->setText(s.name.c_str());
2624
2625 fChatOnline = s.index==0;
2626
2627 SetLedColor(fStatusChatLed, fChatOnline ? kLedGreen : kLedGray, time);
2628
2629 fChatSend->setEnabled(fChatOnline);
2630 fChatMessage->setEnabled(fChatOnline);
2631 }
2632
2633 if (server=="SCHEDULER")
2634 {
2635 fStatusSchedulerLabel->setText(s.name.c_str());
2636
2637 SetLedColor(fStatusSchedulerLed, s.index>=0 ? kLedGreen : kLedRed, time);
2638 }
2639 }
2640
2641 void on_fTabWidget_currentChanged(int which)
2642 {
2643 if (fTabWidget->tabText(which)=="Chat")
2644 fTabWidget->setTabIcon(which, QIcon());
2645 }
2646
2647 void handleWrite(const Time &time, const string &text, int qos)
2648 {
2649 stringstream out;
2650
2651 if (text.substr(0, 6)=="CHAT: ")
2652 {
2653 if (qos==MessageImp::kDebug)
2654 return;
2655
2656 out << "<font size='-1' color='navy'>[<B>";
2657 out << time.GetAsStr("%H:%M:%S");
2658 out << "</B>]</FONT> " << text.substr(6);
2659 fChatText->append(out.str().c_str());
2660
2661 if (fTabWidget->tabText(fTabWidget->currentIndex())=="Chat")
2662 return;
2663
2664 static int num = 0;
2665 if (num++<2)
2666 return;
2667
2668 for (int i=0; i<fTabWidget->count(); i++)
2669 if (fTabWidget->tabText(i)=="Chat")
2670 {
2671 fTabWidget->setTabIcon(i, QIcon(":/Resources/icons/warning 3.png"));
2672 break;
2673 }
2674
2675 return;
2676 }
2677
2678
2679 out << "<font style='font-family:monospace' color='";
2680
2681 switch (qos)
2682 {
2683 case kMessage: out << "black"; break;
2684 case kInfo: out << "green"; break;
2685 case kWarn: out << "#FF6600"; break;
2686 case kError: out << "maroon"; break;
2687 case kFatal: out << "maroon"; break;
2688 case kDebug: out << "navy"; break;
2689 default: out << "navy"; break;
2690 }
2691 out << "'>";
2692 out << time.GetAsStr("%H:%M:%S.%f").substr(0,12);
2693 out << " - " << text << "</font>";
2694
2695 fLogText->append(out.str().c_str());
2696
2697 if (qos>=kWarn && qos!=kDebug)
2698 fTextEdit->append(out.str().c_str());
2699 }
2700
2701 void IndicateStateChange(const Time &time, const std::string &server)
2702 {
2703 const State s = GetState(server, GetCurrentState(server));
2704
2705 QApplication::postEvent(this,
2706 new FunctionEvent(boost::bind(&FactGui::handleStateChanged, this, time, server, s)));
2707 }
2708
2709 int Write(const Time &time, const string &txt, int qos)
2710 {
2711 QApplication::postEvent(this,
2712 new FunctionEvent(boost::bind(&FactGui::handleWrite, this, time, txt, qos)));
2713
2714 return 0;
2715 }
2716
2717 // ====================== Dim infoHandler================================
2718
2719 void handleDimService(const string &txt)
2720 {
2721 fDimSvcText->append(txt.c_str());
2722 }
2723
2724 void infoHandlerService(DimInfo &info)
2725 {
2726 const string fmt = string(info.getFormat()).empty() ? "C" : info.getFormat();
2727
2728 stringstream dummy;
2729 const Converter conv(dummy, fmt, false);
2730
2731 const Time tm(info.getTimestamp(), info.getTimestampMillisecs()*1000);
2732
2733 stringstream out;
2734 out << "<font size'-1' color='navy'>[";
2735 out << tm.GetAsStr("%H:%M:%S.%f").substr(0,12);
2736 out << "]</font> <B>" << info.getName() << "</B> - ";
2737
2738 bool iserr = true;
2739 if (!conv)
2740 {
2741 out << "Compilation of format string '" << fmt << "' failed!";
2742 }
2743 else
2744 {
2745 try
2746 {
2747 const string dat = conv.GetString(info.getData(), info.getSize());
2748 out << dat;
2749 iserr = false;
2750 }
2751 catch (const runtime_error &e)
2752 {
2753 out << "Conversion to string failed!<pre>" << e.what() << "</pre>";
2754 }
2755 }
2756
2757 // srand(hash<string>()(string(info.getName())));
2758 // int bg = rand()&0xffffff;
2759
2760 int bg = hash<string>()(string(info.getName()));
2761
2762 // allow only light colors
2763 bg = ~(bg&0x1f1f1f)&0xffffff;
2764
2765 if (iserr)
2766 bg = 0xffffff;
2767
2768 stringstream bgcol;
2769 bgcol << hex << setfill('0') << setw(6) << bg;
2770
2771 const string col = iserr ? "red" : "black";
2772 const string str = "<table width='100%' bgcolor=#"+bgcol.str()+"><tr><td><font color='"+col+"'>"+out.str()+"</font></td></tr></table>";
2773
2774 QApplication::postEvent(this,
2775 new FunctionEvent(boost::bind(&FactGui::handleDimService, this, str)));
2776 }
2777
2778 void CallInfoHandler(void (FactGui::*handler)(const DimData&), const DimData &d)
2779 {
2780 fInHandler = true;
2781 (this->*handler)(d);
2782 fInHandler = false;
2783 }
2784
2785 /*
2786 void CallInfoHandler(const boost::function<void()> &func)
2787 {
2788 // This ensures that newly received values are not sent back to the emitter
2789 // because changing the value emits the valueChanged signal (or similar)
2790 fInHandler = true;
2791 func();
2792 fInHandler = false;
2793 }*/
2794
2795 void PostInfoHandler(void (FactGui::*handler)(const DimData&))
2796 {
2797 //const boost::function<void()> f = boost::bind(handler, this, DimData(getInfo()));
2798
2799 FunctionEvent *evt = new FunctionEvent(boost::bind(&FactGui::CallInfoHandler, this, handler, DimData(getInfo())));
2800 // FunctionEvent *evt = new FunctionEvent(boost::bind(&FactGui::CallInfoHandler, this, f));
2801 // FunctionEvent *evt = new FunctionEvent(boost::bind(handler, this, DimData(getInfo()))));
2802
2803 QApplication::postEvent(this, evt);
2804 }
2805
2806 void infoHandler()
2807 {
2808 // Initialize the time-stamp (what a weird workaround...)
2809 if (getInfo())
2810 getInfo()->getTimestamp();
2811
2812 if (getInfo()==&fDimDNS)
2813 return PostInfoHandler(&FactGui::handleDimDNS);
2814#ifdef DEBUG_DIM
2815 cout << "HandleDimInfo " << getInfo()->getName() << endl;
2816#endif
2817 if (getInfo()==&fDimLoggerStats)
2818 return PostInfoHandler(&FactGui::handleLoggerStats);
2819
2820// if (getInfo()==&fDimFadFiles)
2821// return PostInfoHandler(&FactGui::handleFadFiles);
2822
2823 if (getInfo()==&fDimFadWriteStats)
2824 return PostInfoHandler(&FactGui::handleFadWriteStats);
2825
2826 if (getInfo()==&fDimFadConnections)
2827 return PostInfoHandler(&FactGui::handleFadConnections);
2828
2829 if (getInfo()==&fDimFadFwVersion)
2830 return PostInfoHandler(&FactGui::handleFadFwVersion);
2831
2832 if (getInfo()==&fDimFadRunNumber)
2833 return PostInfoHandler(&FactGui::handleFadRunNumber);
2834
2835 if (getInfo()==&fDimFadDNA)
2836 return PostInfoHandler(&FactGui::handleFadDNA);
2837
2838 if (getInfo()==&fDimFadTemperature)
2839 return PostInfoHandler(&FactGui::handleFadTemperature);
2840
2841 if (getInfo()==&fDimFadRefClock)
2842 return PostInfoHandler(&FactGui::handleFadRefClock);
2843
2844 if (getInfo()==&fDimFadRoi)
2845 return PostInfoHandler(&FactGui::handleFadRoi);
2846
2847 if (getInfo()==&fDimFadDac)
2848 return PostInfoHandler(&FactGui::handleFadDac);
2849
2850 if (getInfo()==&fDimFadDrsCalibration)
2851 return PostInfoHandler(&FactGui::handleFadDrsCalibration);
2852
2853 if (getInfo()==&fDimFadPrescaler)
2854 return PostInfoHandler(&FactGui::handleFadPrescaler);
2855
2856 if (getInfo()==&fDimFadStatus)
2857 return PostInfoHandler(&FactGui::handleFadStatus);
2858
2859 if (getInfo()==&fDimFadStatistics1)
2860 return PostInfoHandler(&FactGui::handleFadStatistics1);
2861
2862 if (getInfo()==&fDimFadStatistics2)
2863 return PostInfoHandler(&FactGui::handleFadStatistics2);
2864
2865 if (getInfo()==&fDimFadEvents)
2866 return PostInfoHandler(&FactGui::handleFadEvents);
2867
2868 if (getInfo()==&fDimFadRuns)
2869 return PostInfoHandler(&FactGui::handleFadRuns);
2870
2871 if (getInfo()==&fDimFadStartRun)
2872 return PostInfoHandler(&FactGui::handleFadStartRun);
2873
2874 if (getInfo()==&fDimFadRawData)
2875 return PostInfoHandler(&FactGui::handleFadRawData);
2876
2877 if (getInfo()==&fDimFadEventData)
2878 return PostInfoHandler(&FactGui::handleFadEventData);
2879
2880/*
2881 if (getInfo()==&fDimFadSetup)
2882 return PostInfoHandler(&FactGui::handleFadSetup);
2883*/
2884 if (getInfo()==&fDimLoggerFilenameNight)
2885 return PostInfoHandler(&FactGui::handleLoggerFilenameNight);
2886
2887 if (getInfo()==&fDimLoggerNumSubs)
2888 return PostInfoHandler(&FactGui::handleLoggerNumSubs);
2889
2890 if (getInfo()==&fDimLoggerFilenameRun)
2891 return PostInfoHandler(&FactGui::handleLoggerFilenameRun);
2892
2893 if (getInfo()==&fDimFtmTriggerRates)
2894 return PostInfoHandler(&FactGui::handleFtmTriggerRates);
2895
2896 if (getInfo()==&fDimFtmCounter)
2897 return PostInfoHandler(&FactGui::handleFtmCounter);
2898
2899 if (getInfo()==&fDimFtmDynamicData)
2900 return PostInfoHandler(&FactGui::handleFtmDynamicData);
2901
2902 if (getInfo()==&fDimFtmPassport)
2903 return PostInfoHandler(&FactGui::handleFtmPassport);
2904
2905 if (getInfo()==&fDimFtmFtuList)
2906 return PostInfoHandler(&FactGui::handleFtmFtuList);
2907
2908 if (getInfo()==&fDimFtmStaticData)
2909 return PostInfoHandler(&FactGui::handleFtmStaticData);
2910
2911 if (getInfo()==&fDimFtmError)
2912 return PostInfoHandler(&FactGui::handleFtmError);
2913
2914 if (getInfo()==&fDimFscTemp)
2915 return PostInfoHandler(&FactGui::handleFscTemp);
2916
2917 if (getInfo()==&fDimFscVolt)
2918 return PostInfoHandler(&FactGui::handleFscVolt);
2919
2920 if (getInfo()==&fDimFscCurrent)
2921 return PostInfoHandler(&FactGui::handleFscCurrent);
2922
2923 if (getInfo()==&fDimFscHumidity)
2924 return PostInfoHandler(&FactGui::handleFscHumidity);
2925
2926// if (getInfo()==&fDimBiasVolt)
2927// return PostInfoHandler(&FactGui::handleBiasVolt);
2928
2929 if (getInfo()==&fDimBiasCurrent)
2930 return PostInfoHandler(&FactGui::handleBiasCurrent);
2931
2932// if (getInfo()==&fDimFadFiles)
2933// return PostInfoHandler(&FactGui::handleFadFiles);
2934
2935 for (map<string,DimInfo*>::iterator i=fServices.begin(); i!=fServices.end(); i++)
2936 if (i->second==getInfo())
2937 {
2938 infoHandlerService(*i->second);
2939 return;
2940 }
2941
2942 DimNetwork::infoHandler();
2943 }
2944
2945
2946 // ======================================================================
2947
2948 bool event(QEvent *evt)
2949 {
2950 if (dynamic_cast<FunctionEvent*>(evt))
2951 return static_cast<FunctionEvent*>(evt)->Exec();
2952
2953 if (dynamic_cast<CheckBoxEvent*>(evt))
2954 {
2955 const QStandardItem &item = static_cast<CheckBoxEvent*>(evt)->item;
2956 const QStandardItem *par = item.parent();
2957 if (par)
2958 {
2959 const QString server = par->text();
2960 const QString service = item.text();
2961
2962 const string s = (server+'/'+service).toStdString();
2963
2964 if (item.checkState()==Qt::Checked)
2965 SubscribeService(s);
2966 else
2967 UnsubscribeService(s);
2968 }
2969 }
2970
2971 return MainWindow::event(evt); // unrecognized
2972 }
2973
2974 void on_fDimCmdSend_clicked()
2975 {
2976 const QString server = fDimCmdServers->currentIndex().data().toString();
2977 const QString command = fDimCmdCommands->currentIndex().data().toString();
2978 const QString arguments = fDimCmdLineEdit->displayText();
2979
2980 // FIXME: Sending a command exactly when the info Handler changes
2981 // the list it might lead to confusion.
2982 try
2983 {
2984 SendDimCommand(server.toStdString(), command.toStdString()+" "+arguments.toStdString());
2985 fTextEdit->append("<font color='green'>Command '"+server+'/'+command+"' successfully emitted.</font>");
2986 fDimCmdLineEdit->clear();
2987 }
2988 catch (const runtime_error &e)
2989 {
2990 stringstream txt;
2991 txt << e.what();
2992
2993 string buffer;
2994 while (getline(txt, buffer, '\n'))
2995 fTextEdit->append(("<font color='red'><pre>"+buffer+"</pre></font>").c_str());
2996 }
2997 }
2998
2999#ifdef HAVE_ROOT
3000 void slot_RootEventProcessed(TObject *obj, unsigned int evt, TCanvas *canv)
3001 {
3002 // kMousePressEvent // TCanvas processed QEvent mousePressEvent
3003 // kMouseMoveEvent // TCanvas processed QEvent mouseMoveEvent
3004 // kMouseReleaseEvent // TCanvas processed QEvent mouseReleaseEvent
3005 // kMouseDoubleClickEvent // TCanvas processed QEvent mouseDoubleClickEvent
3006 // kKeyPressEvent // TCanvas processed QEvent keyPressEvent
3007 // kEnterEvent // TCanvas processed QEvent enterEvent
3008 // kLeaveEvent // TCanvas processed QEvent leaveEvent
3009
3010 if (dynamic_cast<TCanvas*>(obj))
3011 return;
3012
3013 TQtWidget *tipped = static_cast<TQtWidget*>(sender());
3014
3015 if (evt==11/*kMouseReleaseEvent*/)
3016 return;
3017
3018 if (evt==61/*kMouseDoubleClickEvent*/)
3019 return;
3020
3021 if (obj)
3022 {
3023 // Find the object which will get picked by the GetObjectInfo
3024 // due to buffer overflows in many root-versions
3025 // in TH1 and TProfile we have to work around and implement
3026 // our own GetObjectInfo which make everything a bit more
3027 // complicated.
3028 canv->cd();
3029#if ROOT_VERSION_CODE > ROOT_VERSION(5,22,00)
3030 const char *objectInfo =
3031 obj->GetObjectInfo(tipped->GetEventX(),tipped->GetEventY());
3032#else
3033 const char *objectInfo = dynamic_cast<TH1*>(obj) ?
3034 "" : obj->GetObjectInfo(tipped->GetEventX(),tipped->GetEventY());
3035#endif
3036
3037 QString tipText;
3038 tipText += obj->GetName();
3039 tipText += " [";
3040 tipText += obj->ClassName();
3041 tipText += "]: ";
3042 tipText += objectInfo;
3043
3044 fStatusBar->showMessage(tipText, 3000);
3045 }
3046
3047 gSystem->DispatchOneEvent(kFALSE);
3048 //gSystem->ProcessEvents();
3049 //QWhatsThis::display(tipText)
3050 }
3051
3052 void slot_RootUpdate()
3053 {
3054 gSystem->DispatchOneEvent(kFALSE);
3055 //gSystem->ProcessEvents();
3056 QTimer::singleShot(10, this, SLOT(slot_RootUpdate()));
3057 }
3058#endif
3059
3060 void ChoosePatchThreshold(Camera &cam, int isw)
3061 {
3062 cam.Reset();
3063
3064 fThresholdIdx->setValue(isw);
3065
3066 const int ihw = isw<0 ? 0 : fPatchMapHW[isw];
3067
3068 fPatchRate->setEnabled(isw>=0);
3069 fThresholdCrate->setEnabled(isw>=0);
3070 fThresholdBoard->setEnabled(isw>=0);
3071 fThresholdPatch->setEnabled(isw>=0);
3072
3073 if (isw<0)
3074 return;
3075
3076 const int patch = ihw%4;
3077 const int board = (ihw/4)%10;
3078 const int crate = (ihw/4)/10;
3079
3080 fInChoosePatchTH = true;
3081
3082 fThresholdCrate->setValue(crate);
3083 fThresholdBoard->setValue(board);
3084 fThresholdPatch->setValue(patch);
3085
3086 fInChoosePatchTH = false;
3087
3088 fThresholdVal->setValue(fFtmStaticData.fThreshold[ihw]);
3089 fPatchRate->setValue(cam.GetData(isw));
3090
3091 // Loop over the software idx of all pixels
3092 for (unsigned int i=0; i<1440; i++)
3093 if (fPatchHW[i]==ihw)
3094 cam.SetBold(i);
3095 }
3096
3097 void ChoosePatchBias(Camera &cam, int isw)
3098 {
3099 cam.Reset();
3100
3101 fBiasPixel->setValue(isw);
3102
3103 const int ihw = isw<0 ? 0 : fPatchMapHW[isw];
3104
3105 fBiasCurrent->setEnabled(isw>=0);
3106 fBiasCrate->setEnabled(isw>=0);
3107 fBiasBoard->setEnabled(isw>=0);
3108 fBiasPatch->setEnabled(isw>=0);
3109
3110 if (isw<0)
3111 return;
3112
3113 const int patch = ihw%4;
3114 const int board = (ihw/4)%10;
3115 const int crate = (ihw/4)/10;
3116
3117 fInChoosePatchBias = true;
3118
3119 fBiasCrate->setValue(crate);
3120 fBiasBoard->setValue(board);
3121 fBiasPatch->setValue(patch);
3122
3123 fInChoosePatchBias = false;
3124
3125 if (fVecBias.size()>0)
3126 {
3127 // FIXME: Mapping
3128 fBiasVoltDac->setValue(fVecBias[ihw]);
3129 fBiasVolt->setValue(fVecBias[ihw]*90/4096);
3130 }
3131
3132 fBiasCurrent->setValue(cam.GetData(isw));
3133
3134 // Loop over the software idx of all pixels
3135 for (unsigned int i=0; i<1440; i++)
3136 if (fPatchHW[i]==ihw)
3137 cam.SetBold(i);
3138 }
3139
3140 void slot_ChoosePixelThreshold(int isw)
3141 {
3142 fPixelIdx->setValue(isw);
3143 const uint16_t ihw = fPixelMapHW[isw];
3144 const bool on = fFtmStaticData.IsEnabled(ihw);
3145 fPixelEnable->setChecked(on);
3146 }
3147
3148 void slot_ChoosePixelBias(int isw)
3149 {
3150 fBiasPixel->setValue(isw);
3151 //const uint16_t ihw = fPixelMapHW[isw];
3152 //const bool on = fFtmStaticData.IsEnabled(ihw);
3153 //fPixelEnable->setChecked(on);
3154 }
3155
3156 void slot_CameraDoubleClick(int isw)
3157 {
3158 fPixelIdx->setValue(isw);
3159 const uint16_t ihw = fPixelMapHW[isw];
3160 Dim::SendCommand("FTM_CONTROL/TOGGLE_PIXEL", ihw);
3161 }
3162
3163 void slot_CameraMouseMove(int isw)
3164 {
3165 const int ihw = fPixelMapHW[isw];
3166 const int idx = fPatchHW[isw];
3167 int ii = 0;
3168 for (; ii<160;ii++)
3169 if (idx ==fPatchMapHW[ii])
3170 break;
3171
3172 const int patch = idx%4;
3173 const int board = (idx/4)%10;
3174 const int crate = (idx/4)/10;
3175 QString tipText;
3176 tipText += fRatesCanv->GetName();
3177 ostringstream str;
3178 str << " || Pixel=" << isw << " (hw=" << ihw << ") || Patch=" << ii << " (hw=" << fPatchMapHW[idx] << "; Crate=" << crate << " Board=" << board << " Patch=" << patch << ")";
3179 tipText += str.str().c_str();
3180 fStatusBar->showMessage(tipText, 3000);
3181 }
3182
3183 void on_fThresholdIdx_valueChanged(int isw)
3184 {
3185//ETIENNE MESS HERE
3186// Camera *cam = (Camera*)fRatesCanv->GetCanvas()->FindObject("Camera");
3187// ChoosePatchTH(*cam, isw);
3188 }
3189
3190 void UpdateThresholdIdx()
3191 {
3192 if (fInChoosePatchTH)
3193 return;
3194
3195 const int crate = fThresholdCrate->value();
3196 const int board = fThresholdBoard->value();
3197 const int patch = fThresholdPatch->value();
3198
3199 const int ihw = patch + board*4 + crate*40;
3200
3201 int isw = 0;
3202 for (; isw<160; isw++)
3203 if (ihw==fPatchMapHW[isw])
3204 break;
3205
3206 on_fThresholdIdx_valueChanged(isw);
3207 }
3208
3209 void UpdateBiasIdx()
3210 {
3211 if (fInChoosePatchBias)
3212 return;
3213
3214 const int crate = fBiasCrate->value();
3215 const int board = fBiasBoard->value();
3216 const int patch = fBiasPatch->value();
3217
3218 const int ihw = patch + board*4 + crate*40;
3219
3220 int isw = 0;
3221 for (; isw<160; isw++)
3222 if (ihw==fPatchMapHW[isw])
3223 break;
3224
3225 on_fBiasPixel_valueChanged(isw);
3226 }
3227
3228 void on_fPixelIdx_valueChanged(int isw)
3229 {
3230 const int ihw = fPixelMapHW[isw];
3231
3232 int ii = 0;
3233 for (; ii<160; ii++)
3234 if (fPatchHW[isw]==fPatchMapHW[ii])
3235 break;
3236
3237 fRatesCanv->SetWhite(isw);
3238 ChoosePatchThreshold(*fRatesCanv, ii);
3239
3240 const bool on = fFtmStaticData.IsEnabled(ihw);
3241 fPixelEnable->setChecked(on);
3242 }
3243
3244 void on_fBiasPixel_valueChanged(int isw)
3245 {
3246 const int ihw = fPixelMapHW[isw];
3247
3248 int ii = 0;
3249 for (; ii<160; ii++)
3250 if (fPatchHW[isw]==fPatchMapHW[ii])
3251 break;
3252
3253 fBiasCam->SetWhite(isw);
3254 ChoosePatchBias(*fRatesCanv, ii);
3255
3256 const bool on = fFtmStaticData.IsEnabled(ihw);
3257 fPixelEnable->setChecked(on);
3258 }
3259
3260
3261 void on_fPixelEnable_stateChanged(int b)
3262 {
3263 if (fInHandler)
3264 return;
3265
3266 const uint16_t isw = fPixelIdx->value();
3267 const uint16_t ihw = fPixelMapHW[isw];
3268
3269 Dim::SendCommand(b==Qt::Unchecked ?
3270 "FTM_CONTROL/DISABLE_PIXEL" : "FTM_CONTROL/ENABLE_PIXEL",
3271 ihw);
3272 }
3273
3274 void on_fPixelDisableOthers_clicked()
3275 {
3276 const uint16_t isw = fPixelIdx->value();
3277 const uint16_t ihw = fPixelMapHW[isw];
3278
3279 Dim::SendCommand("FTM_CONTROL/DISABLE_ALL_PIXELS_EXCEPT", ihw);
3280 }
3281
3282 void on_fThresholdDisableOthers_clicked()
3283 {
3284 const int16_t isw = fThresholdIdx->value();
3285 const int16_t ihw = isw<0 ? -1 : fPatchMapHW[isw];
3286
3287 Dim::SendCommand("FTM_CONTROL/DISABLE_ALL_PATCHES_EXCEPT", ihw);
3288 }
3289
3290 void on_fThresholdVal_valueChanged(int v)
3291 {
3292 fThresholdVolt->setValue(2500./4095*v);
3293
3294 const int32_t isw = fThresholdIdx->value();
3295 const int32_t ihw = isw<0 ? -1 : fPatchMapHW[isw];
3296
3297 const int32_t d[2] = { ihw, v };
3298
3299 if (!fInHandler)
3300 Dim::SendCommand("FTM_CONTROL/SET_THRESHOLD", d);
3301 }
3302
3303 TGraph fGraphFtmTemp[4];
3304 TGraph fGraphFtmRate;
3305 TGraph fGraphPatchRate[160];
3306 TGraph fGraphBoardRate[40];
3307
3308#ifdef HAVE_ROOT
3309 TH1 *DrawTimeFrame(const char *ytitle)
3310 {
3311 const double tm = Time().RootTime();
3312
3313 TH1F *h=new TH1F("TimeFrame", "", 1, tm, tm+60);//Time().RootTime()-1./24/60/60, Time().RootTime());
3314 h->SetDirectory(0);
3315 h->SetBit(kCanDelete);
3316 h->SetStats(kFALSE);
3317// h.SetMinimum(0);
3318// h.SetMaximum(1);
3319 h->SetXTitle("Time");
3320 h->SetYTitle(ytitle);
3321 h->GetXaxis()->CenterTitle();
3322 h->GetYaxis()->CenterTitle();
3323 h->GetXaxis()->SetTimeDisplay(true);
3324 h->GetXaxis()->SetTimeFormat("%Mh%S'");
3325 h->GetXaxis()->SetLabelSize(0.025);
3326 h->GetYaxis()->SetLabelSize(0.025);
3327 h->GetYaxis()->SetTitleOffset(1.2);
3328 // h.GetYaxis()->SetTitleSize(1.2);
3329 h->Draw();
3330
3331 return h;
3332 }
3333#endif
3334
3335 pair<string,string> Split(const string &str) const
3336 {
3337 const size_t p = str.find_first_of('|');
3338 if (p==string::npos)
3339 return make_pair(str, "");
3340
3341 return make_pair(str.substr(0, p), str.substr(p+1));
3342 }
3343
3344public:
3345 FactGui(Configuration &conf) :
3346 fFtuStatus(40),
3347 fPixelMapHW(1440), fPatchMapHW(160), fPatchHW(1440),
3348 fInChoosePatchTH(false), fInChoosePatchBias(false),
3349 fDimDNS("DIS_DNS/VERSION_NUMBER", 1, int(0), this),
3350 //-
3351 fDimLoggerStats ("DATA_LOGGER/STATS", (void*)NULL, 0, this),
3352 fDimLoggerFilenameNight("DATA_LOGGER/FILENAME_NIGHTLY", (void*)NULL, 0, this),
3353 fDimLoggerFilenameRun ("DATA_LOGGER/FILENAME_RUN", (void*)NULL, 0, this),
3354 fDimLoggerNumSubs ("DATA_LOGGER/NUM_SUBS", (void*)NULL, 0, this),
3355 //-
3356 fDimFtmPassport ("FTM_CONTROL/PASSPORT", (void*)NULL, 0, this),
3357 fDimFtmTriggerRates ("FTM_CONTROL/TRIGGER_RATES", (void*)NULL, 0, this),
3358 fDimFtmError ("FTM_CONTROL/ERROR", (void*)NULL, 0, this),
3359 fDimFtmFtuList ("FTM_CONTROL/FTU_LIST", (void*)NULL, 0, this),
3360 fDimFtmStaticData ("FTM_CONTROL/STATIC_DATA", (void*)NULL, 0, this),
3361 fDimFtmDynamicData ("FTM_CONTROL/DYNAMIC_DATA", (void*)NULL, 0, this),
3362 fDimFtmCounter ("FTM_CONTROL/COUNTER", (void*)NULL, 0, this),
3363 //-
3364 fDimFadWriteStats ("FAD_CONTROL/STATS", (void*)NULL, 0, this),
3365 fDimFadStartRun ("FAD_CONTROL/START_RUN", (void*)NULL, 0, this),
3366 fDimFadRuns ("FAD_CONTROL/RUNS", (void*)NULL, 0, this),
3367 fDimFadEvents ("FAD_CONTROL/EVENTS", (void*)NULL, 0, this),
3368 fDimFadRawData ("FAD_CONTROL/RAW_DATA", (void*)NULL, 0, this),
3369 fDimFadEventData ("FAD_CONTROL/EVENT_DATA", (void*)NULL, 0, this),
3370 fDimFadConnections ("FAD_CONTROL/CONNECTIONS", (void*)NULL, 0, this),
3371 fDimFadFwVersion ("FAD_CONTROL/FIRMWARE_VERSION", (void*)NULL, 0, this),
3372 fDimFadRunNumber ("FAD_CONTROL/RUN_NUMBER", (void*)NULL, 0, this),
3373 fDimFadDNA ("FAD_CONTROL/DNA", (void*)NULL, 0, this),
3374 fDimFadTemperature ("FAD_CONTROL/TEMPERATURE", (void*)NULL, 0, this),
3375 fDimFadPrescaler ("FAD_CONTROL/PRESCALER", (void*)NULL, 0, this),
3376 fDimFadRefClock ("FAD_CONTROL/REFERENCE_CLOCK", (void*)NULL, 0, this),
3377 fDimFadRoi ("FAD_CONTROL/REGION_OF_INTEREST", (void*)NULL, 0, this),
3378 fDimFadDac ("FAD_CONTROL/DAC", (void*)NULL, 0, this),
3379 fDimFadDrsCalibration ("FAD_CONTROL/DRS_CALIBRATION", (void*)NULL, 0, this),
3380 fDimFadStatus ("FAD_CONTROL/STATUS", (void*)NULL, 0, this),
3381 fDimFadStatistics1 ("FAD_CONTROL/STATISTICS1", (void*)NULL, 0, this),
3382 fDimFadStatistics2 ("FAD_CONTROL/STATISTICS2", (void*)NULL, 0, this),
3383 //-
3384 fDimFscTemp ("FSC_CONTROL/TEMPERATURE", (void*)NULL, 0, this),
3385 fDimFscVolt ("FSC_CONTROL/VOLTAGE", (void*)NULL, 0, this),
3386 fDimFscCurrent ("FSC_CONTROL/CURRENT", (void*)NULL, 0, this),
3387 fDimFscHumidity ("FSC_CONTROL/HUMIDITY", (void*)NULL, 0, this),
3388 //-
3389 //fDimBiasVolt ("BIAS_CONTROL/VOLTAGE", (void*)NULL, 0, this),
3390 fDimBiasCurrent ("BIAS_CONTROL/CURRENT", (void*)NULL, 0, this),
3391 //-
3392 fEventData(0), fDrsCalibration(1440*1024*6),
3393 fTimeStamp0(0)
3394
3395 {
3396 fClockCondFreq->addItem("--- Hz", QVariant(-1));
3397 fClockCondFreq->addItem("800 MHz", QVariant(800));
3398 fClockCondFreq->addItem("1 GHz", QVariant(1000));
3399 fClockCondFreq->addItem("2 GHz", QVariant(2000));
3400 fClockCondFreq->addItem("3 GHz", QVariant(3000));
3401 fClockCondFreq->addItem("4 GHz", QVariant(4000));
3402 fClockCondFreq->addItem("5 GHz", QVariant(5000));
3403
3404 cout << "-- run counter ---" << endl;
3405 fMcpNumEvents->addItem("unlimited", QVariant(0));
3406 const vector<uint32_t> runcount = conf.Vec<uint32_t>("run-count");
3407 for (vector<uint32_t>::const_iterator it=runcount.begin(); it!=runcount.end(); it++)
3408 {
3409 cout << *it << endl;
3410 ostringstream str;
3411 str << *it;
3412 fMcpNumEvents->addItem(str.str().c_str(), QVariant(*it));
3413 }
3414
3415 cout << "-- run times ---" << endl;
3416 fMcpTime->addItem("unlimited", QVariant(0));
3417 const vector<string> runtime = conf.Vec<string>("run-time");
3418 for (vector<string>::const_iterator it=runtime.begin(); it!=runtime.end(); it++)
3419 {
3420 const pair<string,string> p = Split(*it);
3421 cout << *it << "|" << p.second << "|" << p.first << "|" << endl;
3422 fMcpTime->addItem(p.second.c_str(), QVariant(stoi(p.first)));
3423 }
3424
3425 cout << "-- run types ---" << endl;
3426 const vector<string> runtype = conf.Vec<string>("run-type");
3427 for (vector<string>::const_iterator it=runtype.begin(); it!=runtype.end(); it++)
3428 {
3429 const pair<string,string> p = Split(*it);
3430 cout << *it << "|" << p.second << "|" << p.first << "|" << endl;
3431 fMcpRunType->addItem(p.second.c_str(), QVariant(p.first.c_str()));
3432 }
3433
3434 fTriggerWidget->setEnabled(false);
3435 fFtuWidget->setEnabled(false);
3436 fFtuGroupEnable->setEnabled(false);
3437 fRatesControls->setEnabled(false);
3438 fFadWidget->setEnabled(false);
3439 fEvtBldWidget->setEnabled(false);
3440 fLoggerWidget->setEnabled(false);
3441
3442 fChatSend->setEnabled(false);
3443 fChatMessage->setEnabled(false);
3444
3445 DimClient::sendCommand("CHAT/MSG", "GUI online.");
3446 // + MessageDimRX
3447
3448 // --------------------------------------------------------------------------
3449
3450 ifstream fin1("Trigger-Patches.txt");
3451
3452 int l = 0;
3453
3454 string buf;
3455 while (getline(fin1, buf, '\n'))
3456 {
3457 buf = Tools::Trim(buf);
3458 if (buf[0]=='#')
3459 continue;
3460
3461 stringstream str(buf);
3462 for (int i=0; i<9; i++)
3463 {
3464 unsigned int n;
3465 str >> n;
3466
3467 if (n>=fPatchHW.size())
3468 continue;
3469
3470 fPatchHW[n] = l;
3471 }
3472 l++;
3473 }
3474
3475 if (l!=160)
3476 cerr << "WARNING - Problems reading Trigger-Patches.txt" << endl;
3477
3478 // --------------------------------------------------------------------------
3479
3480 ifstream fin2("MasterList-v3.txt");
3481
3482 l = 0;
3483
3484 while (getline(fin2, buf, '\n'))
3485 {
3486 buf = Tools::Trim(buf);
3487 if (buf[0]=='#')
3488 continue;
3489
3490 unsigned int softid, hardid, dummy;
3491
3492 stringstream str(buf);
3493
3494 str >> softid;
3495 str >> dummy;
3496 str >> hardid;
3497
3498 if (softid>=fPixelMapHW.size())
3499 continue;
3500
3501 fPixelMapHW[softid] = hardid;
3502
3503 l++;
3504 }
3505
3506 if (l!=1440)
3507 cerr << "WARNING - Problems reading MasterList-v3.txt" << endl;
3508
3509 // --------------------------------------------------------------------------
3510
3511 ifstream fin3("PatchList.txt");
3512
3513 l = 0;
3514
3515 while (getline(fin3, buf, '\n'))
3516 {
3517 buf = Tools::Trim(buf);
3518 if (buf[0]=='#')
3519 continue;
3520
3521 unsigned int softid, hardid;
3522
3523 stringstream str(buf);
3524
3525 str >> softid;
3526 str >> hardid;
3527
3528 if (softid>=fPatchMapHW.size())
3529 continue;
3530
3531 fPatchMapHW[softid] = hardid-1;
3532
3533 l++;
3534 }
3535
3536 if (l!=160)
3537 cerr << "WARNING - Problems reading PatchList.txt" << endl;
3538
3539 // --------------------------------------------------------------------------
3540#ifdef HAVE_ROOT
3541
3542 fGraphFtmRate.SetLineColor(kBlue);
3543 fGraphFtmRate.SetMarkerColor(kBlue);
3544 fGraphFtmRate.SetMarkerStyle(kFullDotMedium);
3545
3546 for (int i=0; i<160; i++)
3547 {
3548 fGraphPatchRate[i].SetName("PatchRate");
3549 //fGraphPatchRate[i].SetLineColor(kBlue);
3550 //fGraphPatchRate[i].SetMarkerColor(kBlue);
3551 fGraphPatchRate[i].SetMarkerStyle(kFullDotMedium);
3552 }
3553 for (int i=0; i<40; i++)
3554 {
3555 fGraphBoardRate[i].SetName("BoardRate");
3556 //fGraphBoardRate[i].SetLineColor(kBlue);
3557 //fGraphBoardRate[i].SetMarkerColor(kBlue);
3558 fGraphBoardRate[i].SetMarkerStyle(kFullDotMedium);
3559 }
3560 /*
3561 TCanvas *c = fFtmTempCanv->GetCanvas();
3562 c->SetBit(TCanvas::kNoContextMenu);
3563 c->SetBorderMode(0);
3564 c->SetFrameBorderMode(0);
3565 c->SetFillColor(kWhite);
3566 c->SetRightMargin(0.03);
3567 c->SetTopMargin(0.03);
3568 c->cd();
3569 */
3570 //CreateTimeFrame("Temperature / �C");
3571
3572 fGraphFtmTemp[0].SetMarkerStyle(kFullDotSmall);
3573 fGraphFtmTemp[1].SetMarkerStyle(kFullDotSmall);
3574 fGraphFtmTemp[2].SetMarkerStyle(kFullDotSmall);
3575 fGraphFtmTemp[3].SetMarkerStyle(kFullDotSmall);
3576
3577 fGraphFtmTemp[1].SetLineColor(kBlue);
3578 fGraphFtmTemp[2].SetLineColor(kRed);
3579 fGraphFtmTemp[3].SetLineColor(kGreen);
3580
3581 fGraphFtmTemp[1].SetMarkerColor(kBlue);
3582 fGraphFtmTemp[2].SetMarkerColor(kRed);
3583 fGraphFtmTemp[3].SetMarkerColor(kGreen);
3584
3585 //fGraphFtmTemp[0].Draw("LP");
3586 //fGraphFtmTemp[1].Draw("LP");
3587 //fGraphFtmTemp[2].Draw("LP");
3588 //fGraphFtmTemp[3].Draw("LP");
3589
3590 // --------------------------------------------------------------------------
3591
3592 TCanvas *c = fFtmRateCanv->GetCanvas();
3593 //c->SetBit(TCanvas::kNoContextMenu);
3594 c->SetBorderMode(0);
3595 c->SetFrameBorderMode(0);
3596 c->SetFillColor(kWhite);
3597 c->SetRightMargin(0.03);
3598 c->SetTopMargin(0.03);
3599 c->SetGrid();
3600 c->cd();
3601
3602 TH1 *hf = DrawTimeFrame("Trigger rate [Hz]");
3603 hf->GetYaxis()->SetRangeUser(0, 1010);
3604
3605 fGraphFtmRate.SetMarkerStyle(kFullDotSmall);
3606 fGraphFtmRate.Draw("LP");
3607
3608 // --------------------------------------------------------------------------
3609
3610 fRatesCanv->SetMin(fRatesMin->value());
3611 fRatesCanv->SetMax(fRatesMax->value());
3612 fRatesCanv->updateGL();
3613 on_fPixelIdx_valueChanged(0);
3614
3615 // --------------------------------------------------------------------------
3616
3617 c = fAdcDataCanv->GetCanvas();
3618 //c->SetBit(TCanvas::kNoContextMenu);
3619 c->SetBorderMode(0);
3620 c->SetFrameBorderMode(0);
3621 c->SetFillColor(kWhite);
3622 c->SetRightMargin(0.10);
3623 c->SetGrid();
3624 c->cd();
3625
3626 // Create histogram?
3627
3628 // --------------------------------------------------------------------------
3629
3630 QTimer::singleShot(1000, this, SLOT(slot_RootUpdate()));
3631
3632 //widget->setMouseTracking(true);
3633 //widget->EnableSignalEvents(kMouseMoveEvent);
3634
3635 fFtmRateCanv->setMouseTracking(true);
3636 fFtmRateCanv->EnableSignalEvents(kMouseMoveEvent);
3637
3638 fAdcDataCanv->setMouseTracking(true);
3639 fAdcDataCanv->EnableSignalEvents(kMouseMoveEvent);
3640
3641 fRatesCanv->setMouseTracking(true);
3642
3643 connect(fRatesCanv, SIGNAL(signalPixelMoveOver(int)),
3644 this, SLOT(slot_CameraMouseMove(int)));
3645 connect(fEventCanv1, SIGNAL(signalCurrentPixel(int)),
3646 this, SLOT(slot_CameraMouseMove(int)));
3647 connect(fEventCanv2, SIGNAL(signalCurrentPixel(int)),
3648 this, SLOT(slot_CameraMouseMove(int)));
3649 connect(fEventCanv3, SIGNAL(signalCurrentPixel(int)),
3650 this, SLOT(slot_CameraMouseMove(int)));
3651 connect(fEventCanv4, SIGNAL(signalCurrentPixel(int)),
3652 this, SLOT(slot_CameraMouseMove(int)));
3653
3654 connect(fRatesCanv, SIGNAL(signalPixelDoubleClick(int)),
3655 this, SLOT(slot_CameraDoubleClick(int)));
3656 connect(fRatesCanv, SIGNAL(signalCurrentPixel(int)),
3657 this, SLOT(slot_ChoosePixelThreshold(int)));
3658 connect(fBiasCam, SIGNAL(signalCurrentPixel(int)),
3659 this, SLOT(slot_ChoosePixelBias(int)));
3660 connect(fFtmRateCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)),
3661 this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*)));
3662 connect(fAdcDataCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)),
3663 this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*)));
3664#endif
3665 }
3666
3667 ~FactGui()
3668 {
3669 // Unsubscribe all services
3670 for (map<string,DimInfo*>::iterator i=fServices.begin();
3671 i!=fServices.end(); i++)
3672 delete i->second;
3673
3674 delete fEventData;
3675 }
3676};
3677
3678#endif
Note: See TracBrowser for help on using the repository browser.