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

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