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

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