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

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