#ifndef FACT_FactGui #define FACT_FactGui #include "MainWindow.h" #include #include #include #include #include #include "CheckBoxDelegate.h" #include "src/Dim.h" #include "src/Converter.h" #include "src/HeadersFTM.h" #include "src/HeadersFAD.h" #include "src/DimNetwork.h" #include "src/tools.h" #include "src/FAD.h" #include "TROOT.h" #include "TSystem.h" #include "TGraph.h" #include "TH1.h" #include "TStyle.h" #include "TMarker.h" #include "TColor.h" using namespace std; // ######################################################################### class Camera : public TObject { typedef pair Position; typedef vector Positions; Positions fGeom; void CreatePalette() { /* double ss[5] = {0., 0.10, 0.45, 0.75, 1.00}; double rr[5] = {0., 0.35, 0.85, 1.00, 1.00}; double gg[5] = {0., 0.10, 0.20, 0.73, 1.00}; double bb[5] = {0., 0.03, 0.06, 0.00, 1.00}; */ double ss[5] = {0.00, 0.25, 0.50, 0.75, 1.00}; double rr[5] = {0.15, 0.00, 0.00, 1.00, 0.85}; double gg[5] = {0.15, 0.00, 1.00, 0.00, 0.85}; double bb[5] = {0.15, 1.00, 0.00, 0.00, 0.85}; const Int_t nn = 1440; Int_t idx = TColor::CreateGradientColorTable(5, ss, rr, gg, bb, nn); for (int i=0; i 395.75) continue; fGeom.push_back(make_pair(yy, xx-0.5)); } } } } valarray fData; vector fBold; vector fEnable; int fWhite; public: Camera() : fData(1440), fBold(1440), fEnable(1440), fWhite(-1) { CreatePalette(); CreateGeometry(); for (int i=0; i<1440; i++) { fData[i] = i; fBold[i]=false; fEnable[i]=true; } } void Reset() { fBold.assign(1440, false); } void SetBold(int idx) { fBold[idx]=true; } void SetWhite(int idx) { fWhite=idx; } void SetEnable(int idx, bool b) { fEnable[idx]=b; } void Toggle(int idx) { fEnable[idx]=!fEnable[idx]; } double GetData(int idx) const { return fData[idx]; } const char *GetName() const { return "Camera"; } vector fPalette; void Paint(const Position &p) { static const Double_t fgCos60 = 0.5; // TMath::Cos(60/TMath::RadToDeg()); static const Double_t fgSin60 = sqrt(3.)/2; // TMath::Sin(60/TMath::RadToDeg()); static const Double_t fgDy[6] = { fgCos60, 0., -fgCos60, -fgCos60, 0., fgCos60 }; static const Double_t fgDx[6] = { fgSin60/3, fgSin60*2/3, fgSin60/3, -fgSin60/3, -fgSin60*2/3, -fgSin60/3 }; // // calculate the positions of the pixel corners // Double_t x[7], y[7]; for (Int_t i=0; i<7; i++) { x[i] = p.first + fgDx[i%6]; y[i] = p.second + fgDy[i%6]; } gPad->PaintFillArea(6, x, y); gPad->PaintPolyLine(7, x, y); } double align(double min, double val, double max) const { if (valmax) return max; return val; } void Paint(Option_t *) { gStyle->SetPalette(fPalette.size(), fPalette.data()); const double r = double(gPad->GetWw())/gPad->GetWh(); const double max = 20.5; // 20.5 rings in x and y if (r>1) gPad->Range(-r*max, -max, r*max, max); else gPad->Range(-max, -max/r, max, max/r); Double_t x1, x2, y1, y2; gPad->GetRange(x1, x2, y1, y2); double dmin = fData[0]; double dmax = fData[0]; for (unsigned int i=0; idmax) dmax = fData[i]; if (fData[i]GetColorPalette(col)); else fill.SetFillColor(kWhite); fill.Modify(); Paint(*p); } line.SetLineWidth(2); line.Modify(); cnt = 0; for (Positions::iterator p=fGeom.begin(); p!=fGeom.end(); p++, cnt++) { if (!fBold[cnt]) continue; const double val = align(dmin, fData[cnt], dmax); const int col = (val-min)/scale*(fPalette.size()-1); if (fEnable[cnt]) fill.SetFillColor(gStyle->GetColorPalette(col)); else fill.SetFillColor(kWhite); fill.Modify(); Paint(*p); } TMarker m(0,0,kStar); m.DrawMarker(0, 0); if (fWhite<0) return; const Position &p = fGeom[fWhite]; line.SetLineColor(kWhite); line.Modify(); const double val = align(dmin, fData[fWhite], dmax); const int col = (val-min)/scale*(fPalette.size()-1); if (fEnable[fWhite]) fill.SetFillColor(gStyle->GetColorPalette(col)); else fill.SetFillColor(kWhite); fill.Modify(); Paint(p); } int GetIdx(float px, float py) const { static const double sqrt3 = sqrt(3); int idx = 0; for (Positions::const_iterator p=fGeom.begin(); p!=fGeom.end(); p++, idx++) { const Double_t dy = py - p->second; if (fabs(dy)>0.5) continue; const Double_t dx = px - p->first; if (TMath::Abs(dy + dx*sqrt3) > 1) continue; if (TMath::Abs(dy - dx*sqrt3) > 1) continue; return idx; } return -1; } char *GetObjectInfo(Int_t px, Int_t py) const { static stringstream stream; static string str; const float x = gPad->AbsPixeltoX(px); const float y = gPad->AbsPixeltoY(py); const int idx = GetIdx(x, y); stream.seekp(0); if (idx>=0) { stream << "Pixel=" << idx << " Data=" << fData[idx] << '\0'; } str = stream.str(); return const_cast(str.c_str()); } Int_t DistancetoPrimitive(Int_t px, Int_t py) { const float x = gPad->AbsPixeltoX(px); const float y = gPad->AbsPixeltoY(py); return GetIdx(x, y)>=0 ? 0 : 99999; } void SetData(const valarray &data) { fData = data; } }; // ######################################################################### class FactGui : public MainWindow, public DimNetwork { private: class FunctionEvent : public QEvent { public: boost::function fFunction; FunctionEvent(const boost::function &f) : QEvent((QEvent::Type)QEvent::registerEventType()), fFunction(f) { } bool Exec() { fFunction(*this); return true; } }; valarray fFtuStatus; vector fPixelMapHW; // Software -> Hardware vector fPatchMapHW; // Software -> Hardware vector fPatchHW; // Maps the software(!) pixel id to the hardware(!) patch id bool fInChoosePatch; // FIXME. Find a better solution DimStampedInfo fDimDNS; DimStampedInfo fDimLoggerStats; DimStampedInfo fDimLoggerFilenameNight; DimStampedInfo fDimLoggerFilenameRun; DimStampedInfo fDimLoggerNumSubs; DimStampedInfo fDimFtmPassport; DimStampedInfo fDimFtmTriggerCounter; DimStampedInfo fDimFtmError; DimStampedInfo fDimFtmFtuList; DimStampedInfo fDimFtmStaticData; DimStampedInfo fDimFtmDynamicData; DimStampedInfo fDimFtmCounter; DimStampedInfo fDimFadRuns; DimStampedInfo fDimFadEvents; DimStampedInfo fDimFadEventData; DimStampedInfo fDimFadConnections; DimStampedInfo fDimFadFwVersion; DimStampedInfo fDimFadRunNumber; DimStampedInfo fDimFadDNA; DimStampedInfo fDimFadTemperature; DimStampedInfo fDimFadRefClock; DimStampedInfo fDimFadStatus; DimStampedInfo fDimFadStatistics1; DimStampedInfo fDimFadStatistics2; map fServices; // ========================== LED Colors ================================ enum LedColor_t { kLedRed, kLedGreen, kLedYellow, kLedOrange, kLedGray }; void SetLedColor(QPushButton *button, LedColor_t col, const Time &t) { switch (col) { case kLedRed: button->setIcon(QIcon(":/Resources/icons/red circle 1.png")); break; case kLedGreen: button->setIcon(QIcon(":/Resources/icons/green circle 1.png")); break; case kLedYellow: button->setIcon(QIcon(":/Resources/icons/yellow circle 1.png")); break; case kLedOrange: button->setIcon(QIcon(":/Resources/icons/orange circle 1.png")); break; case kLedGray: button->setIcon(QIcon(":/Resources/icons/gray circle 1.png")); break; } //button->setToolTip("Last change: "+QDateTime::currentDateTimeUtc().toString()+" UTC"); button->setToolTip(("Last change: "+t.GetAsStr()+" (UTC)").c_str()); } // ===================== Services and Commands ========================== QStandardItem *AddServiceItem(const std::string &server, const std::string &service, bool iscmd) { QListView *servers = iscmd ? fDimCmdServers : fDimSvcServers; QListView *services = iscmd ? fDimCmdCommands : fDimSvcServices; QListView *description = iscmd ? fDimCmdDescription : fDimSvcDescription; QStandardItemModel *m = dynamic_cast(servers->model()); if (!m) { m = new QStandardItemModel(this); servers->setModel(m); services->setModel(m); description->setModel(m); } QList l = m->findItems(server.c_str()); if (l.size()>1) { cout << "hae" << endl; return 0; } QStandardItem *col = l.size()==0 ? NULL : l[0]; if (!col) { col = new QStandardItem(server.c_str()); m->appendRow(col); if (!services->rootIndex().isValid()) { services->setRootIndex(col->index()); servers->setCurrentIndex(col->index()); } } QStandardItem *item = 0; for (int i=0; irowCount(); i++) { QStandardItem *coli = col->child(i); if (coli->text().toStdString()==service) return coli; } item = new QStandardItem(service.c_str()); col->appendRow(item); col->sortChildren(0); if (!description->rootIndex().isValid()) { description->setRootIndex(item->index()); services->setCurrentIndex(item->index()); } if (!iscmd) item->setCheckable(true); return item; } void AddDescription(QStandardItem *item, const vector &vec) { if (!item) return; if (vec.size()==0) return; item->setToolTip(vec[0].comment.c_str()); const string str = Description::GetHtmlDescription(vec); QStandardItem *desc = new QStandardItem(str.c_str()); desc->setSelectable(false); item->setChild(0, 0, desc); } void AddServer(const std::string &s) { DimNetwork::AddServer(s); QApplication::postEvent(this, new FunctionEvent(boost::bind(&FactGui::handleAddServer, this, s))); } void AddService(const std::string &server, const std::string &service, const std::string &fmt, bool iscmd) { QApplication::postEvent(this, new FunctionEvent(boost::bind(&FactGui::handleAddService, this, server, service, fmt, iscmd))); } void RemoveService(const std::string &server, const std::string &service, bool iscmd) { UnsubscribeService(server+'/'+service); QApplication::postEvent(this, new FunctionEvent(boost::bind(&FactGui::handleRemoveService, this, server, service, iscmd))); } void RemoveAllServices(const std::string &server) { UnsubscribeAllServices(server); QApplication::postEvent(this, new FunctionEvent(boost::bind(&FactGui::handleRemoveAllServices, this, server))); } void AddDescription(const std::string &server, const std::string &service, const vector &vec) { QApplication::postEvent(this, new FunctionEvent(boost::bind(&FactGui::handleAddDescription, this, server, service, vec))); } // ====================================================================== void handleAddServer(const std::string &server) { const State s = GetState(server, GetCurrentState(server)); handleStateChanged(Time(), server, s); } void handleAddService(const std::string &server, const std::string &service, const std::string &/*fmt*/, bool iscmd) { QStandardItem *item = AddServiceItem(server, service, iscmd); const vector v = GetDescription(server, service); AddDescription(item, v); } void handleRemoveService(const std::string &server, const std::string &service, bool iscmd) { QListView *servers = iscmd ? fDimCmdServers : fDimSvcServers; QStandardItemModel *m = dynamic_cast(servers->model()); if (!m) return; QList l = m->findItems(server.c_str()); if (l.size()!=1) return; for (int i=0; irowCount(); i++) { QStandardItem *row = l[0]->child(i); if (row->text().toStdString()==service) { l[0]->removeRow(row->index().row()); return; } } } void handleRemoveAllServices(const std::string &server) { handleStateChanged(Time(), server, State(-2, "Offline", "No connection via DIM.")); QStandardItemModel *m = 0; if ((m=dynamic_cast(fDimCmdServers->model()))) { QList l = m->findItems(server.c_str()); if (l.size()==1) m->removeRow(l[0]->index().row()); } if ((m = dynamic_cast(fDimSvcServers->model()))) { QList l = m->findItems(server.c_str()); if (l.size()==1) m->removeRow(l[0]->index().row()); } } void handleAddDescription(const std::string &server, const std::string &service, const vector &vec) { const bool iscmd = IsCommand(server, service)==true; QStandardItem *item = AddServiceItem(server, service, iscmd); AddDescription(item, vec); } // ====================================================================== void SubscribeService(const string &service) { if (fServices.find(service)!=fServices.end()) { cout << "ERROR - We are already subscribed to " << service << endl; return; } fServices[service] = new DimStampedInfo(service.c_str(), (void*)NULL, 0, this); } void UnsubscribeService(const string &service) { const map::iterator i=fServices.find(service); if (i==fServices.end()) { cout << "ERROR - We are not subscribed to " << service << endl; return; } delete i->second; fServices.erase(i); } void UnsubscribeAllServices(const string &server) { for (map::iterator i=fServices.begin(); i!=fServices.end(); i++) if (i->first.substr(0, server.length()+1)==server+'/') { delete i->second; fServices.erase(i); } } // ====================================================================== struct DimData { const int qos; const string name; const string format; const vector data; const Time time; Time extract(DimInfo *inf) const { // Must be called in exactly this order! const int tsec = inf->getTimestamp(); const int tms = inf->getTimestampMillisecs(); return Time(tsec, tms*1000); } // DimInfo *info; // this is ONLY for a fast check of the type of the DimData!! DimData(DimInfo *inf) : qos(inf->getQuality()), name(inf->getName()), format(inf->getFormat()), data(inf->getString(), inf->getString()+inf->getSize()), time(extract(inf))/*, info(inf)*/ { } template T get(uint32_t offset=0) const { return *reinterpret_cast(data.data()+offset); } template const T *ptr(uint32_t offset=0) const { return reinterpret_cast(data.data()+offset); } template const T &ref(uint32_t offset=0) const { return *reinterpret_cast(data.data()+offset); } // vector vec(int b) const { return vector(data.begin()+b, data.end()); } // string str(unsigned int b) const { return b>=data.size()?string():string(data.data()+b, data.size()-b); } const char *c_str() const { return (char*)data.data(); } /* vector any() const { const Converter conv(format); conv.Print(); return conv.GetAny(data.data(), data.size()); }*/ size_t size() const { return data.size(); } }; // ======================= DNS ========================================== void handleDimDNS(const DimData &d) { const int version = d.size()!=4 ? 0 : d.get(); ostringstream str; str << "V" << version/100 << 'r' << version%100; ostringstream dns; dns << (version==0?"No connection":"Connection"); dns << " to DIM DNS (" << getenv("DIM_DNS_NODE") << ")"; dns << (version==0?".":" established."); fStatusDNSLabel->setText(version==0?"Offline":str.str().c_str()); fStatusDNSLabel->setToolTip(dns.str().c_str()); SetLedColor(fStatusDNSLed, version==0 ? kLedRed : kLedGreen, Time()); } // ======================= Logger ======================================= void handleLoggerStats(const DimData &d) { const bool connected = d.size()!=0; fLoggerET->setEnabled(connected); fLoggerRate->setEnabled(connected); fLoggerWritten->setEnabled(connected); fLoggerFreeSpace->setEnabled(connected); fLoggerSpaceLeft->setEnabled(connected); if (!connected) return; const uint64_t *vals = d.ptr(); const size_t written = vals[0]; const size_t space = vals[1]; const size_t rate = vals[2]; fLoggerFreeSpace->setSuffix(" MB"); fLoggerFreeSpace->setDecimals(0); fLoggerFreeSpace->setValue(space*1e-6); if (space> 1000000) // > 1GB { fLoggerFreeSpace->setSuffix(" GB"); fLoggerFreeSpace->setDecimals(2); fLoggerFreeSpace->setValue(space*1e-9); } if (space>= 3000000) // >= 3GB { fLoggerFreeSpace->setSuffix(" GB"); fLoggerFreeSpace->setDecimals(1); fLoggerFreeSpace->setValue(space*1e-9); } if (space>=100000000) // >= 100GB { fLoggerFreeSpace->setSuffix(" GB"); fLoggerFreeSpace->setDecimals(0); fLoggerFreeSpace->setValue(space*1e-9); } fLoggerET->setTime(QTime().addSecs(rate>0?space/rate:0)); fLoggerRate->setValue(rate*1e-3); // kB/s fLoggerWritten->setValue(written*1e-6); fLoggerRate->setSuffix(" kB/s"); fLoggerRate->setDecimals(2); fLoggerRate->setValue(rate*1e-3); if (rate> 2000) // > 2kB/s { fLoggerRate->setSuffix(" kB/s"); fLoggerRate->setDecimals(1); fLoggerRate->setValue(rate*1e-3); } if (rate>=100000) // >100kB/s { fLoggerRate->setSuffix(" kB/s"); fLoggerRate->setDecimals(0); fLoggerRate->setValue(rate*1e-3); } if (rate>=1000000) // >100kB/s { fLoggerRate->setSuffix(" MB/s"); fLoggerRate->setDecimals(2); fLoggerRate->setValue(rate*1e-6); } if (rate>=10000000) // >1MB/s { fLoggerRate->setSuffix(" MB/s"); fLoggerRate->setDecimals(1); fLoggerRate->setValue(rate*1e-6); } if (rate>=100000000) // >10MB/s { fLoggerRate->setSuffix(" MB/s"); fLoggerRate->setDecimals(0); fLoggerRate->setValue(rate*1e-6); } if (space/1000000>static_cast(fLoggerSpaceLeft->maximum())) fLoggerSpaceLeft->setValue(fLoggerSpaceLeft->maximum()); // GB else fLoggerSpaceLeft->setValue(space/1000000); // MB } void handleLoggerFilenameNight(const DimData &d) { const bool connected = d.size()!=0; fLoggerFilenameNight->setEnabled(connected); if (!connected) return; fLoggerFilenameNight->setText(d.c_str()+4); const uint32_t files = d.get(); SetLedColor(fLoggerLedLog, files&1 ? kLedGreen : kLedGray, d.time); SetLedColor(fLoggerLedRep, files&2 ? kLedGreen : kLedGray, d.time); SetLedColor(fLoggerLedFits, files&4 ? kLedGreen : kLedGray, d.time); } void handleLoggerFilenameRun(const DimData &d) { const bool connected = d.size()!=0; fLoggerFilenameRun->setEnabled(connected); if (!connected) return; fLoggerFilenameRun->setText(d.c_str()+4); const uint32_t files = d.get(); SetLedColor(fLoggerLedLog, files&1 ? kLedGreen : kLedGray, d.time); SetLedColor(fLoggerLedRep, files&2 ? kLedGreen : kLedGray, d.time); SetLedColor(fLoggerLedFits, files&4 ? kLedGreen : kLedGray, d.time); } void handleLoggerNumSubs(const DimData &d) { const bool connected = d.size()!=0; fLoggerSubscriptions->setEnabled(connected); fLoggerOpenFiles->setEnabled(connected); if (!connected) return; const uint32_t *vals = d.ptr(); fLoggerSubscriptions->setValue(vals[0]); fLoggerOpenFiles->setValue(vals[1]); } // ===================== All ============================================ bool CheckSize(const DimData &d, size_t sz) const { if (d.size()==0) return false; if (d.size()!=sz) { cout << "Size mismatch in " << d.name << ": Found=" << d.size() << " Expected=" << sz << endl; return false; } return true; } // ===================== FAD ============================================ void handleFadRuns(const DimData &d) { if (!CheckSize(d, 20)) return; const uint32_t *ptr = d.ptr(); fEvtBldOpenFiles->setValue(ptr[0]); fEvtBldOpenStreams->setValue(ptr[0]); fEvtBldRunNumberMin->setValue(ptr[1]); fEvtBldRunNumberMax->setValue(ptr[2]); fEvtBldLastOpened->setValue(ptr[3]); fEvtBldLastClosed->setValue(ptr[4]); } void handleFadEvents(const DimData &d) { if (!CheckSize(d, 16)) return; const uint32_t *ptr = d.ptr(); fEvtsSuccessCurRun->setValue(ptr[0]); fEvtsSuccessTotal->setValue(ptr[1]); fEvtBldEventId->setValue(ptr[2]); fEvtBldTriggerId->setValue(ptr[3]); } void handleFadTemperature(const DimData &d) { if (d.size()==0) { fFadTempMin->setEnabled(false); fFadTempMax->setEnabled(false); SetLedColor(fFadLedTemp, kLedGray, d.time); return; } if (!CheckSize(d, 82*sizeof(float))) return; const float *ptr = d.ptr(); fFadTempMin->setEnabled(true); fFadTempMax->setEnabled(true); fFadTempMin->setValue(ptr[0]); fFadTempMax->setValue(ptr[40]); handleFadToolTip(d.time, fFadTempMin, ptr+1); handleFadToolTip(d.time, fFadTempMax, ptr+41); } void handleFadRefClock(const DimData &d) { if (d.size()==0) { fFadRefClockMin->setEnabled(false); fFadRefClockMax->setEnabled(false); SetLedColor(fFadLedRefClock, kLedGray, d.time); return; } if (!CheckSize(d, 42*sizeof(uint32_t))) return; const uint32_t *ptr = d.ptr(); fFadRefClockMin->setEnabled(true); fFadRefClockMax->setEnabled(true); fFadRefClockMin->setValue(ptr[40]*2.048); fFadRefClockMax->setValue(ptr[41]*2.048); const int64_t diff = int64_t(ptr[41]) - int64_t(ptr[40]); SetLedColor(fFadLedRefClock, abs(diff)>3?kLedRed:kLedGreen, d.time); handleFadToolTip(d.time, fFadLedRefClock, ptr+2); } struct DimEventData { uint16_t Roi ; // #slices per pixel (same for all pixels and tmarks) uint32_t EventNum ; // EventNumber as from FTM uint16_t TriggerType ; // Trigger Type from FTM uint32_t PCTime ; // when did event start to arrive at PC uint32_t BoardTime; // int16_t StartPix; // First Channel per Pixel (Pixels sorted according Software ID) ; -1 if not filled int16_t StartTM; // First Channel for TimeMark (sorted Hardware ID) ; -1 if not filled int16_t Adc_Data[]; // final length defined by malloc .... } __attribute__((__packed__));; DimEventData *fEventData; void DisplayEventData() { #ifdef HAVE_ROOT TCanvas *c = fAdcDataCanv->GetCanvas(); TH1 *h = dynamic_cast(c->FindObject("EventData")); if (h && h->GetNbinsX()!=fEventData->Roi) { delete h; h = 0; } if (!h) { c->cd(); TH1D hist("EventData", "", fEventData->Roi, -0.5, fEventData->Roi-0.5); hist.SetStats(kFALSE); //hist->SetBit(TH1::kNoTitle); hist.SetMarkerStyle(kFullDotMedium); hist.SetMarkerColor(kBlue); hist.SetYTitle("Voltage [mV]"); hist.GetXaxis()->CenterTitle(); hist.GetYaxis()->CenterTitle(); hist.SetMinimum(-1026); hist.SetMaximum(1025); h = hist.DrawCopy("PL"); h->SetDirectory(0); } ostringstream str; str << "Event ID = " << fEventData->EventNum << " Trigger type = " << fEventData->TriggerType << " PC Time=" << fEventData->PCTime << " Board time = " << fEventData->BoardTime; h->SetTitle(str.str().c_str()); str.str(""); str << "ADC Pipeline (start=" << fEventData->StartPix << ")"; h->SetXTitle(str.str().c_str()); //str.str(""); //str << "Crate=" << crate << " Board=" << board << " Channel=" << channel << " [" << d.time() << "]" << endl; //hist->SetTitle(str.str().c_str()); const uint32_t p = fAdcChannel->value()+fAdcBoard->value()*36+fAdcCrate->value()*360; for (int i=0; iRoi; i++) h->SetBinContent(i+1, fEventData->Adc_Data[p*fEventData->Roi+i]*0.5); if (fAdcAutoScale->isChecked()) { h->SetMinimum(-1111); h->SetMaximum(-1111); } else { if (h->GetMinimumStored()==-1111) h->SetMinimum(-1026); if (h->GetMaximumStored()==-1111) h->SetMaximum(1025); } c->Modified(); c->Update(); #endif } void handleFadEventData(const DimData &d) { if (d.size()==0) return; if (fAdcStop->isChecked()) return; const DimEventData &dat = d.ref(); if (d.size()setToolTip("FADs or fadctrl seems to be offline."); fEvtBldWidget->setEnabled(false); SetLedColor(fStatusEventBuilderLed, kLedGray, d.time); return; } const uint8_t *ptr = d.ptr(); for (int i=0; i<40; i++) { const uint8_t stat1 = ptr[i]&3; const uint8_t stat2 = ptr[i]>>3; if (stat1==0 && stat2==0) { SetLedColor(fFadLED[i], kLedGray, d.time); continue; } if (stat1==2 && stat2==8) { SetLedColor(fFadLED[i], kLedGreen, d.time); continue; } if (stat1==1 && stat2==1) SetLedColor(fFadLED[i], kLedRed, d.time); else SetLedColor(fFadLED[i], kLedOrange, d.time); } const bool runs = ptr[40]!=0; fStatusEventBuilderLabel->setText(runs?"Running":"Not running"); fStatusEventBuilderLabel->setToolTip(runs?"Event builder thread running.":"Event builder thread stopped."); fEvtBldWidget->setEnabled(runs); SetLedColor(fStatusEventBuilderLed, runs?kLedGreen:kLedRed, d.time); // fFadConnections.assign(ptr, ptr+40); } template void handleFadToolTip(const Time &time, QWidget *w, T *ptr) { ostringstream tip; tip << ""; for (int b=0; b<10; b++) tip << ""; tip << ""; for (int c=0; c<4; c++) { tip << ""; for (int b=0; b<10; b++) tip << ""; tip << ""; } tip << "
" << time.GetAsStr() << " (UTC)
" << b << "
" << c << "" << ptr[c*10+b] << "
"; w->setToolTip(tip.str().c_str()); } template void handleFadMinMax(const DimData &d, QPushButton *led, S *wmin, S *wmax=0) { if (!CheckSize(d, 42*sizeof(T))) return; const T *ptr = d.ptr(); const T min = ptr[40]; const T max = ptr[41]; if (maxsetValue(0); else wmin->setValue(min); if (wmax) wmax->setValue(max); handleFadToolTip(d.time, led, ptr); } void handleFadFwVersion(const DimData &d) { handleFadMinMax(d, fFadLedFwVersion, fFadFwVersion); } void handleFadRunNumber(const DimData &d) { handleFadMinMax(d, fFadLedRunNumber, fFadRunNumber); } void handleFadDNA(const DimData &d) { if (!CheckSize(d, 40*sizeof(uint64_t))) return; const uint64_t *ptr = d.ptr(); ostringstream tip; tip << ""; tip << ""; for (int i=0; i<40; i++) { tip << dec; tip << ""; tip << ""; tip << ""; tip << hex; tip << ""; tip << ""; } tip << "
CrateBoardDNA
" << i/10 << ":" << i%10 << ":0x" << setfill('0') << setw(16) << ptr[i] << "
"; fFadDNA->setText(tip.str().c_str()); } void SetFadLed(QPushButton *led, const DimData &d, uint16_t bitmask, bool invert=false) { if (d.size()==0) { SetLedColor(led, kLedGray, d.time); return; } const bool quality = d.ptr()[0]&bitmask; const bool value = d.ptr()[1]&bitmask; const uint16_t *ptr = d.ptr()+2; SetLedColor(led, quality?kLedOrange:(value^invert?kLedGreen:kLedRed), d.time); ostringstream tip; tip << ""; for (int b=0; b<10; b++) tip << ""; tip << ""; /* tip << "" << hex; tip << ""; tip << ""; tip << ""; */ for (int c=0; c<4; c++) { tip << "" << hex; for (int b=0; b<10; b++) { tip << ""; } tip << ""; } tip << "
" << d.time.GetAsStr() << " (UTC)
" << b << "
" << d.ptr()[0] << " " << (d.ptr()[0]&bitmask) << "" << d.ptr()[1] << " " << (d.ptr()[1]&bitmask) << "
" << dec << c << "" << (ptr[c*10+b]&bitmask) << "
"; led->setToolTip(tip.str().c_str()); } void handleFadStatus(const DimData &d) { if (d.size()!=0 && !CheckSize(d, 42*sizeof(uint16_t))) return; SetFadLed(fFadLedDrsEnabled, d, FAD::EventHeader::kDenable); SetFadLed(fFadLedDrsWrite, d, FAD::EventHeader::kDwrite); SetFadLed(fFadLedDcmLocked, d, FAD::EventHeader::kDcmLocked); SetFadLed(fFadLedDcmReady, d, FAD::EventHeader::kDcmReady); SetFadLed(fFadLedSpiSclk, d, FAD::EventHeader::kSpiSclk); SetFadLed(fFadLedRefClockTooLow, d, FAD::EventHeader::kRefClkTooLow, true); SetFadLed(fFadLedBusy, d, FAD::EventHeader::kBusy); SetFadLed(fFadLedTriggerLine, d, FAD::EventHeader::kTriggerLine); SetFadLed(fFadLedContTrigger, d, FAD::EventHeader::kContTrigger); SetFadLed(fFadLedSocket, d, FAD::EventHeader::kSock17); SetFadLed(fFadLedPllLock, d, 0xf000); } void handleFadStatistics1(const DimData &d) { if (!CheckSize(d, sizeof(GUI_STAT))) return; const GUI_STAT &stat = d.ref(); /* //info about status of the main threads int32_t readStat ; //read thread int32_t procStat ; //processing thread(s) int32_t writStat ; //write thread //info about some rates int32_t deltaT ; //time in milli-seconds for rates int32_t readEvt ; //#events read int32_t procEvt ; //#events processed int32_t writEvt ; //#events written int32_t skipEvt ; //#events skipped //some info about current state of event buffer (snapspot) int32_t evtBuf; //#Events currently waiting in Buffer uint64_t totMem; //#Bytes available in Buffer uint64_t usdMem; //#Bytes currently used uint64_t maxMem; //max #Bytes used during past Second */ fFadBufferMax->setValue(stat.totMem/1000000); fFadBuffer->setMaximum(stat.totMem/100); fFadBuffer->setValue(stat.maxMem/100); cout << stat.totMem << " " << stat.maxMem << endl; /* fFadEvtWait->setValue(stat[1]); fFadEvtSkip->setValue(stat[2]); fFadEvtDel->setValue(stat[3]); fFadEvtTot->setValue(stat[4]); fFadEthernetRateTot->setValue(stat[6]/1024.); fFadEthernetRateAvg->setValue(stat[6]/1024./stat[7]); fFadEvtConn->setValue(stat[7]); */ } void handleFadStatistics2(const DimData &d) { if (!CheckSize(d, sizeof(EVT_STAT))) return; const EVT_STAT &stat = d.ref(); /* //some info about what happened since start of program (or last 'reset') uint32_t reset ; //#if increased, reset all counters uint32_t numRead[MAX_SOCK] ; //how often succesfull read from N sockets per loop uint64_t gotByte[NBOARDS] ; //#Bytes read per Board uint32_t gotErr[NBOARDS] ; //#Communication Errors per Board uint32_t evtGet; //#new Start of Events read uint32_t evtTot; //#complete Events read uint32_t evtErr; //#Events with Errors uint32_t evtSkp; //#Events incomplete (timeout) uint32_t procTot; //#Events processed uint32_t procErr; //#Events showed problem in processing uint32_t procTrg; //#Events accepted by SW trigger uint32_t procSkp; //#Events rejected by SW trigger uint32_t feedTot; //#Events used for feedBack system uint32_t feedErr; //#Events rejected by feedBack uint32_t wrtTot; //#Events written to disk uint32_t wrtErr; //#Events with write-error uint32_t runOpen; //#Runs opened uint32_t runClose; //#Runs closed uint32_t runErr; //#Runs with open/close errors //info about current connection status uint8_t numConn[NBOARDS] ; //#Sockets succesfully open per board */ } // ===================== FTM ============================================ double fTimeStamp1; void handleFtmTriggerCounter(const DimData &d) { if (!CheckSize(d, sizeof(FTM::DimTriggerCounter))) return; const FTM::DimTriggerCounter &sdata = d.ref(); fFtmTime->setText(QString::number(sdata.fTimeStamp/1000000., 'f', 6)+ " s"); fTriggerCounter->setText(QString::number(sdata.fTriggerCounter)); if (sdata.fTimeStamp>0) fTriggerCounterRate->setValue(1000000.*sdata.fTriggerCounter/sdata.fTimeStamp); else fTriggerCounterRate->setValue(0); // ---------------------------------------------- #ifdef HAVE_ROOT if (fTriggerCounter0<0) { fTriggerCounter0 = sdata.fTriggerCounter; fTimeStamp1 = sdata.fTimeStamp; return; } TCanvas *c = fFtmRateCanv->GetCanvas(); TH1 *h = (TH1*)c->FindObject("TimeFrame"); const double rate = sdata.fTriggerCounter-fTriggerCounter0; const double tdiff = sdata.fTimeStamp -fTimeStamp1; fTriggerCounter0 = sdata.fTriggerCounter; fTimeStamp1 = sdata.fTimeStamp; if (rate<0 && tdiff<=0) { fGraphFtmRate.Set(0); const double tm = Time().RootTime(); h->SetBins(1, tm, tm+60); h->GetXaxis()->SetTimeFormat("%M'%S\""); h->GetXaxis()->SetTitle("Time"); c->Modified(); c->Update(); return; } if (rate<0) return; // const double avgrate = sdata.fTimeStamp>0 ? double(sdata.fTriggerCounter)/sdata.fTimeStamp*1000000 : 1; const double t1 = h->GetXaxis()->GetXmax(); const double t0 = h->GetXaxis()->GetXmin(); h->SetBins(h->GetNbinsX()+1, t0, t0+sdata.fTimeStamp/1000000.+1); fGraphFtmRate.SetPoint(fGraphFtmRate.GetN(), t0+sdata.fTimeStamp/1000000., 1000000*rate/tdiff); if (t1-t0>60) { h->GetXaxis()->SetTimeFormat("%Hh%M'"); h->GetXaxis()->SetTitle("Time"); } h->SetMinimum(0); // h->SetMaximum(2*avgrate); c->Modified(); c->Update(); #endif // ---------------------------------------------- } void handleFtmCounter(const DimData &d) { if (!CheckSize(d, sizeof(uint32_t)*6)) return; const uint32_t *sdata = d.ptr(); fFtmCounterH->setValue(sdata[0]); fFtmCounterS->setValue(sdata[1]); fFtmCounterD->setValue(sdata[2]); fFtmCounterF->setValue(sdata[3]); fFtmCounterE->setValue(sdata[4]); fFtmCounterR->setValue(sdata[5]); } int64_t fTriggerCounter0; int64_t fTimeStamp0; void handleFtmDynamicData(const DimData &d) { if (!CheckSize(d, sizeof(FTM::DimDynamicData))) return; const FTM::DimDynamicData &sdata = d.ref(); fOnTime->setText(QString::number(sdata.fOnTimeCounter/1000000., 'f', 6)+" s"); if (sdata.fTimeStamp>0) fOnTimeRel->setValue(100.*sdata.fOnTimeCounter/sdata.fTimeStamp); else fOnTimeRel->setValue(0); fFtmTemp0->setValue(sdata.fTempSensor[0]*0.1); fFtmTemp1->setValue(sdata.fTempSensor[1]*0.1); fFtmTemp2->setValue(sdata.fTempSensor[2]*0.1); fFtmTemp3->setValue(sdata.fTempSensor[3]*0.1); #ifdef HAVE_ROOT // ---------------------------------------------- if (fTimeStamp0<0) { fTimeStamp0 = sdata.fTimeStamp; return; } TCanvas *c = fFtmRateCanv->GetCanvas(); TH1 *h = (TH1*)c->FindObject("TimeFrame"); const double tdiff = sdata.fTimeStamp-fTimeStamp0; fTimeStamp0 = sdata.fTimeStamp; if (tdiff<0) { for (int i=0; i<160; i++) fGraphPatchRate[i].Set(0); for (int i=0; i<40; i++) fGraphBoardRate[i].Set(0); return; } //const double t1 = h->GetXaxis()->GetXmax(); const double t0 = h->GetXaxis()->GetXmin(); for (int i=0; i<160; i++) fGraphPatchRate[i].SetPoint(fGraphPatchRate[i].GetN(), t0+sdata.fTimeStamp/1000000., float(sdata.fRatePatch[i])*2/fFtmStaticData.fPrescaling[i]); for (int i=0; i<40; i++) fGraphBoardRate[i].SetPoint(fGraphBoardRate[i].GetN(), t0+sdata.fTimeStamp/1000000., float(sdata.fRateBoard[i])*2/fFtmStaticData.fPrescaling[i]); c->Modified(); c->Update(); //fGraphFtmRate.ComputeRange(x[0], x[1], x[2], x[3]); // ---------------------------------------------- if (fThresholdIdx->value()>=0) { const int isw = fThresholdIdx->value(); const int ihw = fPatchMapHW[isw]; fPatchRate->setValue(sdata.fRatePatch[ihw]); } valarray dat(0., 1440); // fPatch converts from software id to software patch id for (int i=0; i<1440; i++) { const int ihw = fPatchHW[i]; // const int isw = fPatch[i]; // const int ihw = fPatchMapHW[isw]; dat[i] = sdata.fRatePatch[ihw]; } c = fRatesCanv->GetCanvas(); Camera *cam = (Camera*)c->FindObject("Camera"); cam->SetData(dat); c->Modified(); c->Update(); // ---------------------------------------------- #endif } void DisplayRates() { #ifdef HAVE_ROOT TCanvas *c = fFtmRateCanv->GetCanvas(); while (c->FindObject("PatchRate")) c->GetListOfPrimitives()->Remove(c->FindObject("PatchRate")); while (c->FindObject("BoardRate")) c->GetListOfPrimitives()->Remove(c->FindObject("BoardRate")); c->cd(); if (fRatePatch1->value()>=0) { fGraphPatchRate[fRatePatch1->value()].SetLineColor(kRed); fGraphPatchRate[fRatePatch1->value()].SetMarkerColor(kRed); fGraphPatchRate[fRatePatch1->value()].Draw("PL"); } if (fRatePatch2->value()>=0) { fGraphPatchRate[fRatePatch2->value()].SetLineColor(kGreen); fGraphPatchRate[fRatePatch2->value()].SetMarkerColor(kGreen); fGraphPatchRate[fRatePatch2->value()].Draw("PL"); } if (fRateBoard1->value()>=0) { fGraphBoardRate[fRateBoard1->value()].SetLineColor(kMagenta); fGraphBoardRate[fRateBoard1->value()].SetMarkerColor(kMagenta); fGraphBoardRate[fRateBoard1->value()].Draw("PL"); } if (fRateBoard2->value()>=0) { fGraphBoardRate[fRateBoard2->value()].SetLineColor(kCyan); fGraphBoardRate[fRateBoard2->value()].SetMarkerColor(kCyan); fGraphBoardRate[fRateBoard2->value()].Draw("PL"); } #endif } void on_fRatePatch1_valueChanged(int) { DisplayRates(); } void on_fRatePatch2_valueChanged(int) { DisplayRates(); } void on_fRateBoard1_valueChanged(int) { DisplayRates(); } void on_fRateBoard2_valueChanged(int) { DisplayRates(); } FTM::DimStaticData fFtmStaticData; void SetFtuLed(int idx, int counter, const Time &t) { if (counter==0 || counter>3) counter = 3; if (counter<0) counter = 0; const LedColor_t col[4] = { kLedGray, kLedGreen, kLedOrange, kLedRed }; SetLedColor(fFtuLED[idx], col[counter], t); fFtuStatus[idx] = counter; } void SetFtuStatusLed(const Time &t) { const int max = fFtuStatus.max(); switch (max) { case 0: SetLedColor(fStatusFTULed, kLedGray, t); fStatusFTULabel->setText("All disabled"); fStatusFTULabel->setToolTip("All FTUs are disabled"); break; case 1: SetLedColor(fStatusFTULed, kLedGreen, t); fStatusFTULabel->setToolTip("Communication with FTU is smooth."); fStatusFTULabel->setText("ok"); break; case 2: SetLedColor(fStatusFTULed, kLedOrange, t); fStatusFTULabel->setText("Warning"); fStatusFTULabel->setToolTip("At least one FTU didn't answer immediately"); break; case 3: SetLedColor(fStatusFTULed, kLedRed, t); fStatusFTULabel->setToolTip("At least one FTU didn't answer!"); fStatusFTULabel->setText("ERROR"); break; } const int cnt = count(&fFtuStatus[0], &fFtuStatus[40], 0); fFtuAllOn->setEnabled(cnt!=0); fFtuAllOff->setEnabled(cnt!=40); } void handleFtmStaticData(const DimData &d) { if (!CheckSize(d, sizeof(FTM::DimStaticData))) return; const FTM::DimStaticData &sdata = d.ref(); fTriggerInterval->setValue(sdata.fTriggerInterval); fPhysicsCoincidence->setValue(sdata.fMultiplicityPhysics); fCalibCoincidence->setValue(sdata.fMultiplicityCalib); fPhysicsWindow->setValue(sdata.fWindowPhysics); fCalibWindow->setValue(sdata.fWindowCalib); fTriggerDelay->setValue(sdata.fDelayTrigger); fTimeMarkerDelay->setValue(sdata.fDelayTimeMarker); fDeadTime->setValue(sdata.fDeadTime); fClockCondR0->setValue(sdata.fClockConditioner[0]); fClockCondR1->setValue(sdata.fClockConditioner[1]); fClockCondR8->setValue(sdata.fClockConditioner[2]); fClockCondR9->setValue(sdata.fClockConditioner[3]); fClockCondR11->setValue(sdata.fClockConditioner[4]); fClockCondR13->setValue(sdata.fClockConditioner[5]); fClockCondR14->setValue(sdata.fClockConditioner[6]); fClockCondR15->setValue(sdata.fClockConditioner[7]); const uint32_t R0 = sdata.fClockConditioner[0]; const uint32_t R14 = sdata.fClockConditioner[6]; const uint32_t R15 = sdata.fClockConditioner[7]; const uint32_t Ndiv = (R15&0x1ffff00)<<2; const uint32_t Rdiv = (R14&0x007ff00)>>8; const uint32_t Cdiv = (R0 &0x000ff00)>>8; double freq = 40.*Ndiv/(Rdiv*Cdiv); fClockCondFreqRes->setValue(freq); //fClockCondFreq->setEditText(""); fClockCondFreq->setCurrentIndex(0); fTriggerSeqPed->setValue(sdata.fTriggerSeqPed); fTriggerSeqLPint->setValue(sdata.fTriggerSeqLPint); fTriggerSeqLPext->setValue(sdata.fTriggerSeqLPext); fEnableTrigger->setChecked(sdata.HasTrigger()); fEnableVeto->setChecked(sdata.HasVeto()); fEnableExt1->setChecked(sdata.HasExt1()); fEnableExt2->setChecked(sdata.HasExt2()); fEnableClockCond->setChecked(sdata.HasClockConditioner()); for (int i=0; i<40; i++) { if (!sdata.IsActive(i)) SetFtuLed(i, -1, d.time); else { if (fFtuStatus[i]==0) SetFtuLed(i, 1, d.time); } fFtuLED[i]->setChecked(false); } SetFtuStatusLed(d.time); #ifdef HAVE_ROOT Camera *cam = (Camera*)fRatesCanv->GetCanvas()->FindObject("Camera"); for (int isw=0; isw<1440; isw++) { const int ihw = fPixelMapHW[isw]; cam->SetEnable(isw, sdata.IsEnabled(ihw)); } fRatesCanv->GetCanvas()->Modified(); fRatesCanv->GetCanvas()->Update(); #endif { const int isw = fPixelIdx->value(); const int ihw = fPixelMapHW[isw]; const bool on = sdata.IsEnabled(ihw); fPixelEnable->setChecked(on); } if (fThresholdIdx->value()>=0) { const int isw = fThresholdIdx->value(); const int ihw = fPatchMapHW[isw]; fThresholdVal->setValue(sdata.fThreshold[ihw]); } fPrescalingVal->setValue(sdata.fPrescaling[0]); fFtmStaticData = sdata; } void handleFtmPassport(const DimData &d) { if (!CheckSize(d, sizeof(FTM::DimPassport))) return; const FTM::DimPassport &sdata = d.ref(); stringstream str1, str2; str1 << hex << "0x" << setfill('0') << setw(16) << sdata.fBoardId; str2 << sdata.fFirmwareId; fFtmBoardId->setText(str1.str().c_str()); fFtmFirmwareId->setText(str2.str().c_str()); } void handleFtmFtuList(const DimData &d) { if (!CheckSize(d, sizeof(FTM::DimFtuList))) return; fFtuPing->setChecked(false); const FTM::DimFtuList &sdata = d.ref(); stringstream str; str << "" << setfill('0'); str << ""; for (int i=0; i<40; i++) { str << ""; str << ""; str << ""; str << ""; str << ""; str << ""; str << ""; } str << "
NumAddrDNA
" << dec << i << hex << ":0x" << setw(2) << (int)sdata.fAddr[i] << ":0x" << setw(16) << sdata.fDNA[i] << "
"; fFtuDNA->setText(str.str().c_str()); fFtuAnswersTotal->setValue(sdata.fNumBoards); fFtuAnswersCrate0->setValue(sdata.fNumBoardsCrate[0]); fFtuAnswersCrate1->setValue(sdata.fNumBoardsCrate[1]); fFtuAnswersCrate2->setValue(sdata.fNumBoardsCrate[2]); fFtuAnswersCrate3->setValue(sdata.fNumBoardsCrate[3]); for (int i=0; i<40; i++) SetFtuLed(i, sdata.IsActive(i) ? sdata.fPing[i] : -1, d.time); SetFtuStatusLed(d.time); } void handleFtmError(const DimData &d) { if (!CheckSize(d, sizeof(FTM::DimError))) return; const FTM::DimError &sdata = d.ref(); SetFtuLed(sdata.fError.fDestAddress, sdata.fError.fNumCalls, d.time); SetFtuStatusLed(d.time); // FIXME: Write to special window! //Out() << "Error:" << endl; //Out() << sdata.fError << endl; } // ====================== MessageImp ==================================== bool fChatOnline; void handleStateChanged(const Time &time, const std::string &server, const State &s) { // FIXME: Prefix tooltip with time if (server=="FTM_CONTROL") { // FIXME: Enable FTU page!!! fStatusFTMLabel->setText(s.name.c_str()); fStatusFTMLabel->setToolTip(s.comment.c_str()); bool enable = false; if (s.indexsetEnabled(enable); fFtuWidget->setEnabled(enable); fRatesWidget->setEnabled(enable); if (s.index>=FTM::kConnected) SetFtuStatusLed(time); else { SetLedColor(fStatusFTULed, kLedGray, time); fStatusFTULabel->setText("Offline"); fStatusFTULabel->setToolTip("FTM is not online."); } } if (server=="FAD_CONTROL") { fStatusFADLabel->setText(s.name.c_str()); fStatusFADLabel->setToolTip(s.comment.c_str()); bool enable = false; if (s.indexsetText("Offline"); fStatusEventBuilderLabel->setToolTip("No connection to fadctrl."); fEvtBldWidget->setEnabled(false); SetLedColor(fStatusEventBuilderLed, kLedGray, time); */ } if (s.index==FAD::kOffline) // Dim connection / FTM disconnected SetLedColor(fStatusFADLed, kLedRed, time); if (s.index==FAD::kDisconnected) // Dim connection / FTM disconnected SetLedColor(fStatusFADLed, kLedOrange, time); if (s.index==FAD::kConnecting) // Dim connection / FTM disconnected { SetLedColor(fStatusFADLed, kLedYellow, time); // FIXME FIXME FIXME: The LEDs are not displayed when disabled! enable = true; } if (s.index>=FAD::kConnected) // Dim connection / FTM connected { SetLedColor(fStatusFADLed, kLedGreen, time); enable = true; } fFadWidget->setEnabled(enable); } if (server=="FSC_CONTROL") { fStatusFSCLabel->setText(s.name.c_str()); fStatusFSCLabel->setToolTip(s.comment.c_str()); bool enable = false; if (s.index<1) // No Dim connection SetLedColor(fStatusFSCLed, kLedGray, time); if (s.index==1) // Dim connection / FTM disconnected SetLedColor(fStatusFSCLed, kLedRed, time); if (s.index>=2) // Dim connection / FTM disconnected { SetLedColor(fStatusFSCLed, kLedGreen, time); enable = true; } //fFscWidget->setEnabled(enable); } if (server=="DATA_LOGGER") { fStatusLoggerLabel->setText(s.name.c_str()); fStatusLoggerLabel->setToolTip(s.comment.c_str()); bool enable = true; if (s.index<=30) // Ready/Waiting SetLedColor(fStatusLoggerLed, kLedYellow, time); if (s.index<-1) // Offline { SetLedColor(fStatusLoggerLed, kLedGray, time); enable = false; } if (s.index>=0x100) // Error SetLedColor(fStatusLoggerLed, kLedRed, time); if (s.index==40) // Logging SetLedColor(fStatusLoggerLed, kLedGreen, time); fLoggerWidget->setEnabled(enable); } if (server=="CHAT") { fStatusChatLabel->setText(s.name.c_str()); fChatOnline = s.index==0; SetLedColor(fStatusChatLed, fChatOnline ? kLedGreen : kLedGray, time); fChatSend->setEnabled(fChatOnline); fChatMessage->setEnabled(fChatOnline); } if (server=="SCHEDULER") { fStatusSchedulerLabel->setText(s.name.c_str()); SetLedColor(fStatusSchedulerLed, s.index>=0 ? kLedGreen : kLedRed, time); } } void on_fTabWidget_currentChanged(int which) { if (fTabWidget->tabText(which)=="Chat") fTabWidget->setTabIcon(which, QIcon()); } void handleWrite(const Time &time, const string &text, int qos) { stringstream out; if (text.substr(0, 6)=="CHAT: ") { if (qos==MessageImp::kDebug) return; out << "["; out << Time::fmt("%H:%M:%S") << time << "] "; out << text.substr(6); fChatText->append(out.str().c_str()); if (fTabWidget->tabText(fTabWidget->currentIndex())=="Chat") return; static int num = 0; if (num++<2) return; for (int i=0; icount(); i++) if (fTabWidget->tabText(i)=="Chat") { fTabWidget->setTabIcon(i, QIcon(":/Resources/icons/warning 3.png")); break; } return; } out << "" << time.GetAsStr() << " - " << text << ""; fLogText->append(out.str().c_str()); if (qos>=kWarn) fTextEdit->append(out.str().c_str()); } void IndicateStateChange(const Time &time, const std::string &server) { const State s = GetState(server, GetCurrentState(server)); QApplication::postEvent(this, new FunctionEvent(boost::bind(&FactGui::handleStateChanged, this, time, server, s))); } int Write(const Time &time, const string &txt, int qos) { QApplication::postEvent(this, new FunctionEvent(boost::bind(&FactGui::handleWrite, this, time, txt, qos))); return 0; } // ====================== Dim infoHandler================================ void handleDimService(const string &txt) { fDimSvcText->append(txt.c_str()); } void infoHandlerService(DimInfo &info) { const string fmt = string(info.getFormat()).empty() ? "C" : info.getFormat(); stringstream dummy; const Converter conv(dummy, fmt, false); const Time tm(info.getTimestamp(), info.getTimestampMillisecs()*1000); stringstream out; out << "[" << Time::fmt("%H:%M:%S.%f") << tm << "] " << info.getName() << " - "; bool iserr = true; if (!conv) { out << "Compilation of format string '" << fmt << "' failed!"; } else { try { const string dat = conv.GetString(info.getData(), info.getSize()); out << dat; iserr = false; } catch (const runtime_error &e) { out << "Conversion to string failed!
" << e.what() << "
"; } } // srand(hash()(string(info.getName()))); // int bg = rand()&0xffffff; int bg = hash()(string(info.getName())); // allow only light colors bg = ~(bg&0x1f1f1f)&0xffffff; if (iserr) bg = 0xffffff; stringstream bgcol; bgcol << hex << setfill('0') << setw(6) << bg; const string col = iserr ? "red" : "black"; const string str = "
"+out.str()+"
"; QApplication::postEvent(this, new FunctionEvent(boost::bind(&FactGui::handleDimService, this, str))); } void CallInfoHandler(void (FactGui::*handler)(const DimData&), const DimData &d) { fInHandler = true; (this->*handler)(d); fInHandler = false; } /* void CallInfoHandler(const boost::function &func) { // This ensures that newly received values are not sent back to the emitter // because changing the value emits the valueChanged signal (or similar) fInHandler = true; func(); fInHandler = false; }*/ void PostInfoHandler(void (FactGui::*handler)(const DimData&)) { //const boost::function f = boost::bind(handler, this, DimData(getInfo())); FunctionEvent *evt = new FunctionEvent(boost::bind(&FactGui::CallInfoHandler, this, handler, DimData(getInfo()))); // FunctionEvent *evt = new FunctionEvent(boost::bind(&FactGui::CallInfoHandler, this, f)); // FunctionEvent *evt = new FunctionEvent(boost::bind(handler, this, DimData(getInfo())))); QApplication::postEvent(this, evt); } void infoHandler() { // Initialize the time-stamp (what a weird workaround...) if (getInfo()) getInfo()->getTimestamp(); if (getInfo()==&fDimDNS) return PostInfoHandler(&FactGui::handleDimDNS); #ifdef DEBUG_DIM cout << "HandleDimInfo " << getInfo()->getName() << endl; #endif if (getInfo()==&fDimLoggerStats) return PostInfoHandler(&FactGui::handleLoggerStats); // if (getInfo()==&fDimFadFiles) // return PostInfoHandler(&FactGui::handleFadFiles); if (getInfo()==&fDimFadConnections) return PostInfoHandler(&FactGui::handleFadConnections); if (getInfo()==&fDimFadFwVersion) return PostInfoHandler(&FactGui::handleFadFwVersion); if (getInfo()==&fDimFadRunNumber) return PostInfoHandler(&FactGui::handleFadRunNumber); if (getInfo()==&fDimFadDNA) return PostInfoHandler(&FactGui::handleFadDNA); if (getInfo()==&fDimFadTemperature) return PostInfoHandler(&FactGui::handleFadTemperature); if (getInfo()==&fDimFadRefClock) return PostInfoHandler(&FactGui::handleFadRefClock); if (getInfo()==&fDimFadStatus) return PostInfoHandler(&FactGui::handleFadStatus); if (getInfo()==&fDimFadStatistics1) return PostInfoHandler(&FactGui::handleFadStatistics1); if (getInfo()==&fDimFadStatistics2) return PostInfoHandler(&FactGui::handleFadStatistics2); if (getInfo()==&fDimFadEvents) return PostInfoHandler(&FactGui::handleFadEvents); if (getInfo()==&fDimFadRuns) return PostInfoHandler(&FactGui::handleFadRuns); if (getInfo()==&fDimFadEventData) return PostInfoHandler(&FactGui::handleFadEventData); /* if (getInfo()==&fDimFadSetup) return PostInfoHandler(&FactGui::handleFadSetup); */ if (getInfo()==&fDimLoggerFilenameNight) return PostInfoHandler(&FactGui::handleLoggerFilenameNight); if (getInfo()==&fDimLoggerNumSubs) return PostInfoHandler(&FactGui::handleLoggerNumSubs); if (getInfo()==&fDimLoggerFilenameRun) return PostInfoHandler(&FactGui::handleLoggerFilenameRun); if (getInfo()==&fDimFtmTriggerCounter) return PostInfoHandler(&FactGui::handleFtmTriggerCounter); if (getInfo()==&fDimFtmCounter) return PostInfoHandler(&FactGui::handleFtmCounter); if (getInfo()==&fDimFtmDynamicData) return PostInfoHandler(&FactGui::handleFtmDynamicData); if (getInfo()==&fDimFtmPassport) return PostInfoHandler(&FactGui::handleFtmPassport); if (getInfo()==&fDimFtmFtuList) return PostInfoHandler(&FactGui::handleFtmFtuList); if (getInfo()==&fDimFtmStaticData) return PostInfoHandler(&FactGui::handleFtmStaticData); if (getInfo()==&fDimFtmError) return PostInfoHandler(&FactGui::handleFtmError); // if (getInfo()==&fDimFadFiles) // return PostInfoHandler(&FactGui::handleFadFiles); for (map::iterator i=fServices.begin(); i!=fServices.end(); i++) if (i->second==getInfo()) { infoHandlerService(*i->second); return; } DimNetwork::infoHandler(); } // ====================================================================== bool event(QEvent *evt) { if (dynamic_cast(evt)) return static_cast(evt)->Exec(); if (dynamic_cast(evt)) { const QStandardItem &item = static_cast(evt)->item; const QStandardItem *par = item.parent(); if (par) { const QString server = par->text(); const QString service = item.text(); const string s = (server+'/'+service).toStdString(); if (item.checkState()==Qt::Checked) SubscribeService(s); else UnsubscribeService(s); } } return MainWindow::event(evt); // unrecognized } void on_fDimCmdSend_clicked() { const QString server = fDimCmdServers->currentIndex().data().toString(); const QString command = fDimCmdCommands->currentIndex().data().toString(); const QString arguments = fDimCmdLineEdit->displayText(); // FIXME: Sending a command exactly when the info Handler changes // the list it might lead to confusion. try { SendDimCommand(server.toStdString(), command.toStdString()+" "+arguments.toStdString()); fTextEdit->append("Command '"+server+'/'+command+"' successfully emitted."); fDimCmdLineEdit->clear(); } catch (const runtime_error &e) { stringstream txt; txt << e.what(); string buffer; while (getline(txt, buffer, '\n')) fTextEdit->append(("
"+buffer+"
").c_str()); } } #ifdef HAVE_ROOT void slot_RootEventProcessed(TObject *obj, unsigned int evt, TCanvas *canv) { // kMousePressEvent // TCanvas processed QEvent mousePressEvent // kMouseMoveEvent // TCanvas processed QEvent mouseMoveEvent // kMouseReleaseEvent // TCanvas processed QEvent mouseReleaseEvent // kMouseDoubleClickEvent // TCanvas processed QEvent mouseDoubleClickEvent // kKeyPressEvent // TCanvas processed QEvent keyPressEvent // kEnterEvent // TCanvas processed QEvent enterEvent // kLeaveEvent // TCanvas processed QEvent leaveEvent if (dynamic_cast(obj)) return; TQtWidget *tipped = static_cast(sender()); if (evt==11/*kMouseReleaseEvent*/) { if (dynamic_cast(obj)) { const float xx = canv->AbsPixeltoX(tipped->GetEventX()); const float yy = canv->AbsPixeltoY(tipped->GetEventY()); Camera *cam = static_cast(obj); const int isw = cam->GetIdx(xx, yy); fPixelIdx->setValue(isw); ChoosePixel(*cam, isw); } return; } if (evt==61/*kMouseDoubleClickEvent*/) { if (dynamic_cast(obj)) { const float xx = canv->AbsPixeltoX(tipped->GetEventX()); const float yy = canv->AbsPixeltoY(tipped->GetEventY()); Camera *cam = static_cast(obj); const int isw = cam->GetIdx(xx, yy); ChoosePixel(*cam, isw); fPixelIdx->setValue(isw); const uint16_t ihw = fPixelMapHW[isw]; Dim::SendCommand("FTM_CONTROL/TOGGLE_PIXEL", ihw); } if (dynamic_cast(obj)) static_cast(obj)->UnZoom(); return; } // Find the object which will get picked by the GetObjectInfo // due to buffer overflows in many root-versions // in TH1 and TProfile we have to work around and implement // our own GetObjectInfo which make everything a bit more // complicated. canv->cd(); #if ROOT_VERSION_CODE > ROOT_VERSION(5,22,00) const char *objectInfo = obj->GetObjectInfo(tipped->GetEventX(),tipped->GetEventY()); #else const char *objectInfo = dynamic_cast(obj) ? "" : obj->GetObjectInfo(tipped->GetEventX(),tipped->GetEventY()); #endif QString tipText; tipText += obj->GetName(); tipText += " ["; tipText += obj->ClassName(); tipText += "]: "; tipText += objectInfo; if (dynamic_cast(obj)) { const float xx = canv->AbsPixeltoX(tipped->GetEventX()); const float yy = canv->AbsPixeltoY(tipped->GetEventY()); Camera *cam = static_cast(obj); const int isw = cam->GetIdx(xx, yy); const int ihw = fPixelMapHW[isw]; const int idx = fPatchHW[isw]; int ii = 0; for (; ii<160; ii++) if (idx==fPatchMapHW[ii]) break; const int patch = ihw%4; const int board = (ihw/4)%10; const int crate = (ihw/4)/10; ostringstream str; str << " (hw=" << ihw << ") Patch=" << ii << " (hw=" << fPatchMapHW[idx] << "; Crate=" << crate << " Board=" << board << " Patch=" << patch << ")"; tipText += str.str().c_str(); } fStatusBar->showMessage(tipText, 3000); gSystem->ProcessEvents(); //QWhatsThis::display(tipText) } void slot_RootUpdate() { gSystem->ProcessEvents(); QTimer::singleShot(0, this, SLOT(slot_RootUpdate())); } void ChoosePatch(Camera &cam, int isw) { cam.Reset(); fThresholdIdx->setValue(isw); const int ihw = isw<0 ? 0 : fPatchMapHW[isw]; fPatchRate->setEnabled(isw>=0); fThresholdCrate->setEnabled(isw>=0); fThresholdBoard->setEnabled(isw>=0); fThresholdPatch->setEnabled(isw>=0); if (isw<0) return; const int patch = ihw%4; const int board = (ihw/4)%10; const int crate = (ihw/4)/10; fInChoosePatch = true; fThresholdCrate->setValue(crate); fThresholdBoard->setValue(board); fThresholdPatch->setValue(patch); fInChoosePatch = false; fThresholdVal->setValue(fFtmStaticData.fThreshold[ihw]); fPatchRate->setValue(cam.GetData(isw)); // Loop over the software idx of all pixels for (unsigned int i=0; i<1440; i++) if (fPatchHW[i]==ihw) cam.SetBold(i); } void ChoosePixel(Camera &cam, int isw) { const int ihw = fPixelMapHW[isw]; int ii = 0; for (; ii<160; ii++) if (fPatchHW[isw]==fPatchMapHW[ii]) break; cam.SetWhite(isw); ChoosePatch(cam, ii); const bool on = fFtmStaticData.IsEnabled(ihw); fPixelEnable->setChecked(on); } void UpdatePatch(int isw) { Camera *cam = (Camera*)fRatesCanv->GetCanvas()->FindObject("Camera"); ChoosePatch(*cam, isw); } void on_fThresholdIdx_valueChanged(int isw) { UpdatePatch(isw); fRatesCanv->GetCanvas()->Modified(); fRatesCanv->GetCanvas()->Update(); } void UpdateThresholdIdx() { if (fInChoosePatch) return; const int crate = fThresholdCrate->value(); const int board = fThresholdBoard->value(); const int patch = fThresholdPatch->value(); const int ihw = patch + board*4 + crate*40; int isw = 0; for (; isw<160; isw++) if (ihw==fPatchMapHW[isw]) break; UpdatePatch(isw); } void on_fThresholdPatch_valueChanged(int) { UpdateThresholdIdx(); } void on_fThresholdBoard_valueChanged(int) { UpdateThresholdIdx(); } void on_fThresholdCrate_valueChanged(int) { UpdateThresholdIdx(); } void on_fPixelIdx_valueChanged(int isw) { Camera *cam = (Camera*)fRatesCanv->GetCanvas()->FindObject("Camera"); ChoosePixel(*cam, isw); fRatesCanv->GetCanvas()->Modified(); fRatesCanv->GetCanvas()->Update(); } #endif void on_fPixelEnable_stateChanged(int b) { if (fInHandler) return; const uint16_t isw = fPixelIdx->value(); const uint16_t ihw = fPixelMapHW[isw]; Dim::SendCommand(b==Qt::Unchecked ? "FTM_CONTROL/DISABLE_PIXEL" : "FTM_CONTROL/ENABLE_PIXEL", ihw); } void on_fPixelDisableOthers_clicked() { const uint16_t isw = fPixelIdx->value(); const uint16_t ihw = fPixelMapHW[isw]; Dim::SendCommand("FTM_CONTROL/DISABLE_ALL_PIXELS_EXCEPT", ihw); } void on_fThresholdDisableOthers_clicked() { const uint16_t isw = fThresholdIdx->value(); const uint16_t ihw = fPatchMapHW[isw]; Dim::SendCommand("FTM_CONTROL/DISABLE_ALL_PATCHES_EXCEPT", ihw); } void on_fThresholdVal_valueChanged(int v) { fThresholdVolt->setValue(2500./4095*v); const int32_t isw = fThresholdIdx->value(); const int32_t ihw = fPatchMapHW[isw]; const int32_t d[2] = { ihw, v }; if (!fInHandler) Dim::SendCommand("FTM_CONTROL/SET_THRESHOLD", d); } TGraph fGraphFtmTemp[4]; TGraph fGraphFtmRate; TGraph fGraphPatchRate[160]; TGraph fGraphBoardRate[40]; #ifdef HAVE_ROOT TH1 *DrawTimeFrame(const char *ytitle) { const double tm = Time().RootTime(); TH1F h("TimeFrame", "", 1, tm, tm+60);//Time().RootTime()-1./24/60/60, Time().RootTime()); h.SetDirectory(0); // h.SetBit(TH1::kCanRebin); h.SetStats(kFALSE); // h.SetMinimum(0); // h.SetMaximum(1); h.SetXTitle("Time"); h.SetYTitle(ytitle); h.GetXaxis()->CenterTitle(); h.GetYaxis()->CenterTitle(); h.GetXaxis()->SetTimeDisplay(true); h.GetXaxis()->SetTimeFormat("%Mh%S'"); h.GetXaxis()->SetLabelSize(0.025); h.GetYaxis()->SetLabelSize(0.025); h.GetYaxis()->SetTitleOffset(1.2); // h.GetYaxis()->SetTitleSize(1.2); TH1 *cpy = h.DrawCopy(); cpy->SetDirectory(0); return cpy; } #endif public: FactGui() : fFtuStatus(40), fPixelMapHW(1440), fPatchMapHW(160), fPatchHW(1440), fInChoosePatch(false), fDimDNS("DIS_DNS/VERSION_NUMBER", 1, int(0), this), //- fDimLoggerStats ("DATA_LOGGER/STATS", (void*)NULL, 0, this), fDimLoggerFilenameNight("DATA_LOGGER/FILENAME_NIGHTLY", (void*)NULL, 0, this), fDimLoggerFilenameRun ("DATA_LOGGER/FILENAME_RUN", (void*)NULL, 0, this), fDimLoggerNumSubs ("DATA_LOGGER/NUM_SUBS", (void*)NULL, 0, this), //- fDimFtmPassport ("FTM_CONTROL/PASSPORT", (void*)NULL, 0, this), fDimFtmTriggerCounter ("FTM_CONTROL/TRIGGER_COUNTER", (void*)NULL, 0, this), fDimFtmError ("FTM_CONTROL/ERROR", (void*)NULL, 0, this), fDimFtmFtuList ("FTM_CONTROL/FTU_LIST", (void*)NULL, 0, this), fDimFtmStaticData ("FTM_CONTROL/STATIC_DATA", (void*)NULL, 0, this), fDimFtmDynamicData ("FTM_CONTROL/DYNAMIC_DATA", (void*)NULL, 0, this), fDimFtmCounter ("FTM_CONTROL/COUNTER", (void*)NULL, 0, this), //- fDimFadRuns ("FAD_CONTROL/RUNS", (void*)NULL, 0, this), fDimFadEvents ("FAD_CONTROL/EVENTS", (void*)NULL, 0, this), fDimFadEventData ("FAD_CONTROL/EVENT_DATA", (void*)NULL, 0, this), fDimFadConnections ("FAD_CONTROL/CONNECTIONS", (void*)NULL, 0, this), fDimFadFwVersion ("FAD_CONTROL/FIRMWARE_VERSION", (void*)NULL, 0, this), fDimFadRunNumber ("FAD_CONTROL/RUN_NUMBER", (void*)NULL, 0, this), fDimFadDNA ("FAD_CONTROL/DNA", (void*)NULL, 0, this), fDimFadTemperature ("FAD_CONTROL/TEMPERATURE", (void*)NULL, 0, this), fDimFadRefClock ("FAD_CONTROL/REFERENCE_CLOCK", (void*)NULL, 0, this), fDimFadStatus ("FAD_CONTROL/STATUS", (void*)NULL, 0, this), fDimFadStatistics1 ("FAD_CONTROL/STATISTICS1", (void*)NULL, 0, this), fDimFadStatistics2 ("FAD_CONTROL/STATISTICS2", (void*)NULL, 0, this), //- fEventData(0) { fClockCondFreq->addItem("--- Hz", QVariant(-1)); fClockCondFreq->addItem("800 MHz", QVariant(800)); fClockCondFreq->addItem("1 GHz", QVariant(1000)); fClockCondFreq->addItem("2 GHz", QVariant(2000)); fClockCondFreq->addItem("3 GHz", QVariant(3000)); fClockCondFreq->addItem("4 GHz", QVariant(4000)); fClockCondFreq->addItem("5 GHz", QVariant(5000)); fTriggerWidget->setEnabled(false); fFtuWidget->setEnabled(false); fRatesWidget->setEnabled(false); fFadWidget->setEnabled(false); fEvtBldWidget->setEnabled(false); fLoggerWidget->setEnabled(false); fChatSend->setEnabled(false); fChatMessage->setEnabled(false); DimClient::sendCommand("CHAT/MSG", "GUI online."); // + MessageDimRX // -------------------------------------------------------------------------- ifstream fin1("Trigger-Patches.txt"); int l = 0; string buf; while (getline(fin1, buf, '\n')) { buf = Tools::Trim(buf); if (buf[0]=='#') continue; stringstream str(buf); for (int i=0; i<9; i++) { unsigned int n; str >> n; if (n>=fPatchHW.size()) continue; fPatchHW[n] = l; } l++; } if (l!=160) cerr << "WARNING - Problems reading Trigger-Patches.txt" << endl; // -------------------------------------------------------------------------- ifstream fin2("MasterList-v3.txt"); l = 0; while (getline(fin2, buf, '\n')) { buf = Tools::Trim(buf); if (buf[0]=='#') continue; unsigned int softid, hardid, dummy; stringstream str(buf); str >> softid; str >> dummy; str >> hardid; if (softid>=fPixelMapHW.size()) continue; fPixelMapHW[softid] = hardid; l++; } if (l!=1440) cerr << "WARNING - Problems reading MasterList-v3.txt" << endl; // -------------------------------------------------------------------------- ifstream fin3("PatchList.txt"); l = 0; while (getline(fin3, buf, '\n')) { buf = Tools::Trim(buf); if (buf[0]=='#') continue; unsigned int softid, hardid; stringstream str(buf); str >> softid; str >> hardid; if (softid>=fPatchMapHW.size()) continue; fPatchMapHW[softid] = hardid-1; l++; } if (l!=160) cerr << "WARNING - Problems reading PatchList.txt" << endl; // -------------------------------------------------------------------------- #ifdef HAVE_ROOT fGraphFtmRate.SetLineColor(kBlue); fGraphFtmRate.SetMarkerColor(kBlue); fGraphFtmRate.SetMarkerStyle(kFullDotMedium); for (int i=0; i<160; i++) { fGraphPatchRate[i].SetName("PatchRate"); //fGraphPatchRate[i].SetLineColor(kBlue); //fGraphPatchRate[i].SetMarkerColor(kBlue); fGraphPatchRate[i].SetMarkerStyle(kFullDotMedium); } for (int i=0; i<40; i++) { fGraphBoardRate[i].SetName("BoardRate"); //fGraphBoardRate[i].SetLineColor(kBlue); //fGraphBoardRate[i].SetMarkerColor(kBlue); fGraphBoardRate[i].SetMarkerStyle(kFullDotMedium); } /* TCanvas *c = fFtmTempCanv->GetCanvas(); c->SetBit(TCanvas::kNoContextMenu); c->SetBorderMode(0); c->SetFrameBorderMode(0); c->SetFillColor(kWhite); c->SetRightMargin(0.03); c->SetTopMargin(0.03); c->cd(); */ //CreateTimeFrame("Temperature / °C"); fGraphFtmTemp[0].SetMarkerStyle(kFullDotSmall); fGraphFtmTemp[1].SetMarkerStyle(kFullDotSmall); fGraphFtmTemp[2].SetMarkerStyle(kFullDotSmall); fGraphFtmTemp[3].SetMarkerStyle(kFullDotSmall); fGraphFtmTemp[1].SetLineColor(kBlue); fGraphFtmTemp[2].SetLineColor(kRed); fGraphFtmTemp[3].SetLineColor(kGreen); fGraphFtmTemp[1].SetMarkerColor(kBlue); fGraphFtmTemp[2].SetMarkerColor(kRed); fGraphFtmTemp[3].SetMarkerColor(kGreen); //fGraphFtmTemp[0].Draw("LP"); //fGraphFtmTemp[1].Draw("LP"); //fGraphFtmTemp[2].Draw("LP"); //fGraphFtmTemp[3].Draw("LP"); // -------------------------------------------------------------------------- TCanvas *c = fFtmRateCanv->GetCanvas(); //c->SetBit(TCanvas::kNoContextMenu); c->SetBorderMode(0); c->SetFrameBorderMode(0); c->SetFillColor(kWhite); c->SetRightMargin(0.03); c->SetTopMargin(0.03); c->SetGrid(); c->cd(); TH1 *hf = DrawTimeFrame("Trigger rate [Hz]"); hf->GetYaxis()->SetRangeUser(0, 1010); fTriggerCounter0 = -1; fGraphFtmRate.SetMarkerStyle(kFullDotSmall); fGraphFtmRate.Draw("LP"); // -------------------------------------------------------------------------- c = fRatesCanv->GetCanvas(); //c->SetBit(TCanvas::kNoContextMenu); c->SetBorderMode(0); c->SetFrameBorderMode(0); c->SetFillColor(kWhite); c->cd(); Camera *cam = new Camera; cam->SetBit(kCanDelete); cam->Draw(); ChoosePixel(*cam, 0); // -------------------------------------------------------------------------- c = fAdcDataCanv->GetCanvas(); //c->SetBit(TCanvas::kNoContextMenu); c->SetBorderMode(0); c->SetFrameBorderMode(0); c->SetFillColor(kWhite); c->SetGrid(); c->cd(); // Create histogram? // -------------------------------------------------------------------------- // QTimer::singleShot(0, this, SLOT(slot_RootUpdate())); //widget->setMouseTracking(true); //widget->EnableSignalEvents(kMouseMoveEvent); fFtmRateCanv->setMouseTracking(true); fFtmRateCanv->EnableSignalEvents(kMouseMoveEvent); fAdcDataCanv->setMouseTracking(true); fAdcDataCanv->EnableSignalEvents(kMouseMoveEvent); fRatesCanv->setMouseTracking(true); fRatesCanv->EnableSignalEvents(kMouseMoveEvent|kMouseReleaseEvent|kMouseDoubleClickEvent); connect(fRatesCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)), this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*))); connect(fFtmRateCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)), this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*))); connect(fAdcDataCanv, SIGNAL( RootEventProcessed(TObject*, unsigned int, TCanvas*)), this, SLOT (slot_RootEventProcessed(TObject*, unsigned int, TCanvas*))); #endif } ~FactGui() { // Unsubscribe all services for (map::iterator i=fServices.begin(); i!=fServices.end(); i++) delete i->second; delete fEventData; } }; #endif