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

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