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

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