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

Last change on this file since 20115 was 19387, checked in by tbretz, 6 years ago
Prefix file paths if they are not absolute (should not change anything as right now, --prefix is not defined.
File size: 135.0 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#ifdef HAVE_ROOT
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#endif
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#ifdef HAVE_ROOT
2329 TGraph fGraphRateScan[201];
2330#endif
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 void slot_RootEventProcessed(TObject *obj, unsigned int evt, TCanvas *canv)
3204 {
3205#ifdef HAVE_ROOT
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#endif
3255 }
3256
3257 void slot_RootUpdate()
3258 {
3259#ifdef HAVE_ROOT
3260 gSystem->DispatchOneEvent(kFALSE);
3261 //gSystem->ProcessEvents();
3262 QTimer::singleShot(10, this, SLOT(slot_RootUpdate()));
3263#endif
3264 }
3265
3266 void ChoosePatchThreshold(Camera &cam, int isw)
3267 {
3268 cam.Reset();
3269
3270 fThresholdIdx->setValue(isw);
3271
3272 const int ihw = isw<0 ? 0 : fPatchMapHW[isw];
3273
3274 fPatchRate->setEnabled(isw>=0);
3275 fThresholdCrate->setEnabled(isw>=0);
3276 fThresholdBoard->setEnabled(isw>=0);
3277 fThresholdPatch->setEnabled(isw>=0);
3278
3279 if (isw<0)
3280 return;
3281
3282 const int patch = ihw%4;
3283 const int board = (ihw/4)%10;
3284 const int crate = (ihw/4)/10;
3285
3286 fInChoosePatchTH = true;
3287
3288 fThresholdCrate->setValue(crate);
3289 fThresholdBoard->setValue(board);
3290 fThresholdPatch->setValue(patch);
3291
3292 fInChoosePatchTH = false;
3293
3294 fThresholdVal->setValue(fFtmStaticData.fThreshold[ihw]);
3295 fPatchRate->setValue(fTriggerRates.fPatchRate[ihw]);
3296 fBoardRate->setValue(fTriggerRates.fBoardRate[ihw/4]);
3297
3298 // Loop over the software idx of all pixels
3299// for (unsigned int i=0; i<1440; i++)
3300// if (fPatchHW[i]==ihw)
3301// cam.SetBold(i);
3302 }
3303
3304 void slot_ChoosePixelThreshold(int isw)
3305 {
3306 fPixelIdx->setValue(isw);
3307
3308 const PixelMapEntry &entry = fPixelMap.index(isw);
3309 fPixelEnable->setChecked(fFtmStaticData.IsEnabled(entry.hw()));
3310 }
3311
3312 void slot_CameraDoubleClick(int isw)
3313 {
3314 fPixelIdx->setValue(isw);
3315
3316 const PixelMapEntry &entry = fPixelMap.index(isw);
3317 Dim::SendCommand("FTM_CONTROL/TOGGLE_PIXEL", uint16_t(entry.hw()));
3318 }
3319
3320 void slot_CameraMouseMove(int isw)
3321 {
3322 const PixelMapEntry &entry = fPixelMap.index(isw);
3323
3324 QString tipText;
3325 tipText += fRatesCanv->GetName();
3326 ostringstream str;
3327 str << setfill('0') <<
3328 " || HW: " << entry.crate() << "|" << entry.board() << "|" << entry.patch() << "|" << entry.pixel() << " (crate|board|patch|pixel)" <<
3329 " || HV: " << entry.hv_board << "|" << setw(2) << entry.hv_channel << " (board|channel)" <<
3330 " || ID: " << isw;
3331
3332
3333 tipText += str.str().c_str();
3334 fStatusBar->showMessage(tipText, 3000);
3335 }
3336
3337 void on_fPixelIdx_valueChanged(int isw)
3338 {
3339 int ii = 0;
3340 for (; ii<160; ii++)
3341 if (fPixelMap.index(isw).hw()/9==fPatchMapHW[ii])
3342 break;
3343
3344 fRatesCanv->SetWhite(isw);
3345 ChoosePatchThreshold(*fRatesCanv, ii);
3346
3347 const PixelMapEntry &entry = fPixelMap.index(isw);
3348 fPixelEnable->setChecked(fFtmStaticData.IsEnabled(entry.hw()));
3349 }
3350
3351 // ------------------- Bias display ---------------------
3352
3353 void UpdateBiasValues()
3354 {
3355 const int b = fBiasHvBoard->value();
3356 const int c = fBiasHvChannel->value();
3357
3358 const int ihw = b*32+c;
3359
3360 if (fVecBiasVolt.size()>0)
3361 {
3362 fBiasVoltCur->setValue(fVecBiasVolt[ihw]);
3363 SetLedColor(fBiasNominalLed,
3364 fVecBiasDac[ihw]==fVecBiasDac[ihw+416]?kLedGreen:kLedRed, Time());
3365 }
3366
3367 if (fVecBiasCurrent.size()>0)
3368 {
3369 const double val = abs(fVecBiasCurrent[ihw]) * 5000./4096;
3370 fBiasCurrent->setValue(val);
3371 SetLedColor(fBiasOverCurrentLed,
3372 fVecBiasCurrent[ihw]<0?kLedRed:kLedGreen, Time());
3373 }
3374
3375 const bool calibrated = fStateFeedback>=Feedback::State::kCalibrated &&
3376 fVecFeedbackCurrents.size()>0;
3377
3378 fBiasCalibrated->setValue(calibrated ? fVecFeedbackCurrents[ihw] : 0);
3379 fBiasCalibrated->setEnabled(calibrated);
3380 }
3381
3382 void UpdateBiasCam(const PixelMapEntry &entry)
3383 {
3384 fInChooseBiasCam = true;
3385
3386 fBiasCamCrate->setValue(entry.crate());
3387 fBiasCamBoard->setValue(entry.board());
3388 fBiasCamPatch->setValue(entry.patch());
3389 fBiasCamPixel->setValue(entry.pixel());
3390
3391 fInChooseBiasCam = false;
3392 }
3393
3394 void BiasHvChannelChanged()
3395 {
3396 if (fInChooseBiasHv)
3397 return;
3398
3399 const int b = fBiasHvBoard->value();
3400 const int ch = fBiasHvChannel->value();
3401
3402 // FIXME: Mark corresponding patch in camera
3403 const PixelMapEntry &entry = fPixelMap.hv(b, ch);
3404 fBiasCamV->SetWhite(entry.index);
3405 fBiasCamA->SetWhite(entry.index);
3406 fBiasCamV->updateCamera();
3407 fBiasCamA->updateCamera();
3408
3409 UpdateBiasCam(entry);
3410 UpdateBiasValues();
3411 }
3412
3413 void UpdateBiasHv(const PixelMapEntry &entry)
3414 {
3415 fInChooseBiasHv = true;
3416
3417 fBiasHvBoard->setValue(entry.hv_board);
3418 fBiasHvChannel->setValue(entry.hv_channel);
3419
3420 fInChooseBiasHv = false;
3421 }
3422
3423 void BiasCamChannelChanged()
3424 {
3425 if (fInChooseBiasCam)
3426 return;
3427
3428 const int crate = fBiasCamCrate->value();
3429 const int board = fBiasCamBoard->value();
3430 const int patch = fBiasCamPatch->value();
3431 const int pixel = fBiasCamPixel->value();
3432
3433 // FIXME: Display corresponding patches
3434 const PixelMapEntry &entry = fPixelMap.cbpx(crate, board, patch, pixel);
3435 fBiasCamV->SetWhite(entry.index);
3436 fBiasCamA->SetWhite(entry.index);
3437 fBiasCamV->updateCamera();
3438 fBiasCamA->updateCamera();
3439
3440 UpdateBiasHv(entry);
3441 UpdateBiasValues();
3442 }
3443
3444 void slot_ChooseBiasChannel(int isw)
3445 {
3446 const PixelMapEntry &entry = fPixelMap.index(isw);
3447
3448 UpdateBiasHv(entry);
3449 UpdateBiasCam(entry);
3450 UpdateBiasValues();
3451 }
3452
3453 void on_fBiasDispRefVolt_stateChanged(int = 0)
3454 {
3455 // FIXME: Display patches for which ref==cur
3456
3457 valarray<double> dat(0., 1440);
3458 fBiasCamV->setTitle("Applied BIAS voltage");
3459
3460 if (fVecBiasVolt.size()>0 && fVecBiasDac.size()>0)
3461 {
3462 for (int i=0; i<1440; i++)
3463 {
3464 const PixelMapEntry &entry = fPixelMap.index(i);
3465
3466 dat[i] = fVecBiasVolt[entry.hv()];
3467 fBiasCamV->highlightPixel(i, fVecBiasDac[entry.hv()]!=fVecBiasDac[entry.hv()+416]);
3468 }
3469
3470 fBiasCamV->SetData(dat);
3471 }
3472
3473 fBiasCamV->updateCamera();
3474 }
3475
3476 // ------------------------------------------------------
3477
3478 void on_fPixelEnable_stateChanged(int b)
3479 {
3480 if (fInHandler)
3481 return;
3482
3483 const PixelMapEntry &entry = fPixelMap.index(fPixelIdx->value());
3484
3485 Dim::SendCommand(b==Qt::Unchecked ?
3486 "FTM_CONTROL/DISABLE_PIXEL" : "FTM_CONTROL/ENABLE_PIXEL",
3487 uint16_t(entry.hw()));
3488 }
3489
3490 void on_fPixelDisableOthers_clicked()
3491 {
3492 const PixelMapEntry &entry = fPixelMap.index(fPixelIdx->value());
3493 Dim::SendCommand("FTM_CONTROL/DISABLE_ALL_PIXELS_EXCEPT", uint16_t(entry.hw()));
3494 }
3495
3496 void on_fThresholdDisableOthers_clicked()
3497 {
3498 const int16_t isw = fThresholdIdx->value();
3499 const int16_t ihw = isw<0 ? -1 : fPatchMapHW[isw];
3500 if (ihw<0)
3501 return;
3502
3503 Dim::SendCommand("FTM_CONTROL/DISABLE_ALL_PATCHES_EXCEPT", ihw);
3504 }
3505
3506 void on_fThresholdEnablePatch_clicked()
3507 {
3508 const int16_t isw = fThresholdIdx->value();
3509 const int16_t ihw = isw<0 ? -1 : fPatchMapHW[isw];
3510 if (ihw<0)
3511 return;
3512
3513 Dim::SendCommand("FTM_CONTROL/ENABLE_PATCH", ihw);
3514 }
3515
3516 void on_fThresholdDisablePatch_clicked()
3517 {
3518 const int16_t isw = fThresholdIdx->value();
3519 const int16_t ihw = isw<0 ? -1 : fPatchMapHW[isw];
3520 if (ihw<0)
3521 return;
3522
3523 Dim::SendCommand("FTM_CONTROL/DISABLE_PATCH", ihw);
3524 }
3525
3526 void on_fThresholdVal_valueChanged(int v)
3527 {
3528 fThresholdVolt->setValue(2500./4095*v);
3529
3530 const int32_t isw = fThresholdIdx->value();
3531 const int32_t ihw = isw<0 ? -1 : fPatchMapHW[isw];
3532
3533 const int32_t d[2] = { ihw, v };
3534
3535 if (!fInHandler)
3536 Dim::SendCommand("FTM_CONTROL/SET_THRESHOLD", d);
3537 }
3538
3539#ifdef HAVE_ROOT
3540 TGraph fGraphFtmTemp[4];
3541 TGraph fGraphFtmRate;
3542 TGraph fGraphPatchRate[160];
3543 TGraph fGraphBoardRate[40];
3544
3545 TH1 *DrawTimeFrame(const char *ytitle)
3546 {
3547 const double tm = Time().RootTime();
3548
3549 TH1F *h=new TH1F("TimeFrame", "", 1, tm, tm+60);//Time().RootTime()-1./24/60/60, Time().RootTime());
3550 h->SetDirectory(0);
3551 h->SetBit(kCanDelete);
3552 h->SetStats(kFALSE);
3553// h.SetMinimum(0);
3554// h.SetMaximum(1);
3555 h->SetXTitle("Time");
3556 h->SetYTitle(ytitle);
3557 h->GetXaxis()->CenterTitle();
3558 h->GetYaxis()->CenterTitle();
3559 h->GetXaxis()->SetTimeDisplay(true);
3560 h->GetXaxis()->SetTimeFormat("%Mh%S'%F1995-01-01 00:00:00 GMT");
3561 h->GetXaxis()->SetLabelSize(0.025);
3562 h->GetYaxis()->SetLabelSize(0.025);
3563 h->GetYaxis()->SetTitleOffset(1.2);
3564 // h.GetYaxis()->SetTitleSize(1.2);
3565 return h;
3566 }
3567#endif
3568
3569 pair<string,string> Split(const string &str) const
3570 {
3571 const size_t p = str.find_first_of('|');
3572 if (p==string::npos)
3573 return make_pair(str, "");
3574
3575 return make_pair(str.substr(0, p), str.substr(p+1));
3576 }
3577
3578public:
3579 FactGui(Configuration &conf) :
3580 fFtuStatus(40),
3581 /*fPixelMapHW(1440),*/ fPatchMapHW(160),
3582 fInChoosePatchTH(false),
3583 fInChooseBiasHv(false), fInChooseBiasCam(false),
3584 fDimDNS("DIS_DNS/VERSION_NUMBER", 1, int(0), this),
3585 //-
3586 fDimLoggerStats ("DATA_LOGGER/STATS", (void*)NULL, 0, this),
3587 fDimLoggerFilenameNight("DATA_LOGGER/FILENAME_NIGHTLY", (void*)NULL, 0, this),
3588 fDimLoggerFilenameRun ("DATA_LOGGER/FILENAME_RUN", (void*)NULL, 0, this),
3589 fDimLoggerNumSubs ("DATA_LOGGER/NUM_SUBS", (void*)NULL, 0, this),
3590 //-
3591 fDimFtmPassport ("FTM_CONTROL/PASSPORT", (void*)NULL, 0, this),
3592 fDimFtmTriggerRates ("FTM_CONTROL/TRIGGER_RATES", (void*)NULL, 0, this),
3593 fDimFtmError ("FTM_CONTROL/ERROR", (void*)NULL, 0, this),
3594 fDimFtmFtuList ("FTM_CONTROL/FTU_LIST", (void*)NULL, 0, this),
3595 fDimFtmStaticData ("FTM_CONTROL/STATIC_DATA", (void*)NULL, 0, this),
3596 fDimFtmDynamicData ("FTM_CONTROL/DYNAMIC_DATA", (void*)NULL, 0, this),
3597 fDimFtmCounter ("FTM_CONTROL/COUNTER", (void*)NULL, 0, this),
3598 //-
3599 fDimFadWriteStats ("FAD_CONTROL/STATS", (void*)NULL, 0, this),
3600 fDimFadStartRun ("FAD_CONTROL/START_RUN", (void*)NULL, 0, this),
3601 fDimFadRuns ("FAD_CONTROL/RUNS", (void*)NULL, 0, this),
3602 fDimFadEvents ("FAD_CONTROL/EVENTS", (void*)NULL, 0, this),
3603 fDimFadRawData ("FAD_CONTROL/RAW_DATA", (void*)NULL, 0, this),
3604 fDimFadEventData ("FAD_CONTROL/EVENT_DATA", (void*)NULL, 0, this),
3605 fDimFadConnections ("FAD_CONTROL/CONNECTIONS", (void*)NULL, 0, this),
3606 fDimFadFwVersion ("FAD_CONTROL/FIRMWARE_VERSION", (void*)NULL, 0, this),
3607 fDimFadRunNumber ("FAD_CONTROL/RUN_NUMBER", (void*)NULL, 0, this),
3608 fDimFadDNA ("FAD_CONTROL/DNA", (void*)NULL, 0, this),
3609 fDimFadTemperature ("FAD_CONTROL/TEMPERATURE", (void*)NULL, 0, this),
3610 fDimFadPrescaler ("FAD_CONTROL/PRESCALER", (void*)NULL, 0, this),
3611 fDimFadRefClock ("FAD_CONTROL/REFERENCE_CLOCK", (void*)NULL, 0, this),
3612 fDimFadRoi ("FAD_CONTROL/REGION_OF_INTEREST", (void*)NULL, 0, this),
3613 fDimFadDac ("FAD_CONTROL/DAC", (void*)NULL, 0, this),
3614 fDimFadDrsCalibration ("FAD_CONTROL/DRS_CALIBRATION", (void*)NULL, 0, this),
3615 fDimFadStatus ("FAD_CONTROL/STATUS", (void*)NULL, 0, this),
3616 fDimFadStatistics1 ("FAD_CONTROL/STATISTICS1", (void*)NULL, 0, this),
3617 //fDimFadStatistics2 ("FAD_CONTROL/STATISTICS2", (void*)NULL, 0, this),
3618 fDimFadFileFormat ("FAD_CONTROL/FILE_FORMAT", (void*)NULL, 0, this),
3619 //-
3620 fDimFscTemp ("FSC_CONTROL/TEMPERATURE", (void*)NULL, 0, this),
3621 fDimFscVolt ("FSC_CONTROL/VOLTAGE", (void*)NULL, 0, this),
3622 fDimFscCurrent ("FSC_CONTROL/CURRENT", (void*)NULL, 0, this),
3623 fDimFscHumidity ("FSC_CONTROL/HUMIDITY", (void*)NULL, 0, this),
3624 //-
3625 fDimFeedbackCalibrated ("FEEDBACK/CALIBRATED_CURRENTS", (void*)NULL, 0, this),
3626 //-
3627 fDimBiasNominal ("BIAS_CONTROL/NOMINAL", (void*)NULL, 0, this),
3628 fDimBiasVolt ("BIAS_CONTROL/VOLTAGE", (void*)NULL, 0, this),
3629 fDimBiasDac ("BIAS_CONTROL/DAC", (void*)NULL, 0, this),
3630 fDimBiasCurrent ("BIAS_CONTROL/CURRENT", (void*)NULL, 0, this),
3631 //-
3632 fDimRateScan ("RATE_SCAN/DATA", (void*)NULL, 0, this),
3633 //-
3634 fDimMagicWeather ("MAGIC_WEATHER/DATA", (void*)NULL, 0, this),
3635 //-
3636 fDimVersion(0),
3637 fFreeSpaceLogger(UINT64_MAX), fFreeSpaceData(UINT64_MAX),
3638 fEventData(0),
3639 fDrsCalibration(1440*1024*6+160*1024*2),
3640 fTimeStamp0(0)
3641 {
3642 fClockCondFreq->addItem("--- Hz", QVariant(-1));
3643 fClockCondFreq->addItem("800 MHz", QVariant(800));
3644 fClockCondFreq->addItem("1 GHz", QVariant(1000));
3645 fClockCondFreq->addItem("2 GHz", QVariant(2000));
3646 fClockCondFreq->addItem("3 GHz", QVariant(3000));
3647 fClockCondFreq->addItem("4 GHz", QVariant(4000));
3648 fClockCondFreq->addItem("5 GHz", QVariant(5000));
3649
3650 cout << "-- run counter ---" << endl;
3651 fMcpNumEvents->addItem("unlimited", QVariant(0));
3652 const vector<uint32_t> runcount = conf.Vec<uint32_t>("run-count");
3653 for (vector<uint32_t>::const_iterator it=runcount.begin(); it!=runcount.end(); it++)
3654 {
3655 cout << *it << endl;
3656 ostringstream str;
3657 str << *it;
3658 fMcpNumEvents->addItem(str.str().c_str(), QVariant(*it));
3659 }
3660
3661 cout << "-- run times ---" << endl;
3662 fMcpTime->addItem("unlimited", QVariant(0));
3663 const vector<string> runtime = conf.Vec<string>("run-time");
3664 for (vector<string>::const_iterator it=runtime.begin(); it!=runtime.end(); it++)
3665 {
3666 const pair<string,string> p = Split(*it);
3667 cout << *it << "|" << p.second << "|" << p.first << "|" << endl;
3668 fMcpTime->addItem(p.second.c_str(), QVariant(stoi(p.first)));
3669 }
3670
3671 cout << "-- run types ---" << endl;
3672 const vector<string> runtype = conf.Vec<string>("run-type");
3673 for (vector<string>::const_iterator it=runtype.begin(); it!=runtype.end(); it++)
3674 {
3675 const pair<string,string> p = Split(*it);
3676 cout << *it << "|" << p.second << "|" << p.first << "|" << endl;
3677 fMcpRunType->addItem(p.second.c_str(), QVariant(p.first.c_str()));
3678 }
3679
3680 fTriggerWidget->setEnabled(false);
3681 fFtuWidget->setEnabled(false);
3682 fFtuGroupEnable->setEnabled(false);
3683 fRatesControls->setEnabled(false);
3684 fFadWidget->setEnabled(false);
3685 fGroupEthernet->setEnabled(false);
3686 fGroupOutput->setEnabled(false);
3687 fLoggerWidget->setEnabled(false);
3688 fBiasWidget->setEnabled(false);
3689 fAuxWidget->setEnabled(false);
3690
3691 fChatSend->setEnabled(false);
3692 fChatMessage->setEnabled(false);
3693
3694 DimClient::sendCommand("CHAT/MSG", "GUI online.");
3695 // + MessageDimRX
3696
3697 // --------------------------------------------------------------------------
3698
3699 if (!fPixelMap.Read(conf.GetPrefixedString("pixel-map-file")))
3700 {
3701 cerr << "ERROR - Problems reading " << conf.Get<string>("pixel-map-file") << endl;
3702 exit(-1);
3703 }
3704
3705 // --------------------------------------------------------------------------
3706
3707 ifstream fin3("PatchList.txt");
3708
3709 string buf;
3710
3711 int l = 0;
3712 while (getline(fin3, buf, '\n'))
3713 {
3714 buf = Tools::Trim(buf);
3715 if (buf[0]=='#')
3716 continue;
3717
3718 unsigned int softid, hardid;
3719
3720 stringstream str(buf);
3721
3722 str >> softid;
3723 str >> hardid;
3724
3725 if (softid>=fPatchMapHW.size())
3726 continue;
3727
3728 fPatchMapHW[softid] = hardid-1;
3729
3730 l++;
3731 }
3732
3733 if (l!=160)
3734 cerr << "WARNING - Problems reading PatchList.txt" << endl;
3735
3736 // --------------------------------------------------------------------------
3737
3738 fCommentsWidget->setEnabled(false);
3739
3740 static const boost::regex expr("(([[:word:].-]+)(:(.+))?@)?([[:word:].-]+)(:([[:digit:]]+))?(/([[:word:].-]+))");
3741
3742 const string database = conf.Get<string>("CommentDB");
3743
3744 if (!database.empty())
3745 {
3746 boost::smatch what;
3747 if (!boost::regex_match(database, what, expr, boost::match_extra))
3748 throw runtime_error("Couldn't parse '"+database+"'.");
3749
3750 if (what.size()!=10)
3751 throw runtime_error("Error parsing '"+database+"'.");
3752
3753 const string user = what[2];
3754 const string passwd = what[4];
3755 const string server = what[5];
3756 const string db = what[9];
3757 const int port = atoi(string(what[7]).c_str());
3758
3759 QSqlDatabase qdb = QSqlDatabase::addDatabase("QMYSQL");
3760 qdb.setHostName(server.c_str());
3761 qdb.setDatabaseName(db.c_str());
3762 qdb.setUserName(user.c_str());
3763 qdb.setPassword(passwd.c_str());
3764 qdb.setPort(port);
3765 qdb.setConnectOptions("CLIENT_SSL=1;MYSQL_OPT_RECONNECT=1");
3766 if (qdb.open())
3767 {
3768 QSqlTableModel *model = new QSqlTableModel(fTableComments, qdb);
3769 model->setTable("runcomments");
3770 model->setEditStrategy(QSqlTableModel::OnManualSubmit);
3771
3772 const bool ok2 = model->select();
3773
3774 if (ok2)
3775 {
3776 fTableComments->setModel(model);
3777 fTableComments->resizeColumnsToContents();
3778 fTableComments->resizeRowsToContents();
3779
3780 connect(fCommentSubmit, SIGNAL(clicked()), model, SLOT(submitAll()));
3781 connect(fCommentRevert, SIGNAL(clicked()), model, SLOT(revertAll()));
3782 connect(fCommentUpdateLayout, SIGNAL(clicked()), fTableComments, SLOT(resizeColumnsToContents()));
3783 connect(fCommentUpdateLayout, SIGNAL(clicked()), fTableComments, SLOT(resizeRowsToContents()));
3784
3785 fCommentsWidget->setEnabled(true);
3786 }
3787 else
3788 cout << "\n==> ERROR: Select on table failed.\n" << endl;
3789 }
3790 else
3791 cout << "\n==> ERROR: Connection to database failed:\n "
3792 << qdb.lastError().text().toStdString() << endl << endl;
3793 }
3794
3795 // --------------------------------------------------------------------------
3796#ifdef HAVE_ROOT
3797
3798 fGraphFeedbackDev.SetLineColor(kBlue);
3799 fGraphFeedbackDev.SetMarkerColor(kBlue);
3800 fGraphFeedbackDev.SetMarkerStyle(kFullDotMedium);
3801
3802 fGraphFeedbackCmd.SetLineColor(kBlue);
3803 fGraphFeedbackCmd.SetMarkerColor(kBlue);
3804 fGraphFeedbackCmd.SetMarkerStyle(kFullDotMedium);
3805
3806 // Evolution of control deviation
3807 // Evolution of command values (bias voltage change)
3808 fGraphFeedbackDev.SetName("ControlDev");
3809 fGraphFeedbackCmd.SetName("CommandVal");
3810
3811 TCanvas *c = fFeedbackDev->GetCanvas();
3812 c->SetBorderMode(0);
3813 c->SetFrameBorderMode(0);
3814 c->SetFillColor(kWhite);
3815 c->SetRightMargin(0.03);
3816 c->SetTopMargin(0.03);
3817 c->SetGrid();
3818
3819 TH1 *hf = DrawTimeFrame("Overvoltage [V] ");
3820 hf->GetXaxis()->SetLabelSize(0.07);
3821 hf->GetYaxis()->SetLabelSize(0.07);
3822 hf->GetYaxis()->SetTitleSize(0.08);
3823 hf->GetYaxis()->SetTitleOffset(0.55);
3824 hf->GetXaxis()->SetTitle("");
3825 hf->GetYaxis()->SetRangeUser(0, 1.5);
3826
3827 c->GetListOfPrimitives()->Add(hf, "");
3828 c->GetListOfPrimitives()->Add(&fGraphFeedbackDev, "LP");
3829
3830 c = fFeedbackCmd->GetCanvas();
3831 c->SetBorderMode(0);
3832 c->SetFrameBorderMode(0);
3833 c->SetFillColor(kWhite);
3834 c->SetRightMargin(0.03);
3835 c->SetTopMargin(0.03);
3836 c->SetGrid();
3837
3838 hf = DrawTimeFrame("Command temp delta [V] ");
3839 hf->GetXaxis()->SetLabelSize(0.07);
3840 hf->GetYaxis()->SetLabelSize(0.07);
3841 hf->GetYaxis()->SetTitleSize(0.08);
3842 hf->GetYaxis()->SetTitleOffset(0.55);
3843 hf->GetXaxis()->SetTitle("");
3844 hf->GetYaxis()->SetRangeUser(-2, 2);
3845
3846 c->GetListOfPrimitives()->Add(hf, "");
3847 c->GetListOfPrimitives()->Add(&fGraphFeedbackCmd, "LP");
3848
3849 // --------------------------------------------------------------------------
3850
3851 c = fRateScanCanv->GetCanvas();
3852 //c->SetBit(TCanvas::kNoContextMenu);
3853 c->SetBorderMode(0);
3854 c->SetFrameBorderMode(0);
3855 c->SetFillColor(kWhite);
3856 c->SetRightMargin(0.03);
3857 c->SetTopMargin(0.03);
3858 c->SetGrid();
3859
3860 TH1F *h=new TH1F("Frame", "", 1, 0, 1);
3861 h->SetDirectory(0);
3862 h->SetBit(kCanDelete);
3863 h->SetStats(kFALSE);
3864 h->SetXTitle("Threshold [DAC]");
3865 h->SetYTitle("Rate [Hz]");
3866 h->GetXaxis()->CenterTitle();
3867 h->GetYaxis()->CenterTitle();
3868 h->GetXaxis()->SetLabelSize(0.025);
3869 h->GetYaxis()->SetLabelSize(0.025);
3870 h->GetYaxis()->SetTitleOffset(1.2);
3871 c->GetListOfPrimitives()->Add(h, "");
3872
3873 fGraphRateScan[0].SetName("CameraRate");
3874 for (int i=0; i<40; i++)
3875 {
3876 fGraphRateScan[i+1].SetName("BoardRate");
3877 fGraphRateScan[i+1].SetMarkerStyle(kFullDotMedium);
3878 }
3879 for (int i=0; i<160; i++)
3880 {
3881 fGraphRateScan[i+41].SetName("PatchRate");
3882 fGraphRateScan[i+41].SetMarkerStyle(kFullDotMedium);
3883 }
3884
3885 fGraphRateScan[0].SetLineColor(kBlue);
3886 fGraphRateScan[0].SetMarkerColor(kBlue);
3887 fGraphRateScan[0].SetMarkerStyle(kFullDotSmall);
3888 c->GetListOfPrimitives()->Add(&fGraphRateScan[0], "LP");
3889
3890 // --------------------------------------------------------------------------
3891
3892 c = fFtmRateCanv->GetCanvas();
3893 //c->SetBit(TCanvas::kNoContextMenu);
3894 c->SetBorderMode(0);
3895 c->SetFrameBorderMode(0);
3896 c->SetFillColor(kWhite);
3897 c->SetRightMargin(0.03);
3898 c->SetTopMargin(0.03);
3899 c->SetGrid();
3900
3901 hf = DrawTimeFrame("Trigger rate [Hz]");
3902 hf->GetYaxis()->SetRangeUser(0, 1010);
3903
3904 for (int i=0; i<160; i++)
3905 {
3906 fGraphPatchRate[i].SetName("PatchRate");
3907 //fGraphPatchRate[i].SetLineColor(kBlue);
3908 //fGraphPatchRate[i].SetMarkerColor(kBlue);
3909 fGraphPatchRate[i].SetMarkerStyle(kFullDotMedium);
3910 }
3911 for (int i=0; i<40; i++)
3912 {
3913 fGraphBoardRate[i].SetName("BoardRate");
3914 //fGraphBoardRate[i].SetLineColor(kBlue);
3915 //fGraphBoardRate[i].SetMarkerColor(kBlue);
3916 fGraphBoardRate[i].SetMarkerStyle(kFullDotMedium);
3917 }
3918
3919 fGraphFtmRate.SetLineColor(kBlue);
3920 fGraphFtmRate.SetMarkerColor(kBlue);
3921 fGraphFtmRate.SetMarkerStyle(kFullDotSmall);
3922
3923 c->GetListOfPrimitives()->Add(hf, "");
3924 c->GetListOfPrimitives()->Add(&fGraphFtmRate, "LP");
3925
3926 /*
3927 TCanvas *c = fFtmTempCanv->GetCanvas();
3928 c->SetBit(TCanvas::kNoContextMenu);
3929 c->SetBorderMode(0);
3930 c->SetFrameBorderMode(0);
3931 c->SetFillColor(kWhite);
3932 c->SetRightMargin(0.03);
3933 c->SetTopMargin(0.03);
3934 c->cd();
3935 */
3936 //CreateTimeFrame("Temperature / �C");
3937
3938 fGraphFtmTemp[0].SetMarkerStyle(kFullDotSmall);
3939 fGraphFtmTemp[1].SetMarkerStyle(kFullDotSmall);
3940 fGraphFtmTemp[2].SetMarkerStyle(kFullDotSmall);
3941 fGraphFtmTemp[3].SetMarkerStyle(kFullDotSmall);
3942
3943 fGraphFtmTemp[1].SetLineColor(kBlue);
3944 fGraphFtmTemp[2].SetLineColor(kRed);
3945 fGraphFtmTemp[3].SetLineColor(kGreen);
3946
3947 fGraphFtmTemp[1].SetMarkerColor(kBlue);
3948 fGraphFtmTemp[2].SetMarkerColor(kRed);
3949 fGraphFtmTemp[3].SetMarkerColor(kGreen);
3950
3951 //fGraphFtmTemp[0].Draw("LP");
3952 //fGraphFtmTemp[1].Draw("LP");
3953 //fGraphFtmTemp[2].Draw("LP");
3954 //fGraphFtmTemp[3].Draw("LP");
3955
3956 // --------------------------------------------------------------------------
3957
3958 c = fAdcDataCanv->GetCanvas();
3959 //c->SetBit(TCanvas::kNoContextMenu);
3960 c->SetBorderMode(0);
3961 c->SetFrameBorderMode(0);
3962 c->SetFillColor(kWhite);
3963 c->SetRightMargin(0.10);
3964 c->SetGrid();
3965 //c->cd();
3966#endif
3967
3968 // --------------------------------------------------------------------------
3969 fFeedbackDevCam->assignPixelMap(fPixelMap);
3970 fFeedbackDevCam->setAutoscaleLowerLimit((fFeedbackDevMin->minimum()+0.5*fFeedbackDevMin->singleStep()));
3971 fFeedbackDevCam->SetMin(fFeedbackDevMin->value());
3972 fFeedbackDevCam->SetMax(fFeedbackDevMax->value());
3973 fFeedbackDevCam->updateCamera();
3974
3975 fFeedbackCmdCam->assignPixelMap(fPixelMap);
3976 fFeedbackCmdCam->setAutoscaleLowerLimit((fFeedbackCmdMin->minimum()+0.5*fFeedbackCmdMin->singleStep()));
3977 fFeedbackCmdCam->SetMin(fFeedbackCmdMin->value());
3978 fFeedbackCmdCam->SetMax(fFeedbackCmdMax->value());
3979 fFeedbackCmdCam->updateCamera();
3980
3981 // --------------------------------------------------------------------------
3982
3983 fBiasCamV->assignPixelMap(fPixelMap);
3984 fBiasCamV->setAutoscaleLowerLimit((fBiasVoltMin->minimum()+0.5*fBiasVoltMin->singleStep()));
3985 fBiasCamV->SetMin(fBiasVoltMin->value());
3986 fBiasCamV->SetMax(fBiasVoltMax->value());
3987 fBiasCamV->updateCamera();
3988
3989 fBiasCamA->assignPixelMap(fPixelMap);
3990 fBiasCamA->setAutoscaleLowerLimit((fBiasCurrentMin->minimum()+0.5*fBiasCurrentMin->singleStep()));
3991 fBiasCamA->SetMin(fBiasCurrentMin->value());
3992 fBiasCamA->SetMax(fBiasCurrentMax->value());
3993 fBiasCamA->updateCamera();
3994
3995 // --------------------------------------------------------------------------
3996
3997 fRatesCanv->assignPixelMap(fPixelMap);
3998 fRatesCanv->setAutoscaleLowerLimit((fRatesMin->minimum()+0.5*fRatesMin->singleStep())*0.001);
3999 fRatesCanv->SetMin(fRatesMin->value());
4000 fRatesCanv->SetMax(fRatesMax->value());
4001 fRatesCanv->updateCamera();
4002 on_fPixelIdx_valueChanged(0);
4003
4004 // --------------------------------------------------------------------------
4005
4006 fRatesCanv->setTitle("Patch rates");
4007 fRatesCanv->setUnits("Hz");
4008
4009 fBiasCamA->setTitle("BIAS current");
4010 fBiasCamA->setUnits("uA");
4011
4012 fBiasCamV->setTitle("Applied BIAS voltage");
4013 fBiasCamV->setUnits("V");
4014
4015 fEventCanv1->setTitle("Average (all slices)");
4016 fEventCanv2->setTitle("RMS (all slices)");
4017 fEventCanv3->setTitle("Maximum (all slices)");
4018 fEventCanv4->setTitle("Position of maximum (all slices)");
4019
4020 fEventCanv1->setUnits("mV");
4021 fEventCanv2->setUnits("mV");
4022 fEventCanv3->setUnits("mV");
4023 fEventCanv4->setUnits("slice");
4024
4025 // --------------------------------------------------------------------------
4026
4027 fFeedbackDevCam->setTitle("Control deviation (Pulser amplitude voltage)");
4028 fFeedbackCmdCam->setTitle("Applied voltage change (BIAS voltage)");
4029
4030 fFeedbackDevCam->setUnits("mV");
4031 fFeedbackCmdCam->setUnits("mV");
4032
4033 // --------------------------------------------------------------------------
4034
4035 QTimer::singleShot(1000, this, SLOT(slot_RootUpdate()));
4036
4037 //widget->setMouseTracking(true);
4038 //widget->EnableSignalEvents(kMouseMoveEvent);
4039
4040 fFtmRateCanv->setMouseTracking(true);
4041 fFtmRateCanv->EnableSignalEvents(kMouseMoveEvent);
4042
4043 fAdcDataCanv->setMouseTracking(true);
4044 fAdcDataCanv->EnableSignalEvents(kMouseMoveEvent);
4045
4046 fRatesCanv->setMouseTracking(true);
4047 fEventCanv1->setMouseTracking(true);
4048 fEventCanv2->setMouseTracking(true);
4049 fEventCanv3->setMouseTracking(true);
4050 fEventCanv4->setMouseTracking(true);
4051
4052 fBiasCamV->setMouseTracking(true);
4053 fBiasCamA->setMouseTracking(true);
4054
4055 fFeedbackDevCam->setMouseTracking(true);
4056 fFeedbackCmdCam->setMouseTracking(true);
4057
4058 fEventCanv1->ShowPixelCursor(true);
4059 fEventCanv2->ShowPixelCursor(true);
4060 fEventCanv3->ShowPixelCursor(true);
4061 fEventCanv4->ShowPixelCursor(true);
4062
4063 fEventCanv1->ShowPatchCursor(true);
4064 fEventCanv2->ShowPatchCursor(true);
4065 fEventCanv3->ShowPatchCursor(true);
4066 fEventCanv4->ShowPatchCursor(true);
4067
4068 fFeedbackDevCam->ShowPixelCursor(true);
4069 fFeedbackCmdCam->ShowPixelCursor(true);
4070
4071 fFeedbackDevCam->ShowPatchCursor(true);
4072 fFeedbackCmdCam->ShowPatchCursor(true);
4073
4074 connect(fRatesCanv, SIGNAL(signalPixelMoveOver(int)),
4075 this, SLOT(slot_CameraMouseMove(int)));
4076 connect(fEventCanv1, SIGNAL(signalPixelMoveOver(int)),
4077 this, SLOT(slot_CameraMouseMove(int)));
4078 connect(fEventCanv2, SIGNAL(signalPixelMoveOver(int)),
4079 this, SLOT(slot_CameraMouseMove(int)));
4080 connect(fEventCanv3, SIGNAL(signalPixelMoveOver(int)),
4081 this, SLOT(slot_CameraMouseMove(int)));
4082 connect(fEventCanv4, SIGNAL(signalPixelMoveOver(int)),
4083 this, SLOT(slot_CameraMouseMove(int)));
4084
4085 connect(fBiasCamV, SIGNAL(signalPixelMoveOver(int)),
4086 this, SLOT(slot_CameraMouseMove(int)));
4087 connect(fBiasCamA, SIGNAL(signalPixelMoveOver(int)),
4088 this, SLOT(slot_CameraMouseMove(int)));
4089
4090 connect(fFeedbackDevCam, SIGNAL(signalPixelMoveOver(int)),
4091 this, SLOT(slot_CameraMouseMove(int)));
4092 connect(fFeedbackCmdCam, SIGNAL(signalPixelMoveOver(int)),
4093 this, SLOT(slot_CameraMouseMove(int)));
4094
4095 connect(fRatesCanv, SIGNAL(signalPixelDoubleClick(int)),
4096 this, SLOT(slot_CameraDoubleClick(int)));
4097 connect(fRatesCanv, SIGNAL(signalCurrentPixel(int)),
4098 this, SLOT(slot_ChoosePixelThreshold(int)));
4099 connect(fBiasCamV, SIGNAL(signalCurrentPixel(int)),
4100 this, SLOT(slot_ChooseBiasChannel(int)));
4101 connect(fBiasCamA, SIGNAL(signalCurrentPixel(int)),
4102 this, SLOT(slot_ChooseBiasChannel(int)));
4103
4104 connect(fFtmRateCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)),
4105 this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*)));
4106 connect(fAdcDataCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)),
4107 this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*)));
4108 }
4109
4110 ~FactGui()
4111 {
4112 // Unsubscribe all services
4113 for (map<string,DimInfo*>::iterator i=fServices.begin();
4114 i!=fServices.end(); i++)
4115 delete i->second;
4116
4117 // This is allocated as a chuck of chars
4118 delete [] reinterpret_cast<char*>(fEventData);
4119 }
4120};
4121
4122#endif
Note: See TracBrowser for help on using the repository browser.