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

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