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

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