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

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