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

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