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

Last change on this file since 11876 was 11866, checked in by tbretz, 14 years ago
Replaced fPixelMapHW by fPixelMap
File size: 117.4 KB
Line 
1#ifndef FACT_FactGui
2#define FACT_FactGui
3
4#include "MainWindow.h"
5
6#include <iomanip>
7#include <valarray>
8
9#include <boost/bind.hpp>
10
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 if ((hf && hf->GetNbinsX()!=fEventData->Roi) ||
1276 (dynamic_cast<TH2*>(h) && !fAdcPersistent->isChecked()) ||
1277 (!dynamic_cast<TH2*>(h) && fAdcPersistent->isChecked()))
1278 {
1279 delete hf;
1280 delete h;
1281 delete d0;
1282 delete d1;
1283 delete d2;
1284 d0 = 0;
1285 d1 = 0;
1286 d2 = 0;
1287 hf = 0;
1288 }
1289 const int roi = fEventData->Roi>0 ? fEventData->Roi : 1;
1290
1291 c->cd();
1292
1293 if (!hf)
1294 {
1295 hf = new TH1F("Frame", "", roi, -0.5, roi-0.5);
1296 hf->SetDirectory(0);
1297 hf->SetBit(kCanDelete);
1298 hf->SetStats(kFALSE);
1299 hf->SetYTitle("Voltage [mV]");
1300 hf->GetXaxis()->CenterTitle();
1301 hf->GetYaxis()->CenterTitle();
1302 hf->SetMinimum(-1250);
1303 hf->SetMaximum(2150);
1304
1305 if (!fAdcPersistent->isChecked())
1306 h = new TH1F("EventData", "", roi, -0.5, roi-0.5);
1307 else
1308 {
1309 h = new TH2F("EventData", "", roi, -0.5, roi-0.5, 3301, -1150.5, 2150.5);
1310 h->SetContour(50);
1311 gStyle->SetPalette(1, 0);
1312 }
1313
1314 h->SetDirectory(0);
1315 h->SetBit(kCanDelete);
1316 h->SetMarkerStyle(kFullDotMedium);
1317 h->SetMarkerColor(kBlue);
1318
1319 hf->Draw("");
1320
1321 if (dynamic_cast<TH2*>(h))
1322 h->Draw("col same");
1323 }
1324
1325 if (d0 && !(fDrsCalibBaselineOn->isChecked() && fDrsCalibBaseline->value()>0))
1326 {
1327 delete d0;
1328 d0 = 0;
1329 }
1330 if (d1 && !(fDrsCalibGainOn->isChecked() && fDrsCalibGain->value()>0))
1331 {
1332 delete d1;
1333 d1 = 0;
1334 }
1335 if (d2 && !(fDrsCalibTrgOffsetOn->isChecked() && fDrsCalibTrgOffset->value()>0))
1336 {
1337 delete d2;
1338 d2 = 0;
1339 }
1340
1341 if (!d0 && fDrsCalibBaselineOn->isChecked() && fDrsCalibBaseline->value()>0)
1342 {
1343 d0 = new TH1F("DrsCalib0", "", roi, -0.5, roi-0.5);
1344 d0->SetDirectory(0);
1345 d0->SetBit(kCanDelete);
1346 d0->SetMarkerStyle(kFullDotSmall);
1347 d0->SetMarkerColor(kRed);
1348 d0->SetLineColor(kRed);
1349 d0->Draw("PEX0same");
1350 }
1351
1352 if (!d1 && fDrsCalibGainOn->isChecked() && fDrsCalibGain->value()>0)
1353 {
1354 d1 = new TH1F("DrsCalib1", "", roi, -0.5, roi-0.5);
1355 d1->SetDirectory(0);
1356 d1->SetBit(kCanDelete);
1357 d1->SetMarkerStyle(kFullDotSmall);
1358 d1->SetMarkerColor(kMagenta);
1359 d1->SetLineColor(kMagenta);
1360 d1->Draw("PEX0same");
1361 }
1362
1363 if (!d2 && fDrsCalibTrgOffsetOn->isChecked() && fDrsCalibTrgOffset->value()>0)
1364 {
1365 d2 = new TH1F("DrsCalib2", "", roi, -0.5, roi-0.5);
1366 d2->SetDirectory(0);
1367 d2->SetBit(kCanDelete);
1368 d2->SetMarkerStyle(kFullDotSmall);
1369 d2->SetMarkerColor(kGreen);
1370 d2->SetLineColor(kGreen);
1371 d2->Draw("PEX0same");
1372 }
1373
1374 if (!dynamic_cast<TH2*>(h) && !c->GetListOfPrimitives()->FindObject(h))
1375 h->Draw("PLsame");
1376
1377 // -----------------------------------------------------------
1378
1379 const uint32_t p =
1380 fAdcChannel->value() +
1381 fAdcChip->value() * 9+
1382 fAdcBoard->value() * 36+
1383 fAdcCrate->value() *360;
1384
1385 ostringstream str;
1386 str << "EventNum = " << fEventData->EventNum;
1387 str << " TriggerNum = " << fEventData->TriggerNum;
1388 str << " TriggerType = " << fEventData->TriggerType;
1389 str << " BoardTime = " << fEventData->BoardTime[fAdcBoard->value()+fAdcCrate->value()*10];
1390 str << " (" << Time(fEventData->PCTime, fEventData->PCUsec) << ")";
1391 hf->SetTitle(str.str().c_str());
1392 str.str("");
1393 str << "ADC Pipeline (start cell: " << fEventData->StartPix[p] << ")";
1394 hf->SetXTitle(str.str().c_str());
1395
1396 // -----------------------------------------------------------
1397
1398 const int16_t start = fEventData->StartPix[p];
1399
1400 fDrsCalibBaseline->setEnabled(fDrsCalibBaseline->value()>0);
1401 fDrsCalibGain->setEnabled(fDrsCalibGain->value()>0);
1402 fDrsCalibTrgOffset->setEnabled(fDrsCalibTrgOffset->value()>0);
1403
1404 if (d0)//fDrsCalibBaseline->value()==0 || start<0)
1405 d0->Reset();
1406 if (d1)//fDrsCalibGain->value()==0 || start<0)
1407 d1->Reset();
1408 if (d2)//fDrsCalibTrgOffset->value()==0 || start<0)
1409 d2->Reset();
1410
1411 if (!dynamic_cast<TH2*>(h))
1412 h->Reset();
1413 if (d0)
1414 d0->SetEntries(0);
1415 if (d1)
1416 d1->SetEntries(0);
1417 if (d2)
1418 d2->SetEntries(0);
1419
1420 for (int i=0; i<fEventData->Roi; i++)
1421 {
1422 //if (dynamic_cast<TH2*>(h))
1423 h->Fill(i, reinterpret_cast<float*>(fEventData->Adc_Data)[p*fEventData->Roi+i]);
1424 //else
1425 // h->SetBinContent(i+1, reinterpret_cast<float*>(fEventData->Adc_Data)[p*fEventData->Roi+i]);
1426 if (start<0)
1427 continue;
1428
1429 if (d0)
1430 {
1431 d0->SetBinContent(i+1, fDrsCalibration[1440*1024*0 + p*1024+(start+i)%1024]);
1432 d0->SetBinError(i+1, fDrsCalibration[1440*1024*1 + p*1024+(start+i)%1024]);
1433
1434 }
1435 if (d1)
1436 {
1437 d1->SetBinContent(i+1, fDrsCalibration[1440*1024*2 + p*1024+(start+i)%1024]);
1438 d1->SetBinError(i+1, fDrsCalibration[1440*1024*3 + p*1024+(start+i)%1024]);
1439 }
1440 if (d2)
1441 {
1442 d2->SetBinContent(i+1, fDrsCalibration[1440*1024*4 + p*1024 + i]);
1443 d2->SetBinError(i+1, fDrsCalibration[1440*1024*5 + p*1024 + i]);
1444 }
1445 }
1446
1447 // -----------------------------------------------------------
1448 if (fAdcDynamicScale->isEnabled() && fAdcDynamicScale->isChecked())
1449 {
1450 h->SetMinimum();
1451 h->SetMaximum();
1452
1453 hf->SetMinimum(h->GetMinimum());
1454 hf->SetMaximum(h->GetMaximum());
1455 }
1456 if (fAdcManualScale->isEnabled() && fAdcManualScale->isChecked())
1457 {
1458 if (h->GetMinimumStored()==-1111)
1459 {
1460 h->SetMinimum(-1150);//-1026);
1461 hf->SetMinimum(-1150);//-1026);
1462 }
1463 if (h->GetMaximumStored()==-1111)
1464 {
1465 h->SetMaximum(2150);//1025);
1466 hf->SetMaximum(2150);//1025);
1467 }
1468 }
1469
1470 if (fAdcAutoScale->isEnabled() && fAdcAutoScale->isChecked())
1471 {
1472 h->SetMinimum();
1473 h->SetMaximum();
1474
1475 if (h->GetMinimum()<hf->GetMinimum())
1476 hf->SetMinimum(h->GetMinimum());
1477 if (h->GetMaximum()>hf->GetMaximum())
1478 hf->SetMaximum(h->GetMaximum());
1479 }
1480
1481 if (dynamic_cast<TH2*>(h))
1482 {
1483 h->SetMinimum();
1484 h->SetMaximum();
1485 }
1486
1487 // -----------------------------------------------------------
1488
1489 const int imin = ceil(hf->GetMinimum());
1490 const int imax = floor(hf->GetMaximum());
1491
1492 TH1S hd("", "", imax-imin+1, imin-0.5, imax+0.5);
1493 hd.SetDirectory(0);
1494 TH1S h0("", "", imax-imin+1, imin-0.5, imax+0.5);
1495 h0.SetDirectory(0);
1496 TH1S h1("", "", imax-imin+1, imin-0.5, imax+0.5);
1497 h1.SetDirectory(0);
1498 TH1S h2("", "", imax-imin+1, imin-0.5, imax+0.5);
1499 h2.SetDirectory(0);
1500 hd.SetLineColor(h->GetLineColor());
1501 if (d0)
1502 h0.SetLineColor(d0->GetLineColor());
1503 if (d1)
1504 h1.SetLineColor(d1->GetLineColor());
1505 if (d2)
1506 h2.SetLineColor(d2->GetLineColor());
1507
1508 for (int i=0; i<fEventData->Roi; i++)
1509 {
1510 if (!dynamic_cast<TH2*>(h))
1511 hd.Fill(h->GetBinContent(i+1));
1512 if (d0)
1513 h0.Fill(d0->GetBinContent(i+1));
1514 if (d1)
1515 h1.Fill(d1->GetBinContent(i+1));
1516 if (d2)
1517 h2.Fill(d2->GetBinContent(i+1));
1518 }
1519
1520 double mm = hd.GetMaximum(hd.GetEntries());
1521 if (h0.GetMaximum(h0.GetEntries())>mm)
1522 mm = h0.GetMaximum();
1523 if (h1.GetMaximum(h1.GetEntries())>mm)
1524 mm = h1.GetMaximum();
1525 if (h2.GetMaximum(h2.GetEntries())>mm)
1526 mm = h2.GetMaximum();
1527
1528 TIter Next(hf->GetListOfFunctions());
1529 TObject *obj = 0;
1530 while ((obj=Next()))
1531 if (dynamic_cast<TBox*>(obj))
1532 delete hf->GetListOfFunctions()->Remove(obj);
1533
1534 const double l = h->GetBinLowEdge(h->GetXaxis()->GetLast()+1);
1535 const double m = c->GetX2();
1536
1537 const double scale = 0.9*(m-l)/mm;
1538
1539 c->cd();
1540
1541 DrawHorizontal(hf, l, h2, scale);
1542 DrawHorizontal(hf, l, h1, scale);
1543 DrawHorizontal(hf, l, h0, scale);
1544 DrawHorizontal(hf, l, hd, scale);
1545
1546 // -----------------------------------------------------------
1547
1548 c->Modified();
1549 c->Update();
1550#endif
1551 }
1552
1553 void handleFadRawData(const DimData &d)
1554 {
1555 if (d.size()==0)
1556 return;
1557
1558 if (fAdcStop->isChecked())
1559 return;
1560
1561 const EVENT &dat = d.ref<EVENT>();
1562
1563 if (d.size()<sizeof(EVENT))
1564 {
1565 cerr << "Size mismatch in " << d.name << ": Found=" << d.size() << " Expected>=" << sizeof(EVENT) << endl;
1566 return;
1567 }
1568
1569 if (d.size()!=sizeof(EVENT)+dat.Roi*4*1440)
1570 {
1571 cerr << "Size mismatch in " << d.name << ": Found=" << d.size() << " Expected=" << dat.Roi*4*1440+sizeof(EVENT) << " [roi=" << dat.Roi << "]" << endl;
1572 return;
1573 }
1574
1575 delete fEventData;
1576 fEventData = reinterpret_cast<EVENT*>(new char[d.size()]);
1577 memcpy(fEventData, d.ptr<void>(), d.size());
1578
1579 DisplayEventData();
1580 }
1581
1582 void handleFadEventData(const DimData &d)
1583 {
1584 if (!CheckSize(d, 4*1440*sizeof(float)))
1585 return;
1586
1587 const float *ptr = d.ptr<float>();
1588
1589 valarray<double> arr1(1440);
1590 valarray<double> arr2(1440);
1591 valarray<double> arr3(1440);
1592 valarray<double> arr4(1440);
1593
1594 for (vector<PixelMapEntry>::const_iterator it=fPixelMap.begin(); it!=fPixelMap.end(); it++)
1595 {
1596 arr1[it->index] = ptr[0*1440+it->hw()];
1597 arr2[it->index] = ptr[1*1440+it->hw()];
1598 arr3[it->index] = ptr[2*1440+it->hw()];
1599 arr4[it->index] = ptr[3*1440+it->hw()];
1600 }
1601
1602 fEventCanv1->SetData(arr1);
1603 fEventCanv2->SetData(arr2);
1604 fEventCanv3->SetData(arr3);
1605 fEventCanv4->SetData(arr4);
1606 }
1607
1608 vector<float> fDrsCalibration;
1609
1610 void handleFadDrsCalibration(const DimData &d)
1611 {
1612 if (d.size()==0)
1613 {
1614 fDrsCalibBaseline->setValue(0);
1615 fDrsCalibGain->setValue(0);
1616 fDrsCalibTrgOffset->setValue(0);
1617 fDrsCalibration.assign(1024*1440*6, 0);
1618 DisplayEventData();
1619 return;
1620 }
1621
1622 if (!CheckSize(d, 1024*1440*6*sizeof(float)+3*sizeof(uint32_t)))
1623 // Do WHAT?
1624 return;
1625
1626 const uint32_t *run = d.ptr<uint32_t>();
1627
1628 fDrsCalibBaseline->setValue(run[0]);
1629 fDrsCalibGain->setValue(run[1]);
1630 fDrsCalibTrgOffset->setValue(run[2]);
1631
1632 const float *dat = d.ptr<float>(sizeof(uint32_t)*3);
1633 fDrsCalibration.assign(dat, dat+1024*1440*6);
1634
1635 DisplayEventData();
1636 }
1637
1638// vector<uint8_t> fFadConnections;
1639
1640 void handleFadConnections(const DimData &d)
1641 {
1642 if (!CheckSize(d, 41))
1643 {
1644 fStatusEventBuilderLabel->setText("Offline");
1645 fStatusEventBuilderLabel->setToolTip("FADs or fadctrl seems to be offline.");
1646 fEvtBldWidget->setEnabled(false);
1647
1648 SetLedColor(fStatusEventBuilderLed, kLedGray, d.time);
1649 return;
1650 }
1651
1652 const uint8_t *ptr = d.ptr<uint8_t>();
1653
1654 for (int i=0; i<40; i++)
1655 {
1656 const uint8_t stat1 = ptr[i]&3;
1657 const uint8_t stat2 = ptr[i]>>3;
1658
1659 if (stat1==0 && stat2==0)
1660 {
1661 SetLedColor(fFadLED[i], kLedGray, d.time);
1662 continue;
1663 }
1664 if (stat1==2 && stat2==8)
1665 {
1666 SetLedColor(fFadLED[i], kLedGreen, d.time);
1667 continue;
1668 }
1669
1670 if (stat1==1 && stat2==1)
1671 SetLedColor(fFadLED[i], kLedRed, d.time);
1672 else
1673 SetLedColor(fFadLED[i], kLedOrange, d.time);
1674 }
1675
1676
1677 const bool runs = ptr[40]!=0;
1678
1679 fStatusEventBuilderLabel->setText(runs?"Running":"Not running");
1680 fStatusEventBuilderLabel->setToolTip(runs?"Event builder thread running.":"Event builder thread stopped.");
1681 fEvtBldWidget->setEnabled(runs);
1682
1683 SetLedColor(fStatusEventBuilderLed, runs?kLedGreen:kLedRed, d.time);
1684
1685// fFadConnections.assign(ptr, ptr+40);
1686 }
1687
1688 template<typename T>
1689 void handleFadToolTip(const Time &time, QWidget *w, T *ptr)
1690 {
1691 ostringstream tip;
1692 tip << "<table border='1'><tr><th colspan='11'>" << time.GetAsStr() << " (UTC)</th></tr><tr><th></th>";
1693 for (int b=0; b<10; b++)
1694 tip << "<th>" << b << "</th>";
1695 tip << "</tr>";
1696
1697 for (int c=0; c<4; c++)
1698 {
1699 tip << "<tr><th>" << c << "</th>";
1700 for (int b=0; b<10; b++)
1701 tip << "<td>" << ptr[c*10+b] << "</td>";
1702 tip << "</tr>";
1703 }
1704 tip << "</table>";
1705
1706 w->setToolTip(tip.str().c_str());
1707 }
1708
1709 template<typename T, class S>
1710 void handleFadMinMax(const DimData &d, QPushButton *led, S *wmin, S *wmax=0)
1711 {
1712 if (!CheckSize(d, 42*sizeof(T)))
1713 return;
1714
1715 const T *ptr = d.ptr<T>();
1716 const T min = ptr[40];
1717 const T max = ptr[41];
1718
1719 if (max==0 && min>max)
1720 SetLedColor(led, kLedGray, d.time);
1721 else
1722 SetLedColor(led, min==max?kLedGreen: kLedOrange, d.time);
1723
1724 if (!wmax && max!=min)
1725 wmin->setValue(0);
1726 else
1727 wmin->setValue(min);
1728
1729 if (wmax)
1730 wmax->setValue(max);
1731
1732 handleFadToolTip(d.time, led, ptr);
1733 }
1734
1735 void handleFadFwVersion(const DimData &d)
1736 {
1737 handleFadMinMax<float, QDoubleSpinBox>(d, fFadLedFwVersion, fFadFwVersion);
1738 }
1739
1740 void handleFadRunNumber(const DimData &d)
1741 {
1742 handleFadMinMax<uint32_t, QSpinBox>(d, fFadLedRunNumber, fFadRunNumber);
1743 }
1744
1745 void handleFadPrescaler(const DimData &d)
1746 {
1747 handleFadMinMax<uint16_t, QSpinBox>(d, fFadLedPrescaler, fFadPrescaler);
1748 }
1749
1750 void handleFadDNA(const DimData &d)
1751 {
1752 if (!CheckSize(d, 40*sizeof(uint64_t)))
1753 return;
1754
1755 const uint64_t *ptr = d.ptr<uint64_t>();
1756
1757 ostringstream tip;
1758 tip << "<table width='100%'>";
1759 tip << "<tr><th>Crate</th><td></td><th>Board</th><td></td><th>DNA</th></tr>";
1760
1761 for (int i=0; i<40; i++)
1762 {
1763 tip << dec;
1764 tip << "<tr>";
1765 tip << "<td align='center'>" << i/10 << "</td><td>:</td>";
1766 tip << "<td align='center'>" << i%10 << "</td><td>:</td>";
1767 tip << hex;
1768 tip << "<td>0x" << setfill('0') << setw(16) << ptr[i] << "</td>";
1769 tip << "</tr>";
1770 }
1771 tip << "</table>";
1772
1773 fFadDNA->setText(tip.str().c_str());
1774 }
1775
1776 void SetFadLed(QPushButton *led, const DimData &d, uint16_t bitmask, bool invert=false)
1777 {
1778 if (d.size()==0)
1779 {
1780 SetLedColor(led, kLedGray, d.time);
1781 return;
1782 }
1783
1784 const bool quality = d.ptr<uint16_t>()[0]&bitmask;
1785 const bool value = d.ptr<uint16_t>()[1]&bitmask;
1786 const uint16_t *ptr = d.ptr<uint16_t>()+2;
1787
1788 SetLedColor(led, quality?kLedOrange:(value^invert?kLedGreen:kLedRed), d.time);
1789
1790 ostringstream tip;
1791 tip << "<table border='1'><tr><th colspan='11'>" << d.time.GetAsStr() << " (UTC)</th></tr><tr><th></th>";
1792 for (int b=0; b<10; b++)
1793 tip << "<th>" << b << "</th>";
1794 tip << "</tr>";
1795
1796 /*
1797 tip << "<tr>" << hex;
1798 tip << "<th>" << d.ptr<uint16_t>()[0] << " " << (d.ptr<uint16_t>()[0]&bitmask) << "</th>";
1799 tip << "<th>" << d.ptr<uint16_t>()[1] << " " << (d.ptr<uint16_t>()[1]&bitmask) << "</th>";
1800 tip << "</tr>";
1801 */
1802
1803 for (int c=0; c<4; c++)
1804 {
1805 tip << "<tr><th>" << dec << c << "</th>" << hex;
1806 for (int b=0; b<10; b++)
1807 {
1808 tip << "<td>"
1809 << (ptr[c*10+b]&bitmask)
1810 << "</td>";
1811 }
1812 tip << "</tr>";
1813 }
1814 tip << "</table>";
1815
1816 led->setToolTip(tip.str().c_str());
1817 }
1818
1819 void handleFadStatus(const DimData &d)
1820 {
1821 if (d.size()!=0 && !CheckSize(d, 42*sizeof(uint16_t)))
1822 return;
1823
1824 SetFadLed(fFadLedDrsEnabled, d, FAD::EventHeader::kDenable);
1825 SetFadLed(fFadLedDrsWrite, d, FAD::EventHeader::kDwrite);
1826 SetFadLed(fFadLedDcmLocked, d, FAD::EventHeader::kDcmLocked);
1827 SetFadLed(fFadLedDcmReady, d, FAD::EventHeader::kDcmReady);
1828 SetFadLed(fFadLedSpiSclk, d, FAD::EventHeader::kSpiSclk);
1829 SetFadLed(fFadLedRefClockTooLow, d, FAD::EventHeader::kRefClkTooLow, true);
1830 SetFadLed(fFadLedBusyOn, d, FAD::EventHeader::kBusyOn);
1831 SetFadLed(fFadLedBusyOff, d, FAD::EventHeader::kBusyOff);
1832 SetFadLed(fFadLedTriggerLine, d, FAD::EventHeader::kTriggerLine);
1833 SetFadLed(fFadLedContTrigger, d, FAD::EventHeader::kContTrigger);
1834 SetFadLed(fFadLedSocket, d, FAD::EventHeader::kSock17);
1835 SetFadLed(fFadLedPllLock, d, 0xf000);
1836 }
1837
1838 void handleFadStatistics1(const DimData &d)
1839 {
1840 if (!CheckSize(d, sizeof(GUI_STAT)))
1841 return;
1842
1843 const GUI_STAT &stat = d.ref<GUI_STAT>();
1844
1845 /*
1846 //info about status of the main threads
1847 int32_t readStat ; //read thread
1848 int32_t procStat ; //processing thread(s)
1849 int32_t writStat ; //write thread
1850 */
1851
1852 fFadBufferMax->setValue(stat.totMem/1000000);
1853 fFadBuffer->setMaximum(stat.totMem/100);
1854 fFadBuffer->setValue((stat.maxMem>stat.totMem?stat.totMem:stat.maxMem)/100); // Max mem used in last second
1855
1856 uint32_t sum = 0;
1857 int32_t min = 0x7fffff;
1858 int32_t max = 0;
1859
1860 int cnt = 0;
1861 int err = 0;
1862
1863 for (int i=0; i<40; i++)
1864 {
1865 if (stat.numConn[i]!=7)
1866 continue;
1867
1868 cnt++;
1869
1870 sum += stat.rateBytes[i];
1871 err += stat.errConn[i];
1872
1873 if (stat.rateBytes[i]<min)
1874 min = stat.rateBytes[i];
1875 if (stat.rateBytes[i]>max)
1876 max = stat.rateBytes[i];
1877 }
1878
1879 fFadEvtConn->setValue(cnt);
1880 fFadEvtConnErr->setValue(err);
1881
1882 fFadEvtBufNew->setValue(stat.bufNew); // Incomplete in buffer
1883 fFadEvtBufEvt->setValue(stat.bufEvt); // Complete in buffer
1884 fFadEvtBufMax->setValue(stat.maxEvt); // Complete in buffer
1885 fFadEvtWrite->setValue(stat.evtWrite-stat.evtSkip-stat.evtErr);
1886 fFadEvtSkip->setValue(stat.evtSkip);
1887 fFadEvtErr->setValue(stat.evtErr);
1888
1889 if (stat.deltaT==0)
1890 return;
1891
1892 fFadEthernetRateMin->setValue(min/stat.deltaT);
1893 fFadEthernetRateMax->setValue(max/stat.deltaT);
1894 fFadEthernetRateTot->setValue(sum/stat.deltaT);
1895 fFadEthernetRateAvg->setValue(cnt==0 ? 0 : sum/cnt/stat.deltaT);
1896 fFadEvtRateNew->setValue(1000*stat.rateNew/stat.deltaT);
1897 fFadEvtRateWrite->setValue(1000*stat.rateWrite/stat.deltaT);
1898
1899 fFadTransmission->setValue(fFadEvtRateNew->value());
1900 fFadEthernet->setValue(fFadEthernetRateTot->value());
1901 fFadWriteRate->setValue(fFadEvtRateWrite->value());
1902 }
1903
1904 void handleFadStatistics2(const DimData &d)
1905 {
1906 if (!CheckSize(d, sizeof(EVT_STAT)))
1907 return;
1908
1909 //const EVT_STAT &stat = d.ref<EVT_STAT>();
1910
1911 /*
1912 //some info about what happened since start of program (or last 'reset')
1913 uint32_t reset ; //#if increased, reset all counters
1914 uint32_t numRead[MAX_SOCK] ; //how often succesfull read from N sockets per loop
1915
1916 uint64_t gotByte[NBOARDS] ; //#Bytes read per Board
1917 uint32_t gotErr[NBOARDS] ; //#Communication Errors per Board
1918
1919 uint32_t evtGet; //#new Start of Events read
1920 uint32_t evtTot; //#complete Events read
1921
1922 uint32_t evtErr; //#Events with Errors
1923 uint32_t evtSkp; //#Events incomplete (timeout)
1924
1925
1926 uint32_t procTot; //#Events processed
1927 uint32_t procErr; //#Events showed problem in processing
1928 uint32_t procTrg; //#Events accepted by SW trigger
1929 uint32_t procSkp; //#Events rejected by SW trigger
1930
1931 uint32_t feedTot; //#Events used for feedBack system
1932 uint32_t feedErr; //#Events rejected by feedBack
1933
1934 uint32_t wrtTot; //#Events written to disk
1935 uint32_t wrtErr; //#Events with write-error
1936
1937 uint32_t runOpen; //#Runs opened
1938 uint32_t runClose; //#Runs closed
1939 uint32_t runErr; //#Runs with open/close errors
1940
1941
1942 //info about current connection status
1943 uint8_t numConn[NBOARDS] ; //#Sockets succesfully open per board
1944 */
1945 }
1946
1947 // ===================== FTM ============================================
1948
1949 void UpdateTriggerRate(const FTM::DimTriggerRates &sdata)
1950 {
1951#ifdef HAVE_ROOT
1952 TCanvas *c = fFtmRateCanv->GetCanvas();
1953
1954 TH1 *h = (TH1*)c->FindObject("TimeFrame");
1955
1956 if (sdata.fTriggerRate<0)
1957 {
1958 fGraphFtmRate.Set(0);
1959
1960 const double tm = Time().RootTime();
1961
1962 h->SetBins(1, tm, tm+60);
1963 h->GetXaxis()->SetTimeFormat("%M'%S\"");
1964 h->GetXaxis()->SetTitle("Time");
1965
1966 c->Modified();
1967 c->Update();
1968 return;
1969 }
1970
1971 const double t1 = h->GetXaxis()->GetXmax();
1972 const double t0 = h->GetXaxis()->GetXmin();
1973
1974 const double now = t0+sdata.fTimeStamp/1000000.;
1975
1976 h->SetBins(h->GetNbinsX()+1, t0, now+1);
1977 fGraphFtmRate.SetPoint(fGraphFtmRate.GetN(), now, sdata.fTriggerRate);
1978
1979 if (t1-t0>60)
1980 {
1981 h->GetXaxis()->SetTimeFormat("%Hh%M'");
1982 h->GetXaxis()->SetTitle("Time");
1983 }
1984
1985 h->SetMinimum(0);
1986
1987 c->Modified();
1988 c->Update();
1989#endif
1990 }
1991
1992 void UpdateRatesCam(const FTM::DimTriggerRates &sdata)
1993 {
1994 if (fThresholdIdx->value()>=0)
1995 {
1996 const int isw = fThresholdIdx->value();
1997 const int ihw = fPatchMapHW[isw];
1998 fPatchRate->setValue(sdata.fPatchRate[ihw]);
1999 }
2000
2001 valarray<double> dat(0., 1440);
2002
2003 // fPatch converts from software id to software patch id
2004 for (int i=0; i<1440; i++)
2005 {
2006 const int ihw = fPatchHW[i];
2007// const int isw = fPatch[i];
2008// const int ihw = fPatchMapHW[isw];
2009 dat[i] = sdata.fPatchRate[ihw];
2010
2011 fRatesCanv->SetEnable(ihw, fFtuStatus[ihw/4]);
2012 }
2013
2014 fRatesCanv->SetData(dat);
2015 }
2016
2017 int64_t fTimeStamp0;
2018
2019 void UpdateRatesGraphs(const FTM::DimTriggerRates &sdata)
2020 {
2021#ifdef HAVE_ROOT
2022 if (fTimeStamp0<0)
2023 {
2024 fTimeStamp0 = sdata.fTimeStamp;
2025 return;
2026 }
2027
2028 TCanvas *c = fFtmRateCanv->GetCanvas();
2029
2030 TH1 *h = (TH1*)c->FindObject("TimeFrame");
2031
2032 const double tdiff = sdata.fTimeStamp-fTimeStamp0;
2033 fTimeStamp0 = sdata.fTimeStamp;
2034
2035 if (tdiff<0)
2036 {
2037 for (int i=0; i<160; i++)
2038 fGraphPatchRate[i].Set(0);
2039 for (int i=0; i<40; i++)
2040 fGraphBoardRate[i].Set(0);
2041
2042 return;
2043 }
2044
2045 //const double t1 = h->GetXaxis()->GetXmax();
2046 const double t0 = h->GetXaxis()->GetXmin();
2047
2048 for (int i=0; i<160; i++)
2049 if (fFtuStatus[i/4]>0)
2050 fGraphPatchRate[i].SetPoint(fGraphPatchRate[i].GetN(),
2051 t0+sdata.fTimeStamp/1000000., sdata.fPatchRate[i]);
2052 for (int i=0; i<40; i++)
2053 if (fFtuStatus[i]>0)
2054 fGraphBoardRate[i].SetPoint(fGraphBoardRate[i].GetN(),
2055 t0+sdata.fTimeStamp/1000000., sdata.fBoardRate[i]);
2056
2057 c->Modified();
2058 c->Update();
2059#endif
2060 }
2061
2062 void handleFtmTriggerRates(const DimData &d)
2063 {
2064 if (!CheckSize(d, sizeof(FTM::DimTriggerRates)))
2065 return;
2066
2067 const FTM::DimTriggerRates &sdata = d.ref<FTM::DimTriggerRates>();
2068
2069 fFtmTime->setText(QString::number(sdata.fTimeStamp/1000000., 'f', 6)+ " s");
2070 fTriggerCounter->setText(QString::number(sdata.fTriggerCounter));
2071
2072 if (sdata.fTimeStamp>0)
2073 fTriggerCounterRate->setValue(1000000.*sdata.fTriggerCounter/sdata.fTimeStamp);
2074 else
2075 fTriggerCounterRate->setValue(0);
2076
2077 // ----------------------------------------------
2078
2079 fOnTime->setText(QString::number(sdata.fOnTimeCounter/1000000., 'f', 6)+" s");
2080
2081 if (sdata.fTimeStamp>0)
2082 fOnTimeRel->setValue(100.*sdata.fOnTimeCounter/sdata.fTimeStamp);
2083 else
2084 fOnTimeRel->setValue(0);
2085
2086 // ----------------------------------------------
2087
2088 UpdateTriggerRate(sdata);
2089 UpdateRatesGraphs(sdata);
2090 UpdateRatesCam(sdata);
2091 }
2092
2093 void handleFtmCounter(const DimData &d)
2094 {
2095 if (!CheckSize(d, sizeof(uint32_t)*6))
2096 return;
2097
2098 const uint32_t *sdata = d.ptr<uint32_t>();
2099
2100 fFtmCounterH->setValue(sdata[0]);
2101 fFtmCounterS->setValue(sdata[1]);
2102 fFtmCounterD->setValue(sdata[2]);
2103 fFtmCounterF->setValue(sdata[3]);
2104 fFtmCounterE->setValue(sdata[4]);
2105 fFtmCounterR->setValue(sdata[5]);
2106 }
2107
2108 void handleFtmDynamicData(const DimData &d)
2109 {
2110 if (!CheckSize(d, sizeof(FTM::DimDynamicData)))
2111 return;
2112
2113 const FTM::DimDynamicData &sdata = d.ref<FTM::DimDynamicData>();
2114
2115 fFtmTemp0->setValue(sdata.fTempSensor[0]*0.1);
2116 fFtmTemp1->setValue(sdata.fTempSensor[1]*0.1);
2117 fFtmTemp2->setValue(sdata.fTempSensor[2]*0.1);
2118 fFtmTemp3->setValue(sdata.fTempSensor[3]*0.1);
2119
2120 SetLedColor(fClockCondLed, sdata.fState&FTM::kFtmLocked ? kLedGreen : kLedRed, d.time);
2121 }
2122
2123 void DisplayRates()
2124 {
2125#ifdef HAVE_ROOT
2126 TCanvas *c = fFtmRateCanv->GetCanvas();
2127
2128 while (c->FindObject("PatchRate"))
2129 c->GetListOfPrimitives()->Remove(c->FindObject("PatchRate"));
2130
2131 while (c->FindObject("BoardRate"))
2132 c->GetListOfPrimitives()->Remove(c->FindObject("BoardRate"));
2133
2134 c->cd();
2135
2136 if (fRatePatch1->value()>=0)
2137 {
2138 fGraphPatchRate[fRatePatch1->value()].SetLineColor(kRed);
2139 fGraphPatchRate[fRatePatch1->value()].SetMarkerColor(kRed);
2140 fGraphPatchRate[fRatePatch1->value()].Draw("PL");
2141 }
2142 if (fRatePatch2->value()>=0)
2143 {
2144 fGraphPatchRate[fRatePatch2->value()].SetLineColor(kGreen);
2145 fGraphPatchRate[fRatePatch2->value()].SetMarkerColor(kGreen);
2146 fGraphPatchRate[fRatePatch2->value()].Draw("PL");
2147 }
2148 if (fRateBoard1->value()>=0)
2149 {
2150 fGraphBoardRate[fRateBoard1->value()].SetLineColor(kMagenta);
2151 fGraphBoardRate[fRateBoard1->value()].SetMarkerColor(kMagenta);
2152 fGraphBoardRate[fRateBoard1->value()].Draw("PL");
2153 }
2154 if (fRateBoard2->value()>=0)
2155 {
2156 fGraphBoardRate[fRateBoard2->value()].SetLineColor(kCyan);
2157 fGraphBoardRate[fRateBoard2->value()].SetMarkerColor(kCyan);
2158 fGraphBoardRate[fRateBoard2->value()].Draw("PL");
2159 }
2160#endif
2161 }
2162
2163 FTM::DimStaticData fFtmStaticData;
2164
2165 void SetFtuLed(int idx, int counter, const Time &t)
2166 {
2167 if (counter==0 || counter>3)
2168 counter = 3;
2169
2170 if (counter<0)
2171 counter = 0;
2172
2173 const LedColor_t col[4] = { kLedGray, kLedGreen, kLedOrange, kLedRed };
2174
2175 SetLedColor(fFtuLED[idx], col[counter], t);
2176
2177 fFtuStatus[idx] = counter;
2178 }
2179
2180 void SetFtuStatusLed(const Time &t)
2181 {
2182 const int max = fFtuStatus.max();
2183
2184 switch (max)
2185 {
2186 case 0:
2187 SetLedColor(fStatusFTULed, kLedGray, t);
2188 fStatusFTULabel->setText("All disabled");
2189 fStatusFTULabel->setToolTip("All FTUs are disabled");
2190 break;
2191
2192 case 1:
2193 SetLedColor(fStatusFTULed, kLedGreen, t);
2194 fStatusFTULabel->setToolTip("Communication with FTU is smooth.");
2195 fStatusFTULabel->setText("ok");
2196 break;
2197
2198 case 2:
2199 SetLedColor(fStatusFTULed, kLedOrange, t);
2200 fStatusFTULabel->setText("Warning");
2201 fStatusFTULabel->setToolTip("At least one FTU didn't answer immediately");
2202 break;
2203
2204 case 3:
2205 SetLedColor(fStatusFTULed, kLedRed, t);
2206 fStatusFTULabel->setToolTip("At least one FTU didn't answer!");
2207 fStatusFTULabel->setText("ERROR");
2208 break;
2209 }
2210
2211 const int cnt = count(&fFtuStatus[0], &fFtuStatus[40], 0);
2212 fFtuAllOn->setEnabled(cnt!=0);
2213 fFtuAllOff->setEnabled(cnt!=40);
2214 }
2215
2216 void handleFtmStaticData(const DimData &d)
2217 {
2218 if (!CheckSize(d, sizeof(FTM::DimStaticData)))
2219 return;
2220
2221 const FTM::DimStaticData &sdata = d.ref<FTM::DimStaticData>();
2222
2223 fTriggerInterval->setValue(sdata.fTriggerInterval);
2224 fPhysicsCoincidence->setValue(sdata.fMultiplicityPhysics);
2225 fCalibCoincidence->setValue(sdata.fMultiplicityCalib);
2226 fPhysicsWindow->setValue(sdata.fWindowPhysics);
2227 fCalibWindow->setValue(sdata.fWindowCalib);
2228
2229 fTriggerDelay->setValue(sdata.fDelayTrigger);
2230 fTimeMarkerDelay->setValue(sdata.fDelayTimeMarker);
2231 fDeadTime->setValue(sdata.fDeadTime);
2232
2233 fClockCondR0->setValue(sdata.fClockConditioner[0]);
2234 fClockCondR1->setValue(sdata.fClockConditioner[1]);
2235 fClockCondR8->setValue(sdata.fClockConditioner[2]);
2236 fClockCondR9->setValue(sdata.fClockConditioner[3]);
2237 fClockCondR11->setValue(sdata.fClockConditioner[4]);
2238 fClockCondR13->setValue(sdata.fClockConditioner[5]);
2239 fClockCondR14->setValue(sdata.fClockConditioner[6]);
2240 fClockCondR15->setValue(sdata.fClockConditioner[7]);
2241
2242 const uint32_t R0 = sdata.fClockConditioner[0];
2243 const uint32_t R14 = sdata.fClockConditioner[6];
2244 const uint32_t R15 = sdata.fClockConditioner[7];
2245
2246 const uint32_t Ndiv = (R15&0x1ffff00)<<2;
2247 const uint32_t Rdiv = (R14&0x007ff00)>>8;
2248 const uint32_t Cdiv = (R0 &0x000ff00)>>8;
2249
2250 double freq = 40.*Ndiv/(Rdiv*Cdiv);
2251
2252 fClockCondFreqRes->setValue(freq);
2253
2254 //fClockCondFreq->setEditText("");
2255 fClockCondFreq->setCurrentIndex(0);
2256
2257 fTriggerSeqPed->setValue(sdata.fTriggerSeqPed);
2258 fTriggerSeqLPint->setValue(sdata.fTriggerSeqLPint);
2259 fTriggerSeqLPext->setValue(sdata.fTriggerSeqLPext);
2260
2261 fLpIntIntensity->setValue(sdata.fIntensityLPint);
2262 fLpExtIntensity->setValue(sdata.fIntensityLPext);
2263
2264 fLpIntGroup1->setChecked(sdata.HasLPintG1());
2265 fLpIntGroup2->setChecked(sdata.HasLPintG2());
2266 fLpExtGroup1->setChecked(sdata.HasLPextG1());
2267 fLpExtGroup2->setChecked(sdata.HasLPextG2());
2268
2269 fEnableTrigger->setChecked(sdata.HasTrigger());
2270 fEnableVeto->setChecked(sdata.HasVeto());
2271 fEnableExt1->setChecked(sdata.HasExt1());
2272 fEnableExt2->setChecked(sdata.HasExt2());
2273 fEnableClockCond->setChecked(sdata.HasClockConditioner());
2274
2275 for (int i=0; i<40; i++)
2276 {
2277 if (!sdata.IsActive(i))
2278 SetFtuLed(i, -1, d.time);
2279 else
2280 {
2281 if (fFtuStatus[i]==0)
2282 SetFtuLed(i, 1, d.time);
2283 }
2284 fFtuLED[i]->setChecked(false);
2285 }
2286 SetFtuStatusLed(d.time);
2287
2288 for (vector<PixelMapEntry>::const_iterator it=fPixelMap.begin(); it!=fPixelMap.end(); it++)
2289 fRatesCanv->SetEnable(it->index, sdata.IsEnabled(it->hw()));
2290
2291 const PixelMapEntry &entry = fPixelMap.index(fPixelIdx->value());
2292 fPixelEnable->setChecked(sdata.IsEnabled(entry.index));
2293
2294 if (fThresholdIdx->value()>=0)
2295 {
2296 const int isw = fThresholdIdx->value();
2297 const int ihw = fPatchMapHW[isw];
2298 fThresholdVal->setValue(sdata.fThreshold[ihw]);
2299 }
2300
2301 fPrescalingVal->setValue(sdata.fPrescaling[0]);
2302
2303 fFtmStaticData = sdata;
2304 }
2305
2306 void handleFtmPassport(const DimData &d)
2307 {
2308 if (!CheckSize(d, sizeof(FTM::DimPassport)))
2309 return;
2310
2311 const FTM::DimPassport &sdata = d.ref<FTM::DimPassport>();
2312
2313 stringstream str1, str2;
2314 str1 << hex << "0x" << setfill('0') << setw(16) << sdata.fBoardId;
2315 str2 << sdata.fFirmwareId;
2316
2317 fFtmBoardId->setText(str1.str().c_str());
2318 fFtmFirmwareId->setText(str2.str().c_str());
2319 }
2320
2321 void handleFtmFtuList(const DimData &d)
2322 {
2323 if (!CheckSize(d, sizeof(FTM::DimFtuList)))
2324 return;
2325
2326 fFtuPing->setChecked(false);
2327
2328 const FTM::DimFtuList &sdata = d.ref<FTM::DimFtuList>();
2329
2330 stringstream str;
2331 str << "<table width='100%'>" << setfill('0');
2332 str << "<tr><th>Num</th><th></th><th>Addr</th><th></th><th>DNA</th></tr>";
2333 for (int i=0; i<40; i++)
2334 {
2335 str << "<tr>";
2336 str << "<td align='center'>" << dec << i << hex << "</td>";
2337 str << "<td align='center'>:</td>";
2338 str << "<td align='center'>0x" << setw(2) << (int)sdata.fAddr[i] << "</td>";
2339 str << "<td align='center'>:</td>";
2340 str << "<td align='center'>0x" << setw(16) << sdata.fDNA[i] << "</td>";
2341 str << "</tr>";
2342 }
2343 str << "</table>";
2344
2345 fFtuDNA->setText(str.str().c_str());
2346
2347 fFtuAnswersTotal->setValue(sdata.fNumBoards);
2348 fFtuAnswersCrate0->setValue(sdata.fNumBoardsCrate[0]);
2349 fFtuAnswersCrate1->setValue(sdata.fNumBoardsCrate[1]);
2350 fFtuAnswersCrate2->setValue(sdata.fNumBoardsCrate[2]);
2351 fFtuAnswersCrate3->setValue(sdata.fNumBoardsCrate[3]);
2352
2353 for (int i=0; i<40; i++)
2354 SetFtuLed(i, sdata.IsActive(i) ? sdata.fPing[i] : -1, d.time);
2355
2356 SetFtuStatusLed(d.time);
2357 }
2358
2359 void handleFtmError(const DimData &d)
2360 {
2361 if (!CheckSize(d, sizeof(FTM::DimError)))
2362 return;
2363
2364 const FTM::DimError &sdata = d.ref<FTM::DimError>();
2365
2366 SetFtuLed(sdata.fError.fDestAddress, sdata.fError.fNumCalls, d.time);
2367 SetFtuStatusLed(d.time);
2368
2369 // FIXME: Write to special window!
2370 //Out() << "Error:" << endl;
2371 //Out() << sdata.fError << endl;
2372 }
2373
2374 // ========================== FSC =======================================
2375
2376 void SetFscValue(QDoubleSpinBox *box, const DimData &d, int idx, bool enable)
2377 {
2378 box->setEnabled(enable);
2379 if (!enable)
2380 {
2381 box->setToolTip(d.time.GetAsStr().c_str());
2382 return;
2383 }
2384
2385 ostringstream str;
2386 str << d.time << " -- " << d.get<float>() << "s";
2387
2388 box->setToolTip(str.str().c_str());
2389 box->setValue(d.get<float>(idx*4+4));
2390 }
2391
2392
2393 void handleFscTemp(const DimData &d)
2394 {
2395 const bool enable = d.size()>0 && CheckSize(d, 60*sizeof(float));
2396
2397 QDoubleSpinBox *boxes[] = {
2398 fTempCam00, fTempCam01,
2399 fTempCam10, fTempCam11, fTempCam12, fTempCam13, fTempCam14,
2400 fTempCam20, fTempCam21, fTempCam22, fTempCam23, fTempCam24, fTempCam25,
2401 fTempCam30, fTempCam31, fTempCam32, fTempCam33, fTempCam34,
2402 fTempCam40, fTempCam41, fTempCam42, fTempCam43, fTempCam44, fTempCam45,
2403 fTempCam50, fTempCam51, fTempCam52, fTempCam53, fTempCam54,
2404 fTempCam60, fTempCam61,
2405 fTempCrate00, fTempCrate01, fTempCrate10, fTempCrate11,
2406 fTempCrate20, fTempCrate21, fTempCrate30, fTempCrate31,
2407 fTempPS00, fTempPS01, fTempPS10, fTempPS11,
2408 fTempPS20, fTempPS21, fTempPS30, fTempPS31,
2409 fTempAux0a, fTempAux0b, fTempAux1a, fTempAux1b,
2410 fTempBackpanel0a, fTempBackpanel0b, fTempBackpanel1a, fTempBackpanel1b,
2411 fTempSwitchbox0a, fTempSwitchbox0b, fTempSwitchbox1a, fTempSwitchbox1b,
2412 };
2413
2414 for (int i=0; i<59; i++)
2415 SetFscValue(boxes[i], d, i, enable);
2416 }
2417
2418 void handleFscVolt(const DimData &d)
2419 {
2420 const bool enable = d.size()>0 && CheckSize(d, 31*sizeof(float));
2421
2422 QDoubleSpinBox *boxes[] = {
2423 fVoltFad00, fVoltFad10, fVoltFad20, fVoltFad30,
2424 fVoltFad01, fVoltFad11, fVoltFad21, fVoltFad31,
2425 fVoltFad02, fVoltFad12, fVoltFad22, fVoltFad32,
2426 fVoltFPA00, fVoltFPA10, fVoltFPA20, fVoltFPA30,
2427 fVoltFPA01, fVoltFPA11, fVoltFPA21, fVoltFPA31,
2428 fVoltFPA02, fVoltFPA12, fVoltFPA22, fVoltFPA32,
2429 fVoltETH0, fVoltETH1,
2430 fVoltFTM0, fVoltFTM1,
2431 fVoltFFC, fVoltFLP,
2432 };
2433
2434 for (int i=0; i<30; i++)
2435 SetFscValue(boxes[i], d, i, enable);
2436 }
2437
2438 void handleFscCurrent(const DimData &d)
2439 {
2440 const bool enable = d.size()>0 && CheckSize(d, 31*sizeof(float));
2441
2442 QDoubleSpinBox *boxes[] = {
2443 fAmpFad00, fAmpFad10, fAmpFad20, fAmpFad30,
2444 fAmpFad01, fAmpFad11, fAmpFad21, fAmpFad31,
2445 fAmpFad02, fAmpFad12, fAmpFad22, fAmpFad32,
2446 fAmpFPA00, fAmpFPA10, fAmpFPA20, fAmpFPA30,
2447 fAmpFPA01, fAmpFPA11, fAmpFPA21, fAmpFPA31,
2448 fAmpFPA02, fAmpFPA12, fAmpFPA22, fAmpFPA32,
2449 fAmpETH0, fAmpETH1,
2450 fAmpFTM0, fAmpFTM1,
2451 fAmpFFC, fAmpFLP,
2452 };
2453
2454 for (int i=0; i<30; i++)
2455 SetFscValue(boxes[i], d, i, enable);
2456 }
2457
2458 void handleFscHumidity(const DimData &d)
2459 {
2460 const bool enable = d.size()>0 && CheckSize(d, 5*sizeof(float));
2461
2462 SetFscValue(fHumidity1, d, 0, enable);
2463 SetFscValue(fHumidity2, d, 1, enable);
2464 SetFscValue(fHumidity3, d, 2, enable);
2465 SetFscValue(fHumidity4, d, 3, enable);
2466 }
2467
2468 // ========================== FSC =======================================
2469
2470 vector<int16_t> fVecBiasVolt;
2471 vector<int16_t> fVecBiasCurrent;
2472
2473 void handleBiasVolt(const DimData &d)
2474 {
2475 if (!CheckSize(d, 416*sizeof(int16_t)))
2476 return;
2477
2478 const int16_t *ptr = d.ptr<int16_t>();
2479
2480 fVecBiasVolt.assign(ptr, ptr+416);
2481
2482 UpdateBiasValues();
2483 }
2484
2485 void handleBiasCurrent(const DimData &d)
2486 {
2487 if (!CheckSize(d, 416*sizeof(int16_t)))
2488 return;
2489
2490 const int16_t *ptr = d.ptr<int16_t>();
2491
2492 fVecBiasCurrent.assign(ptr, ptr+416);
2493
2494 valarray<double> dat(0., 1440);
2495
2496 // fPatch converts from software id to software patch id
2497 for (int i=0; i<1440; i++)
2498 {
2499 const PixelMapEntry &entry = fPixelMap.index(i);
2500
2501 // FIXME: Display Overcurrent
2502 dat[i] = abs(ptr[entry.hv()])*5000./4096;
2503
2504 fBiasCam->SetEnable(i, uint16_t(ptr[entry.hv()])!=0x8000);
2505 }
2506
2507 fBiasCam->SetData(dat);
2508
2509 UpdateBiasValues();
2510 }
2511
2512 // ====================== MessageImp ====================================
2513
2514 bool fChatOnline;
2515
2516 void handleStateChanged(const Time &time, const std::string &server,
2517 const State &s)
2518 {
2519 // FIXME: Prefix tooltip with time
2520 if (server=="FTM_CONTROL")
2521 {
2522 // FIXME: Enable FTU page!!!
2523 fStatusFTMLabel->setText(s.name.c_str());
2524 fStatusFTMLabel->setToolTip(s.comment.c_str());
2525
2526 bool enable = false;
2527
2528 if (s.index<FTM::StateMachine::kDisconnected) // No Dim connection
2529 SetLedColor(fStatusFTMLed, kLedGray, time);
2530 if (s.index==FTM::StateMachine::kDisconnected) // Dim connection / FTM disconnected
2531 SetLedColor(fStatusFTMLed, kLedYellow, time);
2532 if (s.index==FTM::StateMachine::kConnected ||
2533 s.index==FTM::StateMachine::kIdle ||
2534 s.index==FTM::StateMachine::kConfiguring1 ||
2535 s.index==FTM::StateMachine::kConfiguring2 ||
2536 s.index==FTM::StateMachine::kConfigured ||
2537 s.index==FTM::StateMachine::kTakingData) // Dim connection / FTM connected
2538 SetLedColor(fStatusFTMLed, kLedGreen, time);
2539
2540 if (s.index==FTM::StateMachine::kConnected ||
2541 s.index==FTM::StateMachine::kIdle) // Dim connection / FTM connected
2542 enable = true;
2543
2544 fTriggerWidget->setEnabled(enable);
2545 fFtuGroupEnable->setEnabled(enable);
2546 fRatesControls->setEnabled(enable);
2547 fFtuWidget->setEnabled(s.index>FTM::StateMachine::kDisconnected);
2548
2549 if (s.index>=FTM::StateMachine::kConnected)
2550 SetFtuStatusLed(time);
2551 else
2552 {
2553 SetLedColor(fStatusFTULed, kLedGray, time);
2554 fStatusFTULabel->setText("Offline");
2555 fStatusFTULabel->setToolTip("FTM is not online.");
2556 }
2557 }
2558
2559 if (server=="FAD_CONTROL")
2560 {
2561 fStatusFADLabel->setText(s.name.c_str());
2562 fStatusFADLabel->setToolTip(s.comment.c_str());
2563
2564 bool enable = false;
2565
2566 if (s.index<FAD::kOffline) // No Dim connection
2567 {
2568 SetLedColor(fStatusFADLed, kLedGray, time);
2569
2570 // Timing problem - sometimes they stay gray :(
2571 //for (int i=0; i<40; i++)
2572 // SetLedColor(fFadLED[i], kLedGray, time);
2573
2574 /*
2575 fStatusEventBuilderLabel->setText("Offline");
2576 fStatusEventBuilderLabel->setToolTip("No connection to fadctrl.");
2577 fEvtBldWidget->setEnabled(false);
2578
2579 SetLedColor(fStatusEventBuilderLed, kLedGray, time);
2580 */
2581 }
2582 if (s.index==FAD::kOffline) // Dim connection / FTM disconnected
2583 SetLedColor(fStatusFADLed, kLedRed, time);
2584 if (s.index==FAD::kDisconnected) // Dim connection / FTM disconnected
2585 SetLedColor(fStatusFADLed, kLedOrange, time);
2586 if (s.index==FAD::kConnecting) // Dim connection / FTM disconnected
2587 {
2588 SetLedColor(fStatusFADLed, kLedYellow, time);
2589 // FIXME FIXME FIXME: The LEDs are not displayed when disabled!
2590 enable = true;
2591 }
2592 if (s.index>=FAD::kConnected) // Dim connection / FTM connected
2593 {
2594 SetLedColor(fStatusFADLed, kLedGreen, time);
2595 enable = true;
2596 }
2597
2598 fFadWidget->setEnabled(enable);
2599 }
2600
2601 if (server=="FSC_CONTROL")
2602 {
2603 fStatusFSCLabel->setText(s.name.c_str());
2604 fStatusFSCLabel->setToolTip(s.comment.c_str());
2605
2606 bool enable = false;
2607
2608 if (s.index<1) // No Dim connection
2609 SetLedColor(fStatusFSCLed, kLedGray, time);
2610 if (s.index==1) // Dim connection / FTM disconnected
2611 SetLedColor(fStatusFSCLed, kLedRed, time);
2612 if (s.index>=2) // Dim connection / FTM disconnected
2613 {
2614 SetLedColor(fStatusFSCLed, kLedGreen, time);
2615 enable = true;
2616 }
2617
2618 fAuxWidget->setEnabled(enable);
2619 }
2620
2621 if (server=="BIAS_CONTROL")
2622 {
2623 fStatusBiasLabel->setText(s.name.c_str());
2624 fStatusBiasLabel->setToolTip(s.comment.c_str());
2625
2626 bool enable = false;
2627
2628 if (s.index<1) // No Dim connection
2629 SetLedColor(fStatusBiasLed, kLedGray, time);
2630 if (s.index==1) // Dim connection / FTM disconnected
2631 SetLedColor(fStatusBiasLed, kLedRed, time);
2632 if (s.index>=2) // Dim connection / FTM disconnected
2633 {
2634 SetLedColor(fStatusBiasLed, kLedGreen, time);
2635 enable = true;
2636 }
2637
2638 fBiasWidget->setEnabled(enable);
2639 }
2640
2641 if (server=="DATA_LOGGER")
2642 {
2643 fStatusLoggerLabel->setText(s.name.c_str());
2644 fStatusLoggerLabel->setToolTip(s.comment.c_str());
2645
2646 bool enable = true;
2647
2648 if (s.index<=30) // Ready/Waiting
2649 SetLedColor(fStatusLoggerLed, kLedYellow, time);
2650 if (s.index<-1) // Offline
2651 {
2652 SetLedColor(fStatusLoggerLed, kLedGray, time);
2653 enable = false;
2654 }
2655 if (s.index>=0x100) // Error
2656 SetLedColor(fStatusLoggerLed, kLedRed, time);
2657 if (s.index==40) // Logging
2658 SetLedColor(fStatusLoggerLed, kLedGreen, time);
2659
2660 fLoggerWidget->setEnabled(enable);
2661 }
2662
2663 if (server=="CHAT")
2664 {
2665 fStatusChatLabel->setText(s.name.c_str());
2666
2667 fChatOnline = s.index==0;
2668
2669 SetLedColor(fStatusChatLed, fChatOnline ? kLedGreen : kLedGray, time);
2670
2671 fChatSend->setEnabled(fChatOnline);
2672 fChatMessage->setEnabled(fChatOnline);
2673 }
2674
2675 if (server=="SCHEDULER")
2676 {
2677 fStatusSchedulerLabel->setText(s.name.c_str());
2678
2679 SetLedColor(fStatusSchedulerLed, s.index>=0 ? kLedGreen : kLedRed, time);
2680 }
2681 }
2682
2683 void on_fTabWidget_currentChanged(int which)
2684 {
2685 if (fTabWidget->tabText(which)=="Chat")
2686 fTabWidget->setTabIcon(which, QIcon());
2687 }
2688
2689 void handleWrite(const Time &time, const string &text, int qos)
2690 {
2691 stringstream out;
2692
2693 if (text.substr(0, 6)=="CHAT: ")
2694 {
2695 if (qos==MessageImp::kDebug)
2696 return;
2697
2698 out << "<font size='-1' color='navy'>[<B>";
2699 out << time.GetAsStr("%H:%M:%S");
2700 out << "</B>]</FONT> " << text.substr(6);
2701 fChatText->append(out.str().c_str());
2702
2703 if (fTabWidget->tabText(fTabWidget->currentIndex())=="Chat")
2704 return;
2705
2706 static int num = 0;
2707 if (num++<2)
2708 return;
2709
2710 for (int i=0; i<fTabWidget->count(); i++)
2711 if (fTabWidget->tabText(i)=="Chat")
2712 {
2713 fTabWidget->setTabIcon(i, QIcon(":/Resources/icons/warning 3.png"));
2714 break;
2715 }
2716
2717 return;
2718 }
2719
2720
2721 out << "<font style='font-family:monospace' color='";
2722
2723 switch (qos)
2724 {
2725 case kMessage: out << "black"; break;
2726 case kInfo: out << "green"; break;
2727 case kWarn: out << "#FF6600"; break;
2728 case kError: out << "maroon"; break;
2729 case kFatal: out << "maroon"; break;
2730 case kDebug: out << "navy"; break;
2731 default: out << "navy"; break;
2732 }
2733 out << "'>";
2734 out << time.GetAsStr("%H:%M:%S.%f").substr(0,12);
2735 out << " - " << text << "</font>";
2736
2737 fLogText->append(out.str().c_str());
2738
2739 if (qos>=kWarn && qos!=kDebug)
2740 fTextEdit->append(out.str().c_str());
2741 }
2742
2743 void IndicateStateChange(const Time &time, const std::string &server)
2744 {
2745 const State s = GetState(server, GetCurrentState(server));
2746
2747 QApplication::postEvent(this,
2748 new FunctionEvent(boost::bind(&FactGui::handleStateChanged, this, time, server, s)));
2749 }
2750
2751 int Write(const Time &time, const string &txt, int qos)
2752 {
2753 QApplication::postEvent(this,
2754 new FunctionEvent(boost::bind(&FactGui::handleWrite, this, time, txt, qos)));
2755
2756 return 0;
2757 }
2758
2759 // ====================== Dim infoHandler================================
2760
2761 void handleDimService(const string &txt)
2762 {
2763 fDimSvcText->append(txt.c_str());
2764 }
2765
2766 void infoHandlerService(DimInfo &info)
2767 {
2768 const string fmt = string(info.getFormat()).empty() ? "C" : info.getFormat();
2769
2770 stringstream dummy;
2771 const Converter conv(dummy, fmt, false);
2772
2773 const Time tm(info.getTimestamp(), info.getTimestampMillisecs()*1000);
2774
2775 stringstream out;
2776 out << "<font size'-1' color='navy'>[";
2777 out << tm.GetAsStr("%H:%M:%S.%f").substr(0,12);
2778 out << "]</font> <B>" << info.getName() << "</B> - ";
2779
2780 bool iserr = true;
2781 if (!conv)
2782 {
2783 out << "Compilation of format string '" << fmt << "' failed!";
2784 }
2785 else
2786 {
2787 try
2788 {
2789 const string dat = conv.GetString(info.getData(), info.getSize());
2790 out << dat;
2791 iserr = false;
2792 }
2793 catch (const runtime_error &e)
2794 {
2795 out << "Conversion to string failed!<pre>" << e.what() << "</pre>";
2796 }
2797 }
2798
2799 // srand(hash<string>()(string(info.getName())));
2800 // int bg = rand()&0xffffff;
2801
2802 int bg = hash<string>()(string(info.getName()));
2803
2804 // allow only light colors
2805 bg = ~(bg&0x1f1f1f)&0xffffff;
2806
2807 if (iserr)
2808 bg = 0xffffff;
2809
2810 stringstream bgcol;
2811 bgcol << hex << setfill('0') << setw(6) << bg;
2812
2813 const string col = iserr ? "red" : "black";
2814 const string str = "<table width='100%' bgcolor=#"+bgcol.str()+"><tr><td><font color='"+col+"'>"+out.str()+"</font></td></tr></table>";
2815
2816 QApplication::postEvent(this,
2817 new FunctionEvent(boost::bind(&FactGui::handleDimService, this, str)));
2818 }
2819
2820 void CallInfoHandler(void (FactGui::*handler)(const DimData&), const DimData &d)
2821 {
2822 fInHandler = true;
2823 (this->*handler)(d);
2824 fInHandler = false;
2825 }
2826
2827 /*
2828 void CallInfoHandler(const boost::function<void()> &func)
2829 {
2830 // This ensures that newly received values are not sent back to the emitter
2831 // because changing the value emits the valueChanged signal (or similar)
2832 fInHandler = true;
2833 func();
2834 fInHandler = false;
2835 }*/
2836
2837 void PostInfoHandler(void (FactGui::*handler)(const DimData&))
2838 {
2839 //const boost::function<void()> f = boost::bind(handler, this, DimData(getInfo()));
2840
2841 FunctionEvent *evt = new FunctionEvent(boost::bind(&FactGui::CallInfoHandler, this, handler, DimData(getInfo())));
2842 // FunctionEvent *evt = new FunctionEvent(boost::bind(&FactGui::CallInfoHandler, this, f));
2843 // FunctionEvent *evt = new FunctionEvent(boost::bind(handler, this, DimData(getInfo()))));
2844
2845 QApplication::postEvent(this, evt);
2846 }
2847
2848 void infoHandler()
2849 {
2850 // Initialize the time-stamp (what a weird workaround...)
2851 if (getInfo())
2852 getInfo()->getTimestamp();
2853
2854 if (getInfo()==&fDimDNS)
2855 return PostInfoHandler(&FactGui::handleDimDNS);
2856#ifdef DEBUG_DIM
2857 cout << "HandleDimInfo " << getInfo()->getName() << endl;
2858#endif
2859 if (getInfo()==&fDimLoggerStats)
2860 return PostInfoHandler(&FactGui::handleLoggerStats);
2861
2862// if (getInfo()==&fDimFadFiles)
2863// return PostInfoHandler(&FactGui::handleFadFiles);
2864
2865 if (getInfo()==&fDimFadWriteStats)
2866 return PostInfoHandler(&FactGui::handleFadWriteStats);
2867
2868 if (getInfo()==&fDimFadConnections)
2869 return PostInfoHandler(&FactGui::handleFadConnections);
2870
2871 if (getInfo()==&fDimFadFwVersion)
2872 return PostInfoHandler(&FactGui::handleFadFwVersion);
2873
2874 if (getInfo()==&fDimFadRunNumber)
2875 return PostInfoHandler(&FactGui::handleFadRunNumber);
2876
2877 if (getInfo()==&fDimFadDNA)
2878 return PostInfoHandler(&FactGui::handleFadDNA);
2879
2880 if (getInfo()==&fDimFadTemperature)
2881 return PostInfoHandler(&FactGui::handleFadTemperature);
2882
2883 if (getInfo()==&fDimFadRefClock)
2884 return PostInfoHandler(&FactGui::handleFadRefClock);
2885
2886 if (getInfo()==&fDimFadRoi)
2887 return PostInfoHandler(&FactGui::handleFadRoi);
2888
2889 if (getInfo()==&fDimFadDac)
2890 return PostInfoHandler(&FactGui::handleFadDac);
2891
2892 if (getInfo()==&fDimFadDrsCalibration)
2893 return PostInfoHandler(&FactGui::handleFadDrsCalibration);
2894
2895 if (getInfo()==&fDimFadPrescaler)
2896 return PostInfoHandler(&FactGui::handleFadPrescaler);
2897
2898 if (getInfo()==&fDimFadStatus)
2899 return PostInfoHandler(&FactGui::handleFadStatus);
2900
2901 if (getInfo()==&fDimFadStatistics1)
2902 return PostInfoHandler(&FactGui::handleFadStatistics1);
2903
2904 if (getInfo()==&fDimFadStatistics2)
2905 return PostInfoHandler(&FactGui::handleFadStatistics2);
2906
2907 if (getInfo()==&fDimFadEvents)
2908 return PostInfoHandler(&FactGui::handleFadEvents);
2909
2910 if (getInfo()==&fDimFadRuns)
2911 return PostInfoHandler(&FactGui::handleFadRuns);
2912
2913 if (getInfo()==&fDimFadStartRun)
2914 return PostInfoHandler(&FactGui::handleFadStartRun);
2915
2916 if (getInfo()==&fDimFadRawData)
2917 return PostInfoHandler(&FactGui::handleFadRawData);
2918
2919 if (getInfo()==&fDimFadEventData)
2920 return PostInfoHandler(&FactGui::handleFadEventData);
2921
2922/*
2923 if (getInfo()==&fDimFadSetup)
2924 return PostInfoHandler(&FactGui::handleFadSetup);
2925*/
2926 if (getInfo()==&fDimLoggerFilenameNight)
2927 return PostInfoHandler(&FactGui::handleLoggerFilenameNight);
2928
2929 if (getInfo()==&fDimLoggerNumSubs)
2930 return PostInfoHandler(&FactGui::handleLoggerNumSubs);
2931
2932 if (getInfo()==&fDimLoggerFilenameRun)
2933 return PostInfoHandler(&FactGui::handleLoggerFilenameRun);
2934
2935 if (getInfo()==&fDimFtmTriggerRates)
2936 return PostInfoHandler(&FactGui::handleFtmTriggerRates);
2937
2938 if (getInfo()==&fDimFtmCounter)
2939 return PostInfoHandler(&FactGui::handleFtmCounter);
2940
2941 if (getInfo()==&fDimFtmDynamicData)
2942 return PostInfoHandler(&FactGui::handleFtmDynamicData);
2943
2944 if (getInfo()==&fDimFtmPassport)
2945 return PostInfoHandler(&FactGui::handleFtmPassport);
2946
2947 if (getInfo()==&fDimFtmFtuList)
2948 return PostInfoHandler(&FactGui::handleFtmFtuList);
2949
2950 if (getInfo()==&fDimFtmStaticData)
2951 return PostInfoHandler(&FactGui::handleFtmStaticData);
2952
2953 if (getInfo()==&fDimFtmError)
2954 return PostInfoHandler(&FactGui::handleFtmError);
2955
2956 if (getInfo()==&fDimFscTemp)
2957 return PostInfoHandler(&FactGui::handleFscTemp);
2958
2959 if (getInfo()==&fDimFscVolt)
2960 return PostInfoHandler(&FactGui::handleFscVolt);
2961
2962 if (getInfo()==&fDimFscCurrent)
2963 return PostInfoHandler(&FactGui::handleFscCurrent);
2964
2965 if (getInfo()==&fDimFscHumidity)
2966 return PostInfoHandler(&FactGui::handleFscHumidity);
2967
2968 if (getInfo()==&fDimBiasVolt)
2969 return PostInfoHandler(&FactGui::handleBiasVolt);
2970
2971 if (getInfo()==&fDimBiasCurrent)
2972 return PostInfoHandler(&FactGui::handleBiasCurrent);
2973
2974// if (getInfo()==&fDimFadFiles)
2975// return PostInfoHandler(&FactGui::handleFadFiles);
2976
2977 for (map<string,DimInfo*>::iterator i=fServices.begin(); i!=fServices.end(); i++)
2978 if (i->second==getInfo())
2979 {
2980 infoHandlerService(*i->second);
2981 return;
2982 }
2983
2984 DimNetwork::infoHandler();
2985 }
2986
2987
2988 // ======================================================================
2989
2990 bool event(QEvent *evt)
2991 {
2992 if (dynamic_cast<FunctionEvent*>(evt))
2993 return static_cast<FunctionEvent*>(evt)->Exec();
2994
2995 if (dynamic_cast<CheckBoxEvent*>(evt))
2996 {
2997 const QStandardItem &item = static_cast<CheckBoxEvent*>(evt)->item;
2998 const QStandardItem *par = item.parent();
2999 if (par)
3000 {
3001 const QString server = par->text();
3002 const QString service = item.text();
3003
3004 const string s = (server+'/'+service).toStdString();
3005
3006 if (item.checkState()==Qt::Checked)
3007 SubscribeService(s);
3008 else
3009 UnsubscribeService(s);
3010 }
3011 }
3012
3013 return MainWindow::event(evt); // unrecognized
3014 }
3015
3016 void on_fDimCmdSend_clicked()
3017 {
3018 const QString server = fDimCmdServers->currentIndex().data().toString();
3019 const QString command = fDimCmdCommands->currentIndex().data().toString();
3020 const QString arguments = fDimCmdLineEdit->displayText();
3021
3022 // FIXME: Sending a command exactly when the info Handler changes
3023 // the list it might lead to confusion.
3024 try
3025 {
3026 SendDimCommand(server.toStdString(), command.toStdString()+" "+arguments.toStdString());
3027 fTextEdit->append("<font color='green'>Command '"+server+'/'+command+"' successfully emitted.</font>");
3028 fDimCmdLineEdit->clear();
3029 }
3030 catch (const runtime_error &e)
3031 {
3032 stringstream txt;
3033 txt << e.what();
3034
3035 string buffer;
3036 while (getline(txt, buffer, '\n'))
3037 fTextEdit->append(("<font color='red'><pre>"+buffer+"</pre></font>").c_str());
3038 }
3039 }
3040
3041#ifdef HAVE_ROOT
3042 void slot_RootEventProcessed(TObject *obj, unsigned int evt, TCanvas *canv)
3043 {
3044 // kMousePressEvent // TCanvas processed QEvent mousePressEvent
3045 // kMouseMoveEvent // TCanvas processed QEvent mouseMoveEvent
3046 // kMouseReleaseEvent // TCanvas processed QEvent mouseReleaseEvent
3047 // kMouseDoubleClickEvent // TCanvas processed QEvent mouseDoubleClickEvent
3048 // kKeyPressEvent // TCanvas processed QEvent keyPressEvent
3049 // kEnterEvent // TCanvas processed QEvent enterEvent
3050 // kLeaveEvent // TCanvas processed QEvent leaveEvent
3051
3052 if (dynamic_cast<TCanvas*>(obj))
3053 return;
3054
3055 TQtWidget *tipped = static_cast<TQtWidget*>(sender());
3056
3057 if (evt==11/*kMouseReleaseEvent*/)
3058 return;
3059
3060 if (evt==61/*kMouseDoubleClickEvent*/)
3061 return;
3062
3063 if (obj)
3064 {
3065 // Find the object which will get picked by the GetObjectInfo
3066 // due to buffer overflows in many root-versions
3067 // in TH1 and TProfile we have to work around and implement
3068 // our own GetObjectInfo which make everything a bit more
3069 // complicated.
3070 canv->cd();
3071#if ROOT_VERSION_CODE > ROOT_VERSION(5,22,00)
3072 const char *objectInfo =
3073 obj->GetObjectInfo(tipped->GetEventX(),tipped->GetEventY());
3074#else
3075 const char *objectInfo = dynamic_cast<TH1*>(obj) ?
3076 "" : obj->GetObjectInfo(tipped->GetEventX(),tipped->GetEventY());
3077#endif
3078
3079 QString tipText;
3080 tipText += obj->GetName();
3081 tipText += " [";
3082 tipText += obj->ClassName();
3083 tipText += "]: ";
3084 tipText += objectInfo;
3085
3086 fStatusBar->showMessage(tipText, 3000);
3087 }
3088
3089 gSystem->DispatchOneEvent(kFALSE);
3090 //gSystem->ProcessEvents();
3091 //QWhatsThis::display(tipText)
3092 }
3093
3094 void slot_RootUpdate()
3095 {
3096 gSystem->DispatchOneEvent(kFALSE);
3097 //gSystem->ProcessEvents();
3098 QTimer::singleShot(10, this, SLOT(slot_RootUpdate()));
3099 }
3100#endif
3101
3102 void ChoosePatchThreshold(Camera &cam, int isw)
3103 {
3104 cam.Reset();
3105
3106 fThresholdIdx->setValue(isw);
3107
3108 const int ihw = isw<0 ? 0 : fPatchMapHW[isw];
3109
3110 fPatchRate->setEnabled(isw>=0);
3111 fThresholdCrate->setEnabled(isw>=0);
3112 fThresholdBoard->setEnabled(isw>=0);
3113 fThresholdPatch->setEnabled(isw>=0);
3114
3115 if (isw<0)
3116 return;
3117
3118 const int patch = ihw%4;
3119 const int board = (ihw/4)%10;
3120 const int crate = (ihw/4)/10;
3121
3122 fInChoosePatchTH = true;
3123
3124 fThresholdCrate->setValue(crate);
3125 fThresholdBoard->setValue(board);
3126 fThresholdPatch->setValue(patch);
3127
3128 fInChoosePatchTH = false;
3129
3130 fThresholdVal->setValue(fFtmStaticData.fThreshold[ihw]);
3131 fPatchRate->setValue(cam.GetData(isw));
3132
3133 // Loop over the software idx of all pixels
3134 for (unsigned int i=0; i<1440; i++)
3135 if (fPatchHW[i]==ihw)
3136 cam.SetBold(i);
3137 }
3138
3139 /*
3140 void ChoosePatchBias(Camera &cam, int isw)
3141 {
3142 cam.Reset();
3143
3144 fBiasChannel->setValue(isw);
3145
3146 const int ihw = isw<0 ? 0 : fPatchMapHW[isw];
3147
3148 fBiasCurrent->setEnabled(isw>=0);
3149 fBiasCrate->setEnabled(isw>=0);
3150 fBiasBoard->setEnabled(isw>=0);
3151 fBiasPatch->setEnabled(isw>=0);
3152
3153 if (isw<0)
3154 return;
3155
3156 const int patch = ihw%4;
3157 const int board = (ihw/4)%10;
3158 const int crate = (ihw/4)/10;
3159
3160 fInChoosePatchBias = true;
3161
3162 fBiasCrate->setValue(crate);
3163 fBiasBoard->setValue(board);
3164 fBiasPatch->setValue(patch);
3165
3166 fInChoosePatchBias = false;
3167
3168 if (fVecBias.size()>0)
3169 {
3170 // FIXME: Mapping
3171 fBiasVoltDac->setValue(fVecBias[ihw]);
3172 fBiasVolt->setValue(fVecBias[ihw]*90./4096);
3173 }
3174
3175 fBiasCurrent->setValue(cam.GetData(isw));
3176
3177 // Loop over the software idx of all pixels
3178 for (unsigned int i=0; i<1440; i++)
3179 if (fPatchHW[i]==ihw)
3180 cam.SetBold(i);
3181 }*/
3182
3183 void slot_ChoosePixelThreshold(int isw)
3184 {
3185 fPixelIdx->setValue(isw);
3186
3187 const PixelMapEntry &entry = fPixelMap.index(isw);
3188 fPixelEnable->setChecked(fFtmStaticData.IsEnabled(entry.hw()));
3189 }
3190
3191 void slot_CameraDoubleClick(int isw)
3192 {
3193 fPixelIdx->setValue(isw);
3194
3195 const PixelMapEntry &entry = fPixelMap.index(isw);
3196 Dim::SendCommand("FTM_CONTROL/TOGGLE_PIXEL", uint16_t(entry.hw()));
3197 }
3198
3199 void slot_CameraMouseMove(int isw)
3200 {
3201 const PixelMapEntry &entry = fPixelMap.index(isw);
3202
3203 const int ihw = entry.hw();
3204
3205 const int idx = fPatchHW[isw];
3206 int ii = 0;
3207 for (; ii<160;ii++)
3208 if (idx ==fPatchMapHW[ii])
3209 break;
3210
3211 const int patch = idx%4;
3212 const int board = (idx/4)%10;
3213 const int crate = (idx/4)/10;
3214 QString tipText;
3215 tipText += fRatesCanv->GetName();
3216 ostringstream str;
3217 str << " || Pixel=" << isw << " (hw=" << ihw << ") || Patch=" << ii << " (hw=" << fPatchMapHW[idx] << "; Crate=" << crate << " Board=" << board << " Patch=" << patch << ")";
3218 tipText += str.str().c_str();
3219 fStatusBar->showMessage(tipText, 3000);
3220 }
3221
3222 void on_fThresholdIdx_valueChanged(int isw)
3223 {
3224//ETIENNE MESS HERE
3225// Camera *cam = (Camera*)fRatesCanv->GetCanvas()->FindObject("Camera");
3226// ChoosePatchTH(*cam, isw);
3227 }
3228
3229 void UpdateThresholdIdx()
3230 {
3231 if (fInChoosePatchTH)
3232 return;
3233
3234 const int crate = fThresholdCrate->value();
3235 const int board = fThresholdBoard->value();
3236 const int patch = fThresholdPatch->value();
3237
3238 const int ihw = patch + board*4 + crate*40;
3239
3240 int isw = 0;
3241 for (; isw<160; isw++)
3242 if (ihw==fPatchMapHW[isw])
3243 break;
3244
3245 on_fThresholdIdx_valueChanged(isw);
3246 }
3247
3248 void on_fPixelIdx_valueChanged(int isw)
3249 {
3250 int ii = 0;
3251 for (; ii<160; ii++)
3252 if (fPatchHW[isw]==fPatchMapHW[ii])
3253 break;
3254
3255 fRatesCanv->SetWhite(isw);
3256 ChoosePatchThreshold(*fRatesCanv, ii);
3257
3258 const PixelMapEntry &entry = fPixelMap.index(isw);
3259 fPixelEnable->setChecked(fFtmStaticData.IsEnabled(entry.hw()));
3260 }
3261
3262 // ------------------- Bias display ---------------------
3263
3264 void UpdateBiasValues()
3265 {
3266 const int b = fBiasHvBoard->value();
3267 const int c = fBiasHvChannel->value();
3268
3269 const int ihw = b*32+c;
3270
3271 if (fVecBiasVolt.size()>0)
3272 {
3273 fBiasVoltDac->setValue(fVecBiasVolt[ihw]);
3274 fBiasVolt->setValue(fVecBiasVolt[ihw]*90./4096);
3275 }
3276
3277 if (fVecBiasCurrent.size()>0)
3278 {
3279 fBiasCurrent->setValue(abs(fVecBiasCurrent[ihw])*5000./4096);
3280 SetLedColor(fBiasOverCurrentLed,
3281 fVecBiasCurrent[ihw]<0?kLedRed:kLedGreen, Time());
3282 }
3283 }
3284
3285 void UpdateBiasCam(const PixelMapEntry &entry)
3286 {
3287 fInChooseBiasCam = true;
3288
3289 fBiasCamCrate->setValue(entry.crate());
3290 fBiasCamBoard->setValue(entry.board());
3291 fBiasCamPatch->setValue(entry.patch());
3292 fBiasCamPixel->setValue(entry.pixel());
3293
3294 fInChooseBiasCam = false;
3295 }
3296
3297 void UpdateBiasHv(const PixelMapEntry &entry)
3298 {
3299 fInChooseBiasHv = true;
3300
3301 fBiasHvBoard->setValue(entry.hv_board);
3302 fBiasHvChannel->setValue(entry.hv_channel);
3303
3304 fInChooseBiasHv = false;
3305 }
3306
3307 void BiasHvChannelChanged()
3308 {
3309 if (fInChooseBiasHv)
3310 return;
3311
3312 const int b = fBiasHvBoard->value();
3313 const int ch = fBiasHvChannel->value();
3314
3315 const PixelMapEntry &entry = fPixelMap.hv(b, ch);
3316 fBiasCam->SetWhite(entry.index);
3317 fBiasCam->updateGL();
3318 // FIXME: mark patch in camera
3319 UpdateBiasCam(entry);
3320 UpdateBiasValues();
3321 }
3322
3323 void BiasCamChannelChanged()
3324 {
3325 if (fInChooseBiasCam)
3326 return;
3327
3328 const int crate = fBiasCamCrate->value();
3329 const int board = fBiasCamBoard->value();
3330 const int patch = fBiasCamPatch->value();
3331 const int pixel = fBiasCamPixel->value();
3332
3333 const PixelMapEntry &entry = fPixelMap.cbpx(crate, board, patch, pixel);
3334 fBiasCam->SetWhite(entry.index);
3335 fBiasCam->updateGL();
3336 // FIXME: mark patch in camera
3337 UpdateBiasHv(entry);
3338 UpdateBiasValues();
3339 }
3340
3341 void slot_ChooseBiasChannel(int isw)
3342 {
3343 const PixelMapEntry &entry = fPixelMap.index(isw);
3344
3345 UpdateBiasHv(entry);
3346 UpdateBiasCam(entry);
3347 UpdateBiasValues();
3348 }
3349
3350 // ------------------------------------------------------
3351
3352 void on_fPixelEnable_stateChanged(int b)
3353 {
3354 if (fInHandler)
3355 return;
3356
3357 const PixelMapEntry &entry = fPixelMap.index(fPixelIdx->value());
3358
3359 Dim::SendCommand(b==Qt::Unchecked ?
3360 "FTM_CONTROL/DISABLE_PIXEL" : "FTM_CONTROL/ENABLE_PIXEL",
3361 uint16_t(entry.hw()));
3362 }
3363
3364 void on_fPixelDisableOthers_clicked()
3365 {
3366 const PixelMapEntry &entry = fPixelMap.index(fPixelIdx->value());
3367
3368 Dim::SendCommand("FTM_CONTROL/DISABLE_ALL_PIXELS_EXCEPT", uint16_t(entry.hw()));
3369 }
3370
3371 void on_fThresholdDisableOthers_clicked()
3372 {
3373 const int16_t isw = fThresholdIdx->value();
3374 const int16_t ihw = isw<0 ? -1 : fPatchMapHW[isw];
3375
3376 Dim::SendCommand("FTM_CONTROL/DISABLE_ALL_PATCHES_EXCEPT", ihw);
3377 }
3378
3379 void on_fThresholdVal_valueChanged(int v)
3380 {
3381 fThresholdVolt->setValue(2500./4095*v);
3382
3383 const int32_t isw = fThresholdIdx->value();
3384 const int32_t ihw = isw<0 ? -1 : fPatchMapHW[isw];
3385
3386 const int32_t d[2] = { ihw, v };
3387
3388 if (!fInHandler)
3389 Dim::SendCommand("FTM_CONTROL/SET_THRESHOLD", d);
3390 }
3391
3392 TGraph fGraphFtmTemp[4];
3393 TGraph fGraphFtmRate;
3394 TGraph fGraphPatchRate[160];
3395 TGraph fGraphBoardRate[40];
3396
3397#ifdef HAVE_ROOT
3398 TH1 *DrawTimeFrame(const char *ytitle)
3399 {
3400 const double tm = Time().RootTime();
3401
3402 TH1F *h=new TH1F("TimeFrame", "", 1, tm, tm+60);//Time().RootTime()-1./24/60/60, Time().RootTime());
3403 h->SetDirectory(0);
3404 h->SetBit(kCanDelete);
3405 h->SetStats(kFALSE);
3406// h.SetMinimum(0);
3407// h.SetMaximum(1);
3408 h->SetXTitle("Time");
3409 h->SetYTitle(ytitle);
3410 h->GetXaxis()->CenterTitle();
3411 h->GetYaxis()->CenterTitle();
3412 h->GetXaxis()->SetTimeDisplay(true);
3413 h->GetXaxis()->SetTimeFormat("%Mh%S'");
3414 h->GetXaxis()->SetLabelSize(0.025);
3415 h->GetYaxis()->SetLabelSize(0.025);
3416 h->GetYaxis()->SetTitleOffset(1.2);
3417 // h.GetYaxis()->SetTitleSize(1.2);
3418 h->Draw();
3419
3420 return h;
3421 }
3422#endif
3423
3424 pair<string,string> Split(const string &str) const
3425 {
3426 const size_t p = str.find_first_of('|');
3427 if (p==string::npos)
3428 return make_pair(str, "");
3429
3430 return make_pair(str.substr(0, p), str.substr(p+1));
3431 }
3432
3433public:
3434 FactGui(Configuration &conf) :
3435 fFtuStatus(40),
3436 /*fPixelMapHW(1440),*/ fPatchMapHW(160), fPatchHW(1440),
3437 fInChoosePatchTH(false),
3438 fInChooseBiasHv(false), fInChooseBiasCam(false),
3439 fDimDNS("DIS_DNS/VERSION_NUMBER", 1, int(0), this),
3440 //-
3441 fDimLoggerStats ("DATA_LOGGER/STATS", (void*)NULL, 0, this),
3442 fDimLoggerFilenameNight("DATA_LOGGER/FILENAME_NIGHTLY", (void*)NULL, 0, this),
3443 fDimLoggerFilenameRun ("DATA_LOGGER/FILENAME_RUN", (void*)NULL, 0, this),
3444 fDimLoggerNumSubs ("DATA_LOGGER/NUM_SUBS", (void*)NULL, 0, this),
3445 //-
3446 fDimFtmPassport ("FTM_CONTROL/PASSPORT", (void*)NULL, 0, this),
3447 fDimFtmTriggerRates ("FTM_CONTROL/TRIGGER_RATES", (void*)NULL, 0, this),
3448 fDimFtmError ("FTM_CONTROL/ERROR", (void*)NULL, 0, this),
3449 fDimFtmFtuList ("FTM_CONTROL/FTU_LIST", (void*)NULL, 0, this),
3450 fDimFtmStaticData ("FTM_CONTROL/STATIC_DATA", (void*)NULL, 0, this),
3451 fDimFtmDynamicData ("FTM_CONTROL/DYNAMIC_DATA", (void*)NULL, 0, this),
3452 fDimFtmCounter ("FTM_CONTROL/COUNTER", (void*)NULL, 0, this),
3453 //-
3454 fDimFadWriteStats ("FAD_CONTROL/STATS", (void*)NULL, 0, this),
3455 fDimFadStartRun ("FAD_CONTROL/START_RUN", (void*)NULL, 0, this),
3456 fDimFadRuns ("FAD_CONTROL/RUNS", (void*)NULL, 0, this),
3457 fDimFadEvents ("FAD_CONTROL/EVENTS", (void*)NULL, 0, this),
3458 fDimFadRawData ("FAD_CONTROL/RAW_DATA", (void*)NULL, 0, this),
3459 fDimFadEventData ("FAD_CONTROL/EVENT_DATA", (void*)NULL, 0, this),
3460 fDimFadConnections ("FAD_CONTROL/CONNECTIONS", (void*)NULL, 0, this),
3461 fDimFadFwVersion ("FAD_CONTROL/FIRMWARE_VERSION", (void*)NULL, 0, this),
3462 fDimFadRunNumber ("FAD_CONTROL/RUN_NUMBER", (void*)NULL, 0, this),
3463 fDimFadDNA ("FAD_CONTROL/DNA", (void*)NULL, 0, this),
3464 fDimFadTemperature ("FAD_CONTROL/TEMPERATURE", (void*)NULL, 0, this),
3465 fDimFadPrescaler ("FAD_CONTROL/PRESCALER", (void*)NULL, 0, this),
3466 fDimFadRefClock ("FAD_CONTROL/REFERENCE_CLOCK", (void*)NULL, 0, this),
3467 fDimFadRoi ("FAD_CONTROL/REGION_OF_INTEREST", (void*)NULL, 0, this),
3468 fDimFadDac ("FAD_CONTROL/DAC", (void*)NULL, 0, this),
3469 fDimFadDrsCalibration ("FAD_CONTROL/DRS_CALIBRATION", (void*)NULL, 0, this),
3470 fDimFadStatus ("FAD_CONTROL/STATUS", (void*)NULL, 0, this),
3471 fDimFadStatistics1 ("FAD_CONTROL/STATISTICS1", (void*)NULL, 0, this),
3472 fDimFadStatistics2 ("FAD_CONTROL/STATISTICS2", (void*)NULL, 0, this),
3473 //-
3474 fDimFscTemp ("FSC_CONTROL/TEMPERATURE", (void*)NULL, 0, this),
3475 fDimFscVolt ("FSC_CONTROL/VOLTAGE", (void*)NULL, 0, this),
3476 fDimFscCurrent ("FSC_CONTROL/CURRENT", (void*)NULL, 0, this),
3477 fDimFscHumidity ("FSC_CONTROL/HUMIDITY", (void*)NULL, 0, this),
3478 //-
3479 fDimBiasVolt ("BIAS_CONTROL/VOLTAGE", (void*)NULL, 0, this),
3480 fDimBiasCurrent ("BIAS_CONTROL/CURRENT", (void*)NULL, 0, this),
3481 //-
3482 fEventData(0), fDrsCalibration(1440*1024*6),
3483 fTimeStamp0(0)
3484 {
3485 fClockCondFreq->addItem("--- Hz", QVariant(-1));
3486 fClockCondFreq->addItem("800 MHz", QVariant(800));
3487 fClockCondFreq->addItem("1 GHz", QVariant(1000));
3488 fClockCondFreq->addItem("2 GHz", QVariant(2000));
3489 fClockCondFreq->addItem("3 GHz", QVariant(3000));
3490 fClockCondFreq->addItem("4 GHz", QVariant(4000));
3491 fClockCondFreq->addItem("5 GHz", QVariant(5000));
3492
3493 cout << "-- run counter ---" << endl;
3494 fMcpNumEvents->addItem("unlimited", QVariant(0));
3495 const vector<uint32_t> runcount = conf.Vec<uint32_t>("run-count");
3496 for (vector<uint32_t>::const_iterator it=runcount.begin(); it!=runcount.end(); it++)
3497 {
3498 cout << *it << endl;
3499 ostringstream str;
3500 str << *it;
3501 fMcpNumEvents->addItem(str.str().c_str(), QVariant(*it));
3502 }
3503
3504 cout << "-- run times ---" << endl;
3505 fMcpTime->addItem("unlimited", QVariant(0));
3506 const vector<string> runtime = conf.Vec<string>("run-time");
3507 for (vector<string>::const_iterator it=runtime.begin(); it!=runtime.end(); it++)
3508 {
3509 const pair<string,string> p = Split(*it);
3510 cout << *it << "|" << p.second << "|" << p.first << "|" << endl;
3511 fMcpTime->addItem(p.second.c_str(), QVariant(stoi(p.first)));
3512 }
3513
3514 cout << "-- run types ---" << endl;
3515 const vector<string> runtype = conf.Vec<string>("run-type");
3516 for (vector<string>::const_iterator it=runtype.begin(); it!=runtype.end(); it++)
3517 {
3518 const pair<string,string> p = Split(*it);
3519 cout << *it << "|" << p.second << "|" << p.first << "|" << endl;
3520 fMcpRunType->addItem(p.second.c_str(), QVariant(p.first.c_str()));
3521 }
3522
3523 fTriggerWidget->setEnabled(false);
3524 fFtuWidget->setEnabled(false);
3525 fFtuGroupEnable->setEnabled(false);
3526 fRatesControls->setEnabled(false);
3527 fFadWidget->setEnabled(false);
3528 fEvtBldWidget->setEnabled(false);
3529 fLoggerWidget->setEnabled(false);
3530
3531 fChatSend->setEnabled(false);
3532 fChatMessage->setEnabled(false);
3533
3534 DimClient::sendCommand("CHAT/MSG", "GUI online.");
3535 // + MessageDimRX
3536
3537 // --------------------------------------------------------------------------
3538
3539 ifstream fin0("FACTmapV5.txt");
3540
3541 int l = 0;
3542
3543 string buf;
3544 while (getline(fin0, buf, '\n'))
3545 {
3546 if (l>1439)
3547 break;
3548
3549 buf = Tools::Trim(buf);
3550 if (buf[0]=='#')
3551 continue;
3552
3553 stringstream str(buf);
3554
3555 int idummy;
3556 float fdummy;
3557
3558 PixelMapEntry entry;
3559
3560 str >> entry.index;
3561 str >> entry.cbpx;
3562 str >> idummy;
3563 str >> idummy;
3564 str >> entry.gapd;
3565 str >> fdummy;
3566 str >> entry.hv_board;
3567 str >> entry.hv_channel;
3568 str >> fdummy;
3569 str >> fdummy;
3570 str >> fdummy;
3571
3572 fPixelMap[l++] = entry;
3573 }
3574
3575 if (l!=1440)
3576 {
3577 cerr << "ERROR - Problems reading FACTmapV5.txt" << endl;
3578 exit(-1);
3579 }
3580
3581 // --------------------------------------------------------------------------
3582
3583 ifstream fin1("Trigger-Patches.txt");
3584
3585 l = 0;
3586 while (getline(fin1, buf, '\n'))
3587 {
3588 buf = Tools::Trim(buf);
3589 if (buf[0]=='#')
3590 continue;
3591
3592 stringstream str(buf);
3593 for (int i=0; i<9; i++)
3594 {
3595 unsigned int n;
3596 str >> n;
3597
3598 if (n>=fPatchHW.size())
3599 continue;
3600
3601 fPatchHW[n] = l;
3602 }
3603 l++;
3604 }
3605
3606 if (l!=160)
3607 cerr << "WARNING - Problems reading Trigger-Patches.txt" << endl;
3608
3609 // --------------------------------------------------------------------------
3610
3611 /*
3612 ifstream fin2("MasterList-v3.txt");
3613
3614 l = 0;
3615
3616 while (getline(fin2, buf, '\n'))
3617 {
3618 buf = Tools::Trim(buf);
3619 if (buf[0]=='#')
3620 continue;
3621
3622 unsigned int softid, hardid, dummy;
3623
3624 stringstream str(buf);
3625
3626 str >> softid;
3627 str >> dummy;
3628 str >> hardid;
3629
3630 if (softid>=fPixelMapHW.size())
3631 continue;
3632
3633 fPixelMapHW[softid] = hardid;
3634
3635 l++;
3636 }
3637
3638 if (l!=1440)
3639 cerr << "WARNING - Problems reading MasterList-v3.txt" << endl;
3640 */
3641 // --------------------------------------------------------------------------
3642
3643 ifstream fin3("PatchList.txt");
3644
3645 l = 0;
3646
3647 while (getline(fin3, buf, '\n'))
3648 {
3649 buf = Tools::Trim(buf);
3650 if (buf[0]=='#')
3651 continue;
3652
3653 unsigned int softid, hardid;
3654
3655 stringstream str(buf);
3656
3657 str >> softid;
3658 str >> hardid;
3659
3660 if (softid>=fPatchMapHW.size())
3661 continue;
3662
3663 fPatchMapHW[softid] = hardid-1;
3664
3665 l++;
3666 }
3667
3668 if (l!=160)
3669 cerr << "WARNING - Problems reading PatchList.txt" << endl;
3670
3671 // --------------------------------------------------------------------------
3672#ifdef HAVE_ROOT
3673
3674 fGraphFtmRate.SetLineColor(kBlue);
3675 fGraphFtmRate.SetMarkerColor(kBlue);
3676 fGraphFtmRate.SetMarkerStyle(kFullDotMedium);
3677
3678 for (int i=0; i<160; i++)
3679 {
3680 fGraphPatchRate[i].SetName("PatchRate");
3681 //fGraphPatchRate[i].SetLineColor(kBlue);
3682 //fGraphPatchRate[i].SetMarkerColor(kBlue);
3683 fGraphPatchRate[i].SetMarkerStyle(kFullDotMedium);
3684 }
3685 for (int i=0; i<40; i++)
3686 {
3687 fGraphBoardRate[i].SetName("BoardRate");
3688 //fGraphBoardRate[i].SetLineColor(kBlue);
3689 //fGraphBoardRate[i].SetMarkerColor(kBlue);
3690 fGraphBoardRate[i].SetMarkerStyle(kFullDotMedium);
3691 }
3692 /*
3693 TCanvas *c = fFtmTempCanv->GetCanvas();
3694 c->SetBit(TCanvas::kNoContextMenu);
3695 c->SetBorderMode(0);
3696 c->SetFrameBorderMode(0);
3697 c->SetFillColor(kWhite);
3698 c->SetRightMargin(0.03);
3699 c->SetTopMargin(0.03);
3700 c->cd();
3701 */
3702 //CreateTimeFrame("Temperature / �C");
3703
3704 fGraphFtmTemp[0].SetMarkerStyle(kFullDotSmall);
3705 fGraphFtmTemp[1].SetMarkerStyle(kFullDotSmall);
3706 fGraphFtmTemp[2].SetMarkerStyle(kFullDotSmall);
3707 fGraphFtmTemp[3].SetMarkerStyle(kFullDotSmall);
3708
3709 fGraphFtmTemp[1].SetLineColor(kBlue);
3710 fGraphFtmTemp[2].SetLineColor(kRed);
3711 fGraphFtmTemp[3].SetLineColor(kGreen);
3712
3713 fGraphFtmTemp[1].SetMarkerColor(kBlue);
3714 fGraphFtmTemp[2].SetMarkerColor(kRed);
3715 fGraphFtmTemp[3].SetMarkerColor(kGreen);
3716
3717 //fGraphFtmTemp[0].Draw("LP");
3718 //fGraphFtmTemp[1].Draw("LP");
3719 //fGraphFtmTemp[2].Draw("LP");
3720 //fGraphFtmTemp[3].Draw("LP");
3721
3722 // --------------------------------------------------------------------------
3723
3724 TCanvas *c = fFtmRateCanv->GetCanvas();
3725 //c->SetBit(TCanvas::kNoContextMenu);
3726 c->SetBorderMode(0);
3727 c->SetFrameBorderMode(0);
3728 c->SetFillColor(kWhite);
3729 c->SetRightMargin(0.03);
3730 c->SetTopMargin(0.03);
3731 c->SetGrid();
3732 c->cd();
3733
3734 TH1 *hf = DrawTimeFrame("Trigger rate [Hz]");
3735 hf->GetYaxis()->SetRangeUser(0, 1010);
3736
3737 fGraphFtmRate.SetMarkerStyle(kFullDotSmall);
3738 fGraphFtmRate.Draw("LP");
3739
3740 // --------------------------------------------------------------------------
3741
3742 fBiasCam->SetMin(fBiasMin->value());
3743 fBiasCam->SetMax(fBiasMax->value());
3744 fBiasCam->updateGL();
3745
3746 // --------------------------------------------------------------------------
3747
3748 fRatesCanv->SetMin(fRatesMin->value());
3749 fRatesCanv->SetMax(fRatesMax->value());
3750 fRatesCanv->updateGL();
3751 on_fPixelIdx_valueChanged(0);
3752
3753 // --------------------------------------------------------------------------
3754
3755 c = fAdcDataCanv->GetCanvas();
3756 //c->SetBit(TCanvas::kNoContextMenu);
3757 c->SetBorderMode(0);
3758 c->SetFrameBorderMode(0);
3759 c->SetFillColor(kWhite);
3760 c->SetRightMargin(0.10);
3761 c->SetGrid();
3762 c->cd();
3763
3764 // Create histogram?
3765
3766 // --------------------------------------------------------------------------
3767
3768 QTimer::singleShot(1000, this, SLOT(slot_RootUpdate()));
3769
3770 //widget->setMouseTracking(true);
3771 //widget->EnableSignalEvents(kMouseMoveEvent);
3772
3773 fFtmRateCanv->setMouseTracking(true);
3774 fFtmRateCanv->EnableSignalEvents(kMouseMoveEvent);
3775
3776 fAdcDataCanv->setMouseTracking(true);
3777 fAdcDataCanv->EnableSignalEvents(kMouseMoveEvent);
3778
3779 fRatesCanv->setMouseTracking(true);
3780
3781 connect(fRatesCanv, SIGNAL(signalPixelMoveOver(int)),
3782 this, SLOT(slot_CameraMouseMove(int)));
3783 connect(fEventCanv1, SIGNAL(signalCurrentPixel(int)),
3784 this, SLOT(slot_CameraMouseMove(int)));
3785 connect(fEventCanv2, SIGNAL(signalCurrentPixel(int)),
3786 this, SLOT(slot_CameraMouseMove(int)));
3787 connect(fEventCanv3, SIGNAL(signalCurrentPixel(int)),
3788 this, SLOT(slot_CameraMouseMove(int)));
3789 connect(fEventCanv4, SIGNAL(signalCurrentPixel(int)),
3790 this, SLOT(slot_CameraMouseMove(int)));
3791
3792 connect(fRatesCanv, SIGNAL(signalPixelDoubleClick(int)),
3793 this, SLOT(slot_CameraDoubleClick(int)));
3794 connect(fRatesCanv, SIGNAL(signalCurrentPixel(int)),
3795 this, SLOT(slot_ChoosePixelThreshold(int)));
3796 connect(fBiasCam, SIGNAL(signalCurrentPixel(int)),
3797 this, SLOT(slot_ChooseBiasChannel(int)));
3798 connect(fFtmRateCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)),
3799 this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*)));
3800 connect(fAdcDataCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)),
3801 this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*)));
3802#endif
3803 }
3804
3805 ~FactGui()
3806 {
3807 // Unsubscribe all services
3808 for (map<string,DimInfo*>::iterator i=fServices.begin();
3809 i!=fServices.end(); i++)
3810 delete i->second;
3811
3812 delete fEventData;
3813 }
3814};
3815
3816#endif
Note: See TracBrowser for help on using the repository browser.